From f1143935f779b19fa2da569e92ffcb480d47f639 Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Tue, 7 May 2024 15:50:52 +0200 Subject: [PATCH 1/9] adds `_presentation_minimal` --- src/Modules/UngradedModules/Presentation.jl | 44 +++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/Modules/UngradedModules/Presentation.jl b/src/Modules/UngradedModules/Presentation.jl index 9820cf8f114..dbbd24ddc77 100644 --- a/src/Modules/UngradedModules/Presentation.jl +++ b/src/Modules/UngradedModules/Presentation.jl @@ -559,6 +559,50 @@ function prune_with_map(M::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldElem}} # return M_new, phi end +function _presentation_minimal(M::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldElem}} + R = base_ring(M) + + # Prepare to set some names + br_name = AbstractAlgebra.get_name(R) + if br_name === nothing + br_name = "br" + end + + M_new, phi = prune_with_map(M) + F0 = ambient_free_module(M_new) + + # M_new is a quotient of a free module + proj_map = hom(F0, M_new, gens(M_new), check=false) + F0_to_M = compose(proj_map, phi) + F0_to_M.generators_map_to_generators = true + AbstractAlgebra.set_name!(F0, "$br_name^$(ngens(M.sub))") + + K, inc = sub(F0, relations(M_new)) + F1 = if is_graded(M) + graded_free_module(R, degrees_of_generators(K)) + else + free_module(R, ngens(K)) + end + F1_to_F0 = compose(hom(F1, K, gens(K), check=false), inc) + AbstractAlgebra.set_name!(F1, "$br_name^$(ngens(F1))") + + # When there is no kernel, clean things up + if is_zero(F1) + F1 = FreeMod(R, 0) + F1_to_F0 = hom(F1, F0, elem_type(F0)[]; check=false) + end + + # prepare the end of the presentation + Z = FreeMod(R, 0) + AbstractAlgebra.set_name!(Z, "0") + M_to_Z = hom(M, Z, elem_type(Z)[zero(Z) for i in 1:ngens(M)]; check=false) + + # compile the presentation complex + CC = Hecke.ComplexOfMorphisms(ModuleFP, ModuleFPHom[F1_to_F0, F0_to_M, M_to_Z], check=false, seed = -2) + set_attribute!(CC, :show => Hecke.pres_show) + return CC +end + function prune_with_map(F::FreeMod) return F, hom(F, F, gens(F)) end From 18a21c6829a2f9665b143ffd1648c672db83a0d6 Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Thu, 9 May 2024 12:53:31 +0200 Subject: [PATCH 2/9] adds `minimal` kw to presentation --- src/Modules/UngradedModules/Presentation.jl | 34 ++++++++++++--------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/Modules/UngradedModules/Presentation.jl b/src/Modules/UngradedModules/Presentation.jl index dbbd24ddc77..7d21cc55211 100644 --- a/src/Modules/UngradedModules/Presentation.jl +++ b/src/Modules/UngradedModules/Presentation.jl @@ -1,11 +1,15 @@ #################### @doc raw""" - presentation(M::SubquoModule) + presentation(M::SubquoModule; minimal=false) -Return a free presentation of `M`. +Return a free presentation of `M`. If `minimal` is set to `true`, the returned +presentation is minimal. """ -function presentation(SQ::SubquoModule) +function presentation(SQ::SubquoModule; + minimal=false) + if minimal + return _presentation_minimal(SQ) if is_graded(SQ) return _presentation_graded(SQ) else @@ -559,8 +563,8 @@ function prune_with_map(M::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldElem}} # return M_new, phi end -function _presentation_minimal(M::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldElem}} - R = base_ring(M) +function _presentation_minimal(SQ::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldElem}} + R = base_ring(SQ) # Prepare to set some names br_name = AbstractAlgebra.get_name(R) @@ -568,17 +572,17 @@ function _presentation_minimal(M::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldEl br_name = "br" end - M_new, phi = prune_with_map(M) - F0 = ambient_free_module(M_new) + SQ_new, phi = prune_with_map(SQ) + F0 = ambient_free_module(SQ_new) # M_new is a quotient of a free module - proj_map = hom(F0, M_new, gens(M_new), check=false) - F0_to_M = compose(proj_map, phi) - F0_to_M.generators_map_to_generators = true - AbstractAlgebra.set_name!(F0, "$br_name^$(ngens(M.sub))") + proj_map = hom(F0, SQ_new, gens(SQ_new), check=false) + F0_to_SQ = compose(proj_map, phi) + F0_to_SQ.generators_map_to_generators = true + AbstractAlgebra.set_name!(F0, "$br_name^$(ngens(SQ.sub))") - K, inc = sub(F0, relations(M_new)) - F1 = if is_graded(M) + K, inc = sub(F0, relations(SQ_new)) + F1 = if is_graded(SQ) graded_free_module(R, degrees_of_generators(K)) else free_module(R, ngens(K)) @@ -595,10 +599,10 @@ function _presentation_minimal(M::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldEl # prepare the end of the presentation Z = FreeMod(R, 0) AbstractAlgebra.set_name!(Z, "0") - M_to_Z = hom(M, Z, elem_type(Z)[zero(Z) for i in 1:ngens(M)]; check=false) + SQ_to_Z = hom(SQ, Z, elem_type(Z)[zero(Z) for i in 1:ngens(SQ)]; check=false) # compile the presentation complex - CC = Hecke.ComplexOfMorphisms(ModuleFP, ModuleFPHom[F1_to_F0, F0_to_M, M_to_Z], check=false, seed = -2) + CC = Hecke.ComplexOfMorphisms(ModuleFP, ModuleFPHom[F1_to_F0, F0_to_SQ, SQ_to_Z], check=false, seed = -2) set_attribute!(CC, :show => Hecke.pres_show) return CC end From 8ad3ad8657908324d0b7c18a849bee2a1e569ec8 Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Thu, 9 May 2024 12:56:51 +0200 Subject: [PATCH 3/9] use minimal kw in `free_resolution` --- src/Modules/UngradedModules/FreeResolutions.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/UngradedModules/FreeResolutions.jl b/src/Modules/UngradedModules/FreeResolutions.jl index 672d8c4696e..e61fe9a35ba 100644 --- a/src/Modules/UngradedModules/FreeResolutions.jl +++ b/src/Modules/UngradedModules/FreeResolutions.jl @@ -313,7 +313,7 @@ function free_resolution(M::SubquoModule{<:MPolyRingElem}; cc_complete = false #= Start with presentation =# - pm = presentation(M) + pm = presentation(M, minimal = algorithm in [:mres, :nres]) maps = [pm.maps[j] for j in 2:3] br = base_ring(M) From 9f41c6a2f6387a60e79a93f42b7747449241bcd6 Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Mon, 13 May 2024 12:18:31 +0200 Subject: [PATCH 4/9] if -> elseif --- src/Modules/UngradedModules/Presentation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/UngradedModules/Presentation.jl b/src/Modules/UngradedModules/Presentation.jl index 7d21cc55211..441948d7898 100644 --- a/src/Modules/UngradedModules/Presentation.jl +++ b/src/Modules/UngradedModules/Presentation.jl @@ -10,7 +10,7 @@ function presentation(SQ::SubquoModule; minimal=false) if minimal return _presentation_minimal(SQ) - if is_graded(SQ) + elseif is_graded(SQ) return _presentation_graded(SQ) else return _presentation_simple(SQ) From 92198c3a0563c4e67f874b60ecc082ef553a09bc Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Tue, 14 May 2024 11:58:28 +0200 Subject: [PATCH 5/9] fix printing --- src/Modules/UngradedModules/Presentation.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/UngradedModules/Presentation.jl b/src/Modules/UngradedModules/Presentation.jl index 441948d7898..0570412fdd5 100644 --- a/src/Modules/UngradedModules/Presentation.jl +++ b/src/Modules/UngradedModules/Presentation.jl @@ -579,7 +579,7 @@ function _presentation_minimal(SQ::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldE proj_map = hom(F0, SQ_new, gens(SQ_new), check=false) F0_to_SQ = compose(proj_map, phi) F0_to_SQ.generators_map_to_generators = true - AbstractAlgebra.set_name!(F0, "$br_name^$(ngens(SQ.sub))") + AbstractAlgebra.set_name!(F0, "$br_name^$(ngens(F0))") K, inc = sub(F0, relations(SQ_new)) F1 = if is_graded(SQ) From 74ef0aef44936aef0525f9cc2f57040c403f7a25 Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Thu, 16 May 2024 18:24:03 +0200 Subject: [PATCH 6/9] minimize kernel in `_presentation_minimal` --- src/Modules/UngradedModules/FreeResolutions.jl | 4 ++-- src/Modules/UngradedModules/Presentation.jl | 8 +++++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Modules/UngradedModules/FreeResolutions.jl b/src/Modules/UngradedModules/FreeResolutions.jl index e61fe9a35ba..b7312236e7b 100644 --- a/src/Modules/UngradedModules/FreeResolutions.jl +++ b/src/Modules/UngradedModules/FreeResolutions.jl @@ -1,4 +1,4 @@ - function map(FR::FreeResolution, i::Int) +function map(FR::FreeResolution, i::Int) return map(FR.C, i) end @@ -313,7 +313,7 @@ function free_resolution(M::SubquoModule{<:MPolyRingElem}; cc_complete = false #= Start with presentation =# - pm = presentation(M, minimal = algorithm in [:mres, :nres]) + pm = algorithm == :mres ? _presentation_minimal(M, minimal_kernel=false) : presentation(M) maps = [pm.maps[j] for j in 2:3] br = base_ring(M) diff --git a/src/Modules/UngradedModules/Presentation.jl b/src/Modules/UngradedModules/Presentation.jl index 0570412fdd5..24ba8ce886d 100644 --- a/src/Modules/UngradedModules/Presentation.jl +++ b/src/Modules/UngradedModules/Presentation.jl @@ -563,7 +563,8 @@ function prune_with_map(M::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldElem}} # return M_new, phi end -function _presentation_minimal(SQ::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldElem}} +function _presentation_minimal(SQ::ModuleFP{T}; + minimal_kernel::Bool=true) where {T<:MPolyRingElem{<:FieldElem}} R = base_ring(SQ) # Prepare to set some names @@ -581,7 +582,12 @@ function _presentation_minimal(SQ::ModuleFP{T}) where {T<:MPolyRingElem{<:FieldE F0_to_SQ.generators_map_to_generators = true AbstractAlgebra.set_name!(F0, "$br_name^$(ngens(F0))") + # if we want a minimal kernel too, we go to prune_with_map K, inc = sub(F0, relations(SQ_new)) + if minimal_kernel + K, inc2 = prune_with_map(K) + inc = compose(inc2, inc) + end F1 = if is_graded(SQ) graded_free_module(R, degrees_of_generators(K)) else From de041603561b95153c909463ace8f336afc4d3ce Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Thu, 16 May 2024 18:33:14 +0200 Subject: [PATCH 7/9] min presentation test --- test/Modules/ModulesGraded.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/Modules/ModulesGraded.jl b/test/Modules/ModulesGraded.jl index a918dbe0929..e37707609ed 100644 --- a/test/Modules/ModulesGraded.jl +++ b/test/Modules/ModulesGraded.jl @@ -339,6 +339,12 @@ end @test codomain(psi) == N @test is_bijective(phi) @test is_bijective(psi) + I = ideal(R, [x^2, x*y, y]) + A, _ = quo(R, I) + M = quotient_ring_as_module(A) + mp = presentation(M, minimal = true) + @test rank(pm[0]) == 1 + @test rank(pm[1]) == 2 end From 5cef808630985698edf2f5280ad64d04e039e8cd Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Tue, 21 May 2024 11:36:58 +0200 Subject: [PATCH 8/9] fix tests --- test/Modules/ModulesGraded.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Modules/ModulesGraded.jl b/test/Modules/ModulesGraded.jl index e37707609ed..8f2c1ae84b5 100644 --- a/test/Modules/ModulesGraded.jl +++ b/test/Modules/ModulesGraded.jl @@ -339,8 +339,8 @@ end @test codomain(psi) == N @test is_bijective(phi) @test is_bijective(psi) - I = ideal(R, [x^2, x*y, y]) - A, _ = quo(R, I) + I = ideal(Rg, [x^2, x*y, y]) + A, _ = quo(Rg, I) M = quotient_ring_as_module(A) mp = presentation(M, minimal = true) @test rank(pm[0]) == 1 From f0641a2c88c07a89f1c284e34f4e8ab7a2cf4e0e Mon Sep 17 00:00:00 2001 From: Rafael Mohr Date: Tue, 21 May 2024 13:23:19 +0200 Subject: [PATCH 9/9] fix tests --- test/Modules/ModulesGraded.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Modules/ModulesGraded.jl b/test/Modules/ModulesGraded.jl index 8f2c1ae84b5..fa11bbea94f 100644 --- a/test/Modules/ModulesGraded.jl +++ b/test/Modules/ModulesGraded.jl @@ -343,8 +343,8 @@ end A, _ = quo(Rg, I) M = quotient_ring_as_module(A) mp = presentation(M, minimal = true) - @test rank(pm[0]) == 1 - @test rank(pm[1]) == 2 + @test rank(mp[0]) == 1 + @test rank(mp[1]) == 2 end