3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-06 17:44:08 +00:00

connect mbi

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-09-29 23:51:09 -07:00
parent 4e74c4cdd4
commit 1d199b707b
8 changed files with 82 additions and 19 deletions

View file

@ -23,6 +23,7 @@ Author:
#include "sat/smt/bv_solver.h"
#include "sat/smt/euf_solver.h"
#include "sat/smt/array_solver.h"
#include "sat/smt/q_solver.h"
namespace euf {
@ -67,10 +68,24 @@ namespace euf {
th_solver* solver::expr2solver(expr* e) {
if (is_app(e))
return func_decl2solver(to_app(e)->get_decl());
return func_decl2solver(to_app(e)->get_decl());
if (is_forall(e) || is_exists(e))
return quantifier2solver();
return nullptr;
}
th_solver* solver::quantifier2solver() {
family_id fid = m.mk_family_id(q::solver::name());
auto* ext = m_id2solver.get(fid, nullptr);
if (ext)
return ext;
ext = alloc(q::solver, *this);
ext->set_solver(m_solver);
ext->push_scopes(s().num_scopes());
add_solver(fid, ext);
return ext;
}
th_solver* solver::get_solver(family_id fid, func_decl* f) {
if (fid == null_family_id)
return nullptr;
@ -122,6 +137,8 @@ namespace euf {
void solver::init_search() {
TRACE("before_search", s().display(tout););
for (auto* s : m_solvers)
s->init_search();
}
bool solver::is_external(bool_var v) {

View file

@ -111,7 +111,7 @@ namespace euf {
bool visit(expr* e) override;
bool visited(expr* e) override;
bool post_visit(expr* e, bool sign, bool root) override;
sat::literal attach_lit(sat::literal lit, expr* e);
void add_distinct_axiom(app* e, euf::enode* const* args);
void add_not_distinct_axiom(app* e, euf::enode* const* args);
void axiomatize_basic(enode* n);
@ -129,6 +129,7 @@ namespace euf {
th_solver* get_solver(family_id fid, func_decl* f);
th_solver* sort2solver(sort* s) { return get_solver(s->get_family_id(), nullptr); }
th_solver* func_decl2solver(func_decl* f) { return get_solver(f->get_family_id(), f); }
th_solver* quantifier2solver();
th_solver* expr2solver(expr* e);
th_solver* bool_var2solver(sat::bool_var v);
th_solver* fid2solver(family_id fid) const { return m_id2solver.get(fid, nullptr); }
@ -287,6 +288,7 @@ namespace euf {
expr_ref mk_eq(euf::enode* n1, euf::enode* n2) { return mk_eq(n1->get_expr(), n2->get_expr()); }
euf::enode* mk_enode(expr* e, unsigned n, enode* const* args) { return m_egraph.mk(e, n, args); }
expr* bool_var2expr(sat::bool_var v) { return m_var2expr.get(v, nullptr); }
sat::literal attach_lit(sat::literal lit, expr* e);
void unhandled_function(func_decl* f);
th_rewriter& get_rewriter() { return m_rewriter; }
bool is_shared(euf::enode* n) const;

View file

@ -64,8 +64,7 @@ namespace q {
expr_ref mbqi::replace_model_value(expr* e) {
if (m.is_model_value(e)) {
register_value(e);
expr_ref r(e, m);
return r;
return expr_ref(e, m);
}
if (is_app(e) && to_app(e)->get_num_args() > 0) {
expr_ref_vector args(m);
@ -98,16 +97,35 @@ namespace q {
return r;
if (r == l_false)
return l_true;
model_ref mdl;
m_solver->get_model(mdl);
expr_ref proj = project(*mdl, q, vars);
if (!proj)
return l_undef;
if (is_forall(q))
qs.add_clause(~ctx.expr2literal(q), ctx.b_internalize(proj));
else
qs.add_clause(ctx.expr2literal(q), ~ctx.b_internalize(proj));
return l_true;
model_ref mdl0, mdl1;
m_solver->get_model(mdl0);
expr_ref proj(m);
auto add_projection = [&](model& mdl) {
proj = project(*mdl1, q, vars);
if (!proj)
return;
if (is_forall(q))
qs.add_clause(~ctx.expr2literal(q), ctx.b_internalize(proj));
else
qs.add_clause(ctx.expr2literal(q), ~ctx.b_internalize(proj));
};
bool added = false;
#if 0
restrict_vars_to_instantiation_sets(mdl0, q, vars);
for (unsigned i = 0; i < m_max_cex && l_true == m_solver->check_sat(0, nullptr); ++i) {
m_solver->get_model(mdl1);
add_projection(*mdl1);
if (!proj)
break;
added = true;
m_solver->assert_expr(m.mk_not(proj));
}
#endif
if (!added) {
add_projection(*mdl0);
added = proj;
}
return added ? l_false : l_undef;
}
expr_ref mbqi::specialize(quantifier* q, expr_ref_vector& vars) {
@ -181,6 +199,7 @@ namespace q {
break;
}
}
m_max_cex += ctx.get_config().m_mbqi_max_cexs;
return result;
}
@ -193,7 +212,11 @@ namespace q {
void mbqi::init_solver() {
if (!m_solver)
m_solver = ctx.mk_solver();
m_solver = mk_smt2_solver(m, ctx.s().params());
}
void mbqi::init_search() {
m_max_cex = ctx.get_config().m_mbqi_max_cexs;
}
}

View file

@ -36,6 +36,7 @@ namespace q {
obj_map<sort, obj_hashtable<expr>*> m_fresh;
scoped_ptr_vector<obj_hashtable<expr>> m_values;
expr_ref_vector m_fresh_trail;
unsigned m_max_cex{ 10 };
void restrict_to_universe(expr * sk, ptr_vector<expr> const & universe);
void register_value(expr* e);
@ -53,6 +54,8 @@ namespace q {
mbqi(euf::solver& ctx, solver& s);
lbool operator()();
void init_search();
};
}

View file

@ -25,7 +25,7 @@ Author:
namespace q {
solver::solver(euf::solver& ctx):
th_euf_solver(ctx, ctx.get_manager().get_family_id("quant")),
th_euf_solver(ctx, ctx.get_manager().get_family_id(name())),
m_mbqi(ctx, *this)
{}
@ -38,7 +38,7 @@ namespace q {
}
else {
// universal force
add_clause(~l, uskolemize(to_quantifier(e)));
// add_clause(~l, uskolemize(to_quantifier(e)));
ctx.push_vec(m_universal, l);
}
}
@ -106,5 +106,16 @@ namespace q {
NOT_IMPLEMENTED_YET();
return sat::null_literal;
}
void solver::init_search() {
m_mbqi.init_search();
}
sat::literal solver::internalize(expr* e, bool sign, bool root, bool learned) {
SASSERT(is_forall(e) || is_exists(e));
sat::bool_var v = ctx.get_si().add_bool_var(e);
sat::literal lit = ctx.attach_lit(sat::literal(v, sign), e);
mk_var(ctx.get_egraph().find(e));
return lit;
}
}

View file

@ -51,6 +51,7 @@ namespace q {
solver(euf::solver& ctx);
~solver() override {}
static char const* name() { return "quant"; }
bool is_external(sat::bool_var v) override { return false; }
void get_antecedents(sat::literal l, sat::ext_justification_idx idx, sat::literal_vector& r, bool probing) override {}
void asserted(sat::literal l) override;
@ -62,9 +63,10 @@ namespace q {
void collect_statistics(statistics& st) const override;
euf::th_solver* clone(sat::solver* s, euf::solver& ctx) override;
bool unit_propagate() override;
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override { UNREACHABLE(); return sat::null_literal; }
sat::literal internalize(expr* e, bool sign, bool root, bool learned) override;
void internalize(expr* e, bool redundant) override { UNREACHABLE(); }
euf::theory_var mk_var(euf::enode* n) override;
void init_search() override;
ast_manager& get_manager() { return m; }
};

View file

@ -34,6 +34,8 @@ public:
solver_factory * mk_smt_strategic_solver_factory(symbol const & logic = symbol::null);
solver* mk_smt2_solver(ast_manager& m, params_ref const& p);
/**
\brief Abstract interface for making solvers available in the Z3
API and front-ends such as SMT 2.0 and (legacy) SMT 1.0.

View file

@ -168,3 +168,6 @@ solver_factory * mk_smt_strategic_solver_factory(symbol const & logic) {
return alloc(smt_strategic_solver_factory, logic);
}
solver* mk_smt2_solver(ast_manager& m, params_ref const& p) {
return mk_inc_sat_solver(m, p);
}