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

more scaffolding

This commit is contained in:
Nikolaj Bjorner 2021-03-21 11:31:14 -07:00
parent a1f484fa35
commit 2fef6dc502
16 changed files with 476 additions and 152 deletions

View file

@ -800,6 +800,8 @@ public:
unsigned storage_size(mpz const & a) { return mpz_manager<SYNCH>::size_info(a); }
unsigned storage_size(mpq const & a) { return mpz_manager<SYNCH>::size_info(a.m_num) + mpz_manager<SYNCH>::size_info(a.m_den); }
bool get_bit(mpq const& a, unsigned index) { SASSERT(is_int(a) && !is_neg(a)); return mpz_manager<SYNCH>::get_bit(a.m_num, index); }
/**
\brief Return true if the number is a perfect square, and
store the square root in 'root'.

View file

@ -2469,6 +2469,33 @@ bool mpz_manager<SYNCH>::decompose(mpz const & a, svector<digit_t> & digits) {
}
}
template<bool SYNCH>
bool mpz_manager<SYNCH>::get_bit(mpz const & a, unsigned index) {
if (is_small(a)) {
SASSERT(a.m_val >= 0);
if (index >= 8*sizeof(digit_t))
return false;
return 0 != (a.m_val & (1ull << (digit_t)index));
}
unsigned i = index / (sizeof(digit_t)*8);
unsigned o = index % (sizeof(digit_t)*8);
#ifndef _MP_GMP
mpz_cell * cell_a = a.m_ptr;
unsigned sz = cell_a->m_size;
if (sz*sizeof(digit_t)*8 <= index)
return false;
return 0 != (cell_a->m_digits[i] & (1ull << (digit_t)o));
#else
SASSERT(!is_neg(a));
svector<digit_t> digits;
decompose(a, digits);
if (digits.size()*sizeof(digit_t)*8 <= index)
return false;
return 0 != (digits[i] & (1ull << (digit_t)o));
#endif
}
template<bool SYNCH>
bool mpz_manager<SYNCH>::divides(mpz const & a, mpz const & b) {
_scoped_numeral<mpz_manager<SYNCH> > tmp(*this);

View file

@ -621,6 +621,7 @@ public:
*/
void display_bin(std::ostream & out, mpz const & a, unsigned num_bits) const;
static unsigned hash(mpz const & a);
static bool is_one(mpz const & a) {
@ -719,6 +720,8 @@ public:
// Store the digits of n into digits, and return the sign.
bool decompose(mpz const & n, svector<digit_t> & digits);
bool get_bit(mpz const& a, unsigned bit);
};
#ifndef SINGLE_THREAD

View file

@ -130,3 +130,26 @@ bool rational::limit_denominator(rational &num, rational const& limit) {
return false;
}
bool rational::mult_inverse(unsigned num_bits, rational & result) {
rational const& n = *this;
if (n.is_one()) {
result = n;
return true;
}
if (n.is_even())
return false;
rational g;
rational x;
rational y;
g = gcd(n, rational::power_of_two(num_bits), x, y);
if (x.is_neg()) {
x = mod(x, rational::power_of_two(num_bits));
}
SASSERT(x.is_pos());
SASSERT(mod(x * n, rational::power_of_two(num_bits)).is_one());
result = x;
return true;
}

View file

@ -308,6 +308,10 @@ public:
bool is_even() const {
return m().is_even(m_val);
}
bool is_odd() const {
return !is_even();
}
friend inline rational floor(rational const & r) {
rational f;
@ -333,6 +337,8 @@ public:
return m().is_power_of_two(m_val, shift);
}
bool mult_inverse(unsigned num_bits, rational & result);
static rational const & zero() {
return m_zero;
}
@ -459,6 +465,18 @@ public:
return get_num_digits(rational(10));
}
bool get_bit(unsigned index) const {
return m().get_bit(m_val, index);
}
unsigned trailing_zeros() const {
if (is_zero())
return 0;
unsigned k = 0;
for (; !get_bit(k); ++k);
return k;
}
static bool limit_denominator(rational &num, rational const& limit);
};