mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 04:28:17 +00:00
Added rewriter.ignore_patterns_on_ground_qbody option to disable simplification of quantifiers that have their universals appear only in patterns, but otherwise have a ground body.
This commit is contained in:
parent
9a757ffffe
commit
27a1758857
|
@ -162,7 +162,7 @@ void defined_names::impl::bound_vars(sort_ref_buffer const & sorts, buffer<symbo
|
|||
1, symbol::null, symbol::null,
|
||||
1, patterns);
|
||||
TRACE("mk_definition_bug", tout << "before elim_unused_vars:\n" << mk_ismt2_pp(q, m_manager) << "\n";);
|
||||
elim_unused_vars(m_manager, q, result);
|
||||
elim_unused_vars(m_manager, q, params_ref(), result);
|
||||
TRACE("mk_definition_bug", tout << "after elim_unused_vars:\n" << mk_ismt2_pp(result, m_manager) << "\n";);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -138,7 +138,7 @@ void der::operator()(quantifier * q, expr_ref & r, proof_ref & pr) {
|
|||
// Eliminate variables that have become unused
|
||||
if (reduced && is_forall(r)) {
|
||||
quantifier * q = to_quantifier(r);
|
||||
elim_unused_vars(m_manager, q, r);
|
||||
elim_unused_vars(m_manager, q, params_ref(), r);
|
||||
if (m_manager.proofs_enabled()) {
|
||||
proof * p1 = m_manager.mk_elim_unused_vars(q, r);
|
||||
pr = m_manager.mk_transitivity(pr, p1);
|
||||
|
|
|
@ -8,5 +8,6 @@ def_module_params('rewriter',
|
|||
("push_ite_bv", BOOL, False, "push if-then-else over bit-vector terms."),
|
||||
("pull_cheap_ite", BOOL, False, "pull if-then-else terms when cheap."),
|
||||
("bv_ineq_consistency_test_max", UINT, 0, "max size of conjunctions on which to perform consistency test based on inequalities on bitvectors."),
|
||||
("cache_all", BOOL, False, "cache all intermediate results.")))
|
||||
("cache_all", BOOL, False, "cache all intermediate results."),
|
||||
("ignore_patterns_on_ground_qbody", BOOL, True, "ignores patterns on quantifiers that don't mention their bound variables.")))
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
bool m_cache_all;
|
||||
bool m_push_ite_arith;
|
||||
bool m_push_ite_bv;
|
||||
bool m_ignore_patterns_on_ground_qbody;
|
||||
|
||||
// substitution support
|
||||
expr_dependency_ref m_used_dependencies; // set of dependencies of used substitutions
|
||||
|
@ -70,6 +71,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
m_cache_all = p.cache_all();
|
||||
m_push_ite_arith = p.push_ite_arith();
|
||||
m_push_ite_bv = p.push_ite_bv();
|
||||
m_ignore_patterns_on_ground_qbody = p.ignore_patterns_on_ground_qbody();
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
|
@ -649,7 +651,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
SASSERT(is_well_sorted(m(), q1));
|
||||
}
|
||||
|
||||
elim_unused_vars(m(), q1, result);
|
||||
elim_unused_vars(m(), q1, params_ref(), result);
|
||||
|
||||
TRACE("reduce_quantifier", tout << "after elim_unused_vars:\n" << mk_ismt2_pp(result, m()) << "\n";);
|
||||
|
||||
|
|
|
@ -39,10 +39,16 @@ void var_subst::operator()(expr * n, unsigned num_args, expr * const * args, exp
|
|||
tout << mk_ismt2_pp(result, m_reducer.m()) << "\n";);
|
||||
}
|
||||
|
||||
unused_vars_eliminator::unused_vars_eliminator(ast_manager & m, params_ref const & params) :
|
||||
m(m), m_subst(m), m_params(params)
|
||||
{
|
||||
m_ignore_patterns_on_ground_qbody = m_params.get_bool("ignore_patterns_on_ground_qbody", true);
|
||||
}
|
||||
|
||||
void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
||||
SASSERT(is_well_sorted(m, q));
|
||||
if (is_ground(q->get_expr())) {
|
||||
// ignore patterns if the body is a ground formula.
|
||||
if (m_ignore_patterns_on_ground_qbody && is_ground(q->get_expr())) {
|
||||
// Ignore patterns if the body is a ground formula.
|
||||
result = q->get_expr();
|
||||
return;
|
||||
}
|
||||
|
@ -146,8 +152,8 @@ void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
|||
SASSERT(is_well_sorted(m, result));
|
||||
}
|
||||
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & result) {
|
||||
unused_vars_eliminator el(m);
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params, expr_ref & result) {
|
||||
unused_vars_eliminator el(m, params);
|
||||
el(q, result);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ Notes:
|
|||
|
||||
#include"rewriter.h"
|
||||
#include"used_vars.h"
|
||||
#include"params.h"
|
||||
|
||||
/**
|
||||
\brief Alias for var_shifter class.
|
||||
|
@ -55,15 +56,17 @@ public:
|
|||
\brief Eliminate the unused variables from \c q. Store the result in \c r.
|
||||
*/
|
||||
class unused_vars_eliminator {
|
||||
ast_manager& m;
|
||||
var_subst m_subst;
|
||||
used_vars m_used;
|
||||
ast_manager & m;
|
||||
var_subst m_subst;
|
||||
used_vars m_used;
|
||||
params_ref m_params;
|
||||
bool m_ignore_patterns_on_ground_qbody;
|
||||
public:
|
||||
unused_vars_eliminator(ast_manager& m): m(m), m_subst(m) {}
|
||||
unused_vars_eliminator(ast_manager & m, params_ref const & params);
|
||||
void operator()(quantifier* q, expr_ref& r);
|
||||
};
|
||||
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, expr_ref & r);
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params, expr_ref & r);
|
||||
|
||||
/**
|
||||
\brief Instantiate quantifier q using the given exprs.
|
||||
|
|
|
@ -126,7 +126,7 @@ void distribute_forall::reduce1_quantifier(quantifier * q) {
|
|||
quantifier_ref tmp_q(m_manager);
|
||||
tmp_q = m_manager.update_quantifier(q, not_arg);
|
||||
expr_ref new_q(m_manager);
|
||||
elim_unused_vars(m_manager, tmp_q, new_q);
|
||||
elim_unused_vars(m_manager, tmp_q, params_ref(), new_q);
|
||||
new_args.push_back(new_q);
|
||||
}
|
||||
expr_ref result(m_manager);
|
||||
|
|
|
@ -188,7 +188,7 @@ void elim_bounds::operator()(quantifier * q, expr_ref & r) {
|
|||
}
|
||||
quantifier_ref new_q(m_manager);
|
||||
new_q = m_manager.update_quantifier(q, new_body);
|
||||
elim_unused_vars(m_manager, new_q, r);
|
||||
elim_unused_vars(m_manager, new_q, params_ref(), r);
|
||||
TRACE("elim_bounds", tout << mk_pp(q, m_manager) << "\n" << mk_pp(r, m_manager) << "\n";);
|
||||
}
|
||||
|
||||
|
|
|
@ -852,7 +852,7 @@ void simplifier::reduce1_quantifier(quantifier * q) {
|
|||
}
|
||||
|
||||
expr_ref r(m);
|
||||
elim_unused_vars(m, q1, r);
|
||||
elim_unused_vars(m, q1, params_ref(), r);
|
||||
|
||||
proof * pr = 0;
|
||||
if (m.fine_grain_proofs()) {
|
||||
|
|
|
@ -29,6 +29,7 @@ Notes:
|
|||
#include"bound_manager.h"
|
||||
#include"used_vars.h"
|
||||
#include"var_subst.h"
|
||||
#include"gparams.h"
|
||||
|
||||
#ifndef _EXTERNAL_RELEASE
|
||||
|
||||
|
@ -271,7 +272,7 @@ UNARY_CMD(elim_unused_vars_cmd, "dbg-elim-unused-vars", "<expr>", "eliminate unu
|
|||
return;
|
||||
}
|
||||
expr_ref r(ctx.m());
|
||||
elim_unused_vars(ctx.m(), to_quantifier(arg), r);
|
||||
elim_unused_vars(ctx.m(), to_quantifier(arg), gparams::get(), r);
|
||||
SASSERT(!is_quantifier(r) || !to_quantifier(r)->may_have_unused_vars());
|
||||
ctx.display(ctx.regular_stream(), r);
|
||||
ctx.regular_stream() << std::endl;
|
||||
|
|
|
@ -348,7 +348,7 @@ namespace Duality {
|
|||
|
||||
|
||||
expr expr::qe_lite() const {
|
||||
::qe_lite qe(m());
|
||||
::qe_lite qe(m(), params_ref());
|
||||
expr_ref result(to_expr(raw()),m());
|
||||
proof_ref pf(m());
|
||||
qe(result,pf);
|
||||
|
@ -356,7 +356,7 @@ namespace Duality {
|
|||
}
|
||||
|
||||
expr expr::qe_lite(const std::set<int> &idxs, bool index_of_bound) const {
|
||||
::qe_lite qe(m());
|
||||
::qe_lite qe(m(), params_ref());
|
||||
expr_ref result(to_expr(raw()),m());
|
||||
proof_ref pf(m());
|
||||
uint_set uis;
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace datalog {
|
|||
m_head(m),
|
||||
m_args(m),
|
||||
m_hnf(m),
|
||||
m_qe(m),
|
||||
m_qe(m, params_ref()),
|
||||
m_rwr(m),
|
||||
m_ufproc(m) {}
|
||||
|
||||
|
|
|
@ -2241,7 +2241,7 @@ namespace pdr {
|
|||
vars.append(aux_vars.size(), aux_vars.c_ptr());
|
||||
|
||||
scoped_ptr<expr_replacer> rep;
|
||||
qe_lite qe(m);
|
||||
qe_lite qe(m, m_params.p);
|
||||
expr_ref phi1 = m_pm.mk_and(Phi);
|
||||
qe(vars, phi1);
|
||||
TRACE("pdr", tout << "Eliminated\n" << mk_pp(phi1, m) << "\n";);
|
||||
|
|
|
@ -520,7 +520,7 @@ namespace tb {
|
|||
m_matcher(m),
|
||||
m_refs(m),
|
||||
m_subst(m),
|
||||
m_qe(m),
|
||||
m_qe(m, params_ref()),
|
||||
m_rw(m),
|
||||
m_solver(m, m_fparams) {}
|
||||
|
||||
|
@ -1067,7 +1067,7 @@ namespace tb {
|
|||
}
|
||||
|
||||
bool unify(clause const& tgt, unsigned idx, clause const& src, bool compute_subst, ref<clause>& result) {
|
||||
qe_lite qe(m);
|
||||
qe_lite qe(m, params_ref());
|
||||
reset();
|
||||
SASSERT(tgt.get_predicate(idx)->get_decl() == src.get_decl());
|
||||
unsigned var_cnt = std::max(tgt.get_num_vars(), src.get_num_vars());
|
||||
|
|
|
@ -91,6 +91,7 @@ namespace eq {
|
|||
expr_ref_vector m_subst_map;
|
||||
expr_ref_buffer m_new_args;
|
||||
th_rewriter m_rewriter;
|
||||
params_ref m_params;
|
||||
|
||||
void der_sort_vars(ptr_vector<var> & vars, ptr_vector<expr> & definitions, unsigned_vector & order) {
|
||||
order.reset();
|
||||
|
@ -563,7 +564,8 @@ namespace eq {
|
|||
void elim_unused_vars(expr_ref& r, proof_ref &pr) {
|
||||
if (is_quantifier(r)) {
|
||||
quantifier * q = to_quantifier(r);
|
||||
::elim_unused_vars(m, q, r);
|
||||
|
||||
::elim_unused_vars(m, q, m_params, r);
|
||||
if (m.proofs_enabled()) {
|
||||
proof * p1 = m.mk_elim_unused_vars(q, r);
|
||||
pr = m.mk_transitivity(pr, p1);
|
||||
|
@ -744,7 +746,7 @@ namespace eq {
|
|||
}
|
||||
|
||||
public:
|
||||
der(ast_manager & m):
|
||||
der(ast_manager & m, params_ref const & p):
|
||||
m(m),
|
||||
a(m),
|
||||
dt(m),
|
||||
|
@ -753,7 +755,8 @@ namespace eq {
|
|||
m_new_exprs(m),
|
||||
m_subst_map(m),
|
||||
m_new_args(m),
|
||||
m_rewriter(m) {}
|
||||
m_rewriter(m),
|
||||
m_params(p) {}
|
||||
|
||||
void set_is_variable_proc(is_variable_proc& proc) { m_is_variable = &proc;}
|
||||
|
||||
|
@ -2346,9 +2349,9 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
impl(ast_manager& m):
|
||||
impl(ast_manager & m, params_ref const & p):
|
||||
m(m),
|
||||
m_der(m),
|
||||
m_der(m, p),
|
||||
m_fm(m),
|
||||
m_array_der(m),
|
||||
m_elim_star(*this),
|
||||
|
@ -2438,8 +2441,8 @@ public:
|
|||
|
||||
};
|
||||
|
||||
qe_lite::qe_lite(ast_manager& m) {
|
||||
m_impl = alloc(impl, m);
|
||||
qe_lite::qe_lite(ast_manager & m, params_ref const & p) {
|
||||
m_impl = alloc(impl, m, p);
|
||||
}
|
||||
|
||||
qe_lite::~qe_lite() {
|
||||
|
@ -2469,9 +2472,9 @@ class qe_lite_tactic : public tactic {
|
|||
ast_manager& m;
|
||||
qe_lite m_qe;
|
||||
|
||||
imp(ast_manager& m, params_ref const& p):
|
||||
imp(ast_manager& m, params_ref const & p):
|
||||
m(m),
|
||||
m_qe(m)
|
||||
m_qe(m, p)
|
||||
{}
|
||||
|
||||
void checkpoint() {
|
||||
|
|
|
@ -31,7 +31,7 @@ class qe_lite {
|
|||
class impl;
|
||||
impl * m_impl;
|
||||
public:
|
||||
qe_lite(ast_manager& m);
|
||||
qe_lite(ast_manager & m, params_ref const & p);
|
||||
|
||||
~qe_lite();
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
|
||||
struct rw_cfg : public default_rewriter_cfg {
|
||||
ast_manager & m;
|
||||
params_ref m_params;
|
||||
bv_util m_util;
|
||||
simplifier m_simp;
|
||||
ref<filter_model_converter> m_mc;
|
||||
|
@ -47,6 +48,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
|
||||
rw_cfg(ast_manager & _m, params_ref const & p) :
|
||||
m(_m),
|
||||
m_params(p),
|
||||
m_util(_m),
|
||||
m_simp(_m),
|
||||
m_bindings(_m),
|
||||
|
@ -178,7 +180,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
|
||||
quantifier_ref new_q(m);
|
||||
new_q = m.update_quantifier(q, body);
|
||||
unused_vars_eliminator el(m);
|
||||
unused_vars_eliminator el(m, m_params);
|
||||
el(new_q, result);
|
||||
|
||||
TRACE("elim_small_bv", tout << "elimination result: " << mk_ismt2_pp(result, m) << std::endl; );
|
||||
|
@ -203,6 +205,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
m_max_memory = megabytes_to_bytes(p.get_uint("max_memory", UINT_MAX));
|
||||
m_max_steps = p.get_uint("max_steps", UINT_MAX);
|
||||
m_max_bits = p.get_uint("max_bits", 4);
|
||||
|
|
|
@ -50,7 +50,7 @@ class distribute_forall_tactic : public tactic {
|
|||
quantifier_ref tmp_q(m);
|
||||
tmp_q = m.update_quantifier(old_q, not_arg);
|
||||
expr_ref new_q(m);
|
||||
elim_unused_vars(m, tmp_q, new_q);
|
||||
elim_unused_vars(m, tmp_q, params_ref(), new_q);
|
||||
new_args.push_back(new_q);
|
||||
}
|
||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
||||
|
@ -70,7 +70,7 @@ class distribute_forall_tactic : public tactic {
|
|||
quantifier_ref tmp_q(m);
|
||||
tmp_q = m.update_quantifier(old_q, arg);
|
||||
expr_ref new_q(m);
|
||||
elim_unused_vars(m, tmp_q, new_q);
|
||||
elim_unused_vars(m, tmp_q, params_ref(), new_q);
|
||||
new_args.push_back(new_q);
|
||||
}
|
||||
result = m.mk_and(new_args.size(), new_args.c_ptr());
|
||||
|
|
|
@ -417,7 +417,7 @@ expr * ufbv_rewriter::rewrite(expr * n) {
|
|||
q = m_manager.update_quantifier(to_quantifier(actual), new_body);
|
||||
m_new_exprs.push_back(q);
|
||||
expr_ref new_q(m_manager);
|
||||
elim_unused_vars(m_manager, q, new_q);
|
||||
elim_unused_vars(m_manager, q, params_ref(), new_q);
|
||||
m_new_exprs.push_back(new_q);
|
||||
rewrite_cache(e, new_q, true);
|
||||
m_rewrite_todo.pop_back();
|
||||
|
|
Loading…
Reference in a new issue