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

fixing 2267

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-05-06 15:31:55 +02:00
parent 16af728fbe
commit 28ce701e17
15 changed files with 174 additions and 48 deletions

View file

@ -21,6 +21,7 @@ Revision History:
#include "ast/ast_smt2_pp.h"
#include "ast/ast_util.h"
#include "model/func_interp.h"
#include "ast/array_decl_plugin.h"
func_entry::func_entry(ast_manager & m, unsigned arity, expr * const * args, expr * result):
m_args_are_values(true),
@ -316,6 +317,37 @@ bool func_interp::is_identity() const {
return (sz.size() == m_entries.size() + 1);
}
expr_ref func_interp::get_array_interp(sort_ref_vector const& domain) const {
if (m_else == nullptr)
return expr_ref(m_manager);
if (!is_ground(m_else)) {
return expr_ref(m_manager);
}
array_util autil(m_manager);
sort_ref A(autil.mk_array_sort(domain.size(), domain.c_ptr(), m_manager.get_sort(m_else)), m_manager);
expr_ref r(autil.mk_const_array(A, m_else), m_manager);
expr_ref_vector args(m_manager);
for (func_entry * curr : m_entries) {
expr * res = curr->get_result();
if (m_else == res) {
continue;
}
args.reset();
args.push_back(r);
for (unsigned i = 0; i < m_arity; i++) {
expr* arg = curr->get_arg(i);
if (!is_ground(arg)) {
return expr_ref(m_manager);
}
args.push_back(arg);
}
args.push_back(res);
r = autil.mk_store(args.size(), args.c_ptr());
}
return r;
}
expr * func_interp::get_interp_core() const {
if (m_else == nullptr)
return nullptr;

View file

@ -112,6 +112,8 @@ public:
expr * get_interp() const;
expr_ref get_array_interp(sort_ref_vector const& domain) const;
func_interp * translate(ast_translation & translator) const;
private:

View file

@ -401,15 +401,25 @@ expr_ref model::cleanup_expr(top_sort& ts, expr* e, unsigned current_partition)
continue;
}
fi = nullptr;
new_t = nullptr;
sort_ref_vector domain(m);
if (autil.is_as_array(a)) {
func_decl* f = autil.get_as_array_func_decl(a);
// only expand auxiliary definitions that occur once.
if (can_inline_def(ts, f)) {
fi = get_func_interp(f);
for (sort* s : *f) {
domain.push_back(s);
}
new_t = fi->get_array_interp(domain);
TRACE("model", tout << new_t << "\n";);
}
}
if (fi && fi->get_interp()) {
if (new_t) {
// noop
}
else if (fi && fi->get_interp()) {
f = autil.get_as_array_func_decl(a);
expr_ref_vector sargs(m);
sort_ref_vector vars(m);
@ -484,6 +494,10 @@ void model::set_solver(expr_solver* s) {
m_mev.set_solver(s);
}
bool model::has_solver() {
return m_mev.has_solver();
}
expr_ref_vector model::operator()(expr_ref_vector const& ts) {
expr_ref_vector rs(m);
for (expr* t : ts) rs.push_back((*this)(t));

View file

@ -95,6 +95,7 @@ public:
bool is_false(expr* t);
bool is_true(expr_ref_vector const& ts);
void reset_eval_cache();
bool has_solver();
void set_solver(expr_solver* solver);
class scoped_model_completion {

View file

@ -695,3 +695,7 @@ bool model_evaluator::eval(expr_ref_vector const& ts, expr_ref& r, bool model_co
void model_evaluator::set_solver(expr_solver* solver) {
m_imp->m_cfg.m_seq_rw.set_solver(solver);
}
bool model_evaluator::has_solver() {
return m_imp->m_cfg.m_seq_rw.has_solver();
}

View file

@ -57,6 +57,7 @@ public:
bool is_true(expr_ref_vector const& ts);
void set_solver(expr_solver* solver);
bool has_solver();
/**
* best effort evaluator of extensional array equality.

View file

@ -194,11 +194,13 @@ static void pp_funs(std::ostream & out, ast_printer_context & ctx, model_core co
ptr_buffer<format> f_entry_conds;
ptr_buffer<func_decl> func_decls;
sort_fun_decls(m, md, func_decls);
for (unsigned i = 0; i < func_decls.size(); i++) {
func_decl * f = func_decls[i];
for (func_decl * f : func_decls) {
if (recfun_util.is_defined(f) && !recfun_util.is_generated(f)) {
continue;
}
if (!m.is_considered_uninterpreted(f)) {
continue;
}
func_interp * f_i = md.get_func_interp(f);
SASSERT(f->get_arity() == f_i->get_arity());
format_ref body(fm(m));
@ -216,8 +218,8 @@ static void pp_funs(std::ostream & out, ast_printer_context & ctx, model_core co
}
TRACE("model_smt2_pp", for (unsigned i = 0; i < var_names.size(); i++) tout << var_names[i] << "\n";);
f_var_names.reset();
for (unsigned i = 0; i < f->get_arity(); i++)
f_var_names.push_back(mk_string(m, var_names[i].bare_str()));
for (auto const& vn : var_names)
f_var_names.push_back(mk_string(m, vn.bare_str()));
f_arg_decls.reset();
for (unsigned i = 0; i < f->get_arity(); i++) {
format_ref f_domain(fm(m));