summaryrefslogtreecommitdiff
path: root/src/util/integer_cln_imp.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/integer_cln_imp.h')
-rw-r--r--src/util/integer_cln_imp.h493
1 files changed, 157 insertions, 336 deletions
diff --git a/src/util/integer_cln_imp.h b/src/util/integer_cln_imp.h
index ff4bcdf69..29a5248e3 100644
--- a/src/util/integer_cln_imp.h
+++ b/src/util/integer_cln_imp.h
@@ -5,7 +5,7 @@
** Tim King, Gereon Kremer, Morgan Deters
** This file is part of the CVC4 project.
** Copyright (c) 2009-2020 by the authors listed in the file AUTHORS
- ** in the top-level source directory) and their institutional affiliations.
+ ** in the top-level source directory and their institutional affiliations.
** All rights reserved. See the file COPYING in the top-level source
** directory for licensing information.\endverbatim
**
@@ -58,6 +58,10 @@ class CVC4_PUBLIC Integer
parseInt(std::string(sp), base);
}
+ /**
+ * Constructs a Integer from a C++ string.
+ * Throws std::invalid_argument if the string is not a valid integer.
+ */
explicit Integer(const std::string& s, unsigned base = 10)
{
parseInt(s, base);
@@ -75,154 +79,96 @@ class CVC4_PUBLIC Integer
Integer(uint64_t z) : d_value(static_cast<unsigned long>(z)) {}
#endif /* CVC4_NEED_INT64_T_OVERLOADS */
+ /** Destructor. */
~Integer() {}
- /**
- * Returns a copy of d_value to enable public access of CLN data.
- */
+ /** Returns a copy of d_value to enable public access of CLN data. */
const cln::cl_I& getValue() const { return d_value; }
- Integer& operator=(const Integer& x)
- {
- if (this == &x) return *this;
- d_value = x.d_value;
- return *this;
- }
-
- bool operator==(const Integer& y) const { return d_value == y.d_value; }
-
- Integer operator-() const { return Integer(-(d_value)); }
-
- bool operator!=(const Integer& y) const { return d_value != y.d_value; }
-
- bool operator<(const Integer& y) const { return d_value < y.d_value; }
-
- bool operator<=(const Integer& y) const { return d_value <= y.d_value; }
-
- bool operator>(const Integer& y) const { return d_value > y.d_value; }
-
- bool operator>=(const Integer& y) const { return d_value >= y.d_value; }
-
- Integer operator+(const Integer& y) const
- {
- return Integer(d_value + y.d_value);
- }
- Integer& operator+=(const Integer& y)
- {
- d_value += y.d_value;
- return *this;
- }
-
- Integer operator-(const Integer& y) const
- {
- return Integer(d_value - y.d_value);
- }
- Integer& operator-=(const Integer& y)
- {
- d_value -= y.d_value;
- return *this;
- }
-
- Integer operator*(const Integer& y) const
- {
- return Integer(d_value * y.d_value);
- }
-
- Integer& operator*=(const Integer& y)
- {
- d_value *= y.d_value;
- return *this;
- }
-
- Integer bitwiseOr(const Integer& y) const
- {
- return Integer(cln::logior(d_value, y.d_value));
- }
-
- Integer bitwiseAnd(const Integer& y) const
- {
- return Integer(cln::logand(d_value, y.d_value));
- }
-
- Integer bitwiseXor(const Integer& y) const
- {
- return Integer(cln::logxor(d_value, y.d_value));
- }
-
- Integer bitwiseNot() const { return Integer(cln::lognot(d_value)); }
+ /** Overload copy assignment operator. */
+ Integer& operator=(const Integer& x);
+
+ /** Overload equality comparison operator. */
+ bool operator==(const Integer& y) const;
+ /** Overload disequality comparison operator. */
+ bool operator!=(const Integer& y) const;
+ /** Overload less than comparison operator. */
+ bool operator<(const Integer& y) const;
+ /** Overload less than or equal comparison operator. */
+ bool operator<=(const Integer& y) const;
+ /** Overload greater than comparison operator. */
+ bool operator>(const Integer& y) const;
+ /** Overload greater than or equal comparison operator. */
+ bool operator>=(const Integer& y) const;
+
+ /** Overload negation operator. */
+ Integer operator-() const;
+ /** Overload addition operator. */
+ Integer operator+(const Integer& y) const;
+ /** Overload addition assignment operator. */
+ Integer& operator+=(const Integer& y);
+ /** Overload subtraction operator. */
+ Integer operator-(const Integer& y) const;
+ /** Overload subtraction assignment operator. */
+ Integer& operator-=(const Integer& y);
+ /** Overload multiplication operator. */
+ Integer operator*(const Integer& y) const;
+ /** Overload multiplication assignment operator. */
+ Integer& operator*=(const Integer& y);
+
+ /** Return the bit-wise or of this and the given Integer. */
+ Integer bitwiseOr(const Integer& y) const;
+ /** Return the bit-wise and of this and the given Integer. */
+ Integer bitwiseAnd(const Integer& y) const;
+ /** Return the bit-wise exclusive or of this and the given Integer. */
+ Integer bitwiseXor(const Integer& y) const;
+ /** Return the bit-wise not of this Integer. */
+ Integer bitwiseNot() const;
+
+ /** Return this*(2^pow). */
+ Integer multiplyByPow2(uint32_t pow) const;
+
+ /** Return true if bit at index 'i' is 1, and false otherwise. */
+ bool isBitSet(uint32_t i) const;
/**
- * Return this*(2^pow).
+ * Returns the Integer obtained by setting the ith bit of the
+ * current Integer to 1.
*/
- Integer multiplyByPow2(uint32_t pow) const
- {
- cln::cl_I ipow(pow);
- return Integer(d_value << ipow);
- }
-
- bool isBitSet(uint32_t i) const { return !extractBitRange(1, i).isZero(); }
-
- Integer setBit(uint32_t i) const
- {
- cln::cl_I mask(1);
- mask = mask << i;
- return Integer(cln::logior(d_value, mask));
- }
+ Integer setBit(uint32_t i, bool value) const;
+ /**
+ * Returns the integer with the binary representation of 'size' bits
+ * extended with 'amount' 1's.
+ */
Integer oneExtend(uint32_t size, uint32_t amount) const;
- uint32_t toUnsignedInt() const { return cln::cl_I_to_uint(d_value); }
-
- /** See CLN Documentation. */
- Integer extractBitRange(uint32_t bitCount, uint32_t low) const
- {
- cln::cl_byte range(bitCount, low);
- return Integer(cln::ldb(d_value, range));
- }
+ /** Return a 32 bit unsigned integer representation of this Integer. */
+ uint32_t toUnsignedInt() const;
/**
- * Returns the floor(this / y)
+ * Extract a range of bits from index 'low' to (excluding) 'low + bitCount'.
+ * Note: corresponds to the extract operator of theory BV.
*/
- Integer floorDivideQuotient(const Integer& y) const
- {
- return Integer(cln::floor1(d_value, y.d_value));
- }
+ Integer extractBitRange(uint32_t bitCount, uint32_t low) const;
- /**
- * Returns r == this - floor(this/y)*y
- */
- Integer floorDivideRemainder(const Integer& y) const
- {
- return Integer(cln::floor2(d_value, y.d_value).remainder);
- }
- /**
- * Computes a floor quoient and remainder for x divided by y.
- */
+ /** Returns the floor(this / y). */
+ Integer floorDivideQuotient(const Integer& y) const;
+
+ /** Returns r == this - floor(this/y)*y. */
+ Integer floorDivideRemainder(const Integer& y) const;
+
+ /** Computes a floor quoient and remainder for x divided by y. */
static void floorQR(Integer& q,
Integer& r,
const Integer& x,
- const Integer& y)
- {
- cln::cl_I_div_t res = cln::floor2(x.d_value, y.d_value);
- q.d_value = res.quotient;
- r.d_value = res.remainder;
- }
+ const Integer& y);
- /**
- * Returns the ceil(this / y)
- */
- Integer ceilingDivideQuotient(const Integer& y) const
- {
- return Integer(cln::ceiling1(d_value, y.d_value));
- }
+ /** Returns the ceil(this / y). */
+ Integer ceilingDivideQuotient(const Integer& y) const;
- /**
- * Returns the ceil(this / y)
- */
- Integer ceilingDivideRemainder(const Integer& y) const
- {
- return Integer(cln::ceiling2(d_value, y.d_value).remainder);
- }
+ /** Returns the ceil(this / y). */
+ Integer ceilingDivideRemainder(const Integer& y) const;
/**
* Computes a quoitent and remainder according to Boute's Euclidean
@@ -236,71 +182,28 @@ class CVC4_PUBLIC Integer
static void euclidianQR(Integer& q,
Integer& r,
const Integer& x,
- const Integer& y)
- {
- // compute the floor and then fix the value up if needed.
- floorQR(q, r, x, y);
-
- if (r.strictlyNegative())
- {
- // if r < 0
- // abs(r) < abs(y)
- // - abs(y) < r < 0, then 0 < r + abs(y) < abs(y)
- // n = y * q + r
- // n = y * q - abs(y) + r + abs(y)
- if (r.sgn() >= 0)
- {
- // y = abs(y)
- // n = y * q - y + r + y
- // n = y * (q-1) + (r+y)
- q -= 1;
- r += y;
- }
- else
- {
- // y = -abs(y)
- // n = y * q + y + r - y
- // n = y * (q+1) + (r-y)
- q += 1;
- r -= y;
- }
- }
- }
+ const Integer& y);
/**
* Returns the quoitent according to Boute's Euclidean definition.
* See the documentation for euclidianQR.
*/
- Integer euclidianDivideQuotient(const Integer& y) const
- {
- Integer q, r;
- euclidianQR(q, r, *this, y);
- return q;
- }
+ Integer euclidianDivideQuotient(const Integer& y) const;
/**
* Returns the remainfing according to Boute's Euclidean definition.
* See the documentation for euclidianQR.
*/
- Integer euclidianDivideRemainder(const Integer& y) const
- {
- Integer q, r;
- euclidianQR(q, r, *this, y);
- return r;
- }
+ Integer euclidianDivideRemainder(const Integer& y) const;
- /**
- * If y divides *this, then exactQuotient returns (this/y)
- */
+ /** If y divides *this, then exactQuotient returns (this/y). */
Integer exactQuotient(const Integer& y) const;
- Integer modByPow2(uint32_t exp) const
- {
- cln::cl_byte range(exp, 0);
- return Integer(cln::ldb(d_value, range));
- }
+ /** Return y mod 2^exp. */
+ Integer modByPow2(uint32_t exp) const;
- Integer divByPow2(uint32_t exp) const { return d_value >> exp; }
+ /** Returns y / 2^exp. */
+ Integer divByPow2(uint32_t exp) const;
/**
* Raise this Integer to the power <code>exp</code>.
@@ -309,32 +212,16 @@ class CVC4_PUBLIC Integer
*/
Integer pow(unsigned long int exp) const;
- /**
- * Return the greatest common divisor of this integer with another.
- */
- Integer gcd(const Integer& y) const
- {
- cln::cl_I result = cln::gcd(d_value, y.d_value);
- return Integer(result);
- }
+ /** Return the greatest common divisor of this integer with another. */
+ Integer gcd(const Integer& y) const;
- /**
- * Return the least common multiple of this integer with another.
- */
- Integer lcm(const Integer& y) const
- {
- cln::cl_I result = cln::lcm(d_value, y.d_value);
- return Integer(result);
- }
+ /** Return the least common multiple of this integer with another. */
+ Integer lcm(const Integer& y) const;
- /**
- * Compute addition of this Integer x + y modulo m.
- */
+ /** Compute addition of this Integer x + y modulo m. */
Integer modAdd(const Integer& y, const Integer& m) const;
- /**
- * Compute multiplication of this Integer x * y modulo m.
- */
+ /** Compute multiplication of this Integer x * y modulo m. */
Integer modMultiply(const Integer& y, const Integer& m) const;
/**
@@ -351,102 +238,62 @@ class CVC4_PUBLIC Integer
*/
Integer modInverse(const Integer& m) const;
- /**
- * Return true if *this exactly divides y.
- */
- bool divides(const Integer& y) const
- {
- cln::cl_I result = cln::rem(y.d_value, d_value);
- return cln::zerop(result);
- }
+ /** Return true if *this exactly divides y. */
+ bool divides(const Integer& y) const;
- /**
- * Return the absolute value of this integer.
- */
- Integer abs() const { return d_value >= 0 ? *this : -*this; }
+ /** Return the absolute value of this integer. */
+ Integer abs() const;
- std::string toString(int base = 10) const
- {
- std::stringstream ss;
- switch (base)
- {
- case 2: fprintbinary(ss, d_value); break;
- case 8: fprintoctal(ss, d_value); break;
- case 10: fprintdecimal(ss, d_value); break;
- case 16: fprinthexadecimal(ss, d_value); break;
- default: throw Exception("Unhandled base in Integer::toString()");
- }
- std::string output = ss.str();
- for (unsigned i = 0; i <= output.length(); ++i)
- {
- if (isalpha(output[i]))
- {
- output.replace(i, 1, 1, tolower(output[i]));
- }
- }
-
- return output;
- }
+ /** Return a string representation of this Integer. */
+ std::string toString(int base = 10) const;
- int sgn() const
- {
- cln::cl_I sgn = cln::signum(d_value);
- return cln::cl_I_to_int(sgn);
- }
+ /** Return 1 if this is > 0, 0 if it is 0, and -1 if it is < 0. */
+ int sgn() const;
- inline bool strictlyPositive() const { return sgn() > 0; }
+ /** Return true if this is > 0. */
+ bool strictlyPositive() const;
- inline bool strictlyNegative() const { return sgn() < 0; }
+ /** Return true if this is < 0. */
+ bool strictlyNegative() const;
- inline bool isZero() const { return sgn() == 0; }
+ /** Return true if this is 0. */
+ bool isZero() const;
- inline bool isOne() const { return d_value == 1; }
+ /** Return true if this is 1. */
+ bool isOne() const;
- inline bool isNegativeOne() const { return d_value == -1; }
+ /** Return true if this is -1. */
+ bool isNegativeOne() const;
- /** fits the C "signed int" primitive */
+ /** Return true if this Integer fits into a signed int. */
bool fitsSignedInt() const;
- /** fits the C "unsigned int" primitive */
+ /** Return true if this Integer fits into an unsigned int. */
bool fitsUnsignedInt() const;
+ /** Return the signed int representation of this Integer. */
int getSignedInt() const;
+ /** Return the unsigned int representation of this Integer. */
unsigned int getUnsignedInt() const;
+ /** Return true if this Integer fits into a signed long. */
bool fitsSignedLong() const;
+ /** Return true if this Integer fits into an unsigned long. */
bool fitsUnsignedLong() const;
- long getLong() const
- {
- // ensure there isn't overflow
- CheckArgument(d_value <= std::numeric_limits<long>::max(),
- this,
- "Overflow detected in Integer::getLong()");
- CheckArgument(d_value >= std::numeric_limits<long>::min(),
- this,
- "Overflow detected in Integer::getLong()");
- return cln::cl_I_to_long(d_value);
- }
+ /** Return the signed long representation of this Integer. */
+ long getLong() const;
- unsigned long getUnsignedLong() const
- {
- // ensure there isn't overflow
- CheckArgument(d_value <= std::numeric_limits<unsigned long>::max(),
- this,
- "Overflow detected in Integer::getUnsignedLong()");
- CheckArgument(d_value >= std::numeric_limits<unsigned long>::min(),
- this,
- "Overflow detected in Integer::getUnsignedLong()");
- return cln::cl_I_to_ulong(d_value);
- }
+ /** Return the unsigned long representation of this Integer. */
+ unsigned long getUnsignedLong() const;
/**
* Computes the hash of the node from the first word of the
* numerator, the denominator.
*/
- size_t hash() const { return equal_hashcode(d_value); }
+ size_t hash() const;
/**
* Returns true iff bit n is set.
@@ -454,46 +301,19 @@ class CVC4_PUBLIC Integer
* @param n the bit to test (0 == least significant bit)
* @return true if bit n is set in this integer; false otherwise
*/
- bool testBit(unsigned n) const { return cln::logbitp(n, d_value); }
+ bool testBit(unsigned n) const;
/**
* Returns k if the integer is equal to 2^(k-1)
* @return k if the integer is equal to 2^(k-1) and 0 otherwise
*/
- unsigned isPow2() const
- {
- if (d_value <= 0) return 0;
- // power2p returns n such that d_value = 2^(n-1)
- return cln::power2p(d_value);
- }
+ unsigned isPow2() const;
/**
* If x != 0, returns the unique n s.t. 2^{n-1} <= abs(x) < 2^{n}.
* If x == 0, returns 1.
*/
- size_t length() const
- {
- int s = sgn();
- if (s == 0)
- {
- return 1;
- }
- else if (s < 0)
- {
- size_t len = cln::integer_length(d_value);
- /*If this is -2^n, return len+1 not len to stay consistent with the
- * definition above! From CLN's documentation of integer_length: This is
- * the smallest n >= 0 such that -2^n <= x < 2^n. If x > 0, this is the
- * unique n > 0 such that 2^(n-1) <= x < 2^n.
- */
- size_t ord2 = cln::ord2(d_value);
- return (len == ord2) ? (len + 1) : len;
- }
- else
- {
- return cln::integer_length(d_value);
- }
- }
+ size_t length() const;
/* cl_I xgcd (const cl_I& a, const cl_I& b, cl_I* u, cl_I* v) */
/* This function ("extended gcd") returns the greatest common divisor g of a
@@ -503,22 +323,13 @@ class CVC4_PUBLIC Integer
* sense: If a and b are non-zero, and abs(a) != abs(b), u and v will satisfy
* the inequalities abs(u) <= abs(b)/(2*g), abs(v) <= abs(a)/(2*g). */
static void extendedGcd(
- Integer& g, Integer& s, Integer& t, const Integer& a, const Integer& b)
- {
- g.d_value = cln::xgcd(a.d_value, b.d_value, &s.d_value, &t.d_value);
- }
+ Integer& g, Integer& s, Integer& t, const Integer& a, const Integer& b);
/** Returns a reference to the minimum of two integers. */
- static const Integer& min(const Integer& a, const Integer& b)
- {
- return (a <= b) ? a : b;
- }
+ static const Integer& min(const Integer& a, const Integer& b);
/** Returns a reference to the maximum of two integers. */
- static const Integer& max(const Integer& a, const Integer& b)
- {
- return (a >= b) ? a : b;
- }
+ static const Integer& max(const Integer& a, const Integer& b);
private:
/**
@@ -526,45 +337,55 @@ class CVC4_PUBLIC Integer
* Only accessible to friend classes.
*/
const cln::cl_I& get_cl_I() const { return d_value; }
- // Throws a std::invalid_argument on invalid input `s` for the given base.
+
+ /**
+ * Helper for parseInt.
+ * Throws a std::invalid_argument on invalid input `s` for the given base.
+ */
void readInt(const cln::cl_read_flags& flags,
const std::string& s,
unsigned base);
- // Throws a std::invalid_argument on invalid inputs.
+ /**
+ * Parse string representation of integer into this Integer.
+ * Throws a std::invalid_argument on invalid inputs.
+ */
void parseInt(const std::string& s, unsigned base);
- // These constants are to help with CLN conversion in 32 bit.
- // See http://www.ginac.de/CLN/cln.html#Conversions
- static signed int s_fastSignedIntMax; /* 2^29 - 1 */
- static signed int s_fastSignedIntMin; /* -2^29 */
- static unsigned int s_fastUnsignedIntMax; /* 2^29 - 1 */
-
- static signed long
- s_slowSignedIntMax; /* std::numeric_limits<signed int>::max() */
- static signed long
- s_slowSignedIntMin; /* std::numeric_limits<signed int>::min() */
- static unsigned long
- s_slowUnsignedIntMax; /* std::numeric_limits<unsigned int>::max() */
+ /**
+ * The following constants are to help with CLN conversion in 32 bit.
+ * See http://www.ginac.de/CLN/cln.html#Conversions.
+ */
+
+ /** 2^29 - 1 */
+ static signed int s_fastSignedIntMax;
+ /** -2^29 */
+ static signed int s_fastSignedIntMin;
+ /** 2^29 - 1 */
+ static unsigned int s_fastUnsignedIntMax;
+ /** std::numeric_limits<signed int>::max() */
+ static signed long s_slowSignedIntMax;
+ /** std::numeric_limits<signed int>::min() */
+ static signed long s_slowSignedIntMin;
+ /** std::numeric_limits<unsigned int>::max() */
+ static unsigned long s_slowUnsignedIntMax;
+ /** std::numeric_limits<signed long>::min() */
static unsigned long s_signedLongMin;
+ /** std::numeric_limits<signed long>::max() */
static unsigned long s_signedLongMax;
+ /** std::numeric_limits<unsigned long>::max() */
static unsigned long s_unsignedLongMax;
- /**
- * Stores the value of the rational is stored in a C++ CLN integer class.
- */
+ /** Value of the rational is stored in a C++ CLN integer class. */
cln::cl_I d_value;
}; /* class Integer */
struct IntegerHashFunction
{
- inline size_t operator()(const CVC4::Integer& i) const { return i.hash(); }
+ size_t operator()(const CVC4::Integer& i) const { return i.hash(); }
}; /* struct IntegerHashFunction */
-inline std::ostream& operator<<(std::ostream& os, const Integer& n)
-{
- return os << n.toString();
-}
+std::ostream& operator<<(std::ostream& os, const Integer& n);
} // namespace CVC4
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback