mirror of
https://github.com/Z3Prover/z3
synced 2025-04-10 19:27:06 +00:00
fix #6304
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.
This commit is contained in:
parent
45d8d73fce
commit
36d76a5bb2
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
|
Loading…
Reference in a new issue