Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make base_ring_type part of the ring interface #1682

Merged
merged 3 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/src/extending_abstractalgebra.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ $\mathbb{Z}[x]$, then one should implement

```@docs
base_ring
base_ring_type
```

## Special elements
Expand Down
11 changes: 10 additions & 1 deletion docs/src/ring_interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,13 @@ Return the type of the elements of the ring whose parent object has the given ty
This is the inverse of the `parent_type` function, i.e. `elem_type(Generic.PolyRing{T})`
will return `Generic.Poly{T}`.

```julia
base_ring_type(::Type{MyParent})
```

Return the type of the of base rings for parent objects with the given parent type.
For example, `base_ring_type(Generic.PolyRing{T})` will return `parent_type(T)`.

```julia
base_ring(R::MyParent)
```
Expand Down Expand Up @@ -839,7 +846,9 @@ parent_type(::Type{ConstPoly{T}}) where T <: RingElement = ConstPolyRing{T}

elem_type(::Type{ConstPolyRing{T}}) where T <: RingElement = ConstPoly{T}

base_ring(R::ConstPolyRing) = R.base_ring
base_ring_type(::Type{ConstPoly{T}}) where T <: RingElement = parent_type(T)

base_ring(R::ConstPolyRing) = R.base_ring::base_ring_type(R)

parent(f::ConstPoly) = f.parent

Expand Down
2 changes: 2 additions & 0 deletions src/Ideal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ function *(R::Ring, x::RingElement)
end

iszero(I::Ideal) = all(iszero, gens(I))

base_ring_type(::Type{<:IdealSet{T}}) where T <: RingElement = parent_type(T)
2 changes: 2 additions & 0 deletions src/MPoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#
###############################################################################

base_ring_type(::Type{<:MPolyRing{T}}) where T<:RingElement = parent_type(T)

Check warning on line 13 in src/MPoly.jl

View check run for this annotation

Codecov / codecov/patch

src/MPoly.jl#L13

Added line #L13 was not covered by tests

coefficient_ring(R::MPolyRing) = base_ring(R)

@doc raw"""
Expand Down
6 changes: 1 addition & 5 deletions src/MatRing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,7 @@
#
###############################################################################

base_ring_type(::Type{MatRing{T}}) where T <: NCRingElement = parent_type(T)

function base_ring(a::MatRing{T}) where {T <: NCRingElement}
a.base_ring::parent_type(T)
end
base_ring_type(::Type{<:MatRing{T}}) where T <: NCRingElement = parent_type(T)

function check_parent(a::MatRingElem{T}, b::MatRingElem{T}, throw::Bool = true) where T <: NCRingElement
fl = (base_ring(a) != base_ring(b) || degree(a) != degree(b))
Expand Down
2 changes: 1 addition & 1 deletion src/Residue.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
###############################################################################

base_ring_type(::Type{ResidueRing{T}}) where T <: RingElement = parent_type(T)
base_ring_type(::Type{<:ResidueRing{T}}) where T <: RingElement = parent_type(T)

base_ring(S::ResidueRing{T}) where {T <: RingElement} = S.base_ring::parent_type(T)

Expand Down
5 changes: 3 additions & 2 deletions src/fundamental_interface.jl
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,10 @@
true
```
"""
base_ring_type(x::NCRing) = base_ring_type(typeof(x))
base_ring_type(x::NCRingElement) = base_ring_type(parent_type(x))
base_ring_type(x) = base_ring_type(typeof(x))
base_ring_type(x::Type{<:NCRingElement}) = base_ring_type(parent_type(x))
base_ring_type(x::Type{<:ModuleElem}) = base_ring_type(parent_type(x))

Check warning on line 129 in src/fundamental_interface.jl

View check run for this annotation

Codecov / codecov/patch

src/fundamental_interface.jl#L129

Added line #L129 was not covered by tests
base_ring_type(x::Type{<:Ideal}) = base_ring_type(parent_type(x))
base_ring_type(T::DataType) = throw(MethodError(base_ring_type, (T,)))

# generic coefficient_ring method
Expand Down
4 changes: 2 additions & 2 deletions src/generic/DirectSum.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ elem_type(::Type{DirectSumModule{T}}) where T <: RingElement = DirectSumModuleEl

parent(v::DirectSumModuleElem) = v.parent

base_ring(N::DirectSumModule{T}) where T <: RingElement = base_ring(N.m[1])
base_ring_type(::Type{DirectSumModule{T}}) where T <: RingElement = parent_type(T)

base_ring(v::DirectSumModuleElem{T}) where T <: RingElement = base_ring(v.parent)
base_ring(N::DirectSumModule{T}) where T <: RingElement = base_ring(N.m[1])::base_ring_type(N)

dim(M::DirectSumModule{<:FieldElem}) = sum(dim(x) for x = M.m)

Expand Down
20 changes: 5 additions & 15 deletions src/generic/FactoredFraction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,17 @@
#
###############################################################################

function parent(a::FactoredFracFieldElem{T}) where T <: RingElement
return a.parent
end
parent(a::FactoredFracFieldElem{T}) where T <: RingElement = a.parent

function parent_type(::Type{FactoredFracFieldElem{T}}) where {T <: RingElement}
return FactoredFracField{T}
end
parent_type(::Type{FactoredFracFieldElem{T}}) where {T <: RingElement} = FactoredFracField{T}

function elem_type(::Type{FactoredFracField{T}}) where {T <: RingElement}
return FactoredFracFieldElem{T}
end
elem_type(::Type{FactoredFracField{T}}) where {T <: RingElement} = FactoredFracFieldElem{T}

base_ring_type(::Type{FactoredFracField{T}}) where T <: NCRingElement = parent_type(T)

function base_ring(F::FactoredFracField{T}) where T <: RingElement
return F.base_ring::parent_type(T)
end
base_ring(F::FactoredFracField{T}) where T <: RingElement = F.base_ring::parent_type(T)

function characteristic(F::FactoredFracField{T}) where T <: RingElement
return characteristic(base_ring(F))
end
characteristic(F::FactoredFracField{T}) where T <: RingElement = characteristic(base_ring(F))

###############################################################################
#
Expand Down
2 changes: 1 addition & 1 deletion src/generic/Fraction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ parent_type(::Type{FracFieldElem{T}}) where T <: RingElem = FracField{T}

elem_type(::Type{FracField{T}}) where {T <: RingElem} = FracFieldElem{T}

base_ring(a::FracField{T}) where T <: RingElem = a.base_ring::base_ring_type(typeof(a))
base_ring(a::FracField{T}) where T <: RingElem = a.base_ring::base_ring_type(a)

###############################################################################
#
Expand Down
5 changes: 1 addition & 4 deletions src/generic/FunctionField.jl
Original file line number Diff line number Diff line change
Expand Up @@ -530,10 +530,7 @@ function base_ring_type(::Type{FunctionField{T}}) where T <: FieldElement
return RationalFunctionField{T, U}
end

function base_ring(R::FunctionField{T}) where T <: FieldElement
U = dense_poly_type(T)
return R.base_ring::RationalFunctionField{T, U}
end
base_ring(R::FunctionField{T}) where T <: FieldElement = R.base_ring::base_ring_type(R)

# For consistency with number fields in Hecke.jl
@doc raw"""
Expand Down
2 changes: 1 addition & 1 deletion src/generic/GenericTypes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1500,7 +1500,7 @@ end
#
###############################################################################

@attributes mutable struct IdealSet{T <: RingElement} <: AbstractAlgebra.Set
@attributes mutable struct IdealSet{T <: RingElement} <: AbstractAlgebra.IdealSet{T}
base_ring::Ring

function IdealSet{T}(R::Ring, cached::Bool = true) where T <: RingElement
Expand Down
4 changes: 2 additions & 2 deletions src/generic/Ideal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
#
###############################################################################

base_ring(S::IdealSet) = S.base_ring
base_ring(S::IdealSet) = S.base_ring::base_ring_type(S)

base_ring(I::Ideal) = I.base_ring
base_ring(I::Ideal) = I.base_ring::base_ring_type(I)

function parent(I::Ideal)
R = base_ring(I)
Expand Down
4 changes: 2 additions & 2 deletions src/generic/InvariantFactorDecomposition.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ elem_type(::Type{SNFModule{T}}) where T <: RingElement = SNFModuleElem{T}

parent(v::SNFModuleElem) = v.parent

base_ring(N::SNFModule{T}) where T <: RingElement = N.base_ring
base_ring_type(::Type{SNFModule{T}}) where T <: RingElement = parent_type(T)

base_ring(v::SNFModuleElem{T}) where T <: RingElement = base_ring(v.parent)
base_ring(N::SNFModule{T}) where T <: RingElement = N.base_ring::base_ring_type(N)

number_of_generators(N::SNFModule{T}) where T <: RingElement = length(N.invariant_factors)

Expand Down
4 changes: 3 additions & 1 deletion src/generic/LaurentMPoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ elem_type(::Type{LaurentMPolyWrapRing{T, PR}}) where {T, PR} =

parent(p::LaurentMPolyWrap) = p.parent

base_ring(R::LaurentMPolyWrapRing) = base_ring(R.mpolyring)
base_ring_type(::Type{<:LaurentMPolyWrapRing{T}}) where {T} = parent_type(T)

base_ring(R::LaurentMPolyWrapRing) = base_ring(R.mpolyring)::base_ring_type(R)

coefficient_ring(R::LaurentMPolyWrapRing) = coefficient_ring(R.mpolyring)

Expand Down
4 changes: 3 additions & 1 deletion src/generic/LaurentPoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ parent(p::LaurentPolyWrap) = p.parent

coefficient_ring(R::LaurentPolyWrapRing) = coefficient_ring(R.polyring)

base_ring(R::LaurentPolyWrapRing) = base_ring(R.polyring)
base_ring_type(::Type{<:LaurentPolyWrapRing{T}}) where {T} = parent_type(T)

base_ring(R::LaurentPolyWrapRing) = base_ring(R.polyring)::base_ring_type(R)

var(R::LaurentPolyWrapRing) = var(R.polyring)

Expand Down
4 changes: 2 additions & 2 deletions src/generic/LaurentSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@

elem_type(::Type{LaurentSeriesField{T}}) where T <: FieldElement = LaurentSeriesFieldElem{T}

base_ring_type(::Type{LaurentSeriesRing{T}}) where T <: RingElement = parent_type(T)
base_ring_type(::Type{<:LaurentSeriesRing{T}}) where T <: RingElement = parent_type(T)

Check warning on line 36 in src/generic/LaurentSeries.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/LaurentSeries.jl#L36

Added line #L36 was not covered by tests

base_ring_type(::Type{LaurentSeriesField{T}}) where T <: FieldElement = parent_type(T)
base_ring_type(::Type{<:LaurentSeriesField{T}}) where T <: FieldElement = parent_type(T)

Check warning on line 38 in src/generic/LaurentSeries.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/LaurentSeries.jl#L38

Added line #L38 was not covered by tests

base_ring(R::LaurentSeriesRing{T}) where T <: RingElement = R.base_ring::parent_type(T)

Expand Down
2 changes: 0 additions & 2 deletions src/generic/MPoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ parent_type(::Type{MPoly{T}}) where T <: RingElement = MPolyRing{T}

elem_type(::Type{MPolyRing{T}}) where T <: RingElement = MPoly{T}

base_ring_type(::Type{MPolyRing{T}}) where T <: RingElement = parent_type(T)

base_ring(R::MPolyRing{T}) where T <: RingElement = R.base_ring::parent_type(T)

@doc raw"""
Expand Down
2 changes: 2 additions & 0 deletions src/generic/MatRing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ parent_type(::Type{MatRingElem{T}}) where T <: NCRingElement = MatRing{T}

elem_type(::Type{MatRing{T}}) where {T <: NCRingElement} = MatRingElem{T}

base_ring(a::MatRing{T}) where {T <: NCRingElement} = a.base_ring::parent_type(T)

@doc raw"""
parent(a::MatRingElem{T}) where T <: NCRingElement

Expand Down
1 change: 1 addition & 0 deletions src/generic/Matrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@

AbstractAlgebra.nrows(K::InjProjMat) = K.n
AbstractAlgebra.ncols(K::InjProjMat) = K.m
AbstractAlgebra.base_ring_type(::Type{InjProjMat{T}}) where T = parent_type(T)

Check warning on line 269 in src/generic/Matrix.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/Matrix.jl#L269

Added line #L269 was not covered by tests
AbstractAlgebra.base_ring(K::InjProjMat{T}) where T = K.R::parent_type(T)

function AbstractAlgebra.matrix(K::InjProjMat)
Expand Down
4 changes: 3 additions & 1 deletion src/generic/Misc/Localization.jl
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@

parent_type(::Type{LocalizedEuclideanRingElem{T}}) where {T} = LocalizedEuclideanRing{T}

base_ring(L::LocalizedEuclideanRing) = L.base_ring
base_ring_type(::Type{LocalizedEuclideanRingElem{T}}) where {T} = parent_type(T)

Check warning on line 121 in src/generic/Misc/Localization.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/Misc/Localization.jl#L121

Added line #L121 was not covered by tests

base_ring(L::LocalizedEuclideanRing) = L.base_ring::base_ring_type(L)

Check warning on line 123 in src/generic/Misc/Localization.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/Misc/Localization.jl#L123

Added line #L123 was not covered by tests

parent(a::LocalizedEuclideanRingElem) = a.parent

Expand Down
4 changes: 4 additions & 0 deletions src/generic/PuiseuxSeries.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@

elem_type(::Type{PuiseuxSeriesField{T}}) where T <: FieldElement = PuiseuxSeriesFieldElem{T}

base_ring_type(::Type{PuiseuxSeriesRing{T}}) where T <: RingElement = parent_type(T)

Check warning on line 52 in src/generic/PuiseuxSeries.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/PuiseuxSeries.jl#L52

Added line #L52 was not covered by tests

base_ring_type(::Type{PuiseuxSeriesField{T}}) where T <: RingElement = parent_type(T)

Check warning on line 54 in src/generic/PuiseuxSeries.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/PuiseuxSeries.jl#L54

Added line #L54 was not covered by tests

base_ring(R::PuiseuxSeriesRing{T}) where T <: RingElement = base_ring(laurent_ring(R))

base_ring(R::PuiseuxSeriesField{T}) where T <: FieldElement = base_ring(laurent_ring(R))
Expand Down
4 changes: 2 additions & 2 deletions src/generic/QuotientModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

parent(v::QuotientModuleElem) = v.parent

base_ring(N::QuotientModule{T}) where T <: RingElement = N.base_ring
base_ring_type(::Type{QuotientModule{T}}) where T <: RingElement = parent_type(T)

Check warning on line 19 in src/generic/QuotientModule.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/QuotientModule.jl#L19

Added line #L19 was not covered by tests

base_ring(v::QuotientModuleElem{T}) where T <: RingElement = base_ring(v.parent)
base_ring(N::QuotientModule{T}) where T <: RingElement = N.base_ring::parent_type(T)

number_of_generators(N::QuotientModule{T}) where T <: RingElement = length(N.gen_cols)

Expand Down
4 changes: 2 additions & 2 deletions src/generic/Submodule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@

parent(v::SubmoduleElem) = v.parent

base_ring(N::Submodule{T}) where T <: RingElement = N.base_ring::parent_type(T)
base_ring_type(::Type{Submodule{T}}) where T <: RingElement = parent_type(T)

Check warning on line 19 in src/generic/Submodule.jl

View check run for this annotation

Codecov / codecov/patch

src/generic/Submodule.jl#L19

Added line #L19 was not covered by tests

base_ring(v::SubmoduleElem{T}) where T <: RingElement = base_ring(v.parent)
base_ring(N::Submodule{T}) where T <: RingElement = N.base_ring::parent_type(T)

number_of_generators(N::Submodule{T}) where T <: RingElement = length(N.gen_cols)

Expand Down
4 changes: 3 additions & 1 deletion src/generic/UnivPoly.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
#
###############################################################################

base_ring(S::UniversalPolyRing) = S.base_ring
base_ring_type(::Type{<:UniversalPolyRing{T}}) where T = parent_type(T)

base_ring(S::UniversalPolyRing) = S.base_ring::base_ring_type(S)

coefficient_ring(S::UniversalPolyRing) = base_ring(S)

Expand Down
2 changes: 2 additions & 0 deletions src/julia/Float.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ elem_type(::Type{Floats{T}}) where T <: AbstractFloat = T

parent_type(::Type{T}) where T <: AbstractFloat = Floats{T}

base_ring_type(::Type{Floats{T}}) where T <: AbstractFloat = typeof(Union{})

base_ring(a::Floats{T}) where T <: AbstractFloat = Union{}

is_domain_type(::Type{T}) where T <: AbstractFloat = true
Expand Down
2 changes: 2 additions & 0 deletions src/julia/GF.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ parent_type(::Type{GFElem{T}}) where T <: Integer = GFField{T}

elem_type(::Type{GFField{T}}) where T <: Integer = GFElem{T}

base_ring_type(::Type{<:GFField}) = typeof(Union{})

base_ring(a::GFField) = Union{}

parent(a::GFElem) = a.parent
Expand Down
2 changes: 2 additions & 0 deletions src/julia/Integer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ elem_type(::Type{Integers{T}}) where T <: Integer = T

parent_type(::Type{T}) where T <: Integer = Integers{T}

base_ring_type(::Type{<:Integers}) = typeof(Union{})

base_ring(a::Integers{T}) where T <: Integer = Union{}

is_exact_type(::Type{T}) where T <: Integer = true
Expand Down
10 changes: 1 addition & 9 deletions src/julia/Rational.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,10 @@ elem_type(::Type{Rationals{T}}) where T <: Integer = Rational{T}

parent_type(::Type{Rational{T}}) where T <: Integer = Rationals{T}

base_ring(a::Rational{Int}) = zz

base_ring(a::Rational{BigInt}) = JuliaZZ

base_ring(a::Rationals{Int}) = zz

base_ring(a::Rationals{BigInt}) = JuliaZZ
base_ring_type(::Type{Rationals{T}}) where T <: Integer = Integers{T}

base_ring(a::Rationals{T}) where T <: Integer = Integers{T}()

base_ring(a::Rational{T}) where T <: Integer = Integers{T}()

is_exact_type(::Type{Rational{T}}) where T <: Integer = true

is_domain_type(::Type{Rational{T}}) where T <: Integer = true
Expand Down
5 changes: 5 additions & 0 deletions test/Rings-conformance-tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ function test_NCRing_interface(R::AbstractAlgebra.NCRing; reps = 50)
@test is_domain_type(T) isa Bool
@test is_exact_type(T) isa Bool

@test base_ring_type(R) == typeof(base_ring(R))
@test base_ring_type(zero(R)) == typeof(base_ring(zero(R)))
@test base_ring_type(typeof(R)) == typeof(base_ring(R))
@test base_ring_type(T) == typeof(base_ring(zero(R)))

# some rings don't support characteristic and raise an exception (see issue #993)
try ch = characteristic(R)
@test iszero(R(characteristic(R)))
Expand Down
5 changes: 4 additions & 1 deletion test/algorithms/GenericFunctions-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import AbstractAlgebra: RingElem
import AbstractAlgebra: add!
import AbstractAlgebra: addeq!
import AbstractAlgebra: base_ring
import AbstractAlgebra: base_ring_type
import AbstractAlgebra: canonical_unit
import AbstractAlgebra: characteristic
import AbstractAlgebra: divexact
Expand Down Expand Up @@ -74,7 +75,9 @@ parent_type(::Type{ConstPoly{T}}) where T <: RingElement = ConstPolyRing{T}

elem_type(::Type{ConstPolyRing{T}}) where T <: RingElement = ConstPoly{T}

base_ring(R::ConstPolyRing) = R.base_ring
base_ring_type(::Type{ConstPolyRing{T}}) where T <: RingElement = parent_type(T)

base_ring(R::ConstPolyRing) = R.base_ring::base_ring_type(R)

parent(f::ConstPoly) = f.parent

Expand Down
Loading