3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 17:44:08 +00:00

extend rewriting features for arrays, #2151

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2019-03-21 23:34:56 -07:00
parent e59d60fbbe
commit 62ec02e50f
3 changed files with 44 additions and 16 deletions

View file

@ -36,36 +36,48 @@ void array_rewriter::get_param_descrs(param_descrs & r) {
br_status array_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * const * args, expr_ref & result) {
SASSERT(f->get_family_id() == get_fid());
TRACE("array_rewriter", tout << mk_pp(f, m()) << "\n";
for (unsigned i = 0; i < num_args; ++i) {
tout << mk_pp(args[i], m()) << "\n";
});
br_status st;
switch (f->get_decl_kind()) {
case OP_SELECT:
return mk_select_core(num_args, args, result);
st = mk_select_core(num_args, args, result);
break;
case OP_STORE:
return mk_store_core(num_args, args, result);
st = mk_store_core(num_args, args, result);
break;
case OP_ARRAY_MAP:
SASSERT(f->get_num_parameters() == 1);
SASSERT(f->get_parameter(0).is_ast());
SASSERT(is_func_decl(f->get_parameter(0).get_ast()));
return mk_map_core(to_func_decl(f->get_parameter(0).get_ast()), num_args, args, result);
st = mk_map_core(to_func_decl(f->get_parameter(0).get_ast()), num_args, args, result);
break;
case OP_SET_UNION:
return mk_set_union(num_args, args, result);
st = mk_set_union(num_args, args, result);
break;
case OP_SET_INTERSECT:
return mk_set_intersect(num_args, args, result);
st = mk_set_intersect(num_args, args, result);
break;
case OP_SET_SUBSET:
SASSERT(num_args == 2);
return mk_set_subset(args[0], args[1], result);
st = mk_set_subset(args[0], args[1], result);
break;
case OP_SET_COMPLEMENT:
SASSERT(num_args == 1);
return mk_set_complement(args[0], result);
st = mk_set_complement(args[0], result);
break;
case OP_SET_DIFFERENCE:
SASSERT(num_args == 2);
return mk_set_difference(args[0], args[1], result);
st = mk_set_difference(args[0], args[1], result);
break;
default:
return BR_FAILED;
}
TRACE("array_rewriter", tout << mk_pp(f, m()) << "\n";
for (unsigned i = 0; i < num_args; ++i) {
tout << mk_pp(args[i], m()) << "\n";
}
tout << "\n --> " << result << "\n";
);
return st;
}
// l_true -- all equal
@ -456,6 +468,17 @@ bool array_rewriter::has_index_set(expr* e, expr_ref& e0, vector<expr_ref_vector
}
br_status array_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) {
TRACE("array_rewriter", tout << mk_pp(lhs, m()) << " " << mk_pp(rhs, m()) << "\n";);
expr* v = nullptr;
if (m_util.is_const(rhs) && is_lambda(lhs)) {
std::swap(lhs, rhs);
}
if (m_util.is_const(lhs, v) && is_lambda(rhs)) {
quantifier* lam = to_quantifier(rhs);
expr_ref e(m().mk_eq(lam->get_expr(), v), m());
result = m().update_quantifier(lam, quantifier_kind::forall_k, e);
return BR_REWRITE2;
}
if (!m_expand_store_eq) {
return BR_FAILED;
}

View file

@ -32,6 +32,7 @@ Notes:
#include "ast/rewriter/var_subst.h"
#include "ast/expr_substitution.h"
#include "ast/ast_smt2_pp.h"
#include "ast/ast_pp.h"
#include "ast/ast_util.h"
#include "ast/well_sorted.h"
@ -184,7 +185,6 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
st = m_ar_rw.mk_eq_core(args[0], args[1], result);
else if (s_fid == m_seq_rw.get_fid())
st = m_seq_rw.mk_eq_core(args[0], args[1], result);
if (st != BR_FAILED)
return st;
}

View file

@ -38,6 +38,7 @@ Revision History:
#include "ast/rewriter/var_subst.h"
namespace {
struct evaluator_cfg : public default_rewriter_cfg {
ast_manager & m;
model_core & m_model;
@ -165,7 +166,8 @@ struct evaluator_cfg : public default_rewriter_cfg {
if (k == OP_EQ) {
// theory dispatch for =
SASSERT(num == 2);
family_id s_fid = m.get_sort(args[0])->get_family_id();
sort* s = m.get_sort(args[0]);
family_id s_fid = s->get_family_id();
if (s_fid == m_a_rw.get_fid())
st = m_a_rw.mk_eq_core(args[0], args[1], result);
else if (s_fid == m_bv_rw.get_fid())
@ -178,6 +180,9 @@ struct evaluator_cfg : public default_rewriter_cfg {
st = m_seq_rw.mk_eq_core(args[0], args[1], result);
else if (s_fid == m_ar_rw.get_fid())
st = mk_array_eq(args[0], args[1], result);
TRACE("model_evaluator",
tout << st << " " << mk_pp(s, m) << " " << s_fid << " " << m_ar_rw.get_fid() << " "
<< mk_pp(args[0], m) << " " << mk_pp(args[1], m) << " " << result << "\n";);
if (st != BR_FAILED)
return st;
}
@ -348,7 +353,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
return BR_DONE;
}
if (!m_array_equalities) {
return BR_FAILED;
return m_ar_rw.mk_eq_core(a, b, result);
}
vector<expr_ref_vector> stores1, stores2;
@ -389,7 +394,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
);
return BR_REWRITE_FULL;
}
return BR_FAILED;
return m_ar_rw.mk_eq_core(a, b, result);
}
struct args_eq {