mirror of
https://github.com/Z3Prover/z3
synced 2026-02-08 10:07:59 +00:00
working on sub/super slices
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
9a7e50c1e8
commit
5bbec43235
4 changed files with 134 additions and 24 deletions
|
|
@ -36,7 +36,7 @@ namespace polysat {
|
|||
}
|
||||
};
|
||||
|
||||
void solver::get_subslices(pvar pv, subslice_infos& slices) {
|
||||
void solver::get_sub_slices(pvar pv, slice_infos& slices) {
|
||||
theory_var v = m_pddvar2var[pv];
|
||||
unsigned lo, hi;
|
||||
expr* e = nullptr;
|
||||
|
|
@ -60,11 +60,11 @@ namespace polysat {
|
|||
}
|
||||
}
|
||||
for (auto p : euf::enode_parents(n->get_root())) {
|
||||
if (p->is_marked1())
|
||||
if (p->get_root()->is_marked1())
|
||||
continue;
|
||||
if (bv.is_extract(p->get_expr(), lo, hi, e)) {
|
||||
auto child = expr2enode(e);
|
||||
SASSERT(n == child->get_root());
|
||||
SASSERT(n->get_root() == child->get_root());
|
||||
scoped_eq_justification sp(*this, just, child, n);
|
||||
slices.push_back({ p, offset + lo, just });
|
||||
}
|
||||
|
|
@ -74,41 +74,136 @@ namespace polysat {
|
|||
n->get_root()->unmark1();
|
||||
}
|
||||
|
||||
void solver::get_super_slices(pvar pv, slice_infos& slices) {
|
||||
theory_var v = m_pddvar2var[pv];
|
||||
unsigned lo, hi;
|
||||
expr* e = nullptr;
|
||||
euf::enode* n = var2enode(v);
|
||||
slices.push_back({ n, 0, {} });
|
||||
|
||||
// walk the egraph starting with pvar for overlaps.
|
||||
for (unsigned i = 0; i < slices.size(); ++i) {
|
||||
auto [n, offset, just] = slices[i];
|
||||
if (n->get_root()->is_marked1())
|
||||
continue;
|
||||
n->get_root()->mark1();
|
||||
for (auto sib : euf::enode_class(n)) {
|
||||
if (bv.is_extract(sib->get_expr(), lo, hi, e)) {
|
||||
auto child = expr2enode(e);
|
||||
SASSERT(n->get_root() == child->get_root());
|
||||
scoped_eq_justification sp(*this, just, child, n);
|
||||
slices.push_back({ sib, offset + lo, just });
|
||||
}
|
||||
}
|
||||
for (auto p : euf::enode_parents(n->get_root())) {
|
||||
if (p->get_root()->is_marked1())
|
||||
continue;
|
||||
if (bv.is_concat(p->get_expr())) {
|
||||
unsigned delta = 0;
|
||||
for (unsigned j = p->num_args(); j-- > 0; ) {
|
||||
auto arg = p->get_arg(j);
|
||||
if (arg->get_root() == n->get_root()) {
|
||||
scoped_eq_justification sp(*this, just, arg, n);
|
||||
slices.push_back({ p, offset + delta, just });
|
||||
}
|
||||
delta += bv.get_bv_size(arg->get_expr());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto const& [n, offset, d] : slices)
|
||||
n->get_root()->unmark1();
|
||||
}
|
||||
|
||||
|
||||
// walk the egraph starting with pvar for suffix overlaps.
|
||||
void solver::get_bitvector_suffixes(pvar pv, justified_slices& out) {
|
||||
subslice_infos slices;
|
||||
get_subslices(pv, slices);
|
||||
slice_infos slices;
|
||||
get_sub_slices(pv, slices);
|
||||
uint_set seen;
|
||||
|
||||
for (auto& [n, offset, just] : slices) {
|
||||
if (offset != 0)
|
||||
continue;
|
||||
auto w = n->get_th_var(get_id());
|
||||
if (w == euf::null_theory_var)
|
||||
continue;
|
||||
auto const& p = m_var2pdd[w];
|
||||
if (p.is_var())
|
||||
out.push_back({ p.var(), dependency(just, s().scope_lvl())}); // approximate to current scope
|
||||
for (auto sib : euf::enode_class(n)) {
|
||||
auto w = sib->get_th_var(get_id());
|
||||
if (w == euf::null_theory_var)
|
||||
continue;
|
||||
if (seen.contains(w))
|
||||
continue;
|
||||
seen.insert(w);
|
||||
auto const& p = m_var2pdd[w];
|
||||
if (!p.is_var())
|
||||
continue;
|
||||
scoped_eq_justification sp(*this, just, sib, n);
|
||||
out.push_back({ p.var(), offset, dependency(just, s().scope_lvl()) }); // approximate to current scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// walk the egraph starting with pvar for any overlaps.
|
||||
void solver::get_bitvector_sub_slices(pvar pv, justified_slices& out) {
|
||||
slice_infos slices;
|
||||
get_sub_slices(pv, slices);
|
||||
uint_set seen;
|
||||
|
||||
for (auto& [n, offset, just] : slices) {
|
||||
for (auto sib : euf::enode_class(n)) {
|
||||
auto w = sib->get_th_var(get_id());
|
||||
if (w == euf::null_theory_var)
|
||||
continue;
|
||||
if (seen.contains(w))
|
||||
continue;
|
||||
seen.insert(w);
|
||||
auto const& p = m_var2pdd[w];
|
||||
if (!p.is_var())
|
||||
continue;
|
||||
scoped_eq_justification sp(*this, just, sib, n);
|
||||
out.push_back({ p.var(), offset, dependency(just, s().scope_lvl()) }); // approximate to current scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// walk the egraph for bit-vectors that contain pv.
|
||||
void solver::get_bitvector_super_slices(pvar pv, justified_slices& out) {
|
||||
slice_infos slices;
|
||||
get_super_slices(pv, slices);
|
||||
uint_set seen;
|
||||
|
||||
for (auto& [n, offset, just] : slices) {
|
||||
for (auto sib : euf::enode_class(n)) {
|
||||
auto w = sib->get_th_var(get_id());
|
||||
if (w == euf::null_theory_var)
|
||||
continue;
|
||||
if (seen.contains(w))
|
||||
continue;
|
||||
seen.insert(w);
|
||||
auto const& p = m_var2pdd[w];
|
||||
if (!p.is_var())
|
||||
continue;
|
||||
scoped_eq_justification sp(*this, just, sib, n);
|
||||
out.push_back({ p.var(), offset, dependency(just, s().scope_lvl()) }); // approximate to current scope
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// walk the e-graph to retrieve fixed overlaps
|
||||
void solver::get_fixed_bits(pvar pv, justified_fixed_bits& out) {
|
||||
subslice_infos slices;
|
||||
get_subslices(pv, slices);
|
||||
slice_infos slices;
|
||||
get_sub_slices(pv, slices);
|
||||
|
||||
for (auto& [n, offset, just] : slices) {
|
||||
if (offset != 0)
|
||||
continue;
|
||||
n = n->get_root();
|
||||
if (!n->interpreted())
|
||||
if (!n->get_root()->interpreted())
|
||||
continue;
|
||||
auto w = n->get_th_var(get_id());
|
||||
|
||||
auto w = n->get_root()->get_th_var(get_id());
|
||||
if (w == euf::null_theory_var)
|
||||
continue;
|
||||
auto const& p = m_var2pdd[w];
|
||||
if (!p.is_var())
|
||||
continue;
|
||||
scoped_eq_justification sp(*this, just, n, n->get_root());
|
||||
unsigned lo = offset, hi = bv.get_bv_size(n->get_expr());
|
||||
rational value;
|
||||
VERIFY(bv.is_numeral(n->get_expr(), value));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue