mirror of
https://github.com/Z3Prover/z3
synced 2025-04-27 19:05:51 +00:00
Merge branch 'master' of https://github.com/z3prover/z3
This commit is contained in:
commit
6fc08e9c9f
236 changed files with 14093 additions and 16593 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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'),
|
||||
))
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue