mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
tuning eval
This commit is contained in:
parent
2e176a0e02
commit
92c1b600c3
|
@ -129,7 +129,7 @@ namespace euf {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
egraph::egraph(ast_manager& m) : m(m), m_table(m), m_tmp_app(2), m_exprs(m) {
|
egraph::egraph(ast_manager& m) : m(m), m_table(m), m_tmp_app(2), m_exprs(m), m_eq_decls(m) {
|
||||||
m_tmp_eq = enode::mk_tmp(m_region, 2);
|
m_tmp_eq = enode::mk_tmp(m_region, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,7 +592,7 @@ namespace euf {
|
||||||
SASSERT(!n1->get_root()->m_target);
|
SASSERT(!n1->get_root()->m_target);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool egraph::are_diseq(enode* a, enode* b) const {
|
bool egraph::are_diseq(enode* a, enode* b) {
|
||||||
enode* ra = a->get_root(), * rb = b->get_root();
|
enode* ra = a->get_root(), * rb = b->get_root();
|
||||||
if (ra == rb)
|
if (ra == rb)
|
||||||
return false;
|
return false;
|
||||||
|
@ -600,12 +600,16 @@ namespace euf {
|
||||||
return true;
|
return true;
|
||||||
if (ra->get_sort() != rb->get_sort())
|
if (ra->get_sort() != rb->get_sort())
|
||||||
return true;
|
return true;
|
||||||
expr_ref eq(m.mk_eq(a->get_expr(), b->get_expr()), m);
|
if (ra->num_parents() > rb->num_parents())
|
||||||
m_tmp_eq->m_args[0] = a;
|
std::swap(ra, rb);
|
||||||
m_tmp_eq->m_args[1] = b;
|
if (ra->num_parents() <= 3) {
|
||||||
m_tmp_eq->m_expr = eq;
|
for (enode* p : enode_parents(ra))
|
||||||
SASSERT(m_tmp_eq->num_args() == 2);
|
if (p->is_equality() && p->get_root()->value() == l_false &&
|
||||||
enode* r = m_table.find(m_tmp_eq);
|
(rb == p->get_arg(0)->get_root() || rb == p->get_arg(1)->get_root()))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
enode* r = tmp_eq(ra, rb);
|
||||||
if (r && r->get_root()->value() == l_false)
|
if (r && r->get_root()->value() == l_false)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -617,6 +621,24 @@ namespace euf {
|
||||||
return find(m_tmp_app.get_app(), num_args, args);
|
return find(m_tmp_app.get_app(), num_args, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enode* egraph::tmp_eq(enode* a, enode* b) {
|
||||||
|
func_decl* f = nullptr;
|
||||||
|
for (unsigned i = m_eq_decls.size(); i-- > 0; ) {
|
||||||
|
auto e = m_eq_decls.get(i);
|
||||||
|
if (e->get_domain(0) == a->get_sort()) {
|
||||||
|
f = e;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!f) {
|
||||||
|
app_ref eq(m.mk_eq(a->get_expr(), b->get_expr()), m);
|
||||||
|
m_eq_decls.push_back(eq->get_decl());
|
||||||
|
f = eq->get_decl();
|
||||||
|
}
|
||||||
|
enode* args[2] = { a, b };
|
||||||
|
return get_enode_eq_to(f, 2, args);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief generate an explanation for a congruence.
|
\brief generate an explanation for a congruence.
|
||||||
Each pair of children under a congruence have the same roots
|
Each pair of children under a congruence have the same roots
|
||||||
|
@ -714,12 +736,7 @@ namespace euf {
|
||||||
explain_eq(justifications, b, rb);
|
explain_eq(justifications, b, rb);
|
||||||
return sat::null_bool_var;
|
return sat::null_bool_var;
|
||||||
}
|
}
|
||||||
expr_ref eq(m.mk_eq(a->get_expr(), b->get_expr()), m);
|
enode* r = tmp_eq(a, b);
|
||||||
m_tmp_eq->m_args[0] = a;
|
|
||||||
m_tmp_eq->m_args[1] = b;
|
|
||||||
m_tmp_eq->m_expr = eq;
|
|
||||||
SASSERT(m_tmp_eq->num_args() == 2);
|
|
||||||
enode* r = m_table.find(m_tmp_eq);
|
|
||||||
SASSERT(r && r->get_root()->value() == l_false);
|
SASSERT(r && r->get_root()->value() == l_false);
|
||||||
explain_eq(justifications, r, r->get_root());
|
explain_eq(justifications, r, r->get_root());
|
||||||
return r->get_root()->bool_var();
|
return r->get_root()->bool_var();
|
||||||
|
|
|
@ -165,6 +165,7 @@ namespace euf {
|
||||||
tmp_app m_tmp_app;
|
tmp_app m_tmp_app;
|
||||||
enode_vector m_nodes;
|
enode_vector m_nodes;
|
||||||
expr_ref_vector m_exprs;
|
expr_ref_vector m_exprs;
|
||||||
|
func_decl_ref_vector m_eq_decls;
|
||||||
vector<enode_vector> m_decl2enodes;
|
vector<enode_vector> m_decl2enodes;
|
||||||
enode_vector m_empty_enodes;
|
enode_vector m_empty_enodes;
|
||||||
unsigned m_num_scopes = 0;
|
unsigned m_num_scopes = 0;
|
||||||
|
@ -263,10 +264,12 @@ namespace euf {
|
||||||
/**
|
/**
|
||||||
* \brief check if two nodes are known to be disequal.
|
* \brief check if two nodes are known to be disequal.
|
||||||
*/
|
*/
|
||||||
bool are_diseq(enode* a, enode* b) const;
|
bool are_diseq(enode* a, enode* b);
|
||||||
|
|
||||||
enode* get_enode_eq_to(func_decl* f, unsigned num_args, enode* const* args);
|
enode* get_enode_eq_to(func_decl* f, unsigned num_args, enode* const* args);
|
||||||
|
|
||||||
|
enode* tmp_eq(enode* a, enode* b);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief Maintain and update cursor into propagated consequences.
|
\brief Maintain and update cursor into propagated consequences.
|
||||||
The result of get_literal() is a pair (n, is_eq)
|
The result of get_literal() is a pair (n, is_eq)
|
||||||
|
|
|
@ -25,7 +25,10 @@ namespace q {
|
||||||
struct eval::scoped_mark_reset {
|
struct eval::scoped_mark_reset {
|
||||||
eval& e;
|
eval& e;
|
||||||
scoped_mark_reset(eval& e): e(e) {}
|
scoped_mark_reset(eval& e): e(e) {}
|
||||||
~scoped_mark_reset() { e.m_mark.reset(); }
|
~scoped_mark_reset() {
|
||||||
|
e.m_mark.reset();
|
||||||
|
e.m_diseq_undef = euf::enode_pair();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
eval::eval(euf::solver& ctx):
|
eval::eval(euf::solver& ctx):
|
||||||
|
@ -97,12 +100,18 @@ namespace q {
|
||||||
if (sn && sn == tn)
|
if (sn && sn == tn)
|
||||||
return l_true;
|
return l_true;
|
||||||
|
|
||||||
|
if (sn && sn == m_diseq_undef.first && tn == m_diseq_undef.second)
|
||||||
|
return l_undef;
|
||||||
|
|
||||||
if (sn && tn && ctx.get_egraph().are_diseq(sn, tn)) {
|
if (sn && tn && ctx.get_egraph().are_diseq(sn, tn)) {
|
||||||
evidence.push_back(euf::enode_pair(sn, tn));
|
evidence.push_back(euf::enode_pair(sn, tn));
|
||||||
return l_false;
|
return l_false;
|
||||||
}
|
}
|
||||||
if (sn && tn)
|
if (sn && tn) {
|
||||||
|
m_diseq_undef = euf::enode_pair(sn, tn);
|
||||||
return l_undef;
|
return l_undef;
|
||||||
|
}
|
||||||
|
|
||||||
if (!sn && !tn)
|
if (!sn && !tn)
|
||||||
return compare_rec(n, binding, s, t, evidence);
|
return compare_rec(n, binding, s, t, evidence);
|
||||||
|
|
||||||
|
@ -115,7 +124,11 @@ namespace q {
|
||||||
std::swap(t, s);
|
std::swap(t, s);
|
||||||
}
|
}
|
||||||
unsigned sz = evidence.size();
|
unsigned sz = evidence.size();
|
||||||
for (euf::enode* t1 : euf::enode_class(tn)) {
|
unsigned count = 0;
|
||||||
|
for (euf::enode* t1 : euf::enode_class(tn)) {
|
||||||
|
if (!t1->is_cgr())
|
||||||
|
continue;
|
||||||
|
++count;
|
||||||
expr* t2 = t1->get_expr();
|
expr* t2 = t1->get_expr();
|
||||||
if ((c = compare_rec(n, binding, s, t2, evidence), c != l_undef)) {
|
if ((c = compare_rec(n, binding, s, t2, evidence), c != l_undef)) {
|
||||||
evidence.push_back(euf::enode_pair(t1, tn));
|
evidence.push_back(euf::enode_pair(t1, tn));
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace q {
|
||||||
euf::enode_vector m_eval;
|
euf::enode_vector m_eval;
|
||||||
euf::enode_vector m_indirect_nodes;
|
euf::enode_vector m_indirect_nodes;
|
||||||
bool m_freeze_swap = false;
|
bool m_freeze_swap = false;
|
||||||
|
euf::enode_pair m_diseq_undef;
|
||||||
|
|
||||||
struct scoped_mark_reset;
|
struct scoped_mark_reset;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue