mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
#5778 - missed tracking literal assignment justification
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
00608cd719
commit
20bd59bb20
|
@ -293,11 +293,12 @@ namespace euf {
|
||||||
VERIFY(n->num_args() == 0 || !n->merge_enabled() || m_table.contains(n));
|
VERIFY(n->num_args() == 0 || !n->merge_enabled() || m_table.contains(n));
|
||||||
}
|
}
|
||||||
|
|
||||||
void egraph::set_value(enode* n, lbool value) {
|
void egraph::set_value(enode* n, lbool value, justification j) {
|
||||||
if (n->value() == l_undef) {
|
if (n->value() == l_undef) {
|
||||||
force_push();
|
force_push();
|
||||||
TRACE("euf", tout << bpp(n) << " := " << value << "\n";);
|
TRACE("euf", tout << bpp(n) << " := " << value << "\n";);
|
||||||
n->set_value(value);
|
n->set_value(value);
|
||||||
|
n->set_justification(j);
|
||||||
m_updates.push_back(update_record(n, update_record::value_assignment()));
|
m_updates.push_back(update_record(n, update_record::value_assignment()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -657,6 +658,7 @@ namespace euf {
|
||||||
push_lca(n1->get_arg(1), n2->get_arg(0));
|
push_lca(n1->get_arg(1), n2->get_arg(0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TRACE("euf_verbose", tout << bpp(n1) << " " << bpp(n2) << "\n");
|
||||||
|
|
||||||
for (unsigned i = 0; i < n1->num_args(); ++i)
|
for (unsigned i = 0; i < n1->num_args(); ++i)
|
||||||
push_lca(n1->get_arg(i), n2->get_arg(i));
|
push_lca(n1->get_arg(i), n2->get_arg(i));
|
||||||
|
@ -713,6 +715,15 @@ namespace euf {
|
||||||
explain_todo(justifications);
|
explain_todo(justifications);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void egraph::explain_eq(ptr_vector<T>& justifications, enode* a, enode* b, justification const& j) {
|
||||||
|
if (j.is_external())
|
||||||
|
justifications.push_back(j.ext<T>());
|
||||||
|
else if (j.is_congruence())
|
||||||
|
push_congruence(a, b, j.is_commutative());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void egraph::explain_eq(ptr_vector<T>& justifications, enode* a, enode* b) {
|
void egraph::explain_eq(ptr_vector<T>& justifications, enode* a, enode* b) {
|
||||||
SASSERT(a->get_root() == b->get_root());
|
SASSERT(a->get_root() == b->get_root());
|
||||||
|
@ -746,11 +757,21 @@ namespace euf {
|
||||||
void egraph::explain_todo(ptr_vector<T>& justifications) {
|
void egraph::explain_todo(ptr_vector<T>& justifications) {
|
||||||
for (unsigned i = 0; i < m_todo.size(); ++i) {
|
for (unsigned i = 0; i < m_todo.size(); ++i) {
|
||||||
enode* n = m_todo[i];
|
enode* n = m_todo[i];
|
||||||
if (n->m_target && !n->is_marked1()) {
|
if (n->is_marked1())
|
||||||
|
continue;
|
||||||
|
if (n->m_target) {
|
||||||
n->mark1();
|
n->mark1();
|
||||||
CTRACE("euf_verbose", m_display_justification, n->m_justification.display(tout << n->get_expr_id() << " = " << n->m_target->get_expr_id() << " ", m_display_justification) << "\n";);
|
CTRACE("euf_verbose", m_display_justification, n->m_justification.display(tout << n->get_expr_id() << " = " << n->m_target->get_expr_id() << " ", m_display_justification) << "\n";);
|
||||||
explain_eq(justifications, n, n->m_target, n->m_justification);
|
explain_eq(justifications, n, n->m_target, n->m_justification);
|
||||||
}
|
}
|
||||||
|
else if (!n->is_marked1() && n->value() != l_undef) {
|
||||||
|
n->mark1();
|
||||||
|
if (m.is_true(n->get_expr()) || m.is_false(n->get_expr()))
|
||||||
|
continue;
|
||||||
|
justification j = n->m_justification;
|
||||||
|
SASSERT(j.is_external());
|
||||||
|
justifications.push_back(j.ext<T>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -226,12 +226,8 @@ namespace euf {
|
||||||
void erase_from_table(enode* p);
|
void erase_from_table(enode* p);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void explain_eq(ptr_vector<T>& justifications, enode* a, enode* b, justification const& j) {
|
void explain_eq(ptr_vector<T>& justifications, enode* a, enode* b, justification const& j);
|
||||||
if (j.is_external())
|
|
||||||
justifications.push_back(j.ext<T>());
|
|
||||||
else if (j.is_congruence())
|
|
||||||
push_congruence(a, b, j.is_commutative());
|
|
||||||
}
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void explain_todo(ptr_vector<T>& justifications);
|
void explain_todo(ptr_vector<T>& justifications);
|
||||||
|
|
||||||
|
@ -295,7 +291,7 @@ namespace euf {
|
||||||
void add_th_var(enode* n, theory_var v, theory_id id);
|
void add_th_var(enode* n, theory_var v, theory_id id);
|
||||||
void set_th_propagates_diseqs(theory_id id);
|
void set_th_propagates_diseqs(theory_id id);
|
||||||
void set_merge_enabled(enode* n, bool enable_merge);
|
void set_merge_enabled(enode* n, bool enable_merge);
|
||||||
void set_value(enode* n, lbool value);
|
void set_value(enode* n, lbool value, justification j);
|
||||||
void set_bool_var(enode* n, unsigned v) { n->set_bool_var(v); }
|
void set_bool_var(enode* n, unsigned v) { n->set_bool_var(v); }
|
||||||
void set_relevant(enode* n);
|
void set_relevant(enode* n);
|
||||||
void set_default_relevant(bool b) { m_default_relevant = b; }
|
void set_default_relevant(bool b) { m_default_relevant = b; }
|
||||||
|
|
|
@ -133,6 +133,7 @@ namespace euf {
|
||||||
void del_th_var(theory_id id) { m_th_vars.del_var(id); }
|
void del_th_var(theory_id id) { m_th_vars.del_var(id); }
|
||||||
void set_merge_enabled(bool m) { m_merge_enabled = m; }
|
void set_merge_enabled(bool m) { m_merge_enabled = m; }
|
||||||
void set_value(lbool v) { m_value = v; }
|
void set_value(lbool v) { m_value = v; }
|
||||||
|
void set_justification(justification j) { m_justification = j; }
|
||||||
void set_is_equality() { m_is_equality = true; }
|
void set_is_equality() { m_is_equality = true; }
|
||||||
void set_bool_var(sat::bool_var v) { m_bool_var = v; }
|
void set_bool_var(sat::bool_var v) { m_bool_var = v; }
|
||||||
|
|
||||||
|
|
|
@ -190,8 +190,9 @@ namespace euf {
|
||||||
m_egraph.set_bool_var(n, v);
|
m_egraph.set_bool_var(n, v);
|
||||||
if (m.is_eq(e) || m.is_or(e) || m.is_and(e) || m.is_not(e))
|
if (m.is_eq(e) || m.is_or(e) || m.is_and(e) || m.is_not(e))
|
||||||
m_egraph.set_merge_enabled(n, false);
|
m_egraph.set_merge_enabled(n, false);
|
||||||
if (s().value(lit) != l_undef)
|
lbool val = s().value(lit);
|
||||||
m_egraph.set_value(n, s().value(lit));
|
if (val != l_undef)
|
||||||
|
m_egraph.set_value(n, val, justification::external(to_ptr(val == l_true ? lit : ~lit)));
|
||||||
return lit;
|
return lit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -309,7 +309,7 @@ namespace euf {
|
||||||
if (!n)
|
if (!n)
|
||||||
return;
|
return;
|
||||||
bool sign = l.sign();
|
bool sign = l.sign();
|
||||||
m_egraph.set_value(n, sign ? l_false : l_true);
|
m_egraph.set_value(n, sign ? l_false : l_true, justification::external(to_ptr(l)));
|
||||||
for (auto const& th : enode_th_vars(n))
|
for (auto const& th : enode_th_vars(n))
|
||||||
m_id2solver[th.get_id()]->asserted(l);
|
m_id2solver[th.get_id()]->asserted(l);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue