mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 12:08:18 +00:00
fix evaluator for array store expressions
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
46a4bc6030
commit
be9d5c7088
|
@ -26,6 +26,7 @@ void array_rewriter::updt_params(params_ref const & _p) {
|
||||||
m_sort_store = p.sort_store();
|
m_sort_store = p.sort_store();
|
||||||
m_expand_select_store = p.expand_select_store();
|
m_expand_select_store = p.expand_select_store();
|
||||||
m_expand_store_eq = p.expand_store_eq();
|
m_expand_store_eq = p.expand_store_eq();
|
||||||
|
m_expand_select_ite = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_rewriter::get_param_descrs(param_descrs & r) {
|
void array_rewriter::get_param_descrs(param_descrs & r) {
|
||||||
|
@ -201,6 +202,17 @@ br_status array_rewriter::mk_select_core(unsigned num_args, expr * const * args,
|
||||||
result = m().mk_app(f, num_args - 1, args + 1);
|
result = m().mk_app(f, num_args - 1, args + 1);
|
||||||
return BR_REWRITE1;
|
return BR_REWRITE1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr* c, *th, *el;
|
||||||
|
if (m_expand_select_ite && m().is_ite(args[0], c, th, el)) {
|
||||||
|
ptr_vector<expr> args1, args2;
|
||||||
|
args1.push_back(th);
|
||||||
|
args1.append(num_args-1, args + 1);
|
||||||
|
args2.push_back(el);
|
||||||
|
args2.append(num_args-1, args + 1);
|
||||||
|
result = m().mk_ite(c, m_util.mk_select(num_args, args1.c_ptr()), m_util.mk_select(num_args, args2.c_ptr()));
|
||||||
|
return BR_REWRITE2;
|
||||||
|
}
|
||||||
|
|
||||||
return BR_FAILED;
|
return BR_FAILED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ class array_rewriter {
|
||||||
bool m_sort_store;
|
bool m_sort_store;
|
||||||
bool m_expand_select_store;
|
bool m_expand_select_store;
|
||||||
bool m_expand_store_eq;
|
bool m_expand_store_eq;
|
||||||
|
bool m_expand_select_ite;
|
||||||
template<bool CHECK_DISEQ>
|
template<bool CHECK_DISEQ>
|
||||||
lbool compare_args(unsigned num_args, expr * const * args1, expr * const * args2);
|
lbool compare_args(unsigned num_args, expr * const * args1, expr * const * args2);
|
||||||
public:
|
public:
|
||||||
|
@ -43,6 +44,8 @@ public:
|
||||||
ast_manager & m() const { return m_util.get_manager(); }
|
ast_manager & m() const { return m_util.get_manager(); }
|
||||||
family_id get_fid() const { return m_util.get_family_id(); }
|
family_id get_fid() const { return m_util.get_family_id(); }
|
||||||
|
|
||||||
|
void set_expand_select_store(bool f) { m_expand_select_store = f; }
|
||||||
|
void set_expand_select_ite(bool f) { m_expand_select_ite = f; }
|
||||||
void updt_params(params_ref const & p);
|
void updt_params(params_ref const & p);
|
||||||
static void get_param_descrs(param_descrs & r);
|
static void get_param_descrs(param_descrs & r);
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,7 @@ Revision History:
|
||||||
#include"cooperate.h"
|
#include"cooperate.h"
|
||||||
#include"ast_pp.h"
|
#include"ast_pp.h"
|
||||||
#include"ast_util.h"
|
#include"ast_util.h"
|
||||||
|
#include"model_smt2_pp.h"
|
||||||
|
|
||||||
|
|
||||||
struct evaluator_cfg : public default_rewriter_cfg {
|
struct evaluator_cfg : public default_rewriter_cfg {
|
||||||
|
@ -69,6 +70,8 @@ struct evaluator_cfg : public default_rewriter_cfg {
|
||||||
m_a_rw.set_flat(flat);
|
m_a_rw.set_flat(flat);
|
||||||
m_bv_rw.set_flat(flat);
|
m_bv_rw.set_flat(flat);
|
||||||
m_bv_rw.set_mkbv2num(true);
|
m_bv_rw.set_mkbv2num(true);
|
||||||
|
m_ar_rw.set_expand_select_store(true);
|
||||||
|
m_ar_rw.set_expand_select_ite(true);
|
||||||
updt_params(p);
|
updt_params(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,6 +403,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
|
||||||
SASSERT(m_ar.is_array(a));
|
SASSERT(m_ar.is_array(a));
|
||||||
bool are_values = true;
|
bool are_values = true;
|
||||||
are_unique = true;
|
are_unique = true;
|
||||||
|
TRACE("model_evaluator", tout << mk_pp(a, m()) << "\n";);
|
||||||
|
|
||||||
while (m_ar.is_store(a)) {
|
while (m_ar.is_store(a)) {
|
||||||
expr_ref_vector store(m());
|
expr_ref_vector store(m());
|
||||||
|
@ -438,13 +442,28 @@ struct evaluator_cfg : public default_rewriter_cfg {
|
||||||
}
|
}
|
||||||
else_case = g->get_else();
|
else_case = g->get_else();
|
||||||
if (!else_case) {
|
if (!else_case) {
|
||||||
TRACE("model_evaluator", tout << "no else case " << mk_pp(a, m()) << "\n";);
|
TRACE("model_evaluator", tout << "no else case " << mk_pp(a, m()) << "\n";
|
||||||
|
/*model_smt2_pp(tout, m(), m_model, 0);*/
|
||||||
|
);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!is_ground(else_case)) {
|
if (!is_ground(else_case)) {
|
||||||
TRACE("model_evaluator", tout << "non-ground else case " << mk_pp(a, m()) << "\n" << else_case << "\n";);
|
TRACE("model_evaluator", tout << "non-ground else case " << mk_pp(a, m()) << "\n" << else_case << "\n";);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (m_ar.is_as_array(else_case)) {
|
||||||
|
bool are_unique1 = true;
|
||||||
|
expr_ref tmp(m());
|
||||||
|
unsigned num_stores = stores.size();
|
||||||
|
if (!extract_array_func_interp(else_case, stores, tmp, are_unique1)) {
|
||||||
|
stores.shrink(num_stores);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sort* srt = m().get_sort(else_case);
|
||||||
|
else_case = m_ar.mk_const_array(srt, tmp);
|
||||||
|
are_unique &= are_unique1;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (unsigned i = stores.size(); are_values && i > 0; ) {
|
for (unsigned i = stores.size(); are_values && i > 0; ) {
|
||||||
--i;
|
--i;
|
||||||
if (m().are_equal(else_case, stores[i].back())) {
|
if (m().are_equal(else_case, stores[i].back())) {
|
||||||
|
|
|
@ -404,7 +404,7 @@ namespace smt {
|
||||||
r = assert_delayed_axioms();
|
r = assert_delayed_axioms();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("as_array", tout << "m_found_unsupported_op: " << m_found_unsupported_op << " " << r << "\n";);
|
TRACE("array", tout << "m_found_unsupported_op: " << m_found_unsupported_op << " " << r << "\n";);
|
||||||
if (r == FC_DONE && m_found_unsupported_op)
|
if (r == FC_DONE && m_found_unsupported_op)
|
||||||
r = FC_GIVEUP;
|
r = FC_GIVEUP;
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace smt {
|
||||||
}
|
}
|
||||||
|
|
||||||
void theory_array_base::found_unsupported_op(expr * n) {
|
void theory_array_base::found_unsupported_op(expr * n) {
|
||||||
TRACE("theory_array_unsup", tout << mk_ll_pp(n, get_manager()) << "\n";);
|
TRACE("array", tout << mk_ll_pp(n, get_manager()) << "\n";);
|
||||||
if (!m_found_unsupported_op) {
|
if (!m_found_unsupported_op) {
|
||||||
get_context().push_trail(value_trail<context, bool>(m_found_unsupported_op));
|
get_context().push_trail(value_trail<context, bool>(m_found_unsupported_op));
|
||||||
m_found_unsupported_op = true;
|
m_found_unsupported_op = true;
|
||||||
|
|
Loading…
Reference in a new issue