This PR adds the convenience function NodeManager::mkRealAlgebraicNumber().
#include "theory/type_enumerator.h"
#include "util/abstract_value.h"
#include "util/bitvector.h"
+#include "util/poly_util.h"
#include "util/rational.h"
#include "util/resource_manager.h"
return mkConstInt(r);
}
+Node NodeManager::mkRealAlgebraicNumber(const RealAlgebraicNumber& ran)
+{
+ if (ran.isRational())
+ {
+ return mkConstReal(ran.toRational());
+ }
+ return mkNode(Kind::REAL_ALGEBRAIC_NUMBER,
+ mkConst(Kind::REAL_ALGEBRAIC_NUMBER_OP, ran));
+}
+
} // namespace cvc5
*/
Node mkConstRealOrInt(const TypeNode& tn, const Rational& r);
+ /**
+ * Make a real algebraic number node from a RealAlgebraicNumber.
+ * If the real algebraic number is found to be rational, this method returns a
+ * node of kind CONST_RATIONAL. Otherwise, it returns a node of kind
+ * REAL_ALGEBRIAC_NUMBER.
+ *
+ * It is, unfortunately, not entirely possible to provide the usual uniqueness
+ * guarantees for real algebraic number nodes. As a REAL_ALGEBRIAC_NUMBER node
+ * may turn out to be rational later on, it may be semantically equal to a
+ * CONST_RATIONAL node, although the comparison operator would always return
+ * false. For this reason, comparisons should be performed by evaluating (i.e.
+ * rewriting) the EQUAL predicate, or by inspecting the values manually. Note
+ * that the comparison operators for RealAlgebraicNumber properly support
+ * Rational as well.
+ */
+ Node mkRealAlgebraicNumber(const RealAlgebraicNumber& ran);
+
/** Create a node with children. */
TypeNode mkTypeNode(Kind kind, TypeNode child1);
TypeNode mkTypeNode(Kind kind, TypeNode child1, TypeNode child2);
constant REAL_ALGEBRAIC_NUMBER_OP \
class \
- RealAlgebraicNumber \
+ RealAlgebraicNumber+ \
::cvc5::RealAlgebraicNumberHashFunction \
"util/real_algebraic_number.h" \
"a real algebraic number constant; payload is an instance of the cvc5::RealAlgebraicNumber class"
#include "base/check.h"
#include "util/poly_util.h"
+#define RAN_UNREACHABLE \
+ Unreachable() << "RealAlgebraicNumber is not available without libpoly."
+
namespace cvc5 {
RealAlgebraicNumber::RealAlgebraicNumber(poly::AlgebraicNumber&& an)
poly::UPolynomial(std::move(coeffs)), lower, upper);
}
+bool RealAlgebraicNumber::isRational() const
+{
+#ifdef CVC5_POLY_IMP
+ return poly::is_rational(getValue());
+#else
+ RAN_UNREACHABLE;
+ return true;
+#endif
+}
+Rational RealAlgebraicNumber::toRational() const
+{
+#ifdef CVC5_POLY_IMP
+ return poly_utils::toRational(poly::to_rational_approximation(getValue()));
+#else
+ RAN_UNREACHABLE;
+ return Rational(0);
+#endif
+}
+
std::ostream& operator<<(std::ostream& os, const RealAlgebraicNumber& ran)
{
return os << ran.getValue();
Assert(!isZero(rhs)) << "Can not divide by zero";
return lhs.getValue() / rhs.getValue();
#else
+ RAN_UNREACHABLE;
return lhs;
#endif
}
Assert(!isZero(ran)) << "Can not invert zero";
return inverse(ran.getValue());
#else
+ RAN_UNREACHABLE;
return ran;
#endif
}
#ifdef CVC5_POLY_IMP
return lp_algebraic_number_hash_approx(ran.getValue().get_internal(), 2);
#else
+ RAN_UNREACHABLE;
return 0;
#endif
}
/** Get the internal value as a non-const reference. */
poly::AlgebraicNumber& getValue() { return d_value; }
+ /**
+ * Check if this real algebraic number is actually rational.
+ * If true, the value is rational and toRational() can safely be called.
+ * If false, the value may still be rational, but was not recognized as
+ * such yet.
+ */
+ bool isRational() const;
+ /**
+ * Returns the stored value as a rational.
+ * The value is exact if isRational() returns true, otherwise it may only be a
+ * rational approximation (of unknown precision).
+ */
+ Rational toRational() const;
+
private:
/**
* Stores the actual real algebraic number.