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:
parent
feac705cb8
commit
1a1c705376
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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'),
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue