mirror of
https://github.com/Z3Prover/z3
synced 2025-08-21 10:41:35 +00:00
commit
54a9482716
145 changed files with 2605 additions and 1588 deletions
|
@ -20,6 +20,7 @@ Notes:
|
|||
#include "ast/rewriter/array_rewriter_params.hpp"
|
||||
#include "ast/ast_lt.h"
|
||||
#include "ast/ast_pp.h"
|
||||
#include "ast/rewriter/var_subst.h"
|
||||
|
||||
void array_rewriter::updt_params(params_ref const & _p) {
|
||||
array_rewriter_params p(_p);
|
||||
|
@ -196,6 +197,17 @@ br_status array_rewriter::mk_select_core(unsigned num_args, expr * const * args,
|
|||
return BR_DONE;
|
||||
}
|
||||
|
||||
if (is_lambda(args[0])) {
|
||||
// anywhere lambda reduction as opposed to whnf
|
||||
// select(lambda(X) M, N) -> M[N/X]
|
||||
quantifier* q = to_quantifier(args[0]);
|
||||
SASSERT(q->get_num_decls() == num_args - 1);
|
||||
var_subst subst(m());
|
||||
result = subst(q->get_expr(), num_args - 1, args + 1);
|
||||
return BR_REWRITE_FULL;
|
||||
|
||||
}
|
||||
|
||||
if (m_util.is_as_array(args[0])) {
|
||||
// select(as-array[f], I) --> f(I)
|
||||
func_decl * f = m_util.get_as_array_func_decl(to_app(args[0]));
|
||||
|
|
|
@ -636,7 +636,7 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
|
|||
new_decl_names.push_back(n);
|
||||
}
|
||||
}
|
||||
result = m().mk_quantifier(old_q->is_forall(), new_decl_sorts.size(), new_decl_sorts.c_ptr(), new_decl_names.c_ptr(),
|
||||
result = m().mk_quantifier(old_q->get_kind(), new_decl_sorts.size(), new_decl_sorts.c_ptr(), new_decl_names.c_ptr(),
|
||||
new_body, old_q->get_weight(), old_q->get_qid(), old_q->get_skid(),
|
||||
old_q->get_num_patterns(), new_patterns, old_q->get_num_no_patterns(), new_no_patterns);
|
||||
result_pr = nullptr;
|
||||
|
|
|
@ -588,58 +588,39 @@ br_status bool_rewriter::try_ite_value(app * ite, app * val, expr_ref & result)
|
|||
VERIFY(m().is_ite(ite, cond, t, e));
|
||||
SASSERT(m().is_value(val));
|
||||
|
||||
if (m().is_value(t) && m().is_value(e)) {
|
||||
if (t != val && e != val) {
|
||||
TRACE("try_ite_value", tout << mk_ismt2_pp(t, m()) << " " << mk_ismt2_pp(e, m()) << " " << mk_ismt2_pp(val, m()) << "\n";
|
||||
tout << t << " " << e << " " << val << "\n";);
|
||||
result = m().mk_false();
|
||||
}
|
||||
else if (t == val && e == val) {
|
||||
if (m().are_distinct(val, e)) {
|
||||
result = m().mk_and(m().mk_eq(t, val), cond);
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (m().are_distinct(val, t)) {
|
||||
result = m().mk_and(m().mk_eq(e, val), m().mk_not(cond));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (m().are_equal(val, t)) {
|
||||
if (m().are_equal(val, e)) {
|
||||
result = m().mk_true();
|
||||
}
|
||||
else if (t == val) {
|
||||
result = cond;
|
||||
return BR_DONE;
|
||||
}
|
||||
else {
|
||||
SASSERT(e == val);
|
||||
mk_not(cond, result);
|
||||
result = m().mk_or(m().mk_eq(e, val), cond);
|
||||
}
|
||||
return BR_DONE;
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (m_ite_extra_rules) {
|
||||
if (m().is_value(t)) {
|
||||
if (val == t) {
|
||||
result = m().mk_or(cond, m().mk_eq(val, e));
|
||||
}
|
||||
else {
|
||||
mk_not(cond, result);
|
||||
result = m().mk_and(result, m().mk_eq(val, e));
|
||||
}
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (m().is_value(e)) {
|
||||
if (val == e) {
|
||||
mk_not(cond, result);
|
||||
result = m().mk_or(result, m().mk_eq(val, t));
|
||||
}
|
||||
else {
|
||||
result = m().mk_and(cond, m().mk_eq(val, t));
|
||||
}
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (m().are_equal(val, e)) {
|
||||
result = m().mk_or(m().mk_eq(t, val), m().mk_not(cond));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
{
|
||||
expr* cond2, *t2, *e2;
|
||||
if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
|
||||
try_ite_value(to_app(t), val, result);
|
||||
result = m().mk_ite(cond, result, m().mk_eq(e, val));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
|
||||
try_ite_value(to_app(e), val, result);
|
||||
result = m().mk_ite(cond, m().mk_eq(t, val), result);
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
expr* cond2 = nullptr, *t2 = nullptr, *e2 = nullptr;
|
||||
if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
|
||||
try_ite_value(to_app(t), val, result);
|
||||
result = m().mk_ite(cond, result, m().mk_eq(e, val));
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
|
||||
try_ite_value(to_app(e), val, result);
|
||||
result = m().mk_ite(cond, m().mk_eq(t, val), result);
|
||||
return BR_REWRITE2;
|
||||
}
|
||||
|
||||
return BR_FAILED;
|
||||
|
|
|
@ -87,20 +87,16 @@ bool bv_elim_cfg::reduce_quantifier(quantifier * q,
|
|||
expr* const* sub = subst_map.c_ptr();
|
||||
unsigned sub_size = subst_map.size();
|
||||
|
||||
subst(old_body, sub_size, sub, new_body);
|
||||
new_body = subst(old_body, sub_size, sub);
|
||||
|
||||
for (unsigned j = 0; j < q->get_num_patterns(); j++) {
|
||||
expr_ref pat(m);
|
||||
subst(new_patterns[j], sub_size, sub, pat);
|
||||
pats.push_back(pat);
|
||||
pats.push_back(subst(new_patterns[j], sub_size, sub));
|
||||
}
|
||||
for (unsigned j = 0; j < q->get_num_no_patterns(); j++) {
|
||||
expr_ref nopat(m);
|
||||
subst(new_no_patterns[j], sub_size, sub, nopat);
|
||||
no_pats.push_back(nopat);
|
||||
no_pats.push_back(subst(new_no_patterns[j], sub_size, sub));
|
||||
}
|
||||
|
||||
result = m.mk_quantifier(true,
|
||||
result = m.mk_quantifier(forall_k,
|
||||
names.size(),
|
||||
sorts.c_ptr(),
|
||||
names.c_ptr(),
|
||||
|
|
|
@ -133,7 +133,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, params_ref(), r);
|
||||
r = elim_unused_vars(m_manager, q, params_ref());
|
||||
if (m_manager.proofs_enabled()) {
|
||||
proof * p1 = m_manager.mk_elim_unused_vars(q, r);
|
||||
pr = m_manager.mk_transitivity(pr, p1);
|
||||
|
@ -343,8 +343,7 @@ void der::create_substitution(unsigned sz) {
|
|||
expr_ref cur(m_map[m_order[i]], m_manager);
|
||||
|
||||
// do all the previous substitutions before inserting
|
||||
expr_ref r(m_manager);
|
||||
m_subst(cur, m_subst_map.size(), m_subst_map.c_ptr(), r);
|
||||
expr_ref r = m_subst(cur, m_subst_map.size(), m_subst_map.c_ptr());
|
||||
|
||||
unsigned inx = sz - m_order[i]- 1;
|
||||
SASSERT(m_subst_map[inx]==0);
|
||||
|
@ -369,21 +368,18 @@ void der::apply_substitution(quantifier * q, expr_ref & r) {
|
|||
unsigned sz = m_new_args.size();
|
||||
expr_ref t(m_manager);
|
||||
t = (sz == 1) ? m_new_args[0] : m_manager.mk_or(sz, m_new_args.c_ptr());
|
||||
expr_ref new_e(m_manager);
|
||||
m_subst(t, m_subst_map.size(), m_subst_map.c_ptr(), new_e);
|
||||
expr_ref new_e = m_subst(t, m_subst_map.size(), m_subst_map.c_ptr());
|
||||
|
||||
// don't forget to update the quantifier patterns
|
||||
expr_ref_buffer new_patterns(m_manager);
|
||||
expr_ref_buffer new_no_patterns(m_manager);
|
||||
for (unsigned j = 0; j < q->get_num_patterns(); j++) {
|
||||
expr_ref new_pat(m_manager);
|
||||
m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_pat);
|
||||
expr_ref new_pat = m_subst(q->get_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
|
||||
new_patterns.push_back(new_pat);
|
||||
}
|
||||
|
||||
for (unsigned j = 0; j < q->get_num_no_patterns(); j++) {
|
||||
expr_ref new_nopat(m_manager);
|
||||
m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr(), new_nopat);
|
||||
expr_ref new_nopat = m_subst(q->get_no_pattern(j), m_subst_map.size(), m_subst_map.c_ptr());
|
||||
new_no_patterns.push_back(new_nopat);
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ void distribute_forall::reduce1_app(app * a) {
|
|||
|
||||
void distribute_forall::reduce1_quantifier(quantifier * q) {
|
||||
// This transformation is applied after skolemization/quantifier elimination. So, all quantifiers are universal.
|
||||
SASSERT(q->is_forall());
|
||||
SASSERT(q->get_kind() == forall_k);
|
||||
|
||||
// This transformation is applied after basic pre-processing steps.
|
||||
// So, we can assume that
|
||||
|
@ -126,8 +126,7 @@ void distribute_forall::reduce1_quantifier(quantifier * q) {
|
|||
br.mk_not(arg, not_arg);
|
||||
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, params_ref(), new_q);
|
||||
expr_ref new_q = elim_unused_vars(m_manager, tmp_q, params_ref());
|
||||
new_args.push_back(new_q);
|
||||
}
|
||||
expr_ref result(m_manager);
|
||||
|
|
|
@ -114,7 +114,7 @@ bool elim_bounds_cfg::reduce_quantifier(quantifier * q,
|
|||
expr * const * new_no_patterns,
|
||||
expr_ref & result,
|
||||
proof_ref & result_pr) {
|
||||
if (!q->is_forall()) {
|
||||
if (!is_forall(q)) {
|
||||
return false;
|
||||
}
|
||||
unsigned num_vars = q->get_num_decls();
|
||||
|
@ -194,7 +194,7 @@ bool elim_bounds_cfg::reduce_quantifier(quantifier * q,
|
|||
}
|
||||
quantifier_ref new_q(m);
|
||||
new_q = m.update_quantifier(q, new_body);
|
||||
elim_unused_vars(m, new_q, params_ref(), result);
|
||||
result = elim_unused_vars(m, new_q, params_ref());
|
||||
result_pr = m.mk_rewrite(q, result);
|
||||
TRACE("elim_bounds", tout << mk_pp(q, m) << "\n" << result << "\n";);
|
||||
return true;
|
||||
|
|
|
@ -159,6 +159,8 @@ struct enum2bv_rewriter::imp {
|
|||
expr * const * new_no_patterns,
|
||||
expr_ref & result,
|
||||
proof_ref & result_pr) {
|
||||
|
||||
if (q->get_kind() == lambda_k) return false;
|
||||
m_sorts.reset();
|
||||
expr_ref_vector bounds(m);
|
||||
bool found = false;
|
||||
|
@ -182,15 +184,20 @@ struct enum2bv_rewriter::imp {
|
|||
}
|
||||
expr_ref new_body_ref(old_body, m), tmp(m);
|
||||
if (!bounds.empty()) {
|
||||
if (q->is_forall()) {
|
||||
switch (q->get_kind()) {
|
||||
case forall_k:
|
||||
new_body_ref = m.mk_implies(mk_and(bounds), new_body_ref);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
case exists_k:
|
||||
bounds.push_back(new_body_ref);
|
||||
new_body_ref = mk_and(bounds);
|
||||
break;
|
||||
case lambda_k:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = m.mk_quantifier(q->is_forall(), q->get_num_decls(), m_sorts.c_ptr(), q->get_decl_names(), new_body_ref,
|
||||
result = m.mk_quantifier(q->get_kind(), q->get_num_decls(), m_sorts.c_ptr(), q->get_decl_names(), new_body_ref,
|
||||
q->get_weight(), q->get_qid(), q->get_skid(),
|
||||
q->get_num_patterns(), new_patterns,
|
||||
q->get_num_no_patterns(), new_no_patterns);
|
||||
|
|
|
@ -32,7 +32,7 @@ bool simplify_inj_axiom(ast_manager & m, quantifier * q, expr_ref & result) {
|
|||
expr* arg1 = nullptr, * arg2 = nullptr, *narg = nullptr;
|
||||
expr* app1 = nullptr, * app2 = nullptr;
|
||||
expr* var1 = nullptr, * var2 = nullptr;
|
||||
if (q->is_forall() && m.is_or(n, arg1, arg2)) {
|
||||
if (is_forall(q) && m.is_or(n, arg1, arg2)) {
|
||||
if (m.is_not(arg2))
|
||||
std::swap(arg1, arg2);
|
||||
if (m.is_not(arg1, narg) &&
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
TRACE("qe_verbose",
|
||||
tout << mk_pp(fml, m) << "\n";
|
||||
tout << mk_pp(result, m) << "\n";);
|
||||
fml = result;
|
||||
fml = std::move(result);
|
||||
}
|
||||
|
||||
void extract_quantifier(quantifier* q, app_ref_vector& vars, expr_ref& result, bool use_fresh) {
|
||||
|
@ -79,12 +79,12 @@ public:
|
|||
vars.push_back(a);
|
||||
}
|
||||
expr * const * exprs = (expr* const*) (vars.c_ptr() + vars.size()- nd);
|
||||
instantiate(m, q, exprs, result);
|
||||
result = instantiate(m, q, exprs);
|
||||
}
|
||||
|
||||
unsigned pull_quantifier(bool is_forall, expr_ref& fml, ptr_vector<sort>* sorts, svector<symbol>* names, bool use_fresh, bool rewrite_ok) {
|
||||
unsigned pull_quantifier(bool _is_forall, expr_ref& fml, ptr_vector<sort>* sorts, svector<symbol>* names, bool use_fresh, bool rewrite_ok) {
|
||||
unsigned index = var_counter().get_next_var(fml);
|
||||
while (is_quantifier(fml) && (is_forall == to_quantifier(fml)->is_forall())) {
|
||||
while (is_quantifier(fml) && _is_forall == is_forall(fml)) {
|
||||
quantifier* q = to_quantifier(fml);
|
||||
index += q->get_num_decls();
|
||||
if (names) {
|
||||
|
@ -99,7 +99,7 @@ public:
|
|||
return index;
|
||||
}
|
||||
app_ref_vector vars(m);
|
||||
pull_quantifier(is_forall, fml, vars, use_fresh, rewrite_ok);
|
||||
pull_quantifier(_is_forall, fml, vars, use_fresh, rewrite_ok);
|
||||
if (vars.empty()) {
|
||||
return index;
|
||||
}
|
||||
|
@ -277,12 +277,16 @@ private:
|
|||
}
|
||||
case AST_QUANTIFIER: {
|
||||
quantifier* q = to_quantifier(fml);
|
||||
expr_ref tmp(m);
|
||||
if (!is_compatible(qt, q->is_forall())) {
|
||||
if (is_lambda(q)) {
|
||||
result = fml;
|
||||
break;
|
||||
}
|
||||
set_quantifier_type(qt, q->is_forall());
|
||||
expr_ref tmp(m);
|
||||
if (!is_compatible(qt, is_forall(q))) {
|
||||
result = fml;
|
||||
break;
|
||||
}
|
||||
set_quantifier_type(qt, is_forall(q));
|
||||
extract_quantifier(q, vars, tmp, use_fresh);
|
||||
pull_quantifier(tmp, qt, vars, result, use_fresh, rewrite_ok);
|
||||
break;
|
||||
|
|
|
@ -208,12 +208,10 @@ void rewriter_core::cleanup() {
|
|||
|
||||
#ifdef _TRACE
|
||||
void rewriter_core::display_stack(std::ostream & out, unsigned pp_depth) {
|
||||
svector<frame>::iterator it = m_frame_stack.begin();
|
||||
svector<frame>::iterator end = m_frame_stack.end();
|
||||
for (; it != end; ++it) {
|
||||
out << mk_bounded_pp(it->m_curr, m(), pp_depth) << "\n";
|
||||
out << "state: " << it->m_state << "\n";
|
||||
out << "cache: " << it->m_cache_result << ", new_child: " << it->m_new_child << ", max-depth: " << it->m_max_depth << ", i: " << it->m_i << "\n";
|
||||
for (frame& f : m_frame_stack) {
|
||||
out << mk_bounded_pp(f.m_curr, m(), pp_depth) << "\n";
|
||||
out << "state: " << f.m_state << "\n";
|
||||
out << "cache: " << f.m_cache_result << ", new_child: " << f.m_new_child << ", max-depth: " << f.m_max_depth << ", i: " << f.m_i << "\n";
|
||||
out << "------------------\n";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,11 +350,13 @@ public:
|
|||
void update_inv_binding_at(unsigned i, expr* binding);
|
||||
void operator()(expr * t, expr_ref & result, proof_ref & result_pr);
|
||||
void operator()(expr * t, expr_ref & result) { operator()(t, result, m_pr); }
|
||||
void operator()(expr * n, unsigned num_bindings, expr * const * bindings, expr_ref & result) {
|
||||
expr_ref operator()(expr * n, unsigned num_bindings, expr * const * bindings) {
|
||||
expr_ref result(m());
|
||||
SASSERT(!m_proof_gen);
|
||||
reset();
|
||||
set_inv_bindings(num_bindings, bindings);
|
||||
operator()(n, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void resume(expr_ref & result, proof_ref & result_pr);
|
||||
|
|
|
@ -448,7 +448,7 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
|
|||
m_r = result_stack().back();
|
||||
if (!is_ground(m_r)) {
|
||||
m_inv_shifter(m_r, num_args, tmp);
|
||||
m_r = tmp;
|
||||
m_r = std::move(tmp);
|
||||
}
|
||||
result_stack().shrink(fr.m_spos);
|
||||
result_stack().push_back(m_r);
|
||||
|
@ -542,7 +542,7 @@ void rewriter_tpl<Config>::process_quantifier(quantifier * q, frame & fr) {
|
|||
}
|
||||
result_stack().shrink(fr.m_spos);
|
||||
result_stack().push_back(m_r.get());
|
||||
SASSERT(m().is_bool(m_r));
|
||||
SASSERT(m().get_sort(q) == m().get_sort(m_r));
|
||||
if (!ProofGen) {
|
||||
SASSERT(num_decls <= m_bindings.size());
|
||||
m_bindings.shrink(m_bindings.size() - num_decls);
|
||||
|
|
|
@ -36,7 +36,7 @@ expr_ref sym_expr::accept(expr* e) {
|
|||
switch (m_ty) {
|
||||
case t_pred: {
|
||||
var_subst subst(m);
|
||||
subst(m_t, 1, &e, result);
|
||||
result = subst(m_t, 1, &e);
|
||||
break;
|
||||
}
|
||||
case t_char:
|
||||
|
|
|
@ -16,6 +16,7 @@ Author:
|
|||
Notes:
|
||||
|
||||
--*/
|
||||
#include "util/cooperate.h"
|
||||
#include "ast/rewriter/th_rewriter.h"
|
||||
#include "ast/rewriter/rewriter_params.hpp"
|
||||
#include "ast/rewriter/bool_rewriter.h"
|
||||
|
@ -28,10 +29,9 @@ Notes:
|
|||
#include "ast/rewriter/pb_rewriter.h"
|
||||
#include "ast/rewriter/seq_rewriter.h"
|
||||
#include "ast/rewriter/rewriter_def.h"
|
||||
#include "ast/rewriter/var_subst.h"
|
||||
#include "ast/expr_substitution.h"
|
||||
#include "ast/ast_smt2_pp.h"
|
||||
#include "util/cooperate.h"
|
||||
#include "ast/rewriter/var_subst.h"
|
||||
#include "ast/ast_util.h"
|
||||
#include "ast/well_sorted.h"
|
||||
|
||||
|
@ -606,7 +606,8 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
quantifier_ref q1(m());
|
||||
proof * p1 = nullptr;
|
||||
if (is_quantifier(new_body) &&
|
||||
to_quantifier(new_body)->is_forall() == old_q->is_forall() &&
|
||||
to_quantifier(new_body)->get_kind() == old_q->get_kind() &&
|
||||
to_quantifier(new_body)->get_kind() != lambda_k &&
|
||||
!old_q->has_patterns() &&
|
||||
!to_quantifier(new_body)->has_patterns()) {
|
||||
|
||||
|
@ -619,7 +620,7 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
sorts.append(nested_q->get_num_decls(), nested_q->get_decl_sorts());
|
||||
names.append(nested_q->get_num_decls(), nested_q->get_decl_names());
|
||||
|
||||
q1 = m().mk_quantifier(old_q->is_forall(),
|
||||
q1 = m().mk_quantifier(old_q->get_kind(),
|
||||
sorts.size(),
|
||||
sorts.c_ptr(),
|
||||
names.c_ptr(),
|
||||
|
@ -653,17 +654,19 @@ struct th_rewriter_cfg : public default_rewriter_cfg {
|
|||
SASSERT(is_well_sorted(m(), q1));
|
||||
}
|
||||
|
||||
elim_unused_vars(m(), q1, params_ref(), result);
|
||||
SASSERT(m().get_sort(old_q) == m().get_sort(q1));
|
||||
result = elim_unused_vars(m(), q1, params_ref());
|
||||
|
||||
TRACE("reduce_quantifier", tout << "after elim_unused_vars:\n" << mk_ismt2_pp(result, m()) << "\n";);
|
||||
TRACE("reduce_quantifier", tout << "after elim_unused_vars:\n" << result << "\n";);
|
||||
|
||||
result_pr = nullptr;
|
||||
if (m().proofs_enabled()) {
|
||||
proof * p2 = nullptr;
|
||||
if (q1.get() != result.get())
|
||||
if (q1.get() != result.get() && q1->get_kind() != lambda_k)
|
||||
p2 = m().mk_elim_unused_vars(q1, result);
|
||||
result_pr = m().mk_transitivity(p1, p2);
|
||||
}
|
||||
SASSERT(m().get_sort(old_q) == m().get_sort(result));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -773,7 +776,7 @@ void th_rewriter::reset() {
|
|||
void th_rewriter::operator()(expr_ref & term) {
|
||||
expr_ref result(term.get_manager());
|
||||
m_imp->operator()(term, result);
|
||||
term = result;
|
||||
term = std::move(result);
|
||||
}
|
||||
|
||||
void th_rewriter::operator()(expr * t, expr_ref & result) {
|
||||
|
@ -784,8 +787,8 @@ void th_rewriter::operator()(expr * t, expr_ref & result, proof_ref & result_pr)
|
|||
m_imp->operator()(t, result, result_pr);
|
||||
}
|
||||
|
||||
void th_rewriter::operator()(expr * n, unsigned num_bindings, expr * const * bindings, expr_ref & result) {
|
||||
m_imp->operator()(n, num_bindings, bindings, result);
|
||||
expr_ref th_rewriter::operator()(expr * n, unsigned num_bindings, expr * const * bindings) {
|
||||
return m_imp->operator()(n, num_bindings, bindings);
|
||||
}
|
||||
|
||||
void th_rewriter::set_substitution(expr_substitution * s) {
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
void operator()(expr_ref& term);
|
||||
void operator()(expr * t, expr_ref & result);
|
||||
void operator()(expr * t, expr_ref & result, proof_ref & result_pr);
|
||||
void operator()(expr * n, unsigned num_bindings, expr * const * bindings, expr_ref & result);
|
||||
expr_ref operator()(expr * n, unsigned num_bindings, expr * const * bindings);
|
||||
|
||||
expr_ref mk_app(func_decl* f, unsigned num_args, expr* const* args);
|
||||
|
||||
|
|
|
@ -23,10 +23,11 @@ Notes:
|
|||
#include "ast/well_sorted.h"
|
||||
#include "ast/for_each_expr.h"
|
||||
|
||||
void var_subst::operator()(expr * n, unsigned num_args, expr * const * args, expr_ref & result) {
|
||||
expr_ref var_subst::operator()(expr * n, unsigned num_args, expr * const * args) {
|
||||
expr_ref result(m_reducer.m());
|
||||
if (is_ground(n)) {
|
||||
result = n;
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
SASSERT(is_well_sorted(result.m(), n));
|
||||
m_reducer.reset();
|
||||
|
@ -41,6 +42,7 @@ void var_subst::operator()(expr * n, unsigned num_args, expr * const * args, exp
|
|||
for (unsigned i = 0; i < num_args; i++) tout << mk_ismt2_pp(args[i], m_reducer.m()) << "\n";
|
||||
tout << "\n------>\n";
|
||||
tout << mk_ismt2_pp(result, m_reducer.m()) << "\n";);
|
||||
return result;
|
||||
}
|
||||
|
||||
unused_vars_eliminator::unused_vars_eliminator(ast_manager & m, params_ref const & params) :
|
||||
|
@ -49,16 +51,22 @@ unused_vars_eliminator::unused_vars_eliminator(ast_manager & m, params_ref const
|
|||
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) {
|
||||
expr_ref unused_vars_eliminator::operator()(quantifier* q) {
|
||||
expr_ref result(m);
|
||||
SASSERT(is_well_sorted(m, q));
|
||||
TRACE("elim_unused_vars", tout << expr_ref(q, m) << "\n";);
|
||||
if (is_lambda(q)) {
|
||||
result = q;
|
||||
return result;
|
||||
}
|
||||
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;
|
||||
return result;
|
||||
}
|
||||
if (!q->may_have_unused_vars()) {
|
||||
result = q;
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
m_used.reset();
|
||||
m_used.process(q->get_expr());
|
||||
|
@ -73,7 +81,7 @@ void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
|||
if (m_used.uses_all_vars(num_decls)) {
|
||||
q->set_no_unused_vars();
|
||||
result = q;
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
|
||||
ptr_buffer<sort> used_decl_sorts;
|
||||
|
@ -120,11 +128,11 @@ void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
|||
|
||||
expr_ref new_expr(m);
|
||||
|
||||
m_subst(q->get_expr(), var_mapping.size(), var_mapping.c_ptr(), new_expr);
|
||||
new_expr = m_subst(q->get_expr(), var_mapping.size(), var_mapping.c_ptr());
|
||||
|
||||
if (num_removed == num_decls) {
|
||||
result = new_expr;
|
||||
return;
|
||||
return result;
|
||||
}
|
||||
|
||||
expr_ref tmp(m);
|
||||
|
@ -132,15 +140,15 @@ void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
|||
expr_ref_buffer new_no_patterns(m);
|
||||
|
||||
for (unsigned i = 0; i < num_patterns; i++) {
|
||||
m_subst(q->get_pattern(i), var_mapping.size(), var_mapping.c_ptr(), tmp);
|
||||
tmp = m_subst(q->get_pattern(i), var_mapping.size(), var_mapping.c_ptr());
|
||||
new_patterns.push_back(tmp);
|
||||
}
|
||||
for (unsigned i = 0; i < num_no_patterns; i++) {
|
||||
m_subst(q->get_no_pattern(i), var_mapping.size(), var_mapping.c_ptr(), tmp);
|
||||
tmp = m_subst(q->get_no_pattern(i), var_mapping.size(), var_mapping.c_ptr());
|
||||
new_no_patterns.push_back(tmp);
|
||||
}
|
||||
|
||||
result = m.mk_quantifier(q->is_forall(),
|
||||
result = m.mk_quantifier(q->get_kind(),
|
||||
used_decl_sorts.size(),
|
||||
used_decl_sorts.c_ptr(),
|
||||
used_decl_names.c_ptr(),
|
||||
|
@ -154,24 +162,28 @@ void unused_vars_eliminator::operator()(quantifier* q, expr_ref & result) {
|
|||
new_no_patterns.c_ptr());
|
||||
to_quantifier(result)->set_no_unused_vars();
|
||||
SASSERT(is_well_sorted(m, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params, expr_ref & result) {
|
||||
expr_ref elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params) {
|
||||
unused_vars_eliminator el(m, params);
|
||||
el(q, result);
|
||||
expr_ref result = el(q);
|
||||
TRACE("elim_unused_vars", tout << expr_ref(q, m) << " -> " << result << "\n";);
|
||||
return result;
|
||||
}
|
||||
|
||||
void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref & result) {
|
||||
expr_ref instantiate(ast_manager & m, quantifier * q, expr * const * exprs) {
|
||||
var_subst subst(m);
|
||||
expr_ref new_expr(m);
|
||||
subst(q->get_expr(), q->get_num_decls(), exprs, new_expr);
|
||||
TRACE("var_subst", tout << mk_pp(q, m) << "\n" << mk_pp(new_expr, m) << "\n";);
|
||||
expr_ref new_expr(m), result(m);
|
||||
new_expr = subst(q->get_expr(), q->get_num_decls(), exprs);
|
||||
TRACE("var_subst", tout << mk_pp(q, m) << "\n" << new_expr << "\n";);
|
||||
inv_var_shifter shift(m);
|
||||
shift(new_expr, q->get_num_decls(), result);
|
||||
SASSERT(is_well_sorted(m, result));
|
||||
TRACE("instantiate_bug", tout << mk_ismt2_pp(q, m) << "\nusing\n";
|
||||
for (unsigned i = 0; i < q->get_num_decls(); i++) tout << mk_ismt2_pp(exprs[i], m) << "\n";
|
||||
tout << "\n----->\n" << mk_ismt2_pp(result, m) << "\n";);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void get_free_vars_offset(expr_sparse_mark& mark, ptr_vector<expr>& todo, unsigned offset, expr* e, ptr_vector<sort>& sorts) {
|
||||
|
|
|
@ -48,7 +48,7 @@ public:
|
|||
|
||||
Otherwise, (VAR 0) is stored in the first position, (VAR 1) in the second, and so on.
|
||||
*/
|
||||
void operator()(expr * n, unsigned num_args, expr * const * args, expr_ref & result);
|
||||
expr_ref operator()(expr * n, unsigned num_args, expr * const * args);
|
||||
void reset() { m_reducer.reset(); }
|
||||
};
|
||||
|
||||
|
@ -63,10 +63,10 @@ class unused_vars_eliminator {
|
|||
bool m_ignore_patterns_on_ground_qbody;
|
||||
public:
|
||||
unused_vars_eliminator(ast_manager & m, params_ref const & params);
|
||||
void operator()(quantifier* q, expr_ref& r);
|
||||
expr_ref operator()(quantifier* q);
|
||||
};
|
||||
|
||||
void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params, expr_ref & r);
|
||||
expr_ref elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params);
|
||||
|
||||
/**
|
||||
\brief Instantiate quantifier q using the given exprs.
|
||||
|
@ -77,7 +77,7 @@ void elim_unused_vars(ast_manager & m, quantifier * q, params_ref const & params
|
|||
...
|
||||
(VAR (q->get_num_decls() - 1)) is stored in the first position of the array.
|
||||
*/
|
||||
void instantiate(ast_manager & m, quantifier * q, expr * const * exprs, expr_ref & result);
|
||||
expr_ref instantiate(ast_manager & m, quantifier * q, expr * const * exprs);
|
||||
|
||||
/**
|
||||
\brief Enumerate set of free variables in expression.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue