3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-09-07 18:21:23 +00:00

make proto-model evaluation use model_evaluator instead of legacy evaluator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-03-05 10:14:15 -08:00
parent 6fef24edb4
commit 70f13ced33
22 changed files with 528 additions and 297 deletions

View file

@ -61,8 +61,10 @@ br_status arith_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c
case OP_ADD: st = mk_add_core(num_args, args, result); break;
case OP_MUL: st = mk_mul_core(num_args, args, result); break;
case OP_SUB: st = mk_sub(num_args, args, result); break;
case OP_DIV: SASSERT(num_args == 2); st = mk_div_core(args[0], args[1], result); break;
case OP_IDIV: SASSERT(num_args == 2); st = mk_idiv_core(args[0], args[1], result); break;
case OP_DIV: if (num_args == 1) { result = args[0]; st = BR_DONE; break; }
SASSERT(num_args == 2); st = mk_div_core(args[0], args[1], result); break;
case OP_IDIV: if (num_args == 1) { result = args[0]; st = BR_DONE; break; }
SASSERT(num_args == 2); st = mk_idiv_core(args[0], args[1], result); break;
case OP_MOD: SASSERT(num_args == 2); st = mk_mod_core(args[0], args[1], result); break;
case OP_REM: SASSERT(num_args == 2); st = mk_rem_core(args[0], args[1], result); break;
case OP_UMINUS: SASSERT(num_args == 1); st = mk_uminus(args[0], result); break;

View file

@ -572,35 +572,61 @@ bool bool_rewriter::local_ctx_simp(unsigned num_args, expr * const * args, expr_
*/
br_status bool_rewriter::try_ite_value(app * ite, app * val, expr_ref & result) {
SASSERT(m().is_ite(ite));
expr* cond, *t, *e;
VERIFY(m().is_ite(ite, cond, t, e));
SASSERT(m().is_value(val));
expr * t = ite->get_arg(1);
expr * e = ite->get_arg(2);
if (!m().is_value(t) || !m().is_value(e))
return BR_FAILED;
if (t != val && e != val) {
TRACE("try_ite_value", tout << mk_ismt2_pp(t, m()) << " " << mk_ismt2_pp(e, m()) << " " << mk_ismt2_pp(val, m()) << "\n";
tout << t << " " << e << " " << val << "\n";);
result = m().mk_false();
if (m().is_value(t) && m().is_value(e)) {
if (t != val && e != val) {
TRACE("try_ite_value", tout << mk_ismt2_pp(t, m()) << " " << mk_ismt2_pp(e, m()) << " " << mk_ismt2_pp(val, m()) << "\n";
tout << t << " " << e << " " << val << "\n";);
result = m().mk_false();
}
else if (t == val && e == val) {
result = m().mk_true();
}
else if (t == val) {
result = cond;
}
else {
SASSERT(e == val);
mk_not(cond, result);
}
return BR_DONE;
}
if (t == val && e == val) {
result = m().mk_true();
return BR_DONE;
if (m().is_value(t)) {
if (val == t) {
result = m().mk_or(cond, m().mk_eq(val, e));
}
else {
mk_not(cond, result);
result = m().mk_and(result, m().mk_eq(val, e));
}
return BR_REWRITE2;
}
if (m().is_value(e)) {
if (val == e) {
mk_not(cond, result);
result = m().mk_or(result, m().mk_eq(val, t));
}
else {
result = m().mk_and(cond, m().mk_eq(val, t));
}
return BR_REWRITE2;
}
expr* cond2, *t2, *e2;
if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(t), val, result);
result = m().mk_ite(cond, result, m().mk_eq(e, val));
return BR_REWRITE2;
}
if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(e), val, result);
result = m().mk_ite(cond, m().mk_eq(t, val), result);
return BR_REWRITE2;
}
if (t == val) {
result = ite->get_arg(0);
return BR_DONE;
}
SASSERT(e == val);
mk_not(ite->get_arg(0), result);
return BR_DONE;
return BR_FAILED;
}
#if 0

View file

@ -51,6 +51,8 @@ void rewriter_core::cache_result(expr * k, expr * v) {
TRACE("rewriter_cache_result", tout << mk_ismt2_pp(k, m()) << "\n--->\n" << mk_ismt2_pp(v, m()) << "\n";);
SASSERT(m().get_sort(k) == m().get_sort(v));
m_cache->insert(k, v);
#if 0
static unsigned num_cached = 0;

View file

@ -214,10 +214,12 @@ protected:
unsigned m_num_steps;
ptr_vector<expr> m_bindings;
var_shifter m_shifter;
inv_var_shifter m_inv_shifter;
expr_ref m_r;
proof_ref m_pr;
proof_ref m_pr2;
unsigned_vector m_shifts;
svector<frame> & frame_stack() { return this->m_frame_stack; }
svector<frame> const & frame_stack() const { return this->m_frame_stack; }
expr_ref_vector & result_stack() { return this->m_result_stack; }
@ -225,6 +227,8 @@ protected:
proof_ref_vector & result_pr_stack() { return this->m_result_pr_stack; }
proof_ref_vector const & result_pr_stack() const { return this->m_result_pr_stack; }
void display_bindings(std::ostream& out);
void set_new_child_flag(expr * old_t) {
SASSERT(frame_stack().empty() || frame_stack().back().m_state != PROCESS_CHILDREN || this->is_child_of_top_frame(old_t));
if (!frame_stack().empty())
@ -232,7 +236,6 @@ protected:
}
void set_new_child_flag(expr * old_t, expr * new_t) { if (old_t != new_t) set_new_child_flag(old_t); }
// cache the result of shared non atomic expressions.
bool cache_results() const { return m_cfg.cache_results(); }
// cache all results share and non shared expressions non atomic expressions.

View file

@ -24,6 +24,7 @@ template<bool ProofGen>
void rewriter_tpl<Config>::process_var(var * v) {
if (m_cfg.reduce_var(v, m_r, m_pr)) {
result_stack().push_back(m_r);
SASSERT(v->get_sort() == m().get_sort(m_r));
if (ProofGen) {
result_pr_stack().push_back(m_pr);
m_pr = 0;
@ -36,18 +37,21 @@ void rewriter_tpl<Config>::process_var(var * v) {
// bindings are only used when Proof Generation is not enabled.
unsigned idx = v->get_idx();
if (idx < m_bindings.size()) {
expr * r = m_bindings[m_bindings.size() - idx - 1];
TRACE("process_var", if (r) tout << "idx: " << idx << " --> " << mk_ismt2_pp(r, m()) << "\n";
tout << "bindings:\n";
for (unsigned i = 0; i < m_bindings.size(); i++) if (m_bindings[i]) tout << i << ": " << mk_ismt2_pp(m_bindings[i], m()) << "\n";);
unsigned index = m_bindings.size() - idx - 1;
expr * r = m_bindings[index];
if (r != 0) {
if (m_num_qvars == 0 || is_ground(r)) {
result_stack().push_back(r);
SASSERT(v->get_sort() == m().get_sort(r));
if (!is_ground(r) && m_shifts[index] != UINT_MAX) {
unsigned shift_amount = m_bindings.size() - m_shifts[index];
expr_ref tmp(m());
m_shifter(r, shift_amount, tmp);
result_stack().push_back(tmp);
TRACE("process_var", tout << "shift: " << shift_amount << " idx: " << idx << " --> " << tmp << "\n";
display_bindings(tout););
}
else {
expr_ref new_term(m());
m_shifter(r, m_num_qvars, new_term);
result_stack().push_back(new_term);
result_stack().push_back(r);
}
set_new_child_flag(v);
return;
@ -64,6 +68,7 @@ template<bool ProofGen>
void rewriter_tpl<Config>::process_const(app * t) {
SASSERT(t->get_num_args() == 0);
br_status st = m_cfg.reduce_app(t->get_decl(), 0, 0, m_r, m_pr);
SASSERT(st != BR_DONE || m().get_sort(m_r) == m().get_sort(t));
SASSERT(st == BR_FAILED || st == BR_DONE);
if (st == BR_DONE) {
result_stack().push_back(m_r.get());
@ -100,6 +105,7 @@ bool rewriter_tpl<Config>::visit(expr * t, unsigned max_depth) {
proof * new_t_pr;
if (m_cfg.get_subst(t, new_t, new_t_pr)) {
TRACE("rewriter_subst", tout << "subst\n" << mk_ismt2_pp(t, m()) << "\n---->\n" << mk_ismt2_pp(new_t, m()) << "\n";);
SASSERT(m().get_sort(t) == m().get_sort(new_t));
result_stack().push_back(new_t);
set_new_child_flag(t, new_t);
if (ProofGen)
@ -124,6 +130,7 @@ bool rewriter_tpl<Config>::visit(expr * t, unsigned max_depth) {
#endif
expr * r = get_cached(t);
if (r) {
SASSERT(m().get_sort(r) == m().get_sort(t));
result_stack().push_back(r);
set_new_child_flag(t, r);
if (ProofGen) {
@ -213,6 +220,7 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
}
}
br_status st = m_cfg.reduce_app(f, new_num_args, new_args, m_r, m_pr2);
SASSERT(st != BR_DONE || m().get_sort(m_r) == m().get_sort(t));
TRACE("reduce_app",
tout << mk_ismt2_pp(t, m()) << "\n";
tout << "st: " << st;
@ -220,6 +228,7 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
tout << "\n";);
if (st != BR_FAILED) {
result_stack().shrink(fr.m_spos);
SASSERT(m().get_sort(m_r) == m().get_sort(t));
result_stack().push_back(m_r);
if (ProofGen) {
result_pr_stack().shrink(fr.m_spos);
@ -295,6 +304,7 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
if (get_macro(f, def, def_q, def_pr)) {
SASSERT(!f->is_associative() || !flat_assoc(f));
SASSERT(new_num_args == t->get_num_args());
SASSERT(m().get_sort(def) == m().get_sort(t));
if (is_ground(def)) {
m_r = def;
if (ProofGen) {
@ -317,16 +327,18 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
TRACE("get_macro", tout << "f: " << f->get_name() << ", def: \n" << mk_ismt2_pp(def, m()) << "\n";
tout << "Args num: " << num_args << "\n";
for (unsigned i = 0; i < num_args; i++) tout << mk_ismt2_pp(new_args[i], m()) << "\n";);
unsigned sz = m_bindings.size();
unsigned i = num_args;
while (i > 0) {
--i;
m_bindings.push_back(new_args[i]);
m_bindings.push_back(new_args[i]); // num_args - i - 1]);
m_shifts.push_back(sz);
}
result_stack().push_back(def);
TRACE("get_macro", tout << "bindings:\n";
for (unsigned j = 0; j < m_bindings.size(); j++) tout << j << ": " << mk_ismt2_pp(m_bindings[j], m()) << "\n";);
TRACE("get_macro", display_bindings(tout););
begin_scope();
m_num_qvars = 0;
m_num_qvars += num_args;
//m_num_qvars = 0;
m_root = def;
push_frame(def, false, RW_UNBOUNDED_DEPTH);
return;
@ -383,9 +395,17 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
SASSERT(fr.m_spos + t->get_num_args() + 2 == result_stack().size());
SASSERT(t->get_num_args() <= m_bindings.size());
if (!ProofGen) {
m_bindings.shrink(m_bindings.size() - t->get_num_args());
expr_ref tmp(m());
unsigned num_args = t->get_num_args();
m_bindings.shrink(m_bindings.size() - num_args);
m_shifts.shrink(m_shifts.size() - num_args);
m_num_qvars -= num_args;
end_scope();
m_r = result_stack().back();
if (!is_ground(m_r)) {
m_inv_shifter(m_r, num_args, tmp);
m_r = tmp;
}
result_stack().shrink(fr.m_spos);
result_stack().push_back(m_r);
cache_result<ProofGen>(t, m_r, m_pr, fr.m_cache_result);
@ -411,23 +431,26 @@ template<typename Config>
template<bool ProofGen>
void rewriter_tpl<Config>::process_quantifier(quantifier * q, frame & fr) {
SASSERT(fr.m_state == PROCESS_CHILDREN);
unsigned num_decls = q->get_num_decls();
if (fr.m_i == 0) {
if (!ProofGen) {
begin_scope();
m_root = q->get_expr();
}
m_num_qvars += q->get_num_decls();
if (!ProofGen) {
for (unsigned i = 0; i < q->get_num_decls(); i++)
unsigned sz = m_bindings.size();
for (unsigned i = 0; i < num_decls; i++) {
m_bindings.push_back(0);
m_shifts.push_back(sz);
}
}
m_num_qvars += num_decls;
}
unsigned num_children = rewrite_patterns() ? q->get_num_children() : 1;
while (fr.m_i < num_children) {
expr * child = q->get_child(fr.m_i);
fr.m_i++;
if (!visit<ProofGen>(child, fr.m_max_depth))
if (!visit<ProofGen>(child, fr.m_max_depth)) {
return;
}
}
SASSERT(fr.m_spos + num_children == result_stack().size());
expr * const * it = result_stack().c_ptr() + fr.m_spos;
@ -456,6 +479,8 @@ void rewriter_tpl<Config>::process_quantifier(quantifier * q, frame & fr) {
result_pr_stack().push_back(m_pr);
}
else {
expr_ref tmp(m());
if (!m_cfg.reduce_quantifier(q, new_body, new_pats, new_no_pats, m_r, m_pr)) {
if (fr.m_new_child) {
m_r = m().update_quantifier(q, q->get_num_patterns(), new_pats, q->get_num_no_patterns(), new_no_pats, new_body);
@ -468,9 +493,11 @@ void rewriter_tpl<Config>::process_quantifier(quantifier * q, frame & fr) {
}
result_stack().shrink(fr.m_spos);
result_stack().push_back(m_r.get());
SASSERT(m().is_bool(m_r));
if (!ProofGen) {
SASSERT(q->get_num_decls() <= m_bindings.size());
m_bindings.shrink(m_bindings.size() - q->get_num_decls());
SASSERT(num_decls <= m_bindings.size());
m_bindings.shrink(m_bindings.size() - num_decls);
m_shifts.shrink(m_shifts.size() - num_decls);
end_scope();
cache_result<ProofGen>(q, m_r, m_pr, fr.m_cache_result);
}
@ -496,6 +523,7 @@ rewriter_tpl<Config>::rewriter_tpl(ast_manager & m, bool proof_gen, Config & cfg
m_cfg(cfg),
m_num_steps(0),
m_shifter(m),
m_inv_shifter(m),
m_r(m),
m_pr(m),
m_pr2(m) {
@ -510,7 +538,9 @@ void rewriter_tpl<Config>::reset() {
m_cfg.reset();
rewriter_core::reset();
m_bindings.reset();
m_shifts.reset();
m_shifter.reset();
m_inv_shifter.reset();
}
template<typename Config>
@ -519,6 +549,17 @@ void rewriter_tpl<Config>::cleanup() {
rewriter_core::cleanup();
m_bindings.finalize();
m_shifter.cleanup();
m_shifts.finalize();
m_inv_shifter.cleanup();
}
template<typename Config>
void rewriter_tpl<Config>::display_bindings(std::ostream& out) {
out << "bindings:\n";
for (unsigned i = 0; i < m_bindings.size(); i++) {
if (m_bindings[i])
out << i << ": " << mk_ismt2_pp(m_bindings[i], m()) << "\n";
}
}
template<typename Config>
@ -526,11 +567,14 @@ void rewriter_tpl<Config>::set_bindings(unsigned num_bindings, expr * const * bi
SASSERT(!m_proof_gen);
SASSERT(not_rewriting());
m_bindings.reset();
m_shifts.reset();
unsigned i = num_bindings;
while (i > 0) {
--i;
m_bindings.push_back(bindings[i]);
m_shifts.push_back(UINT_MAX);
}
TRACE("rewriter", display_bindings(tout););
}
template<typename Config>
@ -538,9 +582,12 @@ void rewriter_tpl<Config>::set_inv_bindings(unsigned num_bindings, expr * const
SASSERT(!m_proof_gen);
SASSERT(not_rewriting());
m_bindings.reset();
m_shifts.reset();
for (unsigned i = 0; i < num_bindings; i++) {
m_bindings.push_back(bindings[i]);
m_shifts.push_back(UINT_MAX);
}
TRACE("rewriter", display_bindings(tout););
}
template<typename Config>
@ -562,9 +609,11 @@ void rewriter_tpl<Config>::main_loop(expr * t, expr_ref & result, proof_ref & re
result_pr = m().mk_reflexivity(t);
SASSERT(result_pr_stack().empty());
}
return;
}
resume_core<ProofGen>(result, result_pr);
else {
resume_core<ProofGen>(result, result_pr);
}
TRACE("rewriter", tout << mk_ismt2_pp(t, m()) << "\n=>\n" << result << "\n";;);
}
/**
@ -587,6 +636,7 @@ void rewriter_tpl<Config>::resume_core(expr_ref & result, proof_ref & result_pr)
if (first_visit(fr) && fr.m_cache_result) {
expr * r = get_cached(t);
if (r) {
SASSERT(m().get_sort(r) == m().get_sort(t));
result_stack().push_back(r);
if (ProofGen) {
proof * pr = get_cached_pr(t);

View file

@ -579,7 +579,7 @@ br_status seq_rewriter::mk_seq_contains(expr* a, expr* b, expr_ref& result) {
unsigned lenA = 0, lenB = 0;
bool lA = min_length(as.size(), as.c_ptr(), lenA);
if (lA) {
bool lB = min_length(bs.size(), bs.c_ptr(), lenB);
min_length(bs.size(), bs.c_ptr(), lenB);
if (lenB > lenA) {
result = m().mk_false();
return BR_DONE;