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