3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 03:15:50 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-10-25 09:13:18 -07:00
parent a8049c7feb
commit 64dd4e1c83
6 changed files with 58 additions and 27 deletions

View file

@ -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) {

View file

@ -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());