Skip to content

Commit 68f1f1e

Browse files
fix #4162
1 parent 9f6a733 commit 68f1f1e

File tree

2 files changed

+14
-7
lines changed

2 files changed

+14
-7
lines changed

src/ast/macros/macro_finder.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, bool deps_valid, expr_de
6161
if (!m_util.is_arith_macro(body, num_decls, head, def, inv))
6262
return false;
6363
app_ref new_body(m);
64+
func_decl * f = head->get_decl();
65+
// functions introduced within macros are Skolem functions
66+
// To avoid unsound expansion of these as macros (because they
67+
// appear in model conversions and are therefore not fully
68+
// replacable) we prevent these from being treated as macro functions.
69+
if (m_macro_manager.contains(f) || f->is_skolem())
70+
return false;
6471

6572
if (!inv || m.is_eq(body))
6673
new_body = m.mk_app(to_app(body)->get_decl(), head, def);
@@ -82,8 +89,7 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, bool deps_valid, expr_de
8289
}
8390
// is ge or le
8491
//
85-
TRACE("macro_finder", tout << "is_arith_macro: is_ge or is_le\n";);
86-
func_decl * f = head->get_decl();
92+
TRACE("macro_finder", tout << "is_arith_macro: is_ge or is_le " << f->get_name() << "\n";);
8793
func_decl * k = m.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range());
8894
app * k_app = m.mk_app(k, head->get_num_args(), head->get_args());
8995
expr_ref_buffer new_rhs_args(m);
@@ -132,6 +138,9 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, vector<justified_expr>&
132138
if (!m_util.is_arith_macro(body, num_decls, head, def, inv))
133139
return false;
134140
app_ref new_body(m);
141+
func_decl * f = head->get_decl();
142+
if (m_macro_manager.contains(f) || f->is_skolem())
143+
return false;
135144

136145
if (!inv || m.is_eq(body))
137146
new_body = m.mk_app(to_app(body)->get_decl(), head, def);
@@ -148,12 +157,11 @@ bool macro_finder::is_arith_macro(expr * n, proof * pr, vector<justified_expr>&
148157
new_pr = m.mk_modus_ponens(pr, rw);
149158
}
150159
if (m.is_eq(body)) {
151-
return m_macro_manager.insert(head->get_decl(), new_q, new_pr);
160+
return m_macro_manager.insert(f, new_q, new_pr);
152161
}
153162
// is ge or le
154163
//
155164
TRACE("macro_finder", tout << "is_arith_macro: is_ge or is_le\n";);
156-
func_decl * f = head->get_decl();
157165
func_decl * k = m.mk_fresh_func_decl(f->get_name(), symbol::null, f->get_arity(), f->get_domain(), f->get_range());
158166
app * k_app = m.mk_app(k, head->get_num_args(), head->get_args());
159167
expr_ref_buffer new_rhs_args(m);
@@ -289,7 +297,7 @@ bool macro_finder::expand_macros(expr_ref_vector const& exprs, proof_ref_vector
289297
found_new_macro = true;
290298
}
291299
else if (m_util.is_pseudo_predicate_macro(new_n, head, t, def)) {
292-
TRACE("macro_finder", tout << "found new pseudo macro:\n" << head << "\n" << t << "\n" << def << "\n";);
300+
TRACE("macro_finder", tout << "found new pseudo macro:\n" << head->get_decl()->get_name() << "\n" << t << "\n" << def << "\n";);
293301
pseudo_predicate_macro2macro(m, head, t, def, to_quantifier(new_n), new_pr, deps_valid, new_dep, new_exprs, new_prs, new_deps);
294302
found_new_macro = true;
295303
}
@@ -300,8 +308,6 @@ bool macro_finder::expand_macros(expr_ref_vector const& exprs, proof_ref_vector
300308
if (deps_valid)
301309
new_deps.push_back(new_dep);
302310
}
303-
TRACE("macro_finder", tout << exprs.size() << " " << deps.size() << " : ";
304-
tout << new_exprs.size() << " " << new_deps.size() << "\n";);
305311
SASSERT(exprs.size() != deps.size() || new_exprs.size() == new_deps.size());
306312
// SASSERT(!m.proofs_enabled() || new_exprs.size() == new_prs.size());
307313

src/ast/macros/macro_manager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ class macro_manager {
7979
bool is_forbidden(func_decl * d) const { return m_forbidden_set.contains(d); }
8080
obj_hashtable<func_decl> const & get_forbidden_set() const { return m_forbidden_set; }
8181
void display(std::ostream & out);
82+
bool contains(func_decl* d) const { return m_decls.contains(d); }
8283
unsigned get_num_macros() const { return m_decls.size(); }
8384
unsigned get_first_macro_last_level() const { return m_scopes.empty() ? 0 : m_scopes.back().m_decls_lim; }
8485
func_decl * get_macro_func_decl(unsigned i) const { return m_decls.get(i); }

0 commit comments

Comments
 (0)