3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2018-10-23 08:16:26 -07:00
parent fac114872f
commit aa6e1badf2
9 changed files with 95 additions and 33 deletions

View file

@ -96,5 +96,6 @@ def_module_params(module_name='smt',
('core.extend_nonlocal_patterns', BOOL, False, 'extend unsat cores with literals that have quantifiers with patterns that contain symbols which are not in the quantifier\'s body'),
('lemma_gc_strategy', UINT, 0, 'lemma garbage collection strategy: 0 - fixed, 1 - geometric, 2 - at restart, 3 - none'),
('dt_lazy_splits', UINT, 1, 'How lazy datatype splits are performed: 0- eager, 1- lazy for infinite types, 2- lazy'),
('recfun.native', BOOL, False, 'use native rec-fun solver')
('recfun.native', BOOL, False, 'use native rec-fun solver'),
('recfun.depth', UINT, 2, 'initial depth for maxrec expansion')
))

View file

@ -1384,7 +1384,10 @@ namespace smt {
SASSERT(m_manager.is_eq(n));
expr * lhs = n->get_arg(0);
expr * rhs = n->get_arg(1);
if (val == l_true) {
if (m_manager.is_bool(lhs)) {
// no-op
}
else if (val == l_true) {
add_eq(get_enode(lhs), get_enode(rhs), eq_justification(l));
}
else {

View file

@ -303,7 +303,7 @@ namespace smt {
for (bool_var v = 0; v < num; v++) {
if (has_enode(v)) {
enode * n = bool_var2enode(v);
if (n->is_eq() && is_relevant(n) && get_assignment(v) == l_false) {
if (n->is_eq() && is_relevant(n) && get_assignment(v) == l_false && !m_manager.is_iff(n->get_owner())) {
TRACE("check_th_diseq_propagation", tout << "checking: #" << n->get_owner_id() << " " << mk_bounded_pp(n->get_owner(), m_manager) << "\n";);
enode * lhs = n->get_arg(0)->get_root();
enode * rhs = n->get_arg(1)->get_root();

View file

@ -50,7 +50,14 @@ namespace smt {
return alloc(theory_recfun, new_ctx->get_manager());
}
void theory_recfun::init_search_eh() {
smt_params_helper p(ctx().get_params());
m_max_depth = p.recfun_depth();
}
bool theory_recfun::internalize_atom(app * atom, bool gate_ctx) {
TRACEFN(mk_pp(atom, m));
for (expr * arg : *atom) {
ctx().internalize(arg, false);
}
@ -76,7 +83,13 @@ namespace smt {
}
void theory_recfun::reset_queues() {
for (auto* e : m_q_case_expand) {
dealloc(e);
}
m_q_case_expand.reset();
for (auto* e : m_q_body_expand) {
dealloc(e);
}
m_q_body_expand.reset();
m_q_clauses.clear();
}
@ -96,8 +109,7 @@ namespace smt {
SASSERT(ctx().relevancy());
if (u().is_defined(n)) {
TRACEFN("relevant_eh: (defined) " << mk_pp(n, m));
case_expansion e(u(), n);
push_case_expand(std::move(e));
push_case_expand(alloc(case_expansion, u(), n));
}
}
@ -114,11 +126,13 @@ namespace smt {
// restore depth book-keeping
unsigned new_lim = m_preds_lim.size()-num_scopes;
#if 0
unsigned start = m_preds_lim[new_lim];
for (unsigned i = start; i < m_preds.size(); ++i) {
m_pred_depth.remove(m_preds.get(i));
}
m_preds.resize(start);
#endif
m_preds_lim.shrink(new_lim);
}
@ -141,25 +155,31 @@ namespace smt {
ctx().mk_th_axiom(get_id(), c);
}
m_q_clauses.clear();
for (unsigned i = 0; i < m_q_case_expand.size(); ++i) {
case_expansion & e = m_q_case_expand[i];
if (e.m_def->is_fun_macro()) {
case_expansion* e = m_q_case_expand[i];
if (e->m_def->is_fun_macro()) {
// body expand immediately
assert_macro_axiom(e);
assert_macro_axiom(*e);
}
else {
// case expand
SASSERT(e.m_def->is_fun_defined());
assert_case_axioms(e);
SASSERT(e->m_def->is_fun_defined());
assert_case_axioms(*e);
}
dealloc(e);
m_q_case_expand[i] = nullptr;
}
m_q_case_expand.clear();
m_stats.m_case_expansions += m_q_case_expand.size();
m_q_case_expand.reset();
for (unsigned i = 0; i < m_q_body_expand.size(); ++i) {
assert_body_axiom(m_q_body_expand[i]);
assert_body_axiom(*m_q_body_expand[i]);
dealloc(m_q_body_expand[i]);
m_q_body_expand[i] = nullptr;
}
m_q_body_expand.clear();
m_stats.m_body_expansions += m_q_body_expand.size();
m_q_body_expand.reset();
}
/**
@ -167,7 +187,6 @@ namespace smt {
* the guard appears at a depth below the current cutoff.
*/
void theory_recfun::assert_max_depth_limit(expr* guard) {
TRACEFN("max-depth limit");
literal_vector c;
app_ref dlimit = m_util.mk_depth_limit_pred(m_max_depth);
c.push_back(~mk_literal(dlimit));
@ -216,8 +235,7 @@ namespace smt {
if (is_true && u().is_case_pred(e)) {
TRACEFN("assign_case_pred_true " << mk_pp(e, m));
// body-expand
body_expansion b_e(u(), to_app(e));
push_body_expand(std::move(b_e));
push_body_expand(alloc(body_expansion, u(), to_app(e)));
}
}
@ -268,6 +286,7 @@ namespace smt {
* 2. add unit clause `f(args) = rhs`
*/
void theory_recfun::assert_macro_axiom(case_expansion & e) {
m_stats.m_macro_expansions++;
TRACEFN("case expansion " << pp_case_expansion(e, m) << "\n");
SASSERT(e.m_def->is_fun_macro());
auto & vars = e.m_def->get_vars();
@ -381,6 +400,7 @@ namespace smt {
for (auto & e : unsat_core) {
if (u().is_depth_limit(e)) {
m_max_depth = (3 * m_max_depth) / 2;
IF_VERBOSE(1, verbose_stream() << "(smt.recfun :increase-depth " << m_max_depth << ")\n");
return true;
}
}

View file

@ -101,8 +101,8 @@ namespace smt {
unsigned_vector m_preds_lim;
unsigned m_max_depth; // for fairness and termination
vector<case_expansion> m_q_case_expand;
vector<body_expansion> m_q_body_expand;
ptr_vector<case_expansion> m_q_case_expand;
ptr_vector<body_expansion> m_q_body_expand;
vector<literal_vector> m_q_clauses;
recfun_util & u() const { return m_util; }
@ -128,8 +128,8 @@ namespace smt {
return vars.size() == 0 || vars[vars.size()-1]->get_idx() == 0;
}
protected:
void push_case_expand(case_expansion&& e) { m_q_case_expand.push_back(e); }
void push_body_expand(body_expansion&& e) { m_q_body_expand.push_back(e); }
void push_case_expand(case_expansion* e) { m_q_case_expand.push_back(e); }
void push_body_expand(body_expansion* e) { m_q_body_expand.push_back(e); }
bool internalize_atom(app * atom, bool gate_ctx) override;
bool internalize_term(app * term) override;
@ -153,7 +153,7 @@ namespace smt {
theory_recfun(ast_manager & m);
~theory_recfun() override;
theory * mk_fresh(context * new_ctx) override;
void init_search_eh() override { m_max_depth = 2; }
void init_search_eh() override;
void display(std::ostream & out) const override;
void collect_statistics(::statistics & st) const override;
};