mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 12:28:44 +00:00
tidy model generator
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
5e5f46f0f8
commit
9f2bafbf10
|
@ -28,6 +28,15 @@ Revision History:
|
|||
|
||||
namespace smt {
|
||||
|
||||
void fresh_value_proc::get_dependencies(buffer<model_value_dependency>& result) {
|
||||
result.push_back(model_value_dependency(m_value));
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, model_value_dependency const& src) {
|
||||
if (src.is_fresh_value()) return out << "fresh!" << src.get_value()->get_idx();
|
||||
else return out << "#" << src.get_enode()->get_owner_id();
|
||||
}
|
||||
|
||||
model_generator::model_generator(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_context(nullptr),
|
||||
|
@ -161,20 +170,20 @@ namespace smt {
|
|||
source2color & colors,
|
||||
obj_hashtable<sort> & already_traversed,
|
||||
svector<source> & todo) {
|
||||
|
||||
if (src.is_fresh_value()) {
|
||||
// there is an implicit dependency between a fresh value stub of sort S and the root enodes of sort S that are not associated with fresh values.
|
||||
// there is an implicit dependency between a fresh value stub of
|
||||
// sort S and the root enodes of sort S that are not associated with fresh values.
|
||||
//
|
||||
sort * s = src.get_value()->get_sort();
|
||||
if (already_traversed.contains(s))
|
||||
return true;
|
||||
bool visited = true;
|
||||
unsigned sz = roots.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
enode * r = roots[i];
|
||||
for (enode * r : roots) {
|
||||
if (m_manager.get_sort(r->get_owner()) != s)
|
||||
continue;
|
||||
SASSERT(r == r->get_root());
|
||||
model_value_proc * proc = nullptr;
|
||||
root2proc.find(r, proc);
|
||||
model_value_proc * proc = root2proc[r];
|
||||
SASSERT(proc);
|
||||
if (proc->is_fresh())
|
||||
continue; // r is associated with a fresh value...
|
||||
|
@ -192,17 +201,12 @@ namespace smt {
|
|||
enode * n = src.get_enode();
|
||||
SASSERT(n == n->get_root());
|
||||
bool visited = true;
|
||||
model_value_proc * proc = nullptr;
|
||||
root2proc.find(n, proc);
|
||||
SASSERT(proc);
|
||||
model_value_proc * proc = root2proc[n];
|
||||
buffer<model_value_dependency> dependencies;
|
||||
proc->get_dependencies(dependencies);
|
||||
for (model_value_dependency const& dep : dependencies) {
|
||||
visit_child(dep, colors, todo, visited);
|
||||
TRACE("mg_top_sort", tout << "#" << n->get_owner_id() << " -> ";
|
||||
if (dep.is_fresh_value()) tout << "fresh!" << dep.get_value()->get_idx();
|
||||
else tout << "#" << dep.get_enode()->get_owner_id();
|
||||
tout << "\n";);
|
||||
TRACE("mg_top_sort", tout << "#" << n->get_owner_id() << " -> " << dep << " already visited: " << visited << "\n";);
|
||||
}
|
||||
return visited;
|
||||
}
|
||||
|
@ -215,9 +219,7 @@ namespace smt {
|
|||
svector<source> & todo,
|
||||
svector<source> & sorted_sources) {
|
||||
TRACE("mg_top_sort", tout << "process source, is_fresh: " << src.is_fresh_value() << " ";
|
||||
if (src.is_fresh_value()) tout << "fresh!" << src.get_value()->get_idx();
|
||||
else tout << "#" << src.get_enode()->get_owner_id();
|
||||
tout << ", todo.size(): " << todo.size() << "\n";);
|
||||
tout << src << ", todo.size(): " << todo.size() << "\n";);
|
||||
int color = get_color(colors, src);
|
||||
SASSERT(color != Grey);
|
||||
if (color == Black)
|
||||
|
@ -227,17 +229,16 @@ namespace smt {
|
|||
while (!todo.empty()) {
|
||||
source curr = todo.back();
|
||||
TRACE("mg_top_sort", tout << "current source, is_fresh: " << curr.is_fresh_value() << " ";
|
||||
if (curr.is_fresh_value()) tout << "fresh!" << curr.get_value()->get_idx();
|
||||
else tout << "#" << curr.get_enode()->get_owner_id();
|
||||
tout << ", todo.size(): " << todo.size() << "\n";);
|
||||
tout << curr << ", todo.size(): " << todo.size() << "\n";);
|
||||
switch (get_color(colors, curr)) {
|
||||
case White:
|
||||
set_color(colors, curr, Grey);
|
||||
visit_children(curr, roots, root2proc, colors, already_traversed, todo);
|
||||
break;
|
||||
case Grey:
|
||||
SASSERT(visit_children(curr, roots, root2proc, colors, already_traversed, todo));
|
||||
// SASSERT(visit_children(curr, roots, root2proc, colors, already_traversed, todo));
|
||||
set_color(colors, curr, Black);
|
||||
TRACE("mg_top_sort", tout << "append " << curr << "\n";);
|
||||
sorted_sources.push_back(curr);
|
||||
break;
|
||||
case Black:
|
||||
|
@ -266,18 +267,15 @@ namespace smt {
|
|||
// topological sort
|
||||
|
||||
// traverse all extra fresh values...
|
||||
unsigned sz = m_extra_fresh_values.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
extra_fresh_value * f = m_extra_fresh_values[i];
|
||||
for (extra_fresh_value * f : m_extra_fresh_values) {
|
||||
process_source(source(f), roots, root2proc, colors, already_traversed, todo, sorted_sources);
|
||||
}
|
||||
|
||||
// traverse all enodes that are associated with fresh values...
|
||||
sz = roots.size();
|
||||
unsigned sz = roots.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
enode * r = roots[i];
|
||||
model_value_proc * proc = nullptr;
|
||||
root2proc.find(r, proc);
|
||||
model_value_proc * proc = root2proc[r];
|
||||
SASSERT(proc);
|
||||
if (!proc->is_fresh())
|
||||
continue;
|
||||
|
@ -303,43 +301,38 @@ namespace smt {
|
|||
TRACE("sorted_sources",
|
||||
for (source const& curr : sources) {
|
||||
if (curr.is_fresh_value()) {
|
||||
tout << "fresh!" << curr.get_value()->get_idx() << " " << mk_pp(curr.get_value()->get_sort(), m_manager) << "\n";
|
||||
tout << curr << " " << mk_pp(curr.get_value()->get_sort(), m_manager) << "\n";
|
||||
}
|
||||
else {
|
||||
enode * n = curr.get_enode();
|
||||
SASSERT(n->get_root() == n);
|
||||
sort * s = m_manager.get_sort(n->get_owner());
|
||||
tout << "#" << n->get_owner_id() << " " << mk_pp(s, m_manager);
|
||||
model_value_proc * proc = 0;
|
||||
root2proc.find(n, proc);
|
||||
SASSERT(proc);
|
||||
tout << " is_fresh: " << proc->is_fresh() << "\n";
|
||||
tout << curr << " " << mk_pp(s, m_manager);
|
||||
tout << " is_fresh: " << root2proc[n]->is_fresh() << "\n";
|
||||
}
|
||||
});
|
||||
for (source const& curr : sources) {
|
||||
if (curr.is_fresh_value()) {
|
||||
sort * s = curr.get_value()->get_sort();
|
||||
TRACE("model_fresh_bug", tout << "mk fresh!" << curr.get_value()->get_idx() << " : " << mk_pp(s, m_manager) << "\n";);
|
||||
TRACE("model_fresh_bug", tout << curr << " : " << mk_pp(s, m_manager) << "\n";);
|
||||
expr * val = m_model->get_fresh_value(s);
|
||||
TRACE("model_fresh_bug", tout << "mk fresh!" << curr.get_value()->get_idx() << " := #" << (val == 0 ? UINT_MAX : val->get_id()) << "\n";);
|
||||
TRACE("model_fresh_bug", tout << curr << " := #" << (val == nullptr ? UINT_MAX : val->get_id()) << "\n";);
|
||||
m_asts.push_back(val);
|
||||
curr.get_value()->set_value(val);
|
||||
}
|
||||
else {
|
||||
enode * n = curr.get_enode();
|
||||
SASSERT(n->get_root() == n);
|
||||
TRACE("mg_top_sort", tout << "#" << n->get_owner_id() << "\n";);
|
||||
TRACE("mg_top_sort", tout << curr << "\n";);
|
||||
dependencies.reset();
|
||||
dependency_values.reset();
|
||||
model_value_proc * proc = nullptr;
|
||||
VERIFY(root2proc.find(n, proc));
|
||||
model_value_proc * proc = root2proc[n];
|
||||
SASSERT(proc);
|
||||
proc->get_dependencies(dependencies);
|
||||
for (model_value_dependency const& d : dependencies) {
|
||||
if (d.is_fresh_value()) {
|
||||
CTRACE("mg_top_sort", !d.get_value()->get_value(),
|
||||
tout << "#" << n->get_owner_id() << " -> ";
|
||||
tout << "fresh!" << d.get_value()->get_idx() << "\n";);
|
||||
tout << "#" << n->get_owner_id() << " -> " << d << "\n";);
|
||||
SASSERT(d.get_value()->get_value());
|
||||
dependency_values.push_back(d.get_value()->get_value());
|
||||
}
|
||||
|
|
|
@ -100,14 +100,16 @@ namespace smt {
|
|||
extra_fresh_value * m_value; //!< When m_fresh == true, contains the sort of the fresh value
|
||||
};
|
||||
public:
|
||||
model_value_dependency():m_fresh(true), m_value(nullptr) {}
|
||||
model_value_dependency(enode * n):m_fresh(false), m_enode(n->get_root()) {}
|
||||
model_value_dependency(extra_fresh_value * v):m_fresh(true), m_value(v) {}
|
||||
model_value_dependency():m_fresh(true), m_value(nullptr) { }
|
||||
explicit model_value_dependency(enode * n):m_fresh(false), m_enode(n->get_root()) {}
|
||||
explicit model_value_dependency(extra_fresh_value * v) :m_fresh(true), m_value(v) { SASSERT(v); }
|
||||
bool is_fresh_value() const { return m_fresh; }
|
||||
enode * get_enode() const { SASSERT(!is_fresh_value()); return m_enode; }
|
||||
extra_fresh_value * get_value() const { SASSERT(is_fresh_value()); return m_value; }
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& out, model_value_dependency const& d);
|
||||
|
||||
typedef model_value_dependency source;
|
||||
|
||||
struct source_hash_proc {
|
||||
|
@ -166,7 +168,7 @@ namespace smt {
|
|||
extra_fresh_value * m_value;
|
||||
public:
|
||||
fresh_value_proc(extra_fresh_value * v):m_value(v) {}
|
||||
void get_dependencies(buffer<model_value_dependency> & result) override { result.push_back(m_value); }
|
||||
void get_dependencies(buffer<model_value_dependency> & result) override;
|
||||
app * mk_value(model_generator & m, ptr_vector<expr> & values) override { return to_app(values[0]); }
|
||||
bool is_fresh() const override { return true; }
|
||||
};
|
||||
|
|
|
@ -636,6 +636,7 @@ namespace smt {
|
|||
void add_dependency(enode * n) { m_dependencies.push_back(model_value_dependency(n)); }
|
||||
~datatype_value_proc() override {}
|
||||
void get_dependencies(buffer<model_value_dependency> & result) override {
|
||||
for (model_value_dependency& d : m_dependencies) { }
|
||||
result.append(m_dependencies.size(), m_dependencies.c_ptr());
|
||||
}
|
||||
app * mk_value(model_generator & mg, ptr_vector<expr> & values) override {
|
||||
|
|
Loading…
Reference in a new issue