1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
/* Main Interface */
use std::fmt::Debug;
use clause::{Var,Lit,lbool};
/// Result returned by the `final_check` call.
///
/// A theory can validate the model (returning `Done`)
/// or signal a conflict (`Conflict`). If the theory also pushed clauses
/// upon `Done` then the model search will resume.
#[derive(Debug,PartialEq,Eq,Clone,Copy)]
pub enum FinalCheckRes {
Done,
Conflict,
}
/// Theory that parametrizes the solver and can react on events
pub trait Theory<S : TheoryArgument> : Debug {
/// Check the model candidate `model` thoroughly.
///
/// If the partial model isn't satisfiable in the theory then
/// this *must* return `FinalCheckRes::Conflict` and push a conflict
/// clause.
fn final_check(&mut self, &mut S, model: &[Lit]) -> FinalCheckRes;
/// Push a new backtracking level
fn create_level(&mut self);
/// Pop `n` levels from the stack
fn pop_level(&mut self, n: u32);
/// Called whenever the solver gets a new clause
fn on_add_clause(&mut self, c: &S::Clause, learnt: bool);
}
/// Interface provided to the theory
pub trait TheoryArgument {
/// The public representation of clauses from a theory's perspective
type Clause : Debug+PartialEq+Eq;
/// Access the literals of a clause
fn clause_lits(&self, c: &Self::Clause) -> &[Lit];
/// Is this a learnt clause?
fn clause_learnt(&self, c: &Self::Clause) -> bool;
/// Allocate a new literal
fn new_lit(&mut self) -> Lit;
/// Push a theory lemma into the solver
fn add_theory_lemma(&mut self, &[Lit]);
}
/// Main interface for a solver: it makes it possible to add clauses,
/// allocate variables, and check for satisfiability
pub trait SolverInterface {
fn num_vars(&self) -> u32;
fn num_clauses(&self) -> u32;
fn num_conflicts(&self) -> u32;
fn is_ok(&self) -> bool;
/// Print some current statistics to standard output.
fn print_stats(&self);
/// Creates a new SAT variable in the solver. If 'decision' is cleared, variable will not be
/// used as a decision variable (NOTE! This has effects on the meaning of a SATISFIABLE result).
fn new_var(&mut self, upol: lbool, dvar: bool) -> Var;
/// Create a new variable with the default polarity
fn new_var_default(&mut self) -> Var;
/// Add a clause to the solver. Returns `false` if the solver is in
/// an `UNSAT` state.
fn add_clause_reuse(&mut self, clause: &mut Vec<Lit>) -> bool;
/// Simplify the clause database according to the current top-level assigment. Currently, the only
/// thing done here is the removal of satisfied clauses, but more things can be put here.
fn simplify(&mut self) -> bool;
/// Search for a model that respects a given set of assumptions (With resource constraints).
fn solve_limited(&mut self, assumps: &[Lit]) -> lbool;
/// Obtain the slice of literals that are proved at level 0.
///
/// These literals will keep this value from now on.
fn proved_at_lvl_0(&self) -> &[Lit];
/// Query whole model
///
/// Precondition: last result was `Sat` (ie `lbool::TRUE`)
fn get_model(&self) -> &[lbool];
/// Query model for var
///
/// Precondition: last result was `Sat` (ie `lbool::TRUE`)
fn value_var(&self, Var) -> lbool;
/// Query model for lit
fn value_lit(&self, Lit) -> lbool;
/// Value of this literal if it's assigned at level 0, or `UNDEF` otherwise
fn value_lvl_0(&self, Lit) -> lbool;
/// Return unsat core (as a subset of assumptions).
///
/// Precondition: last result was `Unsat`
fn unsat_core(&self) -> &[Lit];
/// Does this literal occur in the unsat-core?
///
/// Precondition: last result was `Unsat`
fn unsat_core_contains_lit(&self, lit: Lit) -> bool;
/// Does this variable occur in the unsat-core?
///
/// Precondition: last result was `Unsat`
fn unsat_core_contains_var(&self, v: Var) -> bool;
}