3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-03 09:50:23 +00:00

using rewrite in push_app_ite

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-08-23 17:57:03 -07:00
parent f91496f5ff
commit 8b2d60e3ca
5 changed files with 187 additions and 7 deletions

View file

@ -32,7 +32,7 @@ push_app_ite::~push_app_ite() {
m_plugins.release();
}
int push_app_ite::has_ite_arg(unsigned num_args, expr * const * args) {
static int has_ite_arg(ast_manager& m, unsigned num_args, expr * const * args) {
for (unsigned i = 0; i < num_args; i++)
if (m.is_ite(args[i]))
return i;
@ -41,7 +41,7 @@ int push_app_ite::has_ite_arg(unsigned num_args, expr * const * args) {
void push_app_ite::apply(func_decl * decl, unsigned num_args, expr * const * args, expr_ref & r) {
TRACE("push_app_ite", tout << "pushing app...\n";);
int ite_arg_idx = has_ite_arg(num_args, args);
int ite_arg_idx = has_ite_arg(m, num_args, args);
if (ite_arg_idx < 0) {
mk_app(decl, num_args, args, r);
return;
@ -218,3 +218,64 @@ bool ng_push_app_ite::is_target(func_decl * decl, unsigned num_args, expr * cons
ng_push_app_ite::ng_push_app_ite(simplifier & s, bool conservative):
push_app_ite(s, conservative) {
}
/**
\brief Default (conservative) implementation. Return true if there one and only one ite-term argument.
*/
bool push_app_ite_cfg::is_target(func_decl * decl, unsigned num_args, expr * const * args) {
if (m.is_ite(decl))
return false;
bool found_ite = false;
for (unsigned i = 0; i < num_args; i++) {
if (m.is_ite(args[i]) && !m.is_bool(args[i])) {
if (found_ite) {
if (m_conservative)
return false;
}
else {
found_ite = true;
}
}
}
CTRACE("push_app_ite", found_ite, tout << "found target for push app ite:\n";
tout << decl->get_name();
for (unsigned i = 0; i < num_args; i++) tout << " " << mk_pp(args[i], m);
tout << "\n";);
return found_ite;
}
br_status push_app_ite_cfg::reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
if (!is_target(f, num, args)) {
return BR_FAILED;
}
int ite_arg_idx = has_ite_arg(m, num, args);
if (ite_arg_idx < 0) {
return BR_FAILED;
}
app * ite = to_app(args[ite_arg_idx]);
expr * c = 0, * t = 0, * e = 0;
VERIFY(m.is_ite(ite, c, t, e));
expr ** args_prime = const_cast<expr**>(args);
expr * old = args_prime[ite_arg_idx];
args_prime[ite_arg_idx] = t;
expr_ref t_new(m.mk_app(f, num, args_prime), m);
args_prime[ite_arg_idx] = e;
expr_ref e_new(m.mk_app(f, num, args_prime), m);
args_prime[ite_arg_idx] = old;
result = m.mk_ite(c, t_new, e_new);
if (m.proofs_enabled()) {
result_pr = m.mk_rewrite(m.mk_app(f, num, args), result);
}
return BR_REWRITE2;
}
bool ng_push_app_ite_cfg::is_target(func_decl * decl, unsigned num_args, expr * const * args) {
bool r = push_app_ite_cfg::is_target(decl, num_args, args);
if (!r)
return false;
for (unsigned i = 0; i < num_args; i++)
if (!is_ground(args[i]))
return true;
return false;
}