diff --git a/src/sat/sat_elim_eqs.cpp b/src/sat/sat_elim_eqs.cpp index 870aa7fe2..8633f04d3 100644 --- a/src/sat/sat_elim_eqs.cpp +++ b/src/sat/sat_elim_eqs.cpp @@ -23,9 +23,15 @@ Revision History: namespace sat { elim_eqs::elim_eqs(solver & s): - m_solver(s) { + m_solver(s), + m_to_delete(nullptr) { } + elim_eqs::~elim_eqs() { + dealloc(m_to_delete); + } + + inline literal norm(literal_vector const & roots, literal l) { if (l.sign()) return ~roots[l.var()]; @@ -86,6 +92,12 @@ namespace sat { m_new_bin.reset(); } + void elim_eqs::drat_delete_clause() { + if (m_solver.m_config.m_drat) { + m_solver.m_drat.del(*m_to_delete->get()); + } + } + void elim_eqs::cleanup_clauses(literal_vector const & roots, clause_vector & cs) { clause_vector::iterator it = cs.begin(); clause_vector::iterator it2 = it; @@ -107,8 +119,16 @@ namespace sat { it2++; continue; } - if (!c.frozen()) + if (!c.frozen()) { m_solver.detach_clause(c); + } + + // save clause to be deleted for drat + if (m_solver.m_config.m_drat) { + if (!m_to_delete) m_to_delete = alloc(tmp_clause); + m_to_delete->set(sz, c.begin(), c.is_learned()); + } + // apply substitution for (i = 0; i < sz; i++) { literal lit = c[i]; @@ -124,60 +144,69 @@ namespace sat { CTRACE("sat", l != norm(roots, l), tout << l << " " << norm(roots, l) << "\n"; tout.flush();); SASSERT(l == norm(roots, l)); } }); + // remove duplicates, and check if it is a tautology - literal l_prev = null_literal; unsigned j = 0; + literal l_prev = null_literal; for (i = 0; i < sz; i++) { literal l = c[i]; - if (l == l_prev) - continue; - if (l == ~l_prev) + if (l == ~l_prev) { break; + } + if (l == l_prev) { + continue; + } + SASSERT(l != ~l_prev); l_prev = l; lbool val = m_solver.value(l); - if (val == l_true) - break; // clause was satisfied - if (val == l_false) + if (val == l_true) { + break; + } + if (val == l_false) { continue; // skip + } c[j] = l; j++; } + TRACE("elim_eqs", tout << "after removing duplicates: " << c << " j: " << j << "\n";); + if (i < sz) { - // clause is a tautology or was simplified to true - m_solver.del_clause(c); + drat_delete_clause(); + m_solver.del_clause(c, false); continue; } - if (j == 0) { - // empty clause + + switch (j) { + case 0: m_solver.set_conflict(justification()); for (; it != end; ++it) { *it2 = *it; it2++; } cs.set_end(it2); - return; - } - TRACE("elim_eqs", tout << "after removing duplicates: " << c << " j: " << j << "\n";); - - SASSERT(j >= 1); - switch (j) { + return; case 1: m_solver.assign(c[0], justification()); - m_solver.del_clause(c); + m_solver.del_clause(c, false); + drat_delete_clause(); break; case 2: m_solver.mk_bin_clause(c[0], c[1], c.is_learned()); - m_solver.del_clause(c); + m_solver.del_clause(c, false); + drat_delete_clause(); break; default: SASSERT(*it == &c); if (j < sz) { - if (m_solver.m_config.m_drat) m_solver.m_drat.del(c); c.shrink(j); - if (m_solver.m_config.m_drat) m_solver.m_drat.add(c, true); } - else + else { c.update_approx(); + } + if (m_solver.m_config.m_drat) { + m_solver.m_drat.add(c, true); + drat_delete_clause(); + } DEBUG_CODE(for (literal l : c) VERIFY(l == norm(roots, l));); diff --git a/src/sat/sat_elim_eqs.h b/src/sat/sat_elim_eqs.h index 143fcbb3f..ac132b213 100644 --- a/src/sat/sat_elim_eqs.h +++ b/src/sat/sat_elim_eqs.h @@ -23,6 +23,7 @@ Revision History: namespace sat { class solver; + class tmp_clause; class elim_eqs { struct bin { @@ -32,6 +33,8 @@ namespace sat { }; svector m_new_bin; solver & m_solver; + tmp_clause* m_to_delete; + void drat_delete_clause(); void save_elim(literal_vector const & roots, bool_var_vector const & to_elim); void cleanup_clauses(literal_vector const & roots, clause_vector & cs); void cleanup_bin_watches(literal_vector const & roots); @@ -39,6 +42,7 @@ namespace sat { bool check_clause(clause const& c, literal_vector const& roots) const; public: elim_eqs(solver & s); + ~elim_eqs(); void operator()(literal_vector const & roots, bool_var_vector const & to_elim); }; diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index fc5fce252..6731adc92 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -298,14 +298,14 @@ namespace sat { mk_clause(3, ls, learned); } - void solver::del_clause(clause& c) { + void solver::del_clause(clause& c, bool enable_drat) { if (!c.is_learned()) { m_stats.m_non_learned_generation++; } if (c.frozen()) { --m_num_frozen; } - if (m_config.m_drat && !m_drat.is_cleaned(c)) { + if (enable_drat && m_config.m_drat && !m_drat.is_cleaned(c)) { m_drat.del(c); } dealloc_clause(&c); diff --git a/src/sat/sat_solver.h b/src/sat/sat_solver.h index 8402fc898..3937c67e8 100644 --- a/src/sat/sat_solver.h +++ b/src/sat/sat_solver.h @@ -232,7 +232,7 @@ namespace sat { void defrag_clauses(); bool should_defrag(); bool memory_pressure(); - void del_clause(clause & c); + void del_clause(clause & c, bool enable_drat = true); clause * mk_clause_core(unsigned num_lits, literal * lits, bool learned); clause * mk_clause_core(literal_vector const& lits) { return mk_clause_core(lits.size(), lits.c_ptr()); } clause * mk_clause_core(unsigned num_lits, literal * lits) { return mk_clause_core(num_lits, lits, false); }