3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

Test forbidden intervals, disequal case

This commit is contained in:
Jakob Rath 2022-01-19 19:06:35 +01:00
parent 175b348948
commit fa75a9109e
6 changed files with 180 additions and 13 deletions

View file

@ -244,6 +244,7 @@ namespace polysat {
fi.coeff = -1;
fi.interval = to_interval(c, false, fi.coeff, lo_val, lo, hi_val, hi);
add_non_unit_side_conds(fi, b1, e1, b2, e2);
SASSERT(!fi.interval.is_currently_empty());
return true;
}
return false;

View file

@ -70,6 +70,8 @@ namespace polysat {
return {interval::full(), rational::zero(), rational::zero()};
}
static eval_interval proper(pdd const &lo, rational const &lo_val, pdd const &hi, rational const &hi_val) {
SASSERT(0 <= lo_val && lo_val <= lo.manager().max_value());
SASSERT(0 <= hi_val && hi_val <= hi.manager().max_value());
return {interval::proper(lo, hi), lo_val, hi_val};
}

View file

@ -77,6 +77,7 @@ namespace polysat {
friend class constraint_manager;
friend class scoped_solverv;
friend class test_polysat;
friend class test_fi;
reslimit& m_lim;
params_ref m_params;

View file

@ -206,6 +206,10 @@ namespace polysat {
return floor((e->interval.hi_val() - coeff_val - 1) / e->coeff);
};
// TODO: looks like there's an infinite loop for:
// [match_linear3] a1 = 3; b1 = 0; e1 = 0
// [match_linear3] a2 = 3; b2 = -2; e2 = -2
// naive widening. TODO: can we accelerate this?
// condition e->interval.hi_val() < coeff_val is
// to ensure that widening is performed on the same interval
@ -255,7 +259,8 @@ namespace polysat {
increase_hi(hi);
}
LOG("forbidden interval " << e->coeff << " * " << e->interval << " [" << lo << ", " << hi << "[");
SASSERT(hi <= max_value);
SASSERT(hi <= mod_value);
if (hi == mod_value) hi = 0;
pdd lop = s.var2pdd(v).mk_val(lo);
pdd hip = s.var2pdd(v).mk_val(hi);
entry* ne = alloc_entry();
@ -291,10 +296,11 @@ namespace polysat {
rational const& b1 = e->interval.lo().val();
rational const& a2 = e->interval.hi_val();
rational const& b2 = e->interval.hi().val();
rational lhs = a1 * val + b1;
rational rhs = a2 * val + b2;
SASSERT(a1 != a2 && a1 != 0 && a2 != 0);
rational lhs = mod(a1 * val + b1, mod_value);
rational rhs = mod(a2 * val + b2, mod_value);
auto delta_l = [&](rational const& val) {
rational m1 = ceil((rhs + 1) / a2);
int corr = e->src.is_negative() ? 1 : 0;
@ -304,7 +310,8 @@ namespace polysat {
else
m3 = ceil(m3);
return std::min(m1, m3) - 1;
// return std::min(m1, m3) - 1;
return std::min(val, std::min(m1, m3) - 1);
};
auto delta_u = [&](rational const& val) {
rational m1 = ceil((mod_value - lhs) / a1);
@ -326,8 +333,10 @@ namespace polysat {
// TODO: increase interval
LOG("refine-disequal-lin: " << " [" << lo << ", " << hi << "[");
SASSERT(0 <= lo);
SASSERT(hi <= max_value);
SASSERT(0 <= lo && lo <= val);
// SASSERT(val <= hi && hi <= max_value);
SASSERT(val <= hi && hi <= mod_value);
if (hi == mod_value) hi = 0;
pdd lop = s.var2pdd(v).mk_val(lo);
pdd hip = s.var2pdd(v).mk_val(hi);
entry* ne = alloc_entry();

View file

@ -29,6 +29,8 @@ namespace polysat {
class solver;
class viable {
friend class test_fi;
solver& s;
struct entry : public dll_base<entry>, public fi_record {