3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-09-15 16:45:11 -07:00
parent 545e1c0d31
commit 2d52367368
10 changed files with 62 additions and 43 deletions

View file

@ -23,7 +23,7 @@ namespace euf {
void solver::internalize(expr* e, bool redundant) {
if (si.is_bool_op(e))
attach_lit(si.internalize(e, redundant), e);
else if (auto* ext = get_solver(e))
else if (auto* ext = expr2solver(e))
ext->internalize(e, redundant);
else
visit_rec(m, e, false, false, redundant);
@ -33,7 +33,7 @@ namespace euf {
sat::literal solver::internalize(expr* e, bool sign, bool root, bool redundant) {
if (si.is_bool_op(e))
return attach_lit(si.internalize(e, redundant), e);
if (auto* ext = get_solver(e))
if (auto* ext = expr2solver(e))
return ext->internalize(e, sign, root, redundant);
if (!visit_rec(m, e, sign, root, redundant))
return sat::null_literal;
@ -67,7 +67,7 @@ namespace euf {
m_args.push_back(m_egraph.find(to_app(e)->get_arg(i)));
if (root && internalize_root(to_app(e), sign, m_args))
return false;
if (auto* s = get_solver(e)) {
if (auto* s = expr2solver(e)) {
s->internalize(e, m_is_redundant);
return true;
}
@ -88,8 +88,8 @@ namespace euf {
attach_lit(literal(si.add_bool_var(e), false), e);
if (!m.is_bool(e) && m.get_sort(e)->get_family_id() != null_family_id) {
auto* e_ext = get_solver(e);
auto* s_ext = get_solver(m.get_sort(e));
auto* e_ext = expr2solver(e);
auto* s_ext = sort2solver(m.get_sort(e));
if (s_ext && s_ext != e_ext)
s_ext->apply_sort_cnstr(n, m.get_sort(e));
}

View file

@ -38,7 +38,7 @@ namespace euf {
return true;
if (f->get_family_id() == m.get_basic_family_id())
return false;
euf::th_model_builder* mb = get_solver(f);
euf::th_model_builder* mb = func_decl2solver(f);
return mb && mb->include_func_interp(f);
}
@ -48,7 +48,7 @@ namespace euf {
deps.insert(n, nullptr);
continue;
}
auto* mb = get_solver(n->get_expr());
auto* mb = expr2solver(n->get_expr());
if (mb)
mb->add_dep(n, deps);
else
@ -94,14 +94,14 @@ namespace euf {
}
continue;
}
auto* mb = get_solver(e);
auto* mb = expr2solver(e);
if (mb)
mb->add_value(n, *mdl, values);
else if (m.is_uninterp(m.get_sort(e))) {
expr* v = user_sort.get_fresh_value(m.get_sort(e));
values.set(id, v);
}
else if ((mb = get_solver(m.get_sort(e))))
else if ((mb = sort2solver(m.get_sort(e))))
mb->add_value(n, *mdl, values);
else {
IF_VERBOSE(1, verbose_stream() << "no model values created for " << mk_pp(e, m) << "\n");

View file

@ -53,18 +53,18 @@ namespace euf {
/**
* retrieve extension that is associated with Boolean variable.
*/
th_solver* solver::get_solver(sat::bool_var v) {
th_solver* solver::bool_var2solver(sat::bool_var v) {
if (v >= m_var2expr.size())
return nullptr;
expr* e = m_var2expr[v];
if (!e)
return nullptr;
return get_solver(e);
return expr2solver(e);
}
th_solver* solver::get_solver(expr* e) {
th_solver* solver::expr2solver(expr* e) {
if (is_app(e))
return get_solver(to_app(e)->get_decl());
return func_decl2solver(to_app(e)->get_decl());
return nullptr;
}
@ -112,7 +112,7 @@ namespace euf {
}
void solver::init_search() {
TRACE("euf", display(tout););
TRACE("before_search", s().display(tout););
}
bool solver::is_external(bool_var v) {
@ -220,14 +220,30 @@ namespace euf {
size_t* c = to_ptr(l);
SASSERT(is_literal(c));
SASSERT(l == get_literal(c));
if (m.is_eq(e) && !sign && n->num_args() == 2) {
if (m.is_eq(e) && n->num_args() == 2) {
euf::enode* na = n->get_arg(0);
euf::enode* nb = n->get_arg(1);
m_egraph.merge(na, nb, c);
if (!sign) {
m_egraph.merge(na, nb, c);
return;
}
else
new_diseq(na, nb, l);
}
else {
euf::enode* nb = sign ? mk_false() : mk_true();
m_egraph.merge(n, nb, c);
euf::enode* nb = sign ? mk_false() : mk_true();
m_egraph.merge(n, nb, c);
}
void solver::new_diseq(enode* n1, enode* n2, literal lit) {
enode * r1 = n1->get_root();
enode * r2 = n2->get_root();
if (r1 == r2)
return;
if (r1->has_one_th_var() && r2->has_one_th_var() && r1->get_first_th_id() == r2->get_first_th_id()) {
theory_id id = r1->get_first_th_id();
theory_var v1 = r1->get_th_var(id);
theory_var v2 = r2->get_th_var(id);
fid2solver(id)->new_diseq_eh(r1, r2);
}
}
@ -412,7 +428,7 @@ namespace euf {
}
lbool solver::get_phase(bool_var v) {
auto* ext = get_solver(v);
auto* ext = bool_var2solver(v);
if (ext)
return ext->get_phase(v);
return l_undef;

View file

@ -125,10 +125,11 @@ namespace euf {
// extensions
th_solver* get_solver(family_id fid, func_decl* f);
th_solver* get_solver(sort* s) { return get_solver(s->get_family_id(), nullptr); }
th_solver* get_solver(func_decl* f) { return get_solver(f->get_family_id(), f); }
th_solver* get_solver(expr* e);
th_solver* get_solver(sat::bool_var v);
th_solver* sort2solver(sort* s) { return get_solver(s->get_family_id(), nullptr); }
th_solver* func_decl2solver(func_decl* f) { return get_solver(f->get_family_id(), f); }
th_solver* expr2solver(expr* e);
th_solver* bool_var2solver(sat::bool_var v);
th_solver* fid2solver(family_id fid) { return m_id2solver.get(fid, nullptr); }
void add_solver(family_id fid, th_solver* th);
void init_ackerman();
@ -143,6 +144,7 @@ namespace euf {
void propagate_literals();
void propagate_th_eqs();
void get_antecedents(literal l, constraint& j, literal_vector& r, bool probing);
void new_diseq(enode* a, enode* b, literal lit);
// proofs
void log_antecedents(std::ostream& out, literal l, literal_vector const& r);

View file

@ -93,6 +93,10 @@ namespace euf {
virtual void new_eq_eh(euf::th_eq const& eq) {}
virtual bool use_diseqs() const { return false; }
virtual void new_diseq_eh(euf::enode* a, euf::enode* b) {}
/**
\brief Parametric theories (e.g. Arrays) should implement this method.
*/