3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-11-03 21:09:11 +00:00
This commit is contained in:
Nikolaj Bjorner 2024-02-22 21:19:06 -08:00
parent 74e73f2b84
commit 63804c5296
5 changed files with 148 additions and 195 deletions

View file

@ -27,63 +27,22 @@ Author:
namespace bv {
class bvect : public svector<digit_t> {
unsigned bw = 0;
unsigned nw = 0;
unsigned mask = 0;
public:
bvect() {}
bvect(unsigned sz): svector(sz, (unsigned)0) {}
bvect(unsigned sz) : svector(sz, (unsigned)0) {}
void set_bw(unsigned bw);
void clear_overflow_bits();
void set_sub(bvect const& a, bvect const& b);
bool is_one() const {
SASSERT(bw > 0);
SASSERT(!has_overflow());
for (unsigned i = 1; i < nw; ++i)
if (0 != (*this)[i])
return false;
return 1 == (*this)[0];
}
bool is_ones() const {
SASSERT(bw > 0);
auto const& a = *this;
for (unsigned i = 0; i + 1 < nw; ++i)
if (0 != ~a[i])
return false;
return ((~a[nw - 1]) & mask) == 0;
}
bool is_zero() const {
SASSERT(bw > 0);
auto const& a = *this;
for (unsigned i = 0; i + 1 < nw; ++i)
if (a[i] != 0)
return false;
return (a[nw - 1] & mask) == 0;
}
bool has_overflow() const {
SASSERT(bw > 0);
for (unsigned i = bw; i < nw * sizeof(digit_t) * 8; ++i)
if (get(i))
return true;
return false;
}
bool get(unsigned bit_idx) const {
return (get_bit_word(bit_idx) & get_pos_mask(bit_idx)) != 0;
}
unsigned parity() const {
SASSERT(bw > 0);
SASSERT(!has_overflow());
for (unsigned i = 0; i < nw; ++i)
if ((*this)[i] != 0)
return (8 * sizeof(digit_t) * i) + trailing_zeros((*this)[i]);
@ -135,19 +94,26 @@ namespace bv {
unsigned bw; // bit-width
unsigned nw; // num words
bvect fixed; // bit assignment and don't care bit
sls_valuation(unsigned bw);
void set_bw(unsigned bw);
unsigned num_bytes() const { return (bw + 7) / 8; }
digit_t bits(unsigned i) const { return m_bits[i]; }
bvect const& bits() const { return m_bits; }
bool get_bit(unsigned i) const { return get(m_bits, i); }
bool get_bit(unsigned i) const { return m_bits.get(i); }
bool try_set_bit(unsigned i, bool b) {
if (get(fixed, i) && get_bit(i) != b)
SASSERT(in_range(m_bits));
if (fixed.get(i) && get_bit(i) != b)
return false;
set(m_bits, i, b);
return true;
m_bits.set(i, b);
if (in_range(m_bits))
return true;
m_bits.set(i, !b);
return false;
}
void set_value(bvect& bits, rational const& r);
@ -161,24 +127,49 @@ namespace bv {
bool has_range() const { return lo != hi; }
void init_fixed();
void clear_overflow_bits(bvect& bits) const { bits.clear_overflow_bits(); }
void clear_overflow_bits(bvect& bits) const {
SASSERT(nw > 0);
bits[nw - 1] &= mask;
SASSERT(!has_overflow(bits));
}
bool in_range(bvect const& bits) const;
bool can_set(bvect const& bits) const;
bool eq(sls_valuation const& other) const { return eq(other.m_bits); }
bool eq(bvect const& other) const { return other == m_bits; }
bool is_zero() const { return m_bits.is_zero(); }
bool is_zero(bvect const& a) const { return a.is_zero(); }
bool is_zero() const { return is_zero(m_bits); }
bool is_zero(bvect const& a) const {
SASSERT(!has_overflow(a));
for (unsigned i = 0; i < nw; ++i)
if (a[i] != 0)
return false;
return true;
}
bool is_ones() const { return m_bits.is_ones(); }
bool is_ones() const { return is_ones(m_bits); }
bool is_one() const { return m_bits.is_one(); }
// bool is_one(bvect const& a) const { return a.is_one(); }
bool is_ones(bvect const& a) const {
SASSERT(!has_overflow(a));
for (unsigned i = 0; i + 1 < nw; ++i)
if (0 != ~a[i])
return false;
return 0 == (mask & ~a[nw - 1]);
}
bool sign() const { return get(m_bits, bw - 1); }
bool is_one() const { return is_one(m_bits); }
bool is_one(bvect const& a) const {
SASSERT(!has_overflow(a));
for (unsigned i = 1; i < nw; ++i)
if (0 != a[i])
return false;
return 1 == a[0];
}
bool has_overflow(bvect const& bits) const { return bits.has_overflow(); }
bool sign() const { return m_bits.get(bw - 1); }
bool has_overflow(bvect const& bits) const { return 0 != (bits[nw - 1] & ~mask); }
unsigned parity(bvect const& bits) const { return bits.parity(); }
@ -227,12 +218,12 @@ namespace bv {
void sub1(bvect& out) const {
for (unsigned i = 0; i < bw; ++i) {
if (get(out, i)) {
set(out, i, false);
if (out.get(i)) {
out.set(i, false);
return;
}
else
set(out, i, true);
out.set(i, true);
}
}
@ -243,11 +234,7 @@ namespace bv {
void set_range(bvect& dst, unsigned lo, unsigned hi, bool b) {
for (unsigned i = lo; i < hi; ++i)
set(dst, i, b);
}
void set(bvect& d, unsigned bit_idx, bool val) const {
d.set(bit_idx, val);
dst.set(i, b);
}
void set(bvect& dst, unsigned v) const {
@ -261,14 +248,9 @@ namespace bv {
dst[i] = src[i];
}
bool get(bvect const& d, unsigned bit_idx) const {
return d.get(bit_idx);
}
unsigned to_nat(unsigned max_n);
std::ostream& display(std::ostream& out) const {
out << "V:";
out << std::hex;
print_bits(out, m_bits);
@ -290,19 +272,13 @@ namespace bv {
return !has_overflow(m_bits) && (!has_range() || in_range(m_bits));
}
private:
};
class sls_pre_valuation : public sls_valuation {
public:
sls_pre_valuation(unsigned bw):sls_valuation(bw) {}
sls_pre_valuation(unsigned bw) :sls_valuation(bw) {}
bvect& bits() { return m_bits; }
void set_bit(unsigned i, bool v) { set(m_bits, i, v); }
void set_bit(unsigned i, bool v) { m_bits.set(i, v); }
};
inline std::ostream& operator<<(std::ostream& out, sls_valuation const& v) { return v.display(out); }