mirror of
https://github.com/Z3Prover/z3
synced 2025-04-28 03:15:50 +00:00
parent
a8049c7feb
commit
64dd4e1c83
6 changed files with 58 additions and 27 deletions
|
@ -19,6 +19,7 @@ Revision History:
|
|||
#include "ast/ast_pp.h"
|
||||
#include "ast/ast_ll_pp.h"
|
||||
#include "ast/well_sorted.h"
|
||||
#include "ast/array_decl_plugin.h"
|
||||
#include "ast/used_symbols.h"
|
||||
#include "ast/for_each_expr.h"
|
||||
#include "ast/rewriter/var_subst.h"
|
||||
|
@ -119,19 +120,23 @@ bool proto_model::eval(expr * e, expr_ref & result, bool model_completion) {
|
|||
\brief Replace uninterpreted constants occurring in fi->get_else()
|
||||
by their interpretations.
|
||||
*/
|
||||
void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_aux_fs) {
|
||||
if (fi->is_partial())
|
||||
return;
|
||||
expr * fi_else = fi->get_else();
|
||||
TRACE("model_bug", tout << "cleaning up:\n" << mk_pp(fi_else, m) << "\n";);
|
||||
void proto_model::cleanup_func_interp(expr_ref_vector& trail, func_interp * fi, func_decl_set & found_aux_fs) {
|
||||
if (!fi->is_partial()) {
|
||||
expr * fi_else = fi->get_else();
|
||||
fi->set_else(cleanup_expr(trail, fi_else, found_aux_fs));
|
||||
}
|
||||
}
|
||||
|
||||
expr* proto_model::cleanup_expr(expr_ref_vector& trail, expr* fi_else, func_decl_set& found_aux_fs) {
|
||||
TRACE("model_bug", tout << "cleaning up:\n" << mk_pp(fi_else, m) << "\n";);
|
||||
trail.reset();
|
||||
obj_map<expr, expr*> cache;
|
||||
expr_ref_vector trail(m);
|
||||
ptr_buffer<expr, 128> todo;
|
||||
ptr_buffer<expr> args;
|
||||
todo.push_back(fi_else);
|
||||
|
||||
expr * a;
|
||||
expr_ref new_t(m);
|
||||
|
||||
while (!todo.empty()) {
|
||||
a = todo.back();
|
||||
if (is_uninterp_const(a)) {
|
||||
|
@ -168,8 +173,7 @@ void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_au
|
|||
TRACE("model_bug", tout << f->get_name() << "\n";);
|
||||
found_aux_fs.insert(f);
|
||||
}
|
||||
expr_ref new_t(m);
|
||||
new_t = m_rewrite.mk_app(f, args.size(), args.c_ptr());
|
||||
new_t = m_rewrite.mk_app(f, args.size(), args.c_ptr());
|
||||
if (t != new_t.get())
|
||||
trail.push_back(new_t);
|
||||
todo.pop_back();
|
||||
|
@ -177,7 +181,7 @@ void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_au
|
|||
break;
|
||||
}
|
||||
default:
|
||||
SASSERT(a != 0);
|
||||
SASSERT(a != nullptr);
|
||||
cache.insert(a, a);
|
||||
todo.pop_back();
|
||||
break;
|
||||
|
@ -187,17 +191,14 @@ void proto_model::cleanup_func_interp(func_interp * fi, func_decl_set & found_au
|
|||
|
||||
VERIFY(cache.find(fi_else, a));
|
||||
|
||||
fi->set_else(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
void proto_model::remove_aux_decls_not_in_set(ptr_vector<func_decl> & decls, func_decl_set const & s) {
|
||||
unsigned sz = decls.size();
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
func_decl * f = decls[i];
|
||||
for (func_decl* f : decls) {
|
||||
if (!m_aux_decls.contains(f) || s.contains(f)) {
|
||||
decls[j] = f;
|
||||
j++;
|
||||
decls[j++] = f;
|
||||
}
|
||||
}
|
||||
decls.shrink(j);
|
||||
|
@ -211,12 +212,21 @@ void proto_model::remove_aux_decls_not_in_set(ptr_vector<func_decl> & decls, fun
|
|||
void proto_model::cleanup() {
|
||||
TRACE("model_bug", model_v2_pp(tout, *this););
|
||||
func_decl_set found_aux_fs;
|
||||
expr_ref_vector trail(m);
|
||||
for (auto const& kv : m_finterp) {
|
||||
TRACE("model_bug", tout << kv.m_key->get_name() << "\n";);
|
||||
func_interp * fi = kv.m_value;
|
||||
cleanup_func_interp(fi, found_aux_fs);
|
||||
cleanup_func_interp(trail, fi, found_aux_fs);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < m_const_decls.size(); ++i) {
|
||||
func_decl* d = m_const_decls[i];
|
||||
expr* e = m_interp[d];
|
||||
expr* r = cleanup_expr(trail, e, found_aux_fs);
|
||||
if (e != r) {
|
||||
register_decl(d, r);
|
||||
}
|
||||
}
|
||||
// TRACE("model_bug", model_v2_pp(tout, *this););
|
||||
// remove auxiliary declarations that are not used.
|
||||
if (found_aux_fs.size() != m_aux_decls.size()) {
|
||||
remove_aux_decls_not_in_set(m_decls, found_aux_fs);
|
||||
|
@ -224,12 +234,13 @@ void proto_model::cleanup() {
|
|||
|
||||
for (func_decl* faux : m_aux_decls) {
|
||||
if (!found_aux_fs.contains(faux)) {
|
||||
TRACE("cleanup_bug", tout << "eliminating " << faux->get_name() << "\n";);
|
||||
TRACE("cleanup_bug", tout << "eliminating " << faux->get_name() << " " << faux->get_ref_count() << "\n";);
|
||||
unregister_decl(faux);
|
||||
}
|
||||
}
|
||||
m_aux_decls.swap(found_aux_fs);
|
||||
}
|
||||
TRACE("model_bug", model_v2_pp(tout, *this););
|
||||
}
|
||||
|
||||
value_factory * proto_model::get_factory(family_id fid) {
|
||||
|
|
|
@ -55,8 +55,8 @@ class proto_model : public model_core {
|
|||
// Invariant: m_const_decls subset m_decls
|
||||
|
||||
void remove_aux_decls_not_in_set(ptr_vector<func_decl> & decls, func_decl_set const & s);
|
||||
void cleanup_func_interp(func_interp * fi, func_decl_set & found_aux_fs);
|
||||
|
||||
void cleanup_func_interp(expr_ref_vector& trail, func_interp * fi, func_decl_set & found_aux_fs);
|
||||
expr* cleanup_expr(expr_ref_vector& trail, expr* fi_else, func_decl_set& found_aux_fs);
|
||||
|
||||
public:
|
||||
proto_model(ast_manager & m, params_ref const & p = params_ref());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue