From 4c799c144a2f7554b449dc3a0ad6432e4a348c3f Mon Sep 17 00:00:00 2001 From: Nikolaj Bjorner Date: Fri, 22 Feb 2019 11:14:20 +0100 Subject: [PATCH] fix gc to not remove ternary clauses that are on assignment trail. This addresses issue with drat proofs that don't pass drat-trim due to deletion during gc, but use in conflicts Signed-off-by: Nikolaj Bjorner --- src/sat/sat_clause.cpp | 2 +- src/sat/sat_drat.cpp | 113 +++++++++++++++++++++++++--------- src/sat/sat_drat.h | 4 ++ src/sat/sat_elim_eqs.cpp | 2 +- src/sat/sat_probing.cpp | 3 + src/sat/sat_simplifier.cpp | 24 ++++---- src/sat/sat_simplifier.h | 2 +- src/sat/sat_solver.cpp | 88 ++++++++++++++++++++++---- src/sat/sat_solver.h | 23 +++---- src/sat/sat_watched.cpp | 10 ++- src/sat/tactic/sat_tactic.cpp | 1 + 11 files changed, 201 insertions(+), 71 deletions(-) diff --git a/src/sat/sat_clause.cpp b/src/sat/sat_clause.cpp index d27820e71..03ae55092 100644 --- a/src/sat/sat_clause.cpp +++ b/src/sat/sat_clause.cpp @@ -38,7 +38,6 @@ namespace sat { memcpy(m_lits, lits, sizeof(literal) * sz); mark_strengthened(); SASSERT(check_approx()); - SASSERT(sz > 1); } var_approx_set clause::approx(unsigned num, literal const * lits) { @@ -83,6 +82,7 @@ namespace sat { i++; for (; i < m_size; i++) m_lits[i-1] = m_lits[i]; + m_lits[m_size-1] = l; m_size--; mark_strengthened(); } diff --git a/src/sat/sat_drat.cpp b/src/sat/sat_drat.cpp index ac05b50f1..de65aca92 100644 --- a/src/sat/sat_drat.cpp +++ b/src/sat/sat_drat.cpp @@ -49,10 +49,13 @@ namespace sat { dealloc(m_bout); for (unsigned i = 0; i < m_proof.size(); ++i) { clause* c = m_proof[i]; - if (c && (c->size() == 2 || m_status[i] == status::deleted || m_status[i] == status::external)) { - s.dealloc_clause(c); + if (c) { + m_alloc.del_clause(c); } } + m_proof.reset(); + m_out = nullptr; + m_bout = nullptr; } void drat::updt_config() { @@ -75,7 +78,7 @@ namespace sat { if (st == status::asserted || st == status::external) { return; } - + char buffer[10000]; char digits[20]; // enough for storing unsigned char* lastd = digits + sizeof(digits); @@ -166,6 +169,9 @@ namespace sat { } void drat::append(literal l, status st) { + TRACE("sat_drat", tout << st << " " << l << "\n";); + + declare(l); IF_VERBOSE(20, trace(verbose_stream(), 1, &l, st);); if (st == status::learned) { verify(1, &l); @@ -177,13 +183,15 @@ namespace sat { assign_propagate(l); } - clause* c = s.alloc_clause(1, &l, st == status::learned); - m_proof.push_back(c); - m_status.push_back(st); + m_units.push_back(l); } void drat::append(literal l1, literal l2, status st) { + TRACE("sat_drat", tout << st << " " << l1 << " " << l2 << "\n";); + declare(l1); + declare(l2); literal lits[2] = { l1, l2 }; + IF_VERBOSE(20, trace(verbose_stream(), 2, lits, st);); if (st == status::deleted) { // noop @@ -193,7 +201,7 @@ namespace sat { if (st == status::learned) { verify(2, lits); } - clause* c = s.alloc_clause(2, lits, st == status::learned); + clause* c = m_alloc.mk_clause(2, lits, st == status::learned); m_proof.push_back(c); m_status.push_back(st); if (!m_check_unsat) return; @@ -214,14 +222,37 @@ namespace sat { } } +#if 0 + // debugging code + bool drat::is_clause(clause& c, literal l1, literal l2, literal l3, drat::status st1, drat::status st2) { + //if (st1 != st2) return false; + if (c.size() != 3) return false; + if (l1 == c[0]) { + if (l2 == c[1] && l3 == c[2]) return true; + if (l2 == c[2] && l3 == c[1]) return true; + } + if (l2 == c[0]) { + if (l1 == c[1] && l3 == c[2]) return true; + if (l1 == c[2] && l3 == c[1]) return true; + } + if (l3 == c[0]) { + if (l1 == c[1] && l2 == c[2]) return true; + if (l1 == c[2] && l2 == c[1]) return true; + } + return false; + } +#endif + void drat::append(clause& c, status st) { + TRACE("sat_drat", tout << st << " " << c << "\n";); + for (literal lit : c) declare(lit); unsigned n = c.size(); IF_VERBOSE(20, trace(verbose_stream(), n, c.begin(), st);); if (st == status::learned) { verify(c); } - + m_status.push_back(st); m_proof.push_back(&c); if (st == status::deleted) { @@ -274,6 +305,7 @@ namespace sat { } void drat::declare(literal l) { + if (!m_check) return; unsigned n = static_cast(l.var()); while (m_assignment.size() <= n) { m_assignment.push_back(l_undef); @@ -379,7 +411,7 @@ namespace sat { case l_undef: num_undef++; break; } } - CTRACE("sat", num_true == 0 && num_undef == 1, display(tout);); + CTRACE("sat_drat", num_true == 0 && num_undef == 1, display(tout);); SASSERT(num_true != 0 || num_undef != 1); } } @@ -423,7 +455,7 @@ namespace sat { exit(0); UNREACHABLE(); //display(std::cout); - TRACE("sat", + TRACE("sat_drat", tout << literal_vector(n, c) << "\n"; display(tout); s.display(tout);); @@ -431,16 +463,41 @@ namespace sat { } } + bool drat::contains(literal c, justification const& j) { + if (!m_check_sat) { + return true; + } + switch (j.get_kind()) { + case justification::NONE: + return m_units.contains(c); + case justification::BINARY: + return contains(c, j.get_literal()); + case justification::TERNARY: + return contains(c, j.get_literal1(), j.get_literal2()); + case justification::CLAUSE: + return contains(s.get_clause(j)); + default: + return true; + } + } + bool drat::contains(unsigned n, literal const* lits) { if (!m_check) return true; + unsigned num_add = 0; + unsigned num_del = 0; for (unsigned i = m_proof.size(); i-- > 0; ) { clause& c = *m_proof[i]; status st = m_status[i]; if (match(n, lits, c)) { - return st != status::deleted; + if (st == status::deleted) { + num_del++; + } + else { + num_add++; + } } } - return false; + return num_add > num_del; } bool drat::match(unsigned n, literal const* lits, clause const& c) const { @@ -454,7 +511,9 @@ namespace sat { break; } } - if (!found) return false; + if (!found) { + return false; + } } return true; } @@ -512,7 +571,7 @@ namespace sat { void drat::assign(literal l) { lbool new_value = l.sign() ? l_false : l_true; lbool old_value = value(l); -// TRACE("sat", tout << "assign " << l << " := " << new_value << " from " << old_value << "\n";); +// TRACE("sat_drat", tout << "assign " << l << " := " << new_value << " from " << old_value << "\n";); switch (old_value) { case l_false: m_inconsistent = true; @@ -544,7 +603,7 @@ namespace sat { watched_clause& wc = m_watched_clauses[idx]; clause& c = *wc.m_clause; - //TRACE("sat", tout << "Propagate " << l << " " << c << " watch: " << wc.m_l1 << " " << wc.m_l2 << "\n";); + //TRACE("sat_drat", tout << "Propagate " << l << " " << c << " watch: " << wc.m_l1 << " " << wc.m_l2 << "\n";); if (wc.m_l1 == ~l) { std::swap(wc.m_l1, wc.m_l2); } @@ -596,17 +655,12 @@ namespace sat { } } void drat::add(literal l, bool learned) { - TRACE("sat", tout << "add: " << l << " " << (learned?"l":"t") << "\n";); - declare(l); status st = get_status(learned); if (m_out) dump(1, &l, st); if (m_bout) bdump(1, &l, st); if (m_check) append(l, st); } void drat::add(literal l1, literal l2, bool learned) { - TRACE("sat", tout << "add: " << l1 << " " << l2 << " " << (learned?"l":"t") << "\n";); - declare(l1); - declare(l2); literal ls[2] = {l1, l2}; status st = get_status(learned); if (m_out) dump(2, ls, st); @@ -614,12 +668,13 @@ namespace sat { if (m_check) append(l1, l2, st); } void drat::add(clause& c, bool learned) { - TRACE("sat", tout << "add: " << c << "\n";); - for (unsigned i = 0; i < c.size(); ++i) declare(c[i]); status st = get_status(learned); if (m_out) dump(c.size(), c.begin(), st); if (m_bout) bdump(c.size(), c.begin(), st); - if (m_check_unsat) append(c, get_status(learned)); + if (m_check) { + clause* cl = m_alloc.mk_clause(c.size(), c.begin(), learned); + append(*cl, get_status(learned)); + } } void drat::add(literal_vector const& lits, svector const& premises) { if (m_check) { @@ -627,7 +682,7 @@ namespace sat { case 0: add(); break; case 1: append(lits[0], status::external); break; default: { - clause* c = s.alloc_clause(lits.size(), lits.c_ptr(), true); + clause* c = m_alloc.mk_clause(lits.size(), lits.c_ptr(), true); append(*c, status::external); break; } @@ -635,16 +690,16 @@ namespace sat { } } void drat::add(literal_vector const& c) { - for (unsigned i = 0; i < c.size(); ++i) declare(c[i]); if (m_out) dump(c.size(), c.begin(), status::learned); if (m_bout) bdump(c.size(), c.begin(), status::learned); if (m_check) { + for (literal lit : c) declare(lit); switch (c.size()) { case 0: add(); break; case 1: append(c[0], status::learned); break; default: { verify(c.size(), c.begin()); - clause* cl = s.alloc_clause(c.size(), c.c_ptr(), true); + clause* cl = m_alloc.mk_clause(c.size(), c.c_ptr(), true); append(*cl, status::external); break; } @@ -657,8 +712,10 @@ namespace sat { if (m_bout) bdump(1, &l, status::deleted); if (m_check_unsat) append(l, status::deleted); } + void drat::del(literal l1, literal l2) { literal ls[2] = {l1, l2}; + SASSERT(!(l1 == literal(13923, false) && l2 == literal(14020, true))); if (m_out) dump(2, ls, status::deleted); if (m_bout) bdump(2, ls, status::deleted); if (m_check) append(l1, l2, status::deleted); @@ -677,11 +734,11 @@ namespace sat { } #endif - TRACE("sat", tout << "del: " << c << "\n";); + //SASSERT(!(c.size() == 2 && c[0] == literal(13923, false) && c[1] == literal(14020, true))); if (m_out) dump(c.size(), c.begin(), status::deleted); if (m_bout) bdump(c.size(), c.begin(), status::deleted); if (m_check) { - clause* c1 = s.alloc_clause(c.size(), c.begin(), c.is_learned()); + clause* c1 = m_alloc.mk_clause(c.size(), c.begin(), c.is_learned()); append(*c1, status::deleted); } } diff --git a/src/sat/sat_drat.h b/src/sat/sat_drat.h index 35e5a0655..7224da063 100644 --- a/src/sat/sat_drat.h +++ b/src/sat/sat_drat.h @@ -45,6 +45,7 @@ namespace sat { svector m_watched_clauses; typedef svector watch; solver& s; + clause_allocator m_alloc; std::ostream* m_out; std::ostream* m_bout; ptr_vector m_proof; @@ -61,6 +62,8 @@ namespace sat { void append(literal l1, literal l2, status st); void append(clause& c, status st); + bool is_clause(clause& c, literal l1, literal l2, literal l3, status st1, status st2); + friend std::ostream& operator<<(std::ostream & out, status st); status get_status(bool learned) const; @@ -104,6 +107,7 @@ namespace sat { bool contains(unsigned n, literal const* c); bool contains(literal l1, literal l2) { literal lits[2] = {l1, l2}; return contains(2, lits); } bool contains(literal l1, literal l2, literal l3) { literal lits[3] = {l1, l2, l3}; return contains(3, lits); } + bool contains(literal c, justification const& j); void check_model(model const& m); }; diff --git a/src/sat/sat_elim_eqs.cpp b/src/sat/sat_elim_eqs.cpp index bc69c1f5d..7e19bf520 100644 --- a/src/sat/sat_elim_eqs.cpp +++ b/src/sat/sat_elim_eqs.cpp @@ -207,7 +207,7 @@ namespace sat { c.update_approx(); } if (m_solver.m_config.m_drat) { - m_solver.m_drat.add(c, true); + m_solver.m_drat.add(c, true); drat_delete_clause(); } diff --git a/src/sat/sat_probing.cpp b/src/sat/sat_probing.cpp index 5689112d4..e12e78560 100644 --- a/src/sat/sat_probing.cpp +++ b/src/sat/sat_probing.cpp @@ -52,6 +52,9 @@ namespace sat { unsigned tr_sz = s.m_trail.size(); for (unsigned i = old_tr_sz; i < tr_sz; i++) { entry.m_lits.push_back(s.m_trail[i]); + if (s.m_config.m_drat) { + s.m_drat.add(~l, s.m_trail[i], true); + } } } diff --git a/src/sat/sat_simplifier.cpp b/src/sat/sat_simplifier.cpp index 58dab0ff5..86094d7a3 100644 --- a/src/sat/sat_simplifier.cpp +++ b/src/sat/sat_simplifier.cpp @@ -124,9 +124,9 @@ namespace sat { } } - inline void simplifier::remove_clause(clause & c) { + inline void simplifier::remove_clause(clause & c, bool is_unique) { if (!c.was_removed()) { - if (s.m_config.m_drat) { + if (s.m_config.m_drat && is_unique) { s.m_drat.del(c); } for (literal l : c) { @@ -477,7 +477,7 @@ namespace sat { s.set_learned(c1, false); } TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";); - remove_clause(c2); + remove_clause(c2, false); m_num_subsumed++; } else if (!c2.was_removed()) { @@ -577,7 +577,7 @@ namespace sat { if (c1.is_learned() && !c2.is_learned()) s.set_learned(c1, false); TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";); - remove_clause(c2); + remove_clause(c2, false); m_num_subsumed++; } } @@ -662,7 +662,7 @@ namespace sat { for (auto it = cs.mk_iterator(); !it.at_end(); ) { clause & c = it.curr(); it.next(); - remove_clause(c); + remove_clause(c, true); } cs.reset(); } @@ -674,10 +674,12 @@ namespace sat { m_num_elim_lits++; insert_elim_todo(l.var()); if (s.m_config.m_drat && c.contains(l)) { - m_dummy.set(c.size(), c.begin(), c.is_learned()); + unsigned sz = c.size(); c.elim(l); s.m_drat.add(c, true); - s.m_drat.del(*m_dummy.get()); + c.restore(sz); + s.m_drat.del(c); + c.shrink(sz-1); } else { c.elim(l); @@ -690,7 +692,7 @@ namespace sat { if (cleanup_clause(c)) { // clause was satisfied TRACE("elim_lit", tout << "clause was satisfied\n";); - remove_clause(c); + remove_clause(c, true); return; } unsigned sz = c.size(); @@ -710,7 +712,7 @@ namespace sat { c.restore(sz0); s.mk_bin_clause(c[0], c[1], c.is_learned()); m_sub_bin_todo.push_back(bin_clause(c[0], c[1], c.is_learned())); - remove_clause(c); + remove_clause(c, sz0 != sz); break; default: if (s.m_config.m_drat && sz0 != sz) { @@ -888,7 +890,7 @@ namespace sat { if (s.m_trail.size() > m_last_sub_trail_sz) { unsigned sz0 = c.size(); if (cleanup_clause(c)) { - remove_clause(c); + remove_clause(c, true); continue; } unsigned sz = c.size(); @@ -906,7 +908,7 @@ namespace sat { s.mk_bin_clause(c[0], c[1], c.is_learned()); m_sub_bin_todo.push_back(bin_clause(c[0], c[1], c.is_learned())); c.restore(sz0); - remove_clause(c); + remove_clause(c, sz != sz0); continue; default: if (s.m_config.m_drat && sz != sz0) { diff --git a/src/sat/sat_simplifier.h b/src/sat/sat_simplifier.h index 2aa2b4252..895ebdcb5 100644 --- a/src/sat/sat_simplifier.h +++ b/src/sat/sat_simplifier.h @@ -133,7 +133,7 @@ namespace sat { void register_clauses(clause_vector & cs); - void remove_clause(clause & c); + void remove_clause(clause & c, bool is_unique); void set_learned(clause & c); void set_learned(literal l1, literal l2); diff --git a/src/sat/sat_solver.cpp b/src/sat/sat_solver.cpp index 3deb6fc17..4a0397cee 100644 --- a/src/sat/sat_solver.cpp +++ b/src/sat/sat_solver.cpp @@ -33,19 +33,22 @@ Revision History: namespace sat { + static unsigned s_lemma_count = 0; + static bool s_verify_contains = false; + solver::solver(params_ref const & p, reslimit& l): solver_core(l), m_checkpoint_enabled(true), m_config(p), m_par(nullptr), m_cls_allocator_idx(false), + m_drat(*this), m_cleaner(*this), m_simplifier(*this, p), m_scc(*this, p), m_asymm_branch(*this, p), m_probing(*this, p), m_mus(*this), - m_drat(*this), m_inconsistent(false), m_searching(false), m_num_frozen(0), @@ -382,6 +385,9 @@ namespace sat { if (!learned && !at_search_lvl()) m_clauses_to_reinit.push_back(clause_wrapper(l1, l2)); } + if (l1 == literal(29327, false) && l2 == literal(29328, false)) { + std::cout << s_lemma_count << "\n"; + } m_stats.m_mk_bin_clause++; get_wlist(~l1).push_back(watched(l2, learned)); get_wlist(~l2).push_back(watched(l1, learned)); @@ -413,8 +419,6 @@ namespace sat { clause * r = alloc_clause(3, lits, learned); bool reinit = attach_ter_clause(*r); if (reinit && !learned) push_reinit_stack(*r); - if (m_config.m_drat) m_drat.add(*r, learned); - if (learned) m_learned.push_back(r); else @@ -424,6 +428,9 @@ namespace sat { bool solver::attach_ter_clause(clause & c) { bool reinit = false; + if (m_config.m_drat) m_drat.add(c, c.is_learned()); + TRACE("sat", tout << c << "\n";); + SASSERT(!c.was_removed()); m_watches[(~c[0]).index()].push_back(watched(c[1], c[2])); m_watches[(~c[1]).index()].push_back(watched(c[0], c[2])); m_watches[(~c[2]).index()].push_back(watched(c[0], c[1])); @@ -459,8 +466,9 @@ namespace sat { else { m_clauses.push_back(r); } - if (m_config.m_drat) + if (m_config.m_drat) { m_drat.add(*r, learned); + } return r; } @@ -2163,6 +2171,36 @@ namespace sat { IF_VERBOSE(SAT_VB_LVL, verbose_stream() << "(sat-gc :strategy " << st_name << " :deleted " << (sz - new_sz) << ")\n";); } + bool solver::can_delete3(literal l1, literal l2, literal l3) const { + if (value(l1) == l_true && + value(l2) == l_false && + value(l3) == l_false) { + justification const& j = m_justification[l1.var()]; + if (j.is_ternary_clause()) { + watched w1(l2, l3); + watched w2(j.get_literal1(), j.get_literal2()); + return w1 != w2; + } + } + return true; + } + + bool solver::can_delete(clause const & c) const { + if (c.on_reinit_stack()) + return false; + if (c.size() == 3) { + return + can_delete3(c[0],c[1],c[2]) && + can_delete3(c[1],c[0],c[2]) && + can_delete3(c[2],c[0],c[1]); + } + literal l0 = c[0]; + if (value(l0) != l_true) + return true; + justification const & jst = m_justification[l0.var()]; + return !jst.is_clause() || cls_allocator().get_clause(jst.get_clause_offset()) != &c; + } + /** \brief Use gc based on dynamic psm. Clauses are initially frozen. */ @@ -2381,6 +2419,21 @@ namespace sat { } } + s_lemma_count++; + + if (s_lemma_count == 51802) { + disable_trace("sat"); + disable_trace("sat_conflict"); + s_verify_contains = false; + } + + + if (s_lemma_count == 51801) { + enable_trace("sat"); + enable_trace("sat_conflict"); + s_verify_contains = true; + } + m_lemma.reset(); unsigned idx = skip_literals_above_conflict_level(); @@ -2401,6 +2454,9 @@ namespace sat { do { TRACE("sat_conflict_detail", tout << "processing consequent: " << consequent << "\n"; tout << "num_marks: " << num_marks << ", js: " << js << "\n";); + + // VERIFY(!s_verify_contains || !m_config.m_drat || m_drat.contains(consequent, js)); + switch (js.get_kind()) { case justification::NONE: break; @@ -2455,6 +2511,8 @@ namespace sat { idx--; num_marks--; reset_mark(c_var); + + TRACE("sat", display_justification(tout << consequent << " ", js) << "\n";); } while (num_marks > 0); @@ -2467,12 +2525,13 @@ namespace sat { TRACE("sat_lemma", tout << "new lemma size: " << m_lemma.size() << "\n" << m_lemma << "\n";); unsigned new_scope_lvl = 0; + bool sub_min = false, res_min = false; if (!m_lemma.empty()) { if (m_config.m_minimize_lemmas) { - minimize_lemma(); + res_min = minimize_lemma(); reset_lemma_var_marks(); if (m_config.m_dyn_sub_res) - dyn_sub_res(); + sub_min = dyn_sub_res(); TRACE("sat_lemma", tout << "new lemma (after minimization) size: " << m_lemma.size() << "\n" << m_lemma << "\n";); } else @@ -2492,12 +2551,12 @@ namespace sat { m_slow_glue_avg.update(glue); pop_reinit(m_scope_lvl - new_scope_lvl); TRACE("sat_conflict_detail", tout << glue << " " << new_scope_lvl << "\n";); - // unsound: m_asymm_branch.minimize(m_scc, m_lemma); clause * lemma = mk_clause_core(m_lemma.size(), m_lemma.c_ptr(), true); if (lemma) { lemma->set_glue(glue); if (m_par) m_par->share_clause(*this, *lemma); } + TRACE("sat_conflict_detail", tout << new_scope_lvl << "\n";); decay_activity(); updt_phase_counters(); @@ -2844,7 +2903,7 @@ namespace sat { if (m_lvl_set.may_contain(var_lvl)) { mark(var); m_unmark.push_back(var); - m_lemma_min_stack.push_back(var); + m_lemma_min_stack.push_back(antecedent); } else { return false; @@ -2862,11 +2921,12 @@ namespace sat { */ bool solver::implied_by_marked(literal lit) { m_lemma_min_stack.reset(); // avoid recursive function - m_lemma_min_stack.push_back(lit.var()); + m_lemma_min_stack.push_back(lit); unsigned old_size = m_unmark.size(); while (!m_lemma_min_stack.empty()) { - bool_var var = m_lemma_min_stack.back(); + lit = m_lemma_min_stack.back(); + bool_var var = lit.var(); m_lemma_min_stack.pop_back(); justification const& js = m_justification[var]; switch(js.get_kind()) { @@ -2928,6 +2988,8 @@ namespace sat { UNREACHABLE(); break; } + TRACE("sat_conflict", + display_justification(tout << var << " ",js) << "\n";); } return true; } @@ -2958,7 +3020,7 @@ namespace sat { literals that are implied by other literals in m_lemma and/or literals assigned at level 0. */ - void solver::minimize_lemma() { + bool solver::minimize_lemma() { SASSERT(!m_lemma.empty()); SASSERT(m_unmark.empty()); updt_lemma_lvl_set(); @@ -2982,6 +3044,7 @@ namespace sat { reset_unmark(0); m_lemma.shrink(j); m_stats.m_minimized_lits += sz - j; + return j < sz; } /** @@ -3055,7 +3118,7 @@ namespace sat { \brief Apply dynamic subsumption resolution to new lemma. Only binary and ternary clauses are used. */ - void solver::dyn_sub_res() { + bool solver::dyn_sub_res() { unsigned sz = m_lemma.size(); for (unsigned i = 0; i < sz; i++) { mark_lit(m_lemma[i]); @@ -3168,6 +3231,7 @@ namespace sat { SASSERT(j >= 1); m_lemma.shrink(j); + return j < sz; } diff --git a/src/sat/sat_solver.h b/src/sat/sat_solver.h index c000ccb79..47e226cc4 100644 --- a/src/sat/sat_solver.h +++ b/src/sat/sat_solver.h @@ -85,9 +85,10 @@ namespace sat { stats m_stats; scoped_ptr m_ext; parallel* m_par; - random_gen m_rand; + drat m_drat; // DRAT for generating proofs clause_allocator m_cls_allocator[2]; bool m_cls_allocator_idx; + random_gen m_rand; cleaner m_cleaner; model m_model; model_converter m_mc; @@ -97,7 +98,6 @@ namespace sat { asymm_branch m_asymm_branch; probing m_probing; mus m_mus; // MUS for minimal core extraction - drat m_drat; // DRAT for generating proofs bool m_inconsistent; bool m_searching; // A conflict is usually a single justification. That is, a justification @@ -461,17 +461,8 @@ namespace sat { void gc_dyn_psm(); bool activate_frozen_clause(clause & c); unsigned psm(clause const & c) const; - bool can_delete(clause const & c) const { - if (c.on_reinit_stack()) - return false; - if (c.size() == 3) - return true; // not needed to justify anything. - literal l0 = c[0]; - if (value(l0) != l_true) - return true; - justification const & jst = m_justification[l0.var()]; - return !jst.is_clause() || cls_allocator().get_clause(jst.get_clause_offset()) != &c; - } + bool can_delete(clause const & c) const; + bool can_delete3(literal l1, literal l2, literal l3) const; clause& get_clause(watch_list::iterator it) const { SASSERT(it->get_kind() == watched::CLAUSE); @@ -522,14 +513,14 @@ namespace sat { typedef approx_set_tpl level_approx_set; bool_var_vector m_unmark; level_approx_set m_lvl_set; - bool_var_vector m_lemma_min_stack; + literal_vector m_lemma_min_stack; bool process_antecedent_for_minimization(literal antecedent); bool implied_by_marked(literal lit); void reset_unmark(unsigned old_size); void updt_lemma_lvl_set(); - void minimize_lemma(); void reset_lemma_var_marks(); - void dyn_sub_res(); + bool minimize_lemma(); + bool dyn_sub_res(); // ----------------------- // diff --git a/src/sat/sat_watched.cpp b/src/sat/sat_watched.cpp index 966bd8325..8811a4e74 100644 --- a/src/sat/sat_watched.cpp +++ b/src/sat/sat_watched.cpp @@ -86,7 +86,15 @@ namespace sat { } } wlist.set_end(it2); - //VERIFY(found); +#if 0 + VERIFY(found); + for (watched const& w2 : wlist) { + if (w2 == w) { + std::cout << l1 << " " << l2 << "\n"; + } + //VERIFY(w2 != w); + } +#endif } void conflict_cleanup(watch_list::iterator it, watch_list::iterator it2, watch_list& wlist) { diff --git a/src/sat/tactic/sat_tactic.cpp b/src/sat/tactic/sat_tactic.cpp index 2739932e6..b2137795b 100644 --- a/src/sat/tactic/sat_tactic.cpp +++ b/src/sat/tactic/sat_tactic.cpp @@ -200,6 +200,7 @@ public: throw tactic_exception(ex.msg()); } catch (z3_exception& ex) { + (void)ex; TRACE("sat", tout << ex.msg() << "\n";); throw; }