3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-11-05 13:56:03 +00:00

extend macro detection to negated equivalences #5496

This commit is contained in:
Nikolaj Bjorner 2021-08-25 17:47:30 -07:00
parent f03d756e08
commit e6264a80ff
5 changed files with 64 additions and 17 deletions

View file

@ -126,7 +126,7 @@ bool macro_manager::insert(func_decl * f, quantifier * q, proof * pr, expr_depen
}
app * head;
expr * definition;
expr_ref definition(m);
bool revert = false;
get_head_def(q, f, head, definition, revert);
@ -190,21 +190,22 @@ void macro_manager::mark_forbidden(unsigned n, justified_expr const * exprs) {
}
void macro_manager::get_head_def(quantifier * q, func_decl * d, app * & head, expr * & def, bool& revert) const {
app * body = to_app(q->get_expr());
void macro_manager::get_head_def(quantifier * q, func_decl * d, app * & head, expr_ref & def, bool& revert) const {
expr * body = q->get_expr();
expr * lhs = nullptr, *rhs = nullptr;
bool is_not = m.is_not(body, body);
VERIFY(m.is_eq(body, lhs, rhs));
SASSERT(is_app_of(lhs, d) || is_app_of(rhs, d));
SASSERT(!is_app_of(lhs, d) || !is_app_of(rhs, d));
if (is_app_of(lhs, d)) {
revert = false;
head = to_app(lhs);
def = rhs;
def = is_not ? m.mk_not(rhs) : rhs;
}
else {
revert = true;
head = to_app(rhs);
def = lhs;
def = is_not ? m.mk_not(lhs) : lhs;
}
}
@ -215,7 +216,7 @@ void macro_manager::display(std::ostream & out) {
quantifier * q = nullptr;
m_decl2macro.find(f, q);
app * head;
expr * def;
expr_ref def(m);
bool r;
get_head_def(q, f, head, def, r);
SASSERT(q);
@ -227,7 +228,7 @@ func_decl * macro_manager::get_macro_interpretation(unsigned i, expr_ref & inter
func_decl * f = m_decls.get(i);
quantifier * q = m_macros.get(i);
app * head;
expr * def;
expr_ref def(m);
bool r;
get_head_def(q, f, head, def, r);
TRACE("macro_bug",
@ -298,7 +299,7 @@ struct macro_manager::macro_expander_cfg : public default_rewriter_cfg {
TRACE("macro_manager", tout << "trying to expand:\n" << mk_pp(n, m) << "\nd:\n" << d->get_name() << "\n";);
if (mm.m_decl2macro.find(d, q)) {
app * head = nullptr;
expr * def = nullptr;
expr_ref def(m);
bool revert = false;
mm.get_head_def(q, d, head, def, revert);
unsigned num = n->get_num_args();
@ -320,6 +321,14 @@ struct macro_manager::macro_expander_cfg : public default_rewriter_cfg {
r = rr;
if (m.proofs_enabled()) {
expr_ref instance = s(q->get_expr(), num, subst_args.data());
expr* eq, * lhs, * rhs;
if (m.is_not(instance, eq) && m.is_eq(eq, lhs, rhs)) {
if (revert)
instance = m.mk_eq(m.mk_not(lhs), rhs);
else
instance = m.mk_eq(lhs, m.mk_not(rhs));
}
SASSERT(m.is_eq(instance));
proof * qi_pr = m.mk_quant_inst(m.mk_or(m.mk_not(q), instance), num, subst_args.data());
proof * q_pr = mm.m_decl2macro_pr.find(d);
proof * prs[2] = { qi_pr, q_pr };