3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 11:25:51 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-07-02 11:26:05 -07:00
parent 0520180846
commit 0fc9d7ad0d
4 changed files with 256 additions and 183 deletions

View file

@ -48,12 +48,23 @@ public:
mod_interval(Numeral const& l, Numeral const& h): lo(l), hi(h) {}
static mod_interval free() { return mod_interval(0, 0); }
static mod_interval empty() { mod_interval i(0, 0); i.emp = true; return i; }
bool is_free() const { return !emp && lo == hi; }
bool is_empty() const { return emp; }
bool is_singleton() const { return !is_empty() && (lo + 1 == hi || (hi == 0 && is_max(lo))); }
bool contains(Numeral const& n) const;
virtual bool is_max(Numeral const& n) const { return n + 1 == 0; }
void set_free() { lo = hi = 0; emp = false; }
void set_bounds(Numeral const& l, Numeral const& h) { lo = l; hi = h; }
void set_empty() { emp = true; }
bool contains(Numeral const& n) const;
void intersect_ule(Numeral const& h);
void intersect_uge(Numeral const& l);
void intersect_ult(Numeral const& h);
void intersect_ugt(Numeral const& l);
void intersect_fixed(Numeral const& n);
void intersect_diff(Numeral const& n);
mod_interval operator&(mod_interval const& other) const;
mod_interval operator+(mod_interval const& other) const;
mod_interval operator-(mod_interval const& other) const;

View file

@ -120,3 +120,89 @@ Numeral mod_interval<Numeral>::closest_value(Numeral const& n) const {
return lo;
return hi - 1;
}
// TBD: correctness and completeness for wrap-around semantics needs to be checked/fixed
template<typename Numeral>
void mod_interval<Numeral>::intersect_ule(Numeral const& h) {
if (is_empty())
return;
if (is_max(h))
return;
else if (is_free())
lo = 0, hi = h + 1;
else if (hi > lo && lo > h)
set_empty();
else if (hi != 0 || h + 1 < hi)
hi = h + 1;
}
template<typename Numeral>
void mod_interval<Numeral>::intersect_uge(Numeral const& l) {
if (is_empty())
return;
if (lo < hi && hi <= l)
set_empty();
else if (is_free())
lo = l, hi = 0;
else if (lo < hi && lo < l)
lo = l;
}
template<typename Numeral>
void mod_interval<Numeral>::intersect_ult(Numeral const& h) {
if (is_empty())
return;
if (h == 0)
set_empty();
else if (is_free())
lo = 0, hi = h;
else if (hi > lo && lo >= h)
set_empty();
else if (hi > lo && h < hi)
hi = h;
}
template<typename Numeral>
void mod_interval<Numeral>::intersect_ugt(Numeral const& l) {
if (is_empty())
return;
if (is_max(l))
set_empty();
else if (is_free())
lo = l + 1, hi = 0;
else if (lo > l)
return;
else if (lo < hi && hi <= l)
set_empty();
else if (lo < hi)
lo = l + 1;
}
template<typename Numeral>
void mod_interval<Numeral>::intersect_fixed(Numeral const& a) {
if (is_empty())
return;
if (!contains(a))
set_empty();
else if (is_max(a))
lo = a, hi = 0;
else
lo = a, hi = a + 1;
}
template<typename Numeral>
void mod_interval<Numeral>::intersect_diff(Numeral const& a) {
if (!contains(a) || is_empty())
return;
if (a == lo && a + 1 == hi)
set_empty();
else if (a == lo && hi == 0 && is_max(a))
set_empty();
else if (a == lo && !is_max(a))
lo = a + 1;
else if (a + 1 == hi)
hi = a;
else if (hi == 0 && is_max(a))
hi = a;
}