#[cfg(any(feature = "cadical", test))]
pub mod cadical;
#[cfg(feature = "intel-sat")]
pub mod intel_sat;
pub(crate) mod ipasir;
#[cfg(feature = "kissat")]
pub mod kissat;
#[cfg(feature = "libloading")]
pub mod libloading;
#[cfg(feature = "external-propagation")]
pub mod propagation;
#[cfg(feature = "splr")]
pub mod splr;
use std::num::NonZeroI32;
use crate::{ClauseDatabase, Lit, Valuation, Var, VarRange};
pub trait Assumptions: Solver {
fn solve_assuming<I: IntoIterator<Item = Lit>>(
&mut self,
assumptions: I,
) -> SolveResult<impl Valuation + '_, impl FailedAssumptions + '_>;
}
pub trait FailedAssumptions {
fn fail(&self, lit: Lit) -> bool;
}
pub trait LearnCallback: Solver {
fn set_learn_callback<F: FnMut(&mut dyn Iterator<Item = Lit>) + 'static>(
&mut self,
cb: Option<F>,
);
}
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
pub enum SolveResult<Sol: Valuation, Fail = ()> {
Satisfied(Sol),
Unsatisfiable(Fail),
Unknown,
}
pub trait Solver: ClauseDatabase {
fn solve(&mut self) -> SolveResult<impl Valuation + '_, impl Sized>;
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
pub enum TermSignal {
Continue,
Terminate,
}
pub trait TerminateCallback: Solver {
fn set_terminate_callback<F: FnMut() -> TermSignal + 'static>(&mut self, cb: Option<F>);
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct VarFactory {
pub(crate) next_var: Option<Var>,
}
impl VarFactory {
pub fn emitted_vars(&self) -> VarRange {
let mut start = Var(NonZeroI32::new(1).unwrap());
let end = if let Some(v) = self.next_var {
if let Some(prev) = v.prev_var() {
prev
} else {
start = Var(NonZeroI32::new(2).unwrap());
Var(NonZeroI32::new(1).unwrap())
}
} else {
Var(NonZeroI32::MAX)
};
VarRange { start, end }
}
pub(crate) fn next_var_range(&mut self, size: usize) -> VarRange {
let Some(start) = self.next_var else {
panic!("unable to create more than `Var::MAX_VARS` variables")
};
match size {
0 => VarRange::new(
Var(NonZeroI32::new(2).unwrap()),
Var(NonZeroI32::new(1).unwrap()),
),
1 => {
self.next_var = start.next_var();
VarRange::new(start, start)
}
_ if size > Var::MAX_VARS => {
panic!("unable to create more than `Var::MAX_VARS` variables")
}
_ => {
let size = NonZeroI32::new((size - 1) as i32).unwrap();
if let Some(end) = start.checked_add(size) {
self.next_var = end.next_var();
VarRange::new(start, end)
} else {
panic!("unable to create more than `Var::MAX_VARS` variables")
}
}
}
}
pub fn num_emitted_vars(&self) -> usize {
if let Some(x) = self.next_var {
x.0.get() as usize - 1
} else {
Var::MAX_VARS
}
}
}
impl Default for VarFactory {
fn default() -> Self {
Self {
next_var: Some(Var(NonZeroI32::new(1).unwrap())),
}
}
}