mirror of
https://github.com/Z3Prover/z3
synced 2025-06-07 14:43:23 +00:00
Merge forbidden intervals for positive and negative equations
This commit is contained in:
parent
6c7f556496
commit
6f1e4283bb
2 changed files with 16 additions and 50 deletions
|
@ -181,11 +181,10 @@ namespace polysat {
|
||||||
SASSERT(b2.is_val());
|
SASSERT(b2.is_val());
|
||||||
|
|
||||||
// a*v + b <= 0, a odd
|
// a*v + b <= 0, a odd
|
||||||
|
// a*v + b > 0, a odd
|
||||||
if (match_zero(c, a1, b1, e1, a2, b2, e2, fi))
|
if (match_zero(c, a1, b1, e1, a2, b2, e2, fi))
|
||||||
return true;
|
return true;
|
||||||
// a*v + b > 0, a odd
|
|
||||||
if (match_non_zero_linear(c, a1, b1, e1, a2, b2, e2, fi))
|
|
||||||
return true;
|
|
||||||
if (match_linear1(c, a1, b1, e1, a2, b2, e2, fi))
|
if (match_linear1(c, a1, b1, e1, a2, b2, e2, fi))
|
||||||
return true;
|
return true;
|
||||||
if (match_linear2(c, a1, b1, e1, a2, b2, e2, fi))
|
if (match_linear2(c, a1, b1, e1, a2, b2, e2, fi))
|
||||||
|
@ -390,7 +389,7 @@ namespace polysat {
|
||||||
*
|
*
|
||||||
* TODO: extend to
|
* TODO: extend to
|
||||||
* 2^k*a*v <= 0, a odd
|
* 2^k*a*v <= 0, a odd
|
||||||
* (using periodic intervals?)
|
* (using intervals for the lower bits of v)
|
||||||
*/
|
*/
|
||||||
bool forbidden_intervals::match_zero(
|
bool forbidden_intervals::match_zero(
|
||||||
signed_constraint const& c,
|
signed_constraint const& c,
|
||||||
|
@ -398,52 +397,24 @@ namespace polysat {
|
||||||
rational const & a2, pdd const& b2, pdd const& e2,
|
rational const & a2, pdd const& b2, pdd const& e2,
|
||||||
fi_record& fi) {
|
fi_record& fi) {
|
||||||
_last_function = __func__;
|
_last_function = __func__;
|
||||||
if (c.is_positive() && a1.is_odd() && a2.is_zero() && b2.is_zero()) {
|
if (a1.is_odd() && a2.is_zero() && b2.is_zero()) {
|
||||||
auto& m = e1.manager();
|
auto& m = e1.manager();
|
||||||
rational const& mod_value = m.two_to_N();
|
rational const& mod_value = m.two_to_N();
|
||||||
rational a1_inv;
|
rational a1_inv;
|
||||||
VERIFY(a1.mult_inverse(m.power_of_2(), a1_inv));
|
VERIFY(a1.mult_inverse(m.power_of_2(), a1_inv));
|
||||||
rational hi_val = mod(-b1.val() * a1_inv, mod_value);
|
|
||||||
pdd hi = -e1 * a1_inv;
|
// interval for a*v + b > 0 is [n,n+1[ where n = -b * a^-1
|
||||||
rational lo_val = mod(hi_val + 1, mod_value);
|
rational lo_val = mod(-b1.val() * a1_inv, mod_value);
|
||||||
pdd lo = hi + 1;
|
pdd lo = -e1 * a1_inv;
|
||||||
fi.coeff = 1;
|
rational hi_val = mod(lo_val + 1, mod_value);
|
||||||
fi.interval = eval_interval::proper(lo, lo_val, hi, hi_val);
|
pdd hi = lo + 1;
|
||||||
if (b1 != e1)
|
|
||||||
fi.side_cond.push_back(s.eq(b1, e1));
|
// interval for a*v + b <= 0 is the complement
|
||||||
if (b2 != e2)
|
if (c.is_positive()) {
|
||||||
fi.side_cond.push_back(s.eq(b2, e2));
|
std::swap(lo_val, hi_val);
|
||||||
return true;
|
std::swap(lo, hi);
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* a*v + b > 0, a odd
|
|
||||||
*
|
|
||||||
* TODO: extend to
|
|
||||||
* 2^k*a*v + b > 0, a odd
|
|
||||||
* (using periodic intervals?)
|
|
||||||
*/
|
|
||||||
bool forbidden_intervals::match_non_zero_linear(
|
|
||||||
signed_constraint const& c,
|
|
||||||
rational const & a1, pdd const& b1, pdd const& e1,
|
|
||||||
rational const & a2, pdd const& b2, pdd const& e2,
|
|
||||||
fi_record& fi) {
|
|
||||||
_last_function = __func__;
|
|
||||||
if (c.is_negative() && a1.is_odd() && a2.is_zero() && b2.is_zero()) {
|
|
||||||
// a*v + b > 0
|
|
||||||
// <=> a*v + b != 0
|
|
||||||
// <=> v + a^-1 * b != 0
|
|
||||||
// <=> v != - a^-1 * b
|
|
||||||
auto& m = e1.manager();
|
|
||||||
rational const& mod_value = m.two_to_N();
|
|
||||||
rational a1_inv;
|
|
||||||
VERIFY(a1.mult_inverse(m.power_of_2(), a1_inv));
|
|
||||||
rational lo_val(mod(-b1.val() * a1_inv, mod_value));
|
|
||||||
auto lo = -e1 * a1_inv;
|
|
||||||
rational hi_val(mod(lo_val + 1, mod_value));
|
|
||||||
auto hi = lo + 1;
|
|
||||||
fi.coeff = 1;
|
fi.coeff = 1;
|
||||||
fi.interval = eval_interval::proper(lo, lo_val, hi, hi_val);
|
fi.interval = eval_interval::proper(lo, lo_val, hi, hi_val);
|
||||||
if (b1 != e1)
|
if (b1 != e1)
|
||||||
|
|
|
@ -73,11 +73,6 @@ namespace polysat {
|
||||||
rational const & a2, pdd const& b2, pdd const& e2,
|
rational const & a2, pdd const& b2, pdd const& e2,
|
||||||
fi_record& fi);
|
fi_record& fi);
|
||||||
|
|
||||||
bool match_non_zero_linear(signed_constraint const& c,
|
|
||||||
rational const & a1, pdd const& b1, pdd const& e1,
|
|
||||||
rational const & a2, pdd const& b2, pdd const& e2,
|
|
||||||
fi_record& fi);
|
|
||||||
|
|
||||||
bool match_non_zero(signed_constraint const& c,
|
bool match_non_zero(signed_constraint const& c,
|
||||||
rational const & a1, pdd const& b1, pdd const& e1,
|
rational const & a1, pdd const& b1, pdd const& e1,
|
||||||
fi_record& fi);
|
fi_record& fi);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue