mirror of
https://github.com/Z3Prover/z3
synced 2025-06-28 08:58:44 +00:00
fi disequal: add special treatment for v > -a*v
This commit is contained in:
parent
7d3308b00e
commit
8c2f268506
2 changed files with 48 additions and 3 deletions
|
@ -327,10 +327,31 @@ namespace polysat {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (lhs > rhs || (e->src.is_negative() && lhs == rhs)) {
|
if (lhs > rhs || (e->src.is_negative() && lhs == rhs)) {
|
||||||
rational lo = val - delta_l(val);
|
rational lo;
|
||||||
rational hi = val + delta_u(val) + 1;
|
rational hi;
|
||||||
|
|
||||||
|
// TODO: extract into separate function
|
||||||
|
if (e->src.is_negative() && a2.is_one() && b1.is_zero() && b2.is_zero()) {
|
||||||
|
// special case: v > -a*v for some numeral a
|
||||||
|
rational const& a = mod(-a1, mod_value);
|
||||||
|
if (val.is_zero()) {
|
||||||
|
lo = 0;
|
||||||
|
hi = ceil( (mod_value + 1) / (a + 1) );
|
||||||
|
} else {
|
||||||
|
rational const y = mod(-a * val, mod_value);
|
||||||
|
lo = ceil( val + (y - max_value) / a );
|
||||||
|
hi = ceil( (y + a*val + 1) / (a + 1) );
|
||||||
|
// can always extend to 0
|
||||||
|
if (lo.is_one())
|
||||||
|
lo = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// general case
|
||||||
|
lo = val - delta_l(val);
|
||||||
|
hi = val + delta_u(val) + 1;
|
||||||
// TODO: increase interval
|
// TODO: increase interval
|
||||||
|
}
|
||||||
|
|
||||||
LOG("refine-disequal-lin: " << " [" << lo << ", " << hi << "[");
|
LOG("refine-disequal-lin: " << " [" << lo << ", " << hi << "[");
|
||||||
|
|
||||||
SASSERT(0 <= lo && lo <= val);
|
SASSERT(0 <= lo && lo <= val);
|
||||||
|
|
|
@ -1097,6 +1097,29 @@ public:
|
||||||
s.check();
|
s.check();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_fi_disequal_mild() {
|
||||||
|
{
|
||||||
|
// small version
|
||||||
|
scoped_solver s(__func__);
|
||||||
|
auto a = s.var(s.add_var(6));
|
||||||
|
auto b = s.var(s.add_var(6));
|
||||||
|
// v > -3*v
|
||||||
|
s.add_eq(a - 3);
|
||||||
|
s.add_ult(-a*b, b);
|
||||||
|
s.check();
|
||||||
|
}
|
||||||
|
{
|
||||||
|
// large version
|
||||||
|
scoped_solver s(__func__);
|
||||||
|
auto a = s.var(s.add_var(256));
|
||||||
|
auto b = s.var(s.add_var(256));
|
||||||
|
// v > -100*v
|
||||||
|
s.add_eq(a - 100);
|
||||||
|
s.add_ult(-a*b, b);
|
||||||
|
s.check();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Goal: we probably mix up polysat variables and PDD variables at several points; try to uncover such cases
|
// Goal: we probably mix up polysat variables and PDD variables at several points; try to uncover such cases
|
||||||
// NOTE: actually, add_var seems to keep them in sync, so this is not an issue at the moment (but we should still test it later)
|
// NOTE: actually, add_var seems to keep them in sync, so this is not an issue at the moment (but we should still test it later)
|
||||||
// static void test_mixed_vars() {
|
// static void test_mixed_vars() {
|
||||||
|
@ -1352,6 +1375,7 @@ void tst_polysat() {
|
||||||
test_polysat::test_fi_zero();
|
test_polysat::test_fi_zero();
|
||||||
test_polysat::test_fi_nonzero();
|
test_polysat::test_fi_nonzero();
|
||||||
test_polysat::test_fi_nonmax();
|
test_polysat::test_fi_nonmax();
|
||||||
|
test_polysat::test_fi_disequal_mild();
|
||||||
return;
|
return;
|
||||||
|
|
||||||
test_polysat::test_l2();
|
test_polysat::test_l2();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue