3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 21:38:44 +00:00

Added global model completion for the SMT2 frontend.

This commit is contained in:
Christoph M. Wintersteiger 2017-08-30 19:34:31 +01:00
parent feac705cb8
commit 1a1c705376
5 changed files with 164 additions and 75 deletions

View file

@ -229,6 +229,28 @@ func_decl * func_decls::find(ast_manager & m, unsigned num_args, expr * const *
return find(num_args, sorts.c_ptr(), range); return find(num_args, sorts.c_ptr(), range);
} }
unsigned func_decls::get_num_entries() const {
if (!more_than_one())
return 1;
func_decl_set * fs = UNTAG(func_decl_set *, m_decls);
return fs->size();
}
func_decl * func_decls::get_entry(unsigned inx) {
if (!more_than_one()) {
SASSERT(inx == 0);
return first();
}
else {
func_decl_set * fs = UNTAG(func_decl_set *, m_decls);
auto b = fs->begin();
for (unsigned i = 0; i < inx; i++)
b++;
return *b;
}
}
void macro_decls::finalize(ast_manager& m) { void macro_decls::finalize(ast_manager& m) {
for (auto v : *m_decls) m.dec_ref(v.m_body); for (auto v : *m_decls) m.dec_ref(v.m_body);
dealloc(m_decls); dealloc(m_decls);
@ -1488,6 +1510,7 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
} }
display_sat_result(r); display_sat_result(r);
if (r == l_true) { if (r == l_true) {
complete_model();
validate_model(); validate_model();
} }
validate_check_sat_result(r); validate_check_sat_result(r);
@ -1632,6 +1655,60 @@ struct contains_array_op_proc {
void operator()(quantifier * n) {} void operator()(quantifier * n) {}
}; };
/**
\brief Complete the model if necessary.
*/
void cmd_context::complete_model() {
if (!is_model_available() ||
gparams::get_value("model.completion") != "true")
return;
model_ref md;
get_check_sat_result()->get_model(md);
SASSERT(md.get() != 0);
params_ref p;
p.set_uint("max_degree", UINT_MAX); // evaluate algebraic numbers of any degree.
p.set_uint("sort_store", true);
p.set_bool("completion", true);
model_evaluator evaluator(*(md.get()), p);
evaluator.set_expand_array_equalities(false);
scoped_rlimit _rlimit(m().limit(), 0);
cancel_eh<reslimit> eh(m().limit());
expr_ref r(m());
scoped_ctrl_c ctrlc(eh);
for (auto kd : m_psort_decls) {
symbol const & k = kd.m_key;
psort_decl * v = kd.m_value;
if (v->is_user_decl()) {
SASSERT(!v->has_var_params());
IF_VERBOSE(12, verbose_stream() << "(model.completion " << k << ")\n"; );
ptr_vector<sort> param_sorts(v->get_num_params(), m().mk_bool_sort());
sort * srt = v->instantiate(*m_pmanager, param_sorts.size(), param_sorts.c_ptr());
if (!md->has_uninterpreted_sort(srt)) {
expr * singleton = m().get_some_value(srt);
md->register_usort(srt, 1, &singleton);
}
}
}
for (auto kd : m_func_decls) {
symbol const & k = kd.m_key;
func_decls & v = kd.m_value;
IF_VERBOSE(12, verbose_stream() << "(model.completion " << k << ")\n"; );
for (unsigned i = 0; i < v.get_num_entries(); i++) {
func_decl * f = v.get_entry(i);
if (!md->has_interpretation(f)) {
sort * range = f->get_range();
func_interp * fi = alloc(func_interp, m(), f->get_arity());
fi->set_else(m().get_some_value(range));
md->register_decl(f, fi);
}
}
}
}
/** /**
\brief Check if the current model satisfies the quantifier free formulas. \brief Check if the current model satisfies the quantifier free formulas.
*/ */

View file

@ -58,6 +58,8 @@ public:
func_decl * first() const; func_decl * first() const;
func_decl * find(unsigned arity, sort * const * domain, sort * range) const; func_decl * find(unsigned arity, sort * const * domain, sort * range) const;
func_decl * find(ast_manager & m, unsigned num_args, expr * const * args, sort * range) const; func_decl * find(ast_manager & m, unsigned num_args, expr * const * args, sort * range) const;
unsigned get_num_entries() const;
func_decl * get_entry(unsigned inx);
}; };
struct macro_decl { struct macro_decl {
@ -360,6 +362,7 @@ public:
void set_check_sat_result(check_sat_result * r) { m_check_sat_result = r; } void set_check_sat_result(check_sat_result * r) { m_check_sat_result = r; }
check_sat_result * get_check_sat_result() const { return m_check_sat_result.get(); } check_sat_result * get_check_sat_result() const { return m_check_sat_result.get(); }
check_sat_state cs_state() const; check_sat_state cs_state() const;
void complete_model();
void validate_model(); void validate_model();
void display_model(model_ref& mdl); void display_model(model_ref& mdl);

View file

@ -268,6 +268,7 @@ public:
psort_decl::psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n): psort_decl::psort_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n):
pdecl(id, num_params), pdecl(id, num_params),
m_psort_kind(PSORT_BASE),
m_name(n), m_name(n),
m_inst_cache(0) { m_inst_cache(0) {
} }
@ -314,9 +315,10 @@ void psort_dt_decl::display(std::ostream & out) const {
#endif #endif
psort_user_decl::psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p): psort_user_decl::psort_user_decl(unsigned id, unsigned num_params, pdecl_manager & m, symbol const & n, psort * p) :
psort_decl(id, num_params, m, n), psort_decl(id, num_params, m, n),
m_def(p) { m_def(p) {
m_psort_kind = PSORT_USER;
m.inc_ref(p); m.inc_ref(p);
SASSERT(p == 0 || num_params == p->get_num_params()); SASSERT(p == 0 || num_params == p->get_num_params());
} }
@ -369,6 +371,7 @@ psort_builtin_decl::psort_builtin_decl(unsigned id, pdecl_manager & m, symbol co
psort_decl(id, PSORT_DECL_VAR_PARAMS, m, n), psort_decl(id, PSORT_DECL_VAR_PARAMS, m, n),
m_fid(fid), m_fid(fid),
m_kind(k) { m_kind(k) {
m_psort_kind = PSORT_BUILTIN;
} }
sort * psort_builtin_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) { sort * psort_builtin_decl::instantiate(pdecl_manager & m, unsigned n, sort * const * s) {

View file

@ -86,10 +86,13 @@ typedef ptr_hashtable<psort, psort_hash_proc, psort_eq_proc> psort_table;
#define PSORT_DECL_VAR_PARAMS UINT_MAX #define PSORT_DECL_VAR_PARAMS UINT_MAX
typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN } psort_decl_kind;
class psort_decl : public pdecl { class psort_decl : public pdecl {
protected: protected:
friend class pdecl_manager; friend class pdecl_manager;
symbol m_name; symbol m_name;
psort_decl_kind m_psort_kind;
psort_inst_cache * m_inst_cache; psort_inst_cache * m_inst_cache;
void cache(pdecl_manager & m, sort * const * s, sort * r); void cache(pdecl_manager & m, sort * const * s, sort * r);
sort * find(sort * const * s); sort * find(sort * const * s);
@ -105,6 +108,8 @@ public:
bool has_var_params() const { return m_num_params == PSORT_DECL_VAR_PARAMS; } bool has_var_params() const { return m_num_params == PSORT_DECL_VAR_PARAMS; }
symbol const & get_name() const { return m_name; } symbol const & get_name() const { return m_name; }
virtual void reset_cache(pdecl_manager& m); virtual void reset_cache(pdecl_manager& m);
bool is_user_decl() const { return m_psort_kind == PSORT_USER; }
bool is_builtin_decl() const { return m_psort_kind == PSORT_BUILTIN; }
}; };
class psort_user_decl : public psort_decl { class psort_user_decl : public psort_decl {

View file

@ -4,5 +4,6 @@ def_module_params('model',
('v1', BOOL, False, 'use Z3 version 1.x pretty printer'), ('v1', BOOL, False, 'use Z3 version 1.x pretty printer'),
('v2', BOOL, False, 'use Z3 version 2.x (x <= 16) pretty printer'), ('v2', BOOL, False, 'use Z3 version 2.x (x <= 16) pretty printer'),
('compact', BOOL, False, 'try to compact function graph (i.e., function interpretations that are lookup tables)'), ('compact', BOOL, False, 'try to compact function graph (i.e., function interpretations that are lookup tables)'),
('completion', BOOL, False, 'enable/disable model completion'),
)) ))