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:
parent
f03d756e08
commit
e6264a80ff
5 changed files with 64 additions and 17 deletions
|
|
@ -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 };
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue