3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-07 09:55:19 +00:00

stubs for model finder

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2020-09-30 08:56:05 -07:00
parent 458572323a
commit 414db51d5a
7 changed files with 123 additions and 19 deletions

View file

@ -502,6 +502,17 @@ void model::remove_decls(ptr_vector<func_decl> & decls, func_decl_set const & s)
decls.shrink(j); decls.shrink(j);
} }
expr_ref model::unfold_as_array(expr* e) {
func_decl* f = nullptr;
array_util autil(m);
if (!autil.is_as_array(e, f))
return expr_ref(e, m);
auto* fi = get_func_interp(f);
if (!fi)
return expr_ref(e, m);
return fi->get_array_interp(f);
}
expr_ref model::get_inlined_const_interp(func_decl* f) { expr_ref model::get_inlined_const_interp(func_decl* f) {
expr* v = get_const_interp(f); expr* v = get_const_interp(f);

View file

@ -78,6 +78,7 @@ public:
bool has_uninterpreted_sort(sort * s) const; bool has_uninterpreted_sort(sort * s) const;
expr_ref get_inlined_const_interp(func_decl* f); expr_ref get_inlined_const_interp(func_decl* f);
expr_ref unfold_as_array(expr* e);
// //
// Primitives for building models // Primitives for building models

View file

@ -24,6 +24,7 @@ z3_add_component(sat_smt
euf_relevancy.cpp euf_relevancy.cpp
euf_solver.cpp euf_solver.cpp
q_mbi.cpp q_mbi.cpp
q_model_finder.cpp
q_solver.cpp q_solver.cpp
sat_dual_solver.cpp sat_dual_solver.cpp
sat_th.cpp sat_th.cpp

View file

@ -26,7 +26,7 @@ Author:
namespace q { namespace q {
mbqi::mbqi(euf::solver& ctx, solver& s): mbqi::mbqi(euf::solver& ctx, solver& s):
ctx(ctx), qs(s), m(s.get_manager()), m_fresh_trail(m) {} ctx(ctx), qs(s), m(s.get_manager()), m_model_finder(ctx), m_fresh_trail(m) {}
void mbqi::restrict_to_universe(expr * sk, ptr_vector<expr> const & universe) { void mbqi::restrict_to_universe(expr * sk, ptr_vector<expr> const & universe) {
@ -86,10 +86,10 @@ namespace q {
} }
lbool mbqi::check_forall(quantifier* q) { lbool mbqi::check_forall(quantifier* q) {
expr_ref_vector vars(m);
expr_ref body = specialize(q, vars);
init_solver(); init_solver();
::solver::scoped_push _sp(*m_solver); ::solver::scoped_push _sp(*m_solver);
expr_ref_vector vars(m);
expr_ref body = specialize(q, vars);
m_solver->assert_expr(body); m_solver->assert_expr(body);
lbool r = m_solver->check_sat(0, nullptr); lbool r = m_solver->check_sat(0, nullptr);
if (r == l_undef) if (r == l_undef)
@ -99,8 +99,8 @@ namespace q {
model_ref mdl0, mdl1; model_ref mdl0, mdl1;
m_solver->get_model(mdl0); m_solver->get_model(mdl0);
expr_ref proj(m); expr_ref proj(m);
auto add_projection = [&](model& mdl) { auto add_projection = [&](model& mdl, bool inv) {
proj = project(*mdl1, q, vars); proj = project(mdl, q, vars, inv);
if (!proj) if (!proj)
return; return;
if (is_forall(q)) if (is_forall(q))
@ -110,10 +110,10 @@ namespace q {
}; };
bool added = false; bool added = false;
#if 0 #if 0
restrict_vars_to_instantiation_sets(mdl0, q, vars); m_model_finder.restrict_instantiations(*m_solver, *mdl0, q, vars);
for (unsigned i = 0; i < m_max_cex && l_true == m_solver->check_sat(0, nullptr); ++i) { for (unsigned i = 0; i < m_max_cex && l_true == m_solver->check_sat(0, nullptr); ++i) {
m_solver->get_model(mdl1); m_solver->get_model(mdl1);
add_projection(*mdl1); add_projection(*mdl1, true);
if (!proj) if (!proj)
break; break;
added = true; added = true;
@ -121,7 +121,7 @@ namespace q {
} }
#endif #endif
if (!added) { if (!added) {
add_projection(*mdl0); add_projection(*mdl0, false);
added = proj; added = proj;
} }
return added ? l_false : l_undef; return added ? l_false : l_undef;
@ -146,18 +146,18 @@ namespace q {
return body; return body;
} }
expr_ref mbqi::project(model& mdl, quantifier* q, expr_ref_vector& vars) {
return basic_project(mdl, q, vars);
}
/** /**
* A most rudimentary projection operator that only tries to find proxy terms from the set of existing terms. * A most rudimentary projection operator that only tries to find proxy terms from the set of existing terms.
* Refinements: * Refinements:
* - grammar based from MBQI paper * - grammar based from MBQI paper
* - quantifier elimination based on projection operators defined in qe. * - quantifier elimination based on projection operators defined in qe.
*
* - eliminate as-array terms, use lambda
* - have mode with inv-term from model-finder
*/ */
expr_ref mbqi::basic_project(model& mdl, quantifier* q, expr_ref_vector& vars) { expr_ref mbqi::project(model& mdl, quantifier* q, expr_ref_vector& vars, bool inv) {
unsigned sz = q->get_num_decls(); unsigned sz = q->get_num_decls();
unsigned max_generation = 0;
expr_ref_vector vals(m); expr_ref_vector vals(m);
vals.resize(sz, nullptr); vals.resize(sz, nullptr);
auto const& v2r = ctx.values2root(); auto const& v2r = ctx.values2root();
@ -167,9 +167,13 @@ namespace q {
expr_ref val(mdl.get_some_const_interp(f), m); expr_ref val(mdl.get_some_const_interp(f), m);
if (!val) if (!val)
return expr_ref(m); return expr_ref(m);
expr* t = nullptr; val = mdl.unfold_as_array(val);
if (!val)
return expr_ref(m);
if (inv)
vals[i] = m_model_finder.inv_term(mdl, q, i, val, max_generation);
euf::enode* r = nullptr; euf::enode* r = nullptr;
if (v2r.find(val, r)) if (!vals.get(i) && v2r.find(val, r))
vals[i] = choose_term(r); vals[i] = choose_term(r);
if (!vals.get(i)) if (!vals.get(i))
vals[i] = replace_model_value(val); vals[i] = replace_model_value(val);

View file

@ -16,8 +16,10 @@ Author:
--*/ --*/
#pragma once #pragma once
#include "sat/smt/sat_th.h"
#include "solver/solver.h" #include "solver/solver.h"
#include "sat/smt/sat_th.h"
#include "sat/smt/q_model_finder.h"
namespace euf { namespace euf {
class solver; class solver;
@ -31,6 +33,7 @@ namespace q {
euf::solver& ctx; euf::solver& ctx;
solver& qs; solver& qs;
ast_manager& m; ast_manager& m;
model_finder m_model_finder;
model_ref m_model; model_ref m_model;
ref<::solver> m_solver; ref<::solver> m_solver;
obj_map<sort, obj_hashtable<expr>*> m_fresh; obj_map<sort, obj_hashtable<expr>*> m_fresh;
@ -44,8 +47,7 @@ namespace q {
expr_ref choose_term(euf::enode* r); expr_ref choose_term(euf::enode* r);
lbool check_forall(quantifier* q); lbool check_forall(quantifier* q);
expr_ref specialize(quantifier* q, expr_ref_vector& vars); expr_ref specialize(quantifier* q, expr_ref_vector& vars);
expr_ref project(model& mdl, quantifier* q, expr_ref_vector& vars); expr_ref project(model& mdl, quantifier* q, expr_ref_vector& vars, bool inv);
expr_ref basic_project(model& mdl, quantifier* q, expr_ref_vector& vars);
void init_model(); void init_model();
void init_solver(); void init_solver();

View file

@ -0,0 +1,39 @@
/*++
Copyright (c) 2020 Microsoft Corporation
Module Name:
q_model_finder.cpp
Abstract:
Model-based quantifier instantiation model-finder plugin
Author:
Nikolaj Bjorner (nbjorner) 2020-09-29
Notes:
Derives from smt/smt_model_finder.cpp
--*/
#include "sat/smt/q_model_finder.h"
#include "sat/smt/euf_solver.h"
namespace q {
model_finder::model_finder(euf::solver&):
ctx(ctx), m(ctx.get_manager()) {}
expr_ref model_finder::inv_term(model& mdl, quantifier* q, unsigned idx, expr* value, unsigned& generation) {
return expr_ref(value, m);
}
void model_finder::restrict_instantiations(::solver& s, model& mdl, quantifier* q, expr_ref_vector const& vars) {
}
}

View file

@ -0,0 +1,46 @@
/*++
Copyright (c) 2020 Microsoft Corporation
Module Name:
q_model_finder.h
Abstract:
Model-based quantifier instantiation model-finder plugin
Author:
Nikolaj Bjorner (nbjorner) 2020-09-29
Notes:
Derives from smt/smt_model_finder.cpp
--*/
#pragma once
#include "sat/smt/sat_th.h"
#include "solver/solver.h"
namespace euf {
class solver;
}
namespace q {
class model_finder {
euf::solver& ctx;
ast_manager& m;
public:
model_finder(euf::solver& ctx);
expr_ref inv_term(model& mdl, quantifier* q, unsigned idx, expr* value, unsigned& generation);
void restrict_instantiations(::solver& s, model& mdl, quantifier* q, expr_ref_vector const& vars);
};
}