mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +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
19 changed files with 795 additions and 776 deletions
|
@ -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),
|
||||
|
@ -119,7 +121,7 @@ class elim_small_bv_tactic : public tactic {
|
|||
return res;
|
||||
}
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
TRACE("elim_small_bv_app", expr_ref tmp(m.mk_app(f, num, args), m); tout << "reduce " << tmp << std::endl; );
|
||||
return BR_FAILED;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -305,7 +308,7 @@ public:
|
|||
virtual void cleanup() {
|
||||
ast_manager & m = m_imp->m;
|
||||
imp * d = alloc(imp, m, m_params);
|
||||
std::swap(d, m_imp);
|
||||
std::swap(d, m_imp);
|
||||
dealloc(d);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,9 +24,9 @@ class distribute_forall_tactic : public tactic {
|
|||
ast_manager & m;
|
||||
|
||||
rw_cfg(ast_manager & _m):m(_m) {}
|
||||
bool reduce_quantifier(quantifier * old_q,
|
||||
expr * new_body,
|
||||
expr * const * new_patterns,
|
||||
bool reduce_quantifier(quantifier * old_q,
|
||||
expr * new_body,
|
||||
expr * const * new_patterns,
|
||||
expr * const * new_no_patterns,
|
||||
expr_ref & result,
|
||||
proof_ref & result_pr) {
|
||||
|
@ -34,7 +34,7 @@ class distribute_forall_tactic : public tactic {
|
|||
if (!old_q->is_forall()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (m.is_not(new_body) && m.is_or(to_app(new_body)->get_arg(0))) {
|
||||
// (forall X (not (or F1 ... Fn)))
|
||||
// -->
|
||||
|
@ -50,13 +50,13 @@ 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());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
if (m.is_and(new_body)) {
|
||||
// (forall X (and F1 ... Fn))
|
||||
// -->
|
||||
|
@ -70,20 +70,20 @@ 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());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct rw : public rewriter_tpl<rw_cfg> {
|
||||
rw_cfg m_cfg;
|
||||
|
||||
|
||||
rw(ast_manager & m, bool proofs_enabled):
|
||||
rewriter_tpl<rw_cfg>(m, proofs_enabled, m_cfg),
|
||||
m_cfg(m) {
|
||||
|
@ -99,19 +99,19 @@ public:
|
|||
return alloc(distribute_forall_tactic);
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
virtual void operator()(goal_ref const & g,
|
||||
goal_ref_buffer & result,
|
||||
model_converter_ref & mc,
|
||||
proof_converter_ref & pc,
|
||||
expr_dependency_ref & core) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
ast_manager & m = g->m();
|
||||
bool produce_proofs = g->proofs_enabled();
|
||||
rw r(m, produce_proofs);
|
||||
m_rw = &r;
|
||||
m_rw = &r;
|
||||
mc = 0; pc = 0; core = 0; result.reset();
|
||||
tactic_report report("distribute-forall", *g);
|
||||
|
||||
|
||||
expr_ref new_curr(m);
|
||||
proof_ref new_pr(m);
|
||||
unsigned size = g->size();
|
||||
|
@ -126,12 +126,12 @@ public:
|
|||
}
|
||||
g->update(idx, new_curr, new_pr, g->dep(idx));
|
||||
}
|
||||
|
||||
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
TRACE("distribute-forall", g->display(tout););
|
||||
SASSERT(g->is_well_sorted());
|
||||
m_rw = 0;
|
||||
m_rw = 0;
|
||||
}
|
||||
|
||||
virtual void cleanup() {}
|
||||
|
|
|
@ -49,7 +49,7 @@ ufbv_rewriter::~ufbv_rewriter() {
|
|||
bool ufbv_rewriter::is_demodulator(expr * e, expr_ref & large, expr_ref & small) const {
|
||||
if (e->get_kind() == AST_QUANTIFIER) {
|
||||
quantifier * q = to_quantifier(e);
|
||||
if (q->is_forall()) {
|
||||
if (q->is_forall()) {
|
||||
expr * qe = q->get_expr();
|
||||
if ((m_manager.is_eq(qe) || m_manager.is_iff(qe))) {
|
||||
app * eq = to_app(q->get_expr());
|
||||
|
@ -61,7 +61,7 @@ bool ufbv_rewriter::is_demodulator(expr * e, expr_ref & large, expr_ref & small)
|
|||
<< mk_pp(lhs, m_manager) << "\n"
|
||||
<< mk_pp(rhs, m_manager) << "\n"
|
||||
<< "subset: " << subset << ", smaller: " << smaller << "\n";);
|
||||
// We only track uninterpreted functions, everything else is likely too expensive.
|
||||
// We only track uninterpreted functions, everything else is likely too expensive.
|
||||
if ((subset == +1 || subset == +2) && smaller == +1) {
|
||||
if (is_uninterp(rhs)) {
|
||||
large = rhs;
|
||||
|
@ -78,7 +78,7 @@ bool ufbv_rewriter::is_demodulator(expr * e, expr_ref & large, expr_ref & small)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
if ((subset == -1 || subset == +2) && smaller == -1) {
|
||||
if (is_uninterp(lhs)) {
|
||||
large = lhs;
|
||||
|
@ -113,13 +113,13 @@ bool ufbv_rewriter::is_demodulator(expr * e, expr_ref & large, expr_ref & small)
|
|||
return false;
|
||||
}
|
||||
|
||||
class var_set_proc {
|
||||
class var_set_proc {
|
||||
uint_set & m_set;
|
||||
public:
|
||||
var_set_proc(uint_set &s):m_set(s) {}
|
||||
void operator()(var * n) { m_set.insert(n->get_idx()); }
|
||||
void operator()(quantifier * n) {}
|
||||
void operator()(app * n) {}
|
||||
void operator()(app * n) {}
|
||||
};
|
||||
|
||||
int ufbv_rewriter::is_subset(expr * e1, expr * e2) const {
|
||||
|
@ -132,10 +132,10 @@ int ufbv_rewriter::is_subset(expr * e1, expr * e2) const {
|
|||
for_each_expr(proc1, e1);
|
||||
var_set_proc proc2(ev2);
|
||||
for_each_expr(proc2, e2);
|
||||
|
||||
return (ev1==ev2 ) ? +2 : // We return +2 if the sets are equal.
|
||||
(ev1.subset_of(ev2)) ? +1 :
|
||||
(ev2.subset_of(ev1)) ? -1 :
|
||||
|
||||
return (ev1==ev2 ) ? +2 : // We return +2 if the sets are equal.
|
||||
(ev1.subset_of(ev2)) ? +1 :
|
||||
(ev2.subset_of(ev1)) ? -1 :
|
||||
0 ;
|
||||
}
|
||||
|
||||
|
@ -154,8 +154,8 @@ int ufbv_rewriter::is_smaller(expr * e1, expr * e2) const {
|
|||
else if (is_uninterp(e1) && !is_uninterp(e2))
|
||||
return -1;
|
||||
|
||||
// two uninterpreted functions are ordered first by the number of
|
||||
// arguments, then by their id.
|
||||
// two uninterpreted functions are ordered first by the number of
|
||||
// arguments, then by their id.
|
||||
if (is_uninterp(e1) && is_uninterp(e2)) {
|
||||
if (to_app(e1)->get_num_args() < to_app(e2)->get_num_args())
|
||||
return +1;
|
||||
|
@ -163,10 +163,10 @@ int ufbv_rewriter::is_smaller(expr * e1, expr * e2) const {
|
|||
return -1;
|
||||
else {
|
||||
unsigned a = to_app(e1)->get_decl()->get_id();
|
||||
unsigned b = to_app(e2)->get_decl()->get_id();
|
||||
if (a < b)
|
||||
unsigned b = to_app(e2)->get_decl()->get_id();
|
||||
if (a < b)
|
||||
return +1;
|
||||
else if (a > b)
|
||||
else if (a > b)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
@ -185,8 +185,8 @@ int ufbv_rewriter::is_smaller(expr * e1, expr * e2) const {
|
|||
default: UNREACHABLE();
|
||||
}
|
||||
|
||||
return (sz1 == sz2) ? 0 :
|
||||
(sz1 < sz2) ? +1 :
|
||||
return (sz1 == sz2) ? 0 :
|
||||
(sz1 < sz2) ? +1 :
|
||||
-1 ;
|
||||
}
|
||||
|
||||
|
@ -194,9 +194,9 @@ class max_var_id_proc {
|
|||
unsigned m_max_var_id;
|
||||
public:
|
||||
max_var_id_proc(void):m_max_var_id(0) {}
|
||||
void operator()(var * n) {
|
||||
if(n->get_idx() > m_max_var_id)
|
||||
m_max_var_id = n->get_idx();
|
||||
void operator()(var * n) {
|
||||
if(n->get_idx() > m_max_var_id)
|
||||
m_max_var_id = n->get_idx();
|
||||
}
|
||||
void operator()(quantifier * n) {}
|
||||
void operator()(app * n) {}
|
||||
|
@ -206,7 +206,7 @@ public:
|
|||
unsigned ufbv_rewriter::max_var_id(expr * e)
|
||||
{
|
||||
max_var_id_proc proc;
|
||||
for_each_expr(proc, e);
|
||||
for_each_expr(proc, e);
|
||||
return proc.get_max();
|
||||
}
|
||||
|
||||
|
@ -219,14 +219,14 @@ void ufbv_rewriter::insert_fwd_idx(expr * large, expr * small, quantifier * demo
|
|||
func_decl * fd = to_app(large)->get_decl();
|
||||
|
||||
fwd_idx_map::iterator it = m_fwd_idx.find_iterator(fd);
|
||||
if (it == m_fwd_idx.end()) {
|
||||
quantifier_set * qs = alloc(quantifier_set, 1);
|
||||
if (it == m_fwd_idx.end()) {
|
||||
quantifier_set * qs = alloc(quantifier_set, 1);
|
||||
m_fwd_idx.insert(fd, qs);
|
||||
it = m_fwd_idx.find_iterator(fd);
|
||||
}
|
||||
|
||||
SASSERT(it->m_value);
|
||||
it->m_value->insert(demodulator);
|
||||
it->m_value->insert(demodulator);
|
||||
|
||||
m_manager.inc_ref(demodulator);
|
||||
m_manager.inc_ref(large);
|
||||
|
@ -238,13 +238,13 @@ void ufbv_rewriter::remove_fwd_idx(func_decl * f, quantifier * demodulator) {
|
|||
TRACE("demodulator_fwd", tout << "REMOVE: " << std::hex << (size_t)demodulator << std::endl; );
|
||||
|
||||
fwd_idx_map::iterator it = m_fwd_idx.find_iterator(f);
|
||||
if (it != m_fwd_idx.end()) {
|
||||
if (it != m_fwd_idx.end()) {
|
||||
demodulator2lhs_rhs::iterator fit = m_demodulator2lhs_rhs.find_iterator(demodulator);
|
||||
m_manager.dec_ref(fit->m_value.first);
|
||||
m_manager.dec_ref(fit->m_value.second);
|
||||
m_manager.dec_ref(demodulator);
|
||||
m_demodulator2lhs_rhs.erase(demodulator);
|
||||
it->m_value->erase(demodulator);
|
||||
it->m_value->erase(demodulator);
|
||||
} else {
|
||||
SASSERT(m_demodulator2lhs_rhs.contains(demodulator));
|
||||
}
|
||||
|
@ -281,13 +281,13 @@ void ufbv_rewriter::show_fwd_idx(std::ostream & out) {
|
|||
}
|
||||
}
|
||||
|
||||
bool ufbv_rewriter::rewrite1(func_decl * f, ptr_vector<expr> & m_new_args, expr_ref & np) {
|
||||
bool ufbv_rewriter::rewrite1(func_decl * f, ptr_vector<expr> & m_new_args, expr_ref & np) {
|
||||
fwd_idx_map::iterator it = m_fwd_idx.find_iterator(f);
|
||||
if (it != m_fwd_idx.end()) {
|
||||
TRACE("demodulator_bug", tout << "trying to rewrite: " << f->get_name() << " args:\n";
|
||||
for (unsigned i = 0; i < m_new_args.size(); i++) { tout << mk_pp(m_new_args[i], m_manager) << "\n"; });
|
||||
quantifier_set::iterator dit = it->m_value->begin();
|
||||
quantifier_set::iterator dend = it->m_value->end();
|
||||
quantifier_set::iterator dend = it->m_value->end();
|
||||
for ( ; dit != dend ; dit++ ) {
|
||||
quantifier * d = *dit;
|
||||
|
||||
|
@ -302,7 +302,7 @@ bool ufbv_rewriter::rewrite1(func_decl * f, ptr_vector<expr> & m_new_args, expr_
|
|||
TRACE("demodulator_bug", tout << "Matching with demodulator: " << mk_pp(d, m_manager) << std::endl; );
|
||||
|
||||
SASSERT(large->get_decl() == f);
|
||||
|
||||
|
||||
if (m_match_subst(large, l_s.second, m_new_args.c_ptr(), np)) {
|
||||
TRACE("demodulator_bug", tout << "succeeded...\n" << mk_pp(l_s.second, m_manager) << "\n===>\n" << mk_pp(np, m_manager) << "\n";);
|
||||
return true;
|
||||
|
@ -331,22 +331,22 @@ void ufbv_rewriter::rewrite_cache(expr * e, expr * new_e, bool done) {
|
|||
}
|
||||
|
||||
expr * ufbv_rewriter::rewrite(expr * n) {
|
||||
if (m_fwd_idx.empty())
|
||||
if (m_fwd_idx.empty())
|
||||
return n;
|
||||
|
||||
TRACE("demodulator", tout << "rewrite: " << mk_pp(n, m_manager) << std::endl; );
|
||||
app * a;
|
||||
|
||||
|
||||
SASSERT(m_rewrite_todo.empty());
|
||||
m_rewrite_cache.reset();
|
||||
|
||||
|
||||
m_rewrite_todo.push_back(n);
|
||||
while (!m_rewrite_todo.empty()) {
|
||||
TRACE("demodulator_stack", tout << "STACK: " << std::endl;
|
||||
for ( unsigned i = 0; i<m_rewrite_todo.size(); i++)
|
||||
for ( unsigned i = 0; i<m_rewrite_todo.size(); i++)
|
||||
tout << std::dec << i << ": " << std::hex << (size_t)m_rewrite_todo[i] << std::endl;
|
||||
);
|
||||
|
||||
);
|
||||
|
||||
expr * e = m_rewrite_todo.back();
|
||||
expr * actual = e;
|
||||
|
||||
|
@ -355,7 +355,7 @@ expr * ufbv_rewriter::rewrite(expr * n) {
|
|||
if (ebp.second) {
|
||||
m_rewrite_todo.pop_back();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else {
|
||||
actual = ebp.first;
|
||||
}
|
||||
|
@ -366,8 +366,8 @@ expr * ufbv_rewriter::rewrite(expr * n) {
|
|||
rewrite_cache(e, actual, true);
|
||||
m_rewrite_todo.pop_back();
|
||||
break;
|
||||
case AST_APP:
|
||||
a = to_app(actual);
|
||||
case AST_APP:
|
||||
a = to_app(actual);
|
||||
if (rewrite_visit_children(a)) {
|
||||
func_decl * f = a->get_decl();
|
||||
m_new_args.reset();
|
||||
|
@ -389,12 +389,12 @@ expr * ufbv_rewriter::rewrite(expr * n) {
|
|||
// No pop.
|
||||
} else {
|
||||
if(all_untouched) {
|
||||
rewrite_cache(e, actual, true);
|
||||
}
|
||||
rewrite_cache(e, actual, true);
|
||||
}
|
||||
else {
|
||||
expr_ref na(m_manager);
|
||||
if (f->get_family_id() != m_manager.get_basic_family_id())
|
||||
na = m_manager.mk_app(f, m_new_args.size(), m_new_args.c_ptr());
|
||||
na = m_manager.mk_app(f, m_new_args.size(), m_new_args.c_ptr());
|
||||
else
|
||||
m_bsimp.reduce(f, m_new_args.size(), m_new_args.c_ptr(), na);
|
||||
TRACE("demodulator_bug", tout << "e:\n" << mk_pp(e, m_manager) << "\nnew_args: \n";
|
||||
|
@ -405,9 +405,9 @@ expr * ufbv_rewriter::rewrite(expr * n) {
|
|||
}
|
||||
m_rewrite_todo.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AST_QUANTIFIER: {
|
||||
case AST_QUANTIFIER: {
|
||||
expr * body = to_quantifier(actual)->get_expr();
|
||||
if (m_rewrite_cache.contains(body)) {
|
||||
const expr_bool_pair ebp = m_rewrite_cache.get(body);
|
||||
|
@ -417,13 +417,13 @@ 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);
|
||||
rewrite_cache(e, new_q, true);
|
||||
m_rewrite_todo.pop_back();
|
||||
} else {
|
||||
m_rewrite_todo.push_back(body);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -437,7 +437,7 @@ expr * ufbv_rewriter::rewrite(expr * n) {
|
|||
expr * r = ebp.first;
|
||||
|
||||
TRACE("demodulator", tout << "rewrite result: " << mk_pp(r, m_manager) << std::endl; );
|
||||
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -448,7 +448,7 @@ public:
|
|||
add_back_idx_proc(back_idx_map & bi, expr * e):m_back_idx(bi),m_expr(e) {}
|
||||
void operator()(var * n) {}
|
||||
void operator()(quantifier * n) {}
|
||||
void operator()(app * n) {
|
||||
void operator()(app * n) {
|
||||
// We track only uninterpreted and constant functions.
|
||||
if (n->get_num_args()==0) return;
|
||||
SASSERT(m_expr && m_expr != (expr*) 0x00000003);
|
||||
|
@ -464,7 +464,7 @@ public:
|
|||
m_back_idx.insert(d, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class ufbv_rewriter::remove_back_idx_proc {
|
||||
|
@ -473,15 +473,15 @@ class ufbv_rewriter::remove_back_idx_proc {
|
|||
public:
|
||||
remove_back_idx_proc(back_idx_map & bi, expr * e):m_back_idx(bi),m_expr(e) {}
|
||||
void operator()(var * n) {}
|
||||
void operator()(quantifier * n) {}
|
||||
void operator()(app * n) {
|
||||
void operator()(quantifier * n) {}
|
||||
void operator()(app * n) {
|
||||
// We track only uninterpreted and constant functions.
|
||||
if (n->get_num_args()==0) return;
|
||||
func_decl * d=n->get_decl();
|
||||
if (d->get_family_id() == null_family_id) {
|
||||
if (d->get_family_id() == null_family_id) {
|
||||
back_idx_map::iterator it = m_back_idx.find_iterator(d);
|
||||
if (it != m_back_idx.end()) {
|
||||
SASSERT(it->m_value);
|
||||
SASSERT(it->m_value);
|
||||
it->m_value->remove(m_expr);
|
||||
}
|
||||
}
|
||||
|
@ -489,12 +489,12 @@ public:
|
|||
};
|
||||
|
||||
void ufbv_rewriter::reschedule_processed(func_decl * f) {
|
||||
//use m_back_idx to find all formulas p in m_processed that contains f {
|
||||
//use m_back_idx to find all formulas p in m_processed that contains f {
|
||||
back_idx_map::iterator it = m_back_idx.find_iterator(f);
|
||||
if (it != m_back_idx.end()) {
|
||||
SASSERT(it->m_value);
|
||||
expr_set temp;
|
||||
|
||||
|
||||
expr_set::iterator sit = it->m_value->begin();
|
||||
expr_set::iterator send = it->m_value->end();
|
||||
for ( ; sit != send ; sit++ ) {
|
||||
|
@ -502,7 +502,7 @@ void ufbv_rewriter::reschedule_processed(func_decl * f) {
|
|||
if (m_processed.contains(p))
|
||||
temp.insert(p);
|
||||
}
|
||||
|
||||
|
||||
sit = temp.begin();
|
||||
send = temp.end();
|
||||
for ( ; sit != send; sit++) {
|
||||
|
@ -511,7 +511,7 @@ void ufbv_rewriter::reschedule_processed(func_decl * f) {
|
|||
m_processed.remove(p);
|
||||
remove_back_idx_proc proc(m_back_idx, p); // this could change it->m_value, thus we need the `temp' set.
|
||||
for_each_expr(proc, p);
|
||||
// insert p into m_todo
|
||||
// insert p into m_todo
|
||||
m_todo.push_back(p);
|
||||
}
|
||||
}
|
||||
|
@ -529,40 +529,40 @@ bool ufbv_rewriter::can_rewrite(expr * n, expr * lhs) {
|
|||
|
||||
while (!stack.empty()) {
|
||||
curr = stack.back();
|
||||
|
||||
|
||||
if (visited.is_marked(curr)) {
|
||||
stack.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(curr->get_kind()) {
|
||||
case AST_VAR:
|
||||
case AST_VAR:
|
||||
visited.mark(curr, true);
|
||||
stack.pop_back();
|
||||
break;
|
||||
|
||||
case AST_APP:
|
||||
if (for_each_expr_args(stack, visited, to_app(curr)->get_num_args(), to_app(curr)->get_args())) {
|
||||
if (for_each_expr_args(stack, visited, to_app(curr)->get_num_args(), to_app(curr)->get_args())) {
|
||||
if (m_match_subst(lhs, curr))
|
||||
return true;
|
||||
visited.mark(curr, true);
|
||||
stack.pop_back();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case AST_QUANTIFIER:
|
||||
if (!for_each_expr_args(stack, visited, to_quantifier(curr)->get_num_patterns(),
|
||||
if (!for_each_expr_args(stack, visited, to_quantifier(curr)->get_num_patterns(),
|
||||
to_quantifier(curr)->get_patterns())) {
|
||||
break;
|
||||
}
|
||||
if (!for_each_expr_args(stack, visited, to_quantifier(curr)->get_num_no_patterns(),
|
||||
if (!for_each_expr_args(stack, visited, to_quantifier(curr)->get_num_no_patterns(),
|
||||
to_quantifier(curr)->get_no_patterns())) {
|
||||
break;
|
||||
}
|
||||
if (!visited.is_marked(to_quantifier(curr)->get_expr())) {
|
||||
stack.push_back(to_quantifier(curr)->get_expr());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stack.pop_back();
|
||||
break;
|
||||
|
@ -597,7 +597,7 @@ void ufbv_rewriter::reschedule_demodulators(func_decl * f, expr * lhs) {
|
|||
expr * occ = *esit;
|
||||
|
||||
if (!is_quantifier(occ))
|
||||
continue;
|
||||
continue;
|
||||
|
||||
// Use the fwd idx to find out whether this is a demodulator.
|
||||
demodulator2lhs_rhs::iterator d2lr_it = m_demodulator2lhs_rhs.find_iterator(to_quantifier(occ));
|
||||
|
@ -605,22 +605,22 @@ void ufbv_rewriter::reschedule_demodulators(func_decl * f, expr * lhs) {
|
|||
l = d2lr_it->m_value.first;
|
||||
quantifier_ref d(m_manager);
|
||||
func_decl_ref df(m_manager);
|
||||
d = to_quantifier(occ);
|
||||
d = to_quantifier(occ);
|
||||
df = to_app(l)->get_decl();
|
||||
|
||||
// Now we know there is an occurrence of f in d
|
||||
// if n' can rewrite d {
|
||||
// if n' can rewrite d {
|
||||
if (can_rewrite(d, lhs)) {
|
||||
TRACE("demodulator", tout << "Rescheduling: " << std::endl << mk_pp(d, m_manager) << std::endl; );
|
||||
// remove d from m_fwd_idx
|
||||
remove_fwd_idx(df, d);
|
||||
// remove d from m_back_idx
|
||||
// remove d from m_back_idx
|
||||
// just remember it here, because otherwise it and/or esit might become invalid?
|
||||
// to_remove.insert(d);
|
||||
// to_remove.insert(d);
|
||||
remove_back_idx_proc proc(m_back_idx, d);
|
||||
for_each_expr(proc, d);
|
||||
// insert d into m_todo
|
||||
m_todo.push_back(d);
|
||||
m_todo.push_back(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -629,10 +629,10 @@ void ufbv_rewriter::reschedule_demodulators(func_decl * f, expr * lhs) {
|
|||
//for (ptr_vector<expr>::iterator it = to_remove.begin(); it != to_remove.end(); it++) {
|
||||
// expr * d = *it;
|
||||
// remove_back_idx_proc proc(m_manager, m_back_idx, d);
|
||||
// for_each_expr(proc, d);
|
||||
// for_each_expr(proc, d);
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
void ufbv_rewriter::operator()(unsigned n, expr * const * exprs, proof * const * prs, expr_ref_vector & new_exprs, proof_ref_vector & new_prs) {
|
||||
if (m_manager.proofs_enabled()) {
|
||||
// Let us not waste time with proof production
|
||||
|
@ -655,7 +655,7 @@ void ufbv_rewriter::operator()(unsigned n, expr * const * exprs, proof * const *
|
|||
|
||||
m_match_subst.reserve(max_vid);
|
||||
|
||||
while (!m_todo.empty()) {
|
||||
while (!m_todo.empty()) {
|
||||
// let n be the next formula in m_todo.
|
||||
expr_ref cur(m_manager);
|
||||
cur = m_todo.back();
|
||||
|
@ -670,21 +670,21 @@ void ufbv_rewriter::operator()(unsigned n, expr * const * exprs, proof * const *
|
|||
expr_ref large(m_manager), small(m_manager);
|
||||
if (!is_demodulator(np, large, small)) {
|
||||
// insert n' into m_processed
|
||||
m_processed.insert(np);
|
||||
// update m_back_idx (traverse n' and for each uninterpreted function declaration f in n' add the entry f->n' to m_back_idx)
|
||||
m_processed.insert(np);
|
||||
// update m_back_idx (traverse n' and for each uninterpreted function declaration f in n' add the entry f->n' to m_back_idx)
|
||||
add_back_idx_proc proc(m_back_idx, np);
|
||||
for_each_expr(proc, np);
|
||||
} else {
|
||||
} else {
|
||||
// np is a demodulator that allows us to replace 'large' with 'small'.
|
||||
TRACE("demodulator", tout << "Found demodulator: " << std::endl;
|
||||
tout << mk_pp(large.get(), m_manager) << std::endl << " ---> " <<
|
||||
tout << mk_pp(large.get(), m_manager) << std::endl << " ---> " <<
|
||||
std::endl << mk_pp(small.get(), m_manager) << std::endl; );
|
||||
|
||||
TRACE("demodulator_s", tout << "Found demodulator: " << std::endl;
|
||||
tout << to_app(large)->get_decl()->get_name() <<
|
||||
tout << to_app(large)->get_decl()->get_name() <<
|
||||
"[" << to_app(large)->get_depth() << "]" << " ---> ";
|
||||
if (is_app(small))
|
||||
tout << to_app(small)->get_decl()->get_name() <<
|
||||
tout << to_app(small)->get_decl()->get_name() <<
|
||||
"[" << to_app(small)->get_depth() << "]" << std::endl;
|
||||
else
|
||||
tout << mk_pp(small.get(), m_manager) << std::endl; );
|
||||
|
@ -695,14 +695,14 @@ void ufbv_rewriter::operator()(unsigned n, expr * const * exprs, proof * const *
|
|||
|
||||
reschedule_processed(f);
|
||||
reschedule_demodulators(f, large);
|
||||
|
||||
|
||||
// insert n' into m_fwd_idx
|
||||
insert_fwd_idx(large, small, to_quantifier(np));
|
||||
|
||||
// update m_back_idx
|
||||
add_back_idx_proc proc(m_back_idx, np);
|
||||
for_each_expr(proc, np);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the result is the contents of m_processed + all demodulators in m_fwd_idx.
|
||||
|
@ -743,10 +743,10 @@ ufbv_rewriter::match_subst::match_subst(ast_manager & m):
|
|||
*/
|
||||
struct match_args_aux_proc {
|
||||
substitution & m_subst;
|
||||
struct no_match {};
|
||||
|
||||
struct no_match {};
|
||||
|
||||
match_args_aux_proc(substitution & s):m_subst(s) {}
|
||||
|
||||
|
||||
void operator()(var * n) {
|
||||
expr_offset r;
|
||||
if (m_subst.find(n, 0, r)) {
|
||||
|
@ -766,7 +766,7 @@ struct match_args_aux_proc {
|
|||
bool ufbv_rewriter::match_subst::match_args(app * lhs, expr * const * args) {
|
||||
m_cache.reset();
|
||||
m_todo.reset();
|
||||
|
||||
|
||||
// fill todo-list, and perform quick success/failure tests
|
||||
m_all_args_eq = true;
|
||||
unsigned num_args = lhs->get_num_args();
|
||||
|
@ -777,21 +777,21 @@ bool ufbv_rewriter::match_subst::match_args(app * lhs, expr * const * args) {
|
|||
m_all_args_eq = false;
|
||||
if (is_app(t_arg) && is_app(i_arg) && to_app(t_arg)->get_decl() != to_app(i_arg)->get_decl()) {
|
||||
// quick failure...
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
m_todo.push_back(expr_pair(t_arg, i_arg));
|
||||
}
|
||||
|
||||
if (m_all_args_eq) {
|
||||
|
||||
if (m_all_args_eq) {
|
||||
// quick success worked...
|
||||
return true;
|
||||
}
|
||||
|
||||
m_subst.reset();
|
||||
|
||||
|
||||
while (!m_todo.empty()) {
|
||||
expr_pair const & p = m_todo.back();
|
||||
|
||||
|
||||
if (is_var(p.first)) {
|
||||
expr_offset r;
|
||||
if (m_subst.find(to_var(p.first), 0, r)) {
|
||||
|
@ -814,7 +814,7 @@ bool ufbv_rewriter::match_subst::match_args(app * lhs, expr * const * args) {
|
|||
|
||||
SASSERT(is_app(p.first) && is_app(p.second));
|
||||
|
||||
if (to_app(p.first)->is_ground() && !to_app(p.second)->is_ground())
|
||||
if (to_app(p.first)->is_ground() && !to_app(p.second)->is_ground())
|
||||
return false;
|
||||
|
||||
if (p.first == p.second && to_app(p.first)->is_ground()) {
|
||||
|
@ -827,7 +827,7 @@ bool ufbv_rewriter::match_subst::match_args(app * lhs, expr * const * args) {
|
|||
m_todo.pop_back();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (p.first == p.second) {
|
||||
// p.first and p.second is not ground...
|
||||
|
||||
|
@ -855,10 +855,10 @@ bool ufbv_rewriter::match_subst::match_args(app * lhs, expr * const * args) {
|
|||
|
||||
app * n1 = to_app(p.first);
|
||||
app * n2 = to_app(p.second);
|
||||
|
||||
|
||||
if (n1->get_decl() != n2->get_decl())
|
||||
return false;
|
||||
|
||||
|
||||
unsigned num_args1 = n1->get_num_args();
|
||||
if (num_args1 != n2->get_num_args())
|
||||
return false;
|
||||
|
@ -867,7 +867,7 @@ bool ufbv_rewriter::match_subst::match_args(app * lhs, expr * const * args) {
|
|||
|
||||
if (num_args1 == 0)
|
||||
continue;
|
||||
|
||||
|
||||
m_cache.insert(p);
|
||||
unsigned j = num_args1;
|
||||
while (j > 0) {
|
||||
|
@ -886,7 +886,7 @@ bool ufbv_rewriter::match_subst::operator()(app * lhs, expr * rhs, expr * const
|
|||
new_rhs = rhs;
|
||||
return true;
|
||||
}
|
||||
unsigned deltas[2] = { 0, 0 };
|
||||
unsigned deltas[2] = { 0, 0 };
|
||||
m_subst.apply(2, deltas, expr_offset(rhs, 0), new_rhs);
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue