mirror of
https://github.com/Z3Prover/z3
synced 2025-04-07 18:05:21 +00:00
working on relevant
This commit is contained in:
parent
9527471967
commit
28bce8f09c
|
@ -446,8 +446,8 @@ namespace euf {
|
|||
r2->inc_class_size(r1->class_size());
|
||||
merge_th_eq(r1, r2);
|
||||
reinsert_parents(r1, r2);
|
||||
if (m_on_merge)
|
||||
m_on_merge(r2, r1);
|
||||
for (auto& cb : m_on_merge)
|
||||
cb(r2, r1);
|
||||
}
|
||||
|
||||
void egraph::remove_parents(enode* r1, enode* r2) {
|
||||
|
|
|
@ -32,6 +32,7 @@ Notes:
|
|||
#include "ast/euf/euf_enode.h"
|
||||
#include "ast/euf/euf_etable.h"
|
||||
#include "ast/ast_ll_pp.h"
|
||||
#include <vector>
|
||||
|
||||
namespace euf {
|
||||
|
||||
|
@ -181,7 +182,7 @@ namespace euf {
|
|||
enode_vector m_todo;
|
||||
stats m_stats;
|
||||
bool m_uses_congruence = false;
|
||||
std::function<void(enode*,enode*)> m_on_merge;
|
||||
std::vector<std::function<void(enode*,enode*)>> m_on_merge;
|
||||
std::function<void(enode*)> m_on_make;
|
||||
std::function<void(expr*,expr*,expr*)> m_used_eq;
|
||||
std::function<void(app*,app*)> m_used_cc;
|
||||
|
@ -293,7 +294,7 @@ namespace euf {
|
|||
void set_value(enode* n, lbool value);
|
||||
void set_bool_var(enode* n, unsigned v) { n->set_bool_var(v); }
|
||||
|
||||
void set_on_merge(std::function<void(enode* root,enode* other)>& on_merge) { m_on_merge = on_merge; }
|
||||
void set_on_merge(std::function<void(enode* root,enode* other)>& on_merge) { m_on_merge.push_back(on_merge); }
|
||||
void set_on_make(std::function<void(enode* n)>& on_make) { m_on_make = on_make; }
|
||||
void set_used_eq(std::function<void(expr*,expr*,expr*)>& used_eq) { m_used_eq = used_eq; }
|
||||
void set_used_cc(std::function<void(app*,app*)>& used_cc) { m_used_cc = used_cc; }
|
||||
|
|
|
@ -23,10 +23,10 @@ Author:
|
|||
namespace euf {
|
||||
|
||||
void solver::add_auto_relevant(sat::literal lit) {
|
||||
#if NEW_RELEVANCY
|
||||
m_relevancy.mark_relevant(lit);
|
||||
return;
|
||||
#endif
|
||||
if (m_relevancy.enabled()) {
|
||||
m_relevancy.mark_relevant(lit);
|
||||
return;
|
||||
}
|
||||
if (!relevancy_enabled())
|
||||
return;
|
||||
for (; m_auto_relevant_scopes > 0; --m_auto_relevant_scopes)
|
||||
|
@ -37,10 +37,10 @@ namespace euf {
|
|||
}
|
||||
|
||||
void solver::pop_relevant(unsigned n) {
|
||||
#if NEW_RELEVANCY
|
||||
m_relevancy.pop(n);
|
||||
return;
|
||||
#endif
|
||||
if (m_relevancy.enabled()) {
|
||||
m_relevancy.pop(n);
|
||||
return;
|
||||
}
|
||||
if (m_auto_relevant_scopes >= n) {
|
||||
m_auto_relevant_scopes -= n;
|
||||
return;
|
||||
|
@ -54,31 +54,28 @@ namespace euf {
|
|||
}
|
||||
|
||||
void solver::push_relevant() {
|
||||
#if NEW_RELEVANCY
|
||||
m_relevancy.push();
|
||||
return;
|
||||
#endif
|
||||
if (m_relevancy.enabled()) {
|
||||
m_relevancy.push();
|
||||
return;
|
||||
}
|
||||
++m_auto_relevant_scopes;
|
||||
}
|
||||
|
||||
bool solver::is_relevant(expr* e) const {
|
||||
#if NEW_RELEVANCY
|
||||
return m_relevancy.is_relevant(e);
|
||||
#endif
|
||||
if (m_relevancy.enabled())
|
||||
return m_relevancy.is_relevant(e);
|
||||
return m_relevant_expr_ids.get(e->get_id(), true);
|
||||
}
|
||||
|
||||
bool solver::is_relevant(enode* n) const {
|
||||
#if NEW_RELEVANCY
|
||||
return m_relevancy.is_relevant(n);
|
||||
#endif
|
||||
if (m_relevancy.enabled())
|
||||
return m_relevancy.is_relevant(n);
|
||||
return m_relevant_expr_ids.get(n->get_expr_id(), true);
|
||||
}
|
||||
|
||||
void solver::ensure_dual_solver() {
|
||||
#if NEW_RELEVANCY
|
||||
return;
|
||||
#endif
|
||||
if (m_relevancy.enabled())
|
||||
return;
|
||||
if (m_dual_solver)
|
||||
return;
|
||||
m_dual_solver = alloc(sat::dual_solver, s(), s().rlimit());
|
||||
|
@ -93,10 +90,10 @@ namespace euf {
|
|||
* not tracked.
|
||||
*/
|
||||
void solver::add_root(unsigned n, sat::literal const* lits) {
|
||||
#if NEW_RELEVANCY
|
||||
m_relevancy.add_root(n, lits);
|
||||
return;
|
||||
#endif
|
||||
if (m_relevancy.enabled()) {
|
||||
m_relevancy.add_root(n, lits);
|
||||
return;
|
||||
}
|
||||
if (!relevancy_enabled())
|
||||
return;
|
||||
ensure_dual_solver();
|
||||
|
@ -104,10 +101,10 @@ namespace euf {
|
|||
}
|
||||
|
||||
void solver::add_aux(unsigned n, sat::literal const* lits) {
|
||||
#if NEW_RELEVANCY
|
||||
m_relevancy.add_def(n, lits);
|
||||
return;
|
||||
#endif
|
||||
if (m_relevancy.enabled()) {
|
||||
m_relevancy.add_def(n, lits);
|
||||
return;
|
||||
}
|
||||
if (!relevancy_enabled())
|
||||
return;
|
||||
ensure_dual_solver();
|
||||
|
@ -115,17 +112,15 @@ namespace euf {
|
|||
}
|
||||
|
||||
void solver::track_relevancy(sat::bool_var v) {
|
||||
#if NEW_RELEVANCY
|
||||
return;
|
||||
#endif
|
||||
if (m_relevancy.enabled())
|
||||
return;
|
||||
ensure_dual_solver();
|
||||
m_dual_solver->track_relevancy(v);
|
||||
}
|
||||
|
||||
bool solver::init_relevancy() {
|
||||
#if NEW_RELEVANCY
|
||||
return true;
|
||||
#endif
|
||||
if (m_relevancy.enabled())
|
||||
return true;
|
||||
m_relevant_expr_ids.reset();
|
||||
if (!relevancy_enabled())
|
||||
return true;
|
||||
|
@ -144,19 +139,19 @@ namespace euf {
|
|||
}
|
||||
|
||||
void solver::push_relevant(sat::bool_var v) {
|
||||
SASSERT(!NEW_RELEVANCY);
|
||||
SASSERT(!m_relevancy.enabled());
|
||||
expr* e = m_bool_var2expr.get(v, nullptr);
|
||||
if (e)
|
||||
m_relevant_todo.push_back(e);
|
||||
}
|
||||
|
||||
bool solver::is_propagated(sat::literal lit) {
|
||||
SASSERT(!NEW_RELEVANCY);
|
||||
SASSERT(!m_relevancy.enabled());
|
||||
return s().value(lit) == l_true && !s().get_justification(lit.var()).is_none();
|
||||
}
|
||||
|
||||
void solver::init_relevant_expr_ids() {
|
||||
SASSERT(!NEW_RELEVANCY);
|
||||
SASSERT(!m_relevancy.enabled());
|
||||
unsigned max_id = 0;
|
||||
for (enode* n : m_egraph.nodes())
|
||||
max_id = std::max(max_id, n->get_expr_id());
|
||||
|
@ -166,7 +161,7 @@ namespace euf {
|
|||
}
|
||||
|
||||
void solver::relevant_subterms() {
|
||||
SASSERT(!NEW_RELEVANCY);
|
||||
SASSERT(!m_relevancy.enabled());
|
||||
ptr_vector<expr>& todo = m_relevant_todo;
|
||||
bool_vector& visited = m_relevant_visited;
|
||||
for (unsigned i = 0; i < todo.size(); ++i) {
|
||||
|
|
|
@ -58,6 +58,14 @@ namespace euf {
|
|||
display_justification_ptr(out, reinterpret_cast<size_t*>(j));
|
||||
};
|
||||
m_egraph.set_display_justification(disp);
|
||||
|
||||
if (m_relevancy.enabled()) {
|
||||
std::function<void(euf::enode* root, euf::enode* other)> on_merge =
|
||||
[&](enode* root, enode* other) {
|
||||
m_relevancy.merge(root, other);
|
||||
};
|
||||
m_egraph.set_on_merge(on_merge);
|
||||
}
|
||||
}
|
||||
|
||||
void solver::updt_params(params_ref const& p) {
|
||||
|
@ -244,17 +252,10 @@ namespace euf {
|
|||
bool solver::propagate(enode* a, enode* b, ext_justification_idx idx) {
|
||||
if (a->get_root() == b->get_root())
|
||||
return false;
|
||||
merge(a, b, to_ptr(idx));
|
||||
m_egraph.merge(a, b, to_ptr(idx));
|
||||
return true;
|
||||
}
|
||||
|
||||
void solver::merge(enode* a, enode* b, void* r) {
|
||||
#if NEW_RELEVANCY
|
||||
m_relevancy.merge(a, b);
|
||||
#endif
|
||||
m_egraph.merge(a, b, r);
|
||||
}
|
||||
|
||||
void solver::get_antecedents(literal l, constraint& j, literal_vector& r, bool probing) {
|
||||
expr* e = nullptr;
|
||||
euf::enode* n = nullptr;
|
||||
|
@ -294,12 +295,11 @@ namespace euf {
|
|||
}
|
||||
|
||||
void solver::asserted(literal l) {
|
||||
#if NEW_RELEVANCY
|
||||
if (!m_relevancy.is_relevant(l)) {
|
||||
if (m_relevancy.enabled() && !m_relevancy.is_relevant(l)) {
|
||||
m_relevancy.asserted(l);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
expr* e = m_bool_var2expr.get(l.var(), nullptr);
|
||||
TRACE("euf", tout << "asserted: " << l << "@" << s().scope_lvl() << " := " << mk_bounded_pp(e, m) << "\n";);
|
||||
if (!e)
|
||||
|
@ -320,14 +320,14 @@ namespace euf {
|
|||
euf::enode* r = n->get_root();
|
||||
euf::enode* rb = sign ? mk_true() : mk_false();
|
||||
sat::literal rl(r->bool_var(), r->value() == l_false);
|
||||
merge(n, nb, c);
|
||||
merge(r, rb, to_ptr(rl));
|
||||
m_egraph.merge(n, nb, c);
|
||||
m_egraph.merge(r, rb, to_ptr(rl));
|
||||
SASSERT(m_egraph.inconsistent());
|
||||
return;
|
||||
}
|
||||
if (n->merge_tf()) {
|
||||
euf::enode* nb = sign ? mk_false() : mk_true();
|
||||
merge(n, nb, c);
|
||||
m_egraph.merge(n, nb, c);
|
||||
}
|
||||
if (n->is_equality()) {
|
||||
SASSERT(!m.is_iff(e));
|
||||
|
@ -335,7 +335,7 @@ namespace euf {
|
|||
if (sign)
|
||||
m_egraph.new_diseq(n);
|
||||
else
|
||||
merge(n->get_arg(0), n->get_arg(1), c);
|
||||
m_egraph.merge(n->get_arg(0), n->get_arg(1), c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,9 +343,8 @@ namespace euf {
|
|||
bool solver::unit_propagate() {
|
||||
bool propagated = false;
|
||||
while (!s().inconsistent()) {
|
||||
#if NEW_RELEVANCY
|
||||
m_relevancy.propagate();
|
||||
#endif
|
||||
if (m_relevancy.enabled())
|
||||
m_relevancy.propagate();
|
||||
if (m_egraph.inconsistent()) {
|
||||
unsigned lvl = s().scope_lvl();
|
||||
s().set_conflict(sat::justification::mk_ext_justification(lvl, conflict_constraint().to_index()));
|
||||
|
@ -362,9 +361,13 @@ namespace euf {
|
|||
if (m_solvers[i]->unit_propagate())
|
||||
propagated1 = true;
|
||||
|
||||
if (!propagated1)
|
||||
break;
|
||||
propagated = true;
|
||||
if (propagated1) {
|
||||
propagated = true;
|
||||
continue;
|
||||
}
|
||||
if (m_relevancy.enabled() && m_relevancy.can_propagate())
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
DEBUG_CODE(if (!propagated && !s().inconsistent()) check_missing_eq_propagation(););
|
||||
return propagated;
|
||||
|
@ -439,12 +442,10 @@ namespace euf {
|
|||
void solver::propagate_th_eqs() {
|
||||
for (; m_egraph.has_th_eq() && !s().inconsistent() && !m_egraph.inconsistent(); m_egraph.next_th_eq()) {
|
||||
th_eq eq = m_egraph.get_th_eq();
|
||||
if (eq.is_eq()) {
|
||||
if (!is_self_propagated(eq))
|
||||
m_id2solver[eq.id()]->new_eq_eh(eq);
|
||||
}
|
||||
else
|
||||
if (!eq.is_eq())
|
||||
m_id2solver[eq.id()]->new_diseq_eh(eq);
|
||||
else if (!is_self_propagated(eq))
|
||||
m_id2solver[eq.id()]->new_eq_eh(eq);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,7 +31,6 @@ Author:
|
|||
#include "sat/smt/smt_relevant.h"
|
||||
#include "smt/params/smt_params.h"
|
||||
|
||||
#define NEW_RELEVANCY 0
|
||||
|
||||
namespace euf {
|
||||
typedef sat::literal literal;
|
||||
|
@ -257,6 +256,10 @@ namespace euf {
|
|||
sat::sat_internalizer& get_si() { return si; }
|
||||
ast_manager& get_manager() { return m; }
|
||||
enode* get_enode(expr* e) const { return m_egraph.find(e); }
|
||||
enode* bool_var2enode(sat::bool_var b) const {
|
||||
expr* e = m_bool_var2expr.get(b);
|
||||
return e ? get_enode(e) : nullptr;
|
||||
}
|
||||
sat::literal expr2literal(expr* e) const { return enode2literal(get_enode(e)); }
|
||||
sat::literal enode2literal(enode* n) const { return sat::literal(n->bool_var(), false); }
|
||||
lbool value(enode* n) const { return s().value(enode2literal(n)); }
|
||||
|
@ -293,7 +296,6 @@ namespace euf {
|
|||
|
||||
void propagate(literal lit, ext_justification_idx idx);
|
||||
bool propagate(enode* a, enode* b, ext_justification_idx idx);
|
||||
void merge(enode* a, enode* b, void* r);
|
||||
void set_conflict(ext_justification_idx idx);
|
||||
|
||||
void propagate(literal lit, th_explain* p) { propagate(lit, p->to_index()); }
|
||||
|
@ -395,7 +397,7 @@ namespace euf {
|
|||
void add_auto_relevant(sat::literal lit);
|
||||
void pop_relevant(unsigned n);
|
||||
void push_relevant();
|
||||
|
||||
smt::relevancy& relevancy() { return m_relevancy; }
|
||||
|
||||
// model construction
|
||||
void update_model(model_ref& mdl);
|
||||
|
|
|
@ -66,13 +66,21 @@ namespace q {
|
|||
};
|
||||
std::function<void(euf::enode*)> _on_make =
|
||||
[&](euf::enode* n) {
|
||||
m_mam->add_node(n, false);
|
||||
relevant_eh(n);
|
||||
|
||||
};
|
||||
ctx.get_egraph().set_on_merge(_on_merge);
|
||||
ctx.get_egraph().set_on_make(_on_make);
|
||||
if (ctx.relevancy().enabled())
|
||||
ctx.get_egraph().set_on_make(_on_make);
|
||||
else
|
||||
ctx.relevancy().add_relevant(&s);
|
||||
m_mam = mam::mk(ctx, *this);
|
||||
}
|
||||
|
||||
void ematch::relevant_eh(euf::enode* n) {
|
||||
m_mam->add_node(n, false);
|
||||
}
|
||||
|
||||
void ematch::ensure_ground_enodes(expr* e) {
|
||||
mam::ground_subterms(e, m_ground);
|
||||
for (expr* g : m_ground)
|
||||
|
|
|
@ -135,9 +135,10 @@ namespace q {
|
|||
|
||||
bool unit_propagate();
|
||||
|
||||
|
||||
void add(quantifier* q);
|
||||
|
||||
void relevant_eh(euf::enode* n);
|
||||
|
||||
void collect_statistics(statistics& st) const;
|
||||
|
||||
void get_antecedents(sat::literal l, sat::ext_justification_idx idx, sat::literal_vector& r, bool probing);
|
||||
|
|
|
@ -83,6 +83,7 @@ namespace q {
|
|||
void init_search() override;
|
||||
void finalize_model(model& mdl) override;
|
||||
bool is_shared(euf::theory_var v) const override { return true; }
|
||||
void relevant_eh(euf::enode* n) override { m_ematch.relevant_eh(n); }
|
||||
|
||||
ast_manager& get_manager() { return m; }
|
||||
sat::literal_vector const& universal() const { return m_universal; }
|
||||
|
|
|
@ -111,6 +111,8 @@ namespace euf {
|
|||
|
||||
virtual void new_diseq_eh(euf::th_eq const& eq) {}
|
||||
|
||||
virtual void relevant_eh(euf::enode* n) {}
|
||||
|
||||
/**
|
||||
\brief Parametric theories (e.g. Arrays) should implement this method.
|
||||
*/
|
||||
|
|
|
@ -3,7 +3,7 @@ Copyright (c) 2020 Microsoft Corporation
|
|||
|
||||
Module Name:
|
||||
|
||||
relevancy.cpp
|
||||
smt_relevant.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
|
@ -22,11 +22,13 @@ Author:
|
|||
namespace smt {
|
||||
|
||||
relevancy::relevancy(euf::solver& ctx): ctx(ctx) {
|
||||
m_enabled = ctx.relevancy_enabled();
|
||||
m_enabled = ctx.get_config().m_relevancy_lvl > 2;
|
||||
}
|
||||
|
||||
void relevancy::relevant_eh(euf::enode* n) {
|
||||
// nothing
|
||||
SASSERT(is_relevant(n));
|
||||
for (auto* th : m_relevant_eh)
|
||||
th->relevant_eh(n);
|
||||
}
|
||||
|
||||
void relevancy::relevant_eh(sat::literal lit) {
|
||||
|
@ -102,8 +104,10 @@ namespace smt {
|
|||
m_clauses.push_back(cl);
|
||||
m_roots.push_back(true);
|
||||
m_trail.push_back(std::make_pair(update::add_clause, 0));
|
||||
for (sat::literal lit : *cl)
|
||||
for (sat::literal lit : *cl) {
|
||||
ctx.s().set_external(lit.var());
|
||||
occurs(lit).push_back(sz);
|
||||
}
|
||||
}
|
||||
|
||||
void relevancy::add_def(unsigned n, sat::literal const* lits) {
|
||||
|
@ -121,15 +125,17 @@ namespace smt {
|
|||
m_clauses.push_back(cl);
|
||||
m_roots.push_back(false);
|
||||
m_trail.push_back(std::make_pair(update::add_clause, 0));
|
||||
for (sat::literal lit : *cl)
|
||||
occurs(lit).push_back(sz);
|
||||
for (sat::literal lit : *cl) {
|
||||
ctx.s().set_external(lit.var());
|
||||
occurs(lit).push_back(sz);
|
||||
}
|
||||
}
|
||||
|
||||
void relevancy::asserted(sat::literal lit) {
|
||||
if (!m_enabled)
|
||||
return;
|
||||
flush();
|
||||
if (ctx.s().lvl(lit) == 0) {
|
||||
if (ctx.s().lvl(lit) <= ctx.s().search_lvl()) {
|
||||
mark_relevant(lit);
|
||||
return;
|
||||
}
|
||||
|
@ -164,11 +170,11 @@ namespace smt {
|
|||
}
|
||||
}
|
||||
|
||||
void relevancy::merge(euf::enode* n1, euf::enode* n2) {
|
||||
if (is_relevant(n1))
|
||||
mark_relevant(n2);
|
||||
else if (is_relevant(n2))
|
||||
mark_relevant(n1);
|
||||
void relevancy::merge(euf::enode* root, euf::enode* other) {
|
||||
if (is_relevant(root))
|
||||
mark_relevant(other);
|
||||
else if (is_relevant(other))
|
||||
mark_relevant(root);
|
||||
}
|
||||
|
||||
void relevancy::mark_relevant(euf::enode* n) {
|
||||
|
@ -177,6 +183,8 @@ namespace smt {
|
|||
flush();
|
||||
if (is_relevant(n))
|
||||
return;
|
||||
if (ctx.get_si().is_bool_op(n->get_expr()))
|
||||
return;
|
||||
for (euf::enode* sib : euf::enode_class(n))
|
||||
set_relevant(sib);
|
||||
}
|
||||
|
@ -195,12 +203,12 @@ namespace smt {
|
|||
flush();
|
||||
if (is_relevant(lit))
|
||||
return;
|
||||
euf::enode* n = ctx.bool_var2enode(lit.var());
|
||||
if (n)
|
||||
mark_relevant(n);
|
||||
m_relevant_var_ids.setx(lit.var(), true, false);
|
||||
m_trail.push_back(std::make_pair(update::relevant_var, lit.var()));
|
||||
m_queue.push_back(std::make_pair(lit, nullptr));
|
||||
euf::enode* n = nullptr;
|
||||
if (n)
|
||||
mark_relevant(n);
|
||||
}
|
||||
|
||||
void relevancy::propagate_relevant(sat::literal lit) {
|
||||
|
@ -208,9 +216,9 @@ namespace smt {
|
|||
for (auto idx : occurs(~lit)) {
|
||||
if (m_roots[idx])
|
||||
continue;
|
||||
sat::clause& cl = *m_clauses[idx];
|
||||
sat::clause* cl = m_clauses[idx];
|
||||
sat::literal true_lit = sat::null_literal;
|
||||
for (sat::literal lit2 : cl) {
|
||||
for (sat::literal lit2 : *cl) {
|
||||
if (ctx.s().value(lit2) == l_true) {
|
||||
if (is_relevant(lit2))
|
||||
goto next;
|
||||
|
@ -231,7 +239,6 @@ namespace smt {
|
|||
|
||||
void relevancy::propagate_relevant(euf::enode* n) {
|
||||
relevant_eh(n);
|
||||
// if is_bool_op n, return;
|
||||
for (euf::enode* arg : euf::enode_args(n))
|
||||
mark_relevant(arg);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ Copyright (c) 2020 Microsoft Corporation
|
|||
|
||||
Module Name:
|
||||
|
||||
relevancy.h
|
||||
smt_relevant.h
|
||||
|
||||
Abstract:
|
||||
|
||||
|
@ -26,7 +26,7 @@ The state transitions are:
|
|||
->
|
||||
lit is set relevant
|
||||
|
||||
lit is justified at level 0
|
||||
lit is justified at search level
|
||||
->
|
||||
lit is set relevant
|
||||
|
||||
|
@ -39,7 +39,7 @@ The state transitions are:
|
|||
->
|
||||
all clauses C in Defs where lit appears negatively are added to Roots
|
||||
|
||||
- When a clause R is added to Roots:
|
||||
- When a clause R is added to Roots:
|
||||
R contains a positive literal lit that is relevant
|
||||
->
|
||||
skip adding R to Roots
|
||||
|
@ -72,7 +72,7 @@ Can a literal that is not in a root be set relevant?
|
|||
- yes, if we propagate over expressions
|
||||
|
||||
Do we need full watch lists instead of 2-watch lists?
|
||||
- probably, but unclear. The dual SAT solver only uses 2-watch lists, but has uses a large clause for tracking
|
||||
- probably, but unclear. The dual SAT solver only uses 2-watch lists, but uses a large clause for tracking
|
||||
roots.
|
||||
|
||||
|
||||
|
@ -105,6 +105,7 @@ namespace smt {
|
|||
vector<unsigned_vector> m_occurs; // where do literals occur
|
||||
unsigned m_qhead = 0; // queue head for relevancy
|
||||
svector<std::pair<sat::literal, euf::enode*>> m_queue; // propagation queue for relevancy
|
||||
ptr_vector<euf::th_solver> m_relevant_eh;
|
||||
|
||||
// callbacks during propagation
|
||||
void relevant_eh(euf::enode* n);
|
||||
|
@ -131,6 +132,7 @@ namespace smt {
|
|||
void add_def(unsigned n, sat::literal const* lits);
|
||||
void asserted(sat::literal lit);
|
||||
void propagate();
|
||||
bool can_propagate() const { return m_qhead < m_queue.size(); }
|
||||
|
||||
void mark_relevant(euf::enode* n);
|
||||
void mark_relevant(sat::literal lit);
|
||||
|
@ -139,6 +141,9 @@ namespace smt {
|
|||
bool is_relevant(sat::literal lit) const { return !m_enabled || m_relevant_var_ids.get(lit.var(), false); }
|
||||
bool is_relevant(euf::enode* n) const { return !m_enabled || m_relevant_expr_ids.get(n->get_expr_id(), false); }
|
||||
bool is_relevant(expr* e) const { return !m_enabled || m_relevant_expr_ids.get(e->get_id(), false); }
|
||||
|
||||
|
||||
bool enabled() const { return m_enabled; }
|
||||
|
||||
void add_relevant(euf::th_solver* th) { m_relevant_eh.push_back(th); }
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue