From ef9de06419c8b9ca6f5e0e0c297178e793b6b366 Mon Sep 17 00:00:00 2001 From: Mikelis Emils Mikelsons Date: Wed, 16 Jul 2025 13:28:15 +0200 Subject: [PATCH 1/5] Add is_finitely_generated for FPModules and fix is_noetherian --- src/Module.jl | 1 + src/Rings.jl | 20 +++++++++++++++++++- src/exports.jl | 1 + 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/Module.jl b/src/Module.jl index ed21c70b2a..a98bae676d 100644 --- a/src/Module.jl +++ b/src/Module.jl @@ -26,6 +26,7 @@ function check_parent(M::FPModule{T}, N::FPModule{T}) where T <: RingElement end is_finite(M::FPModule{<:FinFieldElem}) = true +is_finitely_generated(M::FPModule) = true function is_sub_with_data(M::FPModule{T}, N::FPModule{T}) where T <: RingElement fl = is_submodule(N, M) diff --git a/src/Rings.jl b/src/Rings.jl index 23211d4282..6b12fc9ca4 100644 --- a/src/Rings.jl +++ b/src/Rings.jl @@ -265,7 +265,25 @@ is_noetherian(::Integers) = true is_noetherian(R::Union{PolyRing, MPolyRing, LaurentPolyRing, LaurentMPolyRing}) = is_noetherian(coefficient_ring(R)) is_noetherian(R::Union{MSeriesRing, SeriesRing}) = is_noetherian(base_ring(R)) is_noetherian(R::ResidueRing) = is_noetherian(base_ring(R)) || throw(NotImplementedError(:is_noetherian, R)) -is_noetherian(M::Module) = is_noetherian(base_ring(M)) || throw(NotImplementedError(:is_noetherian, M)) + +@doc raw""" + is_noetherian(M::Module) + +Check if the module $M$ is Noetherian. This is currently implemented only for finitely generated modules +in which case it is sufficient to check whether the base ring is Noetherian. + +# Examples +```jldoctest +julia> R, x = polynomial_ring(ZZ, [:x]); + +julia> M = free_module(R, 2) +Free module of rank 2 over R + +julia> is_noetherian(M) +true +``` +""" +is_noetherian(M::Module) = (is_noetherian(base_ring(M)) && is_finitely_generated(M)) || throw(NotImplementedError(:is_noetherian, M)) @doc raw""" krull_dim(R::Ring) diff --git a/src/exports.jl b/src/exports.jl index ae9561bc5f..d024024825 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -302,6 +302,7 @@ export is_even export is_exact_type export is_finite export is_finite_order +export is_finitely_generated export is_free export is_gen export is_hermitian From bb9d4c5309035946cb2379284344969b7f37fa7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C4=B7elis=20Em=C4=ABls=20Mi=C4=B7elsons?= Date: Wed, 16 Jul 2025 21:06:30 +0200 Subject: [PATCH 2/5] Update src/Module.jl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lars Göttgens --- src/Module.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Module.jl b/src/Module.jl index a98bae676d..3a628dfc3a 100644 --- a/src/Module.jl +++ b/src/Module.jl @@ -27,6 +27,7 @@ end is_finite(M::FPModule{<:FinFieldElem}) = true is_finitely_generated(M::FPModule) = true +is_finitely_generated(M::Module) = isfinite(ngens(M)) || throw(NotImplementedError(:is_finitely_generated, M)) function is_sub_with_data(M::FPModule{T}, N::FPModule{T}) where T <: RingElement fl = is_submodule(N, M) From e42725800c3c00e3c3af9c644557ff3103f5d0dd Mon Sep 17 00:00:00 2001 From: Mikelis Emils Mikelsons Date: Wed, 16 Jul 2025 21:31:58 +0200 Subject: [PATCH 3/5] Move is_noetherian(::Module) to Module.jl --- src/Module.jl | 19 +++++++++++++++++++ src/Rings.jl | 19 ------------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/Module.jl b/src/Module.jl index 3a628dfc3a..16c57248d4 100644 --- a/src/Module.jl +++ b/src/Module.jl @@ -29,6 +29,25 @@ is_finite(M::FPModule{<:FinFieldElem}) = true is_finitely_generated(M::FPModule) = true is_finitely_generated(M::Module) = isfinite(ngens(M)) || throw(NotImplementedError(:is_finitely_generated, M)) +@doc raw""" + is_noetherian(M::Module) + +Check if the module $M$ is Noetherian. This is currently implemented only for finitely generated modules +in which case it is sufficient to check whether the base ring is Noetherian. + +# Examples +```jldoctest +julia> R, x = polynomial_ring(ZZ, [:x]); + +julia> M = free_module(R, 2) +Free module of rank 2 over R + +julia> is_noetherian(M) +true +``` +""" +is_noetherian(M::Module) = (is_noetherian(base_ring(M)) && is_finitely_generated(M)) || throw(NotImplementedError(:is_noetherian, M)) + function is_sub_with_data(M::FPModule{T}, N::FPModule{T}) where T <: RingElement fl = is_submodule(N, M) if fl diff --git a/src/Rings.jl b/src/Rings.jl index 6b12fc9ca4..b6b2041243 100644 --- a/src/Rings.jl +++ b/src/Rings.jl @@ -266,25 +266,6 @@ is_noetherian(R::Union{PolyRing, MPolyRing, LaurentPolyRing, LaurentMPolyRing}) is_noetherian(R::Union{MSeriesRing, SeriesRing}) = is_noetherian(base_ring(R)) is_noetherian(R::ResidueRing) = is_noetherian(base_ring(R)) || throw(NotImplementedError(:is_noetherian, R)) -@doc raw""" - is_noetherian(M::Module) - -Check if the module $M$ is Noetherian. This is currently implemented only for finitely generated modules -in which case it is sufficient to check whether the base ring is Noetherian. - -# Examples -```jldoctest -julia> R, x = polynomial_ring(ZZ, [:x]); - -julia> M = free_module(R, 2) -Free module of rank 2 over R - -julia> is_noetherian(M) -true -``` -""" -is_noetherian(M::Module) = (is_noetherian(base_ring(M)) && is_finitely_generated(M)) || throw(NotImplementedError(:is_noetherian, M)) - @doc raw""" krull_dim(R::Ring) From 8a4ad955f18fb3fabc1bd53dd6762318131722c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C4=B7elis=20Em=C4=ABls=20Mi=C4=B7elsons?= Date: Thu, 24 Jul 2025 07:56:26 +0200 Subject: [PATCH 4/5] Apply suggestions from code review Co-authored-by: Max Horn --- src/Module.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Module.jl b/src/Module.jl index 16c57248d4..5d690b48dd 100644 --- a/src/Module.jl +++ b/src/Module.jl @@ -33,7 +33,7 @@ is_finitely_generated(M::Module) = isfinite(ngens(M)) || throw(NotImplementedErr is_noetherian(M::Module) Check if the module $M$ is Noetherian. This is currently implemented only for finitely generated modules -in which case it is sufficient to check whether the base ring is Noetherian. +Check if the module $M$ is Noetherian. # Examples ```jldoctest @@ -46,7 +46,11 @@ julia> is_noetherian(M) true ``` """ -is_noetherian(M::Module) = (is_noetherian(base_ring(M)) && is_finitely_generated(M)) || throw(NotImplementedError(:is_noetherian, M)) +function is_noetherian(M::Module) + is_finitely_generated(M) || return false + is_noetherian(base_ring(M)) && return true + throw(NotImplementedError(:is_noetherian, M)) +end function is_sub_with_data(M::FPModule{T}, N::FPModule{T}) where T <: RingElement fl = is_submodule(N, M) From 4ab97516ee59db2c8f4568cb88fd66f066bf27ec Mon Sep 17 00:00:00 2001 From: Mikelis Emils Mikelsons Date: Thu, 24 Jul 2025 08:00:37 +0200 Subject: [PATCH 5/5] Fix docstring typo --- src/Module.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Module.jl b/src/Module.jl index 5d690b48dd..d63651fe36 100644 --- a/src/Module.jl +++ b/src/Module.jl @@ -32,7 +32,6 @@ is_finitely_generated(M::Module) = isfinite(ngens(M)) || throw(NotImplementedErr @doc raw""" is_noetherian(M::Module) -Check if the module $M$ is Noetherian. This is currently implemented only for finitely generated modules Check if the module $M$ is Noetherian. # Examples