3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00
This commit is contained in:
Nikolaj Bjorner 2017-08-30 14:04:14 -07:00
commit e8198bbbe3
5 changed files with 169 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);
}
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) {
for (auto v : *m_decls) m.dec_ref(v.m_body);
dealloc(m_decls);
@ -1488,6 +1510,7 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
}
display_sat_result(r);
if (r == l_true) {
complete_model();
validate_model();
}
validate_check_sat_result(r);
@ -1632,6 +1655,65 @@ struct contains_array_op_proc {
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();
expr * some_val = m().get_some_value(range);
if (f->get_arity() > 0) {
func_interp * fi = alloc(func_interp, m(), f->get_arity());
fi->set_else(some_val);
md->register_decl(f, fi);
}
else
md->register_decl(f, some_val);
}
}
}
}
/**
\brief Check if the current model satisfies the quantifier free formulas.
*/

View file

@ -58,6 +58,8 @@ public:
func_decl * first() 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;
unsigned get_num_entries() const;
func_decl * get_entry(unsigned inx);
};
struct macro_decl {
@ -360,6 +362,7 @@ public:
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_state cs_state() const;
void complete_model();
void validate_model();
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):
pdecl(id, num_params),
m_psort_kind(PSORT_BASE),
m_name(n),
m_inst_cache(0) {
}
@ -317,6 +318,7 @@ void psort_dt_decl::display(std::ostream & out) const {
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),
m_def(p) {
m_psort_kind = PSORT_USER;
m.inc_ref(p);
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),
m_fid(fid),
m_kind(k) {
m_psort_kind = PSORT_BUILTIN;
}
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
typedef enum { PSORT_BASE = 0, PSORT_USER, PSORT_BUILTIN } psort_decl_kind;
class psort_decl : public pdecl {
protected:
friend class pdecl_manager;
symbol m_name;
psort_decl_kind m_psort_kind;
psort_inst_cache * m_inst_cache;
void cache(pdecl_manager & m, sort * const * s, sort * r);
sort * find(sort * const * s);
@ -105,6 +108,8 @@ public:
bool has_var_params() const { return m_num_params == PSORT_DECL_VAR_PARAMS; }
symbol const & get_name() const { return m_name; }
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 {

View file

@ -4,5 +4,6 @@ def_module_params('model',
('v1', BOOL, False, 'use Z3 version 1.x 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)'),
('completion', BOOL, False, 'enable/disable model completion'),
))