mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
Merge branch 'master' into polysat
This commit is contained in:
commit
20b5455d08
669 changed files with 26145 additions and 20652 deletions
|
@ -211,6 +211,22 @@ public:
|
|||
|
||||
bool contains(const bit_vector & other) const;
|
||||
|
||||
class iterator {
|
||||
bit_vector const& b;
|
||||
unsigned m_curr;
|
||||
public:
|
||||
iterator(bit_vector const& b, unsigned i) : b(b), m_curr(i) {}
|
||||
bool operator*(unsigned i) const { return b.get(m_curr); }
|
||||
bool operator*() const { return b.get(m_curr); }
|
||||
iterator& operator++() { ++m_curr; return *this; }
|
||||
iterator operator++(int) { iterator tmp = *this; ++* this; return tmp; }
|
||||
bool operator==(iterator const& it) const { return m_curr == it.m_curr; }
|
||||
bool operator!=(iterator const& it) const { return m_curr != it.m_curr; }
|
||||
};
|
||||
|
||||
iterator begin() const { return iterator(*this, 0); }
|
||||
iterator end() const { return iterator(*this, size()); }
|
||||
|
||||
};
|
||||
|
||||
inline std::ostream & operator<<(std::ostream & out, bit_vector const & b) {
|
||||
|
|
|
@ -115,7 +115,7 @@ debug_action ask_debug_action(std::istream& in) {
|
|||
|
||||
#if !defined(_WINDOWS) && !defined(NO_Z3_DEBUGGER)
|
||||
void invoke_gdb() {
|
||||
char buffer[1024];
|
||||
std::string buffer;
|
||||
int *x = nullptr;
|
||||
debug_action a = get_default_debug_action();
|
||||
for (;;) {
|
||||
|
@ -131,9 +131,9 @@ void invoke_gdb() {
|
|||
case debug_action::throw_exception:
|
||||
throw default_exception("assertion violation");
|
||||
case debug_action::invoke_debugger:
|
||||
sprintf(buffer, "gdb -nw /proc/%d/exe %d", getpid(), getpid());
|
||||
buffer = "gdb -nw /proc/" + std::to_string(getpid()) + "/exe " + std::to_string(getpid());
|
||||
std::cerr << "invoking GDB...\n";
|
||||
if (system(buffer) == 0) {
|
||||
if (system(buffer.c_str()) == 0) {
|
||||
std::cerr << "continuing the execution...\n";
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -48,7 +48,7 @@ Revision History:
|
|||
// clear to the compiler what instructions should be used. E.g., for sqrt(), the Windows compiler selects
|
||||
// the x87 FPU, even when /arch:SSE2 is on.
|
||||
// Luckily, these are kind of standardized, at least for Windows/Linux/macOS.
|
||||
#if defined(__clang__) || defined(_M_ARM) && defined(_M_ARM64)
|
||||
#if (defined(__clang__) && !defined(__MINGW32__)) || defined(_M_ARM) && defined(_M_ARM64)
|
||||
#undef USE_INTRINSICS
|
||||
#endif
|
||||
|
||||
|
|
|
@ -16,6 +16,17 @@ Copyright (c) 2015 Microsoft Corporation
|
|||
#ifdef __GLIBC__
|
||||
# include <malloc.h>
|
||||
# define HAS_MALLOC_USABLE_SIZE
|
||||
#elif defined(__APPLE__)
|
||||
# include <malloc/malloc.h>
|
||||
# define HAS_MALLOC_USABLE_SIZE
|
||||
# define malloc_usable_size malloc_size
|
||||
#elif defined(__FreeBSD__)
|
||||
# include <malloc_np.h>
|
||||
# define HAS_MALLOC_USABLE_SIZE
|
||||
#elif defined(_WINDOWS)
|
||||
# include <malloc.h>
|
||||
# define HAS_MALLOC_USABLE_SIZE
|
||||
# define malloc_usable_size _msize
|
||||
#endif
|
||||
|
||||
// The following two function are automatically generated by the mk_make.py script.
|
||||
|
|
|
@ -41,9 +41,6 @@ mpf::mpf(unsigned _ebits, unsigned _sbits):
|
|||
set(ebits, sbits);
|
||||
}
|
||||
|
||||
mpf::~mpf() {
|
||||
}
|
||||
|
||||
void mpf::swap(mpf & other) {
|
||||
unsigned tmp = ebits;
|
||||
ebits = other.ebits;
|
||||
|
@ -64,9 +61,6 @@ mpf_manager::mpf_manager() :
|
|||
m_powers2(m_mpz_manager) {
|
||||
}
|
||||
|
||||
mpf_manager::~mpf_manager() {
|
||||
}
|
||||
|
||||
void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, int value) {
|
||||
static_assert(sizeof(int) == 4, "assume integers are 4 bytes");
|
||||
|
||||
|
@ -200,22 +194,20 @@ void mpf_manager::set(mpf & o, unsigned ebits, unsigned sbits, mpf_rounding_mode
|
|||
|
||||
// We expect [i].[f]P[e], where P means that the exponent is interpreted as 2^e instead of 10^e.
|
||||
|
||||
std::string v(value);
|
||||
|
||||
std::string f, e;
|
||||
std::string_view v(value);
|
||||
bool sgn = false;
|
||||
|
||||
if (v.substr(0, 1) == "-") {
|
||||
if (v[0] == '-') {
|
||||
sgn = true;
|
||||
v = v.substr(1);
|
||||
}
|
||||
else if (v.substr(0, 1) == "+")
|
||||
else if (v[0] == '+')
|
||||
v = v.substr(1);
|
||||
|
||||
size_t e_pos = v.find('p');
|
||||
if (e_pos == std::string::npos) e_pos = v.find('P');
|
||||
f = (e_pos != std::string::npos) ? v.substr(0, e_pos) : v;
|
||||
e = (e_pos != std::string::npos) ? v.substr(e_pos+1) : "0";
|
||||
if (e_pos == std::string_view::npos) e_pos = v.find('P');
|
||||
auto f = (e_pos != std::string_view::npos) ? std::string(v.substr(0, e_pos)) : std::string(v);
|
||||
auto e = (e_pos != std::string_view::npos) ? std::string(v.substr(e_pos+1)) : "0";
|
||||
|
||||
TRACE("mpf_dbg", tout << "sgn = " << sgn << " f = " << f << " e = " << e << std::endl;);
|
||||
|
||||
|
@ -1564,7 +1556,7 @@ std::string mpf_manager::to_string(mpf const & x) {
|
|||
if (m_mpq_manager.is_int(r))
|
||||
ss << ".0";
|
||||
ss << " " << exponent;
|
||||
res += ss.str();
|
||||
res += std::move(ss).str();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1602,7 +1594,7 @@ std::string mpf_manager::to_string_raw(mpf const & x) {
|
|||
res += " ";
|
||||
std::stringstream ss("");
|
||||
ss << exp(x);
|
||||
res += ss.str();
|
||||
res += std::move(ss).str();
|
||||
if (is_normal(x))
|
||||
res += " N";
|
||||
else
|
||||
|
@ -1631,7 +1623,7 @@ std::string mpf_manager::to_string_hexfloat(mpf const & x) {
|
|||
ss.setf(ff);
|
||||
ss.precision(13);
|
||||
ss << std::hexfloat << to_double(x);
|
||||
return ss.str();
|
||||
return std::move(ss).str();
|
||||
}
|
||||
|
||||
std::string mpf_manager::to_string_binary(mpf const & x, unsigned upper_extra, unsigned lower_extra) {
|
||||
|
|
|
@ -49,7 +49,6 @@ public:
|
|||
mpf();
|
||||
mpf(unsigned ebits, unsigned sbits);
|
||||
mpf(mpf &&) = default;
|
||||
~mpf();
|
||||
mpf & operator=(mpf const & other) = delete;
|
||||
unsigned get_ebits() const { return ebits; }
|
||||
unsigned get_sbits() const { return sbits; }
|
||||
|
@ -64,7 +63,6 @@ public:
|
|||
typedef mpf numeral;
|
||||
|
||||
mpf_manager();
|
||||
~mpf_manager();
|
||||
|
||||
void reset(mpf & o, unsigned ebits, unsigned sbits) { set(o, ebits, sbits, 0); }
|
||||
void set(mpf & o, unsigned ebits, unsigned sbits, int value);
|
||||
|
|
|
@ -703,7 +703,7 @@ void mpff_manager::add_sub(bool is_sub, mpff const & a, mpff const & b, mpff & c
|
|||
if (sgn_a == sgn_b) {
|
||||
c.m_sign = sgn_a;
|
||||
unsigned * sig_r = m_buffers[1].data();
|
||||
size_t r_sz;
|
||||
unsigned r_sz;
|
||||
m_mpn_manager.add(sig_a, m_precision, n_sig_b, m_precision, sig_r, m_precision + 1, &r_sz);
|
||||
SASSERT(r_sz <= m_precision + 1);
|
||||
unsigned num_leading_zeros = nlz(m_precision + 1, sig_r);
|
||||
|
|
116
src/util/mpn.cpp
116
src/util/mpn.cpp
|
@ -28,20 +28,14 @@ static_assert(sizeof(mpn_double_digit) == 2 * sizeof(mpn_digit), "size alignment
|
|||
|
||||
const mpn_digit mpn_manager::zero = 0;
|
||||
|
||||
mpn_manager::mpn_manager() {
|
||||
}
|
||||
|
||||
mpn_manager::~mpn_manager() {
|
||||
}
|
||||
|
||||
int mpn_manager::compare(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb) const {
|
||||
int mpn_manager::compare(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb) const {
|
||||
int res = 0;
|
||||
|
||||
trace(a, lnga);
|
||||
|
||||
size_t j = max(lnga, lngb) - 1;
|
||||
for (; j != (size_t)-1 && res == 0; j--) {
|
||||
unsigned j = max(lnga, lngb);
|
||||
for (; j-- > 0 && res == 0;) {
|
||||
mpn_digit const & u_j = (j < lnga) ? a[j] : zero;
|
||||
mpn_digit const & v_j = (j < lngb) ? b[j] : zero;
|
||||
if (u_j > v_j)
|
||||
|
@ -56,18 +50,18 @@ int mpn_manager::compare(mpn_digit const * a, size_t const lnga,
|
|||
return res;
|
||||
}
|
||||
|
||||
bool mpn_manager::add(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
mpn_digit * c, size_t const lngc_alloc,
|
||||
size_t * plngc) const {
|
||||
bool mpn_manager::add(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
mpn_digit * c, unsigned lngc_alloc,
|
||||
unsigned * plngc) const {
|
||||
trace(a, lnga, b, lngb, "+");
|
||||
// Essentially Knuth's Algorithm A
|
||||
size_t len = max(lnga, lngb);
|
||||
unsigned len = max(lnga, lngb);
|
||||
SASSERT(lngc_alloc == len+1 && len > 0);
|
||||
mpn_digit k = 0;
|
||||
mpn_digit r;
|
||||
bool c1, c2;
|
||||
for (size_t j = 0; j < len; j++) {
|
||||
for (unsigned j = 0; j < len; j++) {
|
||||
mpn_digit const & u_j = (j < lnga) ? a[j] : zero;
|
||||
mpn_digit const & v_j = (j < lngb) ? b[j] : zero;
|
||||
r = u_j + v_j; c1 = r < u_j;
|
||||
|
@ -75,23 +69,23 @@ bool mpn_manager::add(mpn_digit const * a, size_t const lnga,
|
|||
k = c1 | c2;
|
||||
}
|
||||
c[len] = k;
|
||||
size_t &os = *plngc;
|
||||
unsigned &os = *plngc;
|
||||
for (os = len+1; os > 1 && c[os-1] == 0; ) os--;
|
||||
SASSERT(os > 0 && os <= len+1);
|
||||
trace_nl(c, os);
|
||||
return true; // return k != 0?
|
||||
}
|
||||
|
||||
bool mpn_manager::sub(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
bool mpn_manager::sub(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
mpn_digit * c, mpn_digit * pborrow) const {
|
||||
trace(a, lnga, b, lngb, "-");
|
||||
// Essentially Knuth's Algorithm S
|
||||
size_t len = max(lnga, lngb);
|
||||
unsigned len = max(lnga, lngb);
|
||||
mpn_digit & k = *pborrow; k = 0;
|
||||
mpn_digit r;
|
||||
bool c1, c2;
|
||||
for (size_t j = 0; j < len; j++) {
|
||||
for (unsigned j = 0; j < len; j++) {
|
||||
mpn_digit const & u_j = (j < lnga) ? a[j] : zero;
|
||||
mpn_digit const & v_j = (j < lngb) ? b[j] : zero;
|
||||
r = u_j - v_j; c1 = r > u_j;
|
||||
|
@ -102,13 +96,13 @@ bool mpn_manager::sub(mpn_digit const * a, size_t const lnga,
|
|||
return true; // return k != 0?
|
||||
}
|
||||
|
||||
bool mpn_manager::mul(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
bool mpn_manager::mul(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
mpn_digit * c) const {
|
||||
trace(a, lnga, b, lngb, "*");
|
||||
// Essentially Knuth's Algorithm M.
|
||||
// Perhaps implement a more efficient version, see e.g., Knuth, Section 4.3.3.
|
||||
size_t i;
|
||||
unsigned i;
|
||||
mpn_digit k;
|
||||
|
||||
#define DIGIT_BITS (sizeof(mpn_digit)*8)
|
||||
|
@ -117,7 +111,7 @@ bool mpn_manager::mul(mpn_digit const * a, size_t const lnga,
|
|||
for (unsigned i = 0; i < lnga; i++)
|
||||
c[i] = 0;
|
||||
|
||||
for (size_t j = 0; j < lngb; j++) {
|
||||
for (unsigned j = 0; j < lngb; j++) {
|
||||
mpn_digit const & v_j = b[j];
|
||||
if (v_j == 0) { // This branch may be omitted according to Knuth.
|
||||
c[j+lnga] = 0;
|
||||
|
@ -147,23 +141,23 @@ bool mpn_manager::mul(mpn_digit const * a, size_t const lnga,
|
|||
#define LAST_BITS(N, X) (((X) << (DIGIT_BITS-(N))) >> (DIGIT_BITS-(N)))
|
||||
#define BASE ((mpn_double_digit)0x01 << DIGIT_BITS)
|
||||
|
||||
bool mpn_manager::div(mpn_digit const * numer, size_t const lnum,
|
||||
mpn_digit const * denom, size_t const lden,
|
||||
bool mpn_manager::div(mpn_digit const * numer, unsigned lnum,
|
||||
mpn_digit const * denom, unsigned lden,
|
||||
mpn_digit * quot,
|
||||
mpn_digit * rem) {
|
||||
trace(numer, lnum, denom, lden, "/");
|
||||
bool res = false;
|
||||
|
||||
if (lnum < lden) {
|
||||
for (size_t i = 0; i < (lnum-lden+1); i++)
|
||||
for (unsigned i = 0; i < (lnum-lden+1); i++)
|
||||
quot[i] = 0;
|
||||
for (size_t i = 0; i < lden; i++)
|
||||
for (unsigned i = 0; i < lden; i++)
|
||||
rem[i] = (i < lnum) ? numer[i] : 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool all_zero = true;
|
||||
for (size_t i = 0; i < lden && all_zero; i++)
|
||||
for (unsigned i = 0; i < lden && all_zero; i++)
|
||||
if (denom[i] != zero) all_zero = false;
|
||||
|
||||
if (all_zero) {
|
||||
|
@ -179,12 +173,12 @@ bool mpn_manager::div(mpn_digit const * numer, size_t const lnum,
|
|||
}
|
||||
else if (lnum < lden || (lnum == lden && numer[lnum-1] < denom[lden-1])) {
|
||||
*quot = 0;
|
||||
for (size_t i = 0; i < lden; i++)
|
||||
for (unsigned i = 0; i < lden; i++)
|
||||
rem[i] = (i < lnum) ? numer[i] : 0;
|
||||
}
|
||||
else {
|
||||
mpn_sbuffer u, v, t_ms, t_ab;
|
||||
size_t d = div_normalize(numer, lnum, denom, lden, u, v);
|
||||
unsigned d = div_normalize(numer, lnum, denom, lden, u, v);
|
||||
if (lden == 1)
|
||||
res = div_1(u, v[0], quot);
|
||||
else
|
||||
|
@ -202,10 +196,10 @@ bool mpn_manager::div(mpn_digit const * numer, size_t const lnum,
|
|||
#ifdef Z3DEBUG
|
||||
mpn_sbuffer temp(lnum+1, 0);
|
||||
mul(quot, lnum-lden+1, denom, lden, temp.data());
|
||||
size_t real_size;
|
||||
unsigned real_size;
|
||||
add(temp.data(), lnum, rem, lden, temp.data(), lnum+1, &real_size);
|
||||
bool ok = true;
|
||||
for (size_t i = 0; i < lnum && ok; i++)
|
||||
for (unsigned i = 0; i < lnum && ok; i++)
|
||||
if (temp[i] != numer[i]) ok = false;
|
||||
if (temp[lnum] != 0) ok = false;
|
||||
CTRACE("mpn_dbg", !ok, tout << "DIV BUG: quot * denom + rem = "; display_raw(tout, temp.data(), lnum+1); tout << std::endl; );
|
||||
|
@ -215,12 +209,12 @@ bool mpn_manager::div(mpn_digit const * numer, size_t const lnum,
|
|||
return res;
|
||||
}
|
||||
|
||||
size_t mpn_manager::div_normalize(mpn_digit const * numer, size_t const lnum,
|
||||
mpn_digit const * denom, size_t const lden,
|
||||
unsigned mpn_manager::div_normalize(mpn_digit const * numer, unsigned lnum,
|
||||
mpn_digit const * denom, unsigned lden,
|
||||
mpn_sbuffer & n_numer,
|
||||
mpn_sbuffer & n_denom) const
|
||||
{
|
||||
size_t d = 0;
|
||||
unsigned d = 0;
|
||||
while (lden > 0 && ((denom[lden-1] << d) & MASK_FIRST) == 0) d++;
|
||||
SASSERT(d < DIGIT_BITS);
|
||||
|
||||
|
@ -229,19 +223,19 @@ size_t mpn_manager::div_normalize(mpn_digit const * numer, size_t const lnum,
|
|||
|
||||
if (d == 0) {
|
||||
n_numer[lnum] = 0;
|
||||
for (size_t i = 0; i < lnum; i++)
|
||||
for (unsigned i = 0; i < lnum; i++)
|
||||
n_numer[i] = numer[i];
|
||||
for (size_t i = 0; i < lden; i++)
|
||||
for (unsigned i = 0; i < lden; i++)
|
||||
n_denom[i] = denom[i];
|
||||
}
|
||||
else if (lnum != 0) {
|
||||
SASSERT(lden > 0);
|
||||
mpn_digit q = FIRST_BITS(d, numer[lnum-1]);
|
||||
n_numer[lnum] = q;
|
||||
for (size_t i = lnum-1; i > 0; i--)
|
||||
for (unsigned i = lnum-1; i > 0; i--)
|
||||
n_numer[i] = (numer[i] << d) | FIRST_BITS(d, numer[i-1]);
|
||||
n_numer[0] = numer[0] << d;
|
||||
for (size_t i = lden-1; i > 0; i--)
|
||||
for (unsigned i = lden-1; i > 0; i--)
|
||||
n_denom[i] = denom[i] << d | FIRST_BITS(d, denom[i-1]);
|
||||
n_denom[0] = denom[0] << d;
|
||||
}
|
||||
|
@ -255,13 +249,13 @@ size_t mpn_manager::div_normalize(mpn_digit const * numer, size_t const lnum,
|
|||
}
|
||||
|
||||
void mpn_manager::div_unnormalize(mpn_sbuffer & numer, mpn_sbuffer & denom,
|
||||
size_t const d, mpn_digit * rem) const {
|
||||
unsigned d, mpn_digit * rem) const {
|
||||
if (d == 0) {
|
||||
for (size_t i = 0; i < denom.size(); i++)
|
||||
for (unsigned i = 0; i < denom.size(); i++)
|
||||
rem[i] = numer[i];
|
||||
}
|
||||
else {
|
||||
for (size_t i = 0; i < denom.size()-1; i++)
|
||||
for (unsigned i = 0; i < denom.size()-1; i++)
|
||||
rem[i] = numer[i] >> d | (LAST_BITS(d, numer[i+1]) << (DIGIT_BITS-d));
|
||||
rem[denom.size()-1] = numer[denom.size()-1] >> d;
|
||||
}
|
||||
|
@ -272,7 +266,7 @@ bool mpn_manager::div_1(mpn_sbuffer & numer, mpn_digit const denom,
|
|||
mpn_double_digit q_hat, temp, ms;
|
||||
mpn_digit borrow;
|
||||
|
||||
for (size_t j = numer.size()-1; j > 0; j--) {
|
||||
for (unsigned j = numer.size()-1; j > 0; j--) {
|
||||
temp = (((mpn_double_digit)numer[j]) << DIGIT_BITS) | ((mpn_double_digit)numer[j-1]);
|
||||
q_hat = temp / (mpn_double_digit) denom;
|
||||
if (q_hat >= BASE) {
|
||||
|
@ -306,8 +300,8 @@ bool mpn_manager::div_n(mpn_sbuffer & numer, mpn_sbuffer const & denom,
|
|||
SASSERT(denom.size() > 1);
|
||||
|
||||
// This is essentially Knuth's Algorithm D.
|
||||
size_t m = numer.size() - denom.size();
|
||||
size_t n = denom.size();
|
||||
unsigned m = numer.size() - denom.size();
|
||||
unsigned n = denom.size();
|
||||
|
||||
SASSERT(numer.size() == m+n);
|
||||
|
||||
|
@ -316,7 +310,7 @@ bool mpn_manager::div_n(mpn_sbuffer & numer, mpn_sbuffer const & denom,
|
|||
mpn_double_digit q_hat, temp, r_hat;
|
||||
mpn_digit borrow;
|
||||
|
||||
for (size_t j = m-1; j != (size_t)-1; j--) {
|
||||
for (unsigned j = m; j-- > 0; ) {
|
||||
temp = (((mpn_double_digit)numer[j+n]) << DIGIT_BITS) | ((mpn_double_digit)numer[j+n-1]);
|
||||
q_hat = temp / (mpn_double_digit) denom[n-1];
|
||||
r_hat = temp % (mpn_double_digit) denom[n-1];
|
||||
|
@ -337,9 +331,9 @@ bool mpn_manager::div_n(mpn_sbuffer & numer, mpn_sbuffer const & denom,
|
|||
if (borrow) {
|
||||
quot[j]--;
|
||||
ab.resize(n+2);
|
||||
size_t real_size;
|
||||
unsigned real_size;
|
||||
add(denom.data(), n, &numer[j], n+1, ab.data(), n+2, &real_size);
|
||||
for (size_t i = 0; i < n+1; i++)
|
||||
for (unsigned i = 0; i < n+1; i++)
|
||||
numer[j+i] = ab[i];
|
||||
}
|
||||
TRACE("mpn_div", tout << "q_hat=" << q_hat << " r_hat=" << r_hat;
|
||||
|
@ -352,7 +346,7 @@ bool mpn_manager::div_n(mpn_sbuffer & numer, mpn_sbuffer const & denom,
|
|||
return true; // return rem != 0?
|
||||
}
|
||||
|
||||
char * mpn_manager::to_string(mpn_digit const * a, size_t const lng, char * buf, size_t const lbuf) const {
|
||||
char * mpn_manager::to_string(mpn_digit const * a, unsigned lng, char * buf, unsigned lbuf) const {
|
||||
SASSERT(buf && lbuf > 0);
|
||||
TRACE("mpn_to_string", tout << "[mpn] to_string "; display_raw(tout, a, lng); tout << " == "; );
|
||||
|
||||
|
@ -368,11 +362,11 @@ char * mpn_manager::to_string(mpn_digit const * a, size_t const lng, char * buf,
|
|||
for (unsigned i = 0; i < lng; i++)
|
||||
temp[i] = a[i];
|
||||
|
||||
size_t j = 0;
|
||||
unsigned j = 0;
|
||||
mpn_digit rem;
|
||||
mpn_digit ten = 10;
|
||||
while (!temp.empty() && (temp.size() > 1 || temp[0] != 0)) {
|
||||
size_t d = div_normalize(&temp[0], temp.size(), &ten, 1, t_numer, t_denom);
|
||||
unsigned d = div_normalize(&temp[0], temp.size(), &ten, 1, t_numer, t_denom);
|
||||
div_1(t_numer, t_denom[0], &temp[0]);
|
||||
div_unnormalize(t_numer, t_denom, d, &rem);
|
||||
buf[j++] = '0' + rem;
|
||||
|
@ -382,8 +376,8 @@ char * mpn_manager::to_string(mpn_digit const * a, size_t const lng, char * buf,
|
|||
buf[j] = 0;
|
||||
|
||||
j--;
|
||||
size_t mid = (j/2) + ((j % 2) ? 1 : 0);
|
||||
for (size_t i = 0; i < mid; i++)
|
||||
unsigned mid = (j/2) + ((j % 2) ? 1 : 0);
|
||||
for (unsigned i = 0; i < mid; i++)
|
||||
std::swap(buf[i], buf[j-i]);
|
||||
}
|
||||
|
||||
|
@ -392,14 +386,14 @@ char * mpn_manager::to_string(mpn_digit const * a, size_t const lng, char * buf,
|
|||
return buf;
|
||||
}
|
||||
|
||||
void mpn_manager::display_raw(std::ostream & out, mpn_digit const * a, size_t const lng) const {
|
||||
void mpn_manager::display_raw(std::ostream & out, mpn_digit const * a, unsigned lng) const {
|
||||
out << "[";
|
||||
for (size_t i = lng-1; i != (size_t)-1; i-- ) { out << a[i]; if (i != 0) out << "|"; }
|
||||
for (unsigned i = lng; i-- > 0; ) { out << a[i]; if (i != 0) out << "|"; }
|
||||
out << "]";
|
||||
}
|
||||
|
||||
void mpn_manager::trace(mpn_digit const * a, size_t const lnga,
|
||||
mpn_digit const * b, size_t const lngb,
|
||||
void mpn_manager::trace(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
const char * op) const {
|
||||
#ifdef Z3DEBUG
|
||||
char char_buf[4096];
|
||||
|
@ -409,14 +403,14 @@ void mpn_manager::trace(mpn_digit const * a, size_t const lnga,
|
|||
#endif
|
||||
}
|
||||
|
||||
void mpn_manager::trace(mpn_digit const * a, size_t const lnga) const {
|
||||
void mpn_manager::trace(mpn_digit const * a, unsigned lnga) const {
|
||||
#ifdef Z3DEBUG
|
||||
char char_buf[4096];
|
||||
TRACE("mpn", tout << to_string(a, lnga, char_buf, sizeof(char_buf)); );
|
||||
#endif
|
||||
}
|
||||
|
||||
void mpn_manager::trace_nl(mpn_digit const * a, size_t const lnga) const {
|
||||
void mpn_manager::trace_nl(mpn_digit const * a, unsigned lnga) const {
|
||||
#ifdef Z3DEBUG
|
||||
char char_buf[4096];
|
||||
TRACE("mpn", tout << to_string(a, lnga, char_buf, sizeof(char_buf)) << std::endl; );
|
||||
|
|
|
@ -27,68 +27,42 @@ typedef unsigned int mpn_digit;
|
|||
class mpn_manager {
|
||||
|
||||
public:
|
||||
mpn_manager();
|
||||
~mpn_manager();
|
||||
int compare(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb) const;
|
||||
|
||||
int compare(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb) const;
|
||||
bool add(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
mpn_digit *c, unsigned lngc_alloc,
|
||||
unsigned * plngc) const;
|
||||
|
||||
bool add(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
mpn_digit *c, size_t lngc_alloc,
|
||||
size_t * plngc) const;
|
||||
|
||||
bool sub(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
bool sub(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
mpn_digit * c, mpn_digit * pborrow) const;
|
||||
|
||||
bool mul(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
bool mul(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
mpn_digit * c) const;
|
||||
|
||||
bool div(mpn_digit const * numer, size_t lnum,
|
||||
mpn_digit const * denom, size_t lden,
|
||||
bool div(mpn_digit const * numer, unsigned lnum,
|
||||
mpn_digit const * denom, unsigned lden,
|
||||
mpn_digit * quot,
|
||||
mpn_digit * rem);
|
||||
|
||||
char * to_string(mpn_digit const * a, size_t lng,
|
||||
char * buf, size_t lbuf) const;
|
||||
char * to_string(mpn_digit const * a, unsigned lng,
|
||||
char * buf, unsigned lbuf) const;
|
||||
private:
|
||||
#if defined(__LP64__) || defined(_WIN64)
|
||||
class mpn_sbuffer : public sbuffer<mpn_digit> {
|
||||
public:
|
||||
mpn_sbuffer() : sbuffer<mpn_digit>() {}
|
||||
|
||||
mpn_sbuffer(size_t nsz, const mpn_digit & elem = 0) :
|
||||
sbuffer<mpn_digit>(static_cast<unsigned>(nsz), elem)
|
||||
{
|
||||
}
|
||||
void resize(size_t nsz, const mpn_digit & elem = 0) {
|
||||
sbuffer<mpn_digit>::resize(static_cast<unsigned>(nsz), elem);
|
||||
}
|
||||
|
||||
mpn_digit & operator[](size_t idx) {
|
||||
return sbuffer<mpn_digit>::operator[](static_cast<unsigned>(idx));
|
||||
}
|
||||
|
||||
const mpn_digit & operator[](size_t idx) const {
|
||||
return sbuffer<mpn_digit>::operator[](static_cast<unsigned>(idx));
|
||||
}
|
||||
};
|
||||
#else
|
||||
typedef sbuffer<mpn_digit> mpn_sbuffer;
|
||||
#endif
|
||||
using mpn_sbuffer = sbuffer<mpn_digit>;
|
||||
|
||||
static const mpn_digit zero;
|
||||
void display_raw(std::ostream & out, mpn_digit const * a, size_t lng) const;
|
||||
void display_raw(std::ostream & out, mpn_digit const * a, unsigned lng) const;
|
||||
|
||||
size_t div_normalize(mpn_digit const * numer, size_t lnum,
|
||||
mpn_digit const * denom, size_t lden,
|
||||
unsigned div_normalize(mpn_digit const * numer, unsigned lnum,
|
||||
mpn_digit const * denom, unsigned lden,
|
||||
mpn_sbuffer & n_numer,
|
||||
mpn_sbuffer & n_denom) const;
|
||||
|
||||
void div_unnormalize(mpn_sbuffer & numer, mpn_sbuffer & denom,
|
||||
size_t d, mpn_digit * rem) const;
|
||||
unsigned d, mpn_digit * rem) const;
|
||||
|
||||
bool div_1(mpn_sbuffer & numer, mpn_digit denom,
|
||||
mpn_digit * quot) const;
|
||||
|
@ -97,11 +71,10 @@ private:
|
|||
mpn_digit * quot, mpn_digit * rem,
|
||||
mpn_sbuffer & ms, mpn_sbuffer & ab) const;
|
||||
|
||||
void trace(mpn_digit const * a, size_t lnga,
|
||||
mpn_digit const * b, size_t lngb,
|
||||
void trace(mpn_digit const * a, unsigned lnga,
|
||||
mpn_digit const * b, unsigned lngb,
|
||||
const char * op) const;
|
||||
|
||||
void trace(mpn_digit const * a, size_t lnga) const;
|
||||
void trace_nl(mpn_digit const * a, size_t lnga) const;
|
||||
void trace(mpn_digit const * a, unsigned lnga) const;
|
||||
void trace_nl(mpn_digit const * a, unsigned lnga) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -32,13 +32,10 @@ public:
|
|||
mpq(mpq &&) noexcept = default;
|
||||
mpq & operator=(mpq&&) = default;
|
||||
mpq & operator=(mpq const&) = delete;
|
||||
void swap(mpq & other) { m_num.swap(other.m_num); m_den.swap(other.m_den); }
|
||||
mpz const & numerator() const { return m_num; }
|
||||
mpz const & denominator() const { return m_den; }
|
||||
};
|
||||
|
||||
inline void swap(mpq & m1, mpq & m2) { m1.swap(m2); }
|
||||
|
||||
template<bool SYNCH = true>
|
||||
class mpq_manager : public mpz_manager<SYNCH> {
|
||||
mpz m_tmp1;
|
||||
|
|
|
@ -695,7 +695,7 @@ void mpz_manager<SYNCH>::big_add_sub(mpz const & a, mpz const & b, mpz & c) {
|
|||
mpz_stack tmp;
|
||||
if (SUB)
|
||||
sign_b = -sign_b;
|
||||
size_t real_sz;
|
||||
unsigned real_sz;
|
||||
if (ca.sign() == sign_b) {
|
||||
unsigned sz = std::max(ca.cell()->m_size, cb.cell()->m_size)+1;
|
||||
allocate_if_needed(tmp, sz);
|
||||
|
@ -703,7 +703,7 @@ void mpz_manager<SYNCH>::big_add_sub(mpz const & a, mpz const & b, mpz & c) {
|
|||
cb.cell()->m_digits, cb.cell()->m_size,
|
||||
tmp.m_ptr->m_digits, sz, &real_sz);
|
||||
SASSERT(real_sz <= sz);
|
||||
set(*tmp.m_ptr, c, ca.sign(), static_cast<unsigned>(real_sz));
|
||||
set(*tmp.m_ptr, c, ca.sign(), real_sz);
|
||||
}
|
||||
else {
|
||||
digit_t borrow;
|
||||
|
@ -1460,9 +1460,11 @@ void mpz_manager<SYNCH>::bitwise_xor(mpz const & a, mpz const & b, mpz & c) {
|
|||
template<bool SYNCH>
|
||||
void mpz_manager<SYNCH>::bitwise_not(unsigned sz, mpz const & a, mpz & c) {
|
||||
SASSERT(is_nonneg(a));
|
||||
if (is_small(a) && sz <= 63) {
|
||||
int64_t mask = (static_cast<int64_t>(1) << sz) - static_cast<int64_t>(1);
|
||||
set_i64(c, (~ i64(a)) & mask);
|
||||
if (is_small(a) && sz <= 64) {
|
||||
uint64_t v = ~get_uint64(a);
|
||||
unsigned zero_out = 64 - sz;
|
||||
v = (v << zero_out) >> zero_out;
|
||||
set(c, v);
|
||||
}
|
||||
else {
|
||||
mpz a1, a2, m, tmp;
|
||||
|
|
|
@ -167,6 +167,8 @@ struct param_descrs::imp {
|
|||
names.push_back(kv.m_key);
|
||||
}
|
||||
std::sort(names.begin(), names.end(), symlt());
|
||||
if (names.empty())
|
||||
return;
|
||||
if (markdown) {
|
||||
out << " Parameter | Type | Description | Default\n";
|
||||
out << " ----------|------|-------------|--------\n";
|
||||
|
@ -312,19 +314,19 @@ void param_descrs::display_markdown(std::ostream & out, bool smt2_style, bool in
|
|||
}
|
||||
|
||||
void insert_max_memory(param_descrs & r) {
|
||||
r.insert("max_memory", CPK_UINT, "(default: infty) maximum amount of memory in megabytes.");
|
||||
r.insert("max_memory", CPK_UINT, "(default: infty) maximum amount of memory in megabytes.", "4294967295");
|
||||
}
|
||||
|
||||
void insert_max_steps(param_descrs & r) {
|
||||
r.insert("max_steps", CPK_UINT, "(default: infty) maximum number of steps.");
|
||||
r.insert("max_steps", CPK_UINT, "(default: infty) maximum number of steps.", "4294967295");
|
||||
}
|
||||
|
||||
void insert_produce_models(param_descrs & r) {
|
||||
r.insert("produce_models", CPK_BOOL, "(default: false) model generation.");
|
||||
r.insert("produce_models", CPK_BOOL, "model generation.", "false");
|
||||
}
|
||||
|
||||
void insert_produce_proofs(param_descrs & r) {
|
||||
r.insert("produce_proofs", CPK_BOOL, "(default: false) proof generation.");
|
||||
r.insert("produce_proofs", CPK_BOOL, "proof generation.", "false");
|
||||
}
|
||||
|
||||
void insert_timeout(param_descrs & r) {
|
||||
|
|
|
@ -98,20 +98,21 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T, bool CallDestructors=true>
|
||||
class restore_size_trail : public trail {
|
||||
vector<T, CallDestructors> & m_vector;
|
||||
unsigned m_old_size;
|
||||
template<typename V>
|
||||
class restore_vector : public trail {
|
||||
V& m_vector;
|
||||
unsigned m_old_size;
|
||||
public:
|
||||
restore_size_trail(vector<T, CallDestructors> & v, unsigned sz):
|
||||
restore_vector(V& v):
|
||||
m_vector(v),
|
||||
m_old_size(sz) {
|
||||
}
|
||||
restore_size_trail(vector<T, CallDestructors> & v):
|
||||
m_old_size(v.size())
|
||||
{}
|
||||
|
||||
restore_vector(V& v, unsigned sz):
|
||||
m_vector(v),
|
||||
m_old_size(v.size()) {
|
||||
}
|
||||
|
||||
m_old_size(sz)
|
||||
{}
|
||||
|
||||
void undo() override {
|
||||
m_vector.shrink(m_old_size);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ Revision History:
|
|||
#include <limits>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
|
@ -105,6 +106,7 @@ unsigned uint64_log2(uint64_t v);
|
|||
static_assert(sizeof(unsigned) == 4, "unsigned are 32 bits");
|
||||
|
||||
// Return the number of 1 bits in v.
|
||||
// see e.g. http://en.wikipedia.org/wiki/Hamming_weight
|
||||
static inline unsigned get_num_1bits(unsigned v) {
|
||||
#ifdef __GNUC__
|
||||
return __builtin_popcount(v);
|
||||
|
@ -124,6 +126,25 @@ static inline unsigned get_num_1bits(unsigned v) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static inline unsigned get_num_1bits(uint64_t v) {
|
||||
#ifdef __GNUC__
|
||||
return __builtin_popcountll(v);
|
||||
#else
|
||||
#ifdef Z3DEBUG
|
||||
unsigned c;
|
||||
uint64_t v1 = v;
|
||||
for (c = 0; v1; c++) {
|
||||
v1 &= v1 - 1;
|
||||
}
|
||||
#endif
|
||||
v = v - (v >> 1) & 0x5555555555555555;
|
||||
v = (v & 0x3333333333333333) + ((v >> 2) & 0x3333333333333333);
|
||||
v = (v + (v >> 4)) & 0x0F0F0F0F0F0F0F0F;
|
||||
uint64_t r = (v * 0x0101010101010101) >> 56;
|
||||
SASSERT(c == r);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Remark: on gcc, the operators << and >> do not produce zero when the second argument >= 64.
|
||||
// So, I'm using the following two definitions to fix the problem
|
||||
static inline uint64_t shift_right(uint64_t x, uint64_t y) {
|
||||
|
@ -161,9 +182,8 @@ void display(std::ostream & out, const IT & begin, const IT & end, const char *
|
|||
template<typename T>
|
||||
struct delete_proc {
|
||||
void operator()(T * ptr) {
|
||||
if (ptr) {
|
||||
dealloc(ptr);
|
||||
}
|
||||
if (ptr)
|
||||
dealloc(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -342,6 +362,22 @@ void fatal_error(int error_code);
|
|||
void set_fatal_error_handler(void (*pfn)(int error_code));
|
||||
|
||||
|
||||
template<typename S, typename T>
|
||||
bool any_of(S& set, T const& p) {
|
||||
for (auto const& s : set)
|
||||
if (p(s))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename S, typename T>
|
||||
bool all_of(S& set, T const& p) {
|
||||
for (auto const& s : set)
|
||||
if (!p(s))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Iterator for the [0..sz[0]) X [0..sz[1]) X ... X [0..sz[n-1]).
|
||||
it contains the current value.
|
||||
|
|
49
src/util/visit_helper.h
Normal file
49
src/util/visit_helper.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
visit_helper.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Routine for marking and counting visited occurrences
|
||||
|
||||
Author:
|
||||
|
||||
Clemens Eisenhofer 2022-11-03
|
||||
|
||||
--*/
|
||||
#pragma once
|
||||
|
||||
|
||||
class visit_helper {
|
||||
|
||||
unsigned_vector m_visited;
|
||||
unsigned m_visited_begin = 0;
|
||||
unsigned m_visited_end = 0;
|
||||
|
||||
public:
|
||||
|
||||
void init_visited(unsigned n, unsigned lim = 1) {
|
||||
SASSERT(lim > 0);
|
||||
if (m_visited_end >= m_visited_end + lim) { // overflow
|
||||
m_visited_begin = 0;
|
||||
m_visited_end = lim;
|
||||
m_visited.reset();
|
||||
}
|
||||
else {
|
||||
m_visited_begin = m_visited_end;
|
||||
m_visited_end = m_visited_end + lim;
|
||||
}
|
||||
while (m_visited.size() < n)
|
||||
m_visited.push_back(0);
|
||||
}
|
||||
|
||||
void mark_visited(unsigned v) { m_visited[v] = m_visited_begin + 1; }
|
||||
void inc_visited(unsigned v) {
|
||||
m_visited[v] = std::min(m_visited_end, std::max(m_visited_begin, m_visited[v]) + 1);
|
||||
}
|
||||
bool is_visited(unsigned v) const { return m_visited[v] > m_visited_begin; }
|
||||
unsigned num_visited(unsigned v) { return std::max(m_visited_begin, m_visited[v]) - m_visited_begin; }
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue