mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
working with incremental depth
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
aa6e1badf2
commit
67077d960e
8 changed files with 127 additions and 126 deletions
|
@ -34,7 +34,7 @@ namespace smt {
|
|||
m_plugin(*reinterpret_cast<recfun_decl_plugin*>(m.get_plugin(get_family_id()))),
|
||||
m_util(m_plugin.u()),
|
||||
m_preds(m),
|
||||
m_max_depth(2),
|
||||
m_max_depth(0),
|
||||
m_q_case_expand(),
|
||||
m_q_body_expand()
|
||||
{
|
||||
|
@ -50,11 +50,15 @@ namespace smt {
|
|||
return alloc(theory_recfun, new_ctx->get_manager());
|
||||
}
|
||||
|
||||
void theory_recfun::init_search_eh() {
|
||||
smt_params_helper p(ctx().get_params());
|
||||
void theory_recfun::init(context* ctx) {
|
||||
theory::init(ctx);
|
||||
smt_params_helper p(ctx->get_params());
|
||||
m_max_depth = p.recfun_depth();
|
||||
if (m_max_depth < 2) m_max_depth = 2;
|
||||
}
|
||||
|
||||
void theory_recfun::init_search_eh() {
|
||||
}
|
||||
|
||||
bool theory_recfun::internalize_atom(app * atom, bool gate_ctx) {
|
||||
TRACEFN(mk_pp(atom, m));
|
||||
|
@ -199,26 +203,22 @@ namespace smt {
|
|||
* retrieve depth associated with predicate or expression.
|
||||
*/
|
||||
unsigned theory_recfun::get_depth(expr* e) {
|
||||
SASSERT(u().is_defined(e) || u().is_case_pred(e));
|
||||
unsigned d = 0;
|
||||
m_pred_depth.find(e, d);
|
||||
TRACEFN("depth " << d << " " << mk_pp(e, m));
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update depth of subterms of e with respect to d.
|
||||
*/
|
||||
void theory_recfun::set_depth(unsigned d, expr* e) {
|
||||
void theory_recfun::set_depth_rec(unsigned d, expr* e) {
|
||||
struct insert_c {
|
||||
theory_recfun& th;
|
||||
unsigned m_depth;
|
||||
insert_c(theory_recfun& th, unsigned d): th(th), m_depth(d) {}
|
||||
void operator()(app* e) {
|
||||
if (th.u().is_defined(e) && !th.m_pred_depth.contains(e)) {
|
||||
th.m_pred_depth.insert(e, m_depth);
|
||||
th.m_preds.push_back(e);
|
||||
TRACEFN("depth " << m_depth << " : " << mk_pp(e, th.m));
|
||||
}
|
||||
}
|
||||
void operator()(app* e) { th.set_depth(m_depth, e); }
|
||||
void operator()(quantifier*) {}
|
||||
void operator()(var*) {}
|
||||
};
|
||||
|
@ -226,6 +226,14 @@ namespace smt {
|
|||
for_each_expr(proc, e);
|
||||
}
|
||||
|
||||
void theory_recfun::set_depth(unsigned depth, expr* e) {
|
||||
if ((u().is_defined(e) || u().is_case_pred(e)) && !m_pred_depth.contains(e)) {
|
||||
m_pred_depth.insert(e, depth);
|
||||
m_preds.push_back(e);
|
||||
TRACEFN("depth " << depth << " : " << mk_pp(e, m));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* if `is_true` and `v = C_f_i(t1...tn)`,
|
||||
* then body-expand i-th case of `f(t1...tn)`
|
||||
|
@ -250,7 +258,7 @@ namespace smt {
|
|||
expr_ref new_body(m);
|
||||
new_body = subst(e, args.size(), args.c_ptr());
|
||||
ctx().get_rewriter()(new_body); // simplify
|
||||
set_depth(depth + 1, new_body);
|
||||
set_depth_rec(depth + 1, new_body);
|
||||
return new_body;
|
||||
}
|
||||
|
||||
|
@ -312,19 +320,23 @@ namespace smt {
|
|||
SASSERT(e.m_def->is_fun_defined());
|
||||
// add case-axioms for all case-paths
|
||||
auto & vars = e.m_def->get_vars();
|
||||
literal_vector preds;
|
||||
for (recfun::case_def const & c : e.m_def->get_cases()) {
|
||||
// applied predicate to `args`
|
||||
app_ref pred_applied = c.apply_case_predicate(e.m_args);
|
||||
|
||||
// cut off cases below max-depth
|
||||
unsigned depth = get_depth(e.m_lhs);
|
||||
set_depth(depth, pred_applied);
|
||||
SASSERT(u().owns_app(pred_applied));
|
||||
literal concl = mk_literal(pred_applied);
|
||||
preds.push_back(concl);
|
||||
|
||||
if (depth >= m_max_depth) {
|
||||
assert_max_depth_limit(pred_applied);
|
||||
continue;
|
||||
}
|
||||
|
||||
SASSERT(u().owns_app(pred_applied));
|
||||
literal concl = mk_literal(pred_applied);
|
||||
|
||||
literal_vector guards;
|
||||
guards.push_back(concl);
|
||||
|
@ -338,10 +350,11 @@ namespace smt {
|
|||
ctx().mk_th_axiom(get_id(), guards);
|
||||
|
||||
if (c.is_immediate()) {
|
||||
body_expansion be(e.m_lhs, c, e.m_args);
|
||||
body_expansion be(pred_applied, c, e.m_args);
|
||||
assert_body_axiom(be);
|
||||
}
|
||||
}
|
||||
ctx().mk_th_axiom(get_id(), preds);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -357,7 +370,7 @@ namespace smt {
|
|||
auto & vars = d.get_vars();
|
||||
auto & args = e.m_args;
|
||||
SASSERT(is_standard_order(vars));
|
||||
unsigned depth = get_depth(e.m_lhs);
|
||||
unsigned depth = get_depth(e.m_pred);
|
||||
expr_ref lhs(u().mk_fun_defined(d, args), m);
|
||||
expr_ref rhs = apply_args(depth, vars, args, e.m_cdef->get_rhs());
|
||||
|
||||
|
@ -388,7 +401,7 @@ namespace smt {
|
|||
}
|
||||
|
||||
void theory_recfun::add_theory_assumptions(expr_ref_vector & assumptions) {
|
||||
if (u().has_def()) {
|
||||
if (u().has_defs()) {
|
||||
app_ref dlimit = m_util.mk_depth_limit_pred(m_max_depth);
|
||||
TRACEFN("add_theory_assumption " << mk_pp(dlimit.get(), m));
|
||||
assumptions.push_back(dlimit);
|
||||
|
|
|
@ -66,20 +66,20 @@ namespace smt {
|
|||
|
||||
// one body-expansion of `f(t1...tn)` using a `C_f_i(t1...tn)`
|
||||
struct body_expansion {
|
||||
app* m_lhs;
|
||||
app* m_pred;
|
||||
recfun_case_def const * m_cdef;
|
||||
ptr_vector<expr> m_args;
|
||||
|
||||
body_expansion(recfun_util& u, app * n) : m_lhs(n), m_cdef(0), m_args() {
|
||||
body_expansion(recfun_util& u, app * n) : m_pred(n), m_cdef(0), m_args() {
|
||||
m_cdef = &u.get_case_def(n);
|
||||
m_args.append(n->get_num_args(), n->get_args());
|
||||
}
|
||||
body_expansion(app* lhs, recfun_case_def const & d, ptr_vector<expr> & args) :
|
||||
m_lhs(lhs), m_cdef(&d), m_args(args) {}
|
||||
body_expansion(app* pred, recfun_case_def const & d, ptr_vector<expr> & args) :
|
||||
m_pred(pred), m_cdef(&d), m_args(args) {}
|
||||
body_expansion(body_expansion const & from):
|
||||
m_lhs(from.m_lhs), m_cdef(from.m_cdef), m_args(from.m_args) {}
|
||||
m_pred(from.m_pred), m_cdef(from.m_cdef), m_args(from.m_args) {}
|
||||
body_expansion(body_expansion && from) :
|
||||
m_lhs(from.m_lhs), m_cdef(from.m_cdef), m_args(std::move(from.m_args)) {}
|
||||
m_pred(from.m_pred), m_cdef(from.m_cdef), m_args(std::move(from.m_args)) {}
|
||||
};
|
||||
|
||||
struct pp_body_expansion {
|
||||
|
@ -122,6 +122,7 @@ namespace smt {
|
|||
void assert_max_depth_limit(expr* guard);
|
||||
unsigned get_depth(expr* e);
|
||||
void set_depth(unsigned d, expr* e);
|
||||
void set_depth_rec(unsigned d, expr* e);
|
||||
|
||||
literal mk_eq_lit(expr* l, expr* r);
|
||||
bool is_standard_order(recfun::vars const& vars) const {
|
||||
|
@ -148,6 +149,7 @@ namespace smt {
|
|||
void new_eq_eh(theory_var v1, theory_var v2) override {}
|
||||
void new_diseq_eh(theory_var v1, theory_var v2) override {}
|
||||
void add_theory_assumptions(expr_ref_vector & assumptions) override;
|
||||
void init(context* ctx) override;
|
||||
|
||||
public:
|
||||
theory_recfun(ast_manager & m);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue