1/*******************************************************************\
3Module: CNF Generation, via Tseitin
5Author: Daniel Kroening, kroening@kroening.com
7\*******************************************************************/
25 // a*b=c <==> (a + o')( b + o')(a'+b'+o)
48 // a+b=c <==> (a' + c)( b' + c)(a + b + c')
70 // a xor b = o <==> (a' + b' + o')
101 // a Nand b = o <==> (a + o)( b + o)(a' + b' + o')
123 // a Nor b = o <==> (a' + o')( b' + o')(a + b + o)
165 return land(bv[0], bv[1]);
167 for(
const auto &l : bv)
180 for(
const auto &l :
new_bv)
189 for(
const auto &l :
new_bv)
208 return lor(bv[0], bv[1]);
210 for(
const auto &l : bv)
223 for(
const auto &l :
new_bv)
232 for(
const auto &l :
new_bv)
251 return lxor(bv[0], bv[1]);
255 for(
const auto &l : bv)
265 if(
a.is_true() ||
b.is_false())
267 if(
b.is_true() ||
a.is_false())
281 if(
a.is_false() ||
b.is_true())
283 if(
b.is_false() ||
a.is_true())
339// Tino observed slow-downs up to 50% with OPTIMAL_COMPACT_ITE.
342// #define OPTIMAL_COMPACT_ITE
346 // a?b:c = (a AND b) OR (/a AND c)
348 return a.sign() ?
b :
c;
359 // (a+c'+o) (a+c+o') (a'+b'+o) (a'+b+o')
370 #ifdef OPTIMAL_COMPACT_ITE
371 // additional clauses to enable better propagation
399 result.reserve(width);
402 result.emplace_back(i,
false);
415 std::sort(dest.begin(), dest.end());
416 auto last = std::unique(dest.begin(), dest.end());
417 dest.erase(last, dest.end());
428 // empty clause! this is UNSAT
432 // first check simple things
434 for(
const auto &l : bv)
436 // we never use index 0
437 INVARIANT(l.var_no() != 0,
"variable 0 must not be used");
439 // we never use 'unused_var_no'
442 "variable 'unused_var_no' must not be used");
445 return true;
// clause satisfied
448 continue;
// will remove later
452 "unknown variable " + std::to_string(l.var_no()) +
458 dest.reserve(bv.size());
460 for(
const auto &l : bv)
469 std::sort(dest.begin(), dest.end());
471 // eliminate duplicates and find occurrences of a variable
476 bvt::iterator it=dest.begin();
485 // prevent duplicate literals
488 else if(previous==!l)
489 return true;
// clause satisfied trivially
virtual void clear()
Reset the abstract state.
ait supplies three of the four components needed: an abstract interpreter (in this case handling func...
static bool is_all(const bvt &bv, literalt l)
void gate_equal(literalt a, literalt b, literalt o)
Tseitin encoding of equality between two literals.
bool process_clause(const bvt &bv, bvt &dest) const
filter 'true' from clause, eliminate duplicates, recognise trivially satisfied clauses
bvt new_variables(std::size_t width) override
Generate a vector of new variables.
void gate_or(literalt a, literalt b, literalt o)
Tseitin encoding of disjunction of two literals.
virtual literalt limplies(literalt a, literalt b) override
virtual literalt lselect(literalt a, literalt b, literalt c) override
virtual void set_no_variables(size_t no)
static bvt eliminate_duplicates(const bvt &)
eliminate duplicates from given vector of literals
void gate_nand(literalt a, literalt b, literalt o)
Tseitin encoding of NAND of two literals.
virtual literalt new_variable() override
Generate a new variable and return it as a literal.
void gate_xor(literalt a, literalt b, literalt o)
Tseitin encoding of XOR of two literals.
void gate_nor(literalt a, literalt b, literalt o)
Tseitin encoding of NOR of two literals.
virtual literalt lequal(literalt a, literalt b) override
virtual literalt land(literalt a, literalt b) override
void gate_implies(literalt a, literalt b, literalt o)
Tseitin encoding of implication between two literals.
virtual literalt lxor(const bvt &bv) override
Tseitin encoding of XOR between multiple literals.
void gate_and(literalt a, literalt b, literalt o)
Tseitin encoding of conjunction of two literals.
virtual literalt lnand(literalt a, literalt b) override
virtual literalt lnor(literalt a, literalt b) override
virtual literalt lor(literalt a, literalt b) override
static var_not unused_var_no()
void lcnf(literalt l0, literalt l1)
CNF Generation, via Tseitin.
std::vector< literalt > bvt
literalt const_literal(bool value)
#define INVARIANT(CONDITION, REASON)
This macro uses the wrapper function 'invariant_violated_string'.