Skip to content

Commit 6616b6a

Browse files
only case expand for cases that contain defs. fixes #2601
Signed-off-by: Nikolaj Bjorner <[email protected]>
1 parent 88f0e4a commit 6616b6a

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

src/ast/recfun_decl_plugin.cpp

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,30 @@ namespace recfun {
6464
m_decl = m.mk_func_decl(s, arity, domain, range, info);
6565
}
6666

67+
bool def::contains_def(util& u, expr * e) {
68+
struct def_find_p : public i_expr_pred {
69+
util& u;
70+
def_find_p(util& u): u(u) {}
71+
bool operator()(expr* a) override { return is_app(a) && u.is_defined(to_app(a)->get_decl()); }
72+
};
73+
def_find_p p(u);
74+
check_pred cp(p, m, false);
75+
return cp(e);
76+
}
77+
6778
// does `e` contain any `ite` construct?
68-
bool def::contains_ite(expr * e) {
79+
bool def::contains_ite(util& u, expr * e) {
6980
struct ite_find_p : public i_expr_pred {
7081
ast_manager & m;
71-
ite_find_p(ast_manager & m) : m(m) {}
72-
bool operator()(expr * e) override { return m.is_ite(e); }
82+
def& d;
83+
util& u;
84+
ite_find_p(ast_manager & m, def& d, util& u) : m(m), d(d), u(u) {}
85+
bool operator()(expr * e) override { return m.is_ite(e) && d.contains_def(u, e); }
7386
};
7487
// ignore ites under quantifiers.
7588
// this is redundant as the code
7689
// that unfolds ites uses quantifier-free portion.
77-
ite_find_p p(m);
90+
ite_find_p p(m, *this, u);
7891
check_pred cp(p, m, false);
7992
return cp(e);
8093
}
@@ -189,7 +202,8 @@ namespace recfun {
189202

190203

191204
// Compute a set of cases, given the RHS
192-
void def::compute_cases(replace& subst,
205+
void def::compute_cases(util& u,
206+
replace& subst,
193207
is_immediate_pred & is_i,
194208
unsigned n_vars, var *const * vars, expr* rhs)
195209
{
@@ -209,7 +223,7 @@ namespace recfun {
209223
expr_ref_vector conditions(m);
210224

211225
// is the function a macro (unconditional body)?
212-
if (n_vars == 0 || !contains_ite(rhs)) {
226+
if (n_vars == 0 || !contains_ite(u, rhs)) {
213227
// constant function or trivial control flow, only one (dummy) case
214228
add_case(name, 0, conditions, rhs);
215229
return;
@@ -248,7 +262,7 @@ namespace recfun {
248262
else if (is_app(e)) {
249263
// explore arguments
250264
for (expr * arg : *to_app(e)) {
251-
if (contains_ite(arg)) {
265+
if (contains_ite(u, arg)) {
252266
stack.push_back(arg);
253267
}
254268
}
@@ -361,7 +375,7 @@ namespace recfun {
361375
SASSERT(n_vars == d->get_arity());
362376

363377
is_imm_pred is_i(*u);
364-
d->compute_cases(r, is_i, n_vars, vars, rhs);
378+
d->compute_cases(*u, r, is_i, n_vars, vars, rhs);
365379
}
366380

367381
namespace decl {

src/ast/recfun_decl_plugin.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,11 @@ namespace recfun {
111111
def(ast_manager &m, family_id fid, symbol const & s, unsigned arity, sort *const * domain, sort* range, bool is_generated);
112112

113113
// compute cases for a function, given its RHS (possibly containing `ite`).
114-
void compute_cases(replace& subst, is_immediate_pred &,
114+
void compute_cases(util& u, replace& subst, is_immediate_pred &,
115115
unsigned n_vars, var *const * vars, expr* rhs);
116116
void add_case(std::string & name, unsigned case_index, expr_ref_vector const& conditions, expr* rhs, bool is_imm = false);
117-
bool contains_ite(expr* e); // expression contains a test?
117+
bool contains_ite(util& u, expr* e); // expression contains a test?
118+
bool contains_def(util& u, expr* e); // expression contains a def
118119
public:
119120
symbol const & get_name() const { return m_name; }
120121
vars const & get_vars() const { return m_vars; }

0 commit comments

Comments
 (0)