3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-09 04:31:24 +00:00

saturate worklist

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2024-10-18 14:05:10 -07:00
parent a72ad44200
commit 6c3fe3cf46

View file

@ -276,10 +276,10 @@ namespace sls {
if (n->is_root()) if (n->is_root())
add_dep(n, deps); add_dep(n, deps);
auto trace_assignment = [&](euf::enode* n) { auto trace_assignment = [&](std::ostream& out, euf::enode* n) {
for (auto sib : euf::enode_class(n)) for (auto sib : euf::enode_class(n))
tout << g->bpp(sib) << " "; out << g->bpp(sib) << " ";
tout << " <- " << mk_bounded_pp(m_values.get(n->get_id()), m) << "\n"; out << " <- " << mk_bounded_pp(m_values.get(n->get_id()), m) << "\n";
}; };
deps.topological_sort(); deps.topological_sort();
expr_ref_vector args(m); expr_ref_vector args(m);
@ -317,7 +317,7 @@ namespace sls {
if (!has_null) { if (!has_null) {
m_values.setx(id, m.mk_app(f, args)); m_values.setx(id, m.mk_app(f, args));
m_model->register_value(m_values.get(id)); m_model->register_value(m_values.get(id));
TRACE("dt", tout << "Set interpretation "; trace_assignment(n);); TRACE("dt", tout << "Set interpretation "; trace_assignment(tout, n););
} }
} }
@ -335,27 +335,13 @@ namespace sls {
} }
); );
// attach fresh values to each leaf, walk up parents to assign them values. auto process_workitem = [&](euf::enode* n) {
while (!leaves.empty()) {
SASSERT(worklist.empty());
auto n = leaves.back();
leaves.pop_back();
SASSERT(!get_constructor(n));
auto v = m_model->get_fresh_value(n->get_sort());
if (!v)
v = m_model->get_some_value(n->get_sort());
SASSERT(v);
unsigned id = n->get_id();
m_values.setx(id, v);
TRACE("dt", tout << "Fresh interpretation "; trace_assignment(n););
worklist.push_back(n);
while (!worklist.empty()) {
n = worklist.back();
worklist.pop_back();
if (!leaf2root.contains(n)) if (!leaf2root.contains(n))
continue; return true;
bool all_processed = true;
for (auto p : leaf2root[n]) { for (auto p : leaf2root[n]) {
if (m_values.get(p->get_id(), nullptr))
continue;
auto con = get_constructor(p); auto con = get_constructor(p);
SASSERT(con); SASSERT(con);
auto f = con->get_decl(); auto f = con->get_decl();
@ -371,15 +357,44 @@ namespace sls {
else else
args.push_back(ctx.get_value(arg->get_expr())); args.push_back(ctx.get_value(arg->get_expr()));
} }
if (has_missing) if (has_missing) {
all_processed = false;
continue; continue;
}
worklist.push_back(p); worklist.push_back(p);
SASSERT(all_of(args, [&](expr* e) { return e != nullptr; })); SASSERT(all_of(args, [&](expr* e) { return e != nullptr; }));
m_values.setx(p->get_id(), m.mk_app(f, args)); m_values.setx(p->get_id(), m.mk_app(f, args));
TRACE("dt", tout << "Patched interpretation "; trace_assignment(p);); TRACE("dt", tout << "Patched interpretation "; trace_assignment(tout, p););
m_model->register_value(m_values.get(p->get_id())); m_model->register_value(m_values.get(p->get_id()));
} }
} return all_processed;
};
auto process_worklist = [&](euf::enode_vector& worklist) {
unsigned j = 0, sz = worklist.size();
for (unsigned i = 0; i < worklist.size(); ++i)
if (!process_workitem(worklist[i]))
worklist[j++] = worklist[i];
worklist.shrink(j);
return j < sz;
};
// attach fresh values to each leaf, walk up parents to assign them values.
while (!leaves.empty()) {
auto n = leaves.back();
leaves.pop_back();
SASSERT(!get_constructor(n));
auto v = m_model->get_fresh_value(n->get_sort());
if (!v)
v = m_model->get_some_value(n->get_sort());
SASSERT(v);
unsigned id = n->get_id();
m_values.setx(id, v);
TRACE("dt", tout << "Fresh interpretation "; trace_assignment(tout, n););
worklist.reset();
worklist.push_back(n);
while (process_worklist(worklist))
;
} }
} }