From 42115e41ad464744c7f409149a3afc06e3f77f98 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Fri, 24 Oct 2025 17:49:33 -0700 Subject: [PATCH 01/15] Make context object copyable. --- include/polyxx/context.h | 11 +++++++++++ src/polyxx/context.cpp | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/polyxx/context.h b/include/polyxx/context.h index a1b21106..0c234f33 100644 --- a/include/polyxx/context.h +++ b/include/polyxx/context.h @@ -19,7 +19,18 @@ namespace poly { deleting_unique_ptr mPolynomialContext; public: + /** Constructs a new (empty) context */ Context(); + + /** Wraps the lp context. */ + explicit Context(lp_polynomial_context_t *ctx); + + /** Copy constructor. */ + Context(const Context& other); + + /** No assignment as this would mess with internal reference counting. */ + Context& operator=(const Context& other) = delete; + /** Get a non-const pointer to the internal lp_variable_db_t. * Handle with care! */ diff --git a/src/polyxx/context.cpp b/src/polyxx/context.cpp index bad8945a..e2f8e7c2 100644 --- a/src/polyxx/context.cpp +++ b/src/polyxx/context.cpp @@ -16,6 +16,25 @@ namespace poly { lp_polynomial_context_detach(ptr); }); } + + Context::Context(lp_polynomial_context_t *ctx) { + mVariableDB = deleting_unique_ptr( + ctx->var_db, + [](lp_variable_db_t *ptr) { lp_variable_db_detach(ptr); }); + mVariableOrder = deleting_unique_ptr( + ctx->var_order, + [](lp_variable_order_t *ptr) { lp_variable_order_detach(ptr); }); + mPolynomialContext = deleting_unique_ptr( + ctx, + [](lp_polynomial_context_t *ptr) { lp_polynomial_context_detach(ptr); }); + + lp_variable_db_attach(ctx->var_db); + lp_variable_order_attach(ctx->var_order); + lp_polynomial_context_attach(ctx); + } + + Context::Context(const Context& other) : Context(other.get_polynomial_context()) {} + lp_variable_db_t* Context::get_variable_db() const { return const_cast(mVariableDB.get()); } From 909719bb208edc315fff6c3849235746498ce332 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Fri, 24 Oct 2025 14:41:19 -0700 Subject: [PATCH 02/15] Adding +=, -=, and *= of polynomial with integer to avoid implicit constructor call of polynomial and potential issues with context missmatch. --- include/polyxx/polynomial.h | 6 ++++++ src/polyxx/polynomial.cpp | 35 ++++++++++++++++++++++++++--------- 2 files changed, 32 insertions(+), 9 deletions(-) diff --git a/include/polyxx/polynomial.h b/include/polyxx/polynomial.h index fd4f8e68..1c72bf89 100644 --- a/include/polyxx/polynomial.h +++ b/include/polyxx/polynomial.h @@ -151,6 +151,8 @@ namespace poly { Polynomial operator+(const Integer& lhs, const Polynomial& rhs); /** Add and assign two polynomials. */ Polynomial& operator+=(Polynomial& lhs, const Polynomial& rhs); + /** Add and assign a polynomial with an integer. */ + Polynomial& operator+=(Polynomial& lhs, const Integer& rhs); /** Compute lhs += rhs1 * rhs2. */ Polynomial& add_mul(Polynomial& lhs, const Polynomial& rhs1, const Polynomial& rhs2); @@ -164,6 +166,8 @@ namespace poly { Polynomial operator-(const Integer& lhs, const Polynomial& rhs); /** Subtract and assign two polynomials. */ Polynomial& operator-=(Polynomial& lhs, const Polynomial& rhs); + /** Subtract and assigns a polynomial with an integer. */ + Polynomial& operator-=(Polynomial& lhs, const Integer& rhs); /** Compute lhs -= rhs1 * rhs2. */ Polynomial& sub_mul(Polynomial& lhs, const Polynomial& rhs1, const Polynomial& rhs2); @@ -175,6 +179,8 @@ namespace poly { Polynomial operator*(const Integer& lhs, const Polynomial& rhs); /** Multiply and assign two polynomials. */ Polynomial& operator*=(Polynomial& lhs, const Polynomial& rhs); + /** Multiply and assign a polynomial with an integer */ + Polynomial& operator*=(Polynomial& lhs, const Integer& rhs); /** Multiply with x^n where x is the main variable. */ Polynomial shl(const Polynomial& lhs, unsigned n); diff --git a/src/polyxx/polynomial.cpp b/src/polyxx/polynomial.cpp index 87f33fd0..a1e85d5e 100644 --- a/src/polyxx/polynomial.cpp +++ b/src/polyxx/polynomial.cpp @@ -187,23 +187,30 @@ namespace poly { return res; } Polynomial operator+(const Polynomial& lhs, const Integer& rhs) { - lp_monomial_t monomial; - lp_monomial_construct(detail::context(lhs), &monomial); - lp_monomial_set_coefficient(detail::context(lhs), &monomial, - rhs.get_internal()); Polynomial res(lhs); - lp_polynomial_add_monomial(res.get_internal(), &monomial); - lp_monomial_destruct(&monomial); + res += rhs; return res; } Polynomial operator+(const Integer& lhs, const Polynomial& rhs) { - return rhs + lhs; + Polynomial res(rhs); + res += lhs; + return res; } Polynomial& operator+=(Polynomial& lhs, const Polynomial& rhs) { lp_polynomial_add(lhs.get_internal(), lhs.get_internal(), rhs.get_internal()); return lhs; } + Polynomial& operator+=(Polynomial& lhs, const Integer& rhs) { + lp_monomial_t monomial; + lp_monomial_construct(detail::context(lhs), &monomial); + lp_monomial_set_coefficient(detail::context(lhs), &monomial, + rhs.get_internal()); + lp_polynomial_add_monomial(lhs.get_internal(), &monomial); + lp_monomial_destruct(&monomial); + return lhs; + } + Polynomial& add_mul(Polynomial& lhs, const Polynomial& rhs1, const Polynomial& rhs2) { lp_polynomial_add_mul(lhs.get_internal(), rhs1.get_internal(), @@ -233,6 +240,11 @@ namespace poly { rhs.get_internal()); return lhs; } + Polynomial& operator-=(Polynomial& lhs, const Integer& rhs) { + lhs += (-rhs); + return lhs; + } + Polynomial& sub_mul(Polynomial& lhs, const Polynomial& rhs1, const Polynomial& rhs2) { lp_polynomial_sub_mul(lhs.get_internal(), rhs1.get_internal(), @@ -260,6 +272,11 @@ namespace poly { rhs.get_internal()); return lhs; } + Polynomial& operator*=(Polynomial& lhs, const Integer& rhs) { + lp_polynomial_mul_integer(lhs.get_internal(), lhs.get_internal(), + rhs.get_internal()); + return lhs; + } Polynomial shl(const Polynomial& lhs, unsigned exp) { Polynomial res(detail::context(lhs)); @@ -368,8 +385,8 @@ namespace poly { } Polynomial discriminant(const Polynomial& p) { if (degree(p) == 1) { - // Derivative is constant, making the resultant trivial (and resultant() - // does not cope with that) + // Derivative is constant, making the resultant trivial + // (and resultant() does not cope with that) // This creates the constant polynomial 1 in the context of p. return Polynomial(detail::context(p)) + Integer(1); } From 85d4ce3bf1051242f2ef9e0ec74f54468f66df0d Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Fri, 24 Oct 2025 18:02:26 -0700 Subject: [PATCH 03/15] Adding ==, !=, <, <=, >, and >= between Polynomial and Integer. --- include/polyxx/polynomial.h | 18 ++++++++++-- src/polyxx/polynomial.cpp | 57 +++++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 7 deletions(-) diff --git a/include/polyxx/polynomial.h b/include/polyxx/polynomial.h index 1c72bf89..022df87c 100644 --- a/include/polyxx/polynomial.h +++ b/include/polyxx/polynomial.h @@ -43,10 +43,12 @@ namespace poly { /** Construct i * v^n. */ Polynomial(const Integer& i, Variable v, unsigned n); + /** Construct a constant polynomial from an internal context pointer. */ + Polynomial(const lp_polynomial_context_t* c, const Integer& i); /** Construct from an integer and a custom context. */ - Polynomial(const Context& c, const Integer& i); + Polynomial(const Context& c, const Integer &i); /** Construct from an integer. */ - Polynomial(const Integer& i); + Polynomial(const Integer &i); /** Construct from an integer and a custom context. */ Polynomial(const Context& c, long i); @@ -132,16 +134,28 @@ namespace poly { /** Compare polynomials. */ bool operator==(const Polynomial& lhs, const Polynomial& rhs); + bool operator==(const Integer& lhs, const Polynomial& rhs); + bool operator==(const Polynomial& lhs, const Integer& rhs); /** Compare polynomials. */ bool operator!=(const Polynomial& lhs, const Polynomial& rhs); + bool operator!=(const Integer& lhs, const Polynomial& rhs); + bool operator!=(const Polynomial& lhs, const Integer& rhs); /** Compare polynomials. */ bool operator<(const Polynomial& lhs, const Polynomial& rhs); + bool operator<(const Integer& lhs, const Polynomial& rhs); + bool operator<(const Polynomial& lhs, const Integer& rhs); /** Compare polynomials. */ bool operator<=(const Polynomial& lhs, const Polynomial& rhs); + bool operator<=(const Integer& lhs, const Polynomial& rhs); + bool operator<=(const Polynomial& lhs, const Integer& rhs); /** Compare polynomials. */ bool operator>(const Polynomial& lhs, const Polynomial& rhs); + bool operator>(const Integer& lhs, const Polynomial& rhs); + bool operator>(const Polynomial& lhs, const Integer& rhs); /** Compare polynomials. */ bool operator>=(const Polynomial& lhs, const Polynomial& rhs); + bool operator>=(const Integer& lhs, const Polynomial& rhs); + bool operator>=(const Polynomial& lhs, const Integer& rhs); /** Add two polynomials. */ Polynomial operator+(const Polynomial& lhs, const Polynomial& rhs); diff --git a/src/polyxx/polynomial.cpp b/src/polyxx/polynomial.cpp index a1e85d5e..1c76f03a 100644 --- a/src/polyxx/polynomial.cpp +++ b/src/polyxx/polynomial.cpp @@ -46,11 +46,13 @@ namespace poly { } Polynomial::Polynomial(const Integer& i, Variable v, unsigned n) : Polynomial(Context::get_context(), i, v, n) {} - Polynomial::Polynomial(const Context& c, const Integer& i) + + Polynomial::Polynomial(const lp_polynomial_context_t* c, const Integer & i) : mPoly(lp_polynomial_alloc(), polynomial_deleter) { - lp_polynomial_construct_simple(get_internal(), c.get_polynomial_context(), + lp_polynomial_construct_simple(get_internal(), c, i.get_internal(), lp_variable_null, 0); } + Polynomial::Polynomial(const Context& c, const Integer& i) : Polynomial(c.get_polynomial_context(), i) {} Polynomial::Polynomial(const Integer& i) : Polynomial(Context::get_context(), i){}; Polynomial::Polynomial(const Context& c, long i) : Polynomial(c, Integer(i)) {} @@ -164,21 +166,67 @@ namespace poly { bool operator==(const Polynomial& lhs, const Polynomial& rhs) { return lp_polynomial_eq(lhs.get_internal(), rhs.get_internal()); } + bool operator==(const Polynomial& lhs, const Integer& rhs) { + Polynomial tmp(detail::context(lhs), rhs); + return lp_polynomial_eq(lhs.get_internal(), tmp.get_internal()); + } + bool operator==(const Integer& lhs, const Polynomial& rhs) { + Polynomial tmp(detail::context(rhs), lhs); + return lp_polynomial_eq(tmp.get_internal(), rhs.get_internal()); + } bool operator!=(const Polynomial& lhs, const Polynomial& rhs) { return !(lhs == rhs); } + bool operator!=(const Polynomial& lhs, const Integer& rhs) { + return !(lhs == rhs); + } + bool operator!=(const Integer& lhs, const Polynomial& rhs) { + return !(lhs == rhs); + } bool operator<(const Polynomial& lhs, const Polynomial& rhs) { return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) < 0; } + bool operator<(const Polynomial& lhs, const Integer& rhs) { + Polynomial tmp(detail::context(lhs), rhs); + return lp_polynomial_cmp(lhs.get_internal(), tmp.get_internal()) < 0; + } + bool operator<(const Integer& lhs, const Polynomial& rhs) { + Polynomial tmp(detail::context(rhs), lhs); + return lp_polynomial_cmp(tmp.get_internal(), rhs.get_internal()) < 0; + } bool operator<=(const Polynomial& lhs, const Polynomial& rhs) { return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) <= 0; } + bool operator<=(const Polynomial& lhs, const Integer& rhs) { + Polynomial tmp(detail::context(lhs), rhs); + return lp_polynomial_cmp(lhs.get_internal(), tmp.get_internal()) <= 0; + } + bool operator<=(const Integer& lhs, const Polynomial& rhs) { + Polynomial tmp(detail::context(rhs), lhs); + return lp_polynomial_cmp(tmp.get_internal(), rhs.get_internal()) <= 0; + } bool operator>(const Polynomial& lhs, const Polynomial& rhs) { return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) > 0; } + bool operator>(const Polynomial& lhs, const Integer& rhs) { + Polynomial tmp(detail::context(lhs), rhs); + return lp_polynomial_cmp(lhs.get_internal(), tmp.get_internal()) > 0; + } + bool operator>(const Integer& lhs, const Polynomial& rhs) { + Polynomial tmp(detail::context(rhs), lhs); + return lp_polynomial_cmp(tmp.get_internal(), rhs.get_internal()) > 0; + } bool operator>=(const Polynomial& lhs, const Polynomial& rhs) { return lp_polynomial_cmp(lhs.get_internal(), rhs.get_internal()) >= 0; } + bool operator>=(const Polynomial& lhs, const Integer& rhs) { + Polynomial tmp(detail::context(lhs), rhs); + return lp_polynomial_cmp(lhs.get_internal(), tmp.get_internal()) >= 0; + } + bool operator>=(const Integer& lhs, const Polynomial& rhs) { + Polynomial tmp(detail::context(rhs), lhs); + return lp_polynomial_cmp(tmp.get_internal(), rhs.get_internal()) >= 0; + } Polynomial operator+(const Polynomial& lhs, const Polynomial& rhs) { Polynomial res(detail::context(lhs, rhs)); @@ -233,7 +281,7 @@ namespace poly { return lhs + (-rhs); } Polynomial operator-(const Integer& lhs, const Polynomial& rhs) { - return -rhs + lhs; + return (-rhs) + lhs; } Polynomial& operator-=(Polynomial& lhs, const Polynomial& rhs) { lp_polynomial_sub(lhs.get_internal(), lhs.get_internal(), @@ -387,8 +435,7 @@ namespace poly { if (degree(p) == 1) { // Derivative is constant, making the resultant trivial // (and resultant() does not cope with that) - // This creates the constant polynomial 1 in the context of p. - return Polynomial(detail::context(p)) + Integer(1); + return Polynomial(detail::context(p), Integer(1)); } return div(resultant(p, derivative(p)), leading_coefficient(p)); } From 49267106daf3e0ab47ab3a303bb8f485f370f9f8 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Mon, 27 Oct 2025 15:23:41 -0700 Subject: [PATCH 04/15] typos --- include/polyxx/dyadic_interval.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/polyxx/dyadic_interval.h b/include/polyxx/dyadic_interval.h index 6836e048..27716c19 100644 --- a/include/polyxx/dyadic_interval.h +++ b/include/polyxx/dyadic_interval.h @@ -58,11 +58,11 @@ namespace poly { /** Collapse this interval to a single point. */ void collapse(const DyadicRational& dr); - /** The the lower bound. */ + /** The lower bound. */ void set_lower(const DyadicRational& dr, bool open); - /** The the upper bound. */ + /** The upper bound. */ void set_upper(const DyadicRational& dr, bool open); - /** The this interval by 2^n. */ + /** The interval by 2^n. */ void scale(int n); }; From d86b9f8e04d7e3c573a6d5d8fdb0884385534575 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Mon, 27 Oct 2025 15:24:05 -0700 Subject: [PATCH 05/15] missing constructor in dyadic_rational --- include/polyxx/dyadic_rational.h | 2 ++ src/polyxx/dyadic_rational.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/include/polyxx/dyadic_rational.h b/include/polyxx/dyadic_rational.h index a8be408d..8ef68a29 100644 --- a/include/polyxx/dyadic_rational.h +++ b/include/polyxx/dyadic_rational.h @@ -31,6 +31,8 @@ namespace poly { explicit DyadicRational(double d); /** Construct from an int. */ DyadicRational(int i); + /** Construct from a long. */ + DyadicRational(long i); /** Construct from an internal lp_dyadic_rational_t pointer. */ explicit DyadicRational(const lp_dyadic_rational_t* dr); diff --git a/src/polyxx/dyadic_rational.cpp b/src/polyxx/dyadic_rational.cpp index c80273a3..e77873b8 100644 --- a/src/polyxx/dyadic_rational.cpp +++ b/src/polyxx/dyadic_rational.cpp @@ -25,6 +25,7 @@ namespace poly { lp_dyadic_rational_construct_from_double(&mDRat, d); } DyadicRational::DyadicRational(int i) : DyadicRational(i, 0) {} + DyadicRational::DyadicRational(long i) : DyadicRational(i, 0) {} DyadicRational::DyadicRational(const lp_dyadic_rational_t* dr) { lp_dyadic_rational_construct_copy(&mDRat, dr); From acf9d05b5aca7902c9680b50a9608b4a33682e23 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Mon, 27 Oct 2025 15:24:46 -0700 Subject: [PATCH 06/15] added missing comparison for Integer --- include/polyxx/integer.h | 12 ++++++++++++ src/polyxx/integer.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/include/polyxx/integer.h b/include/polyxx/integer.h index b4e22d9d..d22531f2 100644 --- a/include/polyxx/integer.h +++ b/include/polyxx/integer.h @@ -122,16 +122,28 @@ namespace poly { /** Compare two integers. */ bool operator==(const Integer& lhs, const Integer& rhs); + bool operator==(const Integer& lhs, long rhs); + bool operator==(long lhs, const Integer& rhs); /** Compare two integers. */ bool operator!=(const Integer& lhs, const Integer& rhs); + bool operator!=(const Integer& lhs, long rhs); + bool operator!=(long lhs, const Integer& rhs); /** Compare two integers according to the lexicographic ordering on (lower bound,upper bound). */ bool operator<(const Integer& lhs, const Integer& rhs); + bool operator<(const Integer& lhs, long rhs); + bool operator<(long lhs, const Integer& rhs); /** Compare two integers according to the lexicographic ordering on (lower bound,upper bound). */ bool operator<=(const Integer& lhs, const Integer& rhs); + bool operator<=(const Integer& lhs, long rhs); + bool operator<=(long lhs, const Integer& rhs); /** Compare two integers according to the lexicographic ordering on (lower bound,upper bound). */ bool operator>(const Integer& lhs, const Integer& rhs); + bool operator>(const Integer& lhs, long rhs); + bool operator>(long lhs, const Integer& rhs); /** Compare two integers according to the lexicographic ordering on (lower bound,upper bound). */ bool operator>=(const Integer& lhs, const Integer& rhs); + bool operator>=(const Integer& lhs, long rhs); + bool operator>=(long lhs, const Integer& rhs); /** Compare two integers over the given ring. */ int compare(const IntegerRing& ir, const Integer& lhs, const Integer& rhs); diff --git a/src/polyxx/integer.cpp b/src/polyxx/integer.cpp index 5067a2c5..ec33f561 100644 --- a/src/polyxx/integer.cpp +++ b/src/polyxx/integer.cpp @@ -80,21 +80,57 @@ namespace poly { bool operator==(const Integer& lhs, const Integer& rhs) { return compare(IntegerRing::Z, lhs, rhs) == 0; } + bool operator==(const Integer& lhs, long rhs) { + return compare(IntegerRing::Z, lhs, rhs) == 0; + } + bool operator==(long lhs, const Integer& rhs) { + return compare(IntegerRing::Z, lhs, rhs) == 0; + } bool operator!=(const Integer& lhs, const Integer& rhs) { return compare(IntegerRing::Z, lhs, rhs) != 0; } + bool operator!=(const Integer& lhs, long rhs) { + return compare(IntegerRing::Z, lhs, rhs) != 0; + } + bool operator!=(long lhs, const Integer& rhs) { + return compare(IntegerRing::Z, lhs, rhs) != 0; + } bool operator<(const Integer& lhs, const Integer& rhs) { return compare(IntegerRing::Z, lhs, rhs) < 0; } + bool operator<(const Integer& lhs, long rhs) { + return compare(IntegerRing::Z, lhs, rhs) < 0; + } + bool operator<(long lhs, const Integer& rhs) { + return compare(IntegerRing::Z, lhs, rhs) < 0; + } bool operator<=(const Integer& lhs, const Integer& rhs) { return compare(IntegerRing::Z, lhs, rhs) <= 0; } + bool operator<=(const Integer& lhs, long rhs) { + return compare(IntegerRing::Z, lhs, rhs) <= 0; + } + bool operator<=(long lhs, const Integer& rhs) { + return compare(IntegerRing::Z, lhs, rhs) <= 0; + } bool operator>(const Integer& lhs, const Integer& rhs) { return compare(IntegerRing::Z, lhs, rhs) > 0; } + bool operator>(const Integer& lhs, long rhs) { + return compare(IntegerRing::Z, lhs, rhs) > 0; + } + bool operator>(long lhs, const Integer& rhs) { + return compare(IntegerRing::Z, lhs, rhs) > 0; + } bool operator>=(const Integer& lhs, const Integer& rhs) { return compare(IntegerRing::Z, lhs, rhs) >= 0; } + bool operator>=(const Integer& lhs, long rhs) { + return compare(IntegerRing::Z, lhs, rhs) >= 0; + } + bool operator>=(long lhs, const Integer& rhs) { + return compare(IntegerRing::Z, lhs, rhs) >= 0; + } int compare(const IntegerRing& ir, const Integer& lhs, const Integer& rhs) { return lp_integer_cmp(ir.get_internal(), lhs.get_internal(), From 11a1bb6bc7afebad9dec9a6b9b6c23b7384632fb Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Mon, 27 Oct 2025 15:33:46 -0700 Subject: [PATCH 07/15] add missing constructor for dyadic_interval --- include/polyxx/dyadic_interval.h | 10 ++++++---- src/polyxx/dyadic_interval.cpp | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/polyxx/dyadic_interval.h b/include/polyxx/dyadic_interval.h index 27716c19..08961ee6 100644 --- a/include/polyxx/dyadic_interval.h +++ b/include/polyxx/dyadic_interval.h @@ -33,12 +33,14 @@ namespace poly { /** Construct an open interval. */ DyadicInterval(const Integer& a, const Integer& b); /** Construct an interval from the given bounds. */ - DyadicInterval(const Integer& a, bool a_open, const Integer& b, - bool b_open); + DyadicInterval(const Integer& a, bool a_open, + const Integer& b, bool b_open); + /** Construct a point interval. */ + explicit DyadicInterval(long i); /** Construct an open interval. */ - DyadicInterval(long a, long b); + explicit DyadicInterval(long a, long b); /** Construct an interval from the given bounds. */ - DyadicInterval(long a, bool a_open, long b, bool b_open); + explicit DyadicInterval(long a, bool a_open, long b, bool b_open); /** Copy from a DyadicInterval. */ DyadicInterval(const DyadicInterval& i); /** Move from a DyadicInterval. */ diff --git a/src/polyxx/dyadic_interval.cpp b/src/polyxx/dyadic_interval.cpp index c2d27a4a..f3b06428 100644 --- a/src/polyxx/dyadic_interval.cpp +++ b/src/polyxx/dyadic_interval.cpp @@ -27,6 +27,8 @@ namespace poly { lp_dyadic_interval_construct_from_integer(get_internal(), a.get_internal(), a_open, b.get_internal(), b_open); } + DyadicInterval::DyadicInterval(long i) + : DyadicInterval(DyadicRational(i)) {} DyadicInterval::DyadicInterval(long a, long b) : DyadicInterval(a, true, b, true) {} DyadicInterval::DyadicInterval(long a, bool a_open, long b, bool b_open) { From 26297e1f67da5509cfecd0b6c5b2c93c132bae79 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Mon, 27 Oct 2025 15:46:22 -0700 Subject: [PATCH 08/15] Removed constructors Polynomial(int) but made Integer(int) implicit. --- include/polyxx/integer.h | 4 ++-- include/polyxx/polynomial.h | 5 ----- src/polyxx/polynomial.cpp | 3 --- 3 files changed, 2 insertions(+), 10 deletions(-) diff --git a/include/polyxx/integer.h b/include/polyxx/integer.h index d22531f2..a3f8c3e4 100644 --- a/include/polyxx/integer.h +++ b/include/polyxx/integer.h @@ -22,9 +22,9 @@ namespace poly { /** Constructs zero. */ Integer(); /** Constructs from an int. */ - explicit Integer(int i); + Integer(int i); /** Constructs from a long. */ - explicit Integer(long i); + Integer(long i); /** Constructs from a long into the given ring. */ Integer(const IntegerRing& ir, long i); /** Constructs from a string. */ diff --git a/include/polyxx/polynomial.h b/include/polyxx/polynomial.h index 022df87c..92e2cf73 100644 --- a/include/polyxx/polynomial.h +++ b/include/polyxx/polynomial.h @@ -50,11 +50,6 @@ namespace poly { /** Construct from an integer. */ Polynomial(const Integer &i); - /** Construct from an integer and a custom context. */ - Polynomial(const Context& c, long i); - /** Construct from an integer. */ - Polynomial(long i); - /** Copy from a Polynomial. */ Polynomial(const Polynomial& p); /** Move from a Polynomial. */ diff --git a/src/polyxx/polynomial.cpp b/src/polyxx/polynomial.cpp index 1c76f03a..8889fa17 100644 --- a/src/polyxx/polynomial.cpp +++ b/src/polyxx/polynomial.cpp @@ -54,9 +54,6 @@ namespace poly { } Polynomial::Polynomial(const Context& c, const Integer& i) : Polynomial(c.get_polynomial_context(), i) {} Polynomial::Polynomial(const Integer& i) : Polynomial(Context::get_context(), i){}; - Polynomial::Polynomial(const Context& c, long i) - : Polynomial(c, Integer(i)) {} - Polynomial::Polynomial(long i) : Polynomial(Context::get_context(), i){}; Polynomial::Polynomial(const Polynomial& p) : mPoly(lp_polynomial_new_copy(p.get_internal()), polynomial_deleter) {} From f6e4d0e5fd7b67bc1eff3d887d3dcedb3d0ea28d Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Mon, 27 Oct 2025 18:46:03 -0700 Subject: [PATCH 09/15] adding lp_variable_db_is_valid --- include/variable_db.h | 3 +++ src/variable/variable_db.c | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/include/variable_db.h b/include/variable_db.h index 57dff087..dd2f026d 100644 --- a/include/variable_db.h +++ b/include/variable_db.h @@ -46,6 +46,9 @@ int lp_variable_db_print(const lp_variable_db_t* var_db, FILE* out); /** Get the name of the variable */ const char* lp_variable_db_get_name(const lp_variable_db_t* var_db, lp_variable_t var); +/** Checks if var is a valid index */ +int lp_variable_db_is_valid(const lp_variable_db_t* var_db, lp_variable_t var); + #ifdef __cplusplus } /* close extern "C" { */ #endif diff --git a/src/variable/variable_db.c b/src/variable/variable_db.c index 60f3df4c..eeb82327 100644 --- a/src/variable/variable_db.c +++ b/src/variable/variable_db.c @@ -127,3 +127,7 @@ const char* lp_variable_db_get_name(const lp_variable_db_t* var_db, lp_variable_ assert(var < var_db->size); return var_db->variable_names[var]; } + +int lp_variable_db_is_valid(const lp_variable_db_t* var_db, lp_variable_t var) { + return var < var_db->size; +} From d7f46430a37b409fe3bfc6647fa236954d466146 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Tue, 28 Oct 2025 15:18:41 -0700 Subject: [PATCH 10/15] Improved constructors of Polynomial --- include/polyxx/polynomial.h | 12 ++++++++---- src/polyxx/polynomial.cpp | 23 +++++++++++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/include/polyxx/polynomial.h b/include/polyxx/polynomial.h index 92e2cf73..a1814e06 100644 --- a/include/polyxx/polynomial.h +++ b/include/polyxx/polynomial.h @@ -33,15 +33,19 @@ namespace poly { /** Construct a zero polynomial. */ Polynomial(); + /** Construct a constant polynomial from an internal context pointer. */ + Polynomial(const lp_polynomial_context_t* c, const Variable& v); /** Construct from a variable and a custom context. */ - Polynomial(const Context& c, Variable v); + Polynomial(const Context& c, const Variable& v); /** Construct from a variable. */ - Polynomial(Variable v); + Polynomial(const Variable& v); + /** Construct a constant polynomial from an internal context pointer. */ + Polynomial(const lp_polynomial_context_t* c, const Integer& i, const Variable& v, unsigned n); /** Construct i * v^n from a custom context. */ - Polynomial(const Context& c, const Integer& i, Variable v, unsigned n); + Polynomial(const Context& c, const Integer& i, const Variable& v, unsigned n); /** Construct i * v^n. */ - Polynomial(const Integer& i, Variable v, unsigned n); + Polynomial(const Integer& i, const Variable& v, unsigned n); /** Construct a constant polynomial from an internal context pointer. */ Polynomial(const lp_polynomial_context_t* c, const Integer& i); diff --git a/src/polyxx/polynomial.cpp b/src/polyxx/polynomial.cpp index 8889fa17..57e9441a 100644 --- a/src/polyxx/polynomial.cpp +++ b/src/polyxx/polynomial.cpp @@ -36,15 +36,26 @@ namespace poly { : Polynomial(c.get_polynomial_context()) {} Polynomial::Polynomial() : Polynomial(Context::get_context()) {} - Polynomial::Polynomial(const Context& c, Variable v) - : Polynomial(c, Integer(1), v, 1) {} - Polynomial::Polynomial(Variable v) : Polynomial(Context::get_context(), v) {} - Polynomial::Polynomial(const Context& c, const Integer &i, Variable v, unsigned n) + Polynomial::Polynomial(const lp_polynomial_context_t* c, const Variable& v) : mPoly(lp_polynomial_alloc(), polynomial_deleter) { - lp_polynomial_construct_simple(get_internal(), c.get_polynomial_context(), + assert(lp_variable_db_is_valid(c->var_db, v.get_internal())); + lp_polynomial_construct_simple(get_internal(), c, + Integer(1).get_internal(), + v.get_internal(), 1); + } + Polynomial::Polynomial(const Context& c, const Variable& v) + : Polynomial(c.get_polynomial_context(), v) {} + Polynomial::Polynomial(const Variable& v) : Polynomial(Context::get_context(), v) {} + + Polynomial::Polynomial(const lp_polynomial_context_t* c, const Integer& i, const Variable& v, unsigned n) + : mPoly(lp_polynomial_alloc(), polynomial_deleter) { + assert(lp_variable_db_is_valid(c->var_db, v.get_internal())); + lp_polynomial_construct_simple(get_internal(), c, i.get_internal(), v.get_internal(), n); } - Polynomial::Polynomial(const Integer& i, Variable v, unsigned n) + Polynomial::Polynomial(const Context& c, const Integer& i, const Variable& v, unsigned n) + : Polynomial(c.get_polynomial_context(), i, v, n) {} + Polynomial::Polynomial(const Integer& i, const Variable& v, unsigned n) : Polynomial(Context::get_context(), i, v, n) {} Polynomial::Polynomial(const lp_polynomial_context_t* c, const Integer & i) From 421c5d228179022ebe1ddc3973aae41c82a9caa4 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Tue, 28 Oct 2025 15:58:59 -0700 Subject: [PATCH 11/15] Add warning in variable.h --- include/polyxx/variable.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/polyxx/variable.h b/include/polyxx/variable.h index 614994ce..1e2e5815 100644 --- a/include/polyxx/variable.h +++ b/include/polyxx/variable.h @@ -9,6 +9,8 @@ namespace poly { /** * Implements a wrapper for lp_variable_t. + * WARNING: Variable does not store its context, i.e. the variable database + * it belongs to. Only use it with a Polynomial / Variable of the same context! */ class Variable { /** The actual variable. */ From 7c20bc15a92b92c8fabab8a98d2e1df8b396071d Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Tue, 28 Oct 2025 17:44:43 -0700 Subject: [PATCH 12/15] Fixed whitespaces. --- include/polyxx/context.h | 2 +- include/polyxx/polynomial.h | 2 +- src/polyxx/context.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/polyxx/context.h b/include/polyxx/context.h index 0c234f33..b378c004 100644 --- a/include/polyxx/context.h +++ b/include/polyxx/context.h @@ -23,7 +23,7 @@ namespace poly { Context(); /** Wraps the lp context. */ - explicit Context(lp_polynomial_context_t *ctx); + explicit Context(lp_polynomial_context_t* ctx); /** Copy constructor. */ Context(const Context& other); diff --git a/include/polyxx/polynomial.h b/include/polyxx/polynomial.h index a1814e06..724f4075 100644 --- a/include/polyxx/polynomial.h +++ b/include/polyxx/polynomial.h @@ -50,7 +50,7 @@ namespace poly { /** Construct a constant polynomial from an internal context pointer. */ Polynomial(const lp_polynomial_context_t* c, const Integer& i); /** Construct from an integer and a custom context. */ - Polynomial(const Context& c, const Integer &i); + Polynomial(const Context& c, const Integer& i); /** Construct from an integer. */ Polynomial(const Integer &i); diff --git a/src/polyxx/context.cpp b/src/polyxx/context.cpp index e2f8e7c2..2c65dd59 100644 --- a/src/polyxx/context.cpp +++ b/src/polyxx/context.cpp @@ -17,7 +17,7 @@ namespace poly { }); } - Context::Context(lp_polynomial_context_t *ctx) { + Context::Context(lp_polynomial_context_t* ctx) { mVariableDB = deleting_unique_ptr( ctx->var_db, [](lp_variable_db_t *ptr) { lp_variable_db_detach(ptr); }); From c472cb6a4305f8cbd37ed56dae1da5ffa4b44893 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Tue, 28 Oct 2025 17:46:10 -0700 Subject: [PATCH 13/15] Fixed whitespaces. --- include/polyxx/polynomial.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/polyxx/polynomial.h b/include/polyxx/polynomial.h index 724f4075..9e2ada82 100644 --- a/include/polyxx/polynomial.h +++ b/include/polyxx/polynomial.h @@ -52,7 +52,7 @@ namespace poly { /** Construct from an integer and a custom context. */ Polynomial(const Context& c, const Integer& i); /** Construct from an integer. */ - Polynomial(const Integer &i); + Polynomial(const Integer& i); /** Copy from a Polynomial. */ Polynomial(const Polynomial& p); From fd23d87535031252a6bb333c082fd45121c5fac2 Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Tue, 28 Oct 2025 17:56:31 -0700 Subject: [PATCH 14/15] Added tests. --- test/polyxx/test_context.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/test/polyxx/test_context.cpp b/test/polyxx/test_context.cpp index 112aa08b..c3538534 100644 --- a/test/polyxx/test_context.cpp +++ b/test/polyxx/test_context.cpp @@ -9,6 +9,16 @@ TEST_CASE("context::discriminant") { Context ctx; Variable x(ctx, "x"); Polynomial p1(ctx, x); - Polynomial d = poly::discriminant(p1); // d built in the default context - Polynomial p2 = p1 + d; // assertion failure! + Polynomial d = discriminant(p1); + Polynomial p2 = p1 + d; + CHECK(1 == d); + CHECK(p2 == Polynomial(ctx, x) + 1); +} + +TEST_CASE("context::integer") { + Context ctx; + Polynomial p(ctx); + Polynomial p1 = p + 1; + Polynomial p2 = p + Integer(1); + CHECK(p1 == p2); } From 42789918fe09d51a2e4e26f9f4afa0b2e90340ce Mon Sep 17 00:00:00 2001 From: Thomas Hader Date: Tue, 28 Oct 2025 19:59:00 -0700 Subject: [PATCH 15/15] Make variable constructors explicit --- include/polyxx/variable.h | 6 +++--- src/polyxx/polynomial.cpp | 2 +- src/polyxx/rational_interval.cpp | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/include/polyxx/variable.h b/include/polyxx/variable.h index 1e2e5815..9c2e97df 100644 --- a/include/polyxx/variable.h +++ b/include/polyxx/variable.h @@ -20,11 +20,11 @@ namespace poly { /** Construct with a null variable. */ Variable(); /** Construct from a lp_variable_t. */ - Variable(lp_variable_t var); + explicit Variable(lp_variable_t var); /** Construct a new variable with the given name in the specified context. */ - Variable(const Context& c, const char* name); + explicit Variable(const Context& c, const char* name); /** Construct a new variable with the given name in the default context. */ - Variable(const char* name); + explicit Variable(const char* name); /** Get the internal lp_variable_t. Note that it's only a type alias for * long. diff --git a/src/polyxx/polynomial.cpp b/src/polyxx/polynomial.cpp index 57e9441a..1f40fb62 100644 --- a/src/polyxx/polynomial.cpp +++ b/src/polyxx/polynomial.cpp @@ -117,7 +117,7 @@ namespace poly { return lp_polynomial_degree(p.get_internal()); } Variable main_variable(const Polynomial& p) { - return lp_polynomial_top_variable(p.get_internal()); + return Variable(lp_polynomial_top_variable(p.get_internal())); } Polynomial coefficient(const Polynomial& p, std::size_t k) { Polynomial res(detail::context(p)); diff --git a/src/polyxx/rational_interval.cpp b/src/polyxx/rational_interval.cpp index 9983e69a..d365d919 100644 --- a/src/polyxx/rational_interval.cpp +++ b/src/polyxx/rational_interval.cpp @@ -1,6 +1,7 @@ #include "polyxx/rational_interval.h" #include +#include namespace poly {