3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-07 14:43:23 +00:00

parent list of root may miss nodes from children if they are not congruence roots. We walk parents of all siblings to not miss

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2024-01-14 18:20:44 -08:00
parent 79a2c86c05
commit 42aad423c9
3 changed files with 47 additions and 37 deletions

View file

@ -445,14 +445,15 @@ namespace euf {
delta += width(arg); delta += width(arg);
} }
} }
} for (auto p : euf::enode_parents(sib)) {
for (auto p : euf::enode_parents(n->get_root())) {
if (bv.is_extract(p->get_expr(), lo, hi, e)) { if (bv.is_extract(p->get_expr(), lo, hi, e)) {
SASSERT(g.find(e)->get_root() == n->get_root()); SASSERT(g.find(e)->get_root() == n->get_root());
m_todo.push_back({ p, offset + lo }); m_todo.push_back({ p, offset + lo });
} }
} }
} }
}
clear_offsets(); clear_offsets();
} }
@ -475,8 +476,7 @@ namespace euf {
auto child = g.find(e); auto child = g.find(e);
m_todo.push_back({ child, offset + lo }); m_todo.push_back({ child, offset + lo });
} }
} for (auto p : euf::enode_parents(sib)) {
for (auto p : euf::enode_parents(n->get_root())) {
if (bv.is_concat(p->get_expr())) { if (bv.is_concat(p->get_expr())) {
unsigned delta = 0; unsigned delta = 0;
for (unsigned j = p->num_args(); j-- > 0; ) { for (unsigned j = p->num_args(); j-- > 0; ) {
@ -488,6 +488,7 @@ namespace euf {
} }
} }
} }
}
clear_offsets(); clear_offsets();
} }
@ -524,6 +525,9 @@ namespace euf {
m_offsets.reserve(n->get_root_id() + 1); m_offsets.reserve(n->get_root_id() + 1);
m_offsets[n->get_root_id()].reset(); m_offsets[n->get_root_id()].reset();
} }
for (auto const& off : m_offsets) {
SASSERT(off.empty());
}
m_jtodo.reset(); m_jtodo.reset();
return; return;
} }
@ -538,8 +542,7 @@ namespace euf {
delta += width(arg); delta += width(arg);
} }
} }
} for (auto p : euf::enode_parents(sib)) {
for (auto p : euf::enode_parents(n->get_root())) {
if (bv.is_extract(p->get_expr(), lo, hi, e)) { if (bv.is_extract(p->get_expr(), lo, hi, e)) {
SASSERT(g.find(e)->get_root() == n->get_root()); SASSERT(g.find(e)->get_root() == n->get_root());
unsigned j2 = just.size(); unsigned j2 = just.size();
@ -549,6 +552,13 @@ namespace euf {
} }
} }
}
IF_VERBOSE(0,
g.display(verbose_stream());
verbose_stream() << g.bpp(a) << " offset " << offset << " " << g.bpp(b) << "\n";
for (auto const& [n, offset, j] : m_jtodo)
verbose_stream() << g.bpp(n) << " offset " << offset << " " << g.bpp(n->get_root()) << "\n";
);
UNREACHABLE(); UNREACHABLE();
} }

View file

@ -94,22 +94,24 @@ namespace polysat {
// walk the e-graph to retrieve fixed overlaps // walk the e-graph to retrieve fixed overlaps
void solver::get_fixed_bits(pvar pv, fixed_bits_vector& out) { void solver::get_fixed_bits(pvar pv, fixed_bits_vector& out) {
theory_var v = m_pddvar2var[pv];
euf::enode* b = var2enode(v);
std::function<bool(euf::enode*, unsigned)> consume_slice = [&](euf::enode* n, unsigned offset) { std::function<bool(euf::enode*, unsigned)> consume_slice = [&](euf::enode* n, unsigned offset) {
n = n->get_root(); auto r = n->get_root();
if (!n->interpreted()) if (!r->interpreted())
return true; return true;
auto w = n->get_th_var(get_id()); auto w = r->get_th_var(get_id());
if (w == euf::null_theory_var) if (w == euf::null_theory_var)
return true; return true;
unsigned length = bv.get_bv_size(n->get_expr()); unsigned length = bv.get_bv_size(r->get_expr());
rational value; rational value;
VERIFY(bv.is_numeral(n->get_expr(), value)); VERIFY(bv.is_numeral(r->get_expr(), value));
out.push_back({ fixed_slice(value, offset, length) }); out.push_back({ fixed_slice(value, offset, length) });
return false; return false;
}; };
theory_var v = m_pddvar2var[pv];
m_bv_plugin->sub_slices(var2enode(v), consume_slice); m_bv_plugin->sub_slices(b, consume_slice);
m_bv_plugin->super_slices(var2enode(v), consume_slice); m_bv_plugin->super_slices(b, consume_slice);
} }
void solver::explain_slice(pvar pv, pvar pw, unsigned offset, std::function<void(euf::enode*, euf::enode*)>& consume_eq) { void solver::explain_slice(pvar pv, pvar pw, unsigned offset, std::function<void(euf::enode*, euf::enode*)>& consume_eq) {

View file

@ -135,6 +135,10 @@ namespace polysat {
} }
void solver::explain_dep(dependency const& d, euf::enode_pair_vector& eqs, sat::literal_vector& core) { void solver::explain_dep(dependency const& d, euf::enode_pair_vector& eqs, sat::literal_vector& core) {
std::function<void(euf::enode*, euf::enode*)> consume = [&](auto* a, auto* b) {
eqs.push_back({ a, b });
};
if (d.is_axiom()) if (d.is_axiom())
; ;
else if (d.is_bool_var()) { else if (d.is_bool_var()) {
@ -144,16 +148,10 @@ namespace polysat {
} }
else if (d.is_fixed_claim()) { else if (d.is_fixed_claim()) {
auto const& o = d.fixed(); auto const& o = d.fixed();
std::function<void(euf::enode*, euf::enode*)> consume = [&](auto* a, auto* b) {
eqs.push_back({ a, b });
};
explain_fixed(o.v, o, consume); explain_fixed(o.v, o, consume);
} }
else if (d.is_offset_claim()) { else if (d.is_offset_claim()) {
auto const& offs = d.offset(); auto const& offs = d.offset();
std::function<void(euf::enode*, euf::enode*)> consume = [&](auto* a, auto* b) {
eqs.push_back({ a, b });
};
explain_slice(offs.v, offs.w, offs.offset, consume); explain_slice(offs.v, offs.w, offs.offset, consume);
} }
else { else {