// Most general methodvec<Lit> clause;clause.push(mkLit(0, false));clause.push(mkLit(1, true));clause.push(mkLit(2, false));bool ok = solver.addClause(clause);if (!ok) { // Adding clause made formula unsatisfiable}
Adding a clause may trigger unit propagation. If this leads to a conflict, addClause() returns false, indicating the formula is unsatisfiable.
// Get clause sizeint size = clause.size();// Access literals by indexLit lit0 = clause[0];Lit lit1 = clause[1];// Get last literalLit last = clause.last();// Check if learnedbool is_learnt = clause.learnt();// Get mark (for algorithms)uint32_t mark = clause.mark();clause.mark(1); // Set mark
// Shrink clause by removing last literalsclause.shrink(2); // Remove 2 literals from end// Remove last literalclause.pop();// Strengthen clause (remove specific literal)Lit p = mkLit(2, true);clause.strengthen(p);
Modifying clauses in-place is somewhat unsafe. If you change a clause, you must manually call calcAbstraction() afterward for subsumption operations to work correctly.
Learned clauses have activity scores for deletion heuristics:
if (clause.learnt()) { // Get current activity float act = clause.activity(); // Activity is bumped during conflict analysis // Higher activity = more recently useful}
Lit result = clause1.subsumes(clause2);if (result == lit_Undef) { // clause1 subsumes clause2 // clause2 can be removed} else if (result == lit_Error) { // No subsumption relationship} else { // result is a literal that can be removed // from clause2 (subsumption resolution)}
Subsumption: Clause C1 subsumes C2 if every literal in C1 appears in C2. If C1 is satisfied, C2 is automatically satisfied, so C2 is redundant.
Original clauses may store an abstraction for fast subsumption checks:
if (clause.has_extra() && !clause.learnt()) { uint32_t abs = clause.abstraction(); // Bit mask of variables in clause // Used for quick subsumption filtering}
Unit clauses (single literal) receive special treatment:
// Unit clause forces its literal to be truesolver.addClause(mkLit(5, false)); // x5 must be true// Internally, this triggers immediate propagation// The literal is assigned at decision level 0
Unit clauses are extremely powerful in SAT solving. They immediately reduce the search space and often trigger chains of propagations.
Watched literals: Each clause watches two of its literals. The clause only needs to be examined when one of its watched literals becomes false. This dramatically reduces the number of clause examinations during propagation.