3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-27 19:05:51 +00:00
This commit is contained in:
Nikolaj Bjorner 2018-06-15 14:58:10 -07:00
commit 6fc08e9c9f
236 changed files with 14093 additions and 16593 deletions

View file

@ -47,8 +47,8 @@ bool model_core::eval(func_decl* f, expr_ref & r) const {
void model_core::register_decl(func_decl * d, expr * v) {
SASSERT(d->get_arity() == 0);
decl2expr::obj_map_entry * entry = m_interp.insert_if_not_there2(d, 0);
if (entry->get_data().m_value == 0) {
decl2expr::obj_map_entry * entry = m_interp.insert_if_not_there2(d, nullptr);
if (entry->get_data().m_value == nullptr) {
// new entry
m_decls.push_back(d);
m_const_decls.push_back(d);
@ -67,8 +67,8 @@ void model_core::register_decl(func_decl * d, expr * v) {
void model_core::register_decl(func_decl * d, func_interp * fi) {
SASSERT(d->get_arity() > 0);
SASSERT(&fi->m() == &m_manager);
decl2finterp::obj_map_entry * entry = m_finterp.insert_if_not_there2(d, 0);
if (entry->get_data().m_value == 0) {
decl2finterp::obj_map_entry * entry = m_finterp.insert_if_not_there2(d, nullptr);
if (entry->get_data().m_value == nullptr) {
// new entry
m_decls.push_back(d);
m_func_decls.push_back(d);

View file

@ -53,6 +53,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
bool m_model_completion;
bool m_cache;
bool m_array_equalities;
bool m_array_as_stores;
evaluator_cfg(ast_manager & m, model_core & md, params_ref const & p):
m(m),
@ -87,6 +88,7 @@ struct evaluator_cfg : public default_rewriter_cfg {
m_model_completion = p.completion();
m_cache = p.cache();
m_array_equalities = p.array_equalities();
m_array_as_stores = p.array_as_stores();
}
bool evaluate(func_decl * f, unsigned num, expr * const * args, expr_ref & result) {
@ -201,15 +203,16 @@ struct evaluator_cfg : public default_rewriter_cfg {
return st;
}
void expand_value(expr_ref& val) {
void expand_stores(expr_ref& val) {
vector<expr_ref_vector> stores;
expr_ref else_case(m);
bool _unused;
if (m_ar.is_array(val) && extract_array_func_interp(val, stores, else_case, _unused)) {
if (m_array_as_stores &&
m_ar.is_array(val) &&
extract_array_func_interp(val, stores, else_case, _unused)) {
sort* srt = m.get_sort(val);
val = m_ar.mk_const_array(srt, else_case);
for (unsigned i = stores.size(); i > 0; ) {
--i;
for (unsigned i = stores.size(); i-- > 0; ) {
expr_ref_vector args(m);
args.push_back(val);
args.append(stores[i].size(), stores[i].c_ptr());
@ -288,7 +291,6 @@ struct evaluator_cfg : public default_rewriter_cfg {
bool cache_results() const { return m_cache; }
br_status mk_array_eq(expr* a, expr* b, expr_ref& result) {
TRACE("model_evaluator", tout << "mk_array_eq " << m_array_equalities << "\n";);
if (a == b) {
@ -502,9 +504,6 @@ struct evaluator_cfg : public default_rewriter_cfg {
TRACE("model_evaluator", tout << "else case: " << mk_pp(else_case, m) << "\n";);
return true;
}
};
template class rewriter_tpl<evaluator_cfg>;
@ -518,10 +517,7 @@ struct model_evaluator::imp : public rewriter_tpl<evaluator_cfg> {
m_cfg(md.get_manager(), md, p) {
set_cancel_check(false);
}
void expand_value (expr_ref &val) {
m_cfg.expand_value (val);
}
void expand_stores(expr_ref &val) {m_cfg.expand_stores(val);}
};
model_evaluator::model_evaluator(model_core & md, params_ref const & p) {
@ -567,10 +563,16 @@ void model_evaluator::reset(params_ref const & p) {
updt_params(p);
}
void model_evaluator::reset(model_core &model, params_ref const& p) {
dealloc(m_imp);
m_imp = alloc(imp, model, p);
}
void model_evaluator::operator()(expr * t, expr_ref & result) {
TRACE("model_evaluator", tout << mk_ismt2_pp(t, m()) << "\n";);
m_imp->operator()(t, result);
m_imp->expand_value(result);
m_imp->expand_stores(result);
}
expr_ref model_evaluator::operator()(expr * t) {
@ -579,3 +581,44 @@ expr_ref model_evaluator::operator()(expr * t) {
this->operator()(t, result);
return result;
}
expr_ref_vector model_evaluator::operator()(expr_ref_vector const& ts) {
expr_ref_vector rs(m());
for (expr* t : ts) rs.push_back((*this)(t));
return rs;
}
bool model_evaluator::is_true(expr* t) {
expr_ref tmp(m());
return eval(t, tmp, true) && m().is_true(tmp);
}
bool model_evaluator::is_false(expr* t) {
expr_ref tmp(m());
return eval(t, tmp, true) && m().is_false(tmp);
}
bool model_evaluator::is_true(expr_ref_vector const& ts) {
for (expr* t : ts) if (!is_true(t)) return false;
return true;
}
bool model_evaluator::eval(expr* t, expr_ref& r, bool model_completion) {
set_model_completion(model_completion);
try {
r = (*this)(t);
return true;
}
catch (model_evaluator_exception &ex) {
(void)ex;
TRACE("model_evaluator", tout << ex.msg () << "\n";);
return false;
}
}
bool model_evaluator::eval(expr_ref_vector const& ts, expr_ref& r, bool model_completion) {
expr_ref tmp(m());
tmp = mk_and(ts);
return eval(tmp, r, model_completion);
}

View file

@ -43,11 +43,25 @@ public:
static void get_param_descrs(param_descrs & r);
void operator()(expr * t, expr_ref & r);
expr_ref operator()(expr* t);
expr_ref_vector operator()(expr_ref_vector const& ts);
// exception safe
bool eval(expr* t, expr_ref& r, bool model_completion = true);
bool eval(expr_ref_vector const& ts, expr_ref& r, bool model_completion = true);
bool is_true(expr * t);
bool is_false(expr * t);
bool is_true(expr_ref_vector const& ts);
/**
* best effort evaluator of extensional array equality.
*/
expr_ref eval_array_eq(app* e, expr* arg1, expr* arg2);
void cleanup(params_ref const & p = params_ref());
void reset(params_ref const & p = params_ref());
void reset(model_core& model, params_ref const & p = params_ref());
unsigned get_num_steps() const;
};

View file

@ -4,6 +4,7 @@ def_module_params('model_evaluator',
max_steps_param(),
('completion', BOOL, False, 'assigns an interptetation to symbols that do not have one in the current model, when evaluating expressions in the current model'),
('cache', BOOL, True, 'cache intermediate results in the model evaluator'),
('array_equalities', BOOL, True, 'evaluate array equalities')
('array_equalities', BOOL, True, 'evaluate array equalities'),
('array_as_stores', BOOL, True, 'return array as a set of stores'),
))

View file

@ -172,7 +172,6 @@ void model_implicant::process_formula(app* e, ptr_vector<expr>& todo, ptr_vector
case OP_FALSE:
break;
case OP_EQ:
case OP_IFF:
if (args[0] == args[1]) {
SASSERT(v);
// no-op
@ -742,10 +741,6 @@ void model_implicant::eval_basic(app* e) {
set_x(e);
}
break;
case OP_IFF:
VERIFY(m.is_iff(e, arg1, arg2));
eval_eq(e, arg1, arg2);
break;
case OP_ITE:
VERIFY(m.is_ite(e, argCond, argThen, argElse));
if (is_true(argCond)) {