3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-07 09:55:19 +00:00
This commit is contained in:
Nikolaj Bjorner 2024-02-22 21:33:51 -08:00
parent 63804c5296
commit c451e4e50b
3 changed files with 62 additions and 68 deletions

View file

@ -260,16 +260,10 @@ namespace bv {
auto& a = wval0(e->get_arg(0)); auto& a = wval0(e->get_arg(0));
auto& b = wval0(e->get_arg(1)); auto& b = wval0(e->get_arg(1));
rational r; rational r;
if (bv.is_numeral(e->get_arg(0), r) && b.has_range()) { if (bv.is_numeral(e->get_arg(0), r) && b.has_range())
auto rlo = b.get_lo(); v.add_range(r + b.lo(), r + b.hi());
auto rhi = b.get_hi(); else if (bv.is_numeral(e->get_arg(1), r) && a.has_range())
v.add_range(r + rlo, r + rhi); v.add_range(r + a.lo(), r + a.hi());
}
if (bv.is_numeral(e->get_arg(1), r) && a.has_range()) {
auto rlo = a.get_lo();
auto rhi = a.get_hi();
v.add_range(r + rlo, r + rhi);
}
bool pfixed = true; bool pfixed = true;
for (unsigned i = 0; i < v.bw; ++i) { for (unsigned i = 0; i < v.bw; ++i) {
if (pfixed && a.fixed.get(i) && b.fixed.get(i)) if (pfixed && a.fixed.get(i) && b.fixed.get(i))

View file

@ -58,13 +58,13 @@ namespace bv {
sls_valuation::sls_valuation(unsigned bw) { sls_valuation::sls_valuation(unsigned bw) {
set_bw(bw); set_bw(bw);
lo.set_bw(bw); m_lo.set_bw(bw);
hi.set_bw(bw); m_hi.set_bw(bw);
m_bits.set_bw(bw); m_bits.set_bw(bw);
fixed.set_bw(bw); fixed.set_bw(bw);
// have lo, hi bits, fixed point to memory allocated within this of size num_bytes each allocated // have lo, hi bits, fixed point to memory allocated within this of size num_bytes each allocated
for (unsigned i = 0; i < nw; ++i) for (unsigned i = 0; i < nw; ++i)
lo[i] = 0, hi[i] = 0, m_bits[i] = 0, fixed[i] = 0; m_lo[i] = 0, m_hi[i] = 0, m_bits[i] = 0, fixed[i] = 0;
fixed[nw - 1] = ~mask; fixed[nw - 1] = ~mask;
} }
@ -78,7 +78,7 @@ namespace bv {
bool sls_valuation::in_range(bvect const& bits) const { bool sls_valuation::in_range(bvect const& bits) const {
mpn_manager m; mpn_manager m;
auto c = m.compare(lo.data(), nw, hi.data(), nw); auto c = m.compare(m_lo.data(), nw, m_hi.data(), nw);
SASSERT(!has_overflow(bits)); SASSERT(!has_overflow(bits));
// full range // full range
if (c == 0) if (c == 0)
@ -86,12 +86,12 @@ namespace bv {
// lo < hi: then lo <= bits & bits < hi // lo < hi: then lo <= bits & bits < hi
if (c < 0) if (c < 0)
return return
m.compare(lo.data(), nw, bits.data(), nw) <= 0 && m.compare(m_lo.data(), nw, bits.data(), nw) <= 0 &&
m.compare(bits.data(), nw, hi.data(), nw) < 0; m.compare(bits.data(), nw, m_hi.data(), nw) < 0;
// hi < lo: bits < hi or lo <= bits // hi < lo: bits < hi or lo <= bits
return return
m.compare(lo.data(), nw, bits.data(), nw) <= 0 || m.compare(m_lo.data(), nw, bits.data(), nw) <= 0 ||
m.compare(bits.data(), nw, hi.data(), nw) < 0; m.compare(bits.data(), nw, m_hi.data(), nw) < 0;
} }
// //
@ -170,29 +170,29 @@ namespace bv {
} }
bool sls_valuation::round_up(bvect& dst) const { bool sls_valuation::round_up(bvect& dst) const {
if (lo < hi) { if (m_lo < m_hi) {
if (hi <= dst) if (m_hi <= dst)
return false; return false;
if (lo > dst) if (m_lo > dst)
set(dst, lo); set(dst, m_lo);
} }
else if (hi <= dst && lo > dst) else if (m_hi <= dst && m_lo > dst)
set(dst, lo); set(dst, m_lo);
SASSERT(!has_overflow(dst)); SASSERT(!has_overflow(dst));
return true; return true;
} }
bool sls_valuation::round_down(bvect& dst) const { bool sls_valuation::round_down(bvect& dst) const {
if (lo < hi) { if (m_lo < m_hi) {
if (lo > dst) if (m_lo > dst)
return false; return false;
if (hi <= dst) { if (m_hi <= dst) {
set(dst, hi); set(dst, m_hi);
sub1(dst); sub1(dst);
} }
} }
else if (hi <= dst && lo > dst) { else if (m_hi <= dst && m_lo > dst) {
set(dst, hi); set(dst, m_hi);
sub1(dst); sub1(dst);
} }
SASSERT(well_formed()); SASSERT(well_formed());
@ -214,9 +214,9 @@ namespace bv {
} }
void sls_valuation::min_feasible(bvect& out) const { void sls_valuation::min_feasible(bvect& out) const {
if (lo < hi) { if (m_lo < m_hi) {
for (unsigned i = 0; i < nw; ++i) for (unsigned i = 0; i < nw; ++i)
out[i] = lo[i]; out[i] = m_lo[i];
} }
else { else {
for (unsigned i = 0; i < nw; ++i) for (unsigned i = 0; i < nw; ++i)
@ -226,9 +226,9 @@ namespace bv {
} }
void sls_valuation::max_feasible(bvect& out) const { void sls_valuation::max_feasible(bvect& out) const {
if (lo < hi) { if (m_lo < m_hi) {
for (unsigned i = 0; i < nw; ++i) for (unsigned i = 0; i < nw; ++i)
out[i] = hi[i]; out[i] = m_hi[i];
sub1(out); sub1(out);
} }
else { else {
@ -315,35 +315,35 @@ namespace bv {
SASSERT(is_zero(fixed)); // ranges can only be added before fixed bits are set. SASSERT(is_zero(fixed)); // ranges can only be added before fixed bits are set.
if (lo == hi) { if (m_lo == m_hi) {
set_value(lo, l); set_value(m_lo, l);
set_value(hi, h); set_value(m_hi, h);
} }
else { else {
auto old_lo = get_value(lo); auto old_lo = get_value(m_lo);
auto old_hi = get_value(hi); auto old_hi = get_value(m_hi);
if (old_lo < old_hi) { if (old_lo < old_hi) {
if (old_lo < l && l < old_hi) if (old_lo < l && l < old_hi)
set_value(lo, l), set_value(m_lo, l),
old_lo = l; old_lo = l;
if (old_hi < h && h < old_hi) if (old_hi < h && h < old_hi)
set_value(hi, h); set_value(m_hi, h);
} }
else { else {
SASSERT(old_hi < old_lo); SASSERT(old_hi < old_lo);
if (old_lo < l || l < old_hi) if (old_lo < l || l < old_hi)
set_value(lo, l), set_value(m_lo, l),
old_lo = l; old_lo = l;
if (old_lo < h && h < old_hi) if (old_lo < h && h < old_hi)
set_value(hi, h); set_value(m_hi, h);
else if (old_hi < old_lo && (h < old_hi || old_lo < h)) else if (old_hi < old_lo && (h < old_hi || old_lo < h))
set_value(hi, h); set_value(m_hi, h);
} }
} }
SASSERT(!has_overflow(lo)); SASSERT(!has_overflow(m_lo));
SASSERT(!has_overflow(hi)); SASSERT(!has_overflow(m_hi));
if (!in_range(m_bits)) if (!in_range(m_bits))
set(m_bits, lo); set(m_bits, m_lo);
SASSERT(well_formed()); SASSERT(well_formed());
} }
@ -361,21 +361,21 @@ namespace bv {
// lo < hi, set most significant bits based on hi // lo < hi, set most significant bits based on hi
// //
void sls_valuation::init_fixed() { void sls_valuation::init_fixed() {
if (lo == hi) if (m_lo == m_hi)
return; return;
for (unsigned i = bw; i-- > 0; ) { for (unsigned i = bw; i-- > 0; ) {
if (!fixed.get(i)) if (!fixed.get(i))
continue; continue;
if (m_bits.get(i) == lo.get(i)) if (m_bits.get(i) == m_lo.get(i))
continue; continue;
if (m_bits.get(i)) { if (m_bits.get(i)) {
lo.set(i, true); m_lo.set(i, true);
for (unsigned j = i; j-- > 0; ) for (unsigned j = i; j-- > 0; )
lo.set(j, fixed.get(j) && m_bits.get(j)); m_lo.set(j, fixed.get(j) && m_bits.get(j));
} }
else { else {
for (unsigned j = bw; j-- > 0; ) for (unsigned j = bw; j-- > 0; )
lo.set(j, fixed.get(j) && m_bits.get(j)); m_lo.set(j, fixed.get(j) && m_bits.get(j));
} }
break; break;
} }
@ -383,7 +383,7 @@ namespace bv {
bvect one(nw + 1); bvect one(nw + 1);
one[0] = 1; one[0] = 1;
digit_t c; digit_t c;
mpn_manager().sub(hi.data(), nw, one.data(), nw, hi1.data(), &c); mpn_manager().sub(m_hi.data(), nw, one.data(), nw, hi1.data(), &c);
clear_overflow_bits(hi1); clear_overflow_bits(hi1);
for (unsigned i = bw; i-- > 0; ) { for (unsigned i = bw; i-- > 0; ) {
if (!fixed.get(i)) if (!fixed.get(i))
@ -399,8 +399,8 @@ namespace bv {
for (unsigned j = bw; j-- > 0; ) for (unsigned j = bw; j-- > 0; )
hi1.set(j, fixed.get(j) && m_bits.get(j)); hi1.set(j, fixed.get(j) && m_bits.get(j));
} }
mpn_manager().add(hi1.data(), nw, one.data(), nw, hi.data(), nw + 1, &c); mpn_manager().add(hi1.data(), nw, one.data(), nw, m_hi.data(), nw + 1, &c);
clear_overflow_bits(hi); clear_overflow_bits(m_hi);
break; break;
} }
@ -413,21 +413,21 @@ namespace bv {
}; };
// set most significant bits // set most significant bits
if (lo < hi) { if (m_lo < m_hi) {
unsigned i = bw; unsigned i = bw;
for (; i-- > 0 && !hi.get(i); ) for (; i-- > 0 && !m_hi.get(i); )
set_fixed_bit(i, false); set_fixed_bit(i, false);
if (is_power_of2(hi)) if (is_power_of2(m_hi))
set_fixed_bit(i, false); set_fixed_bit(i, false);
} }
// lo + 1 = hi: then bits = lo // lo + 1 = hi: then bits = lo
mpn_manager().add(lo.data(), nw, one.data(), nw, hi1.data(), nw + 1, &c); mpn_manager().add(m_lo.data(), nw, one.data(), nw, hi1.data(), nw + 1, &c);
clear_overflow_bits(hi1); clear_overflow_bits(hi1);
if (hi == hi1) { if (m_hi == hi1) {
for (unsigned i = 0; i < bw; ++i) for (unsigned i = 0; i < bw; ++i)
set_fixed_bit(i, lo.get(i)); set_fixed_bit(i, m_lo.get(i));
} }
SASSERT(well_formed()); SASSERT(well_formed());
} }

View file

@ -80,7 +80,7 @@ namespace bv {
class sls_valuation { class sls_valuation {
protected: protected:
bvect m_bits; bvect m_bits;
bvect lo, hi; // range assignment to bit-vector, as wrap-around interval bvect m_lo, m_hi; // range assignment to bit-vector, as wrap-around interval
unsigned mask; unsigned mask;
rational get_value(bvect const& bits) const; rational get_value(bvect const& bits) const;
@ -119,12 +119,12 @@ namespace bv {
void set_value(bvect& bits, rational const& r); void set_value(bvect& bits, rational const& r);
rational get_value() const { return get_value(m_bits); } rational get_value() const { return get_value(m_bits); }
rational get_lo() const { return get_value(lo); } rational lo() const { return get_value(m_lo); }
rational get_hi() const { return get_value(hi); } rational hi() const { return get_value(m_hi); }
void get(bvect& dst) const; void get(bvect& dst) const;
void add_range(rational lo, rational hi); void add_range(rational lo, rational hi);
bool has_range() const { return lo != hi; } bool has_range() const { return m_lo != m_hi; }
void init_fixed(); void init_fixed();
void clear_overflow_bits(bvect& bits) const { void clear_overflow_bits(bvect& bits) const {
@ -257,11 +257,11 @@ namespace bv {
out << " fix:"; out << " fix:";
print_bits(out, fixed); print_bits(out, fixed);
if (lo != hi) { if (m_lo != m_hi) {
out << " ["; out << " [";
print_bits(out, lo); print_bits(out, m_lo);
out << ", "; out << ", ";
print_bits(out, hi); print_bits(out, m_hi);
out << "["; out << "[";
} }
out << std::dec; out << std::dec;