mirror of
https://github.com/Z3Prover/z3
synced 2025-08-11 13:40:52 +00:00
fix #5016
This commit is contained in:
parent
04a1d4245c
commit
083d09aa81
14 changed files with 366 additions and 294 deletions
|
@ -20,6 +20,7 @@ Revision History:
|
|||
#include<iostream>
|
||||
#include "ast/for_each_ast.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "ast/datatype_decl_plugin.h"
|
||||
|
||||
// #define AST_LL_PP_SHOW_FAMILY_NAME
|
||||
|
||||
|
@ -30,6 +31,7 @@ class ll_printer {
|
|||
bool m_only_exprs;
|
||||
bool m_compact;
|
||||
arith_util m_autil;
|
||||
datatype_util m_dt;
|
||||
|
||||
void display_def_header(ast * n) {
|
||||
if (n != m_root) {
|
||||
|
@ -114,6 +116,10 @@ class ll_printer {
|
|||
}
|
||||
m_out << "]";
|
||||
}
|
||||
else if (is_func_decl(d) && m_dt.is_is(to_func_decl(d))) {
|
||||
func_decl* fd = m_dt.get_recognizer_constructor(to_func_decl(d));
|
||||
m_out << " " << fd->get_name();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -124,7 +130,8 @@ public:
|
|||
m_root(n),
|
||||
m_only_exprs(only_exprs),
|
||||
m_compact(compact),
|
||||
m_autil(m) {
|
||||
m_autil(m),
|
||||
m_dt(m) {
|
||||
}
|
||||
|
||||
void pp(ast* n) {
|
||||
|
|
|
@ -185,7 +185,9 @@ namespace recfun {
|
|||
conditions.push_back(choices->sign ? c : m.mk_not(c));
|
||||
|
||||
// binding to add to the substitution
|
||||
subst.insert(ite, choices->sign ? th : el);
|
||||
expr_ref tgt(choices->sign ? th : el, m);
|
||||
tgt = subst(tgt);
|
||||
subst.insert(ite, tgt);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -193,9 +195,10 @@ namespace recfun {
|
|||
void def::add_case(std::string & name, unsigned case_index, expr_ref_vector const& conditions, expr * rhs, bool is_imm) {
|
||||
case_def c(m, m_fid, this, name, case_index, get_domain(), conditions, rhs);
|
||||
c.set_is_immediate(is_imm);
|
||||
TRACEFN("add_case " << name << " " << mk_pp(rhs, m)
|
||||
<< " :is_imm " << is_imm
|
||||
<< " :guards " << conditions);
|
||||
TRACEFN("add_case " << name
|
||||
<< "\n" << mk_pp(rhs, m)
|
||||
<< "\n:is_imm " << is_imm
|
||||
<< "\n:guards " << conditions);
|
||||
m_cases.push_back(c);
|
||||
}
|
||||
|
||||
|
@ -250,7 +253,7 @@ namespace recfun {
|
|||
|
||||
while (! stack.empty()) {
|
||||
expr * e = stack.back();
|
||||
stack.pop_back();
|
||||
stack.pop_back();
|
||||
|
||||
if (m.is_ite(e)) {
|
||||
// need to do a case split on `e`, forking the search space
|
||||
|
@ -490,9 +493,9 @@ namespace recfun {
|
|||
max_score = kv.m_value;
|
||||
}
|
||||
}
|
||||
if (max_score <= 4) {
|
||||
if (max_score <= 4)
|
||||
break;
|
||||
}
|
||||
|
||||
ptr_vector<sort> domain;
|
||||
ptr_vector<expr> args;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
|
@ -500,21 +503,20 @@ namespace recfun {
|
|||
args.push_back(vars[i]);
|
||||
}
|
||||
|
||||
symbol fresh_name(m().mk_fresh_id());
|
||||
symbol fresh_name("fold-rec-" + std::to_string(m().mk_fresh_id()));
|
||||
auto pd = mk_def(fresh_name, n, domain.c_ptr(), max_expr->get_sort());
|
||||
func_decl* f = pd.get_def()->get_decl();
|
||||
expr_ref new_body(m().mk_app(f, n, args.c_ptr()), m());
|
||||
set_definition(subst, pd, n, vars, max_expr);
|
||||
subst.insert(max_expr, new_body);
|
||||
result = subst(result);
|
||||
TRACEFN("substituted " << mk_pp(max_expr, m()) << " -> " << new_body << "\n" << result);
|
||||
TRACEFN("substituted\n" << mk_pp(max_expr, m()) << "\n->\n" << new_body << "\n" << result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
case_expansion::case_expansion(recfun::util& u, app * n) :
|
||||
m_lhs(n, u.m()), m_def(nullptr), m_args(u.m()) {
|
||||
SASSERT(u.is_defined(n));
|
||||
|
|
|
@ -312,7 +312,41 @@ namespace recfun {
|
|||
return e.display(out);
|
||||
}
|
||||
|
||||
struct propagation_item {
|
||||
case_expansion* m_case { nullptr };
|
||||
body_expansion* m_body { nullptr };
|
||||
expr_ref_vector* m_core { nullptr };
|
||||
expr* m_guard { nullptr };
|
||||
|
||||
~propagation_item() {
|
||||
dealloc(m_case);
|
||||
dealloc(m_body);
|
||||
dealloc(m_core);
|
||||
}
|
||||
|
||||
propagation_item(expr* guard):
|
||||
m_guard(guard) {}
|
||||
|
||||
propagation_item(expr_ref_vector const& core):
|
||||
m_core(alloc(expr_ref_vector, core)) {
|
||||
}
|
||||
|
||||
propagation_item(body_expansion* b):
|
||||
m_body(b) {}
|
||||
|
||||
propagation_item(case_expansion* c):
|
||||
m_case(c) {}
|
||||
|
||||
bool is_guard() const { return m_guard != nullptr; }
|
||||
bool is_core() const { return m_core != nullptr; }
|
||||
bool is_case() const { return m_case != nullptr; }
|
||||
bool is_body() const { return m_body != nullptr; }
|
||||
|
||||
expr_ref_vector const& core() const { SASSERT(is_core()); return *m_core; }
|
||||
body_expansion & body() const { SASSERT(is_body()); return *m_body; }
|
||||
case_expansion & case_ex() const { SASSERT(is_case()); return *m_case; }
|
||||
expr* guard() const { SASSERT(is_guard()); return m_guard; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue