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:
parent
990aecceb7
commit
01418a06a3
2 changed files with 43 additions and 35 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue