Skip to content

Commit

Permalink
Extend ideal interface (#1731)
Browse files Browse the repository at this point in the history
* Extend ideal interface

* Update src/Ideal.jl

Co-authored-by: Max Horn <[email protected]>

* Update according to comment by Max

Before, it might have happened that the command `R * ZZRingElem(2)` fails while `R * big(2)` succeeds.

* 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 <[email protected]>

* 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.

* Change API / base method

* Update src/Ideal.jl

* Allow ideal(R, x, y, z)

This is already allowed for Hecke ideals.
For consistency, we allow this already in AbstractAlgebra.

* Forbid ideal(R) for creating empty ideal

---------

Co-authored-by: Max Horn <[email protected]>
  • Loading branch information
paemurru and fingolfin authored Aug 18, 2024
1 parent 9b5d770 commit 3fc7d25
Showing 1 changed file with 26 additions and 3 deletions.
29 changes: 26 additions & 3 deletions src/Ideal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,40 @@
#
###############################################################################

function ideal
# We assume that the function
# 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`.

# 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])
end

function *(x::RingElement, R::Ring)
return ideal(R, 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)
return ideal(R, x)
end

function *(x::RingElement, R::Ring)
return ideal(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)

0 comments on commit 3fc7d25

Please sign in to comment.