3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-27 16:38:45 +00:00

Fix quasi-macro variable checks. Fixes #3029.

This commit is contained in:
Christoph M. Wintersteiger 2020-03-04 16:40:36 +00:00
parent fcbf660592
commit 19ed465696
No known key found for this signature in database
GPG key ID: BCF6360F86294467
3 changed files with 35 additions and 35 deletions

View file

@ -366,7 +366,7 @@ bool macro_util::is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t
Return true if \c n is a quasi-macro. Store the macro head in \c head, and the conditions to apply the macro in \c cond. Return true if \c n is a quasi-macro. Store the macro head in \c head, and the conditions to apply the macro in \c cond.
*/ */
bool macro_util::is_quasi_macro_head(expr * n, unsigned num_decls) const { bool macro_util::is_quasi_macro_head(expr * n, unsigned num_decls, expr * def) const {
if (is_app(n) && if (is_app(n) &&
to_app(n)->get_family_id() == null_family_id && to_app(n)->get_family_id() == null_family_id &&
to_app(n)->get_num_args() >= num_decls) { to_app(n)->get_num_args() >= num_decls) {
@ -374,20 +374,22 @@ bool macro_util::is_quasi_macro_head(expr * n, unsigned num_decls) const {
sbuffer<bool> found_vars; sbuffer<bool> found_vars;
found_vars.resize(num_decls, false); found_vars.resize(num_decls, false);
unsigned num_found_vars = 0; unsigned num_found_vars = 0;
expr_free_vars fv;
for (unsigned i = 0; i < num_args; i++) { for (unsigned i = 0; i < num_args; i++) {
expr * arg = to_app(n)->get_arg(i); expr * arg = to_app(n)->get_arg(i);
if (is_var(arg)) {
unsigned idx = to_var(arg)->get_idx();
if (idx >= num_decls)
return false;
if (found_vars[idx] == false) {
found_vars[idx] = true;
num_found_vars++;
}
}
else {
if (occurs(to_app(n)->get_decl(), arg)) if (occurs(to_app(n)->get_decl(), arg))
return false; return false;
else
fv.accumulate(arg);
}
if (def)
fv.accumulate(def);
for (unsigned i = 0; i < fv.size(); i++) {
if (i >= num_decls || !fv.contains(i))
continue; // Quasi-macros may have new variables.
if (found_vars[i] == false) {
found_vars[i] = true;
num_found_vars++;
} }
} }
return num_found_vars == num_decls; return num_found_vars == num_decls;
@ -437,7 +439,8 @@ void macro_util::quasi_macro_head_to_macro_head(app * qhead, unsigned & num_decl
*/ */
void macro_util::mk_macro_interpretation(app * head, unsigned num_decls, expr * def, expr_ref & interp) const { void macro_util::mk_macro_interpretation(app * head, unsigned num_decls, expr * def, expr_ref & interp) const {
TRACE("macro_util", tout << mk_pp(head, m_manager) << "\n";); TRACE("macro_util", tout << mk_pp(head, m_manager) << "\n";);
SASSERT(is_macro_head(head, head->get_num_args())); SASSERT(is_macro_head(head, head->get_num_args()) ||
is_quasi_macro_head(head, head->get_num_args(), def));
SASSERT(!occurs(head->get_decl(), def)); SASSERT(!occurs(head->get_decl(), def));
normalize_expr(head, num_decls, def, interp); normalize_expr(head, num_decls, def, interp);
} }
@ -926,6 +929,3 @@ void macro_util::collect_macro_candidates(quantifier * q, macro_candidates & r)
collect_macro_candidates_core(n, num_decls, r); collect_macro_candidates_core(n, num_decls, r);
} }
} }

View file

@ -112,7 +112,7 @@ public:
bool is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, app_ref & t); bool is_pseudo_head(expr * n, unsigned num_decls, app_ref & head, app_ref & t);
bool is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def); bool is_pseudo_predicate_macro(expr * n, app_ref & head, app_ref & t, expr_ref & def);
bool is_quasi_macro_head(expr * n, unsigned num_decls) const; bool is_quasi_macro_head(expr * n, unsigned num_decls, expr * def = NULL) const;
void quasi_macro_head_to_macro_head(app * qhead, unsigned & num_decls, app_ref & head, expr_ref & cond) const; void quasi_macro_head_to_macro_head(app * qhead, unsigned & num_decls, app_ref & head, expr_ref & cond) const;
void mk_macro_interpretation(app * head, unsigned num_decls, expr * def, expr_ref & interp) const; void mk_macro_interpretation(app * head, unsigned num_decls, expr * def, expr_ref & interp) const;