3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 19:35:50 +00:00

wip - proof hints

This commit is contained in:
Nikolaj Bjorner 2022-10-08 20:12:57 +02:00
parent 6796ea7e49
commit 4623117af8
10 changed files with 176 additions and 29 deletions

View file

@ -103,10 +103,7 @@ namespace dt {
*/
void solver::assert_eq_axiom(enode* n1, expr* e2, literal antecedent) {
expr* e1 = n1->get_expr();
euf::th_proof_hint* ph = nullptr;
if (ctx.use_drat()) {
// todo
}
euf::th_proof_hint* ph = ctx.mk_smt_prop_hint(name(), antecedent, e1, e2);
if (antecedent == sat::null_literal)
add_unit(eq_internalize(e1, e2), ph);
else if (s().value(antecedent) == l_true) {
@ -166,7 +163,8 @@ namespace dt {
literal l = ctx.enode2literal(r);
SASSERT(s().value(l) == l_false);
clear_mark();
ctx.set_conflict(euf::th_explain::conflict(*this, ~l, c, r->get_arg(0)));
auto* ph = ctx.mk_smt_hint(name(), ~l, c, r->get_arg(0));
ctx.set_conflict(euf::th_explain::conflict(*this, ~l, c, r->get_arg(0), ph));
}
/**
@ -204,7 +202,9 @@ namespace dt {
// update_field is identity if 'n' is not created by a matching constructor.
assert_eq_axiom(n, arg1, ~is_con);
app_ref n_is_con(m.mk_app(rec, own), m);
add_clause(~is_con, mk_literal(n_is_con));
literal _n_is_con = mk_literal(n_is_con);
auto* ph = ctx.mk_smt_hint(name(), is_con, ~_n_is_con);
add_clause(~is_con, _n_is_con, ph);
}
euf::theory_var solver::mk_var(enode* n) {
@ -313,7 +313,8 @@ namespace dt {
}
}
}
ctx.set_conflict(euf::th_explain::conflict(*this, m_lits));
auto* ph = ctx.mk_smt_hint(name(), m_lits);
ctx.set_conflict(euf::th_explain::conflict(*this, m_lits, ph));
}
/**
@ -449,8 +450,10 @@ namespace dt {
++idx;
}
TRACE("dt", tout << "propagate " << num_unassigned << " eqs: " << eqs.size() << "\n";);
if (num_unassigned == 0)
ctx.set_conflict(euf::th_explain::conflict(*this, m_lits, eqs));
if (num_unassigned == 0) {
auto* ph = ctx.mk_smt_hint(name(), m_lits, eqs);
ctx.set_conflict(euf::th_explain::conflict(*this, m_lits, eqs, ph));
}
else if (num_unassigned == 1) {
// propagate remaining recognizer
SASSERT(!m_lits.empty());
@ -464,7 +467,13 @@ namespace dt {
app_ref rec_app(m.mk_app(rec, n->get_expr()), m);
consequent = mk_literal(rec_app);
}
ctx.propagate(consequent, euf::th_explain::propagate(*this, m_lits, eqs, consequent));
euf::th_proof_hint* ph = nullptr;
if (ctx.use_drat()) {
m_lits.push_back(~consequent);
ph = ctx.mk_smt_hint(name(), m_lits, eqs);
m_lits.pop_back();
}
ctx.propagate(consequent, euf::th_explain::propagate(*this, m_lits, eqs, consequent, ph));
}
else if (get_config().m_dt_lazy_splits == 0 || (!srt->is_infinite() && get_config().m_dt_lazy_splits == 1))
// there are more than 2 unassigned recognizers...
@ -481,7 +490,7 @@ namespace dt {
auto* con2 = d2->m_constructor;
TRACE("dt", tout << "merging v" << v1 << " v" << v2 << "\n" << ctx.bpp(var2enode(v1)) << " == " << ctx.bpp(var2enode(v2)) << " " << ctx.bpp(con1) << " " << ctx.bpp(con2) << "\n";);
if (con1 && con2 && con1->get_decl() != con2->get_decl())
ctx.set_conflict(euf::th_explain::conflict(*this, con1, con2));
ctx.set_conflict(euf::th_explain::conflict(*this, con1, con2, ctx.mk_smt_hint(name(), con1, con2)));
else if (con2 && !con1) {
ctx.push(set_ptr_trail<enode>(d1->m_constructor));
// check whether there is a recognizer in d1 that conflicts with con2;
@ -706,7 +715,7 @@ namespace dt {
if (res) {
clear_mark();
ctx.set_conflict(euf::th_explain::conflict(*this, m_used_eqs));
ctx.set_conflict(euf::th_explain::conflict(*this, m_used_eqs, ctx.mk_smt_hint(name(), m_used_eqs)));
TRACE("dt", tout << "occurs check conflict: " << ctx.bpp(n) << "\n";);
}
return res;