From 64bfd3bb2a576c9fc539c89f4e56636acfa54577 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Fri, 14 Jun 2024 18:17:48 +0200 Subject: [PATCH 1/9] Extend ideal interface --- src/Ideal.jl | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index ccaca769b0..d183f09e35 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -4,8 +4,11 @@ # ############################################################################### -function ideal -end +# We assume that the functions +# ideal(R::Ring, x::RingElement) +# ideal(R::Ring, xs::AbstractVector) +# are implemented in the package that uses AbstractAlgebra. +# The functions in this file extend the interface for `ideal`. function *(x::RingElement, R::Ring) return ideal(R, x) @@ -15,6 +18,27 @@ function *(R::Ring, x::RingElement) return ideal(R, x) end +function *(R::Ring, x::Any) + return ideal(R, R(x)) +end + +function *(x::Any, R::Ring) + return ideal(R, R(x)) +end + +function ideal(R::Ring, x::Any) + return ideal(R, R(x)) +end + +function ideal(x::RingElement) + return ideal(parent(x), x) +end + +function ideal(xs::AbstractVector{T}) where T<:RingElement + !is_empty(xs) || throw(ArgumentError("Empty collection, cannot determine parent ring, try ideal(ring, xs) instead of ideal(xs)")) + return ideal(parent(xs[1]), xs) +end + iszero(I::Ideal) = all(iszero, gens(I)) base_ring_type(::Type{<:IdealSet{T}}) where T <: RingElement = parent_type(T) From 37bb59ac731d582018935eb59ac387c70810da60 Mon Sep 17 00:00:00 2001 From: Erik Paemurru <143521159+paemurru@users.noreply.github.com> Date: Tue, 18 Jun 2024 15:25:27 +0200 Subject: [PATCH 2/9] Update src/Ideal.jl Co-authored-by: Max Horn --- src/Ideal.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index d183f09e35..82fccbdc6e 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -7,7 +7,7 @@ # We assume that the functions # ideal(R::Ring, x::RingElement) # ideal(R::Ring, xs::AbstractVector) -# are implemented in the package that uses AbstractAlgebra. +# are implemented by anyone implementing ideals for AbstractAlgebra rings. # The functions in this file extend the interface for `ideal`. function *(x::RingElement, R::Ring) From 1724b1d2c15fe1ecbca7477ea4400f5162c9542e Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Tue, 18 Jun 2024 15:26:58 +0200 Subject: [PATCH 3/9] Update according to comment by Max Before, it might have happened that the command `R * ZZRingElem(2)` fails while `R * big(2)` succeeds. --- src/Ideal.jl | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index 82fccbdc6e..0feabdd45e 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -10,14 +10,6 @@ # are implemented by anyone implementing ideals for AbstractAlgebra rings. # The functions in this file extend the interface for `ideal`. -function *(x::RingElement, R::Ring) - return ideal(R, x) -end - -function *(R::Ring, x::RingElement) - return ideal(R, x) -end - function *(R::Ring, x::Any) return ideal(R, R(x)) end From 61459b63a8acff820f04300698f4b544568750f5 Mon Sep 17 00:00:00 2001 From: Erik Paemurru <143521159+paemurru@users.noreply.github.com> Date: Wed, 19 Jun 2024 17:14:31 +0200 Subject: [PATCH 4/9] Apply suggestions from code review Max: "the advantage is that if some ring type wants to implement say ideal(R::MyRing, n::Int) in a special optimized fashion that avoids constructing R(n), then R*2 would benefit from that" Co-authored-by: Max Horn --- src/Ideal.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index 0feabdd45e..67974456a9 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -11,11 +11,11 @@ # The functions in this file extend the interface for `ideal`. function *(R::Ring, x::Any) - return ideal(R, R(x)) + return ideal(R, x) end function *(x::Any, R::Ring) - return ideal(R, R(x)) + return ideal(R, x) end function ideal(R::Ring, x::Any) From b97f93297f6457ade99f5959168296259d6a0270 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Wed, 31 Jul 2024 15:04:40 +0200 Subject: [PATCH 5/9] Use `RingElem` instead of `Any` Previously, there was a possibility of an infinite recursion if the base functions were not implemented. Also, writing `R(x)` when `x` is a vector is problematic, it might have unexpected results. --- src/Ideal.jl | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index 67974456a9..e4b4c4e40c 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -4,22 +4,21 @@ # ############################################################################### -# We assume that the functions -# ideal(R::Ring, x::RingElement) -# ideal(R::Ring, xs::AbstractVector) -# are implemented by anyone implementing ideals for AbstractAlgebra rings. +# We assume that the function +# ideal(R::Ring, xs::AbstractVector{T}) where T<:RingElement +# is implemented by anyone implementing ideals for AbstractAlgebra rings. # The functions in this file extend the interface for `ideal`. -function *(R::Ring, x::Any) - return ideal(R, x) +function ideal(R::Ring, x::RingElement) + return ideal(R, elem_type(R)[R(x)]) end -function *(x::Any, R::Ring) +function *(R::Ring, x::RingElement) return ideal(R, x) end -function ideal(R::Ring, x::Any) - return ideal(R, R(x)) +function *(x::RingElement, R::Ring) + return ideal(R, x) end function ideal(x::RingElement) @@ -27,7 +26,7 @@ function ideal(x::RingElement) end function ideal(xs::AbstractVector{T}) where T<:RingElement - !is_empty(xs) || throw(ArgumentError("Empty collection, cannot determine parent ring, try ideal(ring, xs) instead of ideal(xs)")) + !is_empty(xs) || throw(ArgumentError("Empty collection, cannot determine parent ring. Try ideal(ring, xs) instead of ideal(xs)")) return ideal(parent(xs[1]), xs) end From 60922da63caad641bed4310be53575fd0b2b68f8 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Wed, 31 Jul 2024 15:24:47 +0200 Subject: [PATCH 6/9] Change API / base method --- src/Ideal.jl | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index e4b4c4e40c..5f8be3422e 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -5,10 +5,16 @@ ############################################################################### # We assume that the function -# ideal(R::Ring, xs::AbstractVector{T}) where T<:RingElement -# is implemented by anyone implementing ideals for AbstractAlgebra rings. +# ideal(R::T, xs::Vector{U}) +# with U === elem_type(T) is implemented by anyone implementing ideals +# for AbstractAlgebra rings. # The functions in this file extend the interface for `ideal`. +function ideal(R::Ring, xs::AbstractVector{T}) where T<:RingElement + xs isa Vector{elem_type(R)} && error("ideals unsupported for ring $R") + return ideal(R, elem_type(R)[R(x) for x in xs]) +end + function ideal(R::Ring, x::RingElement) return ideal(R, elem_type(R)[R(x)]) end From 9276a1b16d3b962ca3247e0ba3eaa024420326b4 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 1 Aug 2024 17:26:07 +0200 Subject: [PATCH 7/9] Update src/Ideal.jl --- src/Ideal.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Ideal.jl b/src/Ideal.jl index 5f8be3422e..f44415dc42 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -10,6 +10,8 @@ # for AbstractAlgebra rings. # The functions in this file extend the interface for `ideal`. +# the following helper enables things like `ideal(R, [])` or `ideal(R, [1])` +# the type check ensures we don't run into an infinite recursion function ideal(R::Ring, xs::AbstractVector{T}) where T<:RingElement xs isa Vector{elem_type(R)} && error("ideals unsupported for ring $R") return ideal(R, elem_type(R)[R(x) for x in xs]) From ddce90a0d4dd87c70b13ffb8c6bad9319c56de43 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Thu, 1 Aug 2024 20:46:20 +0200 Subject: [PATCH 8/9] Allow ideal(R, x, y, z) This is already allowed for Hecke ideals. For consistency, we allow this already in AbstractAlgebra. --- src/Ideal.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index f44415dc42..891bdf2e4b 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -17,8 +17,8 @@ function ideal(R::Ring, xs::AbstractVector{T}) where T<:RingElement return ideal(R, elem_type(R)[R(x) for x in xs]) end -function ideal(R::Ring, x::RingElement) - return ideal(R, elem_type(R)[R(x)]) +function ideal(R::Ring, x...) + return ideal(R, elem_type(R)[R(y) for y in [x...]]) end function *(R::Ring, x::RingElement) From 980d758da733c8e1b20f50905b4610358330aed6 Mon Sep 17 00:00:00 2001 From: Erik Paemurru Date: Thu, 1 Aug 2024 21:45:19 +0200 Subject: [PATCH 9/9] Forbid ideal(R) for creating empty ideal --- src/Ideal.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ideal.jl b/src/Ideal.jl index 891bdf2e4b..16784cd66b 100644 --- a/src/Ideal.jl +++ b/src/Ideal.jl @@ -17,8 +17,8 @@ function ideal(R::Ring, xs::AbstractVector{T}) where T<:RingElement return ideal(R, elem_type(R)[R(x) for x in xs]) end -function ideal(R::Ring, x...) - return ideal(R, elem_type(R)[R(y) for y in [x...]]) +function ideal(R::Ring, x, y...) + return ideal(R, elem_type(R)[R(z) for z in [x, y...]]) end function *(R::Ring, x::RingElement)