mirror of
https://github.com/Z3Prover/z3
synced 2025-06-26 15:53:41 +00:00
fix add_overflow
This commit is contained in:
parent
455abb1db3
commit
1dea87a07a
2 changed files with 33 additions and 31 deletions
|
@ -1284,42 +1284,42 @@ namespace polysat {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* x >= x + y & x <= n => y = 0 or y >= N - n
|
* x >= x + y & x <= n ==> y >= M - n or y = 0
|
||||||
* x > x + y & x <= n => y >= N - n
|
* x > x + y & x <= n ==> y >= M - n
|
||||||
* -x <= -x - y & x <= n => y = 0 or y >= N - n
|
* -x <= -x - y & x <= n ==> y >= M - n or y = 0 or x = 0
|
||||||
* -x < -x - y & x <= n => y >= N - n
|
* -x < -x - y & x <= n ==> y >= M - n or x = 0
|
||||||
*
|
*
|
||||||
* NOTE: x + y <= x <==> -y <= x <==> -x-1 <= y-1
|
* NOTE: x + y <= x <=> -y <= x <=> -x-1 <= y-1
|
||||||
* x <= x + y <==> x <= -y-1 <==> y <= -x-1
|
* x <= x + y <=> x <= -y-1 <=> y <= -x-1
|
||||||
* (see notes on equivalent forms in ule_constraint.cpp)
|
* (see notes on equivalent forms in ule_constraint.cpp)
|
||||||
*
|
*
|
||||||
* x >= x + y ==> -y <= x
|
* p <= q ==> p = 0 or -q <= -p
|
||||||
* x > x + y ==> y <= -x-1
|
|
||||||
* -x <= -x - y ==> -y <= x-1
|
|
||||||
* -x < -x - y ==> y <= -x
|
|
||||||
* Add these as simplification rules on ule_constraint instead of this inference rule?
|
|
||||||
*/
|
*/
|
||||||
bool saturation::try_add_overflow_bound(pvar x, conflict& core, inequality const& axb_l_y) {
|
bool saturation::try_add_overflow_bound(pvar x, conflict& core, inequality const& i) {
|
||||||
return false;
|
|
||||||
set_rule("[x] x >= x + y & x <= n => y = 0 or y >= 2^N - n");
|
set_rule("[x] x >= x + y & x <= n => y = 0 or y >= 2^N - n");
|
||||||
signed_constraint y_eq_0;
|
signed_constraint y_eq_0, x_eq_0;
|
||||||
vector<signed_constraint> x_ge_bound;
|
vector<signed_constraint> x_le_bound;
|
||||||
auto& m = s.var2pdd(x);
|
auto& m = s.var2pdd(x);
|
||||||
pdd y = m.zero();
|
pdd y = m.zero();
|
||||||
if (!is_add_overflow(x, axb_l_y, y))
|
bool is_minus;
|
||||||
|
if (!is_add_overflow(x, i, y, is_minus))
|
||||||
return false;
|
return false;
|
||||||
if (!axb_l_y.is_strict() && !is_forced_diseq(y, 0, y_eq_0))
|
if (!i.is_strict() && !is_forced_diseq(y, 0, y_eq_0))
|
||||||
|
return false;
|
||||||
|
if (is_minus && !is_forced_diseq(s.var(x), 0, x_eq_0))
|
||||||
return false;
|
return false;
|
||||||
rational bound;
|
rational bound;
|
||||||
if (!has_upper_bound(x, core, bound, x_ge_bound))
|
if (!has_upper_bound(x, core, bound, x_le_bound))
|
||||||
return false;
|
return false;
|
||||||
SASSERT(bound != 0);
|
SASSERT(bound != 0);
|
||||||
m_lemma.reset();
|
m_lemma.reset();
|
||||||
if (!axb_l_y.is_strict())
|
if (!i.is_strict())
|
||||||
m_lemma.insert_eval(y_eq_0);
|
m_lemma.insert_eval(y_eq_0);
|
||||||
for (auto c : x_ge_bound)
|
if (is_minus)
|
||||||
|
m_lemma.insert_eval(x_eq_0);
|
||||||
|
for (auto c : x_le_bound)
|
||||||
m_lemma.insert_eval(~c);
|
m_lemma.insert_eval(~c);
|
||||||
return propagate(x, core, axb_l_y, s.uge(y, m.two_to_N() - bound));
|
return propagate(x, core, i, s.uge(y, m.two_to_N() - bound));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1329,20 +1329,23 @@ namespace polysat {
|
||||||
* -x <= -x - y
|
* -x <= -x - y
|
||||||
* -x < -x - y
|
* -x < -x - y
|
||||||
*/
|
*/
|
||||||
bool saturation::is_add_overflow(pvar x, inequality const& i, pdd& y) {
|
bool saturation::is_add_overflow(pvar x, inequality const& i, pdd& y, bool& is_minus) {
|
||||||
auto& m = s.var2pdd(x);
|
auto& m = s.var2pdd(x);
|
||||||
pdd X = s.var(x);
|
pdd const X = s.var(x);
|
||||||
pdd a = X;
|
pdd a = X;
|
||||||
if (i.lhs().degree(x) != 1 || i.rhs().degree(x) != 1)
|
if (i.lhs().degree(x) != 1 || i.rhs().degree(x) != 1)
|
||||||
return false;
|
return false;
|
||||||
if (i.rhs() == X) {
|
if (i.rhs() == X) {
|
||||||
i.lhs().factor(x, 1, a, y);
|
i.lhs().factor(x, 1, a, y);
|
||||||
if (a.is_one())
|
if (a.is_one()) {
|
||||||
|
is_minus = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (i.lhs() == -X) {
|
if (i.lhs() == -X) {
|
||||||
i.rhs().factor(x, 1, a, y);
|
i.rhs().factor(x, 1, a, y);
|
||||||
if ((-a).is_one()) {
|
if ((-a).is_one()) {
|
||||||
|
is_minus = true;
|
||||||
y = -y;
|
y = -y;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -138,8 +138,7 @@ namespace polysat {
|
||||||
// p := coeff*x*y where coeff_x = coeff*x, x a variable
|
// p := coeff*x*y where coeff_x = coeff*x, x a variable
|
||||||
bool is_coeffxY(pdd const& coeff_x, pdd const& p, pdd& y);
|
bool is_coeffxY(pdd const& coeff_x, pdd const& p, pdd& y);
|
||||||
|
|
||||||
// i := x + y >= x or x + y > x
|
bool is_add_overflow(pvar x, inequality const& i, pdd& y, bool& is_minus);
|
||||||
bool is_add_overflow(pvar x, inequality const& i, pdd& y);
|
|
||||||
|
|
||||||
bool has_upper_bound(pvar x, conflict& core, rational& bound, vector<signed_constraint>& x_ge_bound);
|
bool has_upper_bound(pvar x, conflict& core, rational& bound, vector<signed_constraint>& x_ge_bound);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue