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

update format and checker for implied-eq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2023-07-27 13:21:45 -07:00
parent 249f0de80b
commit f0184c3fde
8 changed files with 192 additions and 94 deletions

View file

@ -32,7 +32,7 @@ namespace arith {
}
arith_proof_hint* arith_proof_hint_builder::mk(euf::solver& s) {
return new (s.get_region()) arith_proof_hint(m_ty, m_num_le, m_lit_head, m_lit_tail, m_eq_head, m_eq_tail);
return new (s.get_region()) arith_proof_hint(m_ty, m_lit_head, m_lit_tail, m_eq_head, m_eq_tail);
}
std::ostream& solver::display(std::ostream& out) const {
@ -164,7 +164,6 @@ namespace arith {
return nullptr;
m_arith_hint.set_type(ctx, hint_type::implied_eq_h);
explain_assumptions(e);
m_arith_hint.set_num_le(1); // TODO
m_arith_hint.add_diseq(a, b);
return m_arith_hint.mk(ctx);
}
@ -173,13 +172,19 @@ namespace arith {
if (!ctx.use_drat())
return nullptr;
m_arith_hint.set_type(ctx, hint_type::implied_eq_h);
m_arith_hint.set_num_le(1);
m_arith_hint.add_lit(rational(1), le);
m_arith_hint.add_lit(rational(1), ge);
m_arith_hint.add_lit(rational(1), ~eq);
return m_arith_hint.mk(ctx);
}
/**
* The expected format is:
* 1. all equalities
* 2. all inequalities
* 3. optional disequalities (used for the steps that propagate equalities)
*/
expr* arith_proof_hint::get_hint(euf::solver& s) const {
ast_manager& m = s.get_manager();
family_id fid = m.get_family_id("arith");
@ -200,29 +205,39 @@ namespace arith {
break;
case hint_type::implied_eq_h:
name = "implied-eq";
args.push_back(arith.mk_int(m_num_le));
break;
default:
name = "unknown-arithmetic";
break;
}
rational lc(1);
for (unsigned i = m_lit_head; i < m_lit_tail; ++i)
lc = lcm(lc, denominator(a.m_arith_hint.lit(i).first));
for (unsigned i = m_eq_head; i < m_eq_tail; ++i) {
auto [x, y, is_eq] = a.m_arith_hint.eq(i);
auto push_eq = [&](bool is_eq, enode* x, enode* y) {
if (x->get_id() > y->get_id())
std::swap(x, y);
expr_ref eq(m.mk_eq(x->get_expr(), y->get_expr()), m);
if (!is_eq) eq = m.mk_not(eq);
args.push_back(arith.mk_int(1));
args.push_back(eq);
};
rational lc(1);
for (unsigned i = m_lit_head; i < m_lit_tail; ++i)
lc = lcm(lc, denominator(a.m_arith_hint.lit(i).first));
for (unsigned i = m_eq_head; i < m_eq_tail; ++i) {
auto [x, y, is_eq] = a.m_arith_hint.eq(i);
if (is_eq)
push_eq(is_eq, x, y);
}
for (unsigned i = m_lit_head; i < m_lit_tail; ++i) {
auto const& [coeff, lit] = a.m_arith_hint.lit(i);
args.push_back(arith.mk_int(abs(coeff*lc)));
args.push_back(s.literal2expr(lit));
}
for (unsigned i = m_eq_head; i < m_eq_tail; ++i) {
auto [x, y, is_eq] = a.m_arith_hint.eq(i);
if (!is_eq)
push_eq(is_eq, x, y);
}
return m.mk_app(symbol(name), args.size(), args.data(), m.mk_proof_sort());
}
}