use crate::formulas::{EncodedFormula, FormulaFactory, Literal, Variable};
use crate::solver::minisat::sat::{mk_lit, MsLit};
use crate::solver::minisat::MiniSat;
pub trait EncodingResult {
fn new_cc_variable(&mut self, f: &FormulaFactory) -> Variable;
fn reset(&mut self);
fn add_clause(&mut self, f: &FormulaFactory, lits: &[Literal]);
fn add_clause1(&mut self, f: &FormulaFactory, literal: Literal);
fn add_clause2(&mut self, f: &FormulaFactory, literal1: Literal, literal2: Literal);
fn add_clause3(&mut self, f: &FormulaFactory, literal1: Literal, literal2: Literal, literal3: Literal);
fn add_clause4(&mut self, f: &FormulaFactory, literal1: Literal, literal2: Literal, literal3: Literal, literal4: Literal);
}
impl EncodingResult for MiniSat {
fn new_cc_variable(&mut self, f: &FormulaFactory) -> Variable {
let index = self.underlying_solver.new_var(self.config.initial_phase, true);
let variable = f.new_cc_variable();
self.underlying_solver.add_variable(variable, index);
variable
}
fn reset(&mut self) {
}
fn add_clause(&mut self, _f: &FormulaFactory, lits: &[Literal]) {
let mut clause_vec = Vec::<MsLit>::with_capacity(lits.len());
for lit in lits {
clause_vec.push(self.add_literal(lit));
}
self.underlying_solver.add_clause(clause_vec, &None);
self.set_solver_to_undef();
}
fn add_clause1(&mut self, _f: &FormulaFactory, literal: Literal) {
let clause_vec = vec![self.add_literal(&literal)];
self.underlying_solver.add_clause(clause_vec, &None);
self.set_solver_to_undef();
}
fn add_clause2(&mut self, _f: &FormulaFactory, literal1: Literal, literal2: Literal) {
let clause_vec = vec![self.add_literal(&literal1), self.add_literal(&literal2)];
self.underlying_solver.add_clause(clause_vec, &None);
self.set_solver_to_undef();
}
fn add_clause3(&mut self, _f: &FormulaFactory, literal1: Literal, literal2: Literal, literal3: Literal) {
let clause_vec = vec![self.add_literal(&literal1), self.add_literal(&literal2), self.add_literal(&literal3)];
self.underlying_solver.add_clause(clause_vec, &None);
self.set_solver_to_undef();
}
fn add_clause4(&mut self, _f: &FormulaFactory, literal1: Literal, literal2: Literal, literal3: Literal, literal4: Literal) {
let clause_vec =
vec![self.add_literal(&literal1), self.add_literal(&literal2), self.add_literal(&literal3), self.add_literal(&literal4)];
self.underlying_solver.add_clause(clause_vec, &None);
self.set_solver_to_undef();
}
}
impl MiniSat {
fn add_literal(&mut self, lit: &Literal) -> MsLit {
let index = self.underlying_solver.idx_for_variable(lit.variable()).unwrap_or_else(|| {
let new_index = self.underlying_solver.new_var(!self.config.initial_phase, true);
self.underlying_solver.add_variable(lit.variable(), new_index);
new_index
});
mk_lit(index, !lit.phase())
}
}
impl EncodingResult for Vec<EncodedFormula> {
fn new_cc_variable(&mut self, f: &FormulaFactory) -> Variable {
f.new_cc_variable()
}
fn reset(&mut self) {
self.clear();
}
fn add_clause(&mut self, f: &FormulaFactory, lits: &[Literal]) {
let clause = f.or(&lits.iter().map(|lit| EncodedFormula::from(*lit)).collect::<Box<[_]>>());
self.push(clause);
}
fn add_clause1(&mut self, f: &FormulaFactory, literal: Literal) {
let clause = f.or(&[literal.into()]);
self.push(clause);
}
fn add_clause2(&mut self, f: &FormulaFactory, literal1: Literal, literal2: Literal) {
let clause = f.or(&[literal1.into(), literal2.into()]);
self.push(clause);
}
fn add_clause3(&mut self, f: &FormulaFactory, literal1: Literal, literal2: Literal, literal3: Literal) {
let clause = f.or(&[literal1.into(), literal2.into(), literal3.into()]);
self.push(clause);
}
fn add_clause4(&mut self, f: &FormulaFactory, literal1: Literal, literal2: Literal, literal3: Literal, literal4: Literal) {
let clause = f.or(&[literal1.into(), literal2.into(), literal3.into(), literal4.into()]);
self.push(clause);
}
}