3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

fix learned annotation on ternary

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-01-30 03:31:28 -08:00
parent 5a2b072ddf
commit ede12553f2
6 changed files with 56 additions and 19 deletions

View file

@ -65,8 +65,7 @@ namespace sat {
literal & operator[](unsigned idx) { SASSERT(idx < m_size); return m_lits[idx]; } literal & operator[](unsigned idx) { SASSERT(idx < m_size); return m_lits[idx]; }
literal const & operator[](unsigned idx) const { SASSERT(idx < m_size); return m_lits[idx]; } literal const & operator[](unsigned idx) const { SASSERT(idx < m_size); return m_lits[idx]; }
bool is_learned() const { return m_learned; } bool is_learned() const { return m_learned; }
void set_learned() { SASSERT(!is_learned()); m_learned = true; } void set_learned(bool l) { SASSERT(is_learned() != l); m_learned = l; }
void unset_learned() { SASSERT(is_learned()); m_learned = false; }
void shrink(unsigned num_lits) { SASSERT(num_lits <= m_size); if (num_lits < m_size) { m_size = num_lits; mark_strengthened(); } } void shrink(unsigned num_lits) { SASSERT(num_lits <= m_size); if (num_lits < m_size) { m_size = num_lits; mark_strengthened(); } }
bool strengthened() const { return m_strengthened; } bool strengthened() const { return m_strengthened; }
void mark_strengthened() { m_strengthened = true; update_approx(); } void mark_strengthened() { m_strengthened = true; update_approx(); }

View file

@ -151,7 +151,7 @@ namespace sat {
inline void simplifier::block_clause(clause & c) { inline void simplifier::block_clause(clause & c) {
if (m_retain_blocked_clauses) { if (m_retain_blocked_clauses) {
m_need_cleanup = true; m_need_cleanup = true;
c.set_learned(); s.set_learned(c, true);
m_use_list.block(c); m_use_list.block(c);
} }
else { else {
@ -161,7 +161,7 @@ namespace sat {
} }
inline void simplifier::unblock_clause(clause & c) { inline void simplifier::unblock_clause(clause & c) {
c.unset_learned(); s.set_learned(c, false);
m_use_list.unblock(c); m_use_list.unblock(c);
} }
@ -499,7 +499,7 @@ namespace sat {
if (!c2.was_removed() && *l_it == null_literal) { if (!c2.was_removed() && *l_it == null_literal) {
// c2 was subsumed // c2 was subsumed
if (c1.is_learned() && !c2.is_learned()) if (c1.is_learned() && !c2.is_learned())
c1.unset_learned(); s.set_learned(c1, false);
TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";); TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";);
remove_clause(c2); remove_clause(c2);
m_num_subsumed++; m_num_subsumed++;
@ -599,7 +599,7 @@ namespace sat {
clause & c2 = *cp; clause & c2 = *cp;
// c2 was subsumed // c2 was subsumed
if (c1.is_learned() && !c2.is_learned()) if (c1.is_learned() && !c2.is_learned())
c1.unset_learned(); s.set_learned(c1, false);
TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";); TRACE("subsumption", tout << c1 << " subsumed " << c2 << "\n";);
remove_clause(c2); remove_clause(c2);
m_num_subsumed++; m_num_subsumed++;
@ -759,7 +759,7 @@ namespace sat {
SASSERT(wlist[j] == w); SASSERT(wlist[j] == w);
TRACE("set_not_learned_bug", TRACE("set_not_learned_bug",
tout << "marking as not learned: " << l2 << " " << wlist[j].is_learned() << "\n";); tout << "marking as not learned: " << l2 << " " << wlist[j].is_learned() << "\n";);
wlist[j].set_not_learned(); wlist[j].set_learned(false);
mark_as_not_learned_core(get_wlist(~l2), l); mark_as_not_learned_core(get_wlist(~l2), l);
} }
if (s.inconsistent()) if (s.inconsistent())
@ -776,7 +776,7 @@ namespace sat {
void simplifier::mark_as_not_learned_core(watch_list & wlist, literal l2) { void simplifier::mark_as_not_learned_core(watch_list & wlist, literal l2) {
for (watched & w : wlist) { for (watched & w : wlist) {
if (w.is_binary_clause() && w.get_literal() == l2 && w.is_learned()) { if (w.is_binary_clause() && w.get_literal() == l2 && w.is_learned()) {
w.set_not_learned(); w.set_learned(false);
return; return;
} }
} }
@ -1793,7 +1793,7 @@ namespace sat {
w = find_binary_watch(wlist1, l2); w = find_binary_watch(wlist1, l2);
if (w) { if (w) {
if (w->is_learned()) if (w->is_learned())
w->set_not_learned(); w->set_learned(false);
} }
else { else {
wlist1.push_back(watched(l2, false)); wlist1.push_back(watched(l2, false));
@ -1802,7 +1802,7 @@ namespace sat {
w = find_binary_watch(wlist2, l1); w = find_binary_watch(wlist2, l1);
if (w) { if (w) {
if (w->is_learned()) if (w->is_learned())
w->set_not_learned(); w->set_learned(false);
} }
else { else {
wlist2.push_back(watched(l1, false)); wlist2.push_back(watched(l1, false));

View file

@ -336,13 +336,13 @@ namespace sat {
watched* w0 = find_binary_watch(get_wlist(~l1), l2); watched* w0 = find_binary_watch(get_wlist(~l1), l2);
if (w0) { if (w0) {
if (w0->is_learned() && !learned) { if (w0->is_learned() && !learned) {
w0->set_not_learned(); w0->set_learned(false);
} }
w0 = find_binary_watch(get_wlist(~l2), l1); w0 = find_binary_watch(get_wlist(~l2), l1);
} }
if (w0) { if (w0) {
if (w0->is_learned() && !learned) { if (w0->is_learned() && !learned) {
w0->set_not_learned(); w0->set_learned(false);
} }
return; return;
} }
@ -481,6 +481,19 @@ namespace sat {
reinit = attach_nary_clause(c); reinit = attach_nary_clause(c);
} }
void solver::set_learned(clause& c, bool learned) {
if (c.is_learned() == learned)
return;
if (c.size() == 3) {
set_ternary_learned(get_wlist(~c[0]), c[1], c[2], learned);
set_ternary_learned(get_wlist(~c[1]), c[0], c[2], learned);
set_ternary_learned(get_wlist(~c[2]), c[0], c[1], learned);
}
c.set_learned(learned);
}
/** /**
\brief Select a watch literal starting the search at the given position. \brief Select a watch literal starting the search at the given position.
This method is only used for clauses created during the search. This method is only used for clauses created during the search.

View file

@ -233,6 +233,7 @@ namespace sat {
bool attach_nary_clause(clause & c); bool attach_nary_clause(clause & c);
void attach_clause(clause & c, bool & reinit); void attach_clause(clause & c, bool & reinit);
void attach_clause(clause & c) { bool reinit; attach_clause(c, reinit); } void attach_clause(clause & c) { bool reinit; attach_clause(c, reinit); }
void set_learned(clause& c, bool learned);
class scoped_disable_checkpoint { class scoped_disable_checkpoint {
solver& s; solver& s;
public: public:
@ -611,7 +612,7 @@ namespace sat {
clause * const * end_learned() const { return m_learned.end(); } clause * const * end_learned() const { return m_learned.end(); }
clause_vector const& learned() const { return m_learned; } clause_vector const& learned() const { return m_learned; }
clause_vector const& clauses() const { return m_clauses; } clause_vector const& clauses() const { return m_clauses; }
void collect_bin_clauses(svector<bin_clause> & r, bool learned, bool learned_only = false) const; void collect_bin_clauses(svector<bin_clause> & r, bool learned, bool learned_only = false) const;
// ----------------------- // -----------------------
// //

View file

@ -52,7 +52,7 @@ namespace sat {
} }
return nullptr; return nullptr;
} }
void erase_binary_watch(watch_list& wlist, literal l) { void erase_binary_watch(watch_list& wlist, literal l) {
watch_list::iterator it = wlist.begin(), end = wlist.end(); watch_list::iterator it = wlist.begin(), end = wlist.end();
watch_list::iterator it2 = it; watch_list::iterator it2 = it;
@ -70,6 +70,30 @@ namespace sat {
VERIFY(found); VERIFY(found);
} }
void erase_ternary_watch(watch_list& wlist, literal l1, literal l2) {
watch_list::iterator it = wlist.begin(), end = wlist.end();
watch_list::iterator it2 = it;
bool found = false;
for (; it != end; ++it) {
if (it->is_ternary_clause() && it->get_literal1() == l1 && it->get_literal2() == l2) {
found = true;
continue;
}
*it2 = *it;
++it2;
}
wlist.set_end(it2);
VERIFY(found);
}
void set_ternary_learned(watch_list& wlist, literal l1, literal l2, bool learned) {
for (watched& w : wlist) {
if (w.is_ternary_clause() && w.get_literal1() == l1 && w.get_literal2() == l2) {
w.set_learned(learned);
}
}
}
void conflict_cleanup(watch_list::iterator it, watch_list::iterator it2, watch_list& wlist) { void conflict_cleanup(watch_list::iterator it, watch_list::iterator it2, watch_list& wlist) {
watch_list::iterator end = wlist.end(); watch_list::iterator end = wlist.end();
for (; it != end; ++it, ++it2) for (; it != end; ++it, ++it2)

View file

@ -33,7 +33,7 @@ namespace sat {
For binary clauses: we use a bit to store whether the binary clause was learned or not. For binary clauses: we use a bit to store whether the binary clause was learned or not.
Remark: there is not Clause object for binary clauses. Remark: there are no clause objects for binary clauses.
*/ */
class watched { class watched {
public: public:
@ -87,13 +87,12 @@ namespace sat {
bool is_binary_clause() const { return get_kind() == BINARY; } bool is_binary_clause() const { return get_kind() == BINARY; }
literal get_literal() const { SASSERT(is_binary_clause()); return to_literal(static_cast<unsigned>(m_val1)); } literal get_literal() const { SASSERT(is_binary_clause()); return to_literal(static_cast<unsigned>(m_val1)); }
void set_literal(literal l) { SASSERT(is_binary_clause()); m_val1 = l.to_uint(); } void set_literal(literal l) { SASSERT(is_binary_clause()); m_val1 = l.to_uint(); }
bool is_learned() const { SASSERT(is_binary_clause()); return (m_val2 >> 2) == 1; } bool is_learned() const { SASSERT(is_binary_clause() || is_ternary_clause()); return ((m_val2 >> 2) & 1) == 1; }
bool is_binary_learned_clause() const { return is_binary_clause() && is_learned(); } bool is_binary_learned_clause() const { return is_binary_clause() && is_learned(); }
bool is_binary_non_learned_clause() const { return is_binary_clause() && !is_learned(); } bool is_binary_non_learned_clause() const { return is_binary_clause() && !is_learned(); }
void set_not_learned() { SASSERT(is_learned()); m_val2 &= 0x3; SASSERT(!is_learned()); } void set_learned(bool l) { SASSERT(is_learned() != l); if (l) m_val2 |= 4; else m_val2 &= 3; SASSERT(is_learned() == l); }
void set_learned() { SASSERT(!is_learned()); m_val2 |= 0x4; SASSERT(is_learned()); }
bool is_ternary_clause() const { return get_kind() == TERNARY; } bool is_ternary_clause() const { return get_kind() == TERNARY; }
literal get_literal1() const { SASSERT(is_ternary_clause()); return to_literal(static_cast<unsigned>(m_val1)); } literal get_literal1() const { SASSERT(is_ternary_clause()); return to_literal(static_cast<unsigned>(m_val1)); }
@ -136,7 +135,8 @@ namespace sat {
watched* find_binary_watch(watch_list & wlist, literal l); watched* find_binary_watch(watch_list & wlist, literal l);
watched const* find_binary_watch(watch_list const & wlist, literal l); watched const* find_binary_watch(watch_list const & wlist, literal l);
bool erase_clause_watch(watch_list & wlist, clause_offset c); bool erase_clause_watch(watch_list & wlist, clause_offset c);
inline void erase_ternary_watch(watch_list & wlist, literal l1, literal l2) { wlist.erase(watched(l1, l2, true)); wlist.erase(watched(l1, l2, false)); } void erase_ternary_watch(watch_list & wlist, literal l1, literal l2);
void set_ternary_learned(watch_list& wlist, literal l1, literal l2, bool learned);
class clause_allocator; class clause_allocator;
std::ostream& display_watch_list(std::ostream & out, clause_allocator const & ca, watch_list const & wlist); std::ostream& display_watch_list(std::ostream & out, clause_allocator const & ca, watch_list const & wlist);