Skip to content

Commit

Permalink
fix #6304
Browse files Browse the repository at this point in the history
Conditionals are used to guard unfolding of recursive functions.
This is, as shown in #6304, incompatible with the case where recursive functions are used inside if-then-else guards.
We address this by disabling if-conditions as guards if they contain a recursive definition.
The approach is simplistic: if a recursive function, defined prior (not mutually recursive) is used in a guard it should be fine and the condition can guard the current recursive unfolding.
  • Loading branch information
NikolajBjorner committed Aug 30, 2022
1 parent 45d8d73 commit 36d76a5
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/ast/recfun_decl_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,11 @@ namespace recfun {
expr * e = stack.back();
stack.pop_back();

if (m.is_ite(e)) {
expr* cond = nullptr, *th = nullptr, *el = nullptr;
if (m.is_ite(e, cond, th, el) && contains_def(u, cond)) {
// skip
}
else if (m.is_ite(e)) {
// need to do a case split on `e`, forking the search space
b.to_split = st.cons_ite(to_app(e), b.to_split);
}
Expand Down Expand Up @@ -338,9 +342,8 @@ namespace recfun {

// substitute, to get rid of `ite` terms
expr_ref case_rhs = subst(rhs);
for (unsigned i = 0; i < conditions.size(); ++i) {
for (unsigned i = 0; i < conditions.size(); ++i)
conditions[i] = subst(conditions.get(i));
}

// yield new case
bool is_imm = is_i(case_rhs);
Expand Down Expand Up @@ -471,9 +474,8 @@ namespace recfun {

void plugin::set_definition(replace& r, promise_def & d, bool is_macro, unsigned n_vars, var * const * vars, expr * rhs) {
u().set_definition(r, d, is_macro, n_vars, vars, rhs);
for (case_def & c : d.get_def()->get_cases()) {
for (case_def & c : d.get_def()->get_cases())
m_case_defs.insert(c.get_decl(), &c);
}
}

bool plugin::has_defs() const {
Expand Down

0 comments on commit 36d76a5

Please sign in to comment.