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:
parent
249f0de80b
commit
f0184c3fde
8 changed files with 192 additions and 94 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue