3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-21 05:13:39 +00:00

avoid going creating hnf_cuts if all involved vars have integral values

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

add explanations to hnf cuts

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

nits and virtual methods (#68)

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

cleanup from std::cout

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

handle the case when the number of terms is greater than the number of variables in hnf

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

method name's fix

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

restore hnf_cutter to work with m_row_count <= m_column_count

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

tune addition of rational numbers (#70)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

give shorter explanations, call hnf only when have a not integral var

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

overhaul of mpq (#71)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

fix for 32 bit build (#72)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

yes (#74)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* more refactor

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

fix the merge

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fixes in maximize_term untested

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>

fix compilation (#75)

* log quantifiers only if present

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge and fix some warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* set new arith as default for LIA

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* local

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* virtual method in bound propagator

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* prepare for mixed integer-real

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix default tactic usage

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* overhaul of mpz/mpq

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* disabled temporary setting

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* remove prints

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* customize for 64 bit

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* more refactor

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* relax check

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* change for gcc

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* merge

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Lev Nachmanson 2018-05-31 10:37:22 -07:00
parent 9be49ff6ff
commit 9ba4026bc6
41 changed files with 942 additions and 1280 deletions

View file

@ -64,6 +64,7 @@ class mpz_cell {
digit_t m_digits[0];
friend class mpz_manager<true>;
friend class mpz_manager<false>;
friend class mpz_stack;
};
#else
#include<gmp.h>
@ -72,17 +73,25 @@ class mpz_cell {
/**
\brief Multi-precision integer.
If m_ptr == 0, the it is a small number and the value is stored at m_val.
Otherwise, m_val contains the sign (-1 negative, 1 positive), and m_ptr points to a mpz_cell that
store the value. <<< This last statement is true only in Windows.
If m_kind == mpz_small, it is a small number and the value is stored in m_val.
If m_kind == mpz_ptr, the value is stored in m_ptr and m_ptr != nullptr.
m_val contains the sign (-1 negative, 1 positive)
under winodws, m_ptr points to a mpz_cell that store the value.
*/
enum mpz_kind { mpz_small = 0, mpz_ptr = 1};
enum mpz_owner { mpz_self = 0, mpz_ext = 1};
class mpz {
int m_val;
#ifndef _MP_GMP
mpz_cell * m_ptr;
typedef mpz_cell mpz_type;
#else
mpz_t * m_ptr;
typedef mpz_t mpz_type;
#endif
int m_val;
unsigned m_kind:1;
unsigned m_owner:1;
mpz_type * m_ptr;
friend class mpz_manager<true>;
friend class mpz_manager<false>;
friend class mpq_manager<true>;
@ -90,19 +99,38 @@ class mpz {
friend class mpq;
friend class mpbq;
friend class mpbq_manager;
friend class mpz_stack;
mpz & operator=(mpz const & other) { UNREACHABLE(); return *this; }
public:
mpz(int v):m_val(v), m_ptr(nullptr) {}
mpz():m_val(0), m_ptr(nullptr) {}
mpz(mpz && other) : m_val(other.m_val), m_ptr(nullptr) {
mpz(int v):m_val(v), m_kind(mpz_small), m_owner(mpz_self), m_ptr(nullptr) {}
mpz():m_val(0), m_kind(mpz_small), m_owner(mpz_self), m_ptr(nullptr) {}
mpz(mpz_type* ptr): m_val(0), m_kind(mpz_small), m_owner(mpz_ext), m_ptr(ptr) { SASSERT(ptr);}
mpz(mpz && other) : m_val(other.m_val), m_kind(mpz_small), m_owner(mpz_self), m_ptr(nullptr) {
std::swap(m_ptr, other.m_ptr);
unsigned o = m_owner; m_owner = other.m_owner; other.m_owner = o;
unsigned k = m_kind; m_kind = other.m_kind; other.m_kind = k;
}
void swap(mpz & other) {
std::swap(m_val, other.m_val);
std::swap(m_ptr, other.m_ptr);
unsigned o = m_owner; m_owner = other.m_owner; other.m_owner = o;
unsigned k = m_kind; m_kind = other.m_kind; other.m_kind = k;
}
};
#ifndef _MP_GMP
class mpz_stack : public mpz {
static const unsigned capacity = 8;
unsigned char m_bytes[sizeof(mpz_cell) + sizeof(digit_t) * capacity];
public:
mpz_stack():mpz(reinterpret_cast<mpz_cell*>(m_bytes)) {
m_ptr->m_capacity = capacity;
}
};
#else
class mpz_stack : public mpz {};
#endif
inline void swap(mpz & m1, mpz & m2) { m1.swap(m2); }
template<bool SYNCH = true>
@ -115,57 +143,56 @@ class mpz_manager {
#ifndef _MP_GMP
unsigned m_init_cell_capacity;
mpz_cell * m_tmp[2];
mpz_cell * m_arg[2];
mpz m_int_min;
static unsigned cell_size(unsigned capacity) { return sizeof(mpz_cell) + sizeof(digit_t) * capacity; }
static unsigned cell_size(unsigned capacity) {
return sizeof(mpz_cell) + sizeof(digit_t) * capacity;
}
mpz_cell * allocate(unsigned capacity) {
SASSERT(capacity >= m_init_cell_capacity);
MPZ_BEGIN_CRITICAL();
mpz_cell * cell = reinterpret_cast<mpz_cell *>(m_allocator.allocate(cell_size(capacity)));
MPZ_END_CRITICAL();
cell->m_capacity = capacity;
return cell;
}
void deallocate(mpz& n) {
if (n.m_ptr) {
deallocate(n.m_owner == mpz_self, n.m_ptr);
n.m_ptr = nullptr;
n.m_kind = mpz_small;
}
}
// make sure that n is a big number and has capacity equal to at least c.
void allocate_if_needed(mpz & n, unsigned c) {
if (c < m_init_cell_capacity)
c = m_init_cell_capacity;
if (is_small(n)) {
c = std::max(c, m_init_cell_capacity);
if (n.m_ptr == nullptr || capacity(n) < c) {
deallocate(n);
n.m_val = 1;
n.m_kind = mpz_ptr;
n.m_owner = mpz_self;
n.m_ptr = allocate(c);
n.m_ptr->m_capacity = c;
}
else if (capacity(n) < c) {
deallocate(n.m_ptr);
n.m_val = 1;
n.m_ptr = allocate(c);
n.m_ptr->m_capacity = c;
}
}
void deallocate(mpz_cell * ptr) {
m_allocator.deallocate(cell_size(ptr->m_capacity), ptr);
}
/**
\brief Make sure that m_tmp[IDX] can hold the given number of digits
*/
template<int IDX>
void ensure_tmp_capacity(unsigned capacity) {
if (m_tmp[IDX]->m_capacity >= capacity)
return;
deallocate(m_tmp[IDX]);
unsigned new_capacity = (3 * capacity + 1) >> 1;
m_tmp[IDX] = allocate(new_capacity);
SASSERT(m_tmp[IDX]->m_capacity >= capacity);
void deallocate(bool is_heap, mpz_cell * ptr) {
if (is_heap) {
MPZ_BEGIN_CRITICAL();
m_allocator.deallocate(cell_size(ptr->m_capacity), ptr);
MPZ_END_CRITICAL();
}
}
// Expand capacity of a while preserving its content.
void ensure_capacity(mpz & a, unsigned sz);
void normalize(mpz & a);
void clear(mpz& n) { }
#else
// GMP code
mpz_t m_tmp, m_tmp2;
@ -175,22 +202,34 @@ class mpz_manager {
mpz_t m_int64_max;
mpz_t m_int64_min;
mpz_t * allocate() {
mpz_t * allocate() {
MPZ_BEGIN_CRITICAL();
mpz_t * cell = reinterpret_cast<mpz_t*>(m_allocator.allocate(sizeof(mpz_t)));
MPZ_END_CRITICAL();
mpz_init(*cell);
return cell;
}
void deallocate(mpz_t * ptr) { mpz_clear(*ptr); m_allocator.deallocate(sizeof(mpz_t), ptr); }
void deallocate(bool is_heap, mpz_t * ptr) {
mpz_clear(*ptr);
if (is_heap) {
MPZ_BEGIN_CRITICAL();
m_allocator.deallocate(sizeof(mpz_t), ptr);
MPZ_END_CRITICAL();
}
}
void clear(mpz& n) { if (n.m_ptr) mpz_clear(n.m_ptr); }
#endif
mpz m_two64;
/**
\brief Set \c a with the value stored at m_tmp[IDX], and the given sign.
\c sz is an overapproximation of the size of the number stored at \c tmp.
\brief Set \c a with the value stored at src, and the given sign.
\c sz is an overapproximation of the size of the number stored at \c src.
*/
template<int IDX>
void set(mpz & a, int sign, unsigned sz);
void set(mpz_cell& src, mpz & a, int sign, unsigned sz);
static int64_t i64(mpz const & a) { return static_cast<int64_t>(a.m_val); }
@ -198,19 +237,19 @@ class mpz_manager {
void set_i64(mpz & c, int64_t v) {
if (v >= INT_MIN && v <= INT_MAX) {
del(c);
c.m_val = static_cast<int>(v);
c.m_kind = mpz_small;
}
else {
MPZ_BEGIN_CRITICAL();
set_big_i64(c, v);
MPZ_END_CRITICAL();
}
}
void set_big_ui64(mpz & c, uint64_t v);
#ifndef _MP_GMP
static unsigned capacity(mpz const & c) { return c.m_ptr->m_capacity; }
static unsigned size(mpz const & c) { return c.m_ptr->m_size; }
@ -241,16 +280,28 @@ class mpz_manager {
return ((static_cast<uint64_t>(digits(a)[1]) << 32) | (static_cast<uint64_t>(digits(a)[0])));
}
template<int IDX>
void get_sign_cell(mpz const & a, int & sign, mpz_cell * & cell) {
class sign_cell {
static const unsigned capacity = 2;
unsigned char m_bytes[sizeof(mpz_cell) + sizeof(digit_t) * capacity];
mpz m_local;
mpz const& m_a;
int m_sign;
mpz_cell* m_cell;
public:
sign_cell(mpz_manager& m, mpz const& a);
int sign() { return m_sign; }
mpz_cell const* cell() { return m_cell; }
};
void get_sign_cell(mpz const & a, int & sign, mpz_cell * & cell, mpz_cell* reserve) {
if (is_small(a)) {
if (a.m_val == INT_MIN) {
sign = -1;
cell = m_int_min.m_ptr;
}
else {
cell = m_arg[IDX];
SASSERT(cell->m_size == 1);
cell = reserve;
cell->m_size = 1;
if (a.m_val < 0) {
sign = -1;
cell->m_digits[0] = -a.m_val;
@ -266,26 +317,29 @@ class mpz_manager {
cell = a.m_ptr;
}
}
#else
// GMP code
template<int IDX>
void get_arg(mpz const & a, mpz_t * & result) {
if (is_small(a)) {
result = m_arg[IDX];
mpz_set_si(*result, a.m_val);
}
else {
result = a.m_ptr;
}
}
class ensure_mpz_t {
mpz_t m_local;
mpz_t* m_result;
public:
ensure_mpz_t(mpz const& a);
~ensure_mpz_t();
mpz_t& operator()() { return *m_result; }
};
void mk_big(mpz & a) {
if (a.m_ptr == 0) {
if (a.m_ptr == null) {
a.m_val = 0;
a.m_ptr = allocate();
a.m_owner = mpz_self;
}
a.m_kind = mpz_ptr;
}
#endif
#ifndef _MP_GMP
@ -333,245 +387,49 @@ public:
~mpz_manager();
static bool is_small(mpz const & a) { return a.m_ptr == nullptr; }
static bool is_small(mpz const & a) { return a.m_kind == mpz_small; }
static mpz mk_z(int val) { return mpz(val); }
void del(mpz & a) {
if (a.m_ptr != nullptr) {
MPZ_BEGIN_CRITICAL();
deallocate(a.m_ptr);
MPZ_END_CRITICAL();
a.m_ptr = nullptr;
}
}
void del(mpz & a);
void add(mpz const & a, mpz const & b, mpz & c) {
STRACE("mpz", tout << "[mpz] " << to_string(a) << " + " << to_string(b) << " == ";);
if (is_small(a) && is_small(b)) {
set_i64(c, i64(a) + i64(b));
}
else {
MPZ_BEGIN_CRITICAL();
big_add(a, b, c);
MPZ_END_CRITICAL();
}
STRACE("mpz", tout << to_string(c) << "\n";);
}
void add(mpz const & a, mpz const & b, mpz & c);
void sub(mpz const & a, mpz const & b, mpz & c) {
STRACE("mpz", tout << "[mpz] " << to_string(a) << " - " << to_string(b) << " == ";);
if (is_small(a) && is_small(b)) {
set_i64(c, i64(a) - i64(b));
}
else {
MPZ_BEGIN_CRITICAL();
big_sub(a, b, c);
MPZ_END_CRITICAL();
}
STRACE("mpz", tout << to_string(c) << "\n";);
}
void sub(mpz const & a, mpz const & b, mpz & c);
void inc(mpz & a) { add(a, mpz(1), a); }
void dec(mpz & a) { add(a, mpz(-1), a); }
void mul(mpz const & a, mpz const & b, mpz & c) {
STRACE("mpz", tout << "[mpz] " << to_string(a) << " * " << to_string(b) << " == ";);
if (is_small(a) && is_small(b)) {
set_i64(c, i64(a) * i64(b));
}
else {
MPZ_BEGIN_CRITICAL();
big_mul(a, b, c);
MPZ_END_CRITICAL();
}
STRACE("mpz", tout << to_string(c) << "\n";);
}
void mul(mpz const & a, mpz const & b, mpz & c);
// d <- a + b*c
void addmul(mpz const & a, mpz const & b, mpz const & c, mpz & d) {
if (is_one(b)) {
add(a, c, d);
}
else if (is_minus_one(b)) {
sub(a, c, d);
}
else {
mpz tmp;
mul(b,c,tmp);
add(a,tmp,d);
del(tmp);
}
}
void addmul(mpz const & a, mpz const & b, mpz const & c, mpz & d);
// d <- a - b*c
void submul(mpz const & a, mpz const & b, mpz const & c, mpz & d) {
if (is_one(b)) {
sub(a, c, d);
}
else if (is_minus_one(b)) {
add(a, c, d);
}
else {
mpz tmp;
mul(b,c,tmp);
sub(a,tmp,d);
del(tmp);
}
}
void submul(mpz const & a, mpz const & b, mpz const & c, mpz & d);
void machine_div_rem(mpz const & a, mpz const & b, mpz & q, mpz & r);
void machine_div_rem(mpz const & a, mpz const & b, mpz & q, mpz & r) {
STRACE("mpz", tout << "[mpz-ext] divrem(" << to_string(a) << ", " << to_string(b) << ") == ";);
if (is_small(a) && is_small(b)) {
int64_t _a = i64(a);
int64_t _b = i64(b);
set_i64(q, _a / _b);
set_i64(r, _a % _b);
}
else {
MPZ_BEGIN_CRITICAL();
big_div_rem(a, b, q, r);
MPZ_END_CRITICAL();
}
STRACE("mpz", tout << "(" << to_string(q) << ", " << to_string(r) << ")\n";);
}
void machine_div(mpz const & a, mpz const & b, mpz & c);
void machine_div(mpz const & a, mpz const & b, mpz & c) {
STRACE("mpz", tout << "[mpz-ext] machine-div(" << to_string(a) << ", " << to_string(b) << ") == ";);
if (is_small(a) && is_small(b)) {
set_i64(c, i64(a) / i64(b));
}
else {
MPZ_BEGIN_CRITICAL();
big_div(a, b, c);
MPZ_END_CRITICAL();
}
STRACE("mpz", tout << to_string(c) << "\n";);
}
void rem(mpz const & a, mpz const & b, mpz & c);
void rem(mpz const & a, mpz const & b, mpz & c) {
STRACE("mpz", tout << "[mpz-ext] rem(" << to_string(a) << ", " << to_string(b) << ") == ";);
if (is_small(a) && is_small(b)) {
set_i64(c, i64(a) % i64(b));
}
else {
MPZ_BEGIN_CRITICAL();
big_rem(a, b, c);
MPZ_END_CRITICAL();
}
STRACE("mpz", tout << to_string(c) << "\n";);
}
void div_gcd(mpz const & a, mpz const & b, mpz & c);
void div(mpz const & a, mpz const & b, mpz & c) {
STRACE("mpz", tout << "[mpz-ext] div(" << to_string(a) << ", " << to_string(b) << ") == ";);
if (is_neg(a)) {
mpz tmp;
machine_div_rem(a, b, c, tmp);
if (!is_zero(tmp)) {
if (is_neg(b))
add(c, mk_z(1), c);
else
sub(c, mk_z(1), c);
}
del(tmp);
}
else {
machine_div(a, b, c);
}
STRACE("mpz", tout << to_string(c) << "\n";);
}
void div(mpz const & a, mpz const & b, mpz & c);
void mod(mpz const & a, mpz const & b, mpz & c) {
STRACE("mpz", tout << "[mpz-ext] mod(" << to_string(a) << ", " << to_string(b) << ") == ";);
rem(a, b, c);
if (is_neg(c)) {
if (is_pos(b))
add(c, b, c);
else
sub(c, b, c);
}
STRACE("mpz", tout << to_string(c) << "\n";);
}
void mod(mpz const & a, mpz const & b, mpz & c);
void neg(mpz & a) {
STRACE("mpz", tout << "[mpz] 0 - " << to_string(a) << " == ";);
if (is_small(a) && a.m_val == INT_MIN) {
// neg(INT_MIN) is not a small int
MPZ_BEGIN_CRITICAL();
set_big_i64(a, - static_cast<long long>(INT_MIN));
MPZ_END_CRITICAL();
return;
}
#ifndef _MP_GMP
a.m_val = -a.m_val;
#else
if (is_small(a)) {
a.m_val = -a.m_val;
}
else {
mpz_neg(*a.m_ptr, *a.m_ptr);
}
#endif
STRACE("mpz", tout << to_string(a) << "\n";);
}
void neg(mpz & a);
void abs(mpz & a) {
if (is_small(a)) {
if (a.m_val < 0) {
if (a.m_val == INT_MIN) {
// abs(INT_MIN) is not a small int
MPZ_BEGIN_CRITICAL();
set_big_i64(a, - static_cast<long long>(INT_MIN));
MPZ_END_CRITICAL();
}
else
a.m_val = -a.m_val;
}
}
else {
#ifndef _MP_GMP
a.m_val = 1;
#else
mpz_abs(*a.m_ptr, *a.m_ptr);
#endif
}
}
void abs(mpz & a);
static bool is_pos(mpz const & a) {
#ifndef _MP_GMP
return a.m_val > 0;
#else
if (is_small(a))
return a.m_val > 0;
else
return mpz_sgn(*a.m_ptr) > 0;
#endif
}
static bool is_pos(mpz const & a) { return sign(a) > 0; }
static bool is_neg(mpz const & a) {
#ifndef _MP_GMP
return a.m_val < 0;
#else
if (is_small(a))
return a.m_val < 0;
else
return mpz_sgn(*a.m_ptr) < 0;
#endif
}
static bool is_neg(mpz const & a) { return sign(a) < 0; }
static bool is_zero(mpz const & a) {
#ifndef _MP_GMP
return a.m_val == 0;
#else
if (is_small(a))
return a.m_val == 0;
else
return mpz_sgn(*a.m_ptr) == 0;
#endif
}
static bool is_zero(mpz const & a) { return sign(a) == 0; }
static int sign(mpz const & a) {
#ifndef _MP_GMP
@ -593,10 +451,7 @@ public:
return a.m_val == b.m_val;
}
else {
MPZ_BEGIN_CRITICAL();
bool res = big_compare(a, b) == 0;
MPZ_END_CRITICAL();
return res;
return big_compare(a, b) == 0;
}
}
@ -614,10 +469,7 @@ public:
return a.m_val < b.m_val;
}
else {
MPZ_BEGIN_CRITICAL();
bool res = big_compare(a, b) < 0;
MPZ_END_CRITICAL();
return res;
return big_compare(a, b) < 0;
}
}
@ -661,25 +513,24 @@ public:
void set(mpz & target, mpz const & source) {
if (is_small(source)) {
del(target);
target.m_val = source.m_val;
target.m_kind = mpz_small;
}
else {
MPZ_BEGIN_CRITICAL();
big_set(target, source);
MPZ_END_CRITICAL();
}
}
void set(mpz & target, mpz && source) {
del(target);
target.m_val = source.m_val;
std::swap(target.m_ptr, source.m_ptr);
auto o = target.m_owner; target.m_owner = source.m_owner; source.m_owner = o;
auto k = target.m_kind; target.m_kind = source.m_kind; source.m_kind = k;
}
void set(mpz & a, int val) {
del(a);
a.m_val = val;
a.m_kind = mpz_small;
}
void set(mpz & a, unsigned val) {
@ -697,17 +548,15 @@ public:
void set(mpz & a, uint64_t val) {
if (val < INT_MAX) {
del(a);
a.m_val = static_cast<int>(val);
a.m_kind = mpz_small;
}
else {
MPZ_BEGIN_CRITICAL();
set_big_ui64(a, val);
MPZ_END_CRITICAL();
}
}
void set(mpz & target, unsigned sz, digit_t const * digits);
void set_digits(mpz & target, unsigned sz, digit_t const * digits);
mpz dup(const mpz & source) {
mpz temp;
@ -716,13 +565,15 @@ public:
}
void reset(mpz & a) {
del(a);
a.m_val = 0;
a.m_kind = mpz_small;
}
void swap(mpz & a, mpz & b) {
std::swap(a.m_val, b.m_val);
std::swap(a.m_ptr, b.m_ptr);
auto o = a.m_owner; a.m_owner = b.m_owner; b.m_owner = o;
auto k = a.m_kind; a.m_kind = b.m_kind; b.m_kind = k;
}
bool is_uint64(mpz const & a) const;