mirror of
https://github.com/Z3Prover/z3
synced 2025-08-06 19:21:22 +00:00
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 <nbjorner@microsoft.com>
This commit is contained in:
parent
598fc810b5
commit
4c799c144a
11 changed files with 201 additions and 71 deletions
|
@ -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<unsigned>(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<premise> 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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue