3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-20 21:03:39 +00:00
This commit is contained in:
Nikolaj Bjorner 2021-12-15 14:13:01 -08:00
parent 02369647a0
commit 8f8d88bc9d

View file

@ -25,7 +25,7 @@ Additional possible functionality on constraints:
namespace polysat {
op_constraint::op_constraint(constraint_manager& m, code c, pdd const& p, pdd const& q, pdd const& r):
op_constraint::op_constraint(constraint_manager& m, code c, pdd const& p, pdd const& q, pdd const& r) :
constraint(m, ckind_t::op_t), m_op(c), m_p(p), m_q(q), m_r(r) {
m_vars.append(p.free_vars());
for (auto v : q.free_vars())
@ -176,15 +176,20 @@ namespace polysat {
signed_constraint lshr(this, true);
if (pv.is_val() && rv.is_val() && rv.val() > pv.val())
s.add_clause(~lshr, s.ule(r(), p()), true); // r <= p
// r <= p
s.add_clause(~lshr, s.ule(r(), p()), true);
else if (qv.is_val() && qv.val() >= K && rv.is_val() && !rv.is_zero())
s.add_clause(~lshr, ~s.ule(K, q()), s.eq(r()), true); // q >= K -> r = 0
else if (qv.is_zero() && pv.is_val() && rv.is_val() && pv != rv) {
s.add_clause(~lshr, ~s.eq(q()), s.eq(p(), r()), true); // q != 0 & p > 0 => r < p
else if (qv.is_val() && !qv.is_zero() && pv.is_val() && rv.is_val() && !pv.is_zero() && pv.val() <= rv.val()) {
s.add_clause(~lshr, s.eq(q()), s.ule(p(), 0), s.ult(r(), p()), true); // q >= k -> r <= 2^{K-k-1}
// q >= K -> r = 0
s.add_clause(~lshr, ~s.ule(K, q()), s.eq(r()), true);
else if (qv.is_zero() && pv.is_val() && rv.is_val() && pv != rv)
// q = 0 -> p = r
s.add_clause(~lshr, ~s.eq(q()), s.eq(p(), r()), true);
else if (qv.is_val() && !qv.is_zero() && pv.is_val() && rv.is_val() && !pv.is_zero() && pv.val() <= rv.val())
// q != 0 & p > 0 => r < p
s.add_clause(~lshr, s.eq(q()), s.ule(p(), 0), s.ult(r(), p()), true);
else if (qv.is_val() && !qv.is_zero() && qv.val() < K && rv.is_val() &&
rv.val() > rational::power_of_two(K - qv.val().get_unsigned() - 1)) {
rv.val() > rational::power_of_two(K - qv.val().get_unsigned() - 1))
// q >= k -> r <= 2^{K-k-1}
s.add_clause(~lshr, ~s.ule(qv.val(), q()), s.ule(r(), rational::power_of_two(K - qv.val().get_unsigned() - 1)), true);
// q = k -> r[i - k] = p[i] for K - k <= i < K
else if (pv.is_val() && rv.is_val() && qv.is_val() && !qv.is_zero()) {
@ -261,6 +266,7 @@ namespace polysat {
else
UNREACHABLE();
return;
}
}
}
}