3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-10 19:27:06 +00:00

better staging of mbi based on generation

This commit is contained in:
Nikolaj Bjorner 2021-01-18 16:55:58 -08:00
parent 990aecceb7
commit 01418a06a3
2 changed files with 43 additions and 35 deletions

View file

@ -89,10 +89,8 @@ namespace q {
unsigned g = n->class_generation();
generation_min = std::min(generation_min, g);
m_generation_max = std::max(m_generation_max, g);
if (g > m_generation_bound) {
std::cout << "SKIP\n";
if (g > m_generation_bound)
continue;
}
std::cout << mk_pp(e, m) << ": " << ctx.bpp(n) << " gen: " << n->generation() << " " << n->class_generation() << " class-size: " << n->get_root()->class_size() << "\n";
}
eqs.push_back(m.mk_eq(sk, e));
@ -134,7 +132,7 @@ namespace q {
if (count > m_max_choose_candidates)
break;
}
std::cout << "choose " << r->class_size() << " " << expr_ref(r->get_expr(), m) << "\n";
std::cout << "choose " << count << " " << r->class_size() << " " << gen << " " << expr_ref(r->get_expr(), m) << "\n";
return expr_ref(r->get_expr(), m);
}
@ -142,9 +140,6 @@ namespace q {
quantifier* q_flat = m_qs.flatten(q);
init_solver();
m_generation_bound = 1;
m_generation_max = 0;
::solver::scoped_push _sp(*m_solver);
std::cout << mk_pp(q, m, 4) << "\n";
auto* qb = specialize(q_flat);
if (!qb)
@ -152,41 +147,49 @@ namespace q {
if (m.is_false(qb->mbody))
return l_true;
#if 0
if (!qb->free_vars.empty())
quick_check(q, *qb);
add_universe_restriction(q, *qb);
std::cout << "gen-max: " << m_generation_max << "\n";
#if 0
if (quick_check(q, *qb)) {
// return l_false;
}
#endif
m_solver->assert_expr(qb->mbody);
lbool r = m_solver->check_sat(0, nullptr);
if (r == l_undef)
return r;
if (r == l_false)
return l_true;
model_ref mdl;
expr_ref proj(m);
m_solver->get_model(mdl);
if (check_forall_subst(q, *qb, *mdl))
return l_false;
else
return check_forall_default(q, *qb, *mdl);
m_generation_bound = 0;
m_generation_max = 0;
while (true) {
::solver::scoped_push _sp(*m_solver);
add_universe_restriction(q, *qb);
std::cout << "gen-max: " << m_generation_max << "\n";
m_solver->assert_expr(qb->mbody);
++m_stats.m_num_checks;
lbool r = m_solver->check_sat(0, nullptr);
if (r == l_undef)
return r;
if (r == l_true) {
model_ref mdl;
expr_ref proj(m);
m_solver->get_model(mdl);
if (check_forall_subst(q, *qb, *mdl))
return l_false;
if (check_forall_default(q, *qb, *mdl))
return l_false;
}
if (m_generation_bound >= m_generation_max)
return l_true;
m_generation_bound += 1;
m_generation_bound *= 3;
m_generation_bound /= 2;
}
return l_true;
}
lbool mbqi::check_forall_default(quantifier* q, q_body& qb, model& mdl) {
bool mbqi::check_forall_default(quantifier* q, q_body& qb, model& mdl) {
expr_ref_vector eqs(m);
add_domain_bounds(mdl, qb);
auto proj = solver_project(mdl, qb, eqs, false);
if (!proj)
return l_undef;
return false;
std::cout << "project-base\n" << proj << "\n";
add_instantiation(q, proj);
return l_false;
return true;
}
bool mbqi::check_forall_subst(quantifier* q, q_body& qb, model& mdl0) {
@ -197,7 +200,10 @@ namespace q {
unsigned i = 0;
::solver::scoped_push _sp(*m_solver);
add_domain_eqs(mdl0, qb);
for (; i < m_max_cex && l_true == m_solver->check_sat(0, nullptr); ++i) {
for (; i < m_max_cex; ++i) {
++m_stats.m_num_checks;
if (l_true != m_solver->check_sat(0, nullptr))
break;
m_solver->get_model(mdl1);
auto proj = solver_project(*mdl1, qb, eqs, true);
if (!proj)
@ -475,7 +481,6 @@ namespace q {
}
bool mbqi::quick_check(quantifier* q, q_body& qb) {
std::cout << "QUICK-CHECK\n";
unsigned max_rounds = 100;
unsigned_vector offsets;
if (!first_offset(offsets, qb.vars))
@ -485,12 +490,13 @@ namespace q {
expr_ref_vector binding(m);
for (unsigned i = 0; i < max_rounds && bindings < m_max_cex; ++i) {
set_binding(offsets, qb.vars, binding);
std::cout << "binding " << binding << "\n";
// std::cout << "binding " << binding << "\n";
if (m_model->is_true(qb.vbody)) {
expr_ref body(q->get_expr(), m);
body = subst(q->get_expr(), binding);
if (is_forall(q))
body = ::mk_not(m, body);
std::cout << "QUICK-CHECK\n";
std::cout << "instantiate " << mk_pp(q, m) << "\n";
std::cout << "binding:\n" << binding << "\n";
std::cout << "body:\n" << body << "\n";
@ -594,6 +600,7 @@ namespace q {
if (m_solver)
m_solver->collect_statistics(st);
st.update("q-num-instantiations", m_stats.m_num_instantiations);
st.update("q-num-checks", m_stats.m_num_checks);
}
}

View file

@ -32,6 +32,7 @@ namespace q {
class mbqi {
struct stats {
unsigned m_num_instantiations;
unsigned m_num_checks;
stats() { reset(); }
@ -90,7 +91,7 @@ namespace q {
void add_plugin(mbp::project_plugin* p);
void add_instantiation(quantifier* q, expr_ref& proj);
lbool check_forall_default(quantifier* q, q_body& qb, model& mdl);
bool check_forall_default(quantifier* q, q_body& qb, model& mdl);
bool check_forall_subst(quantifier* q, q_body& qb, model& mdl);
bool quick_check(quantifier* q, q_body& qb);