3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-10-10 17:58:06 +00:00

prepare for theory plugins

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-09-02 10:42:07 -07:00
parent 141edef0d6
commit 116390833b
27 changed files with 492 additions and 336 deletions

View file

@ -213,7 +213,7 @@ namespace sat {
if (c->glue() <= 2 || (c->size() <= 40 && c->glue() <= 8) || copy_learned) {
buffer.reset();
for (literal l : *c) buffer.push_back(l);
clause* c1 = mk_clause_core(buffer.size(), buffer.c_ptr(), true);
clause* c1 = mk_clause_core(buffer.size(), buffer.c_ptr(), sat::status::redundant());
if (c1) {
++num_learned;
c1->set_glue(c->glue());
@ -305,7 +305,7 @@ namespace sat {
}
clause* solver::mk_clause(unsigned num_lits, literal * lits, bool learned) {
clause* solver::mk_clause(unsigned num_lits, literal * lits, sat::status st) {
m_model_is_current = false;
DEBUG_CODE({
for (unsigned i = 0; i < num_lits; i++) {
@ -315,24 +315,24 @@ namespace sat {
});
if (m_user_scope_literals.empty()) {
return mk_clause_core(num_lits, lits, learned);
return mk_clause_core(num_lits, lits, st);
}
else {
m_aux_literals.reset();
m_aux_literals.append(num_lits, lits);
m_aux_literals.append(m_user_scope_literals);
return mk_clause_core(m_aux_literals.size(), m_aux_literals.c_ptr(), learned);
return mk_clause_core(m_aux_literals.size(), m_aux_literals.c_ptr(), st);
}
}
clause* solver::mk_clause(literal l1, literal l2, bool learned) {
clause* solver::mk_clause(literal l1, literal l2, sat::status st) {
literal ls[2] = { l1, l2 };
return mk_clause(2, ls, learned);
return mk_clause(2, ls, st);
}
clause* solver::mk_clause(literal l1, literal l2, literal l3, bool learned) {
clause* solver::mk_clause(literal l1, literal l2, literal l3, sat::status st) {
literal ls[3] = { l1, l2, l3 };
return mk_clause(3, ls, learned);
return mk_clause(3, ls, st);
}
void solver::del_clause(clause& c) {
@ -350,9 +350,10 @@ namespace sat {
m_stats.m_del_clause++;
}
clause * solver::mk_clause_core(unsigned num_lits, literal * lits, bool learned) {
TRACE("sat", tout << "mk_clause: " << mk_lits_pp(num_lits, lits) << (learned?" learned":" aux") << "\n";);
if (!learned) {
clause * solver::mk_clause_core(unsigned num_lits, literal * lits, sat::status st) {
bool redundant = st.is_redundant();
TRACE("sat", tout << "mk_clause: " << mk_lits_pp(num_lits, lits) << (redundant?" learned":" aux") << "\n";);
if (!redundant) {
unsigned old_sz = num_lits;
bool keep = simplify_clause(num_lits, lits);
TRACE("sat_mk_clause", tout << "mk_clause (after simp), keep: " << keep << "\n" << mk_lits_pp(num_lits, lits) << "\n";);
@ -360,17 +361,17 @@ namespace sat {
return nullptr; // clause is equivalent to true.
}
// if an input clause is simplified, then log the simplified version as learned
if (!learned && old_sz > num_lits && m_config.m_drat) {
if (old_sz > num_lits && m_config.m_drat) {
m_lemma.reset();
m_lemma.append(num_lits, lits);
m_drat.add(m_lemma);
m_drat.add(m_lemma, st);
}
++m_stats.m_non_learned_generation;
if (!m_searching) {
m_mc.add_clause(num_lits, lits);
}
}
}
switch (num_lits) {
case 0:
set_conflict();
@ -379,55 +380,56 @@ namespace sat {
assign_unit(lits[0]);
return nullptr;
case 2:
mk_bin_clause(lits[0], lits[1], learned);
if (learned && m_par) m_par->share_clause(*this, lits[0], lits[1]);
mk_bin_clause(lits[0], lits[1], st);
if (redundant && m_par) m_par->share_clause(*this, lits[0], lits[1]);
return nullptr;
case 3:
if (ENABLE_TERNARY) {
return mk_ter_clause(lits, learned);
return mk_ter_clause(lits, st);
}
default:
return mk_nary_clause(num_lits, lits, learned);
return mk_nary_clause(num_lits, lits, st);
}
}
void solver::mk_bin_clause(literal l1, literal l2, bool learned) {
void solver::mk_bin_clause(literal l1, literal l2, sat::status st) {
bool redundant = st.is_redundant();
m_touched[l1.var()] = m_touch_index;
m_touched[l2.var()] = m_touch_index;
if (learned && find_binary_watch(get_wlist(~l1), ~l2) && value(l1) == l_undef) {
if (redundant && find_binary_watch(get_wlist(~l1), ~l2) && value(l1) == l_undef) {
assign_unit(l1);
return;
}
if (learned && find_binary_watch(get_wlist(~l2), ~l1) && value(l2) == l_undef) {
if (redundant && find_binary_watch(get_wlist(~l2), ~l1) && value(l2) == l_undef) {
assign_unit(l2);
return;
}
watched* w0 = learned ? find_binary_watch(get_wlist(~l1), l2) : nullptr;
watched* w0 = redundant ? find_binary_watch(get_wlist(~l1), l2) : nullptr;
if (w0) {
TRACE("sat", tout << "found binary " << l1 << " " << l2 << "\n";);
if (w0->is_learned() && !learned) {
if (w0->is_learned() && !redundant) {
w0->set_learned(false);
w0 = find_binary_watch(get_wlist(~l2), l1);
VERIFY(w0);
w0->set_learned(false);
}
if (propagate_bin_clause(l1, l2) && !learned && !at_base_lvl() && !at_search_lvl()) {
if (propagate_bin_clause(l1, l2) && !redundant && !at_base_lvl() && !at_search_lvl()) {
m_clauses_to_reinit.push_back(clause_wrapper(l1, l2));
}
return;
}
if (m_config.m_drat)
m_drat.add(l1, l2, learned);
m_drat.add(l1, l2, st);
if (propagate_bin_clause(l1, l2)) {
if (at_base_lvl())
return;
if (!learned && !at_search_lvl())
if (!redundant && !at_search_lvl())
m_clauses_to_reinit.push_back(clause_wrapper(l1, l2));
}
m_stats.m_mk_bin_clause++;
get_wlist(~l1).push_back(watched(l2, learned));
get_wlist(~l2).push_back(watched(l1, learned));
get_wlist(~l1).push_back(watched(l2, redundant));
get_wlist(~l2).push_back(watched(l1, redundant));
}
bool solver::propagate_bin_clause(literal l1, literal l2) {
@ -451,13 +453,13 @@ namespace sat {
}
clause * solver::mk_ter_clause(literal * lits, bool learned) {
clause * solver::mk_ter_clause(literal * lits, sat::status st) {
VERIFY(ENABLE_TERNARY);
m_stats.m_mk_ter_clause++;
clause * r = alloc_clause(3, lits, learned);
clause * r = alloc_clause(3, lits, st.is_redundant());
bool reinit = attach_ter_clause(*r);
if (reinit && !learned) push_reinit_stack(*r);
if (learned)
if (reinit && !st.is_redundant()) push_reinit_stack(*r);
if (st.is_redundant())
m_learned.push_back(r);
else
m_clauses.push_back(r);
@ -470,7 +472,7 @@ namespace sat {
bool solver::attach_ter_clause(clause & c) {
VERIFY(ENABLE_TERNARY);
bool reinit = false;
if (m_config.m_drat) m_drat.add(c, c.is_learned());
if (m_config.m_drat) m_drat.add(c, c.is_learned() ? status::redundant() : status::asserted());
TRACE("sat_verbose", tout << c << "\n";);
SASSERT(!c.was_removed());
m_watches[(~c[0]).index()].push_back(watched(c[1], c[2]));
@ -496,20 +498,20 @@ namespace sat {
return reinit;
}
clause * solver::mk_nary_clause(unsigned num_lits, literal * lits, bool learned) {
clause * solver::mk_nary_clause(unsigned num_lits, literal * lits, sat::status st) {
m_stats.m_mk_clause++;
clause * r = alloc_clause(num_lits, lits, learned);
SASSERT(!learned || r->is_learned());
clause * r = alloc_clause(num_lits, lits, st.is_redundant());
SASSERT(!st.is_learned() || r->is_learned());
bool reinit = attach_nary_clause(*r);
if (reinit && !learned) push_reinit_stack(*r);
if (learned) {
if (reinit && !st.is_redundant()) push_reinit_stack(*r);
if (st.is_redundant()) {
m_learned.push_back(r);
}
else {
m_clauses.push_back(r);
}
if (m_config.m_drat) {
m_drat.add(*r, learned);
m_drat.add(*r, st);
}
for (literal l : *r) {
m_touched[l.var()] = m_touch_index;
@ -571,15 +573,15 @@ namespace sat {
reinit = attach_nary_clause(c);
}
void solver::set_learned(clause& c, bool learned) {
if (c.is_learned() != learned)
c.set_learned(learned);
void solver::set_learned(clause& c, bool redundant) {
if (c.is_learned() != redundant)
c.set_learned(redundant);
}
void solver::set_learned1(literal l1, literal l2, bool learned) {
void solver::set_learned1(literal l1, literal l2, bool redundant) {
for (watched& w : get_wlist(~l1)) {
if (w.is_binary_clause() && l2 == w.get_literal() && !w.is_learned()) {
w.set_learned(learned);
w.set_learned(redundant);
break;
}
}
@ -594,7 +596,7 @@ namespace sat {
m_touched[l.var()] = m_touch_index;
}
if (m_config.m_drat) {
m_drat.add(c, true);
m_drat.add(c, status::redundant());
c.restore(old_sz);
m_drat.del(c);
c.shrink(new_sz);
@ -687,9 +689,9 @@ namespace sat {
}
void solver::set_learned(literal l1, literal l2, bool learned) {
set_learned1(l1, l2, learned);
set_learned1(l2, l1, learned);
void solver::set_learned(literal l1, literal l2, bool redundant) {
set_learned1(l1, l2, redundant);
set_learned1(l2, l1, redundant);
}
/**
@ -809,9 +811,9 @@ namespace sat {
return simplify_clause_core<false>(num_lits, lits);
}
void solver::detach_bin_clause(literal l1, literal l2, bool learned) {
get_wlist(~l1).erase(watched(l2, learned));
get_wlist(~l2).erase(watched(l1, learned));
void solver::detach_bin_clause(literal l1, literal l2, bool redundant) {
get_wlist(~l1).erase(watched(l2, redundant));
get_wlist(~l2).erase(watched(l1, redundant));
if (m_config.m_drat) m_drat.del(l1, l2);
}
@ -2727,7 +2729,7 @@ namespace sat {
if (m_lemma.empty()) {
pop_reinit(m_scope_lvl);
mk_clause_core(0, nullptr, true);
mk_clause_core(0, nullptr, sat::status::redundant());
return;
}
@ -2777,7 +2779,7 @@ namespace sat {
++m_stats.m_backtracks;
pop_reinit(m_scope_lvl - backtrack_lvl + 1);
}
clause * lemma = mk_clause_core(m_lemma.size(), m_lemma.c_ptr(), true);
clause * lemma = mk_clause_core(m_lemma.size(), m_lemma.c_ptr(), sat::status::redundant());
if (lemma) {
lemma->set_glue(glue);
}
@ -3795,9 +3797,9 @@ namespace sat {
}
}
bool_var solver::max_var(bool learned, bool_var v) {
bool_var solver::max_var(bool redundant, bool_var v) {
m_user_bin_clauses.reset();
collect_bin_clauses(m_user_bin_clauses, learned, false);
collect_bin_clauses(m_user_bin_clauses, redundant, false);
for (unsigned i = 0; i < m_user_bin_clauses.size(); ++i) {
literal l1 = m_user_bin_clauses[i].first;
literal l2 = m_user_bin_clauses[i].second;
@ -3977,8 +3979,8 @@ namespace sat {
// Iterators
//
// -----------------------
void solver::collect_bin_clauses(svector<bin_clause> & r, bool learned, bool learned_only) const {
SASSERT(learned || !learned_only);
void solver::collect_bin_clauses(svector<bin_clause> & r, bool redundant, bool learned_only) const {
SASSERT(redundant || !learned_only);
unsigned sz = m_watches.size();
for (unsigned l_idx = 0; l_idx < sz; l_idx++) {
literal l = to_literal(l_idx);
@ -3986,9 +3988,9 @@ namespace sat {
for (watched const& w : m_watches[l_idx]) {
if (!w.is_binary_clause())
continue;
if (!learned && w.is_learned())
if (!redundant && w.is_learned())
continue;
else if (learned && learned_only && !w.is_learned())
else if (redundant && learned_only && !w.is_learned())
continue;
literal l2 = w.get_literal();
if (l.index() > l2.index())
@ -4121,14 +4123,14 @@ namespace sat {
return num_cls + m_clauses.size() + m_learned.size();
}
void solver::num_binary(unsigned& given, unsigned& learned) const {
given = learned = 0;
void solver::num_binary(unsigned& given, unsigned& redundant) const {
given = redundant = 0;
unsigned l_idx = 0;
for (auto const& wl : m_watches) {
literal l = ~to_literal(l_idx++);
for (auto const& w : wl) {
if (w.is_binary_clause() && l.index() < w.get_literal().index()) {
if (w.is_learned()) ++learned; else ++given;
if (w.is_learned()) ++redundant; else ++given;
}
}
}
@ -4288,10 +4290,10 @@ namespace sat {
return false;
}
void solver::simplify(bool learned) {
void solver::simplify(bool redundant) {
if (!at_base_lvl() || inconsistent())
return;
m_simplifier(learned);
m_simplifier(redundant);
m_simplifier.finalize();
if (m_ext)
m_ext->clauses_modifed();
@ -4921,10 +4923,10 @@ namespace sat {
}
void mk_stat::display(std::ostream & out) const {
unsigned given, learned;
m_solver.num_binary(given, learned);
unsigned given, redundant;
m_solver.num_binary(given, redundant);
out << " " << std::setw(5) << m_solver.m_clauses.size() + given << "/" << given;
out << " " << std::setw(5) << (m_solver.m_learned.size() + learned - m_solver.m_num_frozen) << "/" << learned;
out << " " << std::setw(5) << (m_solver.m_learned.size() + redundant - m_solver.m_num_frozen) << "/" << redundant;
out << " " << std::setw(3) << m_solver.init_trail_size();
out << " " << std::setw(7) << m_solver.m_stats.m_gc_clause << " ";
out << " " << std::setw(7) << mem_stat();