3
0
Fork 0
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:
Nikolaj Bjorner 2019-02-22 11:14:20 +01:00
parent 598fc810b5
commit 4c799c144a
11 changed files with 201 additions and 71 deletions

View file

@ -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);
}
}