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:
parent
a72ad44200
commit
6c3fe3cf46
1 changed files with 52 additions and 37 deletions
|
@ -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))
|
||||||
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue