From 427cbe9ce4c7c292872fc639c30ce84ae34ef651 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Fri, 23 Feb 2024 17:50:31 +0100 Subject: [PATCH 01/30] Add QQBar docs to the manual (#3423) * Add QQBar docs to the manual * Update field overview list (cherry picked from commit 7164435c32412bff19049eb7d9e58266acc76c98) --- docs/doc.main | 1 + docs/src/Fields/intro.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/docs/doc.main b/docs/doc.main index fa22649159fa..68d4dc4eab16 100644 --- a/docs/doc.main +++ b/docs/doc.main @@ -57,6 +57,7 @@ "Nemo/qadic.md", ], "Nemo/finitefield.md", + "Nemo/algebraic.md", "Fields/algebraic_closure_fp.md", ], diff --git a/docs/src/Fields/intro.md b/docs/src/Fields/intro.md index 4e49a56979dc..1e83349c33fb 100644 --- a/docs/src/Fields/intro.md +++ b/docs/src/Fields/intro.md @@ -14,6 +14,8 @@ various kinds of fields: - [Generic fraction fields](@ref) - local fields ([Padics](@ref) and [Qadics](@ref)) - finite fields +- [Algebraic numbers](@ref) +- [Algebraic closure of finite prime fields](@ref) General textbooks offering details on theory and algorithms include: - [Coh93](@cite) From ab83c3b99a45677a34e668c471588c8acb676c06 Mon Sep 17 00:00:00 2001 From: ThomasBreuer Date: Fri, 23 Feb 2024 14:38:33 +0100 Subject: [PATCH 02/30] do not show the OscarInterface banner (cherry picked from commit 5f868036710ef8aa50058bb6166b252ce0c2ed7a) --- src/Oscar.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Oscar.jl b/src/Oscar.jl index ee88287a68fe..751cda8469d0 100644 --- a/src/Oscar.jl +++ b/src/Oscar.jl @@ -83,7 +83,7 @@ function __init__() # `Julia.Oscar` if Oscar is loaded indirectly as a package dependency) GAP.Globals.BindGlobal(GapObj("Oscar"), Oscar) GAP.Globals.SetPackagePath(GAP.Obj("OscarInterface"), GAP.Obj(joinpath(@__DIR__, "..", "gap", "OscarInterface"))) - GAP.Globals.LoadPackage(GAP.Obj("OscarInterface")) + GAP.Globals.LoadPackage(GAP.Obj("OscarInterface"), false) withenv("TERMINFO_DIRS" => joinpath(GAP.GAP_jll.Readline_jll.Ncurses_jll.find_artifact_dir(), "share", "terminfo")) do GAP.Packages.load("browse"; install=true) # needed for all_character_table_names doctest end From 69eed70eb9b98e54d5bba6646e2132789f35896e Mon Sep 17 00:00:00 2001 From: Thomas Breuer Date: Mon, 26 Feb 2024 09:41:24 +0100 Subject: [PATCH 03/30] fix bugs in `all_OD_infos` (#3419) * fix bugs in `all_OD_infos` * added a test (cherry picked from commit 3672388e1b0aafa4d3d1e127d8b23df39f86da96) --- .../OrthogonalDiscriminants/src/data.jl | 60 ++++++++++--------- .../OrthogonalDiscriminants/src/utils.jl | 4 +- .../OrthogonalDiscriminants/test/data.jl | 10 ++++ 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/experimental/OrthogonalDiscriminants/src/data.jl b/experimental/OrthogonalDiscriminants/src/data.jl index 069965fb7859..58feb22cd202 100644 --- a/experimental/OrthogonalDiscriminants/src/data.jl +++ b/experimental/OrthogonalDiscriminants/src/data.jl @@ -6,9 +6,40 @@ const OD_data = JSON.parsefile(joinpath(@__DIR__, "../data/odresults.json")) const OD_simple_names = Dict{String, String}() +@doc raw""" + OD_split_string(str::String, sep::String) + +Return a vector of strings obtained by splitting `str` at characters in `sep`, +but only at those positions where the brackets `(` and `)` are balanced. +""" +function OD_split_string(str::String, sep::String) + open = 0 + res = String[] + start = 0 + for i in 1:length(str) + if str[i] == '(' + open = open + 1 + elseif str[i] == ')' + open = open - 1 + elseif str[i] in sep && open == 0 + push!(res, str[(start+1):(i-1)]) + start = i + end + end + push!(res, str[(start+1):length(str)]) + + return res +end + + for simpnam in OD_data["names"] for x in OD_data[simpnam]["names"] OD_simple_names[x] = simpnam + for p in keys(OD_data[simpnam][x]) + for v in OD_data[simpnam][x][p] + v[end] = OD_split_string(v[end], ",") + end + end end end @@ -266,32 +297,6 @@ end __init_OD() -@doc raw""" - OD_split_string(str::String, sep::String) - -Return a vector of strings obtained by splitting `str` at characters in `sep`, -but only at those positions where the brackets `(` and `)` are balanced. -""" -function OD_split_string(str::String, sep::String) - open = 0 - res = String[] - start = 0 - for i in 1:length(str) - if str[i] == '(' - open = open + 1 - elseif str[i] == ')' - open = open - 1 - elseif str[i] in sep && open == 0 - push!(res, str[(start+1):(i-1)]) - start = i - end - end - push!(res, str[(start+1):length(str)]) - - return res -end - - function _od_info(groupname, p, v) return Dict{Symbol, Any}( :groupname => groupname, @@ -491,9 +496,6 @@ function all_od_infos(L...) end good_char || continue for entry in D[string(char)] - if entry[end] isa String - entry[end] = OD_split_string(entry[end], ",") - end good_dim = true if haskey(conditions, Hecke.dim) dim = parse(Int, filter(isdigit, entry[1])) diff --git a/experimental/OrthogonalDiscriminants/src/utils.jl b/experimental/OrthogonalDiscriminants/src/utils.jl index 396016bdde4f..b9fe437dbb1d 100644 --- a/experimental/OrthogonalDiscriminants/src/utils.jl +++ b/experimental/OrthogonalDiscriminants/src/utils.jl @@ -354,7 +354,7 @@ function show_OD_info(tbl::Oscar.GAPGroupCharacterTable, io::IO = stdout) if length(ppos) > 0 ppos = ppos[1] end - if length(ppos) != 0 && !contains(ppos[end], "(indicator unknown)") + if length(ppos) != 0 && !("(indicator unknown)" in ppos[end]) # must be indicator `+` push!(res1, _character_name(modtbls[j], k)) push!(res2, ppos[4]) @@ -364,7 +364,7 @@ function show_OD_info(tbl::Oscar.GAPGroupCharacterTable, io::IO = stdout) # indicator `o` push!(res1, _character_name(modtbls[j], k) * filter(!isdigit, _character_name(modtbls[j], cc))) - push!(res2, orthogonal_discriminant_indicator0(modtbls[j][k])) + push!(res2, _orthogonal_discriminant_indicator0(modtbls[j][k])) elseif cc == k # indicator is *unknown*; # note that indicator `-` (disc is "O+") cannot occur here diff --git a/experimental/OrthogonalDiscriminants/test/data.jl b/experimental/OrthogonalDiscriminants/test/data.jl index 89005c7a5600..8ce0ee4aa24b 100644 --- a/experimental/OrthogonalDiscriminants/test/data.jl +++ b/experimental/OrthogonalDiscriminants/test/data.jl @@ -1,5 +1,15 @@ @testset "all_od_infos" begin + iob = IOBuffer() + show_OD_info("G2(3)", iob) + str1 = String(take!(iob)) + all_entries = all_od_infos(); + @test all_entries isa Vector + + show_OD_info("G2(3)", iob) + str2 = String(take!(iob)) + @test str1 == str2 + @test length(all_entries) == length(all_od_infos(is_simple)) + length(all_od_infos(! is_simple)) @test length(all_entries) == length(all_od_infos(is_sporadic_simple)) + From 82d40ff554600619a9472a917f21e3fa3f4688ad Mon Sep 17 00:00:00 2001 From: Erik Paemurru <143521159+paemurru@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:18:09 +0100 Subject: [PATCH 04/30] Rename Spec to AffineScheme #3345 (#3425) * Rename Spec -> AffineScheme Use `AffineScheme` only for the type, not the function. * Rename proj for toric divisors to projectivization As was recommended by Martin Bies and Wolfram Decker. * Function ProjectiveScheme to projective_scheme and proj * Fix: spec now extends the constructor AffineScheme In particular, spec allows the argument to be a quotient ring or localized ring. Similarly for proj. Probably the tests would not have passed in the previous commit because of this * add support for projective_scheme and affine_scheme --------- Co-authored-by: Simon Brandhorst (cherry picked from commit b00d5e444e1c353ea833340f190fffc522ebabe1) --- .../AlgebraicSets/AffineAlgebraicSet.md | 4 +- .../AlgebraicVarieties/AffineVariety.md | 2 +- .../Schemes/AffineSchemes.md | 50 +- .../Schemes/ArchitectureOfAffineSchemes.md | 56 +-- .../Schemes/CoveredSchemeMorphisms.md | 20 +- .../Schemes/CoveredSchemes.md | 2 +- .../Schemes/CoveringsAndGluings.md | 6 +- .../Schemes/MorphismsOfAffineSchemes.md | 32 +- .../Schemes/ProjectiveSchemes.md | 14 +- .../ToricVarieties/NormalToricVarieties.md | 2 +- .../Experimental/Singularities/space_germs.md | 4 +- experimental/Experimental.jl | 2 +- .../LieAlgebras/src/LieAlgebraModuleHom.jl | 12 +- .../src/MatroidRealizationSpaces.jl | 6 +- .../src/realization_space.jl | 44 +- .../MatroidRealizationSpaces/test/runtests.jl | 4 +- .../QuadFormAndIsom/src/embeddings.jl | 32 +- .../QuadFormAndIsom/src/enumeration.jl | 22 +- .../src/hermitian_miranda_morrison.jl | 6 +- .../src/lattices_with_isometry.jl | 10 +- experimental/Schemes/AlgebraicCycles.jl | 6 +- experimental/Schemes/Auxiliary.jl | 14 +- experimental/Schemes/BlowupMorphism.jl | 152 +++--- experimental/Schemes/CartierDivisor.jl | 18 +- experimental/Schemes/CoherentSheaves.jl | 150 +++--- .../Schemes/CoveredProjectiveSchemes.jl | 452 +++++++++--------- experimental/Schemes/CoveredScheme.jl | 58 +-- experimental/Schemes/FunctionFields.jl | 16 +- experimental/Schemes/IdealSheaves.jl | 246 +++++----- experimental/Schemes/LazyGluing.jl | 32 +- .../Schemes/MorphismFromRationalFunctions.jl | 90 ++-- .../NormalToricVarieties/attributes.jl | 4 +- experimental/Schemes/ProjectiveModules.jl | 88 ++-- experimental/Schemes/Sheaves.jl | 68 +-- ...ifiedSpec.jl => SimplifiedAffineScheme.jl} | 122 ++--- experimental/Schemes/SpaceGerms.jl | 204 ++++---- .../Schemes/ToricIdealSheaves/constructors.jl | 4 +- experimental/Schemes/Types.jl | 106 ++-- experimental/Schemes/WeilDivisor.jl | 8 +- experimental/Schemes/duValSing.jl | 32 +- experimental/Schemes/elliptic_surface.jl | 6 +- .../src/representations.jl | 34 +- .../src/symmetric_grassmannians.jl | 2 +- .../SymmetricIntersections/test/runtests.jl | 8 +- .../Curves/AffinePlaneCurve.jl | 2 +- .../RationalPoint/AffineRationalPoint.jl | 32 +- .../RationalPoint/PointSet.jl | 2 +- .../RationalPoint/ProjectiveRationalPoint.jl | 2 +- src/AlgebraicGeometry/RationalPoint/Types.jl | 2 +- .../Schemes/AbstractTypes.jl | 8 +- .../AffineAlgebraicSet/Objects/Attributes.jl | 10 +- .../Objects/Constructors.jl | 6 +- .../AffineAlgebraicSet/Objects/Types.jl | 6 +- .../Morphisms/Attributes.jl | 32 +- .../Morphisms/Constructors.jl | 68 +-- .../Morphisms/Methods.jl | 54 +-- .../Morphisms/Types.jl | 18 +- .../Objects/Attributes.jl | 155 ++++++ .../Objects/Constructors.jl | 68 +-- .../Objects/Methods.jl | 74 +-- .../Objects/Properties.jl | 8 +- .../Objects/Types.jl | 28 +- .../Rings/Attributes.jl | 61 +++ .../Rings/Constructors.jl | 128 ++--- .../Rings/Methods.jl | 202 ++++---- .../Rings/Properties.jl | 16 + .../Rings/Types.jl | 36 +- .../AffineSchemes/Morphisms/Attributes.jl | 76 +-- .../AffineSchemes/Morphisms/Constructors.jl | 36 +- .../AffineSchemes/Morphisms/Methods.jl | 94 ++-- .../AffineSchemes/Morphisms/Properties.jl | 14 +- .../Schemes/AffineSchemes/Morphisms/Types.jl | 72 +-- .../AffineSchemes/Objects/Attributes.jl | 222 ++++----- .../AffineSchemes/Objects/Constructors.jl | 287 ++++++----- .../Schemes/AffineSchemes/Objects/Methods.jl | 78 +-- .../AffineSchemes/Objects/Properties.jl | 192 ++++---- .../Schemes/AffineSchemes/Objects/Types.jl | 24 +- .../AffineVariety/Objects/Attributes.jl | 2 +- .../AffineVariety/Objects/Constructors.jl | 6 +- .../Schemes/ClosedEmbedding/Attributes.jl | 2 +- .../Schemes/ClosedEmbedding/Types.jl | 16 +- .../CoveredSchemes/Morphisms/Attributes.jl | 12 +- .../CoveredSchemes/Morphisms/Methods.jl | 8 +- .../CoveredSchemes/Objects/Attributes.jl | 14 +- .../CoveredSchemes/Objects/Constructors.jl | 6 +- .../Schemes/CoveredSchemes/Objects/Methods.jl | 6 +- .../Schemes/Covering/Morphisms/Attributes.jl | 2 +- .../Covering/Morphisms/Constructors.jl | 4 +- .../Schemes/Covering/Morphisms/Methods.jl | 20 +- .../Schemes/Covering/Morphisms/Types.jl | 10 +- .../Schemes/Covering/Objects/Attributes.jl | 46 +- .../Schemes/Covering/Objects/Constructors.jl | 24 +- .../Schemes/Covering/Objects/Methods.jl | 66 +-- .../Schemes/Covering/Objects/Types.jl | 24 +- .../Schemes/Gluing/Constructors.jl | 64 +-- .../Schemes/Gluing/Methods.jl | 14 +- src/AlgebraicGeometry/Schemes/Gluing/Types.jl | 42 +- .../PrincipalOpenInclusion/Attributes.jl | 2 +- .../PrincipalOpenInclusion/Constructors.jl | 4 +- .../Schemes/PrincipalOpenInclusion/Types.jl | 12 +- .../PrincipalOpenSubset/Objects/Attributes.jl | 8 +- .../Objects/Constructors.jl | 4 +- .../PrincipalOpenSubset/Objects/Methods.jl | 6 +- .../PrincipalOpenSubset/Objects/Types.jl | 16 +- .../Objects/Constructors.jl | 4 +- .../ProjectiveSchemes/Morphisms/Attributes.jl | 10 +- .../Morphisms/Constructors.jl | 4 +- .../ProjectiveSchemes/Morphisms/Methods.jl | 8 +- .../ProjectiveSchemes/Morphisms/Types.jl | 10 +- .../ProjectiveSchemes/Objects/Attributes.jl | 54 +-- .../ProjectiveSchemes/Objects/Constructors.jl | 43 +- .../ProjectiveSchemes/Objects/Methods.jl | 22 +- .../ProjectiveSchemes/Objects/Properties.jl | 2 +- .../ProjectiveSchemes/Objects/Types.jl | 4 +- .../ProjectiveVariety/Objects/Constructors.jl | 8 +- .../Schemes/SpecOpen/Objects/Attributes.jl | 155 ------ .../Schemes/SpecOpen/Rings/Attributes.jl | 61 --- .../Schemes/SpecOpen/Rings/Properties.jl | 16 - src/AlgebraicGeometry/Schemes/Types.jl | 20 +- src/AlgebraicGeometry/Schemes/main.jl | 30 +- src/AlgebraicGeometry/Surfaces/SurfacesP4.jl | 4 +- .../ToricVarieties/Proj/constructors.jl | 22 +- .../ToricMorphisms/attributes.jl | 2 +- .../ToricVarieties/ToricSchemes/attributes.jl | 48 +- src/Groups/directproducts.jl | 4 +- src/Modules/UngradedModules/SubQuoHom.jl | 60 +-- .../UngradedModules/SubquoModuleElem.jl | 114 ++--- src/Rings/MPolyQuo.jl | 2 +- src/Rings/ReesAlgebra.jl | 61 +-- src/Rings/localization_interface.jl | 100 ++-- src/deprecations.jl | 14 + src/exports.jl | 26 +- src/forward_declarations.jl | 6 +- .../Schemes/AffineRationalPoint.jl | 8 +- ...ecOpen.jl => AffineSchemeOpenSubscheme.jl} | 128 ++--- .../Schemes/AffineSchemes.jl | 55 ++- .../Schemes/AffineVariety.jl | 2 +- .../Schemes/BlowupMorphism.jl | 4 +- .../Schemes/CartierDivisor.jl | 2 +- .../Schemes/CoherentSheaves.jl | 8 +- .../Schemes/CoveredProjectiveSchemes.jl | 8 +- .../Schemes/CoveredScheme.jl | 22 +- .../Schemes/FunctionFields.jl | 16 +- test/AlgebraicGeometry/Schemes/Gluing.jl | 44 +- .../AlgebraicGeometry/Schemes/IdealSheaves.jl | 14 +- test/AlgebraicGeometry/Schemes/K3.jl | 2 +- .../Schemes/MorphismFromRationalFunctions.jl | 4 +- .../Schemes/ProjectiveSchemes.jl | 36 +- .../Schemes/ProjectiveVarieties.jl | 2 +- test/AlgebraicGeometry/Schemes/Sheaves.jl | 24 +- ...ifiedSpec.jl => SimplifiedAffineScheme.jl} | 2 +- test/AlgebraicGeometry/Schemes/SpaceGerms.jl | 46 +- .../AlgebraicGeometry/Schemes/SpecialTypes.jl | 2 +- test/AlgebraicGeometry/Schemes/WeilDivisor.jl | 14 +- test/AlgebraicGeometry/Schemes/duValSing.jl | 6 +- .../Schemes/singular_locus.jl | 48 +- test/AlgebraicGeometry/Schemes/transforms.jl | 6 +- .../{proj.jl => projectivization.jl} | 32 +- test/Groups/directproducts.jl | 10 +- test/Modules/ModulesGraded.jl | 52 +- test/Modules/UngradedModules.jl | 58 +-- 161 files changed, 3204 insertions(+), 3168 deletions(-) rename experimental/Schemes/{SimplifiedSpec.jl => SimplifiedAffineScheme.jl} (80%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Morphisms/Attributes.jl (67%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Morphisms/Constructors.jl (61%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Morphisms/Methods.jl (77%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Morphisms/Types.jl (76%) create mode 100644 src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Attributes.jl rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Objects/Constructors.jl (69%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Objects/Methods.jl (71%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Objects/Properties.jl (64%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Objects/Types.jl (65%) create mode 100644 src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Attributes.jl rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Rings/Constructors.jl (57%) rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Rings/Methods.jl (67%) create mode 100644 src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Properties.jl rename src/AlgebraicGeometry/Schemes/{SpecOpen => AffineSchemeOpenSubscheme}/Rings/Types.jl (57%) delete mode 100644 src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Attributes.jl delete mode 100644 src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Attributes.jl delete mode 100644 src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Properties.jl rename test/AlgebraicGeometry/Schemes/{SpecOpen.jl => AffineSchemeOpenSubscheme.jl} (83%) rename test/AlgebraicGeometry/Schemes/{SimplifiedSpec.jl => SimplifiedAffineScheme.jl} (86%) rename test/AlgebraicGeometry/ToricVarieties/{proj.jl => projectivization.jl} (84%) diff --git a/docs/src/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet.md b/docs/src/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet.md index 3cc824096c29..e32762182099 100644 --- a/docs/src/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet.md +++ b/docs/src/AlgebraicGeometry/AlgebraicSets/AffineAlgebraicSet.md @@ -28,7 +28,7 @@ The algebraic set $X = V(x^2+y^2) \subseteq \mathbb{A}^2$ is irreducible over $k = \mathbb{R}$. But it is the union of two lines over $K = \mathbb{C}$, i.e. $X$ is irreducible but geometrically reducible. See -[`is_irreducible(X::AbsSpec{<:Field, <:MPolyAnyRing})`](@ref) for details. +[`is_irreducible(X::AbsAffineScheme{<:Field, <:MPolyAnyRing})`](@ref) for details. ## Rational points To study the $k$-points, also called $k$-rational points, of the algebraic set $X$ @@ -97,7 +97,7 @@ algebraic_set(f::MPolyRingElem; check::Bool=true) Convert an affine scheme to an affine algebraic set in order to ignore its (non-reduced) scheme structure. ```@docs -algebraic_set(X::Spec; check::Bool=true) +algebraic_set(X::AffineScheme; check::Bool=true) ``` ```@docs diff --git a/docs/src/AlgebraicGeometry/AlgebraicVarieties/AffineVariety.md b/docs/src/AlgebraicGeometry/AlgebraicVarieties/AffineVariety.md index e72715868893..c79b8d363b4c 100644 --- a/docs/src/AlgebraicGeometry/AlgebraicVarieties/AffineVariety.md +++ b/docs/src/AlgebraicGeometry/AlgebraicVarieties/AffineVariety.md @@ -19,7 +19,7 @@ Functionality which is not (yet) provided by a variety-specific implementation, ## Constructors ```@docs variety(I::MPolyIdeal; check=true) -variety(X::AbsSpec{<:Field}; is_reduced=false, check::Bool=true) +variety(X::AbsAffineScheme{<:Field}; is_reduced=false, check::Bool=true) variety(R::MPolyAnyRing; check=true) ``` diff --git a/docs/src/AlgebraicGeometry/Schemes/AffineSchemes.md b/docs/src/AlgebraicGeometry/Schemes/AffineSchemes.md index 3b319b4fa80c..12284886e4c8 100644 --- a/docs/src/AlgebraicGeometry/Schemes/AffineSchemes.md +++ b/docs/src/AlgebraicGeometry/Schemes/AffineSchemes.md @@ -17,14 +17,14 @@ defined over the integers, a finite field or algebraic field extensions of ``\ma ### General constructors -Besides `Spec(R)` for `R` of either one of the types `MPolyRing`, `MPolyQuoRing`, `MPolyLocRing`, or +Besides `spec(R)` for `R` of either one of the types `MPolyRing`, `MPolyQuoRing`, `MPolyLocRing`, or `MPolyQuoLocRing`, we have the following constructors: ```@docs -Spec(R::MPolyRing, I::MPolyIdeal) -Spec(R::MPolyRing, U::AbsMPolyMultSet) -Spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) +spec(R::MPolyRing, I::MPolyIdeal) +spec(R::MPolyRing, U::AbsMPolyMultSet) +spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) ``` -See [`inclusion_morphism(::AbsSpec, ::AbsSpec)`](@ref) for a way to obtain the ideal ``I`` from ``X = \mathrm{Spec}(R, I)``. +See [`inclusion_morphism(::AbsAffineScheme, ::AbsAffineScheme)`](@ref) for a way to obtain the ideal ``I`` from ``X = \mathrm{Spec}(R, I)``. ### Affine n-space @@ -36,27 +36,27 @@ affine_space(kk::BRT, var_symbols::Vector{Symbol}) where {BRT<:Ring} ### Closed subschemes ```@docs -subscheme(X::AbsSpec, f::Vector{<:RingElem}) -subscheme(X::AbsSpec, I::Ideal) +subscheme(X::AbsAffineScheme, f::Vector{<:RingElem}) +subscheme(X::AbsAffineScheme, I::Ideal) ``` ### Intersections ```@docs -Base.intersect(X::AbsSpec{BRT, <:Ring}, Y::AbsSpec{BRT, <:Ring}) where {BRT<:Ring} +Base.intersect(X::AbsAffineScheme{BRT, <:Ring}, Y::AbsAffineScheme{BRT, <:Ring}) where {BRT<:Ring} ``` ### Open subschemes ```@docs -hypersurface_complement(X::AbsSpec, f::RingElem) -hypersurface_complement(X::AbsSpec, f::Vector{<:RingElem}) +hypersurface_complement(X::AbsAffineScheme, f::RingElem) +hypersurface_complement(X::AbsAffineScheme, f::Vector{<:RingElem}) ``` ### Closure ```@docs -closure(X::AbsSpec, Y::AbsSpec) +closure(X::AbsAffineScheme, Y::AbsAffineScheme) ``` @@ -67,24 +67,24 @@ closure(X::AbsSpec, Y::AbsSpec) Most affine schemes in Oscar ``X = \mathrm{Spec}(R)`` over a ring ``B``, come with an embedding into an affine space ``\mathbb{A}_B``. -More precisely, `ambient_space(X)` is defined for `X = Spec(R)` if `R` +More precisely, `ambient_space(X)` is defined for `X = spec(R)` if `R` is constructed from a polynomial ring. In particular ``\mathrm{Spec}(\mathbb{Z})`` or ``\mathrm{Spec}(\mathbb{k})`` for ``\mathbb k`` a field do not have an ambient affine space. ```@docs -ambient_space(X::AbsSpec) +ambient_space(X::AbsAffineScheme) ``` ### Other attributes ```@docs -base_ring(X::AbsSpec) -codim(X::AbsSpec) -ambient_embedding(X::AbsSpec) -dim(X::AbsSpec) -name(X::AbsSpec) -OO(X::AbsSpec) +base_ring(X::AbsAffineScheme) +codim(X::AbsAffineScheme) +ambient_embedding(X::AbsAffineScheme) +dim(X::AbsAffineScheme) +name(X::AbsAffineScheme) +OO(X::AbsAffineScheme) ``` ### Type getters @@ -97,16 +97,16 @@ source code for details. ## Properties ```@docs -is_open_embedding(X::AbsSpec, Y::AbsSpec) -is_closed_embedding(X::AbsSpec, Y::AbsSpec) -isempty(X::AbsSpec) -is_subscheme(X::AbsSpec, Y::AbsSpec) +is_open_embedding(X::AbsAffineScheme, Y::AbsAffineScheme) +is_closed_embedding(X::AbsAffineScheme, Y::AbsAffineScheme) +isempty(X::AbsAffineScheme) +is_subscheme(X::AbsAffineScheme, Y::AbsAffineScheme) ``` ## Methods ```@docs -tangent_space(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint) +tangent_space(X::AbsAffineScheme{<:Field}, P::AbsAffineRationalPoint) ``` ### Comparison @@ -119,5 +119,5 @@ For ``X`` and ``Y`` with different ambient affine space `X==Y` is always `false` ### Auxiliary methods ```@docs -is_non_zero_divisor(f::RingElem, X::AbsSpec) +is_non_zero_divisor(f::RingElem, X::AbsAffineScheme) ``` diff --git a/docs/src/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes.md b/docs/src/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes.md index 3a07e13f4354..29ddebd8c345 100644 --- a/docs/src/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes.md +++ b/docs/src/AlgebraicGeometry/Schemes/ArchitectureOfAffineSchemes.md @@ -30,7 +30,7 @@ The latter function must return a vector ``v = (a_1,\dots, a_r)`` of elements in ``R`` such that ``f = a_1 \cdot g_1 + \dots + a_r \cdot g_r`` where ``g_1,\dots,g_r`` is the set of `gens(I)`. When ``f`` does not belong to ``I``, it must error. Note that the ring returned by -`quo` must again be admissible for the `AbsSpec` interface. +`quo` must again be admissible for the `AbsAffineScheme` interface. With a view towards the use of the `ambient_coordinate_ring(X)` for computations, it is customary to also implement @@ -83,68 +83,68 @@ Note that the morphism ``P → R`` is induced by natural coercions. The abstract type for affine schemes is ```@docs - AbsSpec{BaseRingType, RingType<:Ring} + AbsAffineScheme{BaseRingType, RingType<:Ring} ``` For any concrete instance of this type, we require the following functions to be implemented: -- `base_ring(X::AbsSpec)`, -- `OO(X::AbsSpec)`. +- `base_ring(X::AbsAffineScheme)`, +- `OO(X::AbsAffineScheme)`. A concrete instance of this type is ```@docs - Spec{BaseRingType, RingType} + AffineScheme{BaseRingType, RingType} ``` It provides an implementation of affine schemes for rings ``R`` of type `MPolyRing`, `MPolyQuoRing`, `MPolyLocRing`, and `MPolyQuoLocRing` defined over the integers or algebraic field extensions of ``\mathbb Q``. This minimal implementation can be used internally, when deriving new -concrete types `MySpec<:AbsSpec` such as, for instance, +concrete types `MyAffineScheme<:AbsAffineScheme` such as, for instance, group schemes, toric schemes, schemes of a particular dimension like curves and surfaces, etc. To this end, one has to store -an instance `Y` of `Spec` in `MySpec` and implement the methods +an instance `Y` of `AffineScheme` in `MyAffineScheme` and implement the methods ``` - underlying_scheme(X::MySpec)::Spec # return Y as above + underlying_scheme(X::MyAffineScheme)::AffineScheme # return Y as above ``` -Then all methods implemented for `Spec` are automatically -forwarded to any instance of `MySpec`. +Then all methods implemented for `AffineScheme` are automatically +forwarded to any instance of `MyAffineScheme`. -**Note:** The above method necessarily returns an instance of `Spec`! -Of course, it can be overwritten for any higher type `MySpec<:AbsSpec` as needed. +**Note:** The above method necessarily returns an instance of `AffineScheme`! +Of course, it can be overwritten for any higher type `MyAffineScheme<:AbsAffineScheme` as needed. ## Existing types of affine scheme morphisms and how to derive new types Any abstract morphism of affine schemes is of the following type: ```@docs - AbsSpecMor{DomainType<:AbsSpec, - CodomainType<:AbsSpec, + AbsAffineSchemeMor{DomainType<:AbsAffineScheme, + CodomainType<:AbsAffineScheme, PullbackType<:Map, MorphismType, BaseMorType } ``` Any such morphism has the attributes `domain`, `codomain` and `pullback`. -A concrete and minimalistic implementation exist for the type `SpecMor`: +A concrete and minimalistic implementation exist for the type `AffineSchemeMor`: ```@docs - SpecMor{DomainType<:AbsSpec, - CodomainType<:AbsSpec, + AffineSchemeMor{DomainType<:AbsAffineScheme, + CodomainType<:AbsAffineScheme, PullbackType<:Map } ``` This basic functionality consists of -- `compose(f::AbsSpecMor, g::AbsSpecMor)`, -- `identity_map(X::AbsSpec)`, -- `restrict(f::AbsSpecMor, X::AbsSpec, Y::AbsSpec; check::Bool=true)`, -- `==(f::AbsSpecMor, g::AbsSpecMor)`, -- `preimage(f::AbsSpecMor, Z::AbsSpec)`. -In particular, for every concrete instance of a type `MySpec<:AbsSpec` that -implements `underlying_scheme`, this basic functionality of `SpecMor` +- `compose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)`, +- `identity_map(X::AbsAffineScheme)`, +- `restrict(f::AbsAffineSchemeMor, X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true)`, +- `==(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor)`, +- `preimage(f::AbsAffineSchemeMor, Z::AbsAffineScheme)`. +In particular, for every concrete instance of a type `MyAffineScheme<:AbsAffineScheme` that +implements `underlying_scheme`, this basic functionality of `AffineSchemeMor` should run naturally. -We may derive higher types of morphisms of affine schemes `MySpecMor<:AbsSpecMor` -by storing an instance `g` of `SpecMor` inside an instance `f` of -`MySpecMor` and implementing +We may derive higher types of morphisms of affine schemes `MyAffineSchemeMor<:AbsAffineSchemeMor` +by storing an instance `g` of `AffineSchemeMor` inside an instance `f` of +`MyAffineSchemeMor` and implementing ``` - underlying_morphism(f::MySpecMor)::SpecMor # return g + underlying_morphism(f::MyAffineSchemeMor)::AffineSchemeMor # return g ``` For example, this allows us to define closed embeddings. diff --git a/docs/src/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms.md b/docs/src/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms.md index 8ed580fb6c05..0fa5007cf320 100644 --- a/docs/src/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms.md +++ b/docs/src/AlgebraicGeometry/Schemes/CoveredSchemeMorphisms.md @@ -15,9 +15,9 @@ This information is held by a `CoveringMorphism`: The basic functionality of `CoveringMorphism`s comprises `domain` and `codomain` which both return a `Covering`, together with ``` - getindex(f::CoveringMorphism, U::AbsSpec) + getindex(f::CoveringMorphism, U::AbsAffineScheme) ``` -which for ``U = U_i`` returns the `AbsSpecMor` ``f_i : U_i \to V_{F(i)}``. +which for ``U = U_i`` returns the `AbsAffineSchemeMor` ``f_i : U_i \to V_{F(i)}``. Note that, in general, neither the `domain` nor the `codomain` of the `covering_morphism` of `f : X \to Y` need to coincide with the `default_covering` of ``X``, respectively ``Y``. @@ -34,8 +34,8 @@ interface. ``` For the user's convenience, also the domain and codomain of the underlying `covering_morphism` are forwarded as `domain_covering` and -`codomain_covering`, respectively, together with `getindex(phi::CoveringMorphism, U::AbsSpec)` -as `getindex(f::AbsCoveredSchemeMorphism, U::AbsSpec)`. +`codomain_covering`, respectively, together with `getindex(phi::CoveringMorphism, U::AbsAffineScheme)` +as `getindex(f::AbsCoveredSchemeMorphism, U::AbsAffineScheme)`. The minimal concrete type of an `AbsCoveredSchemeMorphism` which implements this interface, is `CoveredSchemeMorphism`. @@ -81,12 +81,12 @@ there is no need to realize the full `covering_morphism` of ``f``. In order to facilitate such computations as lazy as possible, there are various fine-grained entry points and caching mechanisms to realize ``f`` on open subsets: ```@docs - realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsSpec) - realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) - realization_preview(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) - random_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) - cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) - realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) + realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme) + realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) + realization_preview(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) + random_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) + cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) + realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) realize(Phi::MorphismFromRationalFunctions) ``` diff --git a/docs/src/AlgebraicGeometry/Schemes/CoveredSchemes.md b/docs/src/AlgebraicGeometry/Schemes/CoveredSchemes.md index cade2cf0c97b..5917d757880f 100644 --- a/docs/src/AlgebraicGeometry/Schemes/CoveredSchemes.md +++ b/docs/src/AlgebraicGeometry/Schemes/CoveredSchemes.md @@ -65,7 +65,7 @@ Every element $U$ of the `affine_charts` of $D$ is either * directly an element of the `affine_charts` of $C$; * a `PrincipalOpenSubset` with some ancestor in the `affine_charts` of $C$; - * a `SimplifiedSpec` with some original in the `affine_charts` of $C$. + * a `SimplifiedAffineScheme` with some original in the `affine_charts` of $C$. In all these cases, the affine subsets in the refinements form a tree and thus remember their origins and ambient spaces. In particular, affine patches and also their gluings can be recycled diff --git a/docs/src/AlgebraicGeometry/Schemes/CoveringsAndGluings.md b/docs/src/AlgebraicGeometry/Schemes/CoveringsAndGluings.md index 478d7bac1fe3..756e1fc08403 100644 --- a/docs/src/AlgebraicGeometry/Schemes/CoveringsAndGluings.md +++ b/docs/src/AlgebraicGeometry/Schemes/CoveringsAndGluings.md @@ -11,7 +11,7 @@ CurrentModule = Oscar ## Constructors ```@docs - Covering(patches::Vector{<:AbsSpec}) + Covering(patches::Vector{<:AbsAffineScheme}) disjoint_union(C1::Covering, C2::Covering) ``` @@ -44,7 +44,7 @@ The available concrete types are ## Constructors ```@docs - Gluing(X::AbsSpec, Y::AbsSpec, f::SchemeMor, g::SchemeMor) + Gluing(X::AbsAffineScheme, Y::AbsAffineScheme, f::SchemeMor, g::SchemeMor) ``` ## Attributes @@ -59,7 +59,7 @@ The available concrete types are ```@docs compose(G::AbsGluing, H::AbsGluing) maximal_extension(G::Gluing) - restrict(G::AbsGluing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true) + restrict(G::AbsGluing, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; check::Bool=true) ``` diff --git a/docs/src/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes.md b/docs/src/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes.md index 018cae7fac11..d251082e3b8a 100644 --- a/docs/src/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes.md +++ b/docs/src/AlgebraicGeometry/Schemes/MorphismsOfAffineSchemes.md @@ -11,16 +11,16 @@ CurrentModule = Oscar ### General constructors ```@docs -morphism(X::AbsSpec, Y::AbsSpec, f::Vector{<:RingElem}; check::Bool=true) +morphism(X::AbsAffineScheme, Y::AbsAffineScheme, f::Vector{<:RingElem}; check::Bool=true) ``` ### Special constructors ```@docs -identity_map(X::AbsSpec{<:Any, <:MPolyRing}) -inclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true) -compose(f::AbsSpecMor, g::AbsSpecMor) -restrict(f::SpecMor, U::AbsSpec, V::AbsSpec) +identity_map(X::AbsAffineScheme{<:Any, <:MPolyRing}) +inclusion_morphism(X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true) +compose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) +restrict(f::AffineSchemeMor, U::AbsAffineScheme, V::AbsAffineScheme) ``` @@ -29,16 +29,16 @@ restrict(f::SpecMor, U::AbsSpec, V::AbsSpec) ### General attributes ```@docs -domain(f::AbsSpecMor) -codomain(f::AbsSpecMor) -pullback(f::AbsSpecMor) -graph(f::AbsSpecMor) +domain(f::AbsAffineSchemeMor) +codomain(f::AbsAffineSchemeMor) +pullback(f::AbsAffineSchemeMor) +graph(f::AbsAffineSchemeMor) ``` ### Special attributes In addition to the standard getters and methods for instances -of `SpecMor`, we also have +of `AffineSchemeMor`, we also have ```@docs image_ideal(f::ClosedEmbedding) ``` @@ -57,16 +57,16 @@ The following functions do exist but are currently undocumented: ## Properties ```@docs -is_isomorphism(f::AbsSpecMor) -is_inverse_of(f::AbsSpecMor, g::AbsSpecMor) -is_identity_map(f::AbsSpecMor) +is_isomorphism(f::AbsAffineSchemeMor) +is_inverse_of(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) +is_identity_map(f::AbsAffineSchemeMor) ``` ## Methods ```@docs -fiber_product(f::AbsSpecMor, g::AbsSpecMor) -product(X::AbsSpec, Y::AbsSpec) -simplify(X::AbsSpec{<:AbstractAlgebra.Field}) +fiber_product(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) +product(X::AbsAffineScheme, Y::AbsAffineScheme) +simplify(X::AbsAffineScheme{<:AbstractAlgebra.Field}) ``` diff --git a/docs/src/AlgebraicGeometry/Schemes/ProjectiveSchemes.md b/docs/src/AlgebraicGeometry/Schemes/ProjectiveSchemes.md index c00d14fe874a..67792d9beef6 100644 --- a/docs/src/AlgebraicGeometry/Schemes/ProjectiveSchemes.md +++ b/docs/src/AlgebraicGeometry/Schemes/ProjectiveSchemes.md @@ -46,13 +46,13 @@ The minimal concrete type realizing this interface is ## Constructors -Besides `ProjectiveScheme(S)` for some graded polynomial ring or a graded affine algebra `S`, we +Besides `proj(S)` for some graded polynomial ring or a graded affine algebra `S`, we provide the following constructors: ``` - projective_scheme(S::MPolyDecRing) - projective_scheme(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem} - projective_scheme(I::MPolyIdeal{<:MPolyDecRingElem}) - projective_scheme(Q::MPolyQuoRing{MPolyDecRingElem{T, PT}}) where {T, PT<:MPolyRingElem{T}} = ProjectiveScheme(Q) + proj(S::MPolyDecRing) + proj(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem} + proj(I::MPolyIdeal{<:MPolyDecRingElem}) + proj(Q::MPolyQuoRing{<:MPolyDecRingElem}) ``` Subschemes defined by homogeneous ideals, ring elements, or lists of elements can be created via the respective methods of the `subscheme(P::AbsProjectiveScheme, ...)` function. @@ -79,8 +79,8 @@ Besides those attributes already covered by the above general interface we have To facilitate the interplay between an `AbsProjectiveScheme` and the affine charts of its `covered_scheme` we provide the following methods: ```@docs - dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec) - homogenization_map(P::AbsProjectiveScheme, U::AbsSpec) + dehomogenization_map(X::AbsProjectiveScheme, U::AbsAffineScheme) + homogenization_map(P::AbsProjectiveScheme, U::AbsAffineScheme) ``` ## Properties diff --git a/docs/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties.md b/docs/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties.md index 58c85973cbb8..b5c04df55f94 100644 --- a/docs/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties.md +++ b/docs/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties.md @@ -84,7 +84,7 @@ normal_toric_varieties_from_glsm(charges::ZZMatrix) ```@docs Base.:*(v::NormalToricVarietyType, w::NormalToricVarietyType) -proj(E::ToricLineBundle...) +projectivization(E::ToricLineBundle...) total_space(E::ToricLineBundle...) ``` diff --git a/docs/src/Experimental/Singularities/space_germs.md b/docs/src/Experimental/Singularities/space_germs.md index 0457ead8759d..b00657e5885e 100644 --- a/docs/src/Experimental/Singularities/space_germs.md +++ b/docs/src/Experimental/Singularities/space_germs.md @@ -48,12 +48,12 @@ In general, space germs in OSCAR are created in the following ways: * localization of an affine scheme at a point ```julia - SpaceGerm(X::AbsSpec, I::Ideal) + SpaceGerm(X::AbsAffineScheme, I::Ideal) ``` where I is a (maximal) ideal describing the chosen ${\mathbb k}$-point on the affine ${\mathbb k}$-scheme X. **Provides:** SpaceGerm. ```julia - germ_at_point(X::AbsSpec, I::Ideal) + germ_at_point(X::AbsAffineScheme, I::Ideal) ``` where I is a (maximal) ideal describing the chosen ${\mathbb k}$-point on the affine ${\mathbb k}$-scheme. diff --git a/experimental/Experimental.jl b/experimental/Experimental.jl index 6dbb42a6db7e..59a94fbb2f5e 100644 --- a/experimental/Experimental.jl +++ b/experimental/Experimental.jl @@ -58,7 +58,7 @@ include("Schemes/AlgebraicCycles.jl") include("Schemes/WeilDivisor.jl") include("Schemes/CoveredProjectiveSchemes.jl") -include("Schemes/SimplifiedSpec.jl") +include("Schemes/SimplifiedAffineScheme.jl") include("Schemes/CoherentSheaves.jl") include("Schemes/LazyGluing.jl") include("Schemes/CartierDivisor.jl") diff --git a/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl b/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl index f544f7a07fd2..c92d9c2dc337 100644 --- a/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl +++ b/experimental/LieAlgebras/src/LieAlgebraModuleHom.jl @@ -45,7 +45,7 @@ end @doc raw""" matrix(h::LieAlgebraModuleHom) -> MatElem - + Return the transformation matrix of `h` w.r.t. the bases of the domain and codomain. Note: The matrix operates on the coefficient vectors from the right. @@ -201,7 +201,7 @@ end @doc raw""" hom(V1::LieAlgebraModule, V2::LieAlgebraModule, imgs::Vector{<:LieAlgebraModuleElem}; check::Bool=true) -> LieAlgebraModuleHom -Construct the homomorphism from `V1` to `V2` by sending the `i`-th basis element of `V1` +Construct the homomorphism from `V1` to `V2` by sending the `i`-th basis element of `V1` to `imgs[i]` and extending linearly. All elements of `imgs` must lie in `V2`. Currently, `V1` and `V2` must be modules over the same Lie algebra. @@ -260,7 +260,7 @@ julia> h = hom(V1, V2, matrix(QQ, 3, 1, [0, 0, 0])) Lie algebra module morphism from standard module of dimension 3 over gl_3 to abstract Lie algebra module of dimension 1 over gl_3 - + julia> [(v, h(v)) for v in basis(V1)] 3-element Vector{Tuple{LieAlgebraModuleElem{QQFieldElem}, LieAlgebraModuleElem{QQFieldElem}}}: (v_1, 0) @@ -420,8 +420,8 @@ end hom_direct_sum(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Matrix{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom hom_direct_sum(V::LieAlgebraModule{C}, W::LieAlgebraModule{C}, hs::Vector{<:LieAlgebraModuleHom}) -> LieAlgebraModuleHom -Given modules `V` and `W` which are direct sums with `r` respective `s` summands, -say $M = M_1 \oplus \cdots \oplus M_r$, $N = N_1 \oplus \cdots \oplus N_s$, and given a $r \times s$ matrix +Given modules `V` and `W` which are direct sums with `r` respective `s` summands, +say $M = M_1 \oplus \cdots \oplus M_r$, $N = N_1 \oplus \cdots \oplus N_s$, and given a $r \times s$ matrix `hs` of homomorphisms $h_{ij} : V_i \to W_j$, return the homomorphism $V \to W$ with $ij$-components $h_{ij}$. @@ -471,7 +471,7 @@ end Given modules `V` and `W` which are tensor products with the same number of factors, say $V = V_1 \otimes \cdots \otimes V_r$, $W = W_1 \otimes \cdots \otimes W_r$, -and given a vector `hs` of homomorphisms $a_i : V_i \to W_i$, return +and given a vector `hs` of homomorphisms $a_i : V_i \to W_i$, return $a_1 \otimes \cdots \otimes a_r$. This works for $r$th tensor powers as well. diff --git a/experimental/MatroidRealizationSpaces/src/MatroidRealizationSpaces.jl b/experimental/MatroidRealizationSpaces/src/MatroidRealizationSpaces.jl index bf15094d83e7..e8ab21f08a8d 100644 --- a/experimental/MatroidRealizationSpaces/src/MatroidRealizationSpaces.jl +++ b/experimental/MatroidRealizationSpaces/src/MatroidRealizationSpaces.jl @@ -2,12 +2,12 @@ include("realization_space.jl") ### Methods for realization spaces of matroids function underlying_scheme(RS::MatroidRealizationSpace{BRT, RT}) where {BRT<:Ring, RT<:MPolyQuoLocRing} - isdefined(RS, :underlying_scheme) && return RS.underlying_scheme::Spec{BRT, RT} + isdefined(RS, :underlying_scheme) && return RS.underlying_scheme::AffineScheme{BRT, RT} P = ambient_ring(RS)::MPolyRing I = defining_ideal(RS)::MPolyIdeal U = MPolyPowersOfElement(P, P.(inequations(RS)))::MPolyPowersOfElement - RS.underlying_scheme = Spec(P, I, U) - return RS.underlying_scheme::Spec{BRT, RT} + RS.underlying_scheme = spec(P, I, U) + return RS.underlying_scheme::AffineScheme{BRT, RT} end diff --git a/experimental/MatroidRealizationSpaces/src/realization_space.jl b/experimental/MatroidRealizationSpaces/src/realization_space.jl index 68992f673ac7..01d0c8699bac 100644 --- a/experimental/MatroidRealizationSpaces/src/realization_space.jl +++ b/experimental/MatroidRealizationSpaces/src/realization_space.jl @@ -1,5 +1,5 @@ -@attributes mutable struct MatroidRealizationSpace{BaseRingType, RingType} <: AbsSpec{BaseRingType, RingType} +@attributes mutable struct MatroidRealizationSpace{BaseRingType, RingType} <: AbsAffineScheme{BaseRingType, RingType} defining_ideal::Union{Ideal,NumFieldOrderIdeal} inequations::Vector{RingElem} ambient_ring::Ring @@ -8,9 +8,9 @@ q::Union{Int,Nothing} ground_ring::Ring one_realization::Bool - + # Fields for caching - underlying_scheme::AbsSpec{BaseRingType, RingType} + underlying_scheme::AbsAffineScheme{BaseRingType, RingType} function MatroidRealizationSpace( I::Union{Ideal,NumFieldOrderIdeal}, @@ -64,13 +64,13 @@ end is_realizable(M; char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing) * If char = nothing, then this function determines whether the matroid is realizable over some field. - + * If `char == 0`, then this function determines whether the matroid is realizable over some field of characteristic 0. - + * If char = p is prime, this function determines whether the matroid is realizable over the finite field ``GF(p)``. - + * If `char == p` and `q` is a power of `p`, this function determines whether the matroid is realizable over the finite field ``GF(q)``. """ @@ -112,12 +112,12 @@ inequations(RS::MatroidRealizationSpace) = RS.inequations @doc raw""" ambient_ring(RS::MatroidRealizationSpace) -The polynomial ring containing the ideal `defining_ideal(RS)` and the polynomials in `inequations(RS)`. +The polynomial ring containing the ideal `defining_ideal(RS)` and the polynomials in `inequations(RS)`. """ ambient_ring(RS::MatroidRealizationSpace) = RS.ambient_ring -### The following method uses types which are declared only later. -# Hence hit has been moved to +### The following method uses types which are declared only later. +# Hence hit has been moved to # # src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl. #= @@ -127,7 +127,7 @@ function underlying_scheme(RS::MatroidRealizationSpace{<:Field, <:MPolyQuoLocRin P = ambient_ring(RS)::MPolyRing I = defining_ideal(RS)::MPolyIdeal U = powers_of_element(inequations)::MPolyPowersOfElement - RS.underlying_scheme = Spec(R, I, U) + RS.underlying_scheme = spec(R, I, U) return RS.underlying_scheme end =# @@ -139,7 +139,7 @@ end realization_matrix(RS::MatroidRealizationSpace) A matrix with entries in ambient_ring(RS) whose columns, when filled in with values satisfying equalities -from `defining_ideal(RS)` and inequations from `inequations(RS)`, form a realization for the matroid. +from `defining_ideal(RS)` and inequations from `inequations(RS)`, form a realization for the matroid. """ realization_matrix(RS::MatroidRealizationSpace) = RS.realization_matrix @@ -229,7 +229,7 @@ end q::Union{Int,Nothing}=nothing, ground_ring::Ring=ZZ )::MatroidRealizationSpace - + This function returns the data for the coordinate ring of the matroid realization space of the matroid `M` as a `MatroidRealizationSpace`. This function has several optional parameters. @@ -441,12 +441,12 @@ function find_good_basis_heuristically(M::Matroid) return min_basis end -# Return the prime divisors of f. +# Return the prime divisors of f. function poly_2_prime_divisors(f::RingElem) return map(first, factor(f)) end -# Return the unique prime divisors of the elements of Sgen, again no exponents. +# Return the unique prime divisors of the elements of Sgen, again no exponents. function gens_2_prime_divisors(Sgens::Vector{<:RingElem}) return unique!(vcat([poly_2_prime_divisors(f) for f in Sgens]...)) end @@ -459,29 +459,29 @@ function stepwise_saturation(I::MPolyIdeal, Sgens::Vector{<:RingElem}) end @doc raw""" - realization(M::Matroid; B::Union{GroundsetType,Nothing} = nothing, - saturate::Bool=false, + realization(M::Matroid; B::Union{GroundsetType,Nothing} = nothing, + saturate::Bool=false, char::Union{Int,Nothing}=nothing, q::Union{Int,Nothing}=nothing )::MatroidRealizationSpace - + This function tries to find one realization in the matroid realization space of -the matroid `M`. The output is again a `MatroidRealizationSpace`. +the matroid `M`. The output is again a `MatroidRealizationSpace`. If the matroid is only realizable over an extension of the prime field the extension field is specified as a splitting field of an irreducible polynomial. -Every root of this polynomial gives an equivalent realization of the matroid. +Every root of this polynomial gives an equivalent realization of the matroid. This function has several optional parameters. Note that one must input either -the characteristic or a specific field of definition for the realization. +the characteristic or a specific field of definition for the realization. * `B` is a basis of M that specifies which columns of `realization_matrix(M)` form the identity matrix. The default is `nothing`, in which case the basis is chosen for you. - + * `char` specifies the characteristic of the coefficient ring, and is used to determine if the matroid is realizable over a field of this characteristic. The default is `nothing`. -* `q` is an integer, and when char = p, this input is used to determine whether the matroid +* `q` is an integer, and when char = p, this input is used to determine whether the matroid is realizable over the finite field ``GF(p^{q})``. The default is `nothing`. * `reduce` determines whether a reduced realization space is returned which means that the equations diff --git a/experimental/MatroidRealizationSpaces/test/runtests.jl b/experimental/MatroidRealizationSpaces/test/runtests.jl index a6c73587ca9b..379dd98855fc 100644 --- a/experimental/MatroidRealizationSpaces/test/runtests.jl +++ b/experimental/MatroidRealizationSpaces/test/runtests.jl @@ -133,11 +133,11 @@ end @testset "realization spaces as schemes" begin X = realization_space(pappus_matroid()) - @test X isa AbsSpec + @test X isa AbsAffineScheme @test !isdefined(X, :underlying_scheme) R = OO(X) @test R isa Oscar.MPolyQuoLocRing f = sum(gens(R)) U = PrincipalOpenSubset(X, f) - @test U isa AbsSpec + @test U isa AbsAffineScheme end diff --git a/experimental/QuadFormAndIsom/src/embeddings.jl b/experimental/QuadFormAndIsom/src/embeddings.jl index 2f6b81d8d3d8..845f42205858 100644 --- a/experimental/QuadFormAndIsom/src/embeddings.jl +++ b/experimental/QuadFormAndIsom/src/embeddings.jl @@ -110,7 +110,7 @@ function _rho_functor(q::TorQuadModule, p::IntegerUnion, l::IntegerUnion; quad:: fr = false end mqf = fr ? QQ(2) : QQ(1) - if l == 0 + if l == 0 Gl = N Gm = intersect(1//p*N, Nv) rholN = torsion_quadratic_module(Gl, p*Gm; modulus = QQ(1), modulus_qf = mqf) @@ -917,7 +917,7 @@ function _subgroups_orbit_representatives_and_stabilizers_elementary(Vinq::TorQu satV, _ = kernel(GtoMGp) g-ngens(snf(abelian_group(H0))[1]) >= dim(Qp) && return res - + F = base_ring(Qp) # K is H0 but seen a subvector space of Vp (which is V) K = kernel(VptoQp.matrix; side = :left) @@ -1299,7 +1299,7 @@ function primitive_embeddings(G::ZZGenus, M::ZZLat; classification::Symbol = :su # Proposition 1.6.1 [Nik79] # # In the non-even case, we need to consider several cases, i.e double odd, - # even-odd or odd-even. + # even-odd or odd-even. # # The complement can be even with discriminant form being # qM(-1), or odd with discriminant form being bM(-1). @@ -1653,11 +1653,11 @@ function admissible_equivariant_primitive_extensions(A::ZZLatWithIsom, p::IntegerUnion, q::IntegerUnion = p; check::Bool = true) # p and q can be equal, and they will be most of the time - @req is_prime(p) && is_prime(q) "p and q must be a prime number" + @req is_prime(p) && is_prime(q) "p and q must be a prime number" # Requirements for [BH23] same_ambient = ambient_space(lattice(A)) === ambient_space(lattice(B)) === ambient_space(lattice(C)) - if check + if check @req all(L -> is_integral(L), [A, B, C]) "Underlying lattices must be integral" chiA = minimal_polynomial(A) chiB = minimal_polynomial(parent(chiA), isometry(B)) @@ -1745,7 +1745,7 @@ function admissible_equivariant_primitive_extensions(A::ZZLatWithIsom, # rho_{l+1}(B) (this works only when `p == 2`). In all the other cases, then # admissible gluings only induce isometries of finite bilinear modules between # rho_{l+1}(A) and rho_{l+1}(B). - spec = (p == 2) && (_is_free(qA, p, l+1)) && (_is_free(qB, p, l+1)) && (_is_even(qC, p, l)) + special = (p == 2) && (_is_free(qA, p, l+1)) && (_is_free(qB, p, l+1)) && (_is_even(qC, p, l)) # We look for the GA|GB-invariant and fA|fB-stable subgroups of VA|VB which respectively # contained lpqA|lpqB, where pqA and pqB are respectively the p-primary parts of qA and qB. @@ -1784,13 +1784,13 @@ function admissible_equivariant_primitive_extensions(A::ZZLatWithIsom, # we need a first admissible gluing. We know that such gluing exists because # we have an admissible triple as input and the glue kernels have been # chosen in such a way that their exist an admissible gluing between them. - phi = _find_admissible_gluing(SAinqA, SBinqB, phi, l, p, spec) + phi = _find_admissible_gluing(SAinqA, SBinqB, phi, l, p, special) # We want all isometries of SB which preserves p^l*q_B and such that they - # define isometries of rho_{l+1}(B). If `spec == true`, then rho_{l+1}(B) is + # define isometries of rho_{l+1}(B). If `special == true`, then rho_{l+1}(B) is # equipped with a quadratic form and we check isometries preserving it. # Otherwise, only isometries preserving the underlying bilinear product. - OSBrB = _compute_double_stabilizer(SBinqB, l, spec) + OSBrB = _compute_double_stabilizer(SBinqB, l, special) @hassert :ZZLatWithIsom 1 fSB in OSBrB # Should always hold since the construction of rho_{l+1}(B) is natural in B fSB = OSBrB(fSB) @@ -1900,10 +1900,10 @@ function _on_modular_matrix_quad(M::QQMatrix, g::AutomorphismGroupElem) return m1 end -# We compute O(SB, rho_{l+1}(B)) where B has discriminant form qB. `spec` keep +# We compute O(SB, rho_{l+1}(B)) where B has discriminant form qB. `special` keep # track whether rho_{l+1}(B) should be considered as a finite quadratic module # or just a finite bilinear module (depends on the overlattice). -function _compute_double_stabilizer(SBinqB::TorQuadModuleMap, l::IntegerUnion, spec::Bool) +function _compute_double_stabilizer(SBinqB::TorQuadModuleMap, l::IntegerUnion, special::Bool) SB = domain(SBinqB) qB = codomain(SBinqB) OSB = orthogonal_group(SB) @@ -1914,7 +1914,7 @@ function _compute_double_stabilizer(SBinqB::TorQuadModuleMap, l::IntegerUnion, s OSBHB, _ = stabilizer(OSB, HBinSB) OHB, OSBHBtoOHB = restrict_automorphism_group(OSBHB, HBinSB; check = false) K, _ = kernel(OSBHBtoOHB) - if spec + if special OHBrB, _ = stabilizer(OHB, gram_matrix_quadratic(rB), _on_modular_matrix_quad) else OHBrB, _ = stabilizer(OHB, gram_matrix_bilinear(rB), _on_modular_matrix) @@ -1938,13 +1938,13 @@ function _find_admissible_gluing(SAinqA::TorQuadModuleMap, phi::TorQuadModuleMap, l::IntegerUnion, p::IntegerUnion, - spec::Bool) + special::Bool) SA = domain(SAinqA) SB = domain(SBinqB) qA = codomain(SAinqA) qB = codomain(SBinqB) - rA = _rho_functor(qA, p, l+1; quad = spec) - rB = _rho_functor(qB, p, l+1; quad = spec) + rA = _rho_functor(qA, p, l+1; quad = special) + rB = _rho_functor(qB, p, l+1; quad = special) @hassert :ZZLatWithIsom modulus_quadratic_form(rA) == modulus_quadratic_form(rB) rAtoSA = hom(rA, SA, elem_type(SA)[SA(QQ(p^l)*lift(a)) for a in gens(rA)]) @@ -1957,7 +1957,7 @@ function _find_admissible_gluing(SAinqA::TorQuadModuleMap, # We construct an abstract isometry between the rho functors: since they have # the same modulus quadratic, either we see them as finite bilinear modules - # or both as finite quadratic modules depending on the value of spec + # or both as finite quadratic modules depending on the value of special # # Our goal would be to massage phi such that it maps HA to HB, and the # restriction to rA and rB agrees with phi_0 diff --git a/experimental/QuadFormAndIsom/src/enumeration.jl b/experimental/QuadFormAndIsom/src/enumeration.jl index 46cb33dd80eb..41ce08255048 100644 --- a/experimental/QuadFormAndIsom/src/enumeration.jl +++ b/experimental/QuadFormAndIsom/src/enumeration.jl @@ -28,7 +28,7 @@ function _find_D(d::T, m::Int, p::Int) where T <: IntegerUnion if m == 0 return _tuples_divisors(d) end - + D = Tuple{T, T}[] # We try all the values of g possible, from 1 to p^m for g in powers(p, m) @@ -142,7 +142,7 @@ function is_admissible_triple(A::ZZGenus, B::ZZGenus, C::ZZGenus, p::IntegerUnio return false end - # At this point, if C is unimodular at p, the gluing condition is equivalent to have + # At this point, if C is unimodular at p, the gluing condition is equivalent to have # an anti-isometry between the p-part of the (quadratic) discriminant forms of A and B qA = discriminant_group(A) qB = discriminant_group(B) @@ -160,7 +160,7 @@ function is_admissible_triple(A::ZZGenus, B::ZZGenus, C::ZZGenus, p::IntegerUnio if a_max != b_max return false end - + # Since p^l*A^\vee/A is in the glue, its order is less than the order of the glue if g < a_max return false @@ -180,13 +180,13 @@ function is_admissible_triple(A::ZZGenus, B::ZZGenus, C::ZZGenus, p::IntegerUnio else Ar = genus(matrix(ZZ,0,0,[]), p) end - + if length(symbol(Bp)) > 1 Br = ZZLocalGenus(p, symbol(Bp)[1:end-1]) else Br = genus(matrix(ZZ, 0, 0, []), p) end - + ABr = direct_sum(Ar, Br) for i = 0:l-1 @@ -216,18 +216,18 @@ function is_admissible_triple(A::ZZGenus, B::ZZGenus, C::ZZGenus, p::IntegerUnio s[1] += 2 end Cp = ZZLocalGenus(p, _Cp) - + if !represents(local_symbol(AperpB, p), Cp) return false end if !represents(C, AperpB) return false - end + end qC = discriminant_group(C) - spec = (p == 2) && (_is_free(qA, p, l+1)) && (_is_free(qB, p, l+1)) && (_is_even(qC, p, l)) - rA = _rho_functor(qA, p, l+1; quad = spec) - rB = _rho_functor(qB, p, l+1; quad = spec) + special = (p == 2) && (_is_free(qA, p, l+1)) && (_is_free(qB, p, l+1)) && (_is_even(qC, p, l)) + rA = _rho_functor(qA, p, l+1; quad = special) + rB = _rho_functor(qB, p, l+1; quad = special) return is_anti_isometric_with_anti_isometry(rA, rB)[1] end @@ -306,7 +306,7 @@ function admissible_triples(G::ZZGenus, p::IntegerUnion; pA::Int = -1, pB::Int = if pA >= 0 r1 >= pA || continue end - m = min(ep, r1) + m = min(ep, r1) D = _find_D(dG, m, p) while !is_empty(D) d1, dp = pop!(D) diff --git a/experimental/QuadFormAndIsom/src/hermitian_miranda_morrison.jl b/experimental/QuadFormAndIsom/src/hermitian_miranda_morrison.jl index 74498c2e6902..394aa4269a5f 100644 --- a/experimental/QuadFormAndIsom/src/hermitian_miranda_morrison.jl +++ b/experimental/QuadFormAndIsom/src/hermitian_miranda_morrison.jl @@ -232,7 +232,7 @@ function _get_product_quotient(E::Hecke.RelSimpleNumField, Fac::Vector{Tuple{Abs function dlog(x::Vector{<:Hecke.RelSimpleNumFieldElem}) if length(x) == 1 - return sum(inj[i](dlogs[i](x[1])) for i in 1:length(Fac)) + return sum(inj[i](dlogs[i](x[1])) for i in 1:length(Fac)) else @hassert :ZZLatWithIsom 1 length(x) == length(Fac) return sum(inj[i](dlogs[i](x[i])) for i in 1:length(Fac)) @@ -263,10 +263,10 @@ end # (D^{-1}L^#/L)_p is not unimodular. # # According to [BH23], the quotient D^{-1}L^#/L is unimodular at p -# if and only if +# if and only if # - either L is unimodular at p, and D and p are coprime # - or L is P^{-a}-modular where P is largest prime ideal -# over p fixed the canonical involution, and a is the valuation of D at P. +# over p fixed the canonical involution, and a is the valuation of D at P. function _elementary_divisors(L::HermLat, D::Hecke.RelNumFieldOrderIdeal) Ps = collect(keys(factor(D))) diff --git a/experimental/QuadFormAndIsom/src/lattices_with_isometry.jl b/experimental/QuadFormAndIsom/src/lattices_with_isometry.jl index b7ad00678a9d..1ab250740090 100644 --- a/experimental/QuadFormAndIsom/src/lattices_with_isometry.jl +++ b/experimental/QuadFormAndIsom/src/lattices_with_isometry.jl @@ -177,7 +177,7 @@ minimal_polynomial(Lf::ZZLatWithIsom) = minimal_polynomial(isometry(Lf)) @doc raw""" genus(Lf::ZZLatWithIsom) -> ZZGenus -Given a lattice with isometry $(L, f)$, return the genus of the underlying +Given a lattice with isometry $(L, f)$, return the genus of the underlying lattice $L$. # Examples @@ -1529,7 +1529,7 @@ Integer lattice of rank 4 and degree 5 julia> H = hermitian_structure(M) Hermitian lattice of rank 1 and degree 1 over relative maximal order of Relative number field of degree 2 over maximal real subfield of cyclotomic field of order 5 - with pseudo-basis + with pseudo-basis (1, 1//1 * <1, 1>) (z_5, 1//1 * <1, 1>) @@ -1592,11 +1592,11 @@ Finite quadratic module Abelian group: Z/6 Bilinear value module: Q/Z Quadratic value module: Q/2Z -Gram matrix quadratic form: +Gram matrix quadratic form: [5//6] julia> qf -Isometry of Finite quadratic module: Z/6 -> Q/2Z defined by +Isometry of Finite quadratic module: Z/6 -> Q/2Z defined by [1] julia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0; @@ -1608,7 +1608,7 @@ julia> f = matrix(QQ, 5, 5, [ 1 0 0 0 0; julia> Lf = integer_lattice_with_isometry(L, f); julia> discriminant_group(Lf)[2] -Isometry of Finite quadratic module: Z/6 -> Q/2Z defined by +Isometry of Finite quadratic module: Z/6 -> Q/2Z defined by [5] ``` """ diff --git a/experimental/Schemes/AlgebraicCycles.jl b/experimental/Schemes/AlgebraicCycles.jl index 38e9ce7893db..c6a368454ede 100644 --- a/experimental/Schemes/AlgebraicCycles.jl +++ b/experimental/Schemes/AlgebraicCycles.jl @@ -184,7 +184,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P, I); +julia> Y = proj(P, I); julia> Ycov = covered_scheme(Y); @@ -222,7 +222,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P); +julia> Y = proj(P); julia> II = IdealSheaf(Y, I); @@ -263,7 +263,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P); +julia> Y = proj(P); julia> II = IdealSheaf(Y, I); diff --git a/experimental/Schemes/Auxiliary.jl b/experimental/Schemes/Auxiliary.jl index 4b5cf092d2c6..035edf538519 100644 --- a/experimental/Schemes/Auxiliary.jl +++ b/experimental/Schemes/Auxiliary.jl @@ -86,7 +86,7 @@ function pullback(f::AbsCoveredSchemeMorphism, II::IdealSheaf) Y = codomain(f) scheme(II) === Y || error("ideal sheaf is not defined on the codomain of the function") phi = covering_morphism(f) - ID = IdDict{AbsSpec, Ideal}() + ID = IdDict{AbsAffineScheme, Ideal}() for U in patches(domain(phi)) f_U = phi[U] V = codomain(f_U) @@ -114,7 +114,7 @@ function pullback(f::AbsCoveredSchemeMorphism, C::EffectiveCartierDivisor) # restrict f to that, obtain a new underlying covering morphism psi cov1' → cov', # and pull back along psi. phi = covering_morphism(f) - triv_dict = IdDict{AbsSpec, RingElem}() + triv_dict = IdDict{AbsAffineScheme, RingElem}() E, a, b = common_refinement(codomain(phi), trivializing_covering(C)) psi = restrict(f, E) psi = compose(psi, b) @@ -191,7 +191,7 @@ function restrict(f::AbsCoveredSchemeMorphism, DD::Covering) # The covering DD has patches Vⱼ in the codomain Y of f. # Their preimages must be taken in every patch Uᵢ of X in # the domain's covering for phi. - res_dict = IdDict{AbsSpec, AbsSpecMor}() + res_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(domain(phi)) V = codomain(phi[U]) for W in patches(DD) @@ -219,7 +219,7 @@ function restrict(f::AbsCoveredSchemeMorphism, DD::Covering) end end end - new_domain = Covering(collect(keys(res_dict)), IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}()) + new_domain = Covering(collect(keys(res_dict)), IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}()) inherit_gluings!(new_domain, domain(phi)) _register!(new_domain, X) @@ -235,7 +235,7 @@ function _register!(C::Covering, X::AbsCoveredScheme) end function _canonical_map(C::Covering, D::Covering) - map_dict = IdDict{AbsSpec, AbsSpecMor}() + map_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(C) f, _ = _find_chart(U, D) map_dict[U] = f @@ -258,8 +258,8 @@ end struct InheritGluingData orig::Covering - X::AbsSpec - Y::AbsSpec + X::AbsAffineScheme + Y::AbsAffineScheme end function _compute_inherited_gluing(gd::InheritGluingData) diff --git a/experimental/Schemes/BlowupMorphism.jl b/experimental/Schemes/BlowupMorphism.jl index 2f655dcbc94e..096c119c12a9 100644 --- a/experimental/Schemes/BlowupMorphism.jl +++ b/experimental/Schemes/BlowupMorphism.jl @@ -6,11 +6,11 @@ export projection ######################################################################## # An abstract type for blowdown morphisms. # -# This should also comprise sequences of simple blowups leading -# to a partial or full resolution of singularities. The interface +# This should also comprise sequences of simple blowups leading +# to a partial or full resolution of singularities. The interface # is specified below. ######################################################################## -abstract type AbsBlowdownMorphism{DomainType<:AbsCoveredScheme, +abstract type AbsBlowdownMorphism{DomainType<:AbsCoveredScheme, CodomainType<:AbsCoveredScheme, BaseMorphismType<:Nothing, BlowdownMorphismType @@ -22,12 +22,12 @@ abstract type AbsBlowdownMorphism{DomainType<:AbsCoveredScheme, } end -# The interface inherits all functionality from AbsCoveredSchemeMorphism. +# The interface inherits all functionality from AbsCoveredSchemeMorphism. # This is extended by the following: @doc raw""" exceptional_divisor(f::AbsBlowdownMorphism) -Return a `CartierDivisor` on the `domain` of `f` which is the +Return a `CartierDivisor` on the `domain` of `f` which is the preimage of the vanishing locus of the `center` of `f`. !!! note If `f` is not a classical blowup, but, for instance, a small contraction, then the exceptional locus need not be a divisor. See `exceptional_locus` for such cases. @@ -39,8 +39,8 @@ end @doc raw""" exceptional_locus(f::AbsBlowdownMorphism) -Return an `AbsAlgebraicCycle` on the `domain` of `f` which is the preimage -of the `center` of `f` in a reasonable sense. In particular, `f` is an isomorphism +Return an `AbsAlgebraicCycle` on the `domain` of `f` which is the preimage +of the `center` of `f` in a reasonable sense. In particular, `f` is an isomorphism onto its image outside the support of its `exceptional_locus`. See also `exceptional_divisor`. """ function exceptional_locus(f::AbsBlowdownMorphism) @@ -50,9 +50,9 @@ end @doc raw""" center(f::AbsBlowdownMorphism) -Return an `IdealSheaf` on the `codomain` of `f` such that on the complement +Return an `IdealSheaf` on the `codomain` of `f` such that on the complement of the vanishing locus of that ideal sheaf `f` is an isomorphism. -The support of the `exceptional_locus` of `f` coincides with the vanishing +The support of the `exceptional_locus` of `f` coincides with the vanishing locus of the pullback of the `center`. !!! note For classical blowup constructions this will be the center which has been blown up. For more exotic blowups, however, this might be more special. @@ -64,10 +64,10 @@ end @doc raw""" strict_transform(f::AbsBlowdownMorphism, a::Any) -Take the closure of the `pullback` of `a` along `f` on the complement -of the `exceptional_locus` in a mathematically reasonable sense. -Depending on `a` this either returns the corresponding object on -the `domain` of `f`, or a tuple consisting of the object and eventually +Take the closure of the `pullback` of `a` along `f` on the complement +of the `exceptional_locus` in a mathematically reasonable sense. +Depending on `a` this either returns the corresponding object on +the `domain` of `f`, or a tuple consisting of the object and eventually induced maps. """ function strict_transform(f::AbsBlowdownMorphism, a::Any) @@ -77,10 +77,10 @@ end @doc raw""" total_transform(f::AbsBlowdownMorphism, a::Any) -Take the `pullback` or preimage of `a` along `f` in a mathematically +Take the `pullback` or preimage of `a` along `f` in a mathematically reasonable sense. -Depending on `a` this either returns the corresponding object on -the `domain` of `f`, or a tuple consisting of the object and eventually +Depending on `a` this either returns the corresponding object on +the `domain` of `f`, or a tuple consisting of the object and eventually induced maps. """ function total_transform(f::AbsBlowdownMorphism, a::Any) @@ -88,12 +88,12 @@ function total_transform(f::AbsBlowdownMorphism, a::Any) end ######################################################################## -# An abstract type for classical blowups of ideal sheaves. +# An abstract type for classical blowups of ideal sheaves. # -# This can either be a BlowupMorphism as below, but also a special +# This can either be a BlowupMorphism as below, but also a special # toric morphism induced by fan subdivisions. ######################################################################## -abstract type AbsSimpleBlowdownMorphism{DomainType<:AbsCoveredScheme, +abstract type AbsSimpleBlowdownMorphism{DomainType<:AbsCoveredScheme, CodomainType<:AbsCoveredScheme, BaseMorphismType<:Nothing, BlowdownMorphismType @@ -108,7 +108,7 @@ end @doc raw""" exceptional_divisor(f::AbsSimpleBlowdownMorphism) -Return a `CartierDivisor` on the `domain` of `f` which coincides +Return a `CartierDivisor` on the `domain` of `f` which coincides with the pullback of the `center` of `f`. """ function exceptional_divisor(f::AbsSimpleBlowdownMorphism) @@ -127,7 +127,7 @@ end @doc raw""" center(f::AbsSimpleBlowdownMorphism) -Return an `IdealSheaf` on the `codomain` of `f` the blowup of which +Return an `IdealSheaf` on the `codomain` of `f` the blowup of which leads to `f`. """ function center(f::AbsSimpleBlowdownMorphism) @@ -137,11 +137,11 @@ end @doc raw""" strict_transform(f::AbsSimpleBlowdownMorphism, a::Any) -Take the closure of the `pullback` of `a` along `f` on the complement -of the `exceptional_divisor` in a mathematically reasonable sense. +Take the closure of the `pullback` of `a` along `f` on the complement +of the `exceptional_divisor` in a mathematically reasonable sense. -Depending on `a` this either returns the corresponding object on -the `domain` of `f`, or a tuple consisting of the object and eventually +Depending on `a` this either returns the corresponding object on +the `domain` of `f`, or a tuple consisting of the object and eventually induced maps. """ function strict_transform(f::AbsSimpleBlowdownMorphism, a::Any) @@ -151,11 +151,11 @@ end @doc raw""" total_transform(f::AbsSimpleBlowdownMorphism, a::Any) -Take the `pullback` or preimage of `a` along `f` in a mathematically +Take the `pullback` or preimage of `a` along `f` in a mathematically reasonable sense. -Depending on `a` this either returns the corresponding object on -the `domain` of `f`, or a tuple consisting of the object and eventually +Depending on `a` this either returns the corresponding object on +the `domain` of `f`, or a tuple consisting of the object and eventually induced maps. """ function total_transform(f::AbsSimpleBlowdownMorphism, a::Any) @@ -165,11 +165,11 @@ end @doc raw""" controlled_transform(f::AbsSimpleBlowdownMorphism, a::Any, k::Int) -Take the `pullback` or preimage of `a` along `f` saturated by `k` times +Take the `pullback` or preimage of `a` along `f` saturated by `k` times the `exceptional_divisor` of `f` in a mathematically reasonable sense. -Depending on `a` this either returns the corresponding object on -the `domain` of `f`, or a tuple consisting of the object and eventually +Depending on `a` this either returns the corresponding object on +the `domain` of `f`, or a tuple consisting of the object and eventually induced maps. """ function controlled_transform(f::AbsSimpleBlowdownMorphism, a::Any, k::Int) @@ -177,10 +177,10 @@ function controlled_transform(f::AbsSimpleBlowdownMorphism, a::Any, k::Int) end ######################################################################## -# BlowupMorphism +# BlowupMorphism # -# A datastructure to maintain all information necessary to effectively -# handle blowups. This is work in progress and will one day serve as +# A datastructure to maintain all information necessary to effectively +# handle blowups. This is work in progress and will one day serve as # a building block for sequences of blowups ######################################################################## @@ -198,7 +198,7 @@ blowup). ```jldoctest julia> R, (x,y,z) = QQ["x", "y", "z"]; -julia> A3 = Spec(R) +julia> A3 = spec(R) Spectrum of multivariate polynomial ring in 3 variables x, y, z over rational field @@ -257,7 +257,7 @@ with restriction BaseMorphismType, BlowupMorphism } - projective_bundle::CoveredProjectiveScheme + projective_bundle::CoveredProjectiveScheme codomain::CodomainType # in general a CoveredScheme center::IdealSheaf # on codomain projection::AbsCoveredSchemeMorphism @@ -301,20 +301,20 @@ covered_projective_scheme(p::BlowupMorphism) = p.projective_bundle @doc raw""" exceptional_divisor(p::BlowupMorphism) -For a `BlowupMorphism` ``p : Y → X`` coming from the blowup of an -`IdealSheaf` ``ℐ`` on X, return the `EffectiveCartierDivisor` ``E`` -on ``Y`` associated to the (relative) tautological bundle ``𝒪(1)``. +For a `BlowupMorphism` ``p : Y → X`` coming from the blowup of an +`IdealSheaf` ``ℐ`` on X, return the `EffectiveCartierDivisor` ``E`` +on ``Y`` associated to the (relative) tautological bundle ``𝒪(1)``. -On a pair of charts ``V → U`` of the `covered_scheme` of the -`projection` of ``p`` this returns the pullback of the `i`-th -generator of ``ℐ(U)`` when ``V`` is the `i-1`-st canonical chart +On a pair of charts ``V → U`` of the `covered_scheme` of the +`projection` of ``p`` this returns the pullback of the `i`-th +generator of ``ℐ(U)`` when ``V`` is the `i-1`-st canonical chart of the local blowup over ``U``. """ function exceptional_divisor(p::BlowupMorphism) if !isdefined(p, :exceptional_divisor) error("exceptional divisor needs to be cached during construction") - # The exceptional divisor must be created - # and set during the construction of the BlowupMorphism. + # The exceptional divisor must be created + # and set during the construction of the BlowupMorphism. end return p.exceptional_divisor end @@ -322,9 +322,9 @@ end @doc raw""" strict_transform(p::BlowupMorphism, inc::CoveredClosedEmbedding) -For a `BlowupMorphism` ``p : Y → X`` and a `CoveredClosedEmbedding` -``ι : Z ↪ X``, compute the strict transform ``Z'`` of ``Z`` along ``p`` and -return a triple ``(Z', j, π)`` containing the `CoveredClosedEmbedding` +For a `BlowupMorphism` ``p : Y → X`` and a `CoveredClosedEmbedding` +``ι : Z ↪ X``, compute the strict transform ``Z'`` of ``Z`` along ``p`` and +return a triple ``(Z', j, π)`` containing the `CoveredClosedEmbedding` ``j : Z' ↪ Y`` and the induced projection ``π : Z' → Z``. """ function strict_transform(p::AbsSimpleBlowdownMorphism, inc::CoveredClosedEmbedding) @@ -333,7 +333,7 @@ function strict_transform(p::AbsSimpleBlowdownMorphism, inc::CoveredClosedEmbedd Z = domain(inc) codomain(inc) === X || error("maps must have the same codomain") I_trans = strict_transform(p, image_ideal(inc)) - inc_Z_trans = CoveredClosedEmbedding(Y, I_trans, + inc_Z_trans = CoveredClosedEmbedding(Y, I_trans, covering=simplified_covering(Y), # Has been set by the previous call check=false) inc_dom_cov = covering_morphism(inc_Z_trans) @@ -342,7 +342,7 @@ function strict_transform(p::AbsSimpleBlowdownMorphism, inc::CoveredClosedEmbedd Z_trans = domain(inc_Z_trans) pr_res = restrict(projection(p), inc_Z_trans, inc) - if has_attribute(p, :isomorphism_on_open_subset) # will only happen when p is a BlowupMorphism + if has_attribute(p, :isomorphism_on_open_subset) # will only happen when p is a BlowupMorphism OOX = OO(X) OOY = OO(Y) p_iso = isomorphism_on_open_subset(p) @@ -359,22 +359,22 @@ function strict_transform(p::AbsSimpleBlowdownMorphism, inc::CoveredClosedEmbedd # Z ↪ X ⊃ V_amb ⊃ V # inc_cod # - # Given all the refinements that potentially had to be done, we have + # Given all the refinements that potentially had to be done, we have # to do the following. - # 1. Find a `patch` `U_sub` of the `domain` of `inc_dom_cov` for which - # inc_dom : U_sub -> W has a codomain `W` which has `U_amb` as an - # ancestor. Since `U_amb` is one of the `affine_charts` of `Y`, this will work. + # 1. Find a `patch` `U_sub` of the `domain` of `inc_dom_cov` for which + # inc_dom : U_sub -> W has a codomain `W` which has `U_amb` as an + # ancestor. Since `U_amb` is one of the `affine_charts` of `Y`, this will work. k = findfirst(x->has_ancestor(y->y===U_amb, codomain(inc_dom_cov[x])), patches(domain(inc_dom_cov))) U_sub = patches(domain(inc_dom_cov))[k] - # 2. pr_res : U_amb -> V_amb has some codomain such that there exists - # an ancestor `VV` in the `domain` of `inc_dom_cov` such that - # inc_dom : VV -> W' has a codomain with `V_amb` as an ancestor. - # 3. outside the `complement_equation`s of `U` and `V` the projection - # was an isomorphism. Then the restriction of `pr_res` to those + # 2. pr_res : U_amb -> V_amb has some codomain such that there exists + # an ancestor `VV` in the `domain` of `inc_dom_cov` such that + # inc_dom : VV -> W' has a codomain with `V_amb` as an ancestor. + # 3. outside the `complement_equation`s of `U` and `V` the projection + # was an isomorphism. Then the restriction of `pr_res` to those # complements in `U_sub` and `V_sub` also is. - U_sub_res = PrincipalOpenSubset(U_sub, + U_sub_res = PrincipalOpenSubset(U_sub, pullback(inc_dom_cov[U_sub])( OOX(U_amb, codomain(inc_dom_cov[U_sub]))( complement_equation(U) @@ -429,7 +429,7 @@ end weak_transform_with_multiplicity((p::BlowupMorphism, I::IdealSheaf) For a `BlowupMorphism` ``p : Y → X`` and an `IdealSheaf` ``I`` on ``X`` return the -weak transform ``J`` of ``I`` on ``Y`` and the multiplicity ``m`` of the exceptional divisor, i.e. +weak transform ``J`` of ``I`` on ``Y`` and the multiplicity ``m`` of the exceptional divisor, i.e. the maximal ``m`` such that ``E^m J = p^*I``, where ``E`` denotes the `IdealSheaf` of the exceptional divisor of ``p``. """ @@ -462,10 +462,10 @@ function _do_transform(p::AbsSimpleBlowdownMorphism, I::IdealSheaf, method::Int= ## initializations and sanity checks for p X = scheme(I) - Y = domain(p) + Y = domain(p) X === codomain(p) || error("ideal sheaf is not defined on the codomain of the morphism") IE = ideal_sheaf(exceptional_divisor(p)) - ID = IdDict{AbsSpec, Ideal}() + ID = IdDict{AbsAffineScheme, Ideal}() ## get our hands on the coverings -- using simplified covering for CY p_cov_temp = covering_morphism(p) @@ -526,10 +526,10 @@ strict transform of ``C`` on ``Y``. """ function strict_transform(p::AbsSimpleBlowdownMorphism, C::EffectiveCartierDivisor) X = scheme(C) - Y = domain(p) + Y = domain(p) X === codomain(p) || error("cartier divisor is not defined on the codomain of the morphism") E = exceptional_divisor(p) - ID = IdDict{AbsSpec, RingElem}() + ID = IdDict{AbsAffineScheme, RingElem}() ## get our hands on the coverings -- trivializing covering for C leading the way CX = trivializing_covering(C) @@ -585,7 +585,7 @@ end function strict_transform(p::AbsSimpleBlowdownMorphism, C::CartierDivisor) X = codomain(p) - Y = domain(p) + Y = domain(p) X === scheme(C) || error("cartier divisor not defined on the codomain of the map") kk = coefficient_ring(C) result = CartierDivisor(Y, kk) @@ -602,12 +602,12 @@ end check::Bool=true ) -For a diagram +For a diagram Z' ↪ Y ↓ f Z ↪ X -with `inc_dom` and `inc_cod` the respective horizontal maps +with `inc_dom` and `inc_cod` the respective horizontal maps we assume ``f(Z') ⊂ Z``, compute and return the restriction ``f : Z' → Z``. """ function restrict(f::AbsCoveredSchemeMorphism, @@ -620,7 +620,7 @@ function restrict(f::AbsCoveredSchemeMorphism, inc_cod_cov = covering_morphism(inc_cod) # We need to do the following. - # - Pass to a common refinement ref_cod in X that both + # - Pass to a common refinement ref_cod in X that both # f and inc_cod can restrict to. # - Pass to a common refinement in Y ref_cod, a, b = _register!(common_refinement(codomain(f_cov), codomain(inc_cod_cov)), codomain(f)) @@ -630,7 +630,7 @@ function restrict(f::AbsCoveredSchemeMorphism, inc_dom_ref = restrict(inc_dom, ref_dom) inc_dom_ref = compose(inc_dom_ref, aa) # Collecting the maps for the restricted projection here - map_dict = IdDict{AbsSpec, AbsSpecMor}() + map_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(domain(inc_dom_ref)) q_res = compose(inc_dom_ref[U], f_res[codomain(inc_dom_ref[U])]) V = codomain(q_res) @@ -654,8 +654,8 @@ function _register!(data::Tuple{<:Covering, <:CoveringMorphism, <:CoveringMorphi return data end -function maps_with_given_codomain(phi::CoveringMorphism, V::AbsSpec) - result = Vector{AbsSpecMor}() +function maps_with_given_codomain(phi::CoveringMorphism, V::AbsAffineScheme) + result = Vector{AbsAffineSchemeMor}() for U in keys(morphisms(phi)) floc = morphisms(phi)[U] codomain(floc) === V || continue @@ -727,7 +727,7 @@ end p_res = CoveredSchemeMorphism(XU, YV, p_res_cov) # Assemble the inverse - iso_inv_dict = IdDict{AbsSpec, AbsSpecMor}() + iso_inv_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for (U, q) in iso_dict V = codomain(q) iso_inv_dict[V] = inverse(q) @@ -742,10 +742,10 @@ end ### Some functionality used by function fields -# If set this attribute shall return some isomorphism on some open subsets of the domain -# and codomain of phi. If both are irreducible, this automatically implies that both are +# If set this attribute shall return some isomorphism on some open subsets of the domain +# and codomain of phi. If both are irreducible, this automatically implies that both are # dense, but we do not check for this. -@attr AbsSpecMor function isomorphism_on_open_subset(f::BlowupMorphism) +@attr AbsAffineSchemeMor function isomorphism_on_open_subset(f::BlowupMorphism) X = domain(f) Y = codomain(f) iso_dict = get_attribute(f, :isos_on_complement_of_center) @@ -791,7 +791,7 @@ function pushforward(f::BlowupMorphism, g::VarietyFunctionFieldElem) return FY.(pfg) end -@attr AbsSpecMor function isomorphism_on_open_subset(phi::AbsCoveredSchemeMorphism) +@attr AbsAffineSchemeMor function isomorphism_on_open_subset(phi::AbsCoveredSchemeMorphism) error("attribute not found; this needs to be set manually in general") end diff --git a/experimental/Schemes/CartierDivisor.jl b/experimental/Schemes/CartierDivisor.jl index ae11f25c33ee..c92145960d57 100644 --- a/experimental/Schemes/CartierDivisor.jl +++ b/experimental/Schemes/CartierDivisor.jl @@ -13,9 +13,9 @@ export trivializing_covering function EffectiveCartierDivisor( X::AbsCoveredScheme, - D::IdDict{<:AbsSpec, <:RingElem}; + D::IdDict{<:AbsAffineScheme, <:RingElem}; trivializing_covering::Covering=begin - C = Covering(collect(keys(D)), IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}()) + C = Covering(collect(keys(D)), IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}()) inherit_gluings!(C, default_covering(X)) C end, @@ -24,7 +24,7 @@ export trivializing_covering for U in patches(trivializing_covering) U in keys(D) || error("the divisor must be prescribed on all patches of its trivializing covering") end - ID = IdDict{AbsSpec, Ideal}() + ID = IdDict{AbsAffineScheme, Ideal}() for U in keys(D) ID[U] = ideal(OO(U), D[U]) end @@ -40,7 +40,7 @@ export trivializing_covering end end -function (C::EffectiveCartierDivisor)(U::AbsSpec) +function (C::EffectiveCartierDivisor)(U::AbsAffineScheme) return gens(C.I(U)) end @@ -54,7 +54,7 @@ function EffectiveCartierDivisor(I::IdealSheaf; check::Bool=true ) X = scheme(I) - eq_dict = IdDict{AbsSpec, RingElem}() + eq_dict = IdDict{AbsAffineScheme, RingElem}() for U in patches(trivializing_covering) isone(ngens(I(U))) || error("ideal sheaf is not principal on the given covering") eq_dict[U] = first(gens(I(U))) @@ -149,7 +149,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P); +julia> Y = proj(P); julia> II = IdealSheaf(Y, I); @@ -215,7 +215,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P); +julia> Y = proj(P); julia> II = IdealSheaf(Y, I); @@ -238,7 +238,7 @@ function effective_cartier_divisor(IP::AbsProjectiveScheme, f::Union{MPolyDecRin parent(f) === homogeneous_coordinate_ring(IP) || error("element does not belong to the correct ring") d = degree(f) X = covered_scheme(IP) - triv_dict = IdDict{AbsSpec, RingElem}() + triv_dict = IdDict{AbsAffineScheme, RingElem}() for U in affine_charts(X) triv_dict[U] = dehomogenization_map(IP, U)(f) end @@ -283,7 +283,7 @@ function irreducible_decomposition(C::EffectiveCartierDivisor) components_here = minimal_primes(I_temp) for comp in components_here I_temp, saturation_index = saturation_with_index(I_temp, comp) - temp_dict=IdDict{AbsSpec,Ideal}() + temp_dict=IdDict{AbsAffineScheme,Ideal}() temp_dict[U] = comp I_sheaf_temp = IdealSheaf(X, extend!(cov, temp_dict), check=false) push!(associated_primes_temp, (I_sheaf_temp, saturation_index)) diff --git a/experimental/Schemes/CoherentSheaves.jl b/experimental/Schemes/CoherentSheaves.jl index a2d8fbd12041..fe4ec6521fb8 100644 --- a/experimental/Schemes/CoherentSheaves.jl +++ b/experimental/Schemes/CoherentSheaves.jl @@ -93,8 +93,8 @@ end # * U::PrincipalOpenSubset ⊂ V::PrincipalOpenSubset with ambient_scheme(U) === ambient_scheme(V) in the basic charts of X # * U::PrincipalOpenSubset ⊂ V::PrincipalOpenSubset with ambient_scheme(U) != ambient_scheme(V) both in the basic charts of X # and U and V contained in the gluing domains of their ambient schemes -# * U::AbsSpec ⊂ U::AbsSpec in the basic charts of X -# * U::AbsSpec ⊂ X for U in the basic charts +# * U::AbsAffineScheme ⊂ U::AbsAffineScheme in the basic charts of X +# * U::AbsAffineScheme ⊂ X for U in the basic charts # * U::PrincipalOpenSubset ⊂ X with ambient_scheme(U) in the basic charts of X function _is_open_for_modules(X::AbsCoveredScheme) function is_open_func(U::PrincipalOpenSubset, V::PrincipalOpenSubset) @@ -117,21 +117,21 @@ function _is_open_for_modules(X::AbsCoveredScheme) function is_open_func(U::PrincipalOpenSubset, Y::AbsCoveredScheme) return Y === X && ambient_scheme(U) in affine_charts(X) end - function is_open_func(U::AbsSpec, Y::AbsCoveredScheme) + function is_open_func(U::AbsAffineScheme, Y::AbsCoveredScheme) return Y === X && U in affine_charts(X) end function is_open_func(Z::AbsCoveredScheme, Y::AbsCoveredScheme) return X === Y === Z end - function is_open_func(U::AbsSpec, V::AbsSpec) + function is_open_func(U::AbsAffineScheme, V::AbsAffineScheme) any(x->x===U, affine_charts(X)) || return false any(x->x===V, affine_charts(X)) || return false G = default_covering(X)[U, V] return is_subscheme(U, gluing_domains(G)[1]) end function is_open_func( - U::AbsSpec, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + U::AbsAffineScheme, + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) is_subscheme(U, V) && return true any(x->x===U, affine_charts(X)) || return false @@ -146,8 +146,8 @@ function _is_open_for_modules(X::AbsCoveredScheme) return is_subset(U, pre_V) end function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - V::AbsSpec + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + V::AbsAffineScheme ) any(x->x===V, affine_charts(X)) || return false inc_U_flat = _flatten_open_subscheme(U, default_covering(X)) @@ -172,7 +172,7 @@ A sheaf of modules ``ℳ`` on an `AbsCoveredScheme` ``X``. Note that due to technical reasons, the admissible open subsets are restricted to the following: - * `U::AbsSpec` among the `basic_patches` of the `default_covering` of `X`; + * `U::AbsAffineScheme` among the `basic_patches` of the `default_covering` of `X`; * `U::PrincipalOpenSubset` with `ambient_scheme(U)` in the `basic_patches` of the `default_covering` of `X`. One can call the restriction maps of ``ℳ`` across charts implicitly using the @@ -185,7 +185,7 @@ identifications given by the gluings in the `default_covering`. SpaceType, OpenType, OutputType, RestrictionType } - ID::IdDict{AbsSpec, ModuleFP} # the modules on the basic patches of the default covering + ID::IdDict{AbsAffineScheme, ModuleFP} # the modules on the basic patches of the default covering OOX::StructureSheafOfRings # the structure sheaf on X M::PreSheafOnScheme # the underlying presheaf of modules for caching C::Covering # The covering of X on which the modules had first been described, a.k.a. the @@ -193,8 +193,8 @@ identifications given by the gluings in the `default_covering`. ### Sheaves of modules on covered schemes function SheafOfModules(X::AbsCoveredScheme, - MD::IdDict{AbsSpec, ModuleFP}, # A dictionary of modules on the `affine_charts` of `X` - MG::IdDict{Tuple{AbsSpec, AbsSpec}, MatrixElem}; # A dictionary for pairs `(U, V)` of + MD::IdDict{AbsAffineScheme, ModuleFP}, # A dictionary of modules on the `affine_charts` of `X` + MG::IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, MatrixElem}; # A dictionary for pairs `(U, V)` of # `affine_charts` of `X` such that # A = MG[(U, V)] has entries aᵢⱼ with # gᵢ = ∑ⱼ aᵢⱼ ⋅ fⱼ on U ∩ V with gᵢ the @@ -205,7 +205,7 @@ identifications given by the gluings in the `default_covering`. check::Bool=true, default_cov::Covering=begin # This will be the `default_covering` of the sheaf to be created. patch_list = collect(keys(MD)) - gluing_dict = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() + gluing_dict = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() C = Covering(patch_list, gluing_dict) inherit_gluings!(C, default_covering(X)) C @@ -270,7 +270,7 @@ identifications given by the gluings in the `default_covering`. ### Production of the modules on open sets; to be cached function production_func( F::AbsPreSheaf, - U::AbsSpec + U::AbsAffineScheme ) # Since the other cases are caught by the methods below, # U can only be an affine_chart of X. @@ -305,7 +305,7 @@ identifications given by the gluings in the `default_covering`. function production_func( F::AbsPreSheaf, - U::SimplifiedSpec + U::SimplifiedAffineScheme ) # Check whether we can directly produce the module haskey(MD, U) && return MD[U] @@ -325,7 +325,7 @@ identifications given by the gluings in the `default_covering`. end ### Production of the restriction maps; to be cached - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) # Since the other cases are caught by the methods below, both U and V # must be `affine_chart`s of X with U contained in V along some gluing. if any(W->(W === U), affine_charts(X)) && any(W->(W === V), affine_charts(X)) @@ -341,7 +341,7 @@ identifications given by the gluings in the `default_covering`. end end - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::PrincipalOpenSubset) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::PrincipalOpenSubset) # If V was not an affine_chart of X, some other function would have # been triggered. @@ -373,7 +373,7 @@ identifications given by the gluings in the `default_covering`. ) end - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::SimplifiedSpec) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::SimplifiedAffineScheme) # If V was not an affine_chart of X, some other function would have # been triggered. @assert any(x->x===V, affine_charts(X)) "first argument must be an affine chart" @@ -407,8 +407,8 @@ identifications given by the gluings in the `default_covering`. ) end function restriction_func(F::AbsPreSheaf, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - U::AbsSpec + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + U::AbsAffineScheme ) # We know that V can not be an ancestor of U, but U must be an affine chart. # Probably even an ancestor of V itself. @@ -499,7 +499,7 @@ identifications given by the gluings in the `default_covering`. end return hom(F(V), F(U), img_gens, OOX(V, U)) end - function restriction_func(F::AbsPreSheaf, V::PrincipalOpenSubset, U::SimplifiedSpec) + function restriction_func(F::AbsPreSheaf, V::PrincipalOpenSubset, U::SimplifiedAffineScheme) if V === original(U) return hom(F(V), F(U), gens(F(U)), OOX(V, U)) # If this had been more complicated, it would have been cached. elseif has_ancestor(W->W===V, U) @@ -557,7 +557,7 @@ identifications given by the gluings in the `default_covering`. end return hom(F(V), F(U), img_gens, OOX(V, U)) end - function restriction_func(F::AbsPreSheaf, V::SimplifiedSpec, U::PrincipalOpenSubset) + function restriction_func(F::AbsPreSheaf, V::SimplifiedAffineScheme, U::PrincipalOpenSubset) if V === ambient_scheme(U) return hom(F(V), F(U), gens(F(U)), OOX(V, U)) # If this had been more complicated, it would have been cached. elseif has_ancestor(W->W===V, U) @@ -615,7 +615,7 @@ identifications given by the gluings in the `default_covering`. end return hom(F(V), F(U), img_gens, OOX(V, U)) end - function restriction_func(F::AbsPreSheaf, V::SimplifiedSpec, U::SimplifiedSpec) + function restriction_func(F::AbsPreSheaf, V::SimplifiedAffineScheme, U::SimplifiedAffineScheme) V === U && return identity_map(F(U)) if V === original(U) @@ -677,12 +677,12 @@ identifications given by the gluings in the `default_covering`. end Mpre = PreSheafOnScheme(X, production_func, restriction_func, - OpenType=AbsSpec, OutputType=ModuleFP, + OpenType=AbsAffineScheme, OutputType=ModuleFP, RestrictionType=Map, - is_open_func=_is_open_func_for_schemes_without_specopen(X) + is_open_func=_is_open_func_for_schemes_without_affine_scheme_open_subscheme(X) #is_open_func=_is_open_for_modules(X) ) - M = new{typeof(X), AbsSpec, ModuleFP, Map}(MD, OOX, Mpre, default_cov) + M = new{typeof(X), AbsAffineScheme, ModuleFP, Map}(MD, OOX, Mpre, default_cov) if check # Check that all sheaves of modules are compatible on the overlaps. # TODO: eventually replace by a check that on every basic @@ -737,7 +737,7 @@ function twisting_sheaf(IP::AbsProjectiveScheme{<:Field}, d::Int) haskey(twisting_sheaves, d) && return twisting_sheaves[d] X = covered_scheme(IP) - MD = IdDict{AbsSpec, ModuleFP}() + MD = IdDict{AbsAffineScheme, ModuleFP}() S = homogeneous_coordinate_ring(IP) n = ngens(S)-1 for i in 1:n+1 @@ -745,7 +745,7 @@ function twisting_sheaf(IP::AbsProjectiveScheme{<:Field}, d::Int) MD[U] = FreeMod(OO(U), ["$(symbols(S)[i])^$d"]) end - MG = IdDict{Tuple{AbsSpec, AbsSpec}, MatrixElem}() + MG = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, MatrixElem}() C = default_covering(X) for G in values(gluings(C)) (U, V) = patches(G) @@ -801,11 +801,11 @@ on ``X`` as a `CoherentSheaf`. """ @attr SheafOfModules function cotangent_sheaf(X::AbsCoveredScheme) - MD = IdDict{AbsSpec, ModuleFP}() + MD = IdDict{AbsAffineScheme, ModuleFP}() for U in affine_charts(X) MD[U] = cotangent_module(U) end - MG = IdDict{Tuple{AbsSpec, AbsSpec}, MatrixElem}() + MG = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, MatrixElem}() C = default_covering(X) for G in values(gluings(C)) (U, V) = patches(G) @@ -821,28 +821,28 @@ on ``X`` as a `CoherentSheaf`. end @doc raw""" - cotangent_module(X::AbsSpec) + cotangent_module(X::AbsAffineScheme) Return the ``𝒪(X)``-module ``Ω¹(X)`` of Kaehler-differentials on ``X``. """ -function cotangent_module(X::AbsSpec) +function cotangent_module(X::AbsAffineScheme) error("method not implemented for this type of ring") end -@attr ModuleFP function cotangent_module(X::AbsSpec{<:Field, <:MPolyRing}) +@attr ModuleFP function cotangent_module(X::AbsAffineScheme{<:Field, <:MPolyRing}) R = OO(X) F = FreeMod(R, ["d$(x)" for x in symbols(R)]) return F end -@attr ModuleFP function cotangent_module(X::AbsSpec{<:Field, <:MPolyLocRing}) +@attr ModuleFP function cotangent_module(X::AbsAffineScheme{<:Field, <:MPolyLocRing}) R = OO(X) P = base_ring(R) F = FreeMod(R, ["d$(x)" for x in symbols(P)]) return F end -@attr ModuleFP function cotangent_module(X::AbsSpec{<:Field, <:MPolyQuoRing}) +@attr ModuleFP function cotangent_module(X::AbsAffineScheme{<:Field, <:MPolyQuoRing}) R = OO(X) P = base_ring(R) F = FreeMod(R, ["d$(x)" for x in symbols(P)]) @@ -851,7 +851,7 @@ end return M end -@attr ModuleFP function cotangent_module(X::AbsSpec{<:Field, <:MPolyQuoLocRing}) +@attr ModuleFP function cotangent_module(X::AbsAffineScheme{<:Field, <:MPolyQuoLocRing}) R = OO(X) P = base_ring(R) F = FreeMod(R, ["d$(x)" for x in symbols(P)]) @@ -895,11 +895,11 @@ end OOX === sheaf_of_rings(G) || error("sheaves must be defined over the same sheaves of rings") ### Production of the modules on open sets; to be cached - function production_func(FF::AbsPreSheaf, U::AbsSpec) + function production_func(FF::AbsPreSheaf, U::AbsAffineScheme) return hom(F(U), G(U))[1] end - function restriction_func(FF::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(FF::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) MV = FF(V) MU = FF(U) dom_res = F(V, U) @@ -923,11 +923,11 @@ end end Mpre = PreSheafOnScheme(X, production_func, restriction_func, - OpenType=AbsSpec, OutputType=ModuleFP, + OpenType=AbsAffineScheme, OutputType=ModuleFP, RestrictionType=Map, - is_open_func=_is_open_func_for_schemes_without_specopen(X) + is_open_func=_is_open_func_for_schemes_without_affine_scheme_open_subscheme(X) ) - M = new{typeof(X), AbsSpec, ModuleFP, Map}(F, G, OOX, Mpre) + M = new{typeof(X), AbsAffineScheme, ModuleFP, Map}(F, G, OOX, Mpre) return M end @@ -961,14 +961,14 @@ codomain(M::HomSheaf) = M.codomain all(x->(sheaf_of_rings(x)===OOX), summands) || error("summands must be defined over the same sheaves of rings") ### Production of the modules on open sets; to be cached - function production_func(FF::AbsPreSheaf, U::AbsSpec) + function production_func(FF::AbsPreSheaf, U::AbsAffineScheme) result, inc, pr = direct_sum([F(U) for F in summands]..., task=:both) set_attribute!(result, :inclusions, inc) # TODO: Workaround as long as the maps are not cached. set_attribute!(result, :projections, pr) return result end - function restriction_func(FF::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(FF::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) MV = FF(V) MU = FF(U) inc_V = get_attribute(MV, :inclusions)::Vector @@ -987,11 +987,11 @@ codomain(M::HomSheaf) = M.codomain end Mpre = PreSheafOnScheme(X, production_func, restriction_func, - OpenType=AbsSpec, OutputType=ModuleFP, + OpenType=AbsAffineScheme, OutputType=ModuleFP, RestrictionType=Map, - is_open_func=_is_open_func_for_schemes_without_specopen(X) + is_open_func=_is_open_func_for_schemes_without_affine_scheme_open_subscheme(X) ) - M = new{typeof(X), AbsSpec, ModuleFP, Map}(summands, OOX, Mpre) + M = new{typeof(X), AbsAffineScheme, ModuleFP, Map}(summands, OOX, Mpre) return M end @@ -1042,12 +1042,12 @@ end function free_module(R::StructureSheafOfRings, gen_names::Vector{Symbol}) X = space(R) n = length(gen_names) - MD = IdDict{AbsSpec, ModuleFP}() + MD = IdDict{AbsAffineScheme, ModuleFP}() for U in affine_charts(X) MD[U] = FreeMod(OO(U), gen_names) end - MG = IdDict{Tuple{AbsSpec, AbsSpec}, MatrixElem}() + MG = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, MatrixElem}() C = default_covering(X) for G in values(gluings(C)) (U, V) = patches(G) @@ -1109,7 +1109,7 @@ end OOX::StructureSheafOfRings OOY::StructureSheafOfRings M::AbsCoherentSheaf - ident::IdDict{AbsSpec, Union{Map, Nothing}} # a dictionary caching the identifications + ident::IdDict{AbsAffineScheme, Union{Map, Nothing}} # a dictionary caching the identifications F::PreSheafOnScheme function PushforwardSheaf(inc::CoveredClosedEmbedding, M::AbsCoherentSheaf) @@ -1120,7 +1120,7 @@ end OOY = OO(Y) ### Production of the modules on open sets; to be cached - function production_func(FF::AbsPreSheaf, U::AbsSpec) + function production_func(FF::AbsPreSheaf, U::AbsAffineScheme) # In case X was empty, return the zero module and store nothing in the identifications. if isempty(X) ident[U] = nothing @@ -1166,7 +1166,7 @@ end end - function restriction_func(FF::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(FF::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) MYV = FF(V) MYU = FF(U) incV_list = maps_with_given_codomain(inc, V) @@ -1183,15 +1183,15 @@ end return hom(MYV, MYU, (x->preimage(ident[U], x)).(img_gens), OOY(V, U)) end - ident = IdDict{AbsSpec, Union{Map, Nothing}}() + ident = IdDict{AbsAffineScheme, Union{Map, Nothing}}() Blubber = PreSheafOnScheme(Y, production_func, restriction_func, - OpenType=AbsSpec, OutputType=ModuleFP, + OpenType=AbsAffineScheme, OutputType=ModuleFP, RestrictionType=Map, - is_open_func=_is_open_func_for_schemes_without_specopen(Y) + is_open_func=_is_open_func_for_schemes_without_affine_scheme_open_subscheme(Y) #is_open_func=_is_open_for_modules(Y) ) - MY = new{typeof(Y), AbsSpec, ModuleFP, Map}(inc, OOX, OOY, M, ident, Blubber) + MY = new{typeof(Y), AbsAffineScheme, ModuleFP, Map}(inc, OOX, OOY, M, ident, Blubber) return MY end end @@ -1255,7 +1255,7 @@ end OOX::StructureSheafOfRings # the sheaf of rings in the domain OOY::StructureSheafOfRings # the sheaf of rings in the codomain M::AbsCoherentSheaf # the sheaf of modules on Y - pullback_of_sections::IdDict{AbsSpec, Union{Map, Nothing}} # a dictionary caching the natural + pullback_of_sections::IdDict{AbsAffineScheme, Union{Map, Nothing}} # a dictionary caching the natural # pullback maps along the maps in the `covering_morphism` of f F::PreSheafOnScheme # the internal caching instance doing the bookkeeping @@ -1268,7 +1268,7 @@ end fcov = covering_morphism(f)::CoveringMorphism CX = domain(fcov)::Covering CY = codomain(fcov)::Covering - pullbacks = IdDict{AbsSpec, Map}() + pullbacks = IdDict{AbsAffineScheme, Map}() ### Production of the modules on open sets. # @@ -1283,7 +1283,7 @@ end # # Again, this case is not implemented for the time being. - function production_func(FF::AbsPreSheaf, U::AbsSpec) + function production_func(FF::AbsPreSheaf, U::AbsAffineScheme) # See whether U is a patch of the domain covering and pull back directly if haskey(morphisms(fcov), U) floc = morphisms(fcov)[U] @@ -1297,7 +1297,7 @@ end end function production_func(FF::AbsPreSheaf, - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) # See whether U is a patch of the domain covering and pull back directly if haskey(morphisms(fcov), U) @@ -1344,7 +1344,7 @@ end # 4) If V is a node hanging below some patch in `domain(ϕ)` and # U is a subset, restrict as usual. - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) if haskey(morphisms(fcov), V) if haskey(morphisms(fcov), U) # case 1) @@ -1365,14 +1365,14 @@ end error("case not implemented") end - ident = IdDict{AbsSpec, Union{Map, Nothing}}() + ident = IdDict{AbsAffineScheme, Union{Map, Nothing}}() Blubber = PreSheafOnScheme(X, production_func, restriction_func, - OpenType=AbsSpec, OutputType=ModuleFP, + OpenType=AbsAffineScheme, OutputType=ModuleFP, RestrictionType=Map, - is_open_func=_is_open_func_for_schemes_without_specopen(X) + is_open_func=_is_open_func_for_schemes_without_affine_scheme_open_subscheme(X) ) - MY = new{typeof(X), AbsSpec, ModuleFP, Map}(f, OOX, OOY, M, pullbacks, Blubber) + MY = new{typeof(X), AbsAffineScheme, ModuleFP, Map}(f, OOX, OOY, M, pullbacks, Blubber) return MY end end @@ -1435,7 +1435,7 @@ end @attr function trivializing_covering(M::AbsCoherentSheaf) X = scheme(M) OOX = OO(X) - patch_list = Vector{AbsSpec}() + patch_list = Vector{AbsAffineScheme}() for U in affine_charts(X) patch_list = vcat(patch_list, _trivializing_covering(M, U)) end @@ -1485,7 +1485,7 @@ end # M on the Ws. dom_triv = trivializing_covering(domain(M)) cod_triv = trivializing_covering(codomain(M)) - patch_list = AbsSpec[] + patch_list = AbsAffineScheme[] for U in patches(dom_triv) for V in patches(cod_triv) success, W = _have_common_ancestor(U, V) @@ -1550,7 +1550,7 @@ end return C end -function _trivializing_covering(M::AbsCoherentSheaf, U::AbsSpec) +function _trivializing_covering(M::AbsCoherentSheaf, U::AbsAffineScheme) X = scheme(M) OOX = OO(X) MU = M(U) @@ -1580,7 +1580,7 @@ function _trivializing_covering(M::AbsCoherentSheaf, U::AbsSpec) Y = connected_components(U) length(Y) == 1 && error("sheaf is not locally free") - return_patches = AbsSpec[] + return_patches = AbsAffineScheme[] for V in Y # Test for being locally free on V rho = OOX(U, V) @@ -1596,7 +1596,7 @@ function _trivializing_covering(M::AbsCoherentSheaf, U::AbsSpec) # are sufficient to do so. This set can not assumed to be minimal, though. a = coordinates(one(OOX(U)), I) nonzero_entries = [ i for i in 1:ngens(I) if !iszero(a[i])] - return_patches = AbsSpec[] + return_patches = AbsAffineScheme[] for t in nonzero_entries i = div(t-1, ncols(A)) + 1 @@ -1707,8 +1707,8 @@ function projectivization(E::AbsCoherentSheaf; X = scheme(E) check && (is_locally_free(E) || error("coherent sheaf must be locally free")) C = trivializing_covering(E) - algebras = IdDict{AbsSpec, Union{MPolyQuoRing, MPolyRing}}() - on_patches = IdDict{AbsSpec, AbsProjectiveScheme}() + algebras = IdDict{AbsAffineScheme, Union{MPolyQuoRing, MPolyRing}}() + on_patches = IdDict{AbsAffineScheme, AbsProjectiveScheme}() # Fill in the names of the variables in case there are none provided. if length(var_names) == 0 @@ -1730,11 +1730,11 @@ function projectivization(E::AbsCoherentSheaf; RU = rees_algebra(E(U), var_names=var_names[1:r]) algebras[U] = RU SU, _ = grade(RU) - PU = ProjectiveScheme(SU) + PU = proj(SU) set_base_scheme!(PU, U) on_patches[U] = PU end - projective_gluings = IdDict{Tuple{AbsSpec, AbsSpec}, AbsProjectiveGluing}() + projective_gluings = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsProjectiveGluing}() OX = StructureSheafOfRings(X) # prepare for the projective gluings @@ -1755,11 +1755,11 @@ function projectivization(E::AbsCoherentSheaf; # on the overlap U ∩ V. !(G isa Gluing) || error("method not implemented for this type of gluing") - # The problem is that on a SpecOpen U ∩ V + # The problem is that on a AffineSchemeOpenSubscheme U ∩ V # despite I(U)|U ∩ V == I(V)|U ∩ V, we # have no method to find coefficients aᵢⱼ such that fᵢ = ∑ⱼaᵢⱼ⋅gⱼ # for the generators fᵢ of I(U) and gⱼ of I(V): Even though - # we can do this locally on the patches of a SpecOpen, the result + # we can do this locally on the patches of a AffineSchemeOpenSubscheme, the result # is not guaranteed to glue to global functions on the overlap. # Abstractly, we know that the intersection of affine charts # in a separated scheme must be affine, but we do not have a diff --git a/experimental/Schemes/CoveredProjectiveSchemes.jl b/experimental/Schemes/CoveredProjectiveSchemes.jl index cd51971b93ef..c4493c90f050 100644 --- a/experimental/Schemes/CoveredProjectiveSchemes.jl +++ b/experimental/Schemes/CoveredProjectiveSchemes.jl @@ -31,27 +31,27 @@ gluing_morphisms(PG::AbsProjectiveGluing) = gluing_morphisms(underlying_gluing(P X::AbsProjectiveScheme, Y::AbsProjectiveScheme, BG::AbsGluing, - compute_function::Function, + compute_function::Function, gluing_data ) Produce a container `pg` to host a non-computed `ProjectiveGluing` of ``X`` with ``Y``. -The arguments consist of +The arguments consist of * the patches ``X`` and ``Y`` to be glued; - * a gluing `BG` of the `base_scheme`s of ``X`` and ``Y`` over which the + * a gluing `BG` of the `base_scheme`s of ``X`` and ``Y`` over which the `ProjectiveGluing` to be computed sits; - * a function `compute_function` which takes a single argument `gluing_data` - of arbitrary type and actually carries out the computation; - * an arbitrary struct `gluing_data` that the user can fill with whatever - information is needed to properly feed their `compute_function`. - -The container `pg` can then be stored as the gluing of ``X`` and ``Y``. As soon -as it is asked about any data on the gluing beyond its two `patches`, it will -invoke the internally stored `compute_function` to actually carry out the computation -of the gluing and then serve the incoming request on the basis of that result. -The latter actual `ProjectiveGluing` will then be cached. + * a function `compute_function` which takes a single argument `gluing_data` + of arbitrary type and actually carries out the computation; + * an arbitrary struct `gluing_data` that the user can fill with whatever + information is needed to properly feed their `compute_function`. + +The container `pg` can then be stored as the gluing of ``X`` and ``Y``. As soon +as it is asked about any data on the gluing beyond its two `patches`, it will +invoke the internally stored `compute_function` to actually carry out the computation +of the gluing and then serve the incoming request on the basis of that result. +The latter actual `ProjectiveGluing` will then be cached. """ mutable struct LazyProjectiveGluing{ GluingType<:AbsGluing, @@ -67,7 +67,7 @@ mutable struct LazyProjectiveGluing{ X::AbsProjectiveScheme, Y::AbsProjectiveScheme, BG::AbsGluing, - compute_function::Function, + compute_function::Function, gluing_data ) (base_scheme(X), base_scheme(Y)) == patches(BG) || error("gluing is incompatible with provided patches") @@ -89,21 +89,21 @@ end @doc raw""" ProjectiveGluing( - G::GluingType, + G::GluingType, incP::IncType, incQ::IncType, f::IsoType, g::IsoType; check::Bool=true ) where {GluingType<:AbsGluing, IncType<:ProjectiveSchemeMor, IsoType<:ProjectiveSchemeMor} -The `AbsProjectiveSchemeMorphism`s `incP` and `incQ` are open embeddings over open -embeddings of their respective `base_scheme`s. +The `AbsProjectiveSchemeMorphism`s `incP` and `incQ` are open embeddings over open +embeddings of their respective `base_scheme`s. PX ↩ PU ≅ QV ↪ QY π ↓ ↓ ↓ ↓ π - G : X ↩ U ≅ V ↪ Y + G : X ↩ U ≅ V ↪ Y -This creates a gluing of the projective schemes `codomain(incP)` and `codomain(incQ)` -over a gluing `G` of their `base_scheme`s along the morphisms of `AbsProjectiveScheme`s +This creates a gluing of the projective schemes `codomain(incP)` and `codomain(incQ)` +over a gluing `G` of their `base_scheme`s along the morphisms of `AbsProjectiveScheme`s `f` and `g`, identifying `domain(incP)` and `domain(incQ)`, respectively. """ mutable struct ProjectiveGluing{ @@ -119,18 +119,18 @@ mutable struct ProjectiveGluing{ f::IsoType1 g::IsoType2 - ### - # Given two relative projective schemes and a gluing + ### + # Given two relative projective schemes and a gluing # # PX ↩ PU ≅ QV ↪ QY # π ↓ ↓ ↓ ↓ π - # G : X ↩ U ≅ V ↪ Y + # G : X ↩ U ≅ V ↪ Y # - # this constructs the gluing of PX and QY along - # their open subsets PU and QV, given the two inclusions + # this constructs the gluing of PX and QY along + # their open subsets PU and QV, given the two inclusions # and isomorphisms over the gluing G in the base schemes. function ProjectiveGluing( - G::GluingType, + G::GluingType, incP::IncType1, incQ::IncType2, f::IsoType1, g::IsoType2; check::Bool=true @@ -206,34 +206,34 @@ patches(PG::ProjectiveGluing) = (codomain(PG.inc_to_P), codomain(PG.inc_to_Q)) gluing_morphisms(PG::ProjectiveGluing) = (PG.f, PG.g) ### Proper schemes π : Z → X over a covered base scheme X -# -# When {Uᵢ} is an affine covering of X, the datum stored -# consists of a list of projective schemes +# +# When {Uᵢ} is an affine covering of X, the datum stored +# consists of a list of projective schemes # # Zᵢ ⊂ ℙʳ⁽ⁱ⁾(𝒪(Uᵢ)) → Uᵢ # -# with varying ambient spaces ℙʳ⁽ⁱ⁾(𝒪(Uᵢ)) and a list of -# identifications (transitions) +# with varying ambient spaces ℙʳ⁽ⁱ⁾(𝒪(Uᵢ)) and a list of +# identifications (transitions) # # Zᵢ ∩ π⁻¹(Uⱼ) ≅ Zⱼ ∩ π⁻¹(Uᵢ) # # of projective schemes over Uᵢ∩ Uⱼ for all pairs (i,j). # -# These structs are designed to accommodate blowups of -# covered schemes along arbitrary centers, as well as -# projective bundles. +# These structs are designed to accommodate blowups of +# covered schemes along arbitrary centers, as well as +# projective bundles. @attributes mutable struct CoveredProjectiveScheme{BRT} <: Scheme{BRT} Y::AbsCoveredScheme # the base scheme BC::Covering # the reference covering of the base scheme - patches::IdDict{AbsSpec, AbsProjectiveScheme} # the projective spaces over the affine patches in the base covering - gluings::IdDict{Tuple{AbsSpec, AbsSpec}, AbsProjectiveGluing} # the transitions sitting over the affine patches in the gluing domains of the base scheme + patches::IdDict{AbsAffineScheme, AbsProjectiveScheme} # the projective spaces over the affine patches in the base covering + gluings::IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsProjectiveGluing} # the transitions sitting over the affine patches in the gluing domains of the base scheme function CoveredProjectiveScheme( Y::AbsCoveredScheme, C::Covering, - projective_patches::IdDict{AbsSpec, AbsProjectiveScheme}, - projective_gluings::IdDict{Tuple{AbsSpec, AbsSpec}, AbsProjectiveGluing}; + projective_patches::IdDict{AbsAffineScheme, AbsProjectiveScheme}, + projective_gluings::IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsProjectiveGluing}; check::Bool=true ) C in coverings(Y) || error("covering not listed") @@ -251,8 +251,8 @@ base_scheme(P::CoveredProjectiveScheme) = P.Y base_covering(P::CoveredProjectiveScheme) = P.BC base_patches(P::CoveredProjectiveScheme) = patches(P.BC) projective_patches(P::CoveredProjectiveScheme) = values(P.patches) -getindex(P::CoveredProjectiveScheme, U::AbsSpec) = (P.patches)[U] -getindex(P::CoveredProjectiveScheme, U::AbsSpec, V::AbsSpec) = (P.gluings)[(U, V)] +getindex(P::CoveredProjectiveScheme, U::AbsAffineScheme) = (P.patches)[U] +getindex(P::CoveredProjectiveScheme, U::AbsAffineScheme, V::AbsAffineScheme) = (P.gluings)[(U, V)] ############################################################################### # @@ -320,19 +320,19 @@ function empty_covered_projective_scheme(R::T) where {T<:AbstractAlgebra.Ring} C = default_covering(Y) #U = C[1] #ST = affine_patch_type(Y) - pp = IdDict{AbsSpec, AbsProjectiveScheme}() + pp = IdDict{AbsAffineScheme, AbsProjectiveScheme}() #P = projective_space(U, 0) #pp[U] = P - tr = IdDict{Tuple{AbsSpec, AbsSpec}, AbsProjectiveGluing}() - #W = SpecOpen(U) + tr = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsProjectiveGluing}() + #W = AffineSchemeOpenSubscheme(U) #PW, inc = fiber_product(restriction_map(U, W), P) - #tr[(U, U)] = ProjectiveGluing(Gluing(U, U, identity_map(W), identity_map(W)), + #tr[(U, U)] = ProjectiveGluing(Gluing(U, U, identity_map(W), identity_map(W)), #inc, inc, identity_map(PW), identity_map(PW)) return CoveredProjectiveScheme(Y, C, pp, tr) end @doc raw""" - blow_up_chart(W::AbsSpec, I::Ideal) + blow_up_chart(W::AbsAffineScheme, I::Ideal) Return the blowup of ``W`` at the ideal ``I``; this is a `ProjectiveScheme` with `base_scheme` ``W``. @@ -341,7 +341,7 @@ with `base_scheme` ``W``. blow_up relies on this internal method for computing the blow ups of all chartsand appropriately assembles the returned projective schemes to a single coverec scheme. """ -function blow_up_chart(W::AbsSpec, I::Ideal; var_name::VarName = :s) +function blow_up_chart(W::AbsAffineScheme, I::Ideal; var_name::VarName = :s) error("method `blow_up_chart` not implemented for arguments of type $(typeof(W)) and $(typeof(I))") end @@ -349,11 +349,11 @@ end # Blowups of affine schemes # ######################################################################## -function blow_up_chart(W::AbsSpec{<:Field, <:MPolyRing}, I::MPolyIdeal; +function blow_up_chart(W::AbsAffineScheme{<:Field, <:MPolyRing}, I::MPolyIdeal; var_name::VarName = :s ) base_ring(I) === OO(W) || error("ideal does not belong to the correct ring") -# if one(OO(W)) in I +# if one(OO(W)) in I # error("blowing up along the unit ideal; this case should be caught earlier") # # construct a relative ℙ⁰ over W with its identifying projection? # end @@ -367,7 +367,7 @@ function blow_up_chart(W::AbsSpec{<:Field, <:MPolyRing}, I::MPolyIdeal; J = ideal(S, [t[i]*g[j] - t[j]*g[i] for i in 1:r, j in i+1:r+1]) IPY = subscheme(IPW, J) # Compute the IdealSheaf for the exceptional divisor - ID = IdDict{AbsSpec, RingElem}() + ID = IdDict{AbsAffineScheme, RingElem}() Y = covered_scheme(IPY) p = covered_projection_to_base(IPY) p_cov = covering_morphism(p) @@ -382,21 +382,21 @@ function blow_up_chart(W::AbsSpec{<:Field, <:MPolyRing}, I::MPolyIdeal; set_attribute!(IPY, :exceptional_divisor, E) # Prepare the decomposition data - decomp_dict = IdDict{AbsSpec, Vector{RingElem}}() + decomp_dict = IdDict{AbsAffineScheme, Vector{RingElem}}() for k in 1:ngens(I) U = affine_charts(Y)[i] decomp_dict[U] = gens(OO(U))[1:k-1] # Relies on the projective variables coming first! end # Cache the isomorphism on the complement of the center - p_res_dict = IdDict{AbsSpec, AbsSpecMor}() + p_res_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for i in 1:ngens(I) UW = PrincipalOpenSubset(W, gen(I, i)) V = affine_charts(Y)[i] VW = PrincipalOpenSubset(V, E(V)) p_res_dict[VW] = restrict(p_cov[V], VW, UW, check=false) g = OO(UW).(gens(I)) - set_attribute!(p_res_dict[VW], :inverse, + set_attribute!(p_res_dict[VW], :inverse, morphism(UW, VW, vcat([g[j]*inv(g[i]) for j in 1:ngens(I) if j != i], gens(OO(UW))), check=false) ) end @@ -410,7 +410,7 @@ function blow_up_chart(W::AbsSpec{<:Field, <:MPolyRing}, I::MPolyIdeal; x = gens(R) kk = coefficient_ring(R) A, x_ext = polynomial_ring(kk, vcat(symbols(R), [:t])) - t = last(x_ext) + t = last(x_ext) inc = hom(R, A, x_ext[1:end-1], check=false) phi = hom(OO(CIPW), A, vcat([inc(g[i])*t for i in 1:r+1], x_ext[1:end-1], ), check=false) # the homogeneous variables come first J = kernel(phi) @@ -418,7 +418,7 @@ function blow_up_chart(W::AbsSpec{<:Field, <:MPolyRing}, I::MPolyIdeal; Jh = ideal(homogeneous_coordinate_ring(IPW), pb.(lifted_numerator.(gens(J)))) IPY = subscheme(IPW, Jh) # Compute the IdealSheaf for the exceptional divisor - ID = IdDict{AbsSpec, RingElem}() + ID = IdDict{AbsAffineScheme, RingElem}() Y = covered_scheme(IPY) p = covered_projection_to_base(IPY) p_cov = covering_morphism(p) @@ -428,24 +428,24 @@ function blow_up_chart(W::AbsSpec{<:Field, <:MPolyRing}, I::MPolyIdeal; W === codomain(p_res) || error("codomain not correct") ID[affine_charts(Y)[i]] = pullback(p_res)(gen(I, i)) end - E = Oscar.EffectiveCartierDivisor(Y, ID, trivializing_covering=domain(p_cov), check=false) + E = Oscar.EffectiveCartierDivisor(Y, ID, trivializing_covering=domain(p_cov), check=false) set_attribute!(Y, :exceptional_divisor, E) set_attribute!(IPY, :exceptional_divisor, E) # Cache the isomorphism on the complement of the center - p_res_dict = IdDict{AbsSpec, AbsSpecMor}() + p_res_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for i in 1:ngens(I) UW = PrincipalOpenSubset(W, gen(I, i)) V = affine_charts(Y)[i] VW = PrincipalOpenSubset(V, E(V)) p_res_dict[VW] = restrict(p_cov[V], VW, UW, check=false) g = OO(UW).(gens(I)) - set_attribute!(p_res_dict[VW], :inverse, + set_attribute!(p_res_dict[VW], :inverse, morphism(UW, VW, vcat([g[j]*inv(g[i]) for j in 1:ngens(I) if j != i], gens(OO(UW))), check=false) ) end - + # Prepare the decomposition data - decomp_dict = IdDict{AbsSpec, Vector{RingElem}}() + decomp_dict = IdDict{AbsAffineScheme, Vector{RingElem}}() for k in 1:ngens(I) U = affine_charts(Y)[k] decomp_dict[U] = gens(OO(U))[1:k-1] # Relies on the projective variables coming first! @@ -457,7 +457,7 @@ function blow_up_chart(W::AbsSpec{<:Field, <:MPolyRing}, I::MPolyIdeal; end end -function blow_up_chart(W::AbsSpec{<:Field, <:RingType}, I::Ideal; +function blow_up_chart(W::AbsAffineScheme{<:Field, <:RingType}, I::Ideal; var_name::VarName = :s ) where {RingType<:Union{MPolyQuoRing, MPolyLocRing, MPolyQuoLocRing}} base_ring(I) === OO(W) || error("ideal does not belong to the correct ring") @@ -469,10 +469,10 @@ function blow_up_chart(W::AbsSpec{<:Field, <:RingType}, I::Ideal; phi = hom(S, T, [t*g for g in gens(I)], check=false) K = kernel(phi) K = ideal(S, [g for g in gens(K) if !iszero(g)]) # clean up superfluous generators - Bl_W = ProjectiveScheme(S, K) + Bl_W = proj(S, K) set_base_scheme!(Bl_W, W) # Compute the IdealSheaf for the exceptional divisor - ID = IdDict{AbsSpec, RingElem}() + ID = IdDict{AbsAffineScheme, RingElem}() Y = covered_scheme(Bl_W) p = covered_projection_to_base(Bl_W) p_cov = covering_morphism(p) @@ -485,23 +485,23 @@ function blow_up_chart(W::AbsSpec{<:Field, <:RingType}, I::Ideal; E = Oscar.EffectiveCartierDivisor(Y, ID, trivializing_covering=domain(p_cov), check=false) set_attribute!(Y, :exceptional_divisor, E) set_attribute!(Bl_W, :exceptional_divisor, E) - + # Cache the isomorphism on the complement of the center - p_res_dict = IdDict{AbsSpec, AbsSpecMor}() + p_res_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for i in 1:ngens(I) UW = PrincipalOpenSubset(W, gen(I, i)) V = affine_charts(Y)[i] VW = PrincipalOpenSubset(V, E(V)) p_res_dict[VW] = restrict(p_cov[V], VW, UW, check=false) g = OO(UW).(gens(I)) - set_attribute!(p_res_dict[VW], :inverse, + set_attribute!(p_res_dict[VW], :inverse, morphism(UW, VW, vcat([g[j]*inv(g[i]) for j in 1:ngens(I) if j != i], gens(OO(UW))), check=false) ) end set_attribute!(p, :isos_on_complement_of_center, p_res_dict) # Prepare the decomposition data - decomp_dict = IdDict{AbsSpec, Vector{RingElem}}() + decomp_dict = IdDict{AbsAffineScheme, Vector{RingElem}}() for k in 1:ngens(I) U = affine_charts(Y)[k] decomp_dict[U] = gens(OO(U))[1:k-1] # Relies on the projective variables coming first! @@ -522,7 +522,7 @@ function is_regular_sequence(g::Vector{T}) where {T<:RingElem} end -#function blow_up(W::Spec, I::MPolyQuoLocalizedIdeal; +#function blow_up(W::AffineScheme, I::MPolyQuoLocalizedIdeal; # var_names::Vector{Symbol}=Symbol.(["s$(i-1)" for i in 1:ngens(I)]), # verbose::Bool=false, # check::Bool=true, @@ -545,9 +545,9 @@ end ## blow up X in the center described by g using these explicit generators. #function blow_up( -# W::Spec, -# I::Vector{RingElemType}; -# var_names::Vector{Symbol}=Vector{Symbol}(), +# W::AffineScheme, +# I::Vector{RingElemType}; +# var_names::Vector{Symbol}=Vector{Symbol}(), # verbose::Bool=false, # check::Bool=true, # is_regular_sequence::Bool=false @@ -614,9 +614,9 @@ end # covered_ambient = as_covered_scheme(Pw) # ambient_projection_map = get_attribute(Pw, :covered_projection_to_base) # C = default_covering(covered_ambient) -# SpecType = affine_patch_type(covered_ambient) -# PolyType = poly_type(SpecType) -# Idict = Dict{SpecType, ideal_type(ring_type(SpecType))}() +# AffineSchemeType = affine_patch_type(covered_ambient) +# PolyType = poly_type(AffineSchemeType) +# Idict = Dict{AffineSchemeType, ideal_type(ring_type(AffineSchemeType))}() # @show I # for i in 1:n_patches(C) # @show i @@ -637,7 +637,7 @@ end # set_attribute!(projective_version, :standard_covering, default_covering(covered_version)) # @show "done" # -# proj_dict = Dict{SpecType, morphism_type(SpecType, SpecType)}() +# proj_dict = Dict{AffineSchemeType, morphism_type(AffineSchemeType, AffineSchemeType)}() # @show "doing some other stuff" # for i in 1:length(I) # @show i @@ -662,23 +662,23 @@ end # end #end -# This is a sample for how to use LazyProjectiveGluings. -# Originally, we probably had some body of a double for-loop iterating over -# pairs of patches (P, Q) that we need to glue. We take that body which -# computes the gluing of P and Q and move -# it to an external function (here _compute_projective_gluing). Then we -# go through all the local variables in the body of the for-loop which -# are needed for the actual computation and create a tailor-made struct to -# house them. We add an extraction section in the beginning of the compute -# function to restore them and recreate the original setting within the -# for-loops. -# -# Finally, we can replace the inner part of the double for-loop with the -# actual wrap-up of the local variables and feed everything to a constructor -# for a `LazyProjectiveGluing` as documented above. +# This is a sample for how to use LazyProjectiveGluings. +# Originally, we probably had some body of a double for-loop iterating over +# pairs of patches (P, Q) that we need to glue. We take that body which +# computes the gluing of P and Q and move +# it to an external function (here _compute_projective_gluing). Then we +# go through all the local variables in the body of the for-loop which +# are needed for the actual computation and create a tailor-made struct to +# house them. We add an extraction section in the beginning of the compute +# function to restore them and recreate the original setting within the +# for-loops. +# +# Finally, we can replace the inner part of the double for-loop with the +# actual wrap-up of the local variables and feed everything to a constructor +# for a `LazyProjectiveGluing` as documented above. struct CoveredProjectiveGluingData - U::AbsSpec - V::AbsSpec + U::AbsAffineScheme + V::AbsAffineScheme P::AbsProjectiveScheme Q::AbsProjectiveScheme G::AbsGluing @@ -700,23 +700,23 @@ function _compute_projective_gluing(gd::CoveredProjectiveGluingData) UV, VU = gluing_domains(G) f, g = gluing_morphisms(G) - # to construct the identifications of PUV with QVU we need to + # to construct the identifications of PUV with QVU we need to # express the generators of I(U) in terms of the generators of I(V) - # on the overlap U ∩ V. + # on the overlap U ∩ V. !(G isa Gluing) || error("method not implemented for this type of gluing") QVU, QVUtoQ = fiber_product(OX(V, VU), Q) PUV, PUVtoP = fiber_product(OX(U, UV), P) - # The problem is that on a SpecOpen U ∩ V - # despite I(U)|U ∩ V == I(V)|U ∩ V, we + # The problem is that on a AffineSchemeOpenSubscheme U ∩ V + # despite I(U)|U ∩ V == I(V)|U ∩ V, we # have no method to find coefficients aᵢⱼ such that fᵢ = ∑ⱼaᵢⱼ⋅gⱼ - # for the generators fᵢ of I(U) and gⱼ of I(V): Even though - # we can do this locally on the patches of a SpecOpen, the result + # for the generators fᵢ of I(U) and gⱼ of I(V): Even though + # we can do this locally on the patches of a AffineSchemeOpenSubscheme, the result # is not guaranteed to glue to global functions on the overlap. - # Abstractly, we know that the intersection of affine charts - # in a separated scheme must be affine, but we do not have a + # Abstractly, we know that the intersection of affine charts + # in a separated scheme must be affine, but we do not have a # model of this overlap as an affine scheme and hence no computational - # backup. + # backup. # fᵢ the generators of I(U) # gⱼ the generators of I(V) @@ -730,8 +730,8 @@ function _compute_projective_gluing(gd::CoveredProjectiveGluingData) B = [coordinates(OX(V, UV)(g), ideal(OO(UV), OX(U, UV).(gens(I(U))))) for g in gens(I(V))] # B[j][i] = bⱼᵢ SQVU = homogeneous_coordinate_ring(QVU) SPUV = homogeneous_coordinate_ring(PUV) - # the induced map is ℙ(UV) → ℙ(VU), tⱼ ↦ ∑ᵢ bⱼᵢ ⋅ sᵢ - # and ℙ(VU) → ℙ(UV), sᵢ ↦ ∑ⱼ aᵢⱼ ⋅ tⱼ + # the induced map is ℙ(UV) → ℙ(VU), tⱼ ↦ ∑ᵢ bⱼᵢ ⋅ sᵢ + # and ℙ(VU) → ℙ(UV), sᵢ ↦ ∑ⱼ aᵢⱼ ⋅ tⱼ fup = ProjectiveSchemeMor(PUV, QVU, hom(SQVU, SPUV, pullback(f), [sum([B[j][i]*SPUV[i] for i in 1:ngens(SPUV)]) for j in 1:length(B)], check=false), check=false) gup = ProjectiveSchemeMor(QVU, PUV, hom(SPUV, SQVU, pullback(g), [sum([A[i][j]*SQVU[j] for j in 1:ngens(SQVU)]) for i in 1:length(A)], check=false), check=false) return ProjectiveGluing(G, PUVtoP, QVUtoQ, fup, gup, check=false) @@ -739,12 +739,12 @@ end @doc raw""" - blow_up(X::AbsSpec, I::Ideal) + blow_up(X::AbsAffineScheme, I::Ideal) Return the blow-up morphism of blowing up ``X`` at ``I`` in ``OO(X)``. """ function blow_up( - X::AbsSpec{<:Any, <:MPolyAnyRing}, + X::AbsAffineScheme{<:Any, <:MPolyAnyRing}, I::MPolyAnyIdeal) R = OO(X) @@ -769,20 +769,20 @@ function blow_up( covering::Covering=default_covering(scheme(I)) ) X = space(I) - local_blowups = IdDict{AbsSpec, AbsProjectiveScheme}() - comp_iso_dict = IdDict{AbsSpec, AbsSpecMor}() + local_blowups = IdDict{AbsAffineScheme, AbsProjectiveScheme}() + comp_iso_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(covering) local_blowups[U] = blow_up_chart(U, I(U), var_name=var_name) # Gather the information on the isomorphism on the complement p = covered_projection_to_base(local_blowups[U]) - isos_on_complement_of_center = get_attribute(p, :isos_on_complement_of_center)::IdDict{<:AbsSpec, <:AbsSpecMor} + isos_on_complement_of_center = get_attribute(p, :isos_on_complement_of_center)::IdDict{<:AbsAffineScheme, <:AbsAffineSchemeMor} # manual merge because `merge` does not preserve IdDicts. for x in keys(isos_on_complement_of_center) comp_iso_dict[x] = isos_on_complement_of_center[x] end #comp_iso_dict = merge(comp_iso_dict, isos_on_complement_of_center) end - projective_gluings = IdDict{Tuple{AbsSpec, AbsSpec}, AbsProjectiveGluing}() + projective_gluings = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsProjectiveGluing}() # prepare for the projective gluings for (U, V) in keys(gluings(covering)) @@ -795,7 +795,7 @@ function blow_up( Bl_I = CoveredProjectiveScheme(X, covering, local_blowups, projective_gluings) Y = covered_scheme(Bl_I) # Assemble the exceptional divisor as a Cartier divisor - ID = IdDict{AbsSpec, RingElem}() + ID = IdDict{AbsAffineScheme, RingElem}() p = covered_projection_to_base(Bl_I) p_cov = covering_morphism(p) for U in patches(domain(p_cov)) # These coincide with the patches on which the local E's are defined @@ -816,32 +816,32 @@ function blow_up( end # The following is a wrap-up of local variables necessary to compute gluings -# from morphisms of graded algebras. It will be used to fill in the +# from morphisms of graded algebras. It will be used to fill in the # `LazyGluing` together with the compute function following below. struct ProjectiveGluingData - down_left::AbsSpec - down_right::AbsSpec - up_left::AbsSpec - up_right::AbsSpec + down_left::AbsAffineScheme + down_right::AbsAffineScheme + up_left::AbsAffineScheme + up_right::AbsAffineScheme down_covering::Covering - projective_scheme::CoveredProjectiveScheme + proj::CoveredProjectiveScheme end -# This function actually computes the gluing with the data extracted -# from the ProjectiveGluingData. +# This function actually computes the gluing with the data extracted +# from the ProjectiveGluingData. # -# Originally, this was in the body of a constructor. But we want to -# postpone the actual computation, so we wrap up all necessary local -# variables in a `ProjectiveGluingData` and copy-paste the required -# part of code into the body of this function. Together with a header -# which is restoring our local variables. +# Originally, this was in the body of a constructor. But we want to +# postpone the actual computation, so we wrap up all necessary local +# variables in a `ProjectiveGluingData` and copy-paste the required +# part of code into the body of this function. Together with a header +# which is restoring our local variables. function _compute_gluing(gd::ProjectiveGluingData) U = gd.down_left V = gd.down_right UW = gd.up_left VW = gd.up_right C = gd.down_covering - # Now we have the following diagram + # Now we have the following diagram # # fup, gup # P[U] ⊃ UW ⇢ UD ↔ VD ⇠ VW ⊂ P[V] @@ -849,8 +849,8 @@ function _compute_gluing(gd::ProjectiveGluingData) # U ⊃ A ↔ B ⊂ V # f,g # - # with UW = {sᵢ≠ 0} and VW = {tⱼ≠ 0}. - P = gd.projective_scheme + # with UW = {sᵢ≠ 0} and VW = {tⱼ≠ 0}. + P = gd.proj (A, B) = gluing_domains(C[U, V]) (f, g) = gluing_morphisms(C[U, V]) (UD, VD) = gluing_domains(P[U, V]) @@ -867,20 +867,20 @@ function _compute_gluing(gd::ProjectiveGluingData) hU = dehomogenization_map(UD, AW)(pullback(fup)(pullback(incV)(t_j))) hV = dehomogenization_map(VD, BW)(pullback(gup)(pullback(incU)(s_i))) - # We need to construct the gluing + # We need to construct the gluing # # f', g' # UW ↩ AAW ↔ BBW ↪ VW - # - # as follows. - # From the base gluing we already have that UW differs + # + # as follows. + # From the base gluing we already have that UW differs # from AAW by the pullback of the equation `complement_equation(A)`. - # But then, also `hU` cuts out another locus which needs to be - # removed before gluing. + # But then, also `hU` cuts out another locus which needs to be + # removed before gluing. # - # The same applies to the other side. Finally, we need to track the - # coordinates through the homogenization-gluing-pullback-dehomogenization - # machinery to provide the gluing morphisms. + # The same applies to the other side. Finally, we need to track the + # coordinates through the homogenization-gluing-pullback-dehomogenization + # machinery to provide the gluing morphisms. ptbUD = covered_projection_to_base(UD) ptbVD = covered_projection_to_base(VD) @@ -903,7 +903,7 @@ function _compute_gluing(gd::ProjectiveGluingData) yhh = [(pullback(fup)(pp), pullback(fup)(qq)) for (pp, qq) in yh] phi = dehomogenization_map(VD, BW) - psi = dehomogenization_map(UD, AW) + psi = dehomogenization_map(UD, AW) pb_AW_to_AAW = hom(OO(AW), OO(AAW), gens(OO(AAW)), check=false) pb_BW_to_BBW = hom(OO(BW), OO(BBW), gens(OO(BBW)), check=false) @@ -920,17 +920,17 @@ end @attr function covered_scheme(P::CoveredProjectiveScheme) X = base_scheme(P) C = base_covering(P) - new_patches = Vector{AbsSpec}() - new_gluings = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() - projection_dict = IdDict{AbsSpec, AbsSpecMor}() - parts = IdDict{AbsSpec, AbsCoveredScheme}() + new_patches = Vector{AbsAffineScheme}() + new_gluings = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() + projection_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() + parts = IdDict{AbsAffineScheme, AbsCoveredScheme}() for U in patches(C) parts[U] = Oscar.covered_scheme(P[U]) end - # We first assemble a Covering where the preimage of every base + # We first assemble a Covering where the preimage of every base # patch appears as one connected component result_patches = vcat([affine_charts(parts[U]) for U in patches(C)]...) - result_gluings = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() + result_gluings = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() for U in patches(C) GG = gluings(parts[U]) for (A, B) in keys(GG) @@ -938,14 +938,14 @@ end end end result_covering = Covering(result_patches, result_gluings, check=false) - + # Now we need to add gluings for U in patches(C) for V in patches(C) U === V && continue for UW in affine_charts(parts[U]) for VW in affine_charts(parts[V]) - GGG = LazyGluing(UW, VW, _compute_gluing, + GGG = LazyGluing(UW, VW, _compute_gluing, ProjectiveGluingData(U, V, UW, VW, C, P) ) result_gluings[(UW, VW)] = GGG @@ -956,7 +956,7 @@ end result_covering = Covering(result_patches, result_gluings, check=false) result = CoveredScheme(result_covering) - projection_dict = IdDict{AbsSpec, AbsSpecMor}() + projection_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(C) PP = P[U] p = covered_projection_to_base(PP) @@ -968,14 +968,14 @@ end end # Assemble the decomposition information if applicable - decomp_dict = IdDict{AbsSpec, Vector{RingElem}}() + decomp_dict = IdDict{AbsAffineScheme, Vector{RingElem}}() if has_decomposition_info(C) for V in patches(C) cov_part = default_covering(parts[V]) if has_decomposition_info(cov_part) for U in patches(cov_part) pr = projection_dict[U] - decomp_dict[U] = vcat(decomposition_info(cov_part)[U], + decomp_dict[U] = vcat(decomposition_info(cov_part)[U], elem_type(OO(U))[pullback(pr)(a) for a in decomposition_info(C)[V]] ) end @@ -987,13 +987,13 @@ end end # TODO: Remove the internal checks in the constructors below - covering_map = CoveringMorphism(result_covering, C, projection_dict, check=false) + covering_map = CoveringMorphism(result_covering, C, projection_dict, check=false) set_attribute!(P, :covering_projection_to_base, covering_map) return result end -@attr function covered_projection_to_base(P::CoveredProjectiveScheme) +@attr function covered_projection_to_base(P::CoveredProjectiveScheme) if !has_attribute(P, :covering_projection_to_base) covered_scheme(P) end @@ -1002,7 +1002,7 @@ end end -# function strict_transform(f::SpecMor, h::Vector{PolyType}, g::Vector{PolyType}) where{PolyType<:MPolyRingElem} +# function strict_transform(f::AffineSchemeMor, h::Vector{PolyType}, g::Vector{PolyType}) where{PolyType<:MPolyRingElem} #(IOw: Exc Div ^\infty) # X = domain(f) @@ -1023,7 +1023,7 @@ end # # # -#function total_transform(f::SpecMor, h::Vector{PolyType}, g::Vector{PolyType}) where{PolyType<:MPolyRingElem} +#function total_transform(f::AffineSchemeMor, h::Vector{PolyType}, g::Vector{PolyType}) where{PolyType<:MPolyRingElem} # #IOw # # X = domain(f) @@ -1038,7 +1038,7 @@ end # # #### NOT TESTED YET -#function weak_transform(f::SpecMor, h::Vector{PolyType}, g::Vector{PolyType}) where{PolyType<:MPolyRingElem} +#function weak_transform(f::AffineSchemeMor, h::Vector{PolyType}, g::Vector{PolyType}) where{PolyType<:MPolyRingElem} # # X = domain(f) # Y = codomain(f) @@ -1051,14 +1051,14 @@ end # while true # Inew = quotient(Iold, Excdiv) # !(Iold == Excdiv * Inew) && break -# Iold = Inew +# Iold = Inew # end # return gens(Iold) # #(IOw : Exc Div ^k), k maximal #end # #### NOT TESTED YET -#function controlled_transform(f::SpecMor, h::Vector{PolyType}, g::Vector{PolyType}, i::Int) where{PolyType<:MPolyRingElem} +#function controlled_transform(f::AffineSchemeMor, h::Vector{PolyType}, g::Vector{PolyType}, i::Int) where{PolyType<:MPolyRingElem} # #(IOw : Exc Div ^i) # # X = domain(f) @@ -1081,12 +1081,12 @@ end #end # #function strict_transform( -# P::AbsProjectiveScheme, -# E::IdealSheaf, +# P::AbsProjectiveScheme, +# E::IdealSheaf, # I::Vector{PolyType} # ) where {PolyType<:MPolyRingElem} # X = as_covered_scheme(P) -# C = covering(E) +# C = covering(E) # C in coverings(X) || error("covering not found") # Y = base_scheme(P) # length(I) > 0 || return IdealSheaf(X) # return the zero ideal sheaf @@ -1094,12 +1094,12 @@ end # parent(I[i]) == base_ring(OO(Y)) || error("polynomials do not belong to the correct ring") # end # f = covered_projection_to_base(P) -# if domain(f) !== C +# if domain(f) !== C # f = compose(X[C, domain(f)], f) # end # -# SpecType = affine_patch_type(X) -# trans_dict = Dict{SpecType, Vector{poly_type(SpecType)}}() +# AffineSchemeType = affine_patch_type(X) +# trans_dict = Dict{AffineSchemeType, Vector{poly_type(AffineSchemeType)}}() # for U in patches(C) # println("computing the strict transform on the patch $U") # trans_dict[U] = strict_transform(f[U], E[U], I) @@ -1114,8 +1114,8 @@ end # Y = codomain(f) # CX = domain_covering(f) # CY = codomain_covering(f) -# SpecType = affine_patch_type(X) -# trans_dict = Dict{SpecType, Vector{poly_type(SpecType)}}() +# AffineSchemeType = affine_patch_type(X) +# trans_dict = Dict{AffineSchemeType, Vector{poly_type(AffineSchemeType)}}() # for U in patches(CX) # trans_dict[U] = strict_transform(f[U], E[U], I[codomain(f[U])]) # end @@ -1128,8 +1128,8 @@ end # Y = codomain(f) # CX = domain_covering(f) # CY = codomain_covering(f) -# SpecType = affine_patch_type(X) -# trans_dict = Dict{SpecType, Vector{poly_type(SpecType)}}() +# AffineSchemeType = affine_patch_type(X) +# trans_dict = Dict{AffineSchemeType, Vector{poly_type(AffineSchemeType)}}() # for U in patches(CX) # trans_dict[U] = total_transform(f[U], E[U], I[codomain(f[U])]) # end @@ -1157,7 +1157,7 @@ end # return I #end # -#function prepare_smooth_center(X::Spec, f::Vector{PolyType}; check::Bool=true) where {PolyType<:MPolyRingElem} +#function prepare_smooth_center(X::AffineScheme, f::Vector{PolyType}; check::Bool=true) where {PolyType<:MPolyRingElem} # X_dict = as_smooth_local_complete_intersection(X, verbose=true) # return X_dict #end @@ -1165,9 +1165,9 @@ end #function as_smooth_local_complete_intersection(I::IdealSheaf; check::Bool=true, verbose::Bool=false) # X = scheme(I) # C = covering(I) -# SpecType = affine_patch_type(X) -# PolyType = poly_type(SpecType) -# res_dict = Dict{SpecType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() +# AffineSchemeType = affine_patch_type(X) +# PolyType = poly_type(AffineSchemeType) +# res_dict = Dict{AffineSchemeType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() # for U in patches(C) # merge!(res_dict, as_smooth_local_complete_intersection(U, I[U], check=check, verbose=verbose)) # end @@ -1175,9 +1175,9 @@ end #end # #function as_smooth_local_complete_intersection( -# X::Spec, -# f::Vector{PolyType}; -# check::Bool=true, +# X::AffineScheme, +# f::Vector{PolyType}; +# check::Bool=true, # verbose::Bool=false # ) where {PolyType} # verbose && println("call with $X and $f") @@ -1196,8 +1196,8 @@ end # end # X_dict = _as_smooth_lci_rec(X, X, PolyType[], (Int[], Int[]), Vector{Tuple{Int, Int}}(), g, Dg, Dg, d, n, check=check, verbose=verbose) # verbose && println("####################### done with the ambient space #######################") -# SpecType = typeof(X) -# f_dict = Dict{SpecType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() +# AffineSchemeType = typeof(X) +# f_dict = Dict{AffineSchemeType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() # for U in keys(X_dict) # verbose && println("proceed with finding a regular sequence on $U") # g = X_dict[U][2] @@ -1206,9 +1206,9 @@ end # good = X_dict[U][3] # Z = subscheme(U, f) # d = dim(Z) -# merge!(f_dict, _as_smooth_lci_rec(X, Z, X_dict[U][1], (collect(1:length(g)), good), -# Vector{Tuple{Int, Int}}(), -# f_ext, Df_ext, Df_ext, d, n, +# merge!(f_dict, _as_smooth_lci_rec(X, Z, X_dict[U][1], (collect(1:length(g)), good), +# Vector{Tuple{Int, Int}}(), +# f_ext, Df_ext, Df_ext, d, n, # check=check, verbose=verbose) # ) # end @@ -1217,16 +1217,16 @@ end # #function as_smooth_lci_of_cod(X::CoveredScheme, c::Int; check::Bool=true, verbose::Bool=false) # C = default_covering(X) -# SpecType = affine_patch_type(X) -# PolyType = poly_type(SpecType) -# res_dict = Dict{SpecType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() +# AffineSchemeType = affine_patch_type(X) +# PolyType = poly_type(AffineSchemeType) +# res_dict = Dict{AffineSchemeType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() # for U in patches(C) # merge!(res_dict, as_smooth_lci_of_cod(U, d, check=check, verbose=verbose)) # end # return res_dict #end # -#function as_smooth_lci_of_cod(X::Spec, c::Int; check::Bool=true, verbose::Bool=false) +#function as_smooth_lci_of_cod(X::AffineScheme, c::Int; check::Bool=true, verbose::Bool=false) # R = base_ring(OO(X)) # f = gens(modulus(OO(X))) # Df = jacobian_matrix(f) @@ -1255,16 +1255,16 @@ end # #function as_smooth_local_complete_intersection(X::CoveredScheme; check::Bool=true, verbose::Bool=false) # C = default_covering(X) -# SpecType = affine_patch_type(X) -# PolyType = poly_type(SpecType) -# res_dict = Dict{SpecType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() +# AffineSchemeType = affine_patch_type(X) +# PolyType = poly_type(AffineSchemeType) +# res_dict = Dict{AffineSchemeType, Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() # for U in patches(C) # merge!(res_dict, as_smooth_local_complete_intersection(U, check=check, verbose=verbose)) # end # return res_dict #end # -#function as_smooth_local_complete_intersection(X::Spec; check::Bool=true, verbose::Bool=false) +#function as_smooth_local_complete_intersection(X::AffineScheme; check::Bool=true, verbose::Bool=false) # R = base_ring(OO(X)) # f = gens(modulus(OO(X))) # Df = jacobian_matrix(f) @@ -1281,42 +1281,42 @@ end # return _as_smooth_lci_rec(X, X, poly_type(X)[], (Int[], Int[]), Vector{Tuple{Int, Int}}(), f, Df, Df, d, n, check=check, verbose=verbose) #end # -#### -## Given a matrix A with polynomial entries, this routine returns a -## list of equations hₖ and gₖ, and sets of columns Iₖ and rows Jₖ such that -## the (Iₖ, Jₖ)-minor of A has the prescribed full rank r along the +#### +## Given a matrix A with polynomial entries, this routine returns a +## list of equations hₖ and gₖ, and sets of columns Iₖ and rows Jₖ such that +## the (Iₖ, Jₖ)-minor of A has the prescribed full rank r along the ## hypersurface complement of hₖ of the zero locus of gₖ on C. ## -## Altogether, the latter sets form a disjoint union of C into locally -## closed sets. In particular, we can derive an open covering of C +## Altogether, the latter sets form a disjoint union of C into locally +## closed sets. In particular, we can derive an open covering of C ## from the hypersurface complements of the listed (I, J)-minors. ## -## Input: -## C::Spec the locus that needs to be covered +## Input: +## C::AffineScheme the locus that needs to be covered ## A::Matrix the matrix that needs to have rank r ## r::Int the prescribed rank of the matrix. ## -## Output: +## Output: ## the following lists with index i ## loc_list::Vector{Vector{MPolyRingElem}} A list of partial ## factorizations of polynomials that need to -## be localized in order to arrive at the i-th +## be localized in order to arrive at the i-th ## patch. -## row_list::Vector{Vector{Int}} the indices of the rows +## row_list::Vector{Vector{Int}} the indices of the rows ## of the non-vanishing minor on the i-th patch. -## column_list::Vector{Vector{Int}} the indices of the -## columns of the non-vanishing minor on the +## column_list::Vector{Vector{Int}} the indices of the +## columns of the non-vanishing minor on the ## i-th patch. #function _non_degeneration_cover( -# C::SpecType, +# C::AffineSchemeType, # A::MatrixType, -# r::Int; +# r::Int; # rec_count::Int=0, # check::Bool=true, # verbose::Bool=false, # restricted_rows::Vector{Vector{Int}}=[Int[]], # restricted_columns::Vector{Vector{Int}}=[Int[]] -# ) where {SpecType<:Spec, MatrixType} #TODO: How specific can we be with the matrices? +# ) where {AffineSchemeType<:AffineScheme, MatrixType} #TODO: How specific can we be with the matrices? # indent_str = prod([ "#" for i in 1:rec_count ]) * " " # #verbose && println(indent_str * "call with $(X) and matrix $(A) for rank $r") # verbose && println(indent_str * "call to _non_degeneration_cover for rank $r") @@ -1337,22 +1337,22 @@ end # end # length(restricted_columns) == 0 && (restricted_columns = [collect(1:n)]) # R = base_ring(OO(C)) -# +# # verbose && println("checking for the scheme being empty...") # if isempty(C) # verbose && println("the scheme is empty; returning empty lists") # return (Vector{Vector{poly_type(C)}}(), Vector{Vector{poly_type(C)}}(), Vector{Vector{Int}}(), Vector{Vector{Int}}()) # end # -## if r == 1 +## if r == 1 ## verbose && println("reached the rank-1-case") ## Y = subscheme(C, ideal(R, [A[i,j] for i in 1:nrows(A) for j in 1:ncols(A)])) -## if check +## if check ## isempty(Y) || error("the prescribed rank can not be achieved on $Y") ## end ## ll = Vector{Vector{poly_type(C)}}() ## dl = Vector{Vector{poly_type(C)}}() -## rl = Vector{Vector{Int}}() +## rl = Vector{Vector{Int}}() ## cl = Vector{Vector{Int}}() ## for i in 1:nrows(A) ## for j in 1:ncols(A) @@ -1384,7 +1384,7 @@ end # verbose && print(".") # for j in 1:n # A[i,j] = w[j] -# if i in restricted_rows[1] && j in restricted_columns[1] +# if i in restricted_rows[1] && j in restricted_columns[1] # allzero = allzero && iszero(A[i,j]) # if total_degree(w[j]) <= d && !iszero(w[j]) # d = total_degree(w[j]) @@ -1432,7 +1432,7 @@ end # # loc_list = Vector{Vector{poly_type(C)}}() # div_list = Vector{Vector{poly_type(C)}}() -# row_list = Vector{Vector{Int}}() +# row_list = Vector{Vector{Int}}() # column_list = Vector{Vector{Int}}() # # if r>1 @@ -1442,9 +1442,9 @@ end # # # harvest from recursion on the open part # verbose && println("recursive call for the complement") -# llU, dlU, rlU, clU = _non_degeneration_cover(U, B_part, r-1, -# rec_count=rec_count+1, -# check=check, +# llU, dlU, rlU, clU = _non_degeneration_cover(U, B_part, r-1, +# rec_count=rec_count+1, +# check=check, # verbose=verbose, # restricted_rows=new_restricted_rows, # restricted_columns=new_restricted_columns @@ -1481,14 +1481,14 @@ end # # # harvest from recursion on the closed part # verbose && println("recursive call for the subscheme") -# llY, dlY, rlY, clY = _non_degeneration_cover(Y, copy(A), r, -# rec_count=rec_count+1, -# check=check, +# llY, dlY, rlY, clY = _non_degeneration_cover(Y, copy(A), r, +# rec_count=rec_count+1, +# check=check, # verbose=verbose, # restricted_rows=restricted_rows, # restricted_columns=restricted_columns # ) -# +# # # process the output according to the preparations for the recursion # loc_list = vcat(loc_list, llY) # div_list = vcat(div_list, [push!(Ud, f) for Ud in dlY]) @@ -1499,14 +1499,14 @@ end # # return loc_list, div_list, row_list, column_list #end -# +# #function _as_smooth_lci_rec( -# X::SpecType, -# Z::SpecType, # the uncovered locus +# X::AffineSchemeType, +# Z::AffineSchemeType, # the uncovered locus # h::Vector{PolyType}, # equations that were localized already # good::Tuple{Vector{Int}, Vector{Int}}, # partial derivatives that form the beginning of the solution sequence # bad::Vector{Tuple{Int, Int}}, # partial derivatives that vanish on the uncovered locus. -# f::Vector{PolyType}, +# f::Vector{PolyType}, # Df::MatrixType, # B::MatrixType, # d::Int, n::Int; @@ -1514,7 +1514,7 @@ end # verbose::Bool=false, # rec_depth::Int=0 # ) where{ -# SpecType<:Spec, +# AffineSchemeType<:AffineScheme, # PolyType<:MPolyRingElem, # MatrixType # } @@ -1522,10 +1522,10 @@ end # #verbose && println(recstring * "call with $X, $Z") # verbose && println(recstring * "selected minors: $(good[1]) x $(good[2])") # verbose && println(recstring * "bad positions: $bad") -# # return format: +# # return format: # # key: affine patch -# # value: (equations that were localized from root, -# # regular sequence, +# # value: (equations that were localized from root, +# # regular sequence, # # index of variables for non-vanishing minor) # res_dict = Dict{typeof(X), Tuple{Vector{PolyType}, Vector{PolyType}, Vector{Int}}}() # @@ -1587,7 +1587,7 @@ end # error("scheme is not smooth") # end # verbose && println(recstring*"selected the $((k, l))-th entry: $(Df[k,l])") -# +# # good_ext = (vcat(good[1], k), vcat(good[2], l)) # p = Df[k,l] # Bnew = copy(B) @@ -1645,8 +1645,8 @@ end # Y = codomain(f) # CX = domain_covering(f) # CY = codomain_covering(f) -# SpecType = affine_patch_type(X) -# trans_dict = Dict{SpecType, Vector{poly_type(SpecType)}}() +# AffineSchemeType = affine_patch_type(X) +# trans_dict = Dict{AffineSchemeType, Vector{poly_type(AffineSchemeType)}}() # for U in patches(CX) # trans_dict[U] = weak_transform(f[U], E[U], I[codomain(f[U])]) # end @@ -1658,8 +1658,8 @@ end # Y = codomain(f) # CX = domain_covering(f) # CY = codomain_covering(f) -# SpecType = affine_patch_type(X) -# trans_dict = Dict{SpecType, Vector{poly_type(SpecType)}}() +# AffineSchemeType = affine_patch_type(X) +# trans_dict = Dict{AffineSchemeType, Vector{poly_type(AffineSchemeType)}}() # for U in patches(CX) # trans_dict[U] = controlled_transform(f[U], E[U], I[codomain(f[U])],i) # end @@ -1720,7 +1720,7 @@ end # Mnew[i-1,j] = maximum([(M[i,j] >= 0 ? M[i,j] + M[k,l] : -1), (M[i,l]>=0 ? M[k,j] + M[i,l] : -1)]) # end # for j in l+1:n -# Mnew[i-1,j-1] = maximum([(M[i,j] >= 0 ? M[i,j] + M[k,l] : -1), +# Mnew[i-1,j-1] = maximum([(M[i,j] >= 0 ? M[i,j] + M[k,l] : -1), # (M[i,l]>=0 ? M[k,j] + M[i,l] : -1)]) # end # end @@ -1763,7 +1763,7 @@ function fiber_product( j1 = Oscar.CoveredClosedEmbedding(domain(i2), pb_I1) Z = domain(j1) - morphism_dict = IdDict{AbsSpec, ClosedEmbedding}() + morphism_dict = IdDict{AbsAffineScheme, ClosedEmbedding}() for U in affine_charts(Z) V2 = codomain(j1[U]) W = codomain(i2[V2]) diff --git a/experimental/Schemes/CoveredScheme.jl b/experimental/Schemes/CoveredScheme.jl index 45bcdb1440a1..a7206761d2b5 100644 --- a/experimental/Schemes/CoveredScheme.jl +++ b/experimental/Schemes/CoveredScheme.jl @@ -7,7 +7,7 @@ export morphism_type ### essential getters #function add_affine_refinement!( -# C::Covering, U::SpecOpen; +# C::Covering, U::AffineSchemeOpenSubscheme; # a::Vector{RingElemType}=as_vector(coordinates(one(OO(ambient_scheme(U))), # ideal(OO(ambient_scheme(U)), # OO(ambient_scheme(U)).(gens(U)))), @@ -30,7 +30,7 @@ export morphism_type # functions for handling sets in coverings -function intersect_in_covering(U::AbsSpec, V::AbsSpec, C::Covering) +function intersect_in_covering(U::AbsAffineScheme, V::AbsAffineScheme, C::Covering) U in C || error("first patch not found in covering") V in C || error("second patch not found in covering") (i, j, k) = indexin(U, C) @@ -71,9 +71,9 @@ function intersect_in_covering(U::AbsSpec, V::AbsSpec, C::Covering) end #affine_patch_type(C::Covering) = affine_patch_type(typeof(C)) -#gluing_type(C::Covering{SpecType, GluingType, SpecOpenType}) where {SpecType<:Spec, GluingType<:Gluing, SpecOpenType<:SpecOpen} = GluingType -#affine_patch_type(::Type{Covering{SpecType, GluingType, SpecOpenType, RingElemType}}) where {SpecType<:Spec, GluingType<:Gluing, SpecOpenType<:SpecOpen, RingElemType<:RingElem} = SpecType -#gluing_type(::Type{Covering{SpecType, GluingType, SpecOpenType}}) where {SpecType<:Spec, GluingType<:Gluing, SpecOpenType<:SpecOpen} = GluingType +#gluing_type(C::Covering{AffineSchemeType, GluingType, AffineSchemeOpenSubschemeType}) where {AffineSchemeType<:AffineScheme, GluingType<:Gluing, AffineSchemeOpenSubschemeType<:AffineSchemeOpenSubscheme} = GluingType +#affine_patch_type(::Type{Covering{AffineSchemeType, GluingType, AffineSchemeOpenSubschemeType, RingElemType}}) where {AffineSchemeType<:AffineScheme, GluingType<:Gluing, AffineSchemeOpenSubschemeType<:AffineSchemeOpenSubscheme, RingElemType<:RingElem} = AffineSchemeType +#gluing_type(::Type{Covering{AffineSchemeType, GluingType, AffineSchemeOpenSubschemeType}}) where {AffineSchemeType<:AffineScheme, GluingType<:Gluing, AffineSchemeOpenSubschemeType<:AffineSchemeOpenSubscheme} = GluingType #open_subset_type(::Type{Covering{R, S, T}}) where {R, S, T} = T #open_subset_type(C::Covering) = open_subset_type(typeof(C)) @@ -99,17 +99,17 @@ affine_refinements(C::Covering) = C.affine_refinements ######################################################################## @doc raw""" - _generate_affine_charts(X::Scheme) -> Dict{Int, AbsSpec} + _generate_affine_charts(X::Scheme) -> Dict{Int, AbsAffineScheme} Helper to generate the affine charts of projective space for `standard_covering`. -This should be overwritten if you want your charts to be of a type different from `Spec`, +This should be overwritten if you want your charts to be of a type different from `AffineScheme`, for instance `AffinePlaneCurve`. """ _generate_affine_charts(X::Scheme) # The case of a non-trivial homogeneous modulus function _generate_affine_charts(X::AbsProjectiveScheme{<:Ring, <:MPolyQuoRing}) - chart_dict = Dict{Int, Spec}() + chart_dict = Dict{Int, AffineScheme}() kk = base_ring(X) S = ambient_coordinate_ring(X) r = relative_ambient_dimension(X) @@ -119,7 +119,7 @@ function _generate_affine_charts(X::AbsProjectiveScheme{<:Ring, <:MPolyQuoRing}) phi = hom(S, R, vcat(gens(R)[1:i], [one(R)], gens(R)[i+1:r]), check=false) I = ideal(R, phi.(gens(defining_ideal(X)))) if !isone(I) # return the non-empty charts only - chart_dict[i+1] = Spec(quo(R, I)[1]) + chart_dict[i+1] = spec(quo(R, I)[1]) end end return chart_dict @@ -127,14 +127,14 @@ end # The case of a trivial homogeneous modulus function _generate_affine_charts(X::AbsProjectiveScheme{<:Ring, <:MPolyDecRing}) - chart_dict = Dict{Int, Spec}() + chart_dict = Dict{Int, AffineScheme}() kk = base_ring(X) S = ambient_coordinate_ring(X) r = relative_ambient_dimension(X) s = symbols(S) for i in 0:r R, x = polynomial_ring(kk, [Symbol("("*String(s[k+1])*"//"*String(s[i+1])*")") for k in 0:r if k != i]) - chart_dict[i+1] = Spec(R) + chart_dict[i+1] = spec(R) end return chart_dict end @@ -149,18 +149,18 @@ end # The two cases for non-trivial base rings function _generate_affine_charts(X::AbsProjectiveScheme{<:CRT, <:MPolyQuoRing}) where {CRT<:Union{<:MPolyQuoLocRing, <:MPolyLocRing, <:MPolyRing, <:MPolyQuoRing}} - chart_dict = Dict{Int, AbsSpec}() + chart_dict = Dict{Int, AbsAffineScheme}() Y = base_scheme(X) R = ambient_coordinate_ring(Y) kk = coefficient_ring(R) S = ambient_coordinate_ring(X) s = symbols(S) - pU = IdDict{AbsSpec, AbsSpecMor}() + pU = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() r = relative_ambient_dimension(X) for i in 0:r R_fiber, x = polynomial_ring(kk, [Symbol("("*String(s[k+1])*"//"*String(s[i+1])*")") for k in 0:r if k != i]) - F = Spec(R_fiber) + F = spec(R_fiber) ambient_space, pF, pY = product(F, Y) fiber_vars = pullback(pF).(gens(R_fiber)) mapped_polys = [map_coefficients(pullback(pY), f) for f in gens(defining_ideal(X))] @@ -174,18 +174,18 @@ end function _generate_affine_charts(X::AbsProjectiveScheme{<:CRT, <:MPolyDecRing}) where {CRT<:Union{<:MPolyQuoLocRing, <:MPolyLocRing, <:MPolyRing, <:MPolyQuoRing}} - chart_dict = Dict{Int, AbsSpec}() + chart_dict = Dict{Int, AbsAffineScheme}() Y = base_scheme(X) R = ambient_coordinate_ring(Y) kk = coefficient_ring(R) S = ambient_coordinate_ring(X) s = symbols(S) - pU = IdDict{AbsSpec, AbsSpecMor}() + pU = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() r = relative_ambient_dimension(X) for i in 0:r R_fiber, x = polynomial_ring(kk, [Symbol("("*String(s[k+1])*"//"*String(s[i+1])*")") for k in 0:r if k != i]) - F = Spec(R_fiber) + F = spec(R_fiber) ambient_space, pF, pY = product(F, Y) fiber_vars = pullback(pF).(gens(R_fiber)) chart_dict[i+1] = ambient_space @@ -205,7 +205,7 @@ end chart_dict = _generate_affine_charts(X) iszero(length(chart_dict)) && return empty_covering(base_ring(X)) @assert all(k->!isempty(chart_dict[k]), keys(chart_dict)) "empty chart created" - decomp_info = IdDict{AbsSpec, Vector{RingElem}}() + decomp_info = IdDict{AbsAffineScheme, Vector{RingElem}}() for (i, U) in chart_dict decomp_info[U] = gens(OO(U))[1:i-1] _dehomogenization_cache(X)[U] = _dehomogenization_map(X, U, i) @@ -245,14 +245,14 @@ end kk = coefficient_ring(R) S = ambient_coordinate_ring(X) r = relative_ambient_dimension(X) - U = Vector{AbsSpec}() + U = Vector{AbsAffineScheme}() # The case of ℙ⁰-bundles appears frequently in blowups when the # ideal sheaf is trivial on some affine open part. if r == 0 result = Covering(Y) set_decomposition_info!(result, Y, elem_type(OO(Y))[]) - pU = IdDict{AbsSpec, AbsSpecMor}() + pU = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() pU[Y] = identity_map(Y) covered_projection = CoveringMorphism(result, result, pU, check=false) set_attribute!(X, :covering_projection_to_base, covered_projection) @@ -267,7 +267,7 @@ end chart_dict, projection_dict = _generate_affine_charts(X) isempty(chart_dict) && return empty_covering(base_ring(Y)) - decomp_info = IdDict{AbsSpec, Vector{RingElem}}() + decomp_info = IdDict{AbsAffineScheme, Vector{RingElem}}() for (i, U) in chart_dict decomp_info[U] = gens(OO(U))[1:i-1] _dehomogenization_cache(X)[U] = _dehomogenization_map(X, U, i) @@ -314,8 +314,8 @@ end #affine_patch_type(C::CoveringMorphism{R, S, T}) where {R, S, T} = R #affine_patch_type(::Type{CoveringMorphism{R, S, T}}) where {R, S, T} = R -#morphism_type(C::Covering{SpecType, GluingType, SpecOpenType}) where {SpecType<:Spec, GluingType<:Gluing, SpecOpenType<:SpecOpen} = CoveringMorphism{SpecType, Covering{SpecType, GluingType, SpecOpenType}, morphism_type(SpecType, SpecType)} -#morphism_type(::Type{Covering{SpecType, GluingType, SpecOpenType}}) where {SpecType<:Spec, GluingType<:Gluing, SpecOpenType<:SpecOpen} = CoveringMorphism{SpecType, Covering{SpecType, GluingType, SpecOpenType}, morphism_type(SpecType, SpecType)} +#morphism_type(C::Covering{AffineSchemeType, GluingType, AffineSchemeOpenSubschemeType}) where {AffineSchemeType<:AffineScheme, GluingType<:Gluing, AffineSchemeOpenSubschemeType<:AffineSchemeOpenSubscheme} = CoveringMorphism{AffineSchemeType, Covering{AffineSchemeType, GluingType, AffineSchemeOpenSubschemeType}, morphism_type(AffineSchemeType, AffineSchemeType)} +#morphism_type(::Type{Covering{AffineSchemeType, GluingType, AffineSchemeOpenSubschemeType}}) where {AffineSchemeType<:AffineScheme, GluingType<:Gluing, AffineSchemeOpenSubschemeType<:AffineSchemeOpenSubscheme} = CoveringMorphism{AffineSchemeType, Covering{AffineSchemeType, GluingType, AffineSchemeOpenSubschemeType}, morphism_type(AffineSchemeType, AffineSchemeType)} refinements(X::AbsCoveredScheme) = refinements(underlying_scheme(X))::Dict{<:Tuple{<:Covering, <:Covering}, <:CoveringMorphism} @@ -332,8 +332,8 @@ refinements(X::AbsCoveredScheme) = refinements(underlying_scheme(X))::Dict{<:Tup #affine_patch_type(::Type{CoveredSchemeType}) where {CoveredSchemeType<:CoveredScheme} = affine_patch_type(covering_type(CoveredSchemeType)) ### type constructors -#covered_scheme_type(::Type{T}) where {T<:Spec} = CoveredScheme{covering_type(T), morphism_type(covering_type(T))} -#covered_scheme_type(X::Spec) = covered_scheme_type(typeof(X)) +#covered_scheme_type(::Type{T}) where {T<:AffineScheme} = CoveredScheme{covering_type(T), morphism_type(covering_type(T))} +#covered_scheme_type(X::AffineScheme) = covered_scheme_type(typeof(X)) # #covered_scheme_type(::Type{T}) where {T<:ProjectiveScheme} = covered_scheme_type(affine_patch_type(P)) #covered_scheme_type(P::AbsProjectiveScheme) = covered_scheme_type(typeof(P)) @@ -532,9 +532,9 @@ image_ideal(phi::CoveredClosedEmbedding) = phi.I function CoveredClosedEmbedding(X::AbsCoveredScheme, I::IdealSheaf; covering::Covering=default_covering(X), check::Bool=true) space(I) === X || error("ideal sheaf is not defined on the correct scheme") - mor_dict = IdDict{AbsSpec, ClosedEmbedding}() # Stores the morphism fᵢ : Uᵢ → Vᵢ for some covering Uᵢ ⊂ Z(I) ⊂ X. - rev_dict = IdDict{AbsSpec, AbsSpec}() # Stores an inverse list to also go back from Vᵢ to Uᵢ for those Vᵢ which are actually hit. - patch_list = Vector{AbsSpec}() + mor_dict = IdDict{AbsAffineScheme, ClosedEmbedding}() # Stores the morphism fᵢ : Uᵢ → Vᵢ for some covering Uᵢ ⊂ Z(I) ⊂ X. + rev_dict = IdDict{AbsAffineScheme, AbsAffineScheme}() # Stores an inverse list to also go back from Vᵢ to Uᵢ for those Vᵢ which are actually hit. + patch_list = Vector{AbsAffineScheme}() for U in patches(covering) inc = ClosedEmbedding(U, I(U)) V = domain(inc) @@ -544,7 +544,7 @@ function CoveredClosedEmbedding(X::AbsCoveredScheme, I::IdealSheaf; rev_dict[U] = V end end - gluing_dict = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() + gluing_dict = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() for Unew in keys(mor_dict) U = codomain(mor_dict[Unew]) for Vnew in keys(mor_dict) diff --git a/experimental/Schemes/FunctionFields.jl b/experimental/Schemes/FunctionFields.jl index 4010e36d1171..4ea6823d2090 100644 --- a/experimental/Schemes/FunctionFields.jl +++ b/experimental/Schemes/FunctionFields.jl @@ -9,7 +9,7 @@ export variety # Check for emptyness # ######################################################################## -@attr Bool function Base.isempty(U::SpecOpen) +@attr Bool function Base.isempty(U::AffineSchemeOpenSubscheme) return all(isempty, affine_patches(U)) end @@ -41,7 +41,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P, I); +julia> Y = proj(P, I); julia> Ycov = covered_scheme(Y) Scheme @@ -249,7 +249,7 @@ end @doc raw""" function move_representative( a::MPolyRingElem, b::MPolyRingElem, - V::AbsSpec, U::AbsSpec, + V::AbsAffineScheme, U::AbsAffineScheme, C::Covering ) @@ -261,7 +261,7 @@ one in ``Quot(P')`` where ``P'`` is the ambient coordinate ring of another patch """ function move_representative( a::MPolyRingElem, b::MPolyRingElem, - V::AbsSpec, U::AbsSpec, + V::AbsAffineScheme, U::AbsAffineScheme, C::Covering ) G = C[U, V] @@ -270,7 +270,7 @@ function move_representative( pba = pullback(f)(OO(B)(a)) pbb = pullback(f)(OO(B)(b)) iszero(pbb) && error("pullback of denominator is zero") - # in the next line, A is either a SpecOpen or a PrincipalOpenSubset + # in the next line, A is either a AffineSchemeOpenSubscheme or a PrincipalOpenSubset h_generic = generic_fraction(pba, A)//generic_fraction(pbb, A) if domain(f) isa PrincipalOpenSubset fac = factor(lifted_numerator(complement_equation(domain(f)))) @@ -313,7 +313,7 @@ function (K::AbstractAlgebra.Generic.FracField)(f::VarietyFunctionFieldElem) return K(numerator(f_mov), denominator(f_mov)) end -function getindex(f::VarietyFunctionFieldElem, V::AbsSpec) +function getindex(f::VarietyFunctionFieldElem, V::AbsAffineScheme) C = default_covering(variety(parent(f))) if any(x->x===V, patches(C)) return move_representative(numerator(f), denominator(f), @@ -478,7 +478,7 @@ function is_regular(f::VarietyFunctionFieldElem, U::Scheme) error("method not implemented") end -function is_regular(f::VarietyFunctionFieldElem, U::AbsSpec) +function is_regular(f::VarietyFunctionFieldElem, U::AbsAffineScheme) p = numerator(f[U]) q = denominator(f[U]) return _is_regular_fraction(OO(U), p, q) @@ -492,7 +492,7 @@ function is_regular(f::VarietyFunctionFieldElem, U::PrincipalOpenSubset) return _is_regular_fraction(OO(U), p, q) end -function is_regular(f::VarietyFunctionFieldElem, W::SpecOpen) +function is_regular(f::VarietyFunctionFieldElem, W::AffineSchemeOpenSubscheme) return all(U->is_regular(f, U), affine_patches(W)) end diff --git a/experimental/Schemes/IdealSheaves.jl b/experimental/Schemes/IdealSheaves.jl index c0cf01c7c4be..5ee58f39a094 100644 --- a/experimental/Schemes/IdealSheaves.jl +++ b/experimental/Schemes/IdealSheaves.jl @@ -14,13 +14,13 @@ scheme(I::IdealSheaf) = space(I) @doc raw""" IdealSheaf(X::AbsProjectiveScheme, g::Vector{<:RingElem}) -Create the ideal sheaf on the covered scheme of ``X`` which is -generated by the dehomogenization of the homogeneous elements in `g` +Create the ideal sheaf on the covered scheme of ``X`` which is +generated by the dehomogenization of the homogeneous elements in `g` in every chart. -**Note:** When taking the pullback of an `IdealSheaf` ``ℐ`` along a morphism -``f : X → Y``, what is actually computed, is ``f⁻¹ ℐ ⋅ 𝒪_{X}``. -To obtain the pullback of ``ℐ`` as a sheaf of modules (i.e. ``f* ℐ``), +**Note:** When taking the pullback of an `IdealSheaf` ``ℐ`` along a morphism +``f : X → Y``, what is actually computed, is ``f⁻¹ ℐ ⋅ 𝒪_{X}``. +To obtain the pullback of ``ℐ`` as a sheaf of modules (i.e. ``f* ℐ``), convert ``ℐ`` into a `CoherentSheaf` on ``Y``, first. # Examples @@ -29,7 +29,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P) +julia> Y = proj(P) Projective space of dimension 2 over rational field with homogeneous coordinates [x, y, z] @@ -46,28 +46,28 @@ with restrictions 3: Ideal ((x//z)^3 - (y//z)^2) ``` """ -function IdealSheaf(X::AbsProjectiveScheme, I::MPolyIdeal) +function IdealSheaf(X::AbsProjectiveScheme, I::MPolyIdeal) S = base_ring(I) S === homogeneous_coordinate_ring(X) || error("ideal does not live in the graded coordinate ring of the scheme") g = gens(I) X_covered = covered_scheme(X) C = default_covering(X_covered) r = relative_ambient_dimension(X) - I = IdDict{AbsSpec, Ideal}() + I = IdDict{AbsAffineScheme, Ideal}() for U in patches(C) I[U] = ideal(OO(U), dehomogenization_map(X, U).(g)) end return IdealSheaf(X_covered, I, check=true) end -function IdealSheaf(X::AbsProjectiveScheme, I::MPolyQuoIdeal) +function IdealSheaf(X::AbsProjectiveScheme, I::MPolyQuoIdeal) S = base_ring(I) S === homogeneous_coordinate_ring(X) || error("ideal does not live in the graded coordinate ring of the scheme") g = gens(I) X_covered = covered_scheme(X) C = default_covering(X_covered) r = relative_ambient_dimension(X) - I = IdDict{AbsSpec, Ideal}() + I = IdDict{AbsAffineScheme, Ideal}() for U in patches(C) I[U] = ideal(OO(U), dehomogenization_map(X, U).(g)) end @@ -78,14 +78,14 @@ ideal_sheaf(X::AbsProjectiveScheme, I::MPolyIdeal) = IdealSheaf(X, I) ideal_sheaf(X::AbsProjectiveScheme, I::MPolyQuoIdeal) = IdealSheaf(X, I) function IdealSheaf( - X::AbsProjectiveScheme, + X::AbsProjectiveScheme, g::MPolyDecRingElem ) return IdealSheaf(X, [g]) end function IdealSheaf( - X::AbsProjectiveScheme, + X::AbsProjectiveScheme, g::MPolyQuoRingElem ) return IdealSheaf(X, [g]) @@ -95,12 +95,12 @@ ideal_sheaf(X::AbsProjectiveScheme, g::MPolyDecRingElem) = IdealSheaf(X, g) ideal_sheaf(X::AbsProjectiveScheme, g::MPolyQuoRingElem) = IdealSheaf(X, g) function IdealSheaf( - X::AbsProjectiveScheme, + X::AbsProjectiveScheme, g::Vector{RingElemType} ) where {RingElemType<:MPolyDecRingElem} X_covered = covered_scheme(X) r = relative_ambient_dimension(X) - I = IdDict{AbsSpec, Ideal}() + I = IdDict{AbsAffineScheme, Ideal}() for U in patches(default_covering(X_covered)) I[U] = ideal(OO(U), dehomogenization_map(X, U).(g)) end @@ -108,12 +108,12 @@ function IdealSheaf( end function IdealSheaf( - X::AbsProjectiveScheme, + X::AbsProjectiveScheme, g::Vector{RingElemType} ) where {RingElemType<:MPolyQuoRingElem} X_covered = covered_scheme(X) r = relative_ambient_dimension(X) - I = IdDict{AbsSpec, Ideal}() + I = IdDict{AbsAffineScheme, Ideal}() for U in patches(default_covering(X_covered)) I[U] = ideal(OO(U), dehomogenization_map(X, U).(g)) end @@ -126,9 +126,9 @@ ideal_sheaf(X::AbsProjectiveScheme, g::Vector{RingElemType}) where {RingElemType # this constructs the zero ideal sheaf -function IdealSheaf(X::AbsCoveredScheme) +function IdealSheaf(X::AbsCoveredScheme) C = default_covering(X) - I = IdDict{AbsSpec, Ideal}() + I = IdDict{AbsAffineScheme, Ideal}() for U in basic_patches(C) I[U] = ideal(OO(U), elem_type(OO(U))[]) end @@ -142,20 +142,20 @@ See the documentation for `IdealSheaf`. """ ideal_sheaf(X::AbsCoveredScheme) = IdealSheaf(X) -# set up an ideal sheaf by automatic extension +# set up an ideal sheaf by automatic extension # from one prescribed set of generators on one affine patch @doc raw""" - IdealSheaf(X::AbsCoveredScheme, U::AbsSpec, g::Vector) + IdealSheaf(X::AbsCoveredScheme, U::AbsAffineScheme, g::Vector) -Set up an ideal sheaf on ``X`` by specifying a set of generators ``g`` -on one affine open subset ``U`` among the `basic_patches` of the -`default_covering` of ``X``. +Set up an ideal sheaf on ``X`` by specifying a set of generators ``g`` +on one affine open subset ``U`` among the `basic_patches` of the +`default_covering` of ``X``. -**Note:** The set ``U`` has to be dense in its connected component -of ``X`` since otherwise, the extension of the ideal sheaf to other -charts can not be inferred. +**Note:** The set ``U`` has to be dense in its connected component +of ``X`` since otherwise, the extension of the ideal sheaf to other +charts can not be inferred. """ -function IdealSheaf(X::AbsCoveredScheme, U::AbsSpec, g::Vector{RET}) where {RET<:RingElem} +function IdealSheaf(X::AbsCoveredScheme, U::AbsAffineScheme, g::Vector{RET}) where {RET<:RingElem} C = default_covering(X) for f in g parent(f) === OO(U) || error("the generators do not belong to the correct ring") @@ -167,31 +167,31 @@ function IdealSheaf(X::AbsCoveredScheme, U::AbsSpec, g::Vector{RET}) where {RET< J = saturated_ideal(pullback(inverse(inc_U_flat))(ideal(OO(U), g))) return IdealSheaf(X, V, OO(V).(gens(J))) end - D = IdDict{AbsSpec, Ideal}() + D = IdDict{AbsAffineScheme, Ideal}() D[U] = ideal(OO(U), g) D = extend!(C, D) I = IdealSheaf(X, D, check=false) return I end -ideal_sheaf(X::AbsCoveredScheme, U::AbsSpec, g::Vector{RET}) where {RET<:RingElem} = IdealSheaf(X, U, g) +ideal_sheaf(X::AbsCoveredScheme, U::AbsAffineScheme, g::Vector{RET}) where {RET<:RingElem} = IdealSheaf(X, U, g) @doc raw""" - IdealSheaf(Y::AbsCoveredScheme, + IdealSheaf(Y::AbsCoveredScheme, phi::CoveringMorphism{<:Any, <:Any, <:ClosedEmbedding} ) -Internal method to create an ideal sheaf from a `CoveringMorphism` -of `ClosedEmbedding`s; return the ideal sheaf describing the images +Internal method to create an ideal sheaf from a `CoveringMorphism` +of `ClosedEmbedding`s; return the ideal sheaf describing the images of the local morphisms. """ -function IdealSheaf(Y::AbsCoveredScheme, +function IdealSheaf(Y::AbsCoveredScheme, phi::CoveringMorphism{<:Any, <:Any, <:ClosedEmbedding}; check::Bool=true ) maps = morphisms(phi) V = [codomain(ff) for ff in values(maps)] - dict = IdDict{AbsSpec, Ideal}() + dict = IdDict{AbsAffineScheme, Ideal}() V = unique!(V) for W in V i = findall(x->(codomain(x) == W), maps) @@ -208,16 +208,16 @@ function IdealSheaf(Y::AbsCoveredScheme, return IdealSheaf(Y, dict, check=check) end - + # pullback of an ideal sheaf for internal use between coverings of the same scheme #function (F::CoveringMorphism)(I::IdealSheaf) # X = scheme(I) # D = codomain(F) # D == covering(I) || error("ideal sheaf is not defined on the correct covering") # C = domain(F) -# new_dict = Dict{AbsSpec, Ideal}() +# new_dict = Dict{AbsAffineScheme, Ideal}() # -# # go through the patches of C and pull back the generators +# # go through the patches of C and pull back the generators # # whenever they are defined on the target patch # for U in patches(C) # f = F[U] @@ -234,7 +234,7 @@ end # h = pullback(f).(gens(W)) # # take care to discard possibly empty preimages of patches # j = [i for i in 1:length(h) if !iszero(h)] -# Wpre = SpecOpen(U, h[j]) +# Wpre = AffineSchemeOpenSubscheme(U, h[j]) # add_affine_refinement!(C, Wpre) # for i in 1:length(j) # if haskey(ideal_dict(I), Wpre[i]) @@ -247,10 +247,10 @@ end # return IdealSheaf(X, C, new_dict) #end -function +(I::IdealSheaf, J::IdealSheaf) +function +(I::IdealSheaf, J::IdealSheaf) X = space(I) X == space(J) || error("ideal sheaves are not defined over the same scheme") - new_dict = IdDict{AbsSpec, Ideal}() + new_dict = IdDict{AbsAffineScheme, Ideal}() CI = default_covering(X) for U in patches(CI) new_dict[U] = I(U) + J(U) @@ -258,10 +258,10 @@ function +(I::IdealSheaf, J::IdealSheaf) return IdealSheaf(X, new_dict, check=false) end -function *(I::IdealSheaf, J::IdealSheaf) +function *(I::IdealSheaf, J::IdealSheaf) X = space(I) X == space(J) || error("ideal sheaves are not defined over the same scheme") - new_dict = IdDict{AbsSpec, Ideal}() + new_dict = IdDict{AbsAffineScheme, Ideal}() CI = default_covering(X) for U in patches(CI) new_dict[U] = I(U) * J(U) @@ -272,20 +272,20 @@ end @doc raw""" simplify!(I::IdealSheaf) -Replaces the set of generators of the ideal sheaf by a minimal -set of random linear combinations in every affine patch. +Replaces the set of generators of the ideal sheaf by a minimal +set of random linear combinations in every affine patch. """ function simplify!(I::IdealSheaf) - new_ideal_dict = IdDict{AbsSpec, Ideal}() + new_ideal_dict = IdDict{AbsAffineScheme, Ideal}() for U in basic_patches(default_covering(space(I))) new_ideal_dict[U] = ideal(OO(U), small_generating_set(I(U))) #= - n = ngens(I(U)) + n = ngens(I(U)) n == 0 && continue R = ambient_coordinate_ring(U) kk = coefficient_ring(R) new_gens = elem_type(OO(U))[] - K = ideal(OO(U), new_gens) + K = ideal(OO(U), new_gens) while !issubset(I(U), K) new_gen = dot([rand(kk, 1:100) for i in 1:n], gens(I(U))) while new_gen in K @@ -294,7 +294,7 @@ function simplify!(I::IdealSheaf) push!(new_gens, new_gen) K = ideal(OO(U), new_gens) end - Oscar.object_cache(underlying_presheaf(I))[U] = K + Oscar.object_cache(underlying_presheaf(I))[U] = K =# end I.I.obj_cache = new_ideal_dict # for some reason the line below led to compiler errors. @@ -303,17 +303,17 @@ function simplify!(I::IdealSheaf) end @doc """ - subscheme(I::IdealSheaf) + subscheme(I::IdealSheaf) For an ideal sheaf ``ℐ`` on an `AbsCoveredScheme` ``X`` return the subscheme ``Y ⊂ X`` given by the zero locus of ``ℐ``. """ -function subscheme(I::IdealSheaf) +function subscheme(I::IdealSheaf) X = space(I) C = default_covering(X) new_patches = [subscheme(U, I(U)) for U in basic_patches(C)] - new_gluings = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() - decomp_dict = IdDict{AbsSpec, Vector{RingElem}}() + new_gluings = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() + decomp_dict = IdDict{AbsAffineScheme, Vector{RingElem}}() for (U, V) in keys(gluings(C)) i = C[U] j = C[V] @@ -321,7 +321,7 @@ function subscheme(I::IdealSheaf) Vnew = new_patches[j] G = C[U, V] #new_gluings[(Unew, Vnew)] = restrict(C[U, V], Unew, Vnew, check=false) - new_gluings[(Unew, Vnew)] = LazyGluing(Unew, Vnew, _compute_restriction, + new_gluings[(Unew, Vnew)] = LazyGluing(Unew, Vnew, _compute_restriction, RestrictionDataClosedEmbedding(C[U, V], Unew, Vnew) ) #new_gluings[(Vnew, Unew)] = inverse(new_gluings[(Unew, Vnew)]) @@ -342,40 +342,40 @@ end @doc raw""" - extend!(C::Covering, D::Dict{SpecType, IdealType}) where {SpecType<:Spec, IdealType<:Ideal} + extend!(C::Covering, D::Dict{AffineSchemeType, IdealType}) where {AffineSchemeType<:AffineScheme, IdealType<:Ideal} -For ``C`` a covering and ``D`` a dictionary holding vectors of -polynomials on affine patches of ``C`` this function extends the -collection of polynomials over all patches in a compatible way; -meaning that on the overlaps the restrictions of either two sets +For ``C`` a covering and ``D`` a dictionary holding vectors of +polynomials on affine patches of ``C`` this function extends the +collection of polynomials over all patches in a compatible way; +meaning that on the overlaps the restrictions of either two sets of polynomials coincides. -This proceeds by crawling through the gluing graph and taking -closures in the patches ``Uⱼ`` of the subschemes -``Zᵢⱼ = V(I) ∩ Uᵢ ∩ Uⱼ`` in the intersection with a patch ``Uᵢ`` +This proceeds by crawling through the gluing graph and taking +closures in the patches ``Uⱼ`` of the subschemes +``Zᵢⱼ = V(I) ∩ Uᵢ ∩ Uⱼ`` in the intersection with a patch ``Uᵢ`` on which ``I`` had already been described. -Note that the covering `C` is not modified. +Note that the covering `C` is not modified. """ function extend!( - C::Covering, D::IdDict{AbsSpec, Ideal}; + C::Covering, D::IdDict{AbsAffineScheme, Ideal}; all_dense::Bool=false ) all(x->any(y->x===y, patches(C)), keys(D)) || error("ideals must be given on the `patches` of the covering") # push all nodes on which I is known in a heap visited = collect(keys(D)) # The nodes which can be used for extension - fat = AbsSpec[U for U in visited if !isone(D[U])] + fat = AbsAffineScheme[U for U in visited if !isone(D[U])] # Nodes which are leafs - flat = AbsSpec[U for U in visited if isone(D[U])] + flat = AbsAffineScheme[U for U in visited if isone(D[U])] # Nodes to which we might need to extend - leftover = AbsSpec[U for U in patches(C) if !(U in keys(D))] + leftover = AbsAffineScheme[U for U in patches(C) if !(U in keys(D))] # Nodes to which we can extend in one step - neighbors = AbsSpec[U for U in leftover if any(V->haskey(gluings(C), (U, V)), fat)] + neighbors = AbsAffineScheme[U for U in leftover if any(V->haskey(gluings(C), (U, V)), fat)] # All other nodes - leftover = AbsSpec[U for U in leftover if !any(W->W===U, neighbors)] + leftover = AbsAffineScheme[U for U in leftover if !any(W->W===U, neighbors)] while length(neighbors) > 0 - good_pairs = Vector{Tuple{AbsSpec, AbsSpec}}() + good_pairs = Vector{Tuple{AbsAffineScheme, AbsAffineScheme}}() for V in neighbors for U in fat G = C[U, V] @@ -418,7 +418,7 @@ function extend!( #J_sat = saturation(J, ideal(OO(V), complement_equation(domain(f)))) J_sat = _iterative_saturation(J, lifted_numerator(complement_equation(domain(f)))) D[V] = J_sat - else + else Z = subscheme(U, D[U]) pZ = preimage(f, Z, check=false) ZV = closure(pZ, V, check=false) @@ -440,7 +440,7 @@ function extend!( leftover = [W for W in leftover if !any(x->x===W, neighbors)] end end - for U in basic_patches(C) + for U in basic_patches(C) if !haskey(D, U) D[U] = ideal(OO(U), one(OO(U))) end @@ -476,9 +476,9 @@ function is_subset(I::IdealSheaf, J::IdealSheaf) return true end -# prepares a refinement C' of the covering for the ideal sheaf I -# such that I can be generated by a regular sequence defining a smooth -# local complete intersection subscheme in every patch U of C' and +# prepares a refinement C' of the covering for the ideal sheaf I +# such that I can be generated by a regular sequence defining a smooth +# local complete intersection subscheme in every patch U of C' and # returns the ideal sheaf with those generators on C'. #function as_smooth_lci( # I::IdealSheaf; @@ -488,14 +488,14 @@ end # ) # X = scheme(I) # C = covering(I) -# SpecType = affine_patch_type(C) -# PolyType = poly_type(SpecType) -# new_gens_dict = Dict{SpecType, Vector{PolyType}}() +# AffineSchemeType = affine_patch_type(C) +# PolyType = poly_type(AffineSchemeType) +# new_gens_dict = Dict{AffineSchemeType, Vector{PolyType}}() # for U in patches(C) -# V, spec_dict = as_smooth_lci(U, I[U], -# verbose=verbose, -# check=check, -# codimension=codimension) +# V, spec_dict = as_smooth_lci(U, I[U], +# verbose=verbose, +# check=check, +# codimension=codimension) # add_affine_refinement!(C, V) # merge!(new_gens_dict, spec_dict) # end @@ -505,7 +505,7 @@ end #end # #function as_smooth_lci( -# U::Spec, g::Vector{T}; +# U::AffineScheme, g::Vector{T}; # verbose::Bool=false, # check::Bool=true, # codimension::Int=dim(U)-dim(subscheme(U, g)) # this assumes both U and its subscheme to be equidimensional @@ -518,23 +518,23 @@ end # r = length(f) # s = length(g) # Dh = jacobian_matrix(h) -# (ll, ql, rl, cl) = _non_degeneration_cover(subscheme(U, g), Dh, codimension + codim(U), -# verbose=verbose, check=check, +# (ll, ql, rl, cl) = _non_degeneration_cover(subscheme(U, g), Dh, codimension + codim(U), +# verbose=verbose, check=check, # restricted_columns=[collect(1:r), [r + k for k in 1:s]]) # # n = length(ll) # # first process the necessary refinements of U -# # The restricted columns in the call to _non_degenerate_cover -# # assure that the first codim(U) entries of every cl[i] are -# # indices of some element of f. However, we can discard these, +# # The restricted columns in the call to _non_degenerate_cover +# # assure that the first codim(U) entries of every cl[i] are +# # indices of some element of f. However, we can discard these, # # as they are trivial generators of the ideal sheaf on U. # minor_list = [det(Dh[rl[i], cl[i]]) for i in 1:n] # V = Vector{open_subset_type(U)}() -# SpecType = typeof(U) +# AffineSchemeType = typeof(U) # PolyType = poly_type(U) -# spec_dict = Dict{SpecType, Vector{PolyType}}() +# spec_dict = Dict{AffineSchemeType, Vector{PolyType}}() # g = Vector{PolyType}() -# W = SpecOpen(U, minor_list) +# W = AffineSchemeOpenSubscheme(U, minor_list) # for i in 1:n # spec_dict[W[i]] = h[cl[i][codim(U)+1:end]] # end @@ -630,7 +630,7 @@ end Return the order of the rational function `f` on the prime divisor given by the ideal sheaf `I`. """ function order_on_divisor( - f::VarietyFunctionFieldElem, + f::VarietyFunctionFieldElem, I::IdealSheaf; check::Bool=true ) @@ -638,15 +638,15 @@ function order_on_divisor( X = space(I)::AbsCoveredScheme X == variety(parent(f)) || error("schemes not compatible") - - #order_dict = Dict{AbsSpec, Int}() - # Since X is integral and I is a sheaf of prime ideals, + #order_dict = Dict{AbsAffineScheme, Int}() + + # Since X is integral and I is a sheaf of prime ideals, # it suffices to find one chart in which I is non-trivial. # We look for the chart with the least complexity V = first(affine_charts(X)) - #complexity = Vector{Tuple{AbsSpec, Int}}() + #complexity = Vector{Tuple{AbsAffineScheme, Int}}() complexity = inf for U in keys(Oscar.object_cache(underlying_presheaf(I))) # Those charts on which I is known. U in default_covering(X) || continue @@ -683,18 +683,18 @@ function order_on_divisor( # L, map = localization(OO(U), # MPolyComplementOfPrimeIdeal(saturated_ideal(I(U))) # ) -# L isa Union{MPolyLocRing{<:Any, <:Any, <:Any, <:Any, +# L isa Union{MPolyLocRing{<:Any, <:Any, <:Any, <:Any, # <:MPolyComplementOfPrimeIdeal}, -# MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, +# MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, # <:MPolyComplementOfPrimeIdeal} # } || error("localization was not successful") -# +# # floc = f[U] # a = numerator(floc) # b = denominator(floc) # # TODO: cache groebner bases in a reasonable way. # P = L(prime_ideal(inverted_set(L))) -# if one(L) in P +# if one(L) in P # continue # the multiplicity is -∞ in this case and does not count # end # upper = _minimal_power_such_that(P, x->!(L(a) in x))[1]-1 @@ -705,9 +705,9 @@ end @doc raw""" smooth_lci_covering(I::IdealSheaf) -For an ideal sheaf ``ℐ`` on a *smooth* scheme ``X`` with a *smooth* +For an ideal sheaf ``ℐ`` on a *smooth* scheme ``X`` with a *smooth* associated subscheme ``Y = V(ℐ)`` this produces a covering ``𝔘 = {Uₐ}, a ∈ A`` -such that ``ℐ(Uₐ) = ⟨f₁,…,fₖ⟩`` is generated by a regular sequence on every +such that ``ℐ(Uₐ) = ⟨f₁,…,fₖ⟩`` is generated by a regular sequence on every patch ``Uₐ`` of that covering. """ function smooth_lci_covering(I::IdealSheaf) @@ -719,7 +719,7 @@ function pushforward(inc::CoveredClosedEmbedding, I::IdealSheaf) scheme(I) === Y || error("ideal sheaf is not defined on the domain of the embedding") X = codomain(inc) phi = covering_morphism(inc) - ID = IdDict{AbsSpec, Ideal}() + ID = IdDict{AbsAffineScheme, Ideal}() for U in patches(domain(phi)) V = codomain(phi[U]) ID[V] = pushforward(phi[U], I(U)) @@ -731,7 +731,7 @@ function pushforward(inc::ClosedEmbedding, I::Ideal) Y = domain(inc) base_ring(I) === OO(Y) || error("ideal is not defined in the coordinate ring of the domain") X = codomain(inc) - return ideal(OO(X), vcat(gens(image_ideal(inc)), + return ideal(OO(X), vcat(gens(image_ideal(inc)), OO(X).(lifted_numerator.(gens(I)))) ) end @@ -759,7 +759,7 @@ function maximal_associated_points(I::IdealSheaf; covering=default_covering(sche charts_todo = copy(patches(covering)) ## todo-list of charts - associated_primes_temp = Vector{IdDict{AbsSpec, Ideal}}() ## already identified components + associated_primes_temp = Vector{IdDict{AbsAffineScheme, Ideal}}() ## already identified components ## may not yet contain all relevant charts. but ## at least one for each identified component @@ -777,7 +777,7 @@ function maximal_associated_points(I::IdealSheaf; covering=default_covering(sche !is_one(I(U)) || continue ## supp(I) might not meet all components components_here = minimal_primes(I(U)) if has_decomposition_info(covering) - # We only need those components which are located at the locus presrcibed by the + # We only need those components which are located at the locus presrcibed by the # decomposition_info in this chart components_here = [ C for C in components_here if all(g->g in C, decomposition_info(covering)[U])] result = vcat(result, [IdealSheaf(X, U, gens(C)) for C in components_here]) @@ -789,7 +789,7 @@ function maximal_associated_points(I::IdealSheaf; covering=default_covering(sche nmatches = length(matches) if nmatches == 0 ## not found - add_dict = IdDict{AbsSpec,Ideal}() ## create new dict + add_dict = IdDict{AbsAffineScheme,Ideal}() ## create new dict add_dict[U] = comp ## and fill it push!(associated_primes_temp, add_dict) elseif nmatches == 1 ## unique match, update it @@ -843,7 +843,7 @@ function associated_points(I::IdealSheaf) OOX = OO(X) charts_todo = copy(affine_charts(X)) ## todo-list of charts - associated_primes_temp = Vector{IdDict{AbsSpec, Ideal}}() ## already identified components + associated_primes_temp = Vector{IdDict{AbsAffineScheme, Ideal}}() ## already identified components ## may not yet contain all relevant charts. but ## at least one for each identified component @@ -859,7 +859,7 @@ function associated_points(I::IdealSheaf) nmatches = length(matches) if nmatches == 0 ## not found - add_dict = IdDict{AbsSpec,Ideal}() ## create new dict + add_dict = IdDict{AbsAffineScheme,Ideal}() ## create new dict add_dict[U] = comp ## and fill it push!(associated_primes_temp, add_dict) elseif nmatches == 1 ## unique match, update it @@ -890,9 +890,9 @@ end function match_on_intersections( X::AbsCoveredScheme, - U::AbsSpec, + U::AbsAffineScheme, I::Union{<:MPolyIdeal, <:MPolyQuoIdeal, <:MPolyQuoLocalizedIdeal, <:MPolyLocalizedIdeal}, - associated_list::Vector{<:IdDict{<:AbsSpec, <:Ideal}}, + associated_list::Vector{<:IdDict{<:AbsAffineScheme, <:Ideal}}, check::Bool=true) @vprint :MaximalAssociatedPoints 2 "matching $(I) \n to $(length(associated_list))\n on $(U)\n" matches = Int[] @@ -906,7 +906,7 @@ function match_on_intersections( for (V,IV) in associated_list[i] G = default_covering(X)[V,U] VU, UV = gluing_domains(G) - if UV isa SpecOpen && VU isa SpecOpen + if UV isa AffineSchemeOpenSubscheme && VU isa AffineSchemeOpenSubscheme I_res = [OOX(U, UV[i])(I) for i in 1:ngens(UV)] IV_res = [OOX(V, UV[i])(IV) for i in 1:ngens(UV)] if all(i->(I_res[i] == IV_res[i]), 1:ngens(UV)) @@ -916,7 +916,7 @@ function match_on_intersections( match_contradicted = true check || break end - elseif UV isa AbsSpec && VU isa AbsSpec + elseif UV isa AbsAffineScheme && VU isa AbsAffineScheme I_res = OOX(U,UV)(I) IV_res = OOX(V,UV)(IV) if (I_res == IV_res) @@ -992,7 +992,7 @@ end X = scheme(II) # If there is a simplified covering, do the calculations there. covering = (has_attribute(X, :simplified_covering) ? simplified_covering(X) : default_covering(X)) - ID = IdDict{AbsSpec, Ideal}() + ID = IdDict{AbsAffineScheme, Ideal}() for U in patches(covering) ID[U] = radical(II(U)) end @@ -1003,7 +1003,7 @@ function small_generating_set(II::IdealSheaf) X = scheme(II) # If there is a simplified covering, do the calculations there. covering = (has_attribute(X, :simplified_covering) ? simplified_covering(X) : default_covering(X)) - ID = IdDict{AbsSpec, Ideal}() + ID = IdDict{AbsAffineScheme, Ideal}() for U in patches(covering) ID[U] = ideal(base_ring(II(U)),small_generating_set(saturated_ideal(II(U)))) end @@ -1126,8 +1126,8 @@ function _separate_disjoint_components(comp::Vector{<:IdealSheaf}; covering::Cov X = scheme(first(comp)) all(x->scheme(x) === X, comp) || error("components must be defined over the same scheme") isone(length(comp)) && return covering - new_patches = Vector{AbsSpec}() - for U in patches(covering) + new_patches = Vector{AbsAffineScheme}() + for U in patches(covering) isempty(U) && continue loc_comp = [I(U) for I in comp] loc_comp = [a for a in loc_comp if !isone(a)] @@ -1169,7 +1169,7 @@ function _cofactors(comp::Vector{<:Ideal}) end function _one_patch_per_component(covering::Covering, comp::Vector{<:IdealSheaf}) - new_patches2 = Vector{AbsSpec}() + new_patches2 = Vector{AbsAffineScheme}() patches_todo = copy(patches(covering)) for P in comp # Find one patch in which this component is supported @@ -1181,14 +1181,14 @@ function _one_patch_per_component(covering::Covering, comp::Vector{<:IdealSheaf} push!(new_patches2, U) # For every other patch V in which P appears we do the following: # Replace V by the complement of the support of P. - # This will not be affine in general, but can be covered by hypersurface + # This will not be affine in general, but can be covered by hypersurface # complements. Even though this may lead to many charts, they will be harmless # in the mext blowup. done = Int[] for (j, V) in enumerate(patches_todo) # Check whether P is visible in this patch; if not leave it isone(P(V)) && continue - # Remember this patch to be done + # Remember this patch to be done push!(done, j) sg = small_generating_set(P(V)) new_patches2 = append!(new_patches2, [PrincipalOpenSubset(V,a) for a in sg]) @@ -1216,7 +1216,7 @@ end function saturation(I::IdealSheaf, J::IdealSheaf) X = scheme(I) - K = IdDict{AbsSpec, Ideal}() + K = IdDict{AbsAffineScheme, Ideal}() for U in affine_charts(X) K[U] = saturation(I(U), J(U)) end @@ -1227,7 +1227,7 @@ function pushforward(f::AbsCoveredSchemeMorphism, II::IdealSheaf) f_cov = covering_morphism(f) dom_cov = domain(f_cov) cod_cov = codomain(f_cov) - ideal_dict = IdDict{AbsSpec, Ideal}() + ideal_dict = IdDict{AbsAffineScheme, Ideal}() for V in cod_cov f_loc = maps_with_given_codomain(f_cov, V) I_loc = [preimage(pullback(f), II(domain(f))) for f in f_loc] @@ -1238,9 +1238,9 @@ end function Base.:^(II::IdealSheaf, k::IntegerUnion) k < 0 && error("negative powers of ideal sheaves are not allowed") - if iszero(k) + if iszero(k) X = scheme(II) - return IdealSheaf(X, IdDict{AbsSpec, Ideal}([U => ideal(OO(U), one(OO(U))) for U in affine_charts(X)]), check=false) + return IdealSheaf(X, IdDict{AbsAffineScheme, Ideal}([U => ideal(OO(U), one(OO(U))) for U in affine_charts(X)]), check=false) end isone(k) && return II b = div(k, 2) diff --git a/experimental/Schemes/LazyGluing.jl b/experimental/Schemes/LazyGluing.jl index 6bb5378a5faa..bb8f860b4710 100644 --- a/experimental/Schemes/LazyGluing.jl +++ b/experimental/Schemes/LazyGluing.jl @@ -1,29 +1,29 @@ @attributes mutable struct LazyGluing{ - LeftSpecType<:AbsSpec, - RightSpecType<:AbsSpec, + LeftAffineSchemeType<:AbsAffineScheme, + RightAffineSchemeType<:AbsAffineScheme, GluingDataType }<:AbsGluing{ - LeftSpecType, - RightSpecType, + LeftAffineSchemeType, + RightAffineSchemeType, Scheme, Scheme, Map, Map } - X::LeftSpecType - Y::RightSpecType + X::LeftAffineSchemeType + Y::RightAffineSchemeType GD::GluingDataType compute_function::Function compute_gluing_domains::Function gluing_domains::Union{Tuple{PrincipalOpenSubset, PrincipalOpenSubset}, - Tuple{SpecOpen, SpecOpen}} + Tuple{AffineSchemeOpenSubscheme, AffineSchemeOpenSubscheme}} G::AbsGluing - function LazyGluing(X::AbsSpec, Y::AbsSpec, + function LazyGluing(X::AbsAffineScheme, Y::AbsAffineScheme, compute_function::Function, GD::GluingDataType ) where {GluingDataType} return new{typeof(X), typeof(Y), GluingDataType}(X, Y, GD, compute_function) end - function LazyGluing(X::AbsSpec, Y::AbsSpec, + function LazyGluing(X::AbsAffineScheme, Y::AbsAffineScheme, compute_function::Function, compute_gluing_domains::Function, GD::GluingDataType ) where {GluingDataType} @@ -63,22 +63,22 @@ end ### Preparations for some sample use cases mutable struct RestrictionDataIsomorphism G::AbsGluing - i::AbsSpecMor - j::AbsSpecMor + i::AbsAffineSchemeMor + j::AbsAffineSchemeMor i_res::SchemeMor j_res::SchemeMor - function RestrictionDataIsomorphism(G::AbsGluing, i::AbsSpecMor, j::AbsSpecMor) + function RestrictionDataIsomorphism(G::AbsGluing, i::AbsAffineSchemeMor, j::AbsAffineSchemeMor) return new(G, i, j) end end mutable struct RestrictionDataClosedEmbedding G::AbsGluing - X::AbsSpec - Y::AbsSpec + X::AbsAffineScheme + Y::AbsAffineScheme UX::Scheme VY::Scheme - function RestrictionDataClosedEmbedding(G::AbsGluing, X::AbsSpec, Y::AbsSpec) + function RestrictionDataClosedEmbedding(G::AbsGluing, X::AbsAffineScheme, Y::AbsAffineScheme) return new(G, X, Y) end end @@ -97,7 +97,7 @@ function _compute_domains(GD::RestrictionDataClosedEmbedding) GD.UX = PrincipalOpenSubset(GD.X, OO(GD.X)(lifted_numerator(complement_equation(U)))) GD.VY = PrincipalOpenSubset(GD.Y, OO(GD.Y)(lifted_numerator(complement_equation(V)))) return GD.UX, GD.VY - elseif U isa SpecOpen + elseif U isa AffineSchemeOpenSubscheme GD.UX = intersect(GD.X, U, check=false) GD.VY = intersect(GD.Y, V, check=false) return GD.UX, GD.VY diff --git a/experimental/Schemes/MorphismFromRationalFunctions.jl b/experimental/Schemes/MorphismFromRationalFunctions.jl index 2b0a82c0d9a5..22187071e7f5 100644 --- a/experimental/Schemes/MorphismFromRationalFunctions.jl +++ b/experimental/Schemes/MorphismFromRationalFunctions.jl @@ -17,21 +17,21 @@ The ``aᵢ`` represent the pullbacks of the coordinates (`gens`) of some codomain::CodomainType domain_covering::Covering codomain_covering::Covering - domain_chart::AbsSpec - codomain_chart::AbsSpec + domain_chart::AbsAffineScheme + codomain_chart::AbsAffineScheme coord_imgs::Vector{<:FieldElem} ### Various fields for caching - patch_representatives::IdDict{<:AbsSpec, <:Tuple{<:AbsSpec, <:Vector{<:FieldElem}}} - realizations::IdDict{<:AbsSpec, <:Vector{<:AbsSpecMor}} - realization_previews::IdDict{<:Tuple{<:AbsSpec, <:AbsSpec}, <:Vector{<:FieldElem}} - maximal_extensions::IdDict{<:Tuple{<:AbsSpec, <:AbsSpec}, <:Vector{<:AbsSpecMor}} - cheap_realizations::IdDict{<:Tuple{<:AbsSpec, <:AbsSpec}, <:AbsSpecMor} + patch_representatives::IdDict{<:AbsAffineScheme, <:Tuple{<:AbsAffineScheme, <:Vector{<:FieldElem}}} + realizations::IdDict{<:AbsAffineScheme, <:Vector{<:AbsAffineSchemeMor}} + realization_previews::IdDict{<:Tuple{<:AbsAffineScheme, <:AbsAffineScheme}, <:Vector{<:FieldElem}} + maximal_extensions::IdDict{<:Tuple{<:AbsAffineScheme, <:AbsAffineScheme}, <:Vector{<:AbsAffineSchemeMor}} + cheap_realizations::IdDict{<:Tuple{<:AbsAffineScheme, <:AbsAffineScheme}, <:AbsAffineSchemeMor} full_realization::CoveredSchemeMorphism function MorphismFromRationalFunctions( X::AbsCoveredScheme, Y::AbsCoveredScheme, - U::AbsSpec, V::AbsSpec, + U::AbsAffineScheme, V::AbsAffineScheme, a::Vector{<:FieldElem}; check::Bool=true, domain_covering::Covering=default_covering(X), @@ -47,12 +47,12 @@ The ``aᵢ`` represent the pullbacks of the coordinates (`gens`) of some R = base_ring(F) all(x->parent(x)===F, a) || error("coordinate images must be elements of the same field") R === ambient_coordinate_ring(U) || error("images of pullback of the coordinates do not live in the correct ring") - patch_repr = IdDict{AbsSpec, Tuple{AbsSpec, Vector{FieldElem}}}() + patch_repr = IdDict{AbsAffineScheme, Tuple{AbsAffineScheme, Vector{FieldElem}}}() patch_repr[U] = (V, a) - realizations = IdDict{AbsSpec, Vector{AbsSpecMor}}() - realization_previews = IdDict{Tuple{AbsSpec, AbsSpec}, Vector{FieldElem}}() - maximal_extensions = IdDict{Tuple{AbsSpec, AbsSpec}, Vector{AbsSpecMor}}() - cheap_realizations = IdDict{Tuple{AbsSpec, AbsSpec}, AbsSpecMor}() + realizations = IdDict{AbsAffineScheme, Vector{AbsAffineSchemeMor}}() + realization_previews = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, Vector{FieldElem}}() + maximal_extensions = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, Vector{AbsAffineSchemeMor}}() + cheap_realizations = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsAffineSchemeMor}() return new{typeof(X), typeof(Y)}(X, Y, domain_covering, codomain_covering, U, V, a, patch_repr, realizations, realization_previews, maximal_extensions, @@ -73,7 +73,7 @@ coordinate_images(Phi::MorphismFromRationalFunctions) = Phi.coord_imgs @doc raw""" morphism_from_rational_functions( X::AbsCoveredScheme, Y::AbsCoveredScheme, - U::AbsSpec, V::AbsSpec, + U::AbsAffineScheme, V::AbsAffineScheme, a::Vector{<:FieldElem}; check::Bool=true, domain_covering::Covering=default_covering(X), @@ -144,7 +144,7 @@ given by the pullback function """ morphism_from_rational_functions( X::AbsCoveredScheme, Y::AbsCoveredScheme, - U::AbsSpec, V::AbsSpec, + U::AbsAffineScheme, V::AbsAffineScheme, a::Vector{<:FieldElem}; check::Bool=true, domain_covering::Covering=default_covering(X), @@ -218,14 +218,14 @@ realization_previews(Phi::MorphismFromRationalFunctions) = Phi.realization_previ cheap_realizations(Phi::MorphismFromRationalFunctions) = Phi.cheap_realizations @doc raw""" - realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsSpec) + realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme) For ``U`` in the `domain_covering` of `Phi` construct a list of morphisms ``fₖ : U'ₖ → Vₖ`` from `PrincipalOpenSubset`s ``U'ₖ`` of ``U`` to `patches` ``Vₖ`` in the `codomain_covering` so that altogether the `fₖ` can be assembled to a `CoveringMorphism` which realizes `Phi`. """ -function realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsSpec) +function realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme) if haskey(realizations(Phi), U) return realizations(Phi)[U] end @@ -236,7 +236,7 @@ function realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsSpec) # Try to cover U by PrincipalOpenSubsets W so that the restriction # of Phi to W extends to a regular morphism φ : W → V' for some # `affine_chart` of the codomain of Phi. - covered_codomain_patches = Vector{AbsSpec}([V]) + covered_codomain_patches = Vector{AbsAffineScheme}([V]) complement_equations = Vector{elem_type(OO(U))}() FY = function_field(Y) FX = function_field(X) @@ -280,13 +280,13 @@ function realize_on_patch(Phi::MorphismFromRationalFunctions, U::AbsSpec) end @doc raw""" - realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) + realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) Returns a morphism `f : U' → V` from some `PrincipalOpenSubset` of `U` to `V` such that the restriction of `Phi` to `U'` is `f`. Note that `U'` need not be maximal with this property! """ -function realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) +function realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) X = domain(Phi) Y = codomain(Phi) # Check that the input is admissible @@ -311,14 +311,14 @@ function realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsSpec, end @doc raw""" - realization_preview(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) + realization_preview(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) For a pair `(U, V)` of `patches` in the `domain_covering` and the `codomain_covering` of `Phi`, respectively, this returns a list of elements in the fraction field of the `ambient_coordinate_ring` of `U` which represent the pullbacks of `gens(OO(V))` under `Phi` to `U`. """ -function realization_preview(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) +function realization_preview(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) if haskey(realization_previews(Phi), (U, V)) return realization_previews(Phi)[(U, V)] end @@ -343,14 +343,14 @@ function realization_preview(Phi::MorphismFromRationalFunctions, U::AbsSpec, V:: end @doc raw""" - random_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) + random_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) For a pair `(U, V)` of `patches` in the `domain_covering` and the `codomain_covering` of `Phi`, respectively, this creates a random `PrincipalOpenSubset` `U'` on which the restriction `f : U' → V` of `Phi` can be realized and returns that restriction. Note that `U'` need not (and usually will not) be maximal with this property. """ -function random_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) +function random_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) img_gens_frac = realization_preview(Phi, U, V) U_sub, img_gens = _random_extension(U, img_gens_frac) phi = morphism(U_sub, ambient_space(V), img_gens, check=true) # Set to false @@ -358,7 +358,7 @@ function random_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::A end @doc raw""" - cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) + cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) For a pair `(U, V)` of `patches` in the `domain_covering` and the `codomain_covering` of `Phi`, respectively, this creates a random `PrincipalOpenSubset` `U'` on which @@ -368,7 +368,7 @@ Note that `U'` need not (and usually will not) be maximal with this property. This method is cheap in the sense that it simply inverts all representatives of the denominators occurring in the `realization_preview(Phi, U, V)`. """ -function cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) +function cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) if haskey(cheap_realizations(Phi), (U, V)) return cheap_realizations(Phi)[(U, V)] end @@ -402,20 +402,20 @@ function cheap_realization(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::Ab end @doc raw""" - realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) + realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) For a pair `(U, V)` of `patches` in the `domain_covering` and the `codomain_covering` of `Phi`, respectively, this returns a list of morphisms `fₖ : U'ₖ → V` such that the restriction of `Phi` to `U'ₖ` and `V` is `fₖ` and altogether the `U'ₖ` cover the maximal open subset `U'⊂ U` on which the restriction `U' → V` of `Phi` can be realized. """ -function realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsSpec, V::AbsSpec) +function realize_maximally_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme) if haskey(maximal_extensions(Phi), (U, V)) return maximal_extensions(Phi)[(U, V)] end img_gens_frac = realization_preview(Phi, U, V) extensions = _extend(U, img_gens_frac) - result = AbsSpecMor[] + result = AbsAffineSchemeMor[] for (U, g) in extensions prelim = morphism(U, ambient_space(V), g, check=false) push!(result, _restrict_properly(prelim, V)) @@ -434,8 +434,8 @@ be avoided. """ function realize(Phi::MorphismFromRationalFunctions) if !isdefined(Phi, :full_realization) - realizations = AbsSpecMor[] - mor_dict = IdDict{AbsSpec, AbsSpecMor}() + realizations = AbsAffineSchemeMor[] + mor_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(domain_covering(Phi)) loc_mors = realize_on_patch(Phi, U) for phi in loc_mors @@ -459,7 +459,7 @@ underlying_morphism(Phi::MorphismFromRationalFunctions) = realize(Phi) ### # Find a random open subset `W ⊂ U` to which all the rational functions # represented by the elements in `a` can be extended as regular functions. -function _random_extension(U::AbsSpec, a::Vector{<:FieldElem}) +function _random_extension(U::AbsAffineScheme, a::Vector{<:FieldElem}) R = ambient_coordinate_ring(U) if iszero(length(a)) return [(U, elem_type(U)[])] @@ -497,7 +497,7 @@ end # represented by the elements in `a` can be extended as regular functions # and return a list of tuples `(W', a')` of realizations on principal # open subsets W' covering W. -function _extend(U::AbsSpec, a::Vector{<:FieldElem}) +function _extend(U::AbsAffineScheme, a::Vector{<:FieldElem}) R = ambient_coordinate_ring(U) if iszero(length(a)) return [(U, elem_type(U)[])] @@ -545,7 +545,7 @@ function _extend(U::AbsSpec, a::Vector{<:FieldElem}) #I_undef = ideal(OO(U), small_generating_set(I_undef)) #I_undef = radical(I_undef) - result = Vector{Tuple{AbsSpec, Vector{RingElem}}}() + result = Vector{Tuple{AbsAffineScheme, Vector{RingElem}}}() for g in small_generating_set(I_undef) Ug = PrincipalOpenSubset(U, g) @@ -570,7 +570,7 @@ equidimensional_decomposition_radical(I::MPolyQuoLocalizedIdeal) = [ideal(base_r # is already fully computed, but which is not in `covered`. # If no such `U` exists: Bad luck. We just take any other one # and the gluing has to be computed eventually. -function _find_good_neighboring_patch(cov::Covering, covered::Vector{<:AbsSpec}) +function _find_good_neighboring_patch(cov::Covering, covered::Vector{<:AbsAffineScheme}) U = [x for x in patches(cov) if !any(y->y===x, covered)] glue = gluings(cov) good_neighbors = [(x, y) for x in U for y in covered if @@ -590,16 +590,16 @@ end # as regular functions on U' and a morphism U' → A to the `ambient_space` # of V can be realized, V might be so small that we need a proper restriction # of the domain. The methods below take care of that. -function _restrict_properly(f::AbsSpecMor, V::AbsSpec{<:Ring, <:MPolyRing}) +function _restrict_properly(f::AbsAffineSchemeMor, V::AbsAffineScheme{<:Ring, <:MPolyRing}) return restrict(f, domain(f), V, check=false) end -function _restrict_properly(f::AbsSpecMor, V::AbsSpec{<:Ring, <:MPolyQuoRing}) +function _restrict_properly(f::AbsAffineSchemeMor, V::AbsAffineScheme{<:Ring, <:MPolyQuoRing}) return restrict(f, domain(f), V, check=false) end function _restrict_properly( - f::AbsSpecMor{<:PrincipalOpenSubset}, V::AbsSpec{<:Ring, <:RT} + f::AbsAffineSchemeMor{<:PrincipalOpenSubset}, V::AbsAffineScheme{<:Ring, <:RT} ) where {RT<:MPolyLocRing{<:Ring, <:RingElem, <:MPolyRing, <:MPolyRingElem, <:MPolyPowersOfElement} @@ -613,7 +613,7 @@ function _restrict_properly( end function _restrict_properly( - f::AbsSpecMor{<:PrincipalOpenSubset}, V::AbsSpec{<:Ring, <:RT} + f::AbsAffineSchemeMor{<:PrincipalOpenSubset}, V::AbsAffineScheme{<:Ring, <:RT} ) where {RT<:MPolyQuoLocRing{<:Ring, <:RingElem, <:MPolyRing, <:MPolyRingElem, <:MPolyPowersOfElement} @@ -718,7 +718,7 @@ function _try_pullback_cheap(phi::MorphismFromRationalFunctions, I::IdealSheaf) scheme(I) === Y || error("ideal sheaf not defined on the correct scheme") # Find a patch in Y on which this component is visible all_V = [V for V in affine_charts(Y) if !isone(I(V))] - function complexity_codomain(V::AbsSpec) + function complexity_codomain(V::AbsAffineScheme) return sum(total_degree.(lifted_numerator.(gens(I(V)))); init=0) end sort!(all_V, lt=(x,y)->complexity_codomain(x)complexity(x)new_complexity(x)x>=0, c) "divisor must be effective" ray_list = rays(polyhedral_fan(X)) # All rays of the polyhedral fan of X - ideal_dict = IdDict{AbsSpec, Ideal}() # The final output: A list of ideals, one for each + ideal_dict = IdDict{AbsAffineScheme, Ideal}() # The final output: A list of ideals, one for each # affine_chart of X for U in affine_charts(X) # Iterate through the charts diff --git a/experimental/Schemes/ProjectiveModules.jl b/experimental/Schemes/ProjectiveModules.jl index d1230aaae7a0..732beef748d5 100644 --- a/experimental/Schemes/ProjectiveModules.jl +++ b/experimental/Schemes/ProjectiveModules.jl @@ -19,17 +19,17 @@ end @doc raw""" is_projective(M::SubquoModule) -Given a subquotient ``M = (A + B)/B`` over a ring ``R`` return a triple -`(success, π, σ)` where `success` is `true` or `false` depending on -whether or not ``M`` is projective and maps ``π : Rʳ ↔ M : σ`` -where ``π`` is a projection onto ``M`` and ``σ`` a section of ``π`` -so that ``Rʳ ≅ M ⊕ N`` splits as a direct sum via the projector +Given a subquotient ``M = (A + B)/B`` over a ring ``R`` return a triple +`(success, π, σ)` where `success` is `true` or `false` depending on +whether or not ``M`` is projective and maps ``π : Rʳ ↔ M : σ`` +where ``π`` is a projection onto ``M`` and ``σ`` a section of ``π`` +so that ``Rʳ ≅ M ⊕ N`` splits as a direct sum via the projector ``σ ∘ π``. """ function is_projective(M::SubquoModule; check::Bool=true) ### Assemble a presentation of M over its base ring - # TODO: Eventually replace by the methods for free - # presentation from the module package. + # TODO: Eventually replace by the methods for free + # presentation from the module package. R = base_ring(M) r = ngens(M) Rr = FreeMod(R, r) @@ -56,19 +56,19 @@ function is_projective(M::FreeMod; check::Bool=true) return true, identity_map(M), identity_map(M) end ### -# Given a presentation matrix A for a module M over a ring R, -# this procedure checks whether M is projective and in the affirmative -# case returns a triple (true, Q, k) where 1//(unit^k) * Q is the -# projector. +# Given a presentation matrix A for a module M over a ring R, +# this procedure checks whether M is projective and in the affirmative +# case returns a triple (true, Q, k) where 1//(unit^k) * Q is the +# projector. # -# The optional argument `unit` indicates that the ring R was obtained -# as the localization R = A[unit⁻¹] from another ring A. -# The output is then returned in a way that Q lifts to A. +# The optional argument `unit` indicates that the ring R was obtained +# as the localization R = A[unit⁻¹] from another ring A. +# The output is then returned in a way that Q lifts to A. # -# Note: It is highly advised to feed this function only matrices -# whose entries do not have denominators. Otherwise, the program will +# Note: It is highly advised to feed this function only matrices +# whose entries do not have denominators. Otherwise, the program will # most likely run very slow. -function _is_projective_without_denominators(A::MatElem; +function _is_projective_without_denominators(A::MatElem; unit::RingElem=one(base_ring(A)), task::Symbol=:with_projector ) @@ -77,21 +77,21 @@ function _is_projective_without_denominators(A::MatElem; n = ncols(A) # The condition for end of recursion: - if iszero(A) + if iszero(A) return true, identity_matrix(R, n), 0 end entry_list = [(A[i,j], i, j) for i in 1:m for j in 1:n if !iszero(A[i,j])] I = ideal(R, [a[1] for a in entry_list]) if !(one(R) in I) - # If I is not the unit ideal, it might still be the case that this holds true for the + # If I is not the unit ideal, it might still be the case that this holds true for the # restriction to the connected components of Spec(R). R isa Union{MPolyRing, MPolyQuoRing, MPolyLocRing, MPolyQuoLocRing} || error("method not implemented") # TODO: Work this out without schemes on the purely algebraic side. - # This is a temporary hotfix to address a particular boundary case, see #1882. + # This is a temporary hotfix to address a particular boundary case, see #1882. # The code below is also not generic and should eventually be adjusted. - X = Spec(R) + X = spec(R) U = connected_components(X) l = length(U) l == 1 && return false, zero_matrix(R, n, n), 0 @@ -99,7 +99,7 @@ function _is_projective_without_denominators(A::MatElem; expon = Int[] for k in 1:l L, inc = localization(R, complement_equation(U[k])) # We can not use OO(U[k]) directly, because - # we'd be missing the map in that case. + # we'd be missing the map in that case. success, p, k = _is_projective_without_denominators(change_base_ring(L, A), unit=L(unit), task=task) !success && return false, zero_matrix(R, n, n), 0 q = zero_matrix(R, nrows(p), ncols(p)) @@ -122,7 +122,7 @@ function _is_projective_without_denominators(A::MatElem; end inner, outer = ppio(d, _lifted_numerator(unit)) - (mpow, upow) = Oscar._minimal_power_such_that(_lifted_numerator(unit), + (mpow, upow) = Oscar._minimal_power_such_that(_lifted_numerator(unit), x->(divides(x, inner)[1])) # pull u^mpow from each entry of the matrix: @@ -142,12 +142,12 @@ function _is_projective_without_denominators(A::MatElem; lambda1 = coordinates(one(R), I) # coefficients for the first powers involved_entries = [k for k in 1:length(lambda1) if !iszero(lambda1[k])] - # For every 'involved entry' u = aᵢⱼ, localize at u and form - # the submatrix B = Bᵢⱼ. For B we obtain the projectors Pᵢⱼ - # by recursion. It will, in general have a denominator uᵏ for - # some k and is returned as a pair (Qᵢⱼ, k) for the given + # For every 'involved entry' u = aᵢⱼ, localize at u and form + # the submatrix B = Bᵢⱼ. For B we obtain the projectors Pᵢⱼ + # by recursion. It will, in general have a denominator uᵏ for + # some k and is returned as a pair (Qᵢⱼ, k) for the given # unit u and a matrix Qᵢⱼ ∈ Rⁿˣⁿ. - + # Get rid of the zero entries. entry_list = entry_list[involved_entries] lambda1 = lambda1[1, involved_entries] @@ -167,9 +167,9 @@ function _is_projective_without_denominators(A::MatElem; Asub = B[[k for k in 1:m if k != i], [k for k in 1:n if k !=j]] Rloc, inc = localization(R, u) push!(sub_localizations, (Rloc, inc)) - # We expect a pair (Q, k) consisting of a matrix Q defined over Rloc, - # but liftable to a matrix over R without effort. The local projector - # over Rloc is then 1//uᵏ ⋅ Q. + # We expect a pair (Q, k) consisting of a matrix Q defined over Rloc, + # but liftable to a matrix over R without effort. The local projector + # over Rloc is then 1//uᵏ ⋅ Q. push!(sub_results, _is_projective_without_denominators(map_entries(Rloc, Asub), unit=u, task=task)) B = last(sub_results)[2] k = last(sub_results)[3] @@ -204,10 +204,10 @@ function _is_projective_without_denominators(A::MatElem; end end - # The matrix Qinc needs to be fed with a vector v whose j-th entry - # has been deleted via the localization at u. This can only be done - # over R for u⋅v, so we multiply by u, keeping in mind that this will - # become a unit in the localization. + # The matrix Qinc needs to be fed with a vector v whose j-th entry + # has been deleted via the localization at u. This can only be done + # over R for u⋅v, so we multiply by u, keeping in mind that this will + # become a unit in the localization. P = u*identity_matrix(R, n) P[j, j] = 0 for l in 1:n @@ -217,14 +217,14 @@ function _is_projective_without_denominators(A::MatElem; result = result + lambda*P*Qinc end - # pull the denominator u from the result and make the matrix liftable. + # pull the denominator u from the result and make the matrix liftable. d = reduce(lcm, _lifted_denominator.(result)) if isone(d) return true, result, 0 end inner, outer = ppio(d, _lifted_numerator(unit)) - (mpow, upow) = Oscar._minimal_power_such_that(_lifted_numerator(unit), + (mpow, upow) = Oscar._minimal_power_such_that(_lifted_numerator(unit), x->(divides(x, inner)[1])) # pull u^mpow from each entry of the matrix: @@ -238,7 +238,7 @@ function _is_projective_without_denominators(A::MatElem; end end return true, L, mpow - elseif task==:without_projector + elseif task==:without_projector return true, zero_matrix(R, n, n), 0 end error("task could not be identified") @@ -257,7 +257,7 @@ _lifted_numerator(a::MPolyQuoLocRingElem) = lifted_numerator(a) ######################################################################## # Various localization routines for localizing at powers of elements # # # -# This deserves special constructors, because we can deliver maps for # +# This deserves special constructors, because we can deliver maps for # # lifting which is not possible in general. # ######################################################################## function localization(A::MPolyQuoRing, f::MPolyQuoRingElem) @@ -269,14 +269,14 @@ function localization(A::MPolyQuoRing, f::MPolyQuoRingElem) parent(a) == A || error("element does not belong to the correct ring") return L(a, check=false) end - function func_inv(a::MPolyQuoLocRingElem{<:Any, <:Any, <:Any, <:Any, + function func_inv(a::MPolyQuoLocRingElem{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement} ) L == parent(a) || error("element does not belong to the correct ring") iszero(numerator(a)) && return zero(A) isone(lifted_denominator(a)) && return A(lifted_numerator(a)) success, c = divides(numerator(a), denominator(a)) - if !success + if !success error("lifting not possible") end return c @@ -293,7 +293,7 @@ function localization(A::MPolyLocRing, f::MPolyLocRingElem) parent(a) == A || error("element does not belong to the correct ring") return L(a, check=false) end - function func_inv(a::MPolyLocRingElem{<:Any, <:Any, <:Any, <:Any, + function func_inv(a::MPolyLocRingElem{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement} ) L == parent(a) || error("element does not belong to the correct ring") @@ -314,7 +314,7 @@ function localization(A::MPolyQuoLocRing, f::MPolyQuoLocRingElem) parent(a) == A || error("element does not belong to the correct ring") return L(a) end - function func_inv(a::MPolyQuoLocRingElem{<:Any, <:Any, <:Any, <:Any, + function func_inv(a::MPolyQuoLocRingElem{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement} ) L == parent(a) || error("element does not belong to the correct ring") @@ -322,7 +322,7 @@ function localization(A::MPolyQuoLocRing, f::MPolyQuoLocRingElem) iszero(numerator(a)) && return zero(A) i, o = ppio(lifted_denominator(a), d) success, c = divides(numerator(a), parent(numerator(a))(i)) - if !success + if !success # last resort: return A(lifted_numerator(a), lifted_denominator(a)) end diff --git a/experimental/Schemes/Sheaves.jl b/experimental/Schemes/Sheaves.jl index ff33d1ea550e..b6126c24c29b 100644 --- a/experimental/Schemes/Sheaves.jl +++ b/experimental/Schemes/Sheaves.jl @@ -182,17 +182,17 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) # We allow the following cases: # # * U::PrincipalOpenSubset with one ancestor W in the basic charts of X - # * U::SimplifiedSpec with one ancestor W in the basic charts of X + # * U::SimplifiedAffineScheme with one ancestor W in the basic charts of X # * U::PrincipalOpenSubset ⊂ V::PrincipalOpenSubset with ambient_scheme(U) === ambient_scheme(V) in the basic charts of X # * U::PrincipalOpenSubset ⊂ V::PrincipalOpenSubset with ambient_scheme(U) != ambient_scheme(V) both in the basic charts of X # and U and V contained in the gluing domains of their ambient schemes - # * U::AbsSpec ⊂ V::AbsSpec in the basic charts of X - # * U::AbsSpec ⊂ X for U in the basic charts + # * U::AbsAffineScheme ⊂ V::AbsAffineScheme in the basic charts of X + # * U::AbsAffineScheme ⊂ X for U in the basic charts # * U::PrincipalOpenSubset ⊂ X with ambient_scheme(U) in the basic charts of X - # * W::SpecOpen ⊂ X with ambient_scheme(U) in the basic charts of X + # * W::AffineSchemeOpenSubscheme ⊂ X with ambient_scheme(U) in the basic charts of X function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) inc_U_flat = _flatten_open_subscheme(U, default_covering(X)) inc_V_flat = _flatten_open_subscheme(V, default_covering(X)) @@ -213,27 +213,27 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) return true end function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, Y::AbsCoveredScheme ) return Y === X && has_ancestor(W->(any(WW->(WW === W), affine_charts(X))), U) end - function is_open_func(U::AbsSpec, Y::AbsCoveredScheme) + function is_open_func(U::AbsAffineScheme, Y::AbsCoveredScheme) return Y === X && has_ancestor(W->any(WW->(WW===W), affine_charts(X)), U) end # The following is implemented for the sake of completeness for boundary cases. function is_open_func(Z::AbsCoveredScheme, Y::AbsCoveredScheme) return X === Y === Z end - function is_open_func(U::AbsSpec, V::AbsSpec) + function is_open_func(U::AbsAffineScheme, V::AbsAffineScheme) any(x->x===U, affine_charts(X)) || return false any(x->x===U, affine_charts(X)) || return false G = default_covering(X)[U, V] return is_subscheme(U, gluing_domains(G)[1]) end function is_open_func( - U::AbsSpec, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + U::AbsAffineScheme, + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) is_subscheme(U, V) && return true any(x->x===U, affine_charts(X)) || return false @@ -248,8 +248,8 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) return is_subset(U, pre_V) end function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - V::AbsSpec + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + V::AbsAffineScheme ) any(x->x===V, affine_charts(X)) || return false inc_U_flat = _flatten_open_subscheme(U, default_covering(X)) @@ -260,11 +260,11 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) G = default_covering(X)[W, V] return is_subset(Udirect, gluing_domains(G)[1]) end - function is_open_func(W::SpecOpen, Y::AbsCoveredScheme) + function is_open_func(W::AffineSchemeOpenSubscheme, Y::AbsCoveredScheme) return Y === X && ambient_scheme(W) in default_covering(X) end - function is_open_func(W::SpecOpen, V::AbsSpec) + function is_open_func(W::AffineSchemeOpenSubscheme, V::AbsAffineScheme) V in default_covering(X) || return false ambient_scheme(W) === V && return true U = ambient_scheme(W) @@ -273,8 +273,8 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) return is_subset(W, gluing_domains(G)[1]) end function is_open_func( - W::SpecOpen, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + W::AffineSchemeOpenSubscheme, + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) PW = ambient_scheme(W) inc_V_flat = _flatten_open_subscheme(V, default_covering(X)) @@ -291,7 +291,7 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) return is_subscheme(W, preV) end end - function is_open_func(W::SpecOpen, V::SpecOpen) + function is_open_func(W::AffineSchemeOpenSubscheme, V::AffineSchemeOpenSubscheme) PW = ambient_scheme(W) PV = ambient_scheme(V) PW in default_covering(X) || return false @@ -304,7 +304,7 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) return is_subscheme(W, preV) end end - function is_open_func(U::AbsSpec, W::SpecOpen) + function is_open_func(U::AbsAffineScheme, W::AffineSchemeOpenSubscheme) U in default_covering(X) || return false if U === ambient_scheme(W) # in this case W must be equal to U @@ -318,8 +318,8 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) end end function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - W::SpecOpen + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + W::AffineSchemeOpenSubscheme ) inc_U_flat = _flatten_open_subscheme(U, default_covering(X)) A = ambient_scheme(codomain(inc_U_flat)) @@ -340,22 +340,22 @@ function _is_open_func_for_schemes(X::AbsCoveredScheme) return is_open_func end -function _is_open_func_for_schemes_without_specopen(X::AbsCoveredScheme) +function _is_open_func_for_schemes_without_affine_scheme_open_subscheme(X::AbsCoveredScheme) ### Checks for open containment. # # We allow the following cases: # # * U::PrincipalOpenSubset with one ancestor W in the basic charts of X - # * U::SimplifiedSpec with one ancestor W in the basic charts of X + # * U::SimplifiedAffineScheme with one ancestor W in the basic charts of X # * U::PrincipalOpenSubset ⊂ V::PrincipalOpenSubset with ambient_scheme(U) === ambient_scheme(V) in the basic charts of X # * U::PrincipalOpenSubset ⊂ V::PrincipalOpenSubset with ambient_scheme(U) != ambient_scheme(V) both in the basic charts of X # and U and V contained in the gluing domains of their ambient schemes - # * U::AbsSpec ⊂ V::AbsSpec in the basic charts of X - # * U::AbsSpec ⊂ X for U in the basic charts + # * U::AbsAffineScheme ⊂ V::AbsAffineScheme in the basic charts of X + # * U::AbsAffineScheme ⊂ X for U in the basic charts # * U::PrincipalOpenSubset ⊂ X with ambient_scheme(U) in the basic charts of X function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) inc_U_flat = _flatten_open_subscheme(U, default_covering(X)) inc_V_flat = _flatten_open_subscheme(V, default_covering(X)) @@ -376,27 +376,27 @@ function _is_open_func_for_schemes_without_specopen(X::AbsCoveredScheme) return true end function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, Y::AbsCoveredScheme ) return Y === X && has_ancestor(W->(any(WW->(WW === W), affine_charts(X))), U) end - function is_open_func(U::AbsSpec, Y::AbsCoveredScheme) + function is_open_func(U::AbsAffineScheme, Y::AbsCoveredScheme) return Y === X && has_ancestor(W->any(WW->(WW===W), affine_charts(X)), U) end # The following is implemented for the sake of completeness for boundary cases. function is_open_func(Z::AbsCoveredScheme, Y::AbsCoveredScheme) return X === Y === Z end - function is_open_func(U::AbsSpec, V::AbsSpec) + function is_open_func(U::AbsAffineScheme, V::AbsAffineScheme) U in affine_charts(X) || return false V in affine_charts(X) || return false G = default_covering(X)[U, V] return is_subscheme(U, gluing_domains(G)[1]) end function is_open_func( - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - V::AbsSpec + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + V::AbsAffineScheme ) V in affine_charts(X) || return false inc_U_flat = _flatten_open_subscheme(U, default_covering(X)) @@ -423,7 +423,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P, I); +julia> Y = proj(P, I); julia> Ycov = covered_scheme(Y) Scheme @@ -512,7 +512,7 @@ end function restrict( a::Union{MPolyRingElem, MPolyQuoRingElem, MPolyLocRingElem, MPolyQuoLocRingElem}, - U::SpecOpen; + U::AffineSchemeOpenSubscheme; check::Bool=true ) parent(a) === OO(ambient_scheme(U)) || return OO(U)(a) diff --git a/experimental/Schemes/SimplifiedSpec.jl b/experimental/Schemes/SimplifiedAffineScheme.jl similarity index 80% rename from experimental/Schemes/SimplifiedSpec.jl rename to experimental/Schemes/SimplifiedAffineScheme.jl index 0fa1a7423181..127fb7df8240 100644 --- a/experimental/Schemes/SimplifiedSpec.jl +++ b/experimental/Schemes/SimplifiedAffineScheme.jl @@ -3,35 +3,35 @@ ######################################################################## ### essential getters -underlying_scheme(X::SimplifiedSpec) = X.X -original(X::SimplifiedSpec) = X.Y -identification_maps(X::SimplifiedSpec) = (X.f, X.g) +underlying_scheme(X::SimplifiedAffineScheme) = X.X +original(X::SimplifiedAffineScheme) = X.Y +identification_maps(X::SimplifiedAffineScheme) = (X.f, X.g) ### High-level constructors @doc raw""" - simplify(X::AbsSpec{<:Field}) + simplify(X::AbsAffineScheme{<:Field}) -Given an affine scheme ``X`` with coordinate ring ``R = 𝕜[x₁,…,xₙ]/I`` -(or a localization thereof), use `Singular`'s `elimpart` to try -to eliminate variables ``xᵢ`` to arrive at a simpler presentation -``R ≅ R' = 𝕜[y₁,…,yₘ]/J`` for some ideal ``J``; return -a `SimplifiedSpec` ``Y`` with ``X`` as its `original`. +Given an affine scheme ``X`` with coordinate ring ``R = 𝕜[x₁,…,xₙ]/I`` +(or a localization thereof), use `Singular`'s `elimpart` to try +to eliminate variables ``xᵢ`` to arrive at a simpler presentation +``R ≅ R' = 𝕜[y₁,…,yₘ]/J`` for some ideal ``J``; return +a `SimplifiedAffineScheme` ``Y`` with ``X`` as its `original`. ***Note:*** The `ambient_coordinate_ring` of the output `Y` will be different from the one of `X` and hence the two schemes will not compare using `==`. """ -function simplify(X::AbsSpec{<:Field}) +function simplify(X::AbsAffineScheme{<:Field}) L, f, g = simplify(OO(X)) - Y = Spec(L) + Y = spec(L) YtoX = morphism(Y, X, f, check=false) XtoY = morphism(X, Y, g, check=false) set_attribute!(YtoX, :inverse, XtoY) set_attribute!(XtoY, :inverse, YtoX) - return SimplifiedSpec(Y, X, YtoX, XtoY, check=false) + return SimplifiedAffineScheme(Y, X, YtoX, XtoY, check=false) end ### Methods to roam in the ancestry tree -function has_ancestor(P::Function, X::SimplifiedSpec) +function has_ancestor(P::Function, X::SimplifiedAffineScheme) return P(X) || has_ancestor(P, original(X)) end @@ -40,23 +40,23 @@ function has_ancestor(P::Function, X::PrincipalOpenSubset) end @doc raw""" - has_ancestor(P::Function, X::AbsSpec) + has_ancestor(P::Function, X::AbsAffineScheme) -Check whether property `P` holds for `X` or some ancestor of `X` in -case it is a `PrincipalOpenSubset`, or a `SimplifiedSpec`. +Check whether property `P` holds for `X` or some ancestor of `X` in +case it is a `PrincipalOpenSubset`, or a `SimplifiedAffineScheme`. """ -function has_ancestor(P::Function, X::AbsSpec) +function has_ancestor(P::Function, X::AbsAffineScheme) return P(X) # This case will only be called when we reached the root. end #= # This crawls up the tree of charts until hitting one of the patches of C. -# Then it returns a pair (f, d) where f is the inclusion morphism +# Then it returns a pair (f, d) where f is the inclusion morphism # of U into the patch V of C and d is a Vector of elements of OO(V) -# which have to be inverted to arrive at U. That is: f induces an -# isomorphism on the complement of d. +# which have to be inverted to arrive at U. That is: f induces an +# isomorphism on the complement of d. =# -function _find_chart(U::AbsSpec, C::Covering; +function _find_chart(U::AbsAffineScheme, C::Covering; complement_equations::Vector{T}=elem_type(OO(U))[] ) where {T<:RingElem} any(W->(W === U), patches(C)) || error("patch not found") @@ -76,7 +76,7 @@ function _find_chart(U::PrincipalOpenSubset, C::Covering; return compose(inclusion_morphism(U), f), d end -function _find_chart(U::SimplifiedSpec, C::Covering; +function _find_chart(U::SimplifiedAffineScheme, C::Covering; complement_equations::Vector{T}=elem_type(OO(U))[] ) where {T<:RingElem} any(W->(W === U), patches(C)) && return identity_map(U), complement_equations @@ -87,7 +87,7 @@ function _find_chart(U::SimplifiedSpec, C::Covering; return compose(f, h), d end -function __find_chart(U::AbsSpec, C::Covering) +function __find_chart(U::AbsAffineScheme, C::Covering) any(W->(W === U), patches(C)) || error("patch not found") return U end @@ -97,20 +97,20 @@ function __find_chart(U::PrincipalOpenSubset, C::Covering) return __find_chart(ambient_scheme(U), C) end -function __find_chart(U::SimplifiedSpec, C::Covering) +function __find_chart(U::SimplifiedAffineScheme, C::Covering) any(W->(W === U), patches(C)) && return U return __find_chart(original(U), C) end #= -# This follows U in its ancestor tree up to the point -# where a patch W in C is found. Then it recreates U as a -# PrincipalOpenSubset UU of W and returns the identification +# This follows U in its ancestor tree up to the point +# where a patch W in C is found. Then it recreates U as a +# PrincipalOpenSubset UU of W and returns the identification # with UU. =# function _flatten_open_subscheme( U::PrincipalOpenSubset, C::Covering; - iso::AbsSpecMor=begin + iso::AbsAffineSchemeMor=begin UU = PrincipalOpenSubset(U, one(OO(U))) f = morphism(U, UU, hom(OO(UU), OO(U), gens(OO(U)), check=false), check=false) f_inv = morphism(UU, U, hom(OO(U), OO(UU), gens(OO(UU)), check=false), check=false) @@ -133,15 +133,15 @@ function _flatten_open_subscheme( new_iso_inv = compose(inv_ident, inverse(iso)) set_attribute!(new_iso, :inverse, new_iso_inv) set_attribute!(new_iso_inv, :inverse, new_iso) - if any(WW->(WW===W), patches(C)) + if any(WW->(WW===W), patches(C)) return new_iso end return _flatten_open_subscheme(W, C, iso=new_iso) end function _flatten_open_subscheme( - U::SimplifiedSpec, C::Covering; - iso::AbsSpecMor=begin + U::SimplifiedAffineScheme, C::Covering; + iso::AbsAffineSchemeMor=begin UU = PrincipalOpenSubset(U, one(OO(U))) f = morphism(U, UU, hom(OO(UU), OO(U), gens(OO(U)), check=false), check=false) f_inv = morphism(UU, U, hom(OO(U), OO(UU), gens(OO(UU)), check=false), check=false) @@ -159,10 +159,10 @@ function _flatten_open_subscheme( f, g = identification_maps(U) hVW = pullback(g)(hV) WV = PrincipalOpenSubset(W, hVW) - ident = morphism(UV, WV, - hom(OO(WV), OO(UV), - [OO(UV)(x, check=false) for x in pullback(f).(gens(ambient_coordinate_ring(WV)))], - check=false), + ident = morphism(UV, WV, + hom(OO(WV), OO(UV), + [OO(UV)(x, check=false) for x in pullback(f).(gens(ambient_coordinate_ring(WV)))], + check=false), check=false) inv_ident = morphism(WV, UV, hom(OO(UV), OO(WV), @@ -173,15 +173,15 @@ function _flatten_open_subscheme( new_iso_inv = compose(inv_ident, inverse(iso)) set_attribute!(new_iso, :inverse, new_iso_inv) set_attribute!(new_iso_inv, :inverse, new_iso) - if any(WW->(WW===W), patches(C)) + if any(WW->(WW===W), patches(C)) return new_iso end return _flatten_open_subscheme(W, C, iso=new_iso) end function _flatten_open_subscheme( - U::AbsSpec, C::Covering; - iso::AbsSpecMor=begin + U::AbsAffineScheme, C::Covering; + iso::AbsAffineSchemeMor=begin UU = PrincipalOpenSubset(U, one(OO(U))) f = morphism(U, UU, hom(OO(UU), OO(U), gens(OO(U)), check=false), check=false) f_inv = morphism(UU, U, hom(OO(U), OO(UU), gens(OO(UU)), check=false), check=false) @@ -194,8 +194,8 @@ function _flatten_open_subscheme( end function _flatten_open_subscheme( - U::PrincipalOpenSubset, P::AbsSpec; - iso::AbsSpecMor=begin + U::PrincipalOpenSubset, P::AbsAffineScheme; + iso::AbsAffineSchemeMor=begin UU = PrincipalOpenSubset(U, one(OO(U))) f = morphism(U, UU, hom(OO(UU), OO(U), gens(OO(U)), check=false), check=false) f_inv = morphism(UU, U, hom(OO(U), OO(UU), gens(OO(UU)), check=false), check=false) @@ -226,8 +226,8 @@ function _flatten_open_subscheme( end function _flatten_open_subscheme( - U::SimplifiedSpec, P::AbsSpec; - iso::AbsSpecMor=begin + U::SimplifiedAffineScheme, P::AbsAffineScheme; + iso::AbsAffineSchemeMor=begin UU = PrincipalOpenSubset(U, one(OO(U))) f = morphism(U, UU, hom(OO(UU), OO(U), gens(OO(U)), check=false), check=false) f_inv = morphism(UU, U, hom(OO(U), OO(UU), gens(OO(UU)), check=false), check=false) @@ -246,16 +246,16 @@ function _flatten_open_subscheme( f, g = identification_maps(U) hVW = pullback(g)(hV) WV = PrincipalOpenSubset(W, hVW) - ident = morphism(UV, WV, - hom(OO(WV), OO(UV), - OO(UV).(pullback(f).(gens(ambient_coordinate_ring(WV)))), - check=false), + ident = morphism(UV, WV, + hom(OO(WV), OO(UV), + OO(UV).(pullback(f).(gens(ambient_coordinate_ring(WV)))), + check=false), check=false) new_iso = compose(iso, ident) - ident_inv = morphism(WV, UV, - hom(OO(UV), OO(WV), - OO(WV).(pullback(g).(gens(ambient_coordinate_ring(UV)))), - check=false), + ident_inv = morphism(WV, UV, + hom(OO(UV), OO(WV), + OO(WV).(pullback(g).(gens(ambient_coordinate_ring(UV)))), + check=false), check=false) new_iso_inv = compose(ident_inv, inverse(iso)) set_attribute!(new_iso, :inverse, new_iso_inv) @@ -267,8 +267,8 @@ function _flatten_open_subscheme( end function _flatten_open_subscheme( - U::AbsSpec, P::AbsSpec; - iso::AbsSpecMor=begin + U::AbsAffineScheme, P::AbsAffineScheme; + iso::AbsAffineSchemeMor=begin UU = PrincipalOpenSubset(U, one(OO(U))) f = morphism(U, UU, hom(OO(UU), OO(U), gens(OO(U)), check=false), check=false) f_inv = morphism(UU, U, hom(OO(U), OO(UU), gens(OO(UU)), check=false), check=false) @@ -299,33 +299,33 @@ function _have_common_ancestor(U::PrincipalOpenSubset, V::PrincipalOpenSubset) return _have_common_ancestor(ambient_scheme(U), ambient_scheme(V)) end -function _have_common_ancestor(U::AbsSpec, V::PrincipalOpenSubset) +function _have_common_ancestor(U::AbsAffineScheme, V::PrincipalOpenSubset) return _have_common_ancestor(U, ambient_scheme(V)) end function _have_common_ancestor( V::PrincipalOpenSubset, - U::AbsSpec + U::AbsAffineScheme ) return _have_common_ancestor(U, ambient_scheme(V)) end -function _have_common_ancestor(U::AbsSpec, V::AbsSpec) +function _have_common_ancestor(U::AbsAffineScheme, V::AbsAffineScheme) return U===V, U end -function _have_common_ancestor(U::AbsSpec, V::SimplifiedSpec) +function _have_common_ancestor(U::AbsAffineScheme, V::SimplifiedAffineScheme) return _have_common_ancestor(U, original(V)) end function _have_common_ancestor( - V::SimplifiedSpec, - U::AbsSpec + V::SimplifiedAffineScheme, + U::AbsAffineScheme ) return _have_common_ancestor(U, original(V)) end -function _have_common_ancestor(U::PrincipalOpenSubset, V::SimplifiedSpec) +function _have_common_ancestor(U::PrincipalOpenSubset, V::SimplifiedAffineScheme) U === V && return true, V if ambient_scheme(U) === V return true, V @@ -338,13 +338,13 @@ function _have_common_ancestor(U::PrincipalOpenSubset, V::SimplifiedSpec) end function _have_common_ancestor( - V::SimplifiedSpec, + V::SimplifiedAffineScheme, U::PrincipalOpenSubset ) return _have_common_ancestor(U, V) end -function _have_common_ancestor(U::SimplifiedSpec, V::SimplifiedSpec) +function _have_common_ancestor(U::SimplifiedAffineScheme, V::SimplifiedAffineScheme) U === V && return true, V if original(U) === V return true, V diff --git a/experimental/Schemes/SpaceGerms.jl b/experimental/Schemes/SpaceGerms.jl index a48a584a6e83..6ec9e45c0667 100644 --- a/experimental/Schemes/SpaceGerms.jl +++ b/experimental/Schemes/SpaceGerms.jl @@ -6,18 +6,18 @@ import AbstractAlgebra: Ring A space germ, i.e. a ringed space ``(X,O_{(X,x)})`` with local ring ``O_{(X,x)}`` of type `RingType` over a coefficient field ``k`` of type `BaseRingType`. """ -abstract type AbsSpaceGerm{BaseRingType<:Ring, RingType<:Ring} <: AbsSpec{BaseRingType, RingType} end +abstract type AbsSpaceGerm{BaseRingType<:Ring, RingType<:Ring} <: AbsAffineScheme{BaseRingType, RingType} end #################################################################### ## two short hand definitions for internal use only #################################################################### -GermAtClosedPoint = Spec{<:Field, - <:AbsLocalizedRing{<:Ring, <:Any, +GermAtClosedPoint = AffineScheme{<:Field, + <:AbsLocalizedRing{<:Ring, <:Any, <:MPolyComplementOfKPointIdeal} } -GermAtGeometricPoint = Spec{<:Field, - <:AbsLocalizedRing{<:Ring, <:Any, +GermAtGeometricPoint = AffineScheme{<:Field, + <:AbsLocalizedRing{<:Ring, <:Any, <:MPolyComplementOfPrimeIdeal} } @@ -26,19 +26,19 @@ GermAtGeometricPoint = Spec{<:Field, ################################################################### @doc raw""" - SpaceGerm{BaseRingType, RingType, SpecType} -A space germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme ``X`` of type SpecType and local ring ``O_{(X,x)}`` of type `RingType` over some base ring ``k`` of type `BaseRingType`. + SpaceGerm{BaseRingType, RingType, AffineSchemeType} +A space germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme ``X`` of type AffineSchemeType and local ring ``O_{(X,x)}`` of type `RingType` over some base ring ``k`` of type `BaseRingType`. """ @attributes mutable struct SpaceGerm{ BaseRingType<:Ring, RingType<:Ring, - SpecType<:Spec} <: AbsSpaceGerm{BaseRingType, RingType} - X::SpecType + AffineSchemeType<:AffineScheme} <: AbsSpaceGerm{BaseRingType, RingType} + X::AffineSchemeType function SpaceGerm(X::GermAtClosedPoint) return new{typeof(base_ring(X)), typeof(OO(X)), typeof(X)}(X) end - + ## the following one is currently unused.. function SpaceGerm(X::GermAtGeometricPoint) return new{typeof(base_ring(X)), typeof(OO(X)), typeof(X)}(X) @@ -46,15 +46,15 @@ A space germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme ``X`` end @doc raw""" - HypersurfaceGerm{BaseRingType, RingType, SpecType} + HypersurfaceGerm{BaseRingType, RingType, AffineSchemeType} -A hypersurface germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme ``X`` of type `SpecType` and local ring ``O_{(X,x)}`` of type `RingType` over some base ring ``k`` of type `BaseRingType`. +A hypersurface germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme ``X`` of type `AffineSchemeType` and local ring ``O_{(X,x)}`` of type `RingType` over some base ring ``k`` of type `BaseRingType`. """ @attributes mutable struct HypersurfaceGerm{ BaseRingType<:Ring, RingType<:Ring, - SpecType<:Spec} <: AbsSpaceGerm{BaseRingType, RingType} - X::SpecType + AffineSchemeType<:AffineScheme} <: AbsSpaceGerm{BaseRingType, RingType} + X::AffineSchemeType f::RingElem function HypersurfaceGerm(X::GermAtClosedPoint,f::MPolyLocRingElem; check::Bool=true) @@ -77,21 +77,21 @@ A hypersurface germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme end @doc raw""" - CompleteIntersectionGerm{BaseRingType, RingType, SpecType} + CompleteIntersectionGerm{BaseRingType, RingType, AffineSchemeType} -A complete intersection germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme ``X`` of type SpecType and local ring ``O_{(X,x)}`` of type `RingType` over some base ring ``k`` of type `BaseRingType`. +A complete intersection germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlying scheme ``X`` of type AffineSchemeType and local ring ``O_{(X,x)}`` of type `RingType` over some base ring ``k`` of type `BaseRingType`. """ -@attributes mutable struct CompleteIntersectionGerm{BaseRingType<:Ring, RingType<:Ring, SpecType<:Spec} <: AbsSpaceGerm{BaseRingType, RingType} - X::SpecType +@attributes mutable struct CompleteIntersectionGerm{BaseRingType<:Ring, RingType<:Ring, AffineSchemeType<:AffineScheme} <: AbsSpaceGerm{BaseRingType, RingType} + X::AffineSchemeType v::Vector{<:RingElem} function CompleteIntersectionGerm(X::GermAtClosedPoint, v::Vector{T}; check::Bool=true) where T<:MPolyLocRingElem R = base_ring(modulus(OO(X))) all(x->parent(x) == R, v) || error("base_rings do not coincide") @check begin -## TODO: change dim(Spec(R)) to dim(R) as soon as the fixes for dim have +## TODO: change dim(spec(R)) to dim(R) as soon as the fixes for dim have ## been moved to the algebra side!!!! - length(v) == dim(Spec(R)) - dim(X) || error("not a complete intersection") + length(v) == dim(spec(R)) - dim(X) || error("not a complete intersection") modulus(OO(X)) == ideal(R,v) || error("given tuple does not generate modulus") end return new{typeof(base_ring(X)), typeof(OO(X)), typeof(X)}(X,v) @@ -103,7 +103,7 @@ A complete intersection germ ``(X,O_{(X,x)}``, i.e. a ringed space with underlyi R = base_ring(OO(X)) all(x->parent(x) == R, v) || error("base_rings do not coincide") @check begin - length(v) == dim(Spec(R)) - dim(X) || error("not a complete intersection") + length(v) == dim(spec(R)) - dim(X) || error("not a complete intersection") modulus(OO(X)) == ideal(R,v) || error("given tuple does not generate modulus") end return new{typeof(base_ring(X)), typeof(OO(X)), typeof(X)}(X,v) @@ -145,7 +145,7 @@ julia> R, (x,y,z) = QQ["x", "y", "z"]; julia> I = ideal(R, [(x-1)*(x^2 - y^2 + z^2)]); -julia> X = Spec(R, I); +julia> X = spec(R, I); julia> XS = SpaceGerm(X,[0,0,0]) Spectrum @@ -181,13 +181,13 @@ Spectrum ``` """ -@attr Spec function representative(X::AnySpaceGerm) - return Spec(underlying_quotient(OO(X))) +@attr AffineScheme function representative(X::AnySpaceGerm) + return AffineScheme(underlying_quotient(OO(X))) end -@attr Spec function representative(X::SpaceGerm{<:Ring, <:MPolyLocRing}) +@attr AffineScheme function representative(X::SpaceGerm{<:Ring, <:MPolyLocRing}) R = ambient_coordinate_ring(X) - return Spec(R) + return AffineScheme(R) end @doc raw""" @@ -204,7 +204,7 @@ julia> R, (x,y,z) = QQ["x", "y", "z"]; julia> I = ideal(R, [(x-1)*(x^2 - y^2 + z^2)]); -julia> X = Spec(R, I); +julia> X = spec(R, I); julia> XS = SpaceGerm(X,[0,0,0]); @@ -250,7 +250,7 @@ julia> R, (x,y,z) = QQ["x", "y", "z"]; julia> I = ideal(R, [(x-1)*(x^2 - y^2 + z^2)]); -julia> X = Spec(R, I); +julia> X = spec(R, I); julia> XS = SpaceGerm(X,[0,0,0]); @@ -285,7 +285,7 @@ julia> R, (x,y,z) = QQ["x", "y", "z"]; julia> I = ideal(R, [(x-1)*(x^2 - y^2 + z^2)]); -julia> X = Spec(R, I); +julia> X = spec(R, I); julia> XS = HypersurfaceGerm(X,[0,0,0]) Spectrum @@ -313,7 +313,7 @@ defining_ring_elements(X::CompleteIntersectionGerm) = X.v::Vector{elem_type(loca Return the $k$-coordinates of the point corresponding to a maximal ideal $I \in k[x_1,\dots,x_n]$, which describes a $k$-point. If $I$ is not maximal -or does not describe a point with coordinates in the field $k$, an error +or does not describe a point with coordinates in the field $k$, an error exception results. # Examples @@ -349,9 +349,9 @@ end ### constructors ####################################################################################### @doc raw""" - SpaceGerm(X::AbsSpec, a::Vector{T}) where T<:Union{Integer, FieldElem} - SpaceGerm(X::AbsSpec, I:Ideal) - SpaceGerm(X::Spec(LocalRing)) + SpaceGerm(X::AbsAffineScheme, a::Vector{T}) where T<:Union{Integer, FieldElem} + SpaceGerm(X::AbsAffineScheme, I:Ideal) + SpaceGerm(X::AffineScheme(LocalRing)) SpaceGerm(A::LocalRing) Return the space germ `(X,p)` arising from the given representative `X` or the given @@ -399,18 +399,18 @@ Spectrum ``` """ -function SpaceGerm(X::AbsSpec, a::Vector{T}) where T<:Union{Integer, FieldElem} +function SpaceGerm(X::AbsAffineScheme, a::Vector{T}) where T<:Union{Integer, FieldElem} R = ambient_coordinate_ring(X) kk = coefficient_ring(R) b = [kk.(v) for v in a] ## throws an error, if vector entries are not compatible U = MPolyComplementOfKPointIdeal(R,b) - Y = Spec(localization(OO(X), U)[1]) + Y = spec(localization(OO(X), U)[1]) Z = SpaceGerm(Y) set_attribute!(Z,:representative,X) return SpaceGerm(Y) end -function SpaceGerm(X::AbsSpec, I::MPolyIdeal) +function SpaceGerm(X::AbsAffineScheme, I::MPolyIdeal) R = base_ring(I) R === ambient_coordinate_ring(X) || error("rings are not compatible") a = rational_point_coordinates(I) @@ -418,7 +418,7 @@ function SpaceGerm(X::AbsSpec, I::MPolyIdeal) return Y end -function SpaceGerm(X::AbsSpec, I::Ideal) +function SpaceGerm(X::AbsAffineScheme, I::Ideal) A = base_ring(I) A === OO(X) || error("rings are incompatible") J = saturated_ideal(I) @@ -427,21 +427,21 @@ function SpaceGerm(X::AbsSpec, I::Ideal) end @doc raw""" - SpaceGerm(X::AbsSpec, p::AbsAffineRationalPoint) + SpaceGerm(X::AbsAffineScheme, p::AbsAffineRationalPoint) SpaceGerm(p::AbsAffineRationalPoint) Return a space germ `(X,p)` for a given `X` and a rational point `p` on some affine scheme `Y`. If no `X` is specified, `Y` is used in the place of `Y`. """ SpaceGerm(p::AbsAffineRationalPoint) = SpaceGerm(codomain(p), coordinates(p)) -function SpaceGerm(X::AbsSpec, p::AbsAffineRationalPoint) +function SpaceGerm(X::AbsAffineScheme, p::AbsAffineRationalPoint) ambient_space(X) == ambient_space(codomain(p)) || error("ambient spaces do not match") return SpaceGerm(X,coordinates(p)) end @doc raw""" - HypersurfaceGerm(X::AbsSpec, a::Vector{T}) where T<:Union{Integer, FieldElem} - HypersurfaceGerm(X::AbsSpec, I:Ideal) + HypersurfaceGerm(X::AbsAffineScheme, a::Vector{T}) where T<:Union{Integer, FieldElem} + HypersurfaceGerm(X::AbsAffineScheme, I:Ideal) HypersurfaceGerm(A::LocalRing) Checks that `X` (or `Spec(A)` respectively) represents a hypersurface germ at the given @@ -452,7 +452,7 @@ may be specified in several equivalent ways: - by a maximal ideal `I` in the ambient_coordinate_ring of `X` - by the maximal ideal of the local ring `A` - HypersurfaceGerm(X::Spec(LocalRing),f::MPolyLocRingElem) + HypersurfaceGerm(X::AffineScheme(LocalRing),f::MPolyLocRingElem) This variant allows explicit specification of the generator for the hypersurface. The given `f` is checked to generate to modulus of OO(X) or A respectively. In the affirmative case, the given generator will subsequently be used by all methods explicitly accessing a generator. @@ -469,7 +469,7 @@ julia> (x,y,z) = gens(R); julia> Q,_ = quo(R,ideal(R,[x^2+y^2+z^2])); -julia> HypersurfaceGerm(Spec(Q),[0,0,0]) +julia> HypersurfaceGerm(spec(Q),[0,0,0]) Spectrum of localization of quotient @@ -480,7 +480,7 @@ Spectrum ``` """ -function HypersurfaceGerm(X::AbsSpec, a::Vector{T}) where T<:Union{Integer, FieldElem} +function HypersurfaceGerm(X::AbsAffineScheme, a::Vector{T}) where T<:Union{Integer, FieldElem} R = ambient_coordinate_ring(X) kk = coefficient_ring(R) b = [kk.(v) for v in a] ## throws an error, if vector entries are not compatible @@ -489,12 +489,12 @@ function HypersurfaceGerm(X::AbsSpec, a::Vector{T}) where T<:Union{Integer, Fiel mingens = minimal_generating_set(modulus(LX)) length(mingens) == 1 || error("not a hypersurface") f = mingens[1] - Y = HypersurfaceGerm(Spec(LX),f) + Y = HypersurfaceGerm(spec(LX),f) set_attribute!(Y,:representative,X) return Y end -function HypersurfaceGerm(X::AbsSpec, I::MPolyIdeal) +function HypersurfaceGerm(X::AbsAffineScheme, I::MPolyIdeal) R = base_ring(I) R === ambient_coordinate_ring(X) || error("rings are not compatible") a = rational_point_coordinates(I) @@ -502,7 +502,7 @@ function HypersurfaceGerm(X::AbsSpec, I::MPolyIdeal) return Y end -function HypersurfaceGerm(X::AbsSpec, I::Ideal) +function HypersurfaceGerm(X::AbsAffineScheme, I::Ideal) A = base_ring(I) A === OO(X) || error("rings are incompatible") J = saturated_ideal(I) @@ -511,21 +511,21 @@ function HypersurfaceGerm(X::AbsSpec, I::Ideal) end @doc raw""" - HypersurfaceGerm(X::AbsSpec, p::AbsAffineRationalPoint) + HypersurfaceGerm(X::AbsAffineScheme, p::AbsAffineRationalPoint) HypersurfaceGerm(p::AbsAffineRationalPoint) Return a hypersurface germ `(X,p)` for a given `X` and a rational point `p` on some scheme `Y`. If no `X` is specified, `Y` is used in its place. """ HypersurfaceGerm(p::AbsAffineRationalPoint) = HypersurfaceGerm(codomain(p), coordinates(p)) -function HypersurfaceGerm(X::AbsSpec, p::AbsAffineRationalPoint) +function HypersurfaceGerm(X::AbsAffineScheme, p::AbsAffineRationalPoint) ambient_space(X) == ambient_space(codomain(p)) || error("ambient spaces do not match") return HypersurfaceGerm(X,coordinates(p)) end @doc raw""" - CompleteIntersectionGerm(X::AbsSpec, a::Vector{T}) where T<:Union{Integer, FieldElem} - CompleteIntersectionGerm(X::AbsSpec, I:Ideal) + CompleteIntersectionGerm(X::AbsAffineScheme, a::Vector{T}) where T<:Union{Integer, FieldElem} + CompleteIntersectionGerm(X::AbsAffineScheme, I:Ideal) Checks that `X` represents a complete intersection germ at the given point `p` and returns the complete intersection germ `(X,p)` from `X` in the affirmative case, where `p` may @@ -544,7 +544,7 @@ julia> (x,y,z) = gens(R); julia> Q,_ = quo(R,ideal(R,[x^2+y^2+z^2,x*y])); -julia> CompleteIntersectionGerm(Spec(Q),[0,0,0]) +julia> CompleteIntersectionGerm(spec(Q),[0,0,0]) Spectrum of localization of quotient @@ -555,24 +555,24 @@ Spectrum ``` """ -function CompleteIntersectionGerm(X::AbsSpec, a::Vector{T}) where T<:Union{Integer, FieldElem} +function CompleteIntersectionGerm(X::AbsAffineScheme, a::Vector{T}) where T<:Union{Integer, FieldElem} R = ambient_coordinate_ring(X) kk = coefficient_ring(R) b = [kk.(v) for v in a] ## throws an error, if vector entries are not compatible U = MPolyComplementOfKPointIdeal(R,b) L,_ = localization(OO(X), U) mingens = minimal_generating_set(modulus(L)) -## TODO: Should be dim(L) and not dim(Spec(L)), but dim for localized +## TODO: Should be dim(L) and not dim(spec(L)), but dim for localized ## quotients is only repaired on the geometric side as of now!!! - SpecL = Spec(L) - length(mingens) == dim(R) - dim(SpecL) || error("not a complete intersection") + AffineSchemeL = spec(L) + length(mingens) == dim(R) - dim(AffineSchemeL) || error("not a complete intersection") w = mingens - Y = CompleteIntersectionGerm(SpecL,w) + Y = CompleteIntersectionGerm(AffineSchemeL,w) set_attribute!(Y,:representative,X) return Y end -function CompleteIntersectionGerm(X::AbsSpec, I::MPolyIdeal) +function CompleteIntersectionGerm(X::AbsAffineScheme, I::MPolyIdeal) R = base_ring(I) R === ambient_coordinate_ring(X) || error("rings are not compatible") a = rational_point_coordinates(I) @@ -580,7 +580,7 @@ function CompleteIntersectionGerm(X::AbsSpec, I::MPolyIdeal) return Y end -function ComleteIntersectionGerm(X::AbsSpec, I::Ideal) +function ComleteIntersectionGerm(X::AbsAffineScheme, I::Ideal) A = base_ring(I) A === OO(X) || error("rings are incompatible") J = saturated_ideal(I) @@ -589,21 +589,21 @@ function ComleteIntersectionGerm(X::AbsSpec, I::Ideal) end @doc raw""" - CompleteIntersectionGerm(X::AbsSpec, p::AbsAffineRationalPoint) + CompleteIntersectionGerm(X::AbsAffineScheme, p::AbsAffineRationalPoint) CompleteIntersectionGerm(p::AbsAffineRationalPoint) Return a complete intersection germ `(X,p)` for a given `X`and a rational point `p` on some affine scheme `Y`, provided that $X$ is locally a complete intersection in some neighborhood of `p`. If no `X` is specified, `Y` is used in its place. """ CompleteIntersectionGerm(p::AbsAffineRationalPoint) = CompleteIntersectionGerm(codomain(p), coordinates(p)) -function CompleteIntersectionGerm(X::AbsSpec, p::AbsAffineRationalPoint) +function CompleteIntersectionGerm(X::AbsAffineScheme, p::AbsAffineRationalPoint) ambient_space(X) == ambient_space(codomain(p)) || error("ambient spaces do not match") return CompleteIntersectionGerm(X,coordinates(p)) end @doc raw""" - germ_at_point(X::AbsSpec, I::Union{Ideal,Vector}) - germ_at_point(X::AbsSpec, I::Union{Ideal,Vector}) + germ_at_point(X::AbsAffineScheme, I::Union{Ideal,Vector}) + germ_at_point(X::AbsAffineScheme, I::Union{Ideal,Vector}) germ_at_point(A::Union{MPolyRing,MPolyQuoRing}, I::Union{Ideal,Vector}) germ_at_point(A::LocalRing, I::Union{Ideal,Vector}) @@ -653,17 +653,17 @@ given by the pullback function ``` """ -function germ_at_point(X::AbsSpec, I::Union{Ideal,Vector}) +function germ_at_point(X::AbsAffineScheme, I::Union{Ideal,Vector}) Y = SpaceGerm(X, I) restr_map = morphism(Y, X, hom(OO(X), OO(Y), gens(OO(Y)), check=false), check=false) return Y, restr_map end germ_at_point(A::Union{MPolyRing,MPolyQuoRing}, - I::Union{Ideal,Vector}) = germ_at_point(Spec(A),I) + I::Union{Ideal,Vector}) = germ_at_point(spec(A),I) @doc raw""" - germ_at_point(X::AbsSpec, p::AbsAffineRationalPoint) + germ_at_point(X::AbsAffineScheme, p::AbsAffineRationalPoint) germ_at_point(p::AbsAffineRationalPoint) Return a space germ `(X,p)` and the corresponding inclusion morphism of spectra arising @@ -672,14 +672,14 @@ from the representative `X` for a given `X` and a rational point `p` on some aff """ germ_at_point(p::AbsAffineRationalPoint) = germ_at_point(codomain(p), coordinates(p)) -function germ_at_point(X::AbsSpec, p::AbsAffineRationalPoint) +function germ_at_point(X::AbsAffineScheme, p::AbsAffineRationalPoint) ambient_space(X) == ambient_space(codomain(p)) || error("ambient spaces do not match") return germ_at_point(X,coordinates(p)) end @doc raw""" - hypersurface_germ(X::AbsSpec, I::Union{Ideal,Vector}) - hypersurface_germ(X::AbsSpec, I::Union{Ideal,Vector}) + hypersurface_germ(X::AbsAffineScheme, I::Union{Ideal,Vector}) + hypersurface_germ(X::AbsAffineScheme, I::Union{Ideal,Vector}) hypersurface_germ(A::Union{MPolyRing,MPolyQuoRing}, I::Union{Ideal,Vector}) hypersurface_germ(A::LocalRing, I::Union{Ideal,Vector}) @@ -731,34 +731,34 @@ given by the pullback function ``` """ -function hypersurface_germ(X::AbsSpec, I::Union{Ideal,Vector}) +function hypersurface_germ(X::AbsAffineScheme, I::Union{Ideal,Vector}) Y = HypersurfaceGerm(X,I) restr_map = morphism(Y, X, hom(OO(X), OO(Y), gens(OO(Y)), check=false), check=false) return Y, restr_map end hypersurface_germ(A::Union{MPolyRing,MPolyQuoRing}, - I::Union{Ideal,Vector}) = hypersurface_germ(Spec(A),I) + I::Union{Ideal,Vector}) = hypersurface_germ(spec(A),I) @doc raw""" - hypersurface_germ(X::AbsSpec, p::AbsAffineRationalPoint) + hypersurface_germ(X::AbsAffineScheme, p::AbsAffineRationalPoint) hypersurface_germ(p::AbsAffineRationalPoint) -Return a hypersurface germ `(X,p)` and the corresponding inclusion morphism of spectra for a given `X` and a rational point `p` on some affine scheme `Y`. If no `X` is specified, `Y` is used in its place. +Return a hypersurface germ `(X,p)` and the corresponding inclusion morphism of spectra for a given `X` and a rational point `p` on some affine scheme `Y`. If no `X` is specified, `Y` is used in its place. !!!note If the defining ideal of `(X,p)` is not principal. an error exception occurs. """ hypersurface_germ(p::AbsAffineRationalPoint) = hypersurface_germ(codomain(p), coordinates(p)) -function hypersurface_germ(X::AbsSpec, p::AbsAffineRationalPoint) +function hypersurface_germ(X::AbsAffineScheme, p::AbsAffineRationalPoint) ambient_space(X) == ambient_space(codomain(p)) || error("ambient spaces do not match") return hypersurface_germ(X,coordinates(p)) end @doc raw""" - complete_intersection_germ(X::AbsSpec, I::Union{Ideal,Vector}) - complete_intersection_germ(X::AbsSpec, I::Union{Ideal,Vector}) + complete_intersection_germ(X::AbsAffineScheme, I::Union{Ideal,Vector}) + complete_intersection_germ(X::AbsAffineScheme, I::Union{Ideal,Vector}) complete_intersection_germ(A::Union{MPolyRing,MPolyQuoRing}, I::Union{Ideal,Vector}) complete_intersection_germ(A::LocalRing, I::Union{Ideal,Vector}) @@ -806,17 +806,17 @@ given by the pullback function ``` """ -function complete_intersection_germ(X::AbsSpec, I::Union{Ideal,Vector}) +function complete_intersection_germ(X::AbsAffineScheme, I::Union{Ideal,Vector}) Y = CompleteIntersectionGerm(X,I) restr_map = morphism(Y, X, hom(OO(X), OO(Y), gens(OO(Y)), check=false), check=false) return Y, restr_map end complete_intersection_germ(A::Union{MPolyRing,MPolyQuoRing}, - I::Union{Ideal,Vector}) = complete_intersection_germ(Spec(A),I) + I::Union{Ideal,Vector}) = complete_intersection_germ(spec(A),I) @doc raw""" - complete_intersection_germ(X::AbsSpec, p::AbsAffineRationalPoint) + complete_intersection_germ(X::AbsAffineScheme, p::AbsAffineRationalPoint) complete_intersection_germ(p::AbsAffineRationalPoint) Return a complete intersection germ `(X,p)` and the corresponding inclusion morphism of spectra for a given `X` and a rational point `p` on some affine scheme `Y`. If no `X` is specified, `Y` is used in its place. @@ -826,7 +826,7 @@ Return a complete intersection germ `(X,p)` and the corresponding inclusion morp """ complete_intersection_germ(p::AbsAffineRationalPoint) = hypersurface_germ(codomain(p), coordinates(p)) -function complete_intersection_germ(X::AbsSpec, p::AbsAffineRationalPoint) +function complete_intersection_germ(X::AbsAffineScheme, p::AbsAffineRationalPoint) ambient_space(X) == ambient_space(codomain(p)) || error("ambient spaces do not match") return complete_intersection_germ(X,coordinates(p)) end @@ -836,26 +836,26 @@ end ######################################################################################### const LocalRing = Union{ - MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, + MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyComplementOfKPointIdeal}, - MPolyLocRing{<:Any, <:Any, <:Any, <:Any, + MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyComplementOfKPointIdeal}, - MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, + MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyComplementOfPrimeIdeal}, - MPolyLocRing{<:Any, <:Any, <:Any, <:Any, + MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyComplementOfPrimeIdeal} } function SpaceGerm(A::LocalRing) - return SpaceGerm(Spec(A)) + return SpaceGerm(spec(A)) end function HypersurfaceGerm(A::LocalRing) I = modulus(A) v = minimal_generating_set(I) length(v) == 1 || error("not a hypersurface germ") - return HypersurfaceGerm(Spec(A),v[1]) + return HypersurfaceGerm(spec(A),v[1]) end function CompleteIntersectionGerm(A::LocalRing) @@ -863,7 +863,7 @@ function CompleteIntersectionGerm(A::LocalRing) !iszero(I) || error("zero ideal not allowed for complete intersection germ") v = minimal_generating_set(I) length(v) == dim(base_ring(I)) - dim(A) || error("not a complete intersection germ") - return CompleteIntersectionGerm(Spec(A),v) + return CompleteIntersectionGerm(spec(A),v) end ## and with identity map to keep usage consistent @@ -888,8 +888,8 @@ end ### basic functionality for space germs ############################################################################## -# note: ==, issubset are basically inherited from Spec -# intersect uses explicit fallback to Spec and adjusted return types +# note: ==, issubset are basically inherited from AffineScheme +# intersect uses explicit fallback to AffineScheme and adjusted return types # union uses explicit fallback and adjusted return types ############################################################################## #@doc raw""" @@ -956,9 +956,9 @@ julia> Q1,_ = quo(R,ideal(R,[x*y])); julia> Q2,_ = quo(R,ideal(R,[x*(x-y)])); -julia> X1 = HypersurfaceGerm(Spec(Q1),[0,0,0]); +julia> X1 = HypersurfaceGerm(spec(Q1),[0,0,0]); -julia> X2 = HypersurfaceGerm(Spec(Q2),[0,0,0]); +julia> X2 = HypersurfaceGerm(spec(Q2),[0,0,0]); julia> union(X1,X2) Spectrum @@ -992,17 +992,17 @@ function Base.union(X::HypersurfaceGerm, Y::HypersurfaceGerm) # otherwise 'point' is not implemented f_new = numerator(defining_ring_element(X))*numerator(defining_ring_element(Y)) f_new = radical(ideal(R,[f_new]))[1] - Y = HypersurfaceGerm(Spec(quo(R,ideal(R,f_new))[1]), point(X)) + Y = HypersurfaceGerm(spec(quo(R,ideal(R,f_new))[1]), point(X)) Y.f = f_new return Y end ############################################################################## -# note: singular_locus, is_smooth and is_regular are inherited from Spec +# note: singular_locus, is_smooth and is_regular are inherited from AffineScheme ############################################################################## # We want the singular locus of an `AbsSpaceGerm` to be a `SpaceGerm` again and -# not a plain `Spec`. +# not a plain `AffineScheme`. @doc raw""" singular_locus(X::AbsSpaceGerm) --> SpaceGerm, ClosedEmbedding @@ -1018,7 +1018,7 @@ julia> (x,y,z) = gens(R); julia> Q,_ = quo(R,ideal(R,[x^2+y^2])); -julia> Y = SpaceGerm(Spec(Q),[0,0,0]); +julia> Y = SpaceGerm(spec(Q),[0,0,0]); julia> XSL, incSL = singular_locus(Y); @@ -1077,7 +1077,7 @@ julia> (x,y,z) = gens(R); julia> Q,_ = quo(R,ideal(R,[x^2+y^2])); -julia> Y = SpaceGerm(Spec(Q),[0,0,0]); +julia> Y = SpaceGerm(spec(Q),[0,0,0]); julia> is_isolated_singularity(Y) false @@ -1130,7 +1130,7 @@ function milnor_number(X::CompleteIntersectionGerm) while !is_empty(v) found = false ## keep track of 'colength condition satisfied?' - ## run through the potential choices, until colength condition satisfied + ## run through the potential choices, until colength condition satisfied for f in v ## note: although we have already moved to polynomial data, we need to ## hand localized ring to helper to ensure shift to origin @@ -1183,11 +1183,11 @@ function _icis_milnor_helper(L::MPolyLocRing, v::Vector,f::RingElem) end @doc raw""" - milnor_algebra(X::Spec{<:Field,<:MPolyQuoRing}) + milnor_algebra(X::AffineScheme{<:Field,<:MPolyQuoRing}) Return the global milnor algebra of the affine hypersurface `X`. If `X` is not a hypersurface, an error occurs. """ -function milnor_algebra(X::Spec{<:Field,<:MPolyQuoRing}) +function milnor_algebra(X::AffineScheme{<:Field,<:MPolyQuoRing}) R = base_ring(OO(X)) ngens(modulus(OO(X))) == 1 || error("not a hypersurface (or unnecessary generators in specified generating set)") v = gen(modulus(OO(X)),1) @@ -1196,11 +1196,11 @@ function milnor_algebra(X::Spec{<:Field,<:MPolyQuoRing}) end @doc raw""" - milnor_number(X::Spec{<:Field,<:MPolyQuoRing}) + milnor_number(X::AffineScheme{<:Field,<:MPolyQuoRing}) Return the global milnor number of the affine hypersurface or complete intersection `X`. If `X` is neither of the two, an error occurs. """ -function milnor_number(X::Spec{<:Field,<:MPolyQuoRing}) +function milnor_number(X::AffineScheme{<:Field,<:MPolyQuoRing}) R = base_ring(OO(X)) v = gens(modulus(OO(X))) if length(v) == 1 @@ -1233,7 +1233,7 @@ function milnor_number(X::Spec{<:Field,<:MPolyQuoRing}) return -dims end -## internal helper for the summands in the Le-Greuel formula -- global case +## internal helper for the summands in the Le-Greuel formula -- global case function _icis_milnor_helper(v::Vector,f::MPolyRingElem) R = parent(f) all(a-> parent(a) == R,v) || error("base rings do not match") diff --git a/experimental/Schemes/ToricIdealSheaves/constructors.jl b/experimental/Schemes/ToricIdealSheaves/constructors.jl index 3de0c6ec2a16..ce976dd458fa 100644 --- a/experimental/Schemes/ToricIdealSheaves/constructors.jl +++ b/experimental/Schemes/ToricIdealSheaves/constructors.jl @@ -56,7 +56,7 @@ function IdealSheaf(X::NormalToricVariety, I::MPolyIdeal) @req is_smooth(X) "Currently, ideal sheaves are only supported for smooth toric varieties" @req is_pure(X) "Currently, ideal sheaves require that all maximal cones have the dimension of the variety" - ideal_dict = IdDict{AbsSpec, Ideal}() + ideal_dict = IdDict{AbsAffineScheme, Ideal}() # We need to dehomogenize the ideal I in the Cox ring S to the local # charts U_sigma, with sigma a cone in the fan of the variety. @@ -157,7 +157,7 @@ function ideal_sheaf(X::NormalToricVariety, tau::Cone) #tau_perp = polarize(tau) @show rays(tau_perp) @show lineality_space(tau_perp) - ideal_dict = IdDict{AbsSpec, Ideal}() + ideal_dict = IdDict{AbsAffineScheme, Ideal}() # We are using Equation (3.2.7) in CLS to determine the local # form of the ideal. for U in affine_charts(X) diff --git a/experimental/Schemes/Types.jl b/experimental/Schemes/Types.jl index 632284775f9d..8e22f1f19c50 100644 --- a/experimental/Schemes/Types.jl +++ b/experimental/Schemes/Types.jl @@ -15,17 +15,17 @@ export VarietyFunctionFieldElem mutable struct VarietyFunctionField{BaseRingType<:Field, FracFieldType<:AbstractAlgebra.Generic.FracField, CoveredSchemeType<:AbsCoveredScheme, - SpecType<:AbsSpec + AffineSchemeType<:AbsAffineScheme } <: Field kk::BaseRingType X::CoveredSchemeType - U::SpecType # representative patch to represent rational functions + U::AffineSchemeType # representative patch to represent rational functions KK::FracFieldType function VarietyFunctionField( X::AbsCoveredScheme; check::Bool=true, - representative_patch::AbsSpec=default_covering(X)[1] + representative_patch::AbsAffineScheme=default_covering(X)[1] ) @check is_irreducible(X) "variety is not irreducible" representative_patch in default_covering(X) || error("representative patch not found") @@ -116,7 +116,7 @@ A basic minimal implementation of the interface for `AbsPreSheaf`; to be used in restriction_func::Function # To produce the restriction maps ℱ(U) → ℱ(V) for V ⊂ U ⊂ X open function PreSheafOnScheme(X::Scheme, production_func::Any, restriction_func::Any; - OpenType=AbsSpec, OutputType=Any, RestrictionType=Any, + OpenType=AbsAffineScheme, OutputType=Any, RestrictionType=Any, is_open_func::Any=is_open_embedding ) return new{typeof(X), OpenType, OutputType, RestrictionType, @@ -130,13 +130,13 @@ end ######################################################################## # Simplified Spectra # ######################################################################## -@attributes mutable struct SimplifiedSpec{BaseRingType, RingType<:Ring} <: AbsSpec{BaseRingType, RingType} - X::AbsSpec - Y::AbsSpec - f::AbsSpecMor - g::AbsSpecMor +@attributes mutable struct SimplifiedAffineScheme{BaseRingType, RingType<:Ring} <: AbsAffineScheme{BaseRingType, RingType} + X::AbsAffineScheme + Y::AbsAffineScheme + f::AbsAffineSchemeMor + g::AbsAffineSchemeMor - function SimplifiedSpec(X::AbsSpec, Y::AbsSpec, f::AbsSpecMor, g::AbsSpecMor; + function SimplifiedAffineScheme(X::AbsAffineScheme, Y::AbsAffineScheme, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; check::Bool=true ) domain(f) === X || error("map is not compatible") @@ -169,9 +169,9 @@ regular functions on ``X``. Note that due to technical reasons, the admissible open subsets are restricted to the following: - * `U::AbsSpec` among the `basic_patches` of the `default_covering` of `X`; + * `U::AbsAffineScheme` among the `basic_patches` of the `default_covering` of `X`; * `U::PrincipalOpenSubset` with `ambient_scheme(U)` in the `basic_patches` of the `default_covering` of `X`; - * `W::SpecOpen` with `ambient_scheme(W)` in the `basic_patches` of the `default_covering` of `X`. + * `W::AffineSchemeOpenSubscheme` with `ambient_scheme(W)` in the `basic_patches` of the `default_covering` of `X`. One can call the restriction maps of ``𝒪`` across charts, implicitly using the identifications given by the gluings in the `default_covering`. @@ -185,48 +185,48 @@ identifications given by the gluings in the `default_covering`. OO::PreSheafOnScheme ### Structure sheaf on affine schemes - function StructureSheafOfRings(X::AbsSpec) - function is_open_func(U::AbsSpec, V::AbsSpec) + function StructureSheafOfRings(X::AbsAffineScheme) + function is_open_func(U::AbsAffineScheme, V::AbsAffineScheme) return is_subset(V, X) && is_open_embedding(U, V) # Note the restriction to subsets of X end - function production_func(F::AbsPreSheaf, U::AbsSpec) + function production_func(F::AbsPreSheaf, U::AbsAffineScheme) return OO(U) end - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) OU = F(U) # assumed to be previously cached OV = F(V) # same as above return hom(OV, OU, gens(OU), check=false) # check=false assures quicker computation end R = PreSheafOnScheme(X, production_func, restriction_func, - OpenType=AbsSpec, OutputType=Ring, + OpenType=AbsAffineScheme, OutputType=Ring, RestrictionType=Map, is_open_func=is_open_func ) - return new{typeof(X), Union{AbsSpec, SpecOpen}, Ring, Map}(R) + return new{typeof(X), Union{AbsAffineScheme, AffineSchemeOpenSubscheme}, Ring, Map}(R) end ### Structure sheaf on covered schemes function StructureSheafOfRings(X::AbsCoveredScheme) ### Production of the rings of regular functions; to be cached - function production_func(F::AbsPreSheaf, U::AbsSpec) + function production_func(F::AbsPreSheaf, U::AbsAffineScheme) return OO(U) end - function production_func(F::AbsPreSheaf, U::SpecOpen) + function production_func(F::AbsPreSheaf, U::AffineSchemeOpenSubscheme) return OO(U) end ### Production of the restriction maps; to be cached - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) V === U || error("basic affine patches must be the same") return identity_map(OO(V)) end function restriction_func( F::AbsPreSheaf, - V::AbsSpec, - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + V::AbsAffineScheme, + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) OV = F(V) # Assumed to be cached or produced on the fly. OU = F(U) # Same as above. @@ -252,8 +252,8 @@ identifications given by the gluings in the `default_covering`. end function restriction_func(F::AbsPreSheaf, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - U::AbsSpec + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + U::AbsAffineScheme ) OV = F(V) OU = F(U) @@ -267,7 +267,7 @@ identifications given by the gluings in the `default_covering`. return hom(OV, OU, psi.(phi.(gens(OV)))) ### deprecated code below; # kept for the moment because of possible incompatibilities with gluings - # along SpecOpens. + # along AffineSchemeOpenSubschemes. function rho_func(a::RingElem) parent(a) === OV || error("element does not belong to the correct ring") # We may assume that all denominators admissible in V are @@ -290,8 +290,8 @@ identifications given by the gluings in the `default_covering`. end end function restriction_func(F::AbsPreSheaf, - V::Union{<:PrincipalOpenSubset, <:SimplifiedSpec}, - U::Union{<:PrincipalOpenSubset, <:SimplifiedSpec} + V::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme}, + U::Union{<:PrincipalOpenSubset, <:SimplifiedAffineScheme} ) OV = F(V) OU = F(U) @@ -326,7 +326,7 @@ identifications given by the gluings in the `default_covering`. error("arguments are invalid") end - function restriction_func(F::AbsPreSheaf, V::AbsSpec, W::SpecOpen) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, W::AffineSchemeOpenSubscheme) OV = F(V) OW = F(W) V in default_covering(X) || return false @@ -345,10 +345,10 @@ identifications given by the gluings in the `default_covering`. end ### cleaned up until here ### - # We do not make SpecOpen compatible with the tree structures, yet. - # All SpecOpen's are hence required to have an ambient_scheme on the top level. + # We do not make AffineSchemeOpenSubscheme compatible with the tree structures, yet. + # All AffineSchemeOpenSubscheme's are hence required to have an ambient_scheme on the top level. - function restriction_func(F::AbsPreSheaf, V::PrincipalOpenSubset, W::SpecOpen) + function restriction_func(F::AbsPreSheaf, V::PrincipalOpenSubset, W::AffineSchemeOpenSubscheme) error("method not implemented at the moment") OV = F(V) OW = F(W) @@ -372,7 +372,7 @@ identifications given by the gluings in the `default_covering`. return MapFromFunc(OV, OW, rho_func2) end end - function restriction_func(F::AbsPreSheaf, V::SpecOpen, W::SpecOpen) + function restriction_func(F::AbsPreSheaf, V::AffineSchemeOpenSubscheme, W::AffineSchemeOpenSubscheme) OV = F(V) OW = F(W) if ambient_scheme(V) === ambient_scheme(W) @@ -391,11 +391,11 @@ identifications given by the gluings in the `default_covering`. end R = PreSheafOnScheme(X, production_func, restriction_func, - OpenType=Union{AbsSpec, SpecOpen}, OutputType=Ring, + OpenType=Union{AbsAffineScheme, AffineSchemeOpenSubscheme}, OutputType=Ring, RestrictionType=Map, is_open_func=_is_open_func_for_schemes(X) ) - return new{typeof(X), Union{AbsSpec, SpecOpen}, Ring, Map}(R) + return new{typeof(X), Union{AbsAffineScheme, AffineSchemeOpenSubscheme}, Ring, Map}(R) end end @@ -409,7 +409,7 @@ A sheaf of ideals ``ℐ`` on an `AbsCoveredScheme` ``X``. Note that due to technical reasons, the admissible open subsets are restricted to the following: - * `U::AbsSpec` among the `basic_patches` of the `default_covering` of `X`; + * `U::AbsAffineScheme` among the `basic_patches` of the `default_covering` of `X`; * `U::PrincipalOpenSubset` with `ambient_scheme(U)` in the `basic_patches` of the `default_covering` of `X`. One can call the restriction maps of ``ℐ`` across charts, implicitly using the @@ -421,17 +421,17 @@ identifications given by the gluings in the `default_covering`. SpaceType, OpenType, OutputType, RestrictionType } - ID::IdDict{AbsSpec, Ideal} # the ideals on the patches of some covering of X + ID::IdDict{AbsAffineScheme, Ideal} # the ideals on the patches of some covering of X OOX::StructureSheafOfRings # the structure sheaf on X I::PreSheafOnScheme # the underlying presheaf of ideals for caching ### Ideal sheaves on covered schemes - function IdealSheaf(X::AbsCoveredScheme, ID::IdDict{AbsSpec, Ideal}; + function IdealSheaf(X::AbsCoveredScheme, ID::IdDict{AbsAffineScheme, Ideal}; check::Bool=true ) OOX = StructureSheafOfRings(X) - function production_func(F::AbsPreSheaf, U::AbsSpec) + function production_func(F::AbsPreSheaf, U::AbsAffineScheme) # If U is an affine chart on which the ideal has already been described, take that. haskey(ID, U) && return ID[U] # Transferring from another chart did not work. That means @@ -440,9 +440,9 @@ identifications given by the gluings in the `default_covering`. # and assemble the ideal from there. V = [W for W in keys(ID) if has_ancestor(x->(x===U), W)] # gather all patches under U - # Check for some SimplifiedSpec lurking around - if any(x->(x isa SimplifiedSpec), V) - i = findfirst(x->(x isa SimplifiedSpec), V) + # Check for some SimplifiedAffineScheme lurking around + if any(x->(x isa SimplifiedAffineScheme), V) + i = findfirst(x->(x isa SimplifiedAffineScheme), V) W = V[i] _, g = identification_maps(W) return ideal(OO(U), pullback(g).(gens(ID[W]))) @@ -466,9 +466,9 @@ identifications given by the gluings in the `default_covering`. if !is_open_func(F)(V, space(F)) V = [W for W in keys(ID) if has_ancestor(x->(x===U), W)] # gather all patches under U - # Check for some SimplifiedSpec lurking around - if any(x->(x isa SimplifiedSpec), V) - i = findfirst(x->(x isa SimplifiedSpec), V) + # Check for some SimplifiedAffineScheme lurking around + if any(x->(x isa SimplifiedAffineScheme), V) + i = findfirst(x->(x isa SimplifiedAffineScheme), V) W = V[i] _, g = identification_maps(W) return ideal(OO(U), pullback(g).(gens(ID[W]))) @@ -490,7 +490,7 @@ identifications given by the gluings in the `default_covering`. IU = ideal(OO(U), rho.(gens(IV))) return IU end - function production_func(F::AbsPreSheaf, U::SimplifiedSpec) + function production_func(F::AbsPreSheaf, U::SimplifiedAffineScheme) haskey(ID, U) && return ID[U] V = original(U) # In case the original is leading out of the admissible domain, @@ -498,9 +498,9 @@ identifications given by the gluings in the `default_covering`. if !is_open_func(F)(V, space(F)) V = [W for W in keys(ID) if has_ancestor(x->(x===U), W)] # gather all patches under U - # Check for some SimplifiedSpec lurking around - if any(x->(x isa SimplifiedSpec), V) - i = findfirst(x->(x isa SimplifiedSpec), V) + # Check for some SimplifiedAffineScheme lurking around + if any(x->(x isa SimplifiedAffineScheme), V) + i = findfirst(x->(x isa SimplifiedAffineScheme), V) W = V[i] _, g = identification_maps(W) return ideal(OO(U), pullback(g).(gens(ID[W]))) @@ -523,18 +523,18 @@ identifications given by the gluings in the `default_covering`. end ### Production of the restriction maps; to be cached - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) return OOX(V, U) # This does not check containment of the arguments # in the ideal. But this is not a parent check and # hence expensive, so we might want to not do that. end Ipre = PreSheafOnScheme(X, production_func, restriction_func, - OpenType=AbsSpec, OutputType=Ideal, + OpenType=AbsAffineScheme, OutputType=Ideal, RestrictionType=Map, - is_open_func=_is_open_func_for_schemes_without_specopen(X) + is_open_func=_is_open_func_for_schemes_without_affine_scheme_open_subscheme(X) ) - I = new{typeof(X), AbsSpec, Ideal, Map}(ID, OOX, Ipre) + I = new{typeof(X), AbsAffineScheme, Ideal, Map}(ID, OOX, Ipre) @check begin # Check that all ideal sheaves are compatible on the overlaps. # TODO: eventually replace by a check that on every basic diff --git a/experimental/Schemes/WeilDivisor.jl b/experimental/Schemes/WeilDivisor.jl index eed77eab164f..3d06a4e3d688 100644 --- a/experimental/Schemes/WeilDivisor.jl +++ b/experimental/Schemes/WeilDivisor.jl @@ -100,7 +100,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P, I); +julia> Y = proj(P, I); julia> Ycov = covered_scheme(Y); @@ -134,7 +134,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P); +julia> Y = proj(P); julia> II = IdealSheaf(Y, I); @@ -415,7 +415,7 @@ end function colength(I::IdealSheaf; covering::Covering=default_covering(scheme(I))) X = scheme(I) patches_todo = copy(patches(covering)) - patches_done = AbsSpec[] + patches_done = AbsAffineScheme[] result = 0 while length(patches_todo) != 0 U = pop!(patches_todo) @@ -485,7 +485,7 @@ function in_linear_system(f::VarietyFunctionFieldElem, D::AbsWeilDivisor; regula # we have to check that f[U] has no poles outside the support of D[U] J = intersect([J(U) for J in components(D)]) incH = ClosedEmbedding(U, J) - W = complement(incH) # This is a SpecOpen + W = complement(incH) # This is a AffineSchemeOpenSubscheme is_regular(f, W) || return false end return true diff --git a/experimental/Schemes/duValSing.jl b/experimental/Schemes/duValSing.jl index 8184ad9c5c01..5838df813b9e 100644 --- a/experimental/Schemes/duValSing.jl +++ b/experimental/Schemes/duValSing.jl @@ -16,7 +16,7 @@ Ideal generated by julia> Rq, _ = quo(R,I) (Quotient of multivariate polynomial ring by ideal (w, x^2 + y^3 + z^4), Map: multivariate polynomial ring -> Rq) -julia> X = Spec(Rq) +julia> X = spec(Rq) Spectrum of quotient of multivariate polynomial ring in 4 variables x, y, z, w @@ -32,10 +32,10 @@ function has_du_val_singularities(X::AbsProjectiveScheme{<:Field,<:Any}) return has_du_val_singularities(covered_scheme(X)) end -function has_du_val_singularities(X::AbsSpec{<:Field,<:Any}) +function has_du_val_singularities(X::AbsAffineScheme{<:Field,<:Any}) R = OO(X) I = modulus(R) - + J = image_ideal(singular_locus(X)[2]) J = ideal(base_ring(I), lift.(gens(J))) + I dim(J) == 0 || return false ## non-isolated @@ -61,7 +61,7 @@ function has_du_val_singularities(X::AbsCoveredScheme{<:Field}) end @doc raw""" - is_du_val_singularity(X::AbsSpec, I::Ideal) + is_du_val_singularity(X::AbsAffineScheme, I::Ideal) Return whether the given ``X`` has at most du Val (surface) singularities at the geometric points specified by the ideal ``I``. @@ -87,7 +87,7 @@ Ideal generated by z w -julia> X = Spec(Rq) +julia> X = spec(Rq) Spectrum of quotient of multivariate polynomial ring in 4 variables x, y, z, w @@ -99,7 +99,7 @@ true ``` """ -function is_du_val_singularity(X::AbsSpec{<:Field,<:Any},I::Ideal) +function is_du_val_singularity(X::AbsAffineScheme{<:Field,<:Any},I::Ideal) OOX = OO(X) dim(X) == 2 || error("Scheme not of dimension 2") J = modulus(OOX) @@ -124,14 +124,14 @@ function is_du_val_singularity(X::AbsSpec{<:Field,<:Any},I::Ideal) r_changed = base_ring(I2) kk = coefficient_ring(r_changed) J_changed = ideal(r_changed, [change_coefficient_ring(kk,a, parent = r_changed) for a=gens(J)]) - is_du_val_singularity(Spec(quo(r_changed,J_changed)[1]),I2) || return false + is_du_val_singularity(spec(quo(r_changed,J_changed)[1]),I2) || return false end - + return true end @doc raw""" - decide_du_val_singularity(X::AbsSpec, I::Ideal) + decide_du_val_singularity(X::AbsAffineScheme, I::Ideal) Return a vector of tuples ``T`` with the following data: - `T[1]::Bool` answers whether ``X`` has at most du Val (surface) singularities at the geometric points specified by the ideal ``I``. @@ -167,7 +167,7 @@ Ideal generated by z w -julia> X = Spec(Rq) +julia> X = spec(Rq) Spectrum of quotient of multivariate polynomial ring in 4 variables x, y, z, w @@ -178,8 +178,8 @@ julia> decide_du_val_singularity(X,J) 1-element Vector{Any}: (true, Ideal (w, z, y, x), (:E, 6), 1) ``` -""" -function decide_du_val_singularity(X::AbsSpec{<:Field,<:Any},I::MPolyIdeal) +""" +function decide_du_val_singularity(X::AbsAffineScheme{<:Field,<:Any},I::MPolyIdeal) OOX = OO(X) dim(X) == 2 || error("Scheme not of dimension 2") J = modulus(OOX) @@ -205,7 +205,7 @@ function decide_du_val_singularity(X::AbsSpec{<:Field,<:Any},I::MPolyIdeal) r_changed = base_ring(I2) kk = coefficient_ring(r_changed) J_changed = ideal(r_changed, [change_coefficient_ring(kk,a, parent = r_changed) for a=gens(J)]) - tempvec = decide_du_val_singularity(Spec(quo(r_changed,J_changed)[1]),I2) + tempvec = decide_du_val_singularity(spec(quo(r_changed,J_changed)[1]),I2) for x in tempvec x[1] || return [x] x = (x[1],x[2],x[3],mult) @@ -233,7 +233,7 @@ function _check_duval_at_point(IX::Ideal,Ipt::Ideal) R == base_ring(Ipt) || error("basering mismatch") kk = base_ring(R) characteristic(kk) == 0 || error("only available in characteristic zero") - + JM = jacobian_matrix(gens(IX)) smooth = (:A,0) @@ -262,10 +262,10 @@ function _check_duval_at_point(IX::Ideal,Ipt::Ideal) F1 = leading_module(Jm_shifted,o) F1quo = quo(F_shifted, F1)[1] - constant_mons = vector_space_dimension(F1quo,0) + constant_mons = vector_space_dimension(F1quo,0) constant_mons < 2 || return (false, typeof(smooth)) ## not a hypersurface constant_mons > 0 || return (true, smooth) ## no singularity - + tau = vector_space_dimension(F1quo) corank = vector_space_dimension(F1quo,1) diff --git a/experimental/Schemes/elliptic_surface.jl b/experimental/Schemes/elliptic_surface.jl index c3a39cebb8ed..d4e926026435 100644 --- a/experimental/Schemes/elliptic_surface.jl +++ b/experimental/Schemes/elliptic_surface.jl @@ -20,7 +20,7 @@ For now functionality is restricted to $C = \mathbb{P}^1$. E::EllipticCurve{BaseCurveFieldType} MWL::Vector{EllipticCurvePoint{BaseCurveFieldType}} # basis for the mordell weil group MWLtors::Vector{EllipticCurvePoint{BaseCurveFieldType}} # torsion sections - Weierstrasschart::AbsSpec + Weierstrasschart::AbsAffineScheme Weierstrassmodel::CoveredScheme inc_Weierstrass::CoveredClosedEmbedding # inclusion of the weierstrass chart in its ambient projective bundle inc_Y::CoveredClosedEmbedding # inclusion of Y in its ambient blown up projective bundle @@ -377,7 +377,7 @@ function _separate_singularities!(X::EllipticSurface) # Refine the covering over the reducible singular fibers # to make sure that there is only a single singular point in each chart - refined_charts = AbsSpec[] + refined_charts = AbsAffineScheme[] U = P[1][1] # the weierstrass_chart IsingU = I_sing_P(U)::MPolyIdeal if isone(IsingU) @@ -778,7 +778,7 @@ Return the fiber of $\pi\colon X \to C$ over $P\in C$ as a Cartier divisor. function fiber_cartier(S::EllipticSurface, P::Vector = ZZ.([0,1])) S0,_ = weierstrass_model(S) underlying_scheme(S) # cache stuff - D = IdDict{AbsSpec, RingElem}() + D = IdDict{AbsAffineScheme, RingElem}() k = base_ring(S0) P = k.(P) diff --git a/experimental/SymmetricIntersections/src/representations.jl b/experimental/SymmetricIntersections/src/representations.jl index 10615d90451a..2f4982e702b1 100644 --- a/experimental/SymmetricIntersections/src/representations.jl +++ b/experimental/SymmetricIntersections/src/representations.jl @@ -178,7 +178,7 @@ function character_representation(RR::RepRing{S, T}, f::GAPGroupHomomorphism{T, Q = abelian_closure(QQ)[1] coll = elem_type(Q)[] H = conjugacy_classes(underlying_group(RR)) - # Any representation rho affords the character e -> trace(rho(e)) + # Any representation rho affords the character e -> trace(rho(e)) for h in H b = f(representative(h)) push!(coll, Q(trace(b))) @@ -265,12 +265,12 @@ Given a character `chi` and an integer `t`, return all the constituents of function constituents(chi::Oscar.GAPGroupClassFunction, t::Int) @req is_character(chi) "chi should be a character" @req t >= 0 "t must be non negative" - + # sort of fallback when t = degree(chi) if t == 0 return typeof(chi)[zero(chi)] end - + # constituents of degree t in chi corresponds bijectively to their # complement which are of degree degree(chi)-t. So to do the smallest # computations, we always reduce to the case t <= floor(degree(chi)/2) @@ -278,15 +278,15 @@ function constituents(chi::Oscar.GAPGroupClassFunction, t::Int) els = constituents(chi, Int(degree(chi)) - t) return typeof(chi)[chi-nu for nu in els] end - + cd = character_decomposition(chi) L = [c[2] for c in cd] ubs = [c[1] for c in cd] - + function _deg(x::Oscar.GAPGroupClassFunction) return ZZ(degree(x)) end - + # _deg(L) represents the degree of all irreducible constituents of chi, # and ubs keeps track of their multiplicities in chi. So that we return # all the t-elevations of (L, _deg) where we impose some upper bound @@ -370,7 +370,7 @@ If not provided, `chi` is automatically computed. """ function linear_representation(RR::RepRing{S, T}, f::GAPGroupHomomorphism, chi::Oscar.GAPGroupClassFunction) where {S, T} @req parent(chi) === character_table_underlying_group(RR) "Character should belong to the character table attached to the given representation ring" - @req domain(f) === underlying_group(RR) "f should be defined over the underlying group of the given representation ring" + @req domain(f) === underlying_group(RR) "f should be defined over the underlying group of the given representation ring" @req codomain(f) isa MatrixGroup "f should take value in a matrix group" return LinRep{S, T, elem_type(S)}(RR, f, chi) end @@ -494,7 +494,7 @@ function irreducible_affording_representation(RR::RepRing{S, T}, chi::Oscar.GAPG else irr_rep = Dict{Oscar.GAPGroupClassFunction, LinRep{S, T, elem_type(S)}}() end - haskey(irr_rep, chi) && return irr_rep[chi] + haskey(irr_rep, chi) && return irr_rep[chi] F = base_field(RR) # we use F and H to make the translation between the representation @@ -505,7 +505,7 @@ function irreducible_affording_representation(RR::RepRing{S, T}, chi::Oscar.GAPG rep = GG.IrreducibleAffordingRepresentation(chi.values)::GAP.GapObj # we compute certain images than we will convert then. - # we use them then to construct the mapping in + # we use them then to construct the mapping in # `_linear_representation` _Mat = GAP.GapObj[GG.Image(rep, h.X) for h in H] Mat = AbstractAlgebra.Generic.MatSpaceElem{elem_type(F)}[] @@ -535,7 +535,7 @@ function affording_representation(RR::RepRing{S, T}, chi::Oscar.GAPGroupClassFun cd = character_decomposition(chi) # The blocks for the block diagonal representation. The - # easiest way for us is to start by looking at the + # easiest way for us is to start by looking at the # irreducible constituents of chi and their multiplicities # and then we take the direct sum of the corresponding # irreducible affording representations with the given multiplicities @@ -711,7 +711,7 @@ end @doc raw""" is_isotypical_component(rep::T, rep2::T) where T <: LinRep -> Bool is_isotypical_component(prep::T, prep2::T) where T <: ProjRep -> Bool - + Given two linear representations `rep` and `rep2` into the same representation ring `RR` of the finite group `E` over the field `F`, return whether the abstract `FE`-module represented by `rep2` is an isotypical component of @@ -834,10 +834,10 @@ end """ A bunch of operations on symmetric/anti-symmetric tensors. """ -function _change_basis(w, basis::Vector{Vector{T}}) where T - @req length(w) == length(basis) "Change of basis impossible" +function _change_basis(w, basis::Vector{Vector{T}}) where T + @req length(w) == length(basis) "Change of basis impossible" gene = Tuple{eltype(w), eltype(basis)}[(w[i], basis[i]) for i =1:length(w) if !iszero(w[i])] - return gene + return gene end function _decompose_in_standard_basis(v) @@ -1151,7 +1151,7 @@ end basis_isotypical_component(rep::LinRep{S, T, U}, chi::Oscar.GAPGroupClassFunction) where {S, T, U} -> Vector{MatElem{U}} - + Given an irreducible character `chi` which is constituent of the character of `rep`, return a basis for the isotypical component of `rep` associated to `chi`. The output is a set of bases each of them corresponding to a copy of a module @@ -1175,7 +1175,7 @@ end where {S, T, U} -> LinRep{S, T, U}, MatElem{U} to_equivalent_block_representation(rep::ProjRep{S, T, U, V}) where {S, T, U, V} -> ProjRep(S, T, U, V}, MatElem{U} - + Given a linear representation `rep` of a group, return an equivalent representation `rep2` whose matrix representation is given by block in the irreducible subrepresentations of `rep`, together with the matrix of change of @@ -1235,7 +1235,7 @@ end @doc raw""" action_on_submodule(rep::LinRep{S, T, U}, M::W) where {S, T, U, W <: MatElem{U}} -> LinRep{S, T, U} - + Given a matrix `M` whose rows define the coordinates of a submodule of `rep` in the standard basis of the underlying vector space of `rep`, return the induced action on the submodule defined by `M`, as a linear representation in the diff --git a/experimental/SymmetricIntersections/src/symmetric_grassmannians.jl b/experimental/SymmetricIntersections/src/symmetric_grassmannians.jl index f528f6961747..ad1289104980 100644 --- a/experimental/SymmetricIntersections/src/symmetric_grassmannians.jl +++ b/experimental/SymmetricIntersections/src/symmetric_grassmannians.jl @@ -500,7 +500,7 @@ function _intersection_with_grassmannian(V::Vector{T}, n::Int, t::Int; S, _ = graded_polynomial_ring(F, "x" => 0:binomial(n, t)-1) end - X = projective_scheme(S) + X = proj(S) if t == 1 ideal_Gr = ideal(S, elem_type(S)[zero(S)]) else diff --git a/experimental/SymmetricIntersections/test/runtests.jl b/experimental/SymmetricIntersections/test/runtests.jl index b7841bcdeec7..4da8dd235178 100644 --- a/experimental/SymmetricIntersections/test/runtests.jl +++ b/experimental/SymmetricIntersections/test/runtests.jl @@ -4,7 +4,7 @@ using Oscar @testset "Elevators" begin W = sort(rand(1:5, 10)) S, x = graded_polynomial_ring(QQ, 10, W; cached=false) - + function weight(p) return degree(p).coeff[1] end @@ -14,7 +14,7 @@ using Oscar Oscar.number_of_elevations(el) == 0 && continue Si, SitoS = homogeneous_component(S, i) @test Oscar.number_of_elevations(el) == dim(Si) - @test Set([prod(x[l]) for l in el]) == Set(SitoS.(gens(Si))) + @test Set([prod(x[l]) for l in el]) == Set(SitoS.(gens(Si))) end S, x = graded_polynomial_ring(QQ, 10; cached=false) @@ -46,7 +46,7 @@ end co = rand(1:2, 3) chi = sum([co[j]*chis[j] for j in 1:3]) - + chid = symmetric_power(conj(chi), 4) cd = @inferred character_decomposition(chid) @test sum([c[1]*Int(degree(c[2])) for c in cd]) == Int(degree(chid)) @@ -135,7 +135,7 @@ end @test is_faithful(rep, p) @test count(prep2 -> is_similar(prep, prep2), fpr) == 1 - + f = representation_mapping_linear_lift(prep) @test order(domain(f)) == 64 @test codomain(f) isa MatrixGroup diff --git a/src/AlgebraicGeometry/Curves/AffinePlaneCurve.jl b/src/AlgebraicGeometry/Curves/AffinePlaneCurve.jl index ab03f5f4f27f..ad7776219d6c 100644 --- a/src/AlgebraicGeometry/Curves/AffinePlaneCurve.jl +++ b/src/AlgebraicGeometry/Curves/AffinePlaneCurve.jl @@ -42,7 +42,7 @@ Affine plane curve end end -AffinePlaneCurve(X::AbsSpec; args...) = AffinePlaneCurve(AffineAlgebraicSet(X;args...);args...) +AffinePlaneCurve(X::AbsAffineScheme; args...) = AffinePlaneCurve(AffineAlgebraicSet(X;args...);args...) # Functions to comply with the AbsAlgebraicSet interface diff --git a/src/AlgebraicGeometry/RationalPoint/AffineRationalPoint.jl b/src/AlgebraicGeometry/RationalPoint/AffineRationalPoint.jl index d9a0a66ca5e5..03868d03b63b 100644 --- a/src/AlgebraicGeometry/RationalPoint/AffineRationalPoint.jl +++ b/src/AlgebraicGeometry/RationalPoint/AffineRationalPoint.jl @@ -1,4 +1,4 @@ -function (X::AbsSpec{BRT})(p::AbsProjectiveRationalPoint) where BRT +function (X::AbsAffineScheme{BRT})(p::AbsProjectiveRationalPoint) where BRT # certainly not the fastest for the standard affine covering # ... but it will work in general. P = codomain(p) @@ -27,13 +27,13 @@ The coordinates are with respect to the ambient space of its ambient scheme. """ coordinates(p::AffineRationalPoint) = p.coordinates -function (X::AbsSpec)(coordinates::Vector; check::Bool=true) +function (X::AbsAffineScheme)(coordinates::Vector; check::Bool=true) k = base_ring(X) coordinates = k.(coordinates) return AffineRationalPoint(rational_point_set(X), coordinates, check=check) end -function (X::AbsSpec)(p::AffineRationalPoint; check::Bool=true) +function (X::AbsAffineScheme)(p::AffineRationalPoint; check::Bool=true) if codomain(p) === X return X end @@ -83,7 +83,7 @@ function ideal(P::AbsAffineRationalPoint) return I end -function _in(P::AbsAffineRationalPoint, X::AbsSpec{<:Any,<:MPolyRing}) +function _in(P::AbsAffineRationalPoint, X::AbsAffineScheme{<:Any,<:MPolyRing}) # X is affine space return ambient_space(P) == X end @@ -92,7 +92,7 @@ function evaluate(f::MPolyRingElem, P::AbsAffineRationalPoint) return evaluate(f, coordinates(P)) end -function _in(P::AbsAffineRationalPoint, X::AbsSpec{<:Any,<:MPolyQuoRing}) +function _in(P::AbsAffineRationalPoint, X::AbsAffineScheme{<:Any,<:MPolyQuoRing}) ambient_space(P) == ambient_space(X) || return false c = coordinates(P) for f in gens(saturated_ideal(defining_ideal(X))) @@ -111,13 +111,13 @@ function _in(P::AbsAffineRationalPoint, X::AbsAffineAlgebraicSet{<:Any,<:MPolyQu return true end -function _in(P::AbsAffineRationalPoint, X::AbsSpec) +function _in(P::AbsAffineRationalPoint, X::AbsAffineScheme) # slow fallback for affine opens # this should be improved return is_subscheme(scheme(P), X) end -function Base.in(P::AbsAffineRationalPoint, X::AbsSpec) +function Base.in(P::AbsAffineRationalPoint, X::AbsAffineScheme) codomain(P) === X && return true return _in(P, X) end @@ -127,7 +127,7 @@ function Base.in(P::AbsAffineRationalPoint, X::AbsCoveredScheme) end @doc raw""" - scheme(P::AbsAffineRationalPoint) -> AbsSpec + scheme(P::AbsAffineRationalPoint) -> AbsAffineScheme Return the rational point ``P`` viewed as a reduced, affine subscheme of its ambient affine space. @@ -135,7 +135,7 @@ of its ambient affine space. function scheme(P::AbsAffineRationalPoint) I = ideal(P) R = OO(ambient_space(P)) - return Spec(R, I) + return spec(R, I) end @doc raw""" @@ -150,7 +150,7 @@ function closed_embedding(P::AbsAffineRationalPoint) end -function (f::AbsSpecMor{<:AbsSpec{S},<:AbsSpec{S},<:Any,<:Any,Nothing})(P::AbsAffineRationalPoint) where {S} +function (f::AbsAffineSchemeMor{<:AbsAffineScheme{S},<:AbsAffineScheme{S},<:Any,<:Any,Nothing})(P::AbsAffineRationalPoint) where {S} # The Nothing type parameter assures that the base morphism is trivial. @req domain(f) == codomain(P) "$(P) not in domain" @req base_ring(domain(f)) == base_ring(codomain(f)) "schemes must be defined over the same base ring. Try to map the point as an ideal instead" @@ -166,11 +166,11 @@ function MPolyComplementOfKPointIdeal(P::AbsAffineRationalPoint) return MPolyComplementOfKPointIdeal(R, coordinates(P)) end -function is_smooth(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint) +function is_smooth(X::AbsAffineScheme{<:Field}, P::AbsAffineRationalPoint) @req P in X "not a point on X" U = MPolyComplementOfKPointIdeal(P) R = OO(codomain(P)) - XU = Spec(localization(R, U)[1]) + XU = spec(localization(R, U)[1]) return is_smooth(XU) end @@ -183,13 +183,13 @@ is_smooth(P::AbsAffineRationalPoint) = is_smooth(codomain(P),P) @doc raw""" - tangent_space(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint) -> AlgebraicSet + tangent_space(X::AbsAffineScheme{<:Field}, P::AbsAffineRationalPoint) -> AlgebraicSet Return the Zariski tangent space of `X` at its rational point `P`. See also [`tangent_space(P::AbsAffineRationalPoint{<:Field})`](@ref) """ -function tangent_space(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint) +function tangent_space(X::AbsAffineScheme{<:Field}, P::AbsAffineRationalPoint) @req P in X "the point needs to lie on the algebraic set" J = jacobian_matrix(gens(saturated_ideal(defining_ideal(X)))) v = coordinates(P) @@ -205,7 +205,7 @@ end Return the Zariski tangent space of the ambient scheme of `P` at its point `P`. -See also [`tangent_space(X::AbsSpec{<:Field}, P::AbsAffineRationalPoint)`](@ref) +See also [`tangent_space(X::AbsAffineScheme{<:Field}, P::AbsAffineRationalPoint)`](@ref) """ tangent_space(P::AbsAffineRationalPoint{<:FieldElem}) = tangent_space(codomain(P), P) @@ -241,7 +241,7 @@ function decide_du_val_singularity(P::AbsAffineRationalPoint{<:FieldElem,<:Any}) return d[1][1],d[1][3] end -function stalk(X::AbsSpec, P::AbsAffineRationalPoint) +function stalk(X::AbsAffineScheme, P::AbsAffineRationalPoint) P in X || error("not a point of X") S = MPolyComplementOfKPointIdeal(P) return localization(OO(X),S) diff --git a/src/AlgebraicGeometry/RationalPoint/PointSet.jl b/src/AlgebraicGeometry/RationalPoint/PointSet.jl index cc5c543f1515..53aed4edf6f1 100644 --- a/src/AlgebraicGeometry/RationalPoint/PointSet.jl +++ b/src/AlgebraicGeometry/RationalPoint/PointSet.jl @@ -28,7 +28,7 @@ function Base.show(io::IO, X::RationalPointSet) end -function (S::RationalPointSet{<:Any,<:AbsSpec})(c::Vector; check::Bool=true) +function (S::RationalPointSet{<:Any,<:AbsAffineScheme})(c::Vector; check::Bool=true) k = coefficient_ring(S) c = k.(c) return AffineRationalPoint(S, c; check=check) diff --git a/src/AlgebraicGeometry/RationalPoint/ProjectiveRationalPoint.jl b/src/AlgebraicGeometry/RationalPoint/ProjectiveRationalPoint.jl index 7d8f47b5d234..808e749e53a0 100644 --- a/src/AlgebraicGeometry/RationalPoint/ProjectiveRationalPoint.jl +++ b/src/AlgebraicGeometry/RationalPoint/ProjectiveRationalPoint.jl @@ -124,7 +124,7 @@ of its ambient projective space. function scheme(P::AbsProjectiveRationalPoint) I = ideal(P) R = ambient_coordinate_ring(codomain(P)) - return ProjectiveScheme(R, I) + return proj(R, I) end function (f::ProjectiveSchemeMor{<:Any,<:Any,<:Any,Nothing})(P::AbsProjectiveRationalPoint) diff --git a/src/AlgebraicGeometry/RationalPoint/Types.jl b/src/AlgebraicGeometry/RationalPoint/Types.jl index 622d12d893c1..e2090af4f7c2 100644 --- a/src/AlgebraicGeometry/RationalPoint/Types.jl +++ b/src/AlgebraicGeometry/RationalPoint/Types.jl @@ -1,4 +1,4 @@ -struct RationalPointSet{P<:AbsSpec, T<:Scheme} <: AbsRationalPointSet{P,T} +struct RationalPointSet{P<:AbsAffineScheme, T<:Scheme} <: AbsRationalPointSet{P,T} domain::P codomain::T end diff --git a/src/AlgebraicGeometry/Schemes/AbstractTypes.jl b/src/AlgebraicGeometry/Schemes/AbstractTypes.jl index e18700db4593..2ab173e854e4 100644 --- a/src/AlgebraicGeometry/Schemes/AbstractTypes.jl +++ b/src/AlgebraicGeometry/Schemes/AbstractTypes.jl @@ -1,9 +1,9 @@ @doc raw""" - AbsAffineAlgebraicSet <: AbsSpec + AbsAffineAlgebraicSet <: AbsAffineScheme An affine, geometrically reduced subscheme of an affine space over a field. """ -abstract type AbsAffineAlgebraicSet{BaseField<:Field, RingType} <:AbsSpec{BaseField, RingType} end +abstract type AbsAffineAlgebraicSet{BaseField<:Field, RingType} <:AbsAffineScheme{BaseField, RingType} end @doc raw""" AbsProjectiveAlgebraicSet <: AbsProjectiveScheme @@ -109,7 +109,7 @@ abstract type AbsCoveredSurface{BaseField<:Field} <: AbsCoveredVariety{BaseField ################################################################################ @doc raw""" - AbsRationalPointSet{P<:AbsSpec,T<:Scheme} + AbsRationalPointSet{P<:AbsAffineScheme,T<:Scheme} Abstract type for the set of rational points of a scheme. @@ -120,7 +120,7 @@ We refer to ``L`` as the `coefficient_ring`, to homset. For traditional reasons we keep the name `ambient_scheme` for the codomain. """ -abstract type AbsRationalPointSet{P<:AbsSpec,T<:Scheme} end +abstract type AbsRationalPointSet{P<:AbsAffineScheme,T<:Scheme} end abstract type AbsRationalPoint{RingElemType, ParentType} end diff --git a/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Attributes.jl index c1177ae0d395..04b160a23056 100644 --- a/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Attributes.jl @@ -1,15 +1,15 @@ ######################################################################## # -# (1) AbsSpec interface +# (1) AbsAffineScheme interface # ######################################################################## @doc raw""" - underlying_scheme(X::AffineAlgebraicSet) -> AbsSpec + underlying_scheme(X::AffineAlgebraicSet) -> AbsAffineScheme Return the underlying reduced scheme defining ``X``. -This is used to forward the `AbsSpec` functionality to ``X``, but may +This is used to forward the `AbsAffineScheme` functionality to ``X``, but may trigger the computation of a radical ideal. Hence this can be expensive. """ function underlying_scheme(X::AffineAlgebraicSet) @@ -32,7 +32,7 @@ function underlying_scheme(X::AffineAlgebraicSet{<:Field,<:MPolyQuoRing}) else Irad = radical(I) end - X.Xred = Spec(base_ring(Irad), Irad) + X.Xred = spec(base_ring(Irad), Irad) return X.Xred end @@ -42,7 +42,7 @@ end # ######################################################################## @doc raw""" - fat_scheme(X::AffineAlgebraicSet) -> AbsSpec + fat_scheme(X::AffineAlgebraicSet) -> AbsAffineScheme Return a scheme whose reduced subscheme is ``X``. diff --git a/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Constructors.jl index fa2470c1f714..482c6771ef14 100644 --- a/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Constructors.jl @@ -3,7 +3,7 @@ ######################################################## @doc raw""" - algebraic_set(X::Spec; is_reduced=false, check=true) -> AffineAlgebraicSet + algebraic_set(X::AffineScheme; is_reduced=false, check=true) -> AffineAlgebraicSet Convert `X` to an `AffineAlgebraicSet` by considering its reduced structure. @@ -11,7 +11,7 @@ If `is_reduced` is set, assume that `X` is already reduced. If `is_reduced` and `check` are set, check that `X` is actually geometrically reduced as claimed. """ -function algebraic_set(X::Spec; is_reduced::Bool=false, check::Bool=true) +function algebraic_set(X::AffineScheme; is_reduced::Bool=false, check::Bool=true) return AffineAlgebraicSet(X, is_reduced=is_reduced, check=check) end @@ -32,7 +32,7 @@ defined by ideal (x^3 + y^2 + y + 1, x) ``` """ function algebraic_set(I::MPolyIdeal{<:MPolyRingElem}; is_radical::Bool=false, check::Bool=true) - X = Spec(base_ring(I), I) + X = spec(base_ring(I), I) return algebraic_set(X, is_reduced=is_radical, check=check) end diff --git a/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Types.jl b/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Types.jl index b7e7c3e21fd8..ac87d1a83505 100644 --- a/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Types.jl +++ b/src/AlgebraicGeometry/Schemes/AffineAlgebraicSet/Objects/Types.jl @@ -37,9 +37,9 @@ defined by ideal(y, x) """ @attributes mutable struct AffineAlgebraicSet{BaseRing<:Field, RingType<:MPolyAnyRing} <: AbsAffineAlgebraicSet{BaseRing, RingType} - X::Spec - Xred::Spec - function AffineAlgebraicSet(X::Spec; is_reduced::Bool=false, check::Bool=true) + X::AffineScheme + Xred::AffineScheme + function AffineAlgebraicSet(X::AffineScheme; is_reduced::Bool=false, check::Bool=true) A = new{typeof(base_ring(X)), typeof(OO(X))}() A.X = X if check && is_reduced diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Attributes.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Attributes.jl similarity index 67% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Attributes.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Attributes.jl index 36d0120d8f8e..1a9b434bc51d 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Attributes.jl @@ -1,18 +1,18 @@ ######################################################################## # Type getters # ######################################################################## -morphism_type(U::S, V::T) where {S<:SpecOpen, T<:SpecOpen} = SpecOpenMor{S, T} -morphism_type(::Type{DomainType}, ::Type{CodomainType}) where {DomainType<:SpecOpen, CodomainType<:SpecOpen} = SpecOpenMor{DomainType, CodomainType} +morphism_type(U::S, V::T) where {S<:AffineSchemeOpenSubscheme, T<:AffineSchemeOpenSubscheme} = AffineSchemeOpenSubschemeMor{S, T} +morphism_type(::Type{DomainType}, ::Type{CodomainType}) where {DomainType<:AffineSchemeOpenSubscheme, CodomainType<:AffineSchemeOpenSubscheme} = AffineSchemeOpenSubschemeMor{DomainType, CodomainType} ######################################################################## # Basic getters # ######################################################################## -domain(f::SpecOpenMor) = f.domain -codomain(f::SpecOpenMor) = f.codomain -maps_on_patches(f::SpecOpenMor) = f.maps_on_patches -getindex(f::SpecOpenMor, i::Int) = maps_on_patches(f)[i] +domain(f::AffineSchemeOpenSubschemeMor) = f.domain +codomain(f::AffineSchemeOpenSubschemeMor) = f.codomain +maps_on_patches(f::AffineSchemeOpenSubschemeMor) = f.maps_on_patches +getindex(f::AffineSchemeOpenSubschemeMor, i::Int) = maps_on_patches(f)[i] -function getindex(f::SpecOpenMor, D::AbsSpec) +function getindex(f::AffineSchemeOpenSubschemeMor, D::AbsAffineScheme) U = affine_patches(domain(f)) D in U || error("affine patch not found in the domain") for i = 1:length(U) @@ -20,14 +20,14 @@ function getindex(f::SpecOpenMor, D::AbsSpec) end end -function pullback(f::SpecOpenMor) +function pullback(f::AffineSchemeOpenSubschemeMor) if !isdefined(f, :pullback) U = codomain(f) V = domain(f) # First check whether we are in an easy case where we only have a restriction if ambient_coordinate_ring(domain(f)) === ambient_coordinate_ring(codomain(f)) && complement_equations(V) == complement_equations(U) - function my_restr(a::SpecOpenRingElem) - return SpecOpenRingElem(OO(V), [OO(V[i])(a[i]) for i in 1:ngens(V)]) + function my_restr(a::AffineSchemeOpenSubschemeRingElem) + return AffineSchemeOpenSubschemeRingElem(OO(V), [OO(V[i])(a[i]) for i in 1:ngens(V)]) end f.pullback = MapFromFunc(OO(U), OO(V), my_restr) return f.pullback::Map{typeof(OO(codomain(f))), typeof(OO(domain(f)))} @@ -35,9 +35,9 @@ function pullback(f::SpecOpenMor) pbs_from_ambient = [pullback(g) for g in maps_on_patches(f)] d = [pullback(f[i]).(complement_equations(U)) for i in 1:ngens(V)] - W = [SpecOpen(V[i], ideal(OO(V[i]), d[i]), check=false) for i in 1:ngens(V)] + W = [AffineSchemeOpenSubscheme(V[i], ideal(OO(V[i]), d[i]), check=false) for i in 1:ngens(V)] # Not every element of d needs to be non-zero. But zero elements will be - # discarded by the constructor for the SpecOpen! So we need to manually + # discarded by the constructor for the AffineSchemeOpenSubscheme! So we need to manually # relate them for the time being. This should only be a temporary fix, however. a = Vector{Vector{Int}}() for i in 1:length(d) @@ -55,21 +55,21 @@ function pullback(f::SpecOpenMor) end pb_res = [[pullback(restrict(f[i], W[i][j], U[a[i][j]], check=false)) for j in 1:ngens(W[i])] for i in 1:ngens(V)] lift_maps = [restriction_map(W[i], V[i], one(ambient_coordinate_ring(V[i])), check=false) for i in 1:ngens(V)] - function mymap(a::SpecOpenRingElem) + function mymap(a::AffineSchemeOpenSubschemeRingElem) b = [lift_maps[i]( - SpecOpenRingElem( + AffineSchemeOpenSubschemeRingElem( OO(W[i]), [pb_res[i][j](a[j]) for j in 1:ngens(U)], check=false) ) for i in 1:ngens(V) ] - return SpecOpenRingElem(OO(V), b, check=false) + return AffineSchemeOpenSubschemeRingElem(OO(V), b, check=false) # shortcut for regular elements on the ambient variety # Does not work because of parent check done by the Map # function mymap(a::RingElem) # parent(a) === OO(ambient(U)) || return mymap(OO(ambient(U))(a)) - # return SpecOpenRingElem(OO(V), + # return AffineSchemeOpenSubschemeRingElem(OO(V), # [f[i](a) for i in 1:ngens(V)], # check=false) # end diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Constructors.jl similarity index 61% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Constructors.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Constructors.jl index c97f3311ce03..1d056c6e801e 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Constructors.jl @@ -1,33 +1,33 @@ ######################################################################## -# Special constructors for morphisms of SpecOpens # +# Special constructors for morphisms of AffineSchemeOpenSubschemes # ######################################################################## -### Construct a morphisms by the restriction of coordinate functions +### Construct a morphisms by the restriction of coordinate functions # to every affine patch -function SpecOpenMor(U::SpecOpen, V::SpecOpen, f::Vector{<:RingElem}; check::Bool=true) +function AffineSchemeOpenSubschemeMor(U::AffineSchemeOpenSubscheme, V::AffineSchemeOpenSubscheme, f::Vector{<:RingElem}; check::Bool=true) Y = ambient_scheme(V) maps = [morphism(W, Y, f, check=check) for W in affine_patches(U)] - return SpecOpenMor(U, V, [morphism(W, Y, f, check=check) for W in affine_patches(U)], check=check) + return AffineSchemeOpenSubschemeMor(U, V, [morphism(W, Y, f, check=check) for W in affine_patches(U)], check=check) end -function SpecOpenMor(X::SpecType, d::RET, Y::SpecType, e::RET, f::Vector{RET}; check::Bool=true) where {SpecType<:Spec, RET<:RingElem} - U = SpecOpen(X, [d], check=check) - V = SpecOpen(Y, [e], check=check) - return SpecOpenMor(U, V, [morphism(U[1], Y, OO(U[1]).(f), check=check)], check=check) +function AffineSchemeOpenSubschemeMor(X::AffineSchemeType, d::RET, Y::AffineSchemeType, e::RET, f::Vector{RET}; check::Bool=true) where {AffineSchemeType<:AffineScheme, RET<:RingElem} + U = AffineSchemeOpenSubscheme(X, [d], check=check) + V = AffineSchemeOpenSubscheme(Y, [e], check=check) + return AffineSchemeOpenSubschemeMor(U, V, [morphism(U[1], Y, OO(U[1]).(f), check=check)], check=check) end ######################################################################## # Constructors for canonical maps # ######################################################################## -function inclusion_morphism(U::SpecOpen, V::SpecOpen; check::Bool=true) +function inclusion_morphism(U::AffineSchemeOpenSubscheme, V::AffineSchemeOpenSubscheme; check::Bool=true) X = ambient_scheme(U) @check is_subscheme(U, V) "method not implemented" - return SpecOpenMor(U, V, gens(ambient_coordinate_ring(X)), check=false) + return AffineSchemeOpenSubschemeMor(U, V, gens(ambient_coordinate_ring(X)), check=false) end -inclusion_morphism(X::SpecOpen, Y::AbsSpec; check::Bool=true) = inclusion_morphism(X, SpecOpen(Y), check=check) +inclusion_morphism(X::AffineSchemeOpenSubscheme, Y::AbsAffineScheme; check::Bool=true) = inclusion_morphism(X, AffineSchemeOpenSubscheme(Y), check=check) -function identity_map(U::SpecOpen) - phi = SpecOpenMor(U, U, +function identity_map(U::AffineSchemeOpenSubscheme) + phi = AffineSchemeOpenSubschemeMor(U, U, [morphism(V, ambient_scheme(U), gens(OO(V)), check=false) for V in affine_patches(U)], check=false ) @@ -35,7 +35,7 @@ function identity_map(U::SpecOpen) end ######################################################################## -# Restrictions of morphisms to SpecOpens # +# Restrictions of morphisms to AffineSchemeOpenSubschemes # ######################################################################## @doc raw""" restrict(f::SchemeMor, U::Scheme, V::Scheme; check::Bool=true) @@ -46,19 +46,19 @@ function restrict(f::SchemeMor, U::Scheme, V::Scheme; check::Bool) error("method not implemented") end -function restrict(f::SpecMor, U::SpecOpen, V::SpecOpen; check::Bool=true) +function restrict(f::AffineSchemeMor, U::AffineSchemeOpenSubscheme, V::AffineSchemeOpenSubscheme; check::Bool=true) @check begin is_subscheme(U, domain(f)) || error("$U is not contained in the domain of $f") is_subscheme(V, codomain(f)) || error("$V is not contained in the codomain of $f") all(x->is_subscheme(preimage(f, x), U), affine_patches(V)) || error("preimage of $V is not contained in $U") end - return SpecOpenMor(U, V, [restrict(f, W, ambient_scheme(V), check=check) for W in affine_patches(U)]) + return AffineSchemeOpenSubschemeMor(U, V, [restrict(f, W, ambient_scheme(V), check=check) for W in affine_patches(U)]) end function restrict( - f::SpecOpenMor, - U::SpecOpen, - V::SpecOpen; + f::AffineSchemeOpenSubschemeMor, + U::AffineSchemeOpenSubscheme, + V::AffineSchemeOpenSubscheme; check::Bool=true ) @check begin @@ -70,10 +70,10 @@ function restrict( help_map = compose(inc, f, check=check) Y = ambient_scheme(V) h = [restrict(g, domain(g), Y, check=check) for g in maps_on_patches(help_map)] - return SpecOpenMor(U, V, h, check=check) + return AffineSchemeOpenSubschemeMor(U, V, h, check=check) end -function restrict(f::SpecOpenMor, W::AbsSpec, Y::AbsSpec; check::Bool=true) +function restrict(f::AffineSchemeOpenSubschemeMor, W::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true) @check begin is_subscheme(W, domain(f)) || error("$U is not contained in the domain of $f") is_subscheme(W, preimage(f, Y)) || error("image of $W is not contained in $Y") @@ -86,9 +86,9 @@ end ### the restriction of a morphism to closed subsets in domain and codomain #function restrict( -# f::SpecOpenMor, -# X::AbsSpec, -# Y::AbsSpec; +# f::AffineSchemeOpenSubschemeMor, +# X::AbsAffineScheme, +# Y::AbsAffineScheme; # check::Bool=true # ) # U = intersect(X, domain(f), check=check) @@ -96,7 +96,7 @@ end # # new_maps_on_patches = [restrict(f[i], U[i], Y, check=check) for i in 1:n_patches(U)] # -# return SpecOpenMor(U, V, new_maps_on_patches, check=check) +# return AffineSchemeOpenSubschemeMor(U, V, new_maps_on_patches, check=check) #end ######################################################################## @@ -104,30 +104,30 @@ end # functions on the affine patches. # ######################################################################## @doc raw""" - maximal_extension(X::AbsSpec, Y::AbsSpec, f::AbstractAlgebra.Generic.FracFieldElem) + maximal_extension(X::AbsAffineScheme, Y::AbsAffineScheme, f::AbstractAlgebra.Generic.FracFieldElem) -Given a rational map ``ϕ : X ---> Y ⊂ Spec 𝕜[y₁,…,yₙ]`` of affine schemes -determined by ``ϕ*(yⱼ) = fⱼ = aⱼ/bⱼ``, find the maximal open subset ``U⊂ X`` +Given a rational map ``ϕ : X ---> Y ⊂ Spec 𝕜[y₁,…,yₙ]`` of affine schemes +determined by ``ϕ*(yⱼ) = fⱼ = aⱼ/bⱼ``, find the maximal open subset ``U⊂ X`` to which ``ϕ`` can be extended to a regular map ``g : U → Y`` and return ``g``. """ function maximal_extension( - X::AbsSpec, - Y::AbsSpec, + X::AbsAffineScheme, + Y::AbsAffineScheme, f::Vector{AbstractAlgebra.Generic.FracFieldElem{RET}} ) where {RET<:RingElem} U, g = maximal_extension(X, f) n = length(affine_patches(U)) - maps = Vector{AbsSpecMor}() + maps = Vector{AbsAffineSchemeMor}() for i in 1:n push!(maps, morphism(affine_patches(U)[i], Y, [restrictions(a)[i] for a in g])) end - h = SpecOpenMor(U, SpecOpen(Y), maps) + h = AffineSchemeOpenSubschemeMor(U, AffineSchemeOpenSubscheme(Y), maps) return h end function maximal_extension( - X::AbsSpec, - Y::AbsSpec, + X::AbsAffineScheme, + Y::AbsAffineScheme, f::Vector{<:RingElem} ) h = maximal_extension(X, Y, fraction_field(ambient_coordinate_ring(X)).(f)) diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Methods.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Methods.jl similarity index 77% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Methods.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Methods.jl index c155ef0d51c1..eafc5f2b6a15 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Methods.jl @@ -6,7 +6,7 @@ # for the ambient space and the description of the complement (and we do not # forget to avoid printing again the coordinates by using the `false`) argument # in both the show function for `domain(f)` and `codomain(f)`). -function Base.show(io::IO, ::MIME"text/plain", f::SpecOpenMor) +function Base.show(io::IO, ::MIME"text/plain", f::AffineSchemeOpenSubschemeMor) io = pretty(io) X = domain(f) cX = ambient_coordinates(X) @@ -20,7 +20,7 @@ function Base.show(io::IO, ::MIME"text/plain", f::SpecOpenMor) kY = length(str) push!(co_str, str) k = max(length.(co_str)...) - println(io, "Spec open morphism") + println(io, "Affine scheme open subscheme morphism") print(io, Indent(), "from ") print(io, co_str[1]*" "^(k-kX+2), Lowercase()) show(IOContext(io, :show_coordinates => false), domain(f)) @@ -45,9 +45,9 @@ function Base.show(io::IO, ::MIME"text/plain", f::SpecOpenMor) print(io, Dedent()) end -function Base.show(io::IO, f::SpecOpenMor) +function Base.show(io::IO, f::AffineSchemeOpenSubschemeMor) if get(io, :supercompact, false) - print(io, "Spec open morphism") + print(io, "Affine scheme open subscheme morphism") else io = pretty(io) print(io, "Hom: ", Lowercase(), domain(f), " -> ", Lowercase(), codomain(f)) @@ -57,7 +57,7 @@ end ######################################################################## # Composition of maps # ######################################################################## -function compose(f::SpecOpenMor, g::SpecOpenMor; check::Bool=true) +function compose(f::AffineSchemeOpenSubschemeMor, g::AffineSchemeOpenSubschemeMor; check::Bool=true) U = domain(f) Cf = codomain(f) V = domain(g) @@ -68,13 +68,13 @@ function compose(f::SpecOpenMor, g::SpecOpenMor; check::Bool=true) Z = ambient_scheme(W) pb_coords = [pullback(f)(pullback(g)(OO(W)(x))) for x in gens(ambient_coordinate_ring(Z))] maps_on_patches = [morphism(A, Z, [restrict(h, A, check=check) for h in pb_coords], check=check) for A in affine_patches(U)] - return SpecOpenMor(U, W, maps_on_patches, check=check) + return AffineSchemeOpenSubschemeMor(U, W, maps_on_patches, check=check) end ######################################################################## # Pullback of regular functions (deprecated) # ######################################################################## -function pullback(f::SpecOpenMor, a::RingElem) +function pullback(f::AffineSchemeOpenSubschemeMor, a::RingElem) U = domain(f) X = ambient_scheme(U) V = codomain(f) @@ -82,13 +82,13 @@ function pullback(f::SpecOpenMor, a::RingElem) R = ambient_coordinate_ring(Y) parent(a) === R || error("element does not belong to the correct ring") pb_a = [pullback(f[i])(a) for i in 1:n_patches(U)] - return SpecOpenRingElem(SpecOpenRing(X, U), pb_a) + return AffineSchemeOpenSubschemeRingElem(AffineSchemeOpenSubschemeRing(X, U), pb_a) end ######################################################################## # Equality test # ######################################################################## -function ==(f::T, g::T) where {T<:SpecOpenMor} +function ==(f::T, g::T) where {T<:AffineSchemeOpenSubschemeMor} (domain(f) == domain(g)) || return false (codomain(f) == codomain(g)) || return false Y = ambient_scheme(codomain(f)) @@ -104,22 +104,22 @@ function ==(f::T, g::T) where {T<:SpecOpenMor} end ######################################################################## -# Preimages under SpecOpenMors # +# Preimages under AffineSchemeOpenSubschemeMors # ######################################################################## -function preimage(f::SpecOpenMor, Z::AbsSpec; check::Bool=true) - U = domain(f) +function preimage(f::AffineSchemeOpenSubschemeMor, Z::AbsAffineScheme; check::Bool=true) + U = domain(f) X = ambient_scheme(U) @check is_closed_embedding(Z, ambient_scheme(codomain(f))) "second argument must be closed in the codomain" n = length(affine_patches(U)) pbZ = [preimage(f[i], Z) for i in 1:n] - Y = X + Y = X for K in pbZ Y = subscheme(Y, gens(modulus(underlying_quotient(OO(K))))) end - return SpecOpen(Y, [g for g in complement_equations(U) if !iszero(OO(Y)(g))]) + return AffineSchemeOpenSubscheme(Y, [g for g in complement_equations(U) if !iszero(OO(Y)(g))]) end -function preimage(f::SpecOpenMor, W::PrincipalOpenSubset; check::Bool=true) - V = codomain(f) +function preimage(f::AffineSchemeOpenSubschemeMor, W::PrincipalOpenSubset; check::Bool=true) + V = codomain(f) Y = ambient_scheme(V) Y === ambient_scheme(W) || error("second argument must be open in the ambient scheme of the domain of the morphism") h = complement_equation(W) @@ -131,11 +131,11 @@ function preimage(f::SpecOpenMor, W::PrincipalOpenSubset; check::Bool=true) for i in 1:n_patches(U) I = intersect(I, saturated_ideal(ideal(OO(U[i]), pbh[i]))) end - return intersect(U, SpecOpen(X, I)) + return intersect(U, AffineSchemeOpenSubscheme(X, I)) end -function preimage(f::SpecOpenMor, V::SpecOpen; check::Bool=true) +function preimage(f::AffineSchemeOpenSubschemeMor, V::AffineSchemeOpenSubscheme; check::Bool=true) U = domain(f) X = ambient_scheme(U) R = ambient_coordinate_ring(X) @@ -143,17 +143,17 @@ function preimage(f::SpecOpenMor, V::SpecOpen; check::Bool=true) for i in 1:n_patches(U) I = intersect(I, saturated_ideal(ideal(OO(U[i]), OO(U[i]).(pullback(f[i]).(complement_equations(V)))))) end - return intersect(U, SpecOpen(X, I)) + return intersect(U, AffineSchemeOpenSubscheme(X, I)) end ######################################################################## # Auxiliary methods # ######################################################################## -function is_non_zero_divisor(f::RET, U::SpecOpen) where {RET<:RingElem} +function is_non_zero_divisor(f::RET, U::AffineSchemeOpenSubscheme) where {RET<:RingElem} return all(x->(is_non_zero_divisor(f, x)), affine_patches(U)) end -function find_non_zero_divisor(U::SpecOpen) +function find_non_zero_divisor(U::AffineSchemeOpenSubscheme) n = ngens(U) X = ambient_scheme(U) R = ambient_coordinate_ring(X) @@ -168,19 +168,19 @@ function find_non_zero_divisor(U::SpecOpen) end @doc raw""" - generic_fractions(f::SpecOpenMor) + generic_fractions(f::AffineSchemeOpenSubschemeMor) -Given a morphism ``f : U → V`` of Zariski open subsets ``U ⊂ X ⊂ 𝔸ᵐ`` and ``V ⊂ Y ⊂ 𝔸ⁿ``, -produce a tuple of fractions ``[a₁/b₁,…,aₙ/bₙ]`` such that ``f`` can be recovered -as the maximal extension of the rational map given by +Given a morphism ``f : U → V`` of Zariski open subsets ``U ⊂ X ⊂ 𝔸ᵐ`` and ``V ⊂ Y ⊂ 𝔸ⁿ``, +produce a tuple of fractions ``[a₁/b₁,…,aₙ/bₙ]`` such that ``f`` can be recovered +as the maximal extension of the rational map given by ``` U ⊃ U' → 𝔸ⁿ, x ↦ [a₁(x)/b₁(x),…,aₙ(x)/bₙ(x)] ``` where ``U'`` is the complement of the zero loci of the denominators ``bᵢ`` in ``U``. -In particular, this requires ``U'`` to be dense in ``U`` and this subset +In particular, this requires ``U'`` to be dense in ``U`` and this subset is chosen at random. """ -function generic_fractions(f::SpecOpenMor) +function generic_fractions(f::AffineSchemeOpenSubschemeMor) U = domain(f) X = ambient_scheme(U) V = codomain(f) diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Types.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Types.jl similarity index 76% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Types.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Types.jl index 49289aef4656..03b60029141a 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Morphisms/Types.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Morphisms/Types.jl @@ -3,7 +3,7 @@ # Morphisms of Zariski-open subsets of affine schemes # ######################################################################## @doc raw""" - SpecOpenMor{DomainType<:SpecOpen, CodomainType<:SpecOpen} + AffineSchemeOpenSubschemeMor{DomainType<:AffineSchemeOpenSubscheme, CodomainType<:AffineSchemeOpenSubscheme} Morphisms ``f : U → V`` of open sets ``U ⊂ X`` and ``V ⊂ Y`` of affine schemes. These are stored as morphisms ``fᵢ: Uᵢ→ Y`` on the affine patches @@ -17,23 +17,23 @@ then * `CodomainType` is the type of the codomain; affine patches of the domain to the affine ambient scheme of the codomain. """ -mutable struct SpecOpenMor{DomainType<:SpecOpen, - CodomainType<:SpecOpen - }<:SchemeMor{DomainType, CodomainType, SpecOpenMor, Nothing} +mutable struct AffineSchemeOpenSubschemeMor{DomainType<:AffineSchemeOpenSubscheme, + CodomainType<:AffineSchemeOpenSubscheme + }<:SchemeMor{DomainType, CodomainType, AffineSchemeOpenSubschemeMor, Nothing} domain::DomainType codomain::CodomainType - maps_on_patches::Vector{AbsSpecMor} + maps_on_patches::Vector{AbsAffineSchemeMor} # fields used for caching - inverse::SpecOpenMor + inverse::AffineSchemeOpenSubschemeMor pullback::Map - function SpecOpenMor( + function AffineSchemeOpenSubschemeMor( U::DomainType, V::CodomainType, - f::Vector{<:AbsSpecMor}; + f::Vector{<:AbsAffineSchemeMor}; check::Bool=true - ) where {DomainType<:SpecOpen, CodomainType<:SpecOpen} + ) where {DomainType<:AffineSchemeOpenSubscheme, CodomainType<:AffineSchemeOpenSubscheme} Y = ambient_scheme(V) n = length(f) n == length(affine_patches(U)) || error("number of patches does not coincide with the number of maps") diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Attributes.jl new file mode 100644 index 000000000000..ef455f1382c7 --- /dev/null +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Attributes.jl @@ -0,0 +1,155 @@ + +######################################################################## +# (1) Type getters for AffineSchemeOpenSubscheme # +######################################################################## +open_subset_type(::Type{AffineSchemeType}) where {BRT, RT, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = AffineSchemeOpenSubscheme{AffineSchemeType, BRT} +open_subset_type(X::AffineScheme) = open_subset_type(typeof(X)) + +ambient_type(U::AffineSchemeOpenSubscheme{AffineSchemeType, BRT}) where {AffineSchemeType<:AffineScheme, BRT} = AffineSchemeType +ambient_type(::Type{AffineSchemeOpenSubscheme{AffineSchemeType, BRT}}) where {AffineSchemeType<:AffineScheme, BRT} = AffineSchemeType + +poly_type(::Type{AffineSchemeOpenSubschemeType}) where {AffineSchemeOpenSubschemeType<:AffineSchemeOpenSubscheme} = poly_type(ambient_type(AffineSchemeOpenSubschemeType)) +poly_type(U::AffineSchemeOpenSubscheme) = poly_type(typeof(U)) + +######################################################################## +# (2) Getter methods for the internally stored data # +######################################################################## +@doc raw""" + affine_patches(U::AffineSchemeOpenSubscheme) + +Return a list of principal affine open subschemes covering ``U``. +TODO: Add example! +""" +function affine_patches(U::AffineSchemeOpenSubscheme) + if !isdefined(U, :patches) + X = ambient_scheme(U) + U.patches = [PrincipalOpenSubset(X, OO(X)(f)) for f in complement_equations(U)] + end + return U.patches +end + +@doc raw""" + intersections(U::AffineSchemeOpenSubscheme) + +Return a list of pairwise intersections of the +principal open subschemes covering ``U``. +TODO: Add example! +""" +function intersections(U::AffineSchemeOpenSubscheme) + if !isdefined(U, :intersections) + X = ambient_scheme(U) + V = affine_patches(U) + for i in 1:length(V) + for j in 1:i-1 + U.intersections[(i,j)] = U.intersections[(j,i)] = intersect(V[i], V[j]) + end + end + end + return U.intersections +end + +@doc raw""" + ambient_scheme(U::AffineSchemeOpenSubscheme) + +Return the ambient scheme ``X`` of a Zariski open subset ``U ⊂ X``. +TODO: Add example! +""" +ambient_scheme(U::AffineSchemeOpenSubscheme) = U.X + +@doc raw""" + ambient_coordinate_ring(U::AffineSchemeOpenSubscheme) + +For the open set `U = X \ V ` return the ambient coordinate ring of `X`. +TODO: Add example! +""" +ambient_coordinate_ring(U::AffineSchemeOpenSubscheme) = ambient_coordinate_ring(ambient_scheme(U)) + +@doc raw""" + ambient_space(U::AffineSchemeOpenSubscheme) -> AffineScheme + +For ``U ⊆ X \subseteq 𝔸 ⁿ`` return the affine space``𝔸 ⁿ``. +""" +ambient_space(U::AffineSchemeOpenSubscheme) = ambient_space(ambient_scheme(U)) + +@doc raw""" + ambient_coordinates(U::AffineSchemeOpenSubscheme) + +Return the coordinates of the ambient affine space of ``U``. +""" +ambient_coordinates(U::AffineSchemeOpenSubscheme) = coordinates(ambient_space(U)) + +@doc raw""" + number_of_patches(U::AffineSchemeOpenSubscheme) + +Return the number of generators stored for describing the complement of ``U``. +""" +number_of_patches(U::AffineSchemeOpenSubscheme) = length(U.gens) + +@doc raw""" + complement_equations(U::AffineSchemeOpenSubscheme) + +Return the generators ``[f₁,…,fᵣ]`` stored for the description +of the complement of ``U``. +""" +complement_equations(U::AffineSchemeOpenSubscheme) = U.gens::Vector{elem_type(ambient_coordinate_ring(ambient_scheme(U)))} +number_of_complement_equations(U::AffineSchemeOpenSubscheme) = length(U.gens) + +@doc raw""" + affine_patch(U::AffineSchemeOpenSubscheme, i::Int) + +Return the hypersurface complement of ``fᵢ`` in the +ambient scheme ``X`` of ``U`` where ``f₁,…,fᵣ`` are +the generators stored for the description of the complement +of ``U``. This function can also be called using the +`getindex` method or simply via `U[i]`. +""" +affine_patch(U::AffineSchemeOpenSubscheme, i::Int) = affine_patches(U)[i] +gens(U::AffineSchemeOpenSubscheme) = affine_patches(U) +gen(U::AffineSchemeOpenSubscheme, i::Int) = affine_patches(U)[i] +getindex(U::AffineSchemeOpenSubscheme, i::Int) = affine_patches(U)[i] +number_of_generators(U::AffineSchemeOpenSubscheme) = number_of_patches(U) + +function getindex(U::AffineSchemeOpenSubscheme, X::AbsAffineScheme) + for i in 1:n_patches(U) + X === U[i] && return i + end + error("scheme $X not found among the open patches in $U") +end + +function getindex(U::AffineSchemeOpenSubscheme, i::Int, j::Int) + if !haskey(intersections(U), (i, j)) + intersections(U)[(i, j)] = hypersurface_complement(U[i], complement_equations(U)[j]) + intersections(U)[(j, i)] = intersections(U)[(i, j)] + end + return intersections(U)[(i,j)] +end + +#TODO: Add docstring. +function complement_ideal(U::AffineSchemeOpenSubscheme) + if !isdefined(U, :complement_ideal) + I = ideal(OO(ambient_scheme(U)), complement_equations(U)) + U.complement_ideal = I + end + return U.complement_ideal::Ideal +end + +# TODO: Add docstring. +function complement(U::AffineSchemeOpenSubscheme) + if !isdefined(U, :complement) + #I = radical(saturated_ideal(ideal(localized_ring(OO(ambient_scheme(U))), complement_equations(U)))) + #U.complement = subscheme(ambient_scheme(U), I) + U.complement = subscheme(ambient_scheme(U), complement_equations(U)) + end + return U.complement +end +function set_name!(U::AffineSchemeOpenSubscheme, name::String) + U.name = name +end + +function name(U::AffineSchemeOpenSubscheme) + if isdefined(U, :name) + return U.name + end + return "open subset of $(ambient_scheme(U))" +end + diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Constructors.jl similarity index 69% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Constructors.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Constructors.jl index c247cdb31e45..8eb9d6081c51 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Constructors.jl @@ -4,7 +4,7 @@ # TODO: Write one dummy constructor for the documentation with an ideal. @doc raw""" - function SpecOpen(X::AbsSpec, I::MPolyAnyIdeal) -> SpecOpen + function AffineSchemeOpenSubscheme(X::AbsAffineScheme, I::MPolyAnyIdeal) -> AffineSchemeOpenSubscheme Return the complement of the zero locus of ``I`` in ``X``. @@ -14,35 +14,35 @@ julia> P, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> A = Spec(P) +julia> A = spec(P) Spectrum of multivariate polynomial ring in 3 variables x, y, z over rational field -julia> SpecOpen(A, I) +julia> AffineSchemeOpenSubscheme(A, I) Open subset of affine 3-space complement to V(x^3 - y^2*z) ``` """ -function SpecOpen(X::AbsSpec, I::MPolyLocalizedIdeal; check::Bool=true) +function AffineSchemeOpenSubscheme(X::AbsAffineScheme, I::MPolyLocalizedIdeal; check::Bool=true) base_ring(I) === OO(X) || error("Ideal does not belong to the correct ring") g = [numerator(a) for a in gens(I) if !iszero(numerator(a))] - return SpecOpen(X, g, check=check) + return AffineSchemeOpenSubscheme(X, g, check=check) end -function SpecOpen(X::AbsSpec, I::MPolyQuoLocalizedIdeal; check::Bool=true) +function AffineSchemeOpenSubscheme(X::AbsAffineScheme, I::MPolyQuoLocalizedIdeal; check::Bool=true) base_ring(I) === OO(X) || error("Ideal does not belong to the correct ring") g = [lifted_numerator(a) for a in gens(I) if !iszero(numerator(a))] - return SpecOpen(X, g, check=check) + return AffineSchemeOpenSubscheme(X, g, check=check) end -function SpecOpen(X::AbsSpec, I::MPolyIdeal; check::Bool=true) - return SpecOpen(X, [g for g in gens(I) if !iszero(OO(X)(g))], check=check) +function AffineSchemeOpenSubscheme(X::AbsAffineScheme, I::MPolyIdeal; check::Bool=true) + return AffineSchemeOpenSubscheme(X, [g for g in gens(I) if !iszero(OO(X)(g))], check=check) end -function SpecOpen(X::AbsSpec, I::MPolyQuoIdeal; check::Bool=true) - return SpecOpen(X, [lift(g) for g in gens(I) if !iszero(OO(X)(g))], check=check) +function AffineSchemeOpenSubscheme(X::AbsAffineScheme, I::MPolyQuoIdeal; check::Bool=true) + return AffineSchemeOpenSubscheme(X, [lift(g) for g in gens(I) if !iszero(OO(X)(g))], check=check) end ######################################################################## @@ -63,12 +63,12 @@ julia> P, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> A = Spec(P) +julia> A = spec(P) Spectrum of multivariate polynomial ring in 3 variables x, y, z over rational field -julia> Y = Spec(P, I) +julia> Y = spec(P, I) Spectrum of quotient of multivariate polynomial ring in 3 variables x, y, z @@ -83,36 +83,36 @@ complement to V(x^3 - y^2*z) """ complement(X::Scheme,Y::Scheme) -function complement(X::AbsSpec, Z::AbsSpec{<:Ring, <:MPolyRing}) +function complement(X::AbsAffineScheme, Z::AbsAffineScheme{<:Ring, <:MPolyRing}) ambient_coordinate_ring(X) == ambient_coordinate_ring(Z) || error("X and Z do not compare") return EmptyScheme(base_ring(X)) end -function complement(X::AbsSpec, Z::AbsSpec{<:Ring, <:MPolyQuoRing}) +function complement(X::AbsAffineScheme, Z::AbsAffineScheme{<:Ring, <:MPolyQuoRing}) ambient_coordinate_ring(X) == ambient_coordinate_ring(Z) || error("X and Z do not compare") - return SpecOpen(X, modulus(OO(Z))) + return AffineSchemeOpenSubscheme(X, modulus(OO(Z))) end -function complement(X::AbsSpec, - Z::AbsSpec{<:Ring, <:MPolyQuoLocRing}; +function complement(X::AbsAffineScheme, + Z::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing}; check::Bool=true ) @check is_closed_embedding(Z, X) "not a closed embedding" - return SpecOpen(Y, modulus(underlying_quotient(OO(Z)))) + return AffineSchemeOpenSubscheme(Y, modulus(underlying_quotient(OO(Z)))) end ######################################################################## -# Conversion from AbsSpec # +# Conversion from AbsAffineScheme # ######################################################################## -SpecOpen(X::AbsSpec) = SpecOpen(X, [one(ambient_coordinate_ring(X))], check=false) +AffineSchemeOpenSubscheme(X::AbsAffineScheme) = AffineSchemeOpenSubscheme(X, [one(ambient_coordinate_ring(X))], check=false) ######################################################################## # Additional constructors # ######################################################################## @doc raw""" - product(U::SpecOpen, Z::AbsSpec) -> SpecOpen, SpecOpenMor, SpecOpenMor + product(U::AffineSchemeOpenSubscheme, Z::AbsAffineScheme) -> AffineSchemeOpenSubscheme, AffineSchemeOpenSubschemeMor, AffineSchemeOpenSubschemeMor Given a Zariski open subset `U` of an affine scheme `X`, complement to a subscheme `Y` of `X`, and given an affine scheme `Z`, return the product @@ -129,12 +129,12 @@ julia> P2, (x2, y2, z2) = polynomial_ring(QQ, [:x2, :y2, :z2]); julia> P1, (x1, y1, z1) = polynomial_ring(QQ, [:x1, :y1, :z1]); -julia> A1 = Spec(P1) +julia> A1 = spec(P1) Spectrum of multivariate polynomial ring in 3 variables x1, y1, z1 over rational field -julia> A2 = Spec(P2) +julia> A2 = spec(P2) Spectrum of multivariate polynomial ring in 3 variables x2, y2, z2 over rational field @@ -143,9 +143,9 @@ julia> I1 = ideal([x1^3-y1^2*z1]); julia> I2 = ideal([x2^2-y2^2+z2^2]); -julia> Y1 = Spec(P1, I1); +julia> Y1 = spec(P1, I1); -julia> Y2 = Spec(P2, I2); +julia> Y2 = spec(P2, I2); julia> U2 = complement(A2, Y2); @@ -158,7 +158,7 @@ Open subset complement to V(x2^2 - y2^2 + z2^2) julia> iU -Spec open morphism +Affine scheme open subscheme morphism from [x2, y2, z2, x1, y1, z1] complement to V(x2^2 - y2^2 + z2^2) to [x2, y2, z2] complement to V(x2^2 - y2^2 + z2^2) defined by the map @@ -171,7 +171,7 @@ defined by the map z2 -> z2 julia> iZ -Spec open morphism +Affine scheme open subscheme morphism from [x2, y2, z2, x1, y1, z1] complement to V(x2^2 - y2^2 + z2^2) to [x1, y1, z1] complement to V(1) defined by the map @@ -184,17 +184,17 @@ defined by the map z1 -> z1 ``` """ -function product(U::SpecOpen, Y::AbsSpec) +function product(U::AffineSchemeOpenSubscheme, Y::AbsAffineScheme) X = ambient_scheme(U) P, pX, pY = product(X, Y) - V = SpecOpen(P, lifted_numerator.(pullback(pX).(complement_equations(U)))) + V = AffineSchemeOpenSubscheme(P, lifted_numerator.(pullback(pX).(complement_equations(U)))) res_pX = restrict(pX, V, U, check=false) - res_pY = restrict(pY, V, SpecOpen(Y), check=false) + res_pY = restrict(pY, V, AffineSchemeOpenSubscheme(Y), check=false) return V, res_pX, res_pY end - -function subscheme(U::SpecOpen, I::Ideal) + +function subscheme(U::AffineSchemeOpenSubscheme, I::Ideal) Z = subscheme(ambient_scheme(U), I) #Takes care of coercion and complains if necessary - return SpecOpen(Z, [g for g in complement_equations(U) if !iszero(OO(Z)(g))]) + return AffineSchemeOpenSubscheme(Z, [g for g in complement_equations(U) if !iszero(OO(Z)(g))]) end diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Methods.jl similarity index 71% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Methods.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Methods.jl index 93cc872bd2fa..7c6b977c6809 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Methods.jl @@ -1,50 +1,50 @@ ######################################################################## -# Implementations of methods for SpecOpen # +# Implementations of methods for AffineSchemeOpenSubscheme # ######################################################################## ######################################################################## # Intersections # ######################################################################## function intersect( - Y::AbsSpec, - U::SpecOpen; + Y::AbsAffineScheme, + U::AffineSchemeOpenSubscheme; check::Bool=true ) X = ambient_scheme(U) ambient_coordinate_ring(U) === ambient_coordinate_ring(Y) || error("schemes can not be compared") - X === Y && return SpecOpen(Y, complement_equations(U), check=check) + X === Y && return AffineSchemeOpenSubscheme(Y, complement_equations(U), check=check) if check && !is_subscheme(Y, X) Y = intersect(Y, X) end - return SpecOpen(Y, [g for g in complement_equations(U) if !iszero(OO(Y)(g))], check=check) + return AffineSchemeOpenSubscheme(Y, [g for g in complement_equations(U) if !iszero(OO(Y)(g))], check=check) end -intersect(U::SpecOpen, Y::AbsSpec) = intersect(Y, U) +intersect(U::AffineSchemeOpenSubscheme, Y::AbsAffineScheme) = intersect(Y, U) function intersect( - U::SpecOpen, - V::SpecOpen + U::AffineSchemeOpenSubscheme, + V::AffineSchemeOpenSubscheme ) X = ambient_scheme(U) X == ambient_scheme(V) || error("ambient schemes do not coincide") - return SpecOpen(X, [a*b for a in complement_equations(U) for b in complement_equations(V)]) + return AffineSchemeOpenSubscheme(X, [a*b for a in complement_equations(U) for b in complement_equations(V)]) end ######################################################################## # Unions # ######################################################################## -function Base.union(U::SpecOpen, V::SpecOpen) +function Base.union(U::AffineSchemeOpenSubscheme, V::AffineSchemeOpenSubscheme) ambient_scheme(U) == ambient_scheme(V) || error("the two open sets are not contained in the same ambient scheme") - return SpecOpen(ambient_scheme(U), vcat(complement_equations(U), complement_equations(V))) + return AffineSchemeOpenSubscheme(ambient_scheme(U), vcat(complement_equations(U), complement_equations(V))) end ######################################################################## # Containment and equality # ######################################################################## function is_subscheme( - Y::AbsSpec, - U::SpecOpen + Y::AbsAffineScheme, + U::AffineSchemeOpenSubscheme ) ambient_coordinate_ring(Y) === ambient_coordinate_ring(U) || return false is_subscheme(Y, ambient_scheme(U)) || return false @@ -53,16 +53,16 @@ end function is_subscheme( - U::SpecOpen, - Y::AbsSpec - ) + U::AffineSchemeOpenSubscheme, + Y::AbsAffineScheme + ) return all(is_subscheme(V, Y) for V in affine_patches(U)) end -function is_subscheme(U::SpecOpen, V::SpecOpen) +function is_subscheme(U::AffineSchemeOpenSubscheme, V::AffineSchemeOpenSubscheme) ambient_coordinate_ring(U) === ambient_coordinate_ring(V) || return false Z = complement(V) - # perform an implicit radical membership test (Rabinowitsch) that is way more + # perform an implicit radical membership test (Rabinowitsch) that is way more # efficient than computing radicals. for g in complement_equations(U) isempty(hypersurface_complement(Z, g)) || return false @@ -72,21 +72,21 @@ function is_subscheme(U::SpecOpen, V::SpecOpen) end # TODO: Where did the type declaration go? -function ==(U::SpecSubset, V::SpecSubset) +function ==(U::AffineSchemeSubset, V::AffineSchemeSubset) ambient_coordinate_ring(U) === ambient_coordinate_ring(V) || return false return is_subscheme(U, V) && is_subscheme(V, U) end ######################################################################## -# Closures of SpecOpens # +# Closures of AffineSchemeOpenSubschemes # ######################################################################## @doc raw""" - closure(U::SpecOpen) + closure(U::AffineSchemeOpenSubscheme) -Compute the Zariski closure of an open set ``U ⊂ X`` +Compute the Zariski closure of an open set ``U ⊂ X`` where ``X`` is the affine ambient scheme of ``U``. """ -function closure(U::SpecOpen{<:StdSpec}) +function closure(U::AffineSchemeOpenSubscheme{<:StdAffineScheme}) X = ambient_scheme(U) R = ambient_coordinate_ring(X) I = saturated_ideal(modulus(OO(X))) @@ -94,11 +94,11 @@ function closure(U::SpecOpen{<:StdSpec}) return subscheme(X, I) end -function closure(U::SpecOpen{SpecType}) where {SpecType<:Spec{<:Ring, <:MPolyRing}} +function closure(U::AffineSchemeOpenSubscheme{AffineSchemeType}) where {AffineSchemeType<:AffineScheme{<:Ring, <:MPolyRing}} return ambient_scheme(U) end -function closure(U::SpecOpen{SpecType}) where {SpecType<:Spec{<:Ring, <:MPolyQuoRing}} +function closure(U::AffineSchemeOpenSubscheme{AffineSchemeType}) where {AffineSchemeType<:AffineScheme{<:Ring, <:MPolyQuoRing}} X = ambient_scheme(U) R = ambient_coordinate_ring(X) I = modulus(OO(X)) @@ -107,13 +107,13 @@ function closure(U::SpecOpen{SpecType}) where {SpecType<:Spec{<:Ring, <:MPolyQuo end @doc raw""" - closure(U::SpecOpen, Y::AbsSpec) + closure(U::AffineSchemeOpenSubscheme, Y::AbsAffineScheme) Compute the closure of ``U ⊂ Y``. """ function closure( - U::SpecOpen, - Y::AbsSpec; check::Bool=true + U::AffineSchemeOpenSubscheme, + Y::AbsAffineScheme; check::Bool=true ) @check is_subscheme(U, Y) "the first set is not contained in the second" X = closure(U) @@ -121,13 +121,13 @@ function closure( end ######################################################################## -# Preimages of open sets under SpecMors # +# Preimages of open sets under AffineSchemeMors # ######################################################################## -function preimage(f::AbsSpecMor, V::SpecOpen; check::Bool=true) +function preimage(f::AbsAffineSchemeMor, V::AffineSchemeOpenSubscheme; check::Bool=true) @check is_subscheme(codomain(f), ambient_scheme(V)) "set is not guaranteed to be open in the codomain" new_gens = pullback(f).(complement_equations(V)) - return SpecOpen(domain(f), lifted_numerator.(new_gens), check=check) + return AffineSchemeOpenSubscheme(domain(f), lifted_numerator.(new_gens), check=check) end @@ -135,7 +135,7 @@ end # Printing # ######################################################################## -function Base.show(io::IO, ::MIME"text/plain", U::SpecOpen) +function Base.show(io::IO, ::MIME"text/plain", U::AffineSchemeOpenSubscheme) io = pretty(io) println(io, "Open subset") println(io, Indent(), "of ", Lowercase(), ambient_space(U)) @@ -147,7 +147,7 @@ end # For the printing of regular functions, we need details on the affine patches. # In general, one could avoid those details by just stating what is its ambient # space and complement (see printing above) -function _show_semi_compact(io::IO, U::SpecOpen) +function _show_semi_compact(io::IO, U::AffineSchemeOpenSubscheme) io = pretty(io) println(io, "Open subset") c = ambient_coordinates(U) @@ -181,7 +181,7 @@ function _show_semi_compact(io::IO, U::SpecOpen) end end -function Base.show(io::IO, U::SpecOpen) +function Base.show(io::IO, U::AffineSchemeOpenSubscheme) show_coord = get(io, :show_coordinates, true) if get(io, :show_semi_compact, false) _show_semi_compact(io, U) @@ -209,13 +209,13 @@ end ######################################################################## # Base change ######################################################################## -function base_change(phi::Any, U::SpecOpen; - ambient_map::AbsSpecMor=base_change(phi, ambient_scheme(U))[2] # the base change on the ambient scheme +function base_change(phi::Any, U::AffineSchemeOpenSubscheme; + ambient_map::AbsAffineSchemeMor=base_change(phi, ambient_scheme(U))[2] # the base change on the ambient scheme ) Y = domain(ambient_map) pbf = pullback(ambient_map) h = pbf.(complement_equations(U)) - UU = SpecOpen(Y, h) + UU = AffineSchemeOpenSubscheme(Y, h) return UU, restrict(ambient_map, UU, U, check=true) # TODO: Set to false after testing end diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Properties.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Properties.jl similarity index 64% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Properties.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Properties.jl index b016516b8ced..228f0e0b6bb5 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Properties.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Properties.jl @@ -1,9 +1,9 @@ ######################################################################## -# Properties of SpecOpens # +# Properties of AffineSchemeOpenSubschemes # ######################################################################## -function is_dense(U::SpecOpen) +function is_dense(U::AffineSchemeOpenSubscheme) X = ambient_scheme(U) I = [modulus(OO(closure(V, X))) for V in affine_patches(U)] J = pre_image_ideal(ideal(OO(X), [one(OO(X))])) @@ -14,7 +14,7 @@ function is_dense(U::SpecOpen) end -function is_dense(U::SpecOpen{<:AbsSpec{BRT,<:MPolyQuoRing}}) where {BRT} +function is_dense(U::AffineSchemeOpenSubscheme{<:AbsAffineScheme{BRT,<:MPolyQuoRing}}) where {BRT} X = ambient_scheme(U) I = [modulus(OO(closure(V, X))) for V in affine_patches(U)] R = ambient_coordinate_ring(X) @@ -25,7 +25,7 @@ function is_dense(U::SpecOpen{<:AbsSpec{BRT,<:MPolyQuoRing}}) where {BRT} return J == modulus(OO(X)) end -function is_dense(U::SpecOpen{<:AbsSpec{BRT, <:Union{MPolyRing,MPolyLocRing}}, BRT}) where {BRT} +function is_dense(U::AffineSchemeOpenSubscheme{<:AbsAffineScheme{BRT, <:Union{MPolyRing,MPolyLocRing}}, BRT}) where {BRT} X = ambient_scheme(U) return any(V -> closure(V,X)==X, affine_patches(U)) end diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Types.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Types.jl similarity index 65% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Types.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Types.jl index 91d78e730bde..9b786ce43356 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Types.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Objects/Types.jl @@ -3,7 +3,7 @@ # Type for Zariski-open subsets of affine schemes # ######################################################################## @doc raw""" - SpecOpen{SpecType, BRT} <: Scheme{BRT} + AffineSchemeOpenSubscheme{AffineSchemeType, BRT} <: Scheme{BRT} Zariski open subset ``U`` of an affine scheme ``X = Spec(R)``. This stores a list of generators ``f₁,…,fᵣ`` of an ideal @@ -11,39 +11,39 @@ This stores a list of generators ``f₁,…,fᵣ`` of an ideal The scheme ``X`` is referred to as the *ambient scheme* and the list ``f₁,…,fᵣ`` as the *generators* for ``U``. """ -@attributes mutable struct SpecOpen{SpecType, BRT} <: Scheme{BRT} - X::SpecType # the ambient scheme +@attributes mutable struct AffineSchemeOpenSubscheme{AffineSchemeType, BRT} <: Scheme{BRT} + X::AffineSchemeType # the ambient scheme gens::Vector # a list of functions defining the complement of the open subset # fields used for caching name::String - patches::Vector{AbsSpec} - intersections::Dict{Tuple{Int, Int}, AbsSpec} - complement::AbsSpec + patches::Vector{AbsAffineScheme} + intersections::Dict{Tuple{Int, Int}, AbsAffineScheme} + complement::AbsAffineScheme complement_ideal::Ideal ring_of_functions::Ring - function SpecOpen( - X::SpecType, + function AffineSchemeOpenSubscheme( + X::AffineSchemeType, f::Vector{RET}; name::String="", check::Bool=true - ) where {SpecType<:AbsSpec, RET<:RingElem} + ) where {AffineSchemeType<:AbsAffineScheme, RET<:RingElem} for a in f parent(a) == ambient_coordinate_ring(X) || error("element does not belong to the correct ring") @check !(!isempty(X) && iszero(OO(X)(a))) "generators must not be zero" end - U = new{SpecType, typeof(base_ring(X))}(X, f) - U.intersections = Dict{Tuple{Int, Int}, AbsSpec}() + U = new{AffineSchemeType, typeof(base_ring(X))}(X, f) + U.intersections = Dict{Tuple{Int, Int}, AbsAffineScheme}() length(name) > 0 && set_name!(U, name) return U end ### Conversion from PrincipalOpenSubsets - function SpecOpen(U::PrincipalOpenSubset) + function AffineSchemeOpenSubscheme(U::PrincipalOpenSubset) X = ambient_scheme(U) h = complement_equation(U) V = new{typeof(X), typeof(base_ring(X))}(X, [lifted_numerator(h)]) - V.intersections = Dict{Tuple{Int, Int}, AbsSpec}() + V.intersections = Dict{Tuple{Int, Int}, AbsAffineScheme}() V.patches = [U] return V end @@ -53,4 +53,4 @@ end # Common type fo subsets of affine space # ######################################################################## -const SpecSubset = Union{SpecOpen,AbsSpec,PrincipalOpenSubset} +const AffineSchemeSubset = Union{AffineSchemeOpenSubscheme,AbsAffineScheme,PrincipalOpenSubset} diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Attributes.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Attributes.jl new file mode 100644 index 000000000000..be9c8cc71af5 --- /dev/null +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Attributes.jl @@ -0,0 +1,61 @@ + +######################################################################## +# Attributes of AffineSchemeOpenSubschemeRing # +######################################################################## + +######################################################################## +# Type getters # +######################################################################## +AffineSchemeOpenSubschemeRing(U::AffineSchemeOpenSubscheme) = AffineSchemeOpenSubschemeRing(ambient_scheme(U), U) + +affine_scheme_open_subscheme_ring_type(::Type{T}) where {T<:AffineScheme} = AffineSchemeOpenSubschemeRing{T, open_subset_type(T)} +affine_scheme_open_subscheme_ring_type(X::AbsAffineScheme) = affine_scheme_open_subscheme_ring_type(typeof(X)) + +ring_type(::Type{AffineSchemeOpenSubschemeType}) where {AffineSchemeOpenSubschemeType<:AffineSchemeOpenSubscheme} = AffineSchemeOpenSubschemeRing{affine_patch_type(AffineSchemeOpenSubschemeType), AffineSchemeOpenSubschemeType} +ring_type(U::AffineSchemeOpenSubscheme) = ring_type(typeof(U)) + +######################################################################## +# Basic attributes # +######################################################################## +@doc raw""" + scheme(R::AffineSchemeOpenSubschemeRing) + +The ring ``R = 𝒪(X, U)`` belongs to a sheaf of rings ``𝒪(X, -)`` and this returns +the scheme ``X`` on which ``𝒪`` is defined. +""" +scheme(R::AffineSchemeOpenSubschemeRing) = R.scheme + +gens(R::AffineSchemeOpenSubschemeRing) = R.(gens(ambient_coordinate_ring(scheme(R)))) +number_of_generators(R::AffineSchemeOpenSubschemeRing) = number_of_generators(ambient_coordinate_ring(scheme(R))) +gen(R::AffineSchemeOpenSubschemeRing, i::Int) = R(gen(ambient_coordinate_ring(scheme(R)), i)) + + +@doc raw""" + domain(R::AffineSchemeOpenSubschemeRing) + +For a ring ``R = 𝒪(X, U)``, return ``U``. +""" +domain(R::AffineSchemeOpenSubschemeRing) = R.domain + +######################################################################## +# Attributes of AffineSchemeOpenSubschemeRingElem # +######################################################################## + +######################################################################## +# Type getters # +######################################################################## +elem_type(::Type{AffineSchemeOpenSubschemeRing{S, T}}) where {S, T} = AffineSchemeOpenSubschemeRingElem{AffineSchemeOpenSubschemeRing{S, T}} +parent_type(::Type{AffineSchemeOpenSubschemeRingElem{S}}) where {S} = S + +######################################################################## +# Basic getters # +######################################################################## +parent(f::AffineSchemeOpenSubschemeRingElem) = f.parent +scheme(f::AffineSchemeOpenSubschemeRingElem) = scheme(parent(f)) +domain(f::AffineSchemeOpenSubschemeRingElem) = domain(parent(f)) +restrictions(f::AffineSchemeOpenSubschemeRingElem) = f.restrictions +affine_patches(f::AffineSchemeOpenSubschemeRingElem) = affine_patches(domain(f)) +number_of_patches(f::AffineSchemeOpenSubschemeRingElem) = length(restrictions(f)) +getindex(f::AffineSchemeOpenSubschemeRingElem, i::Int) = getindex(restrictions(f), i) +getindex(f::AffineSchemeOpenSubschemeRingElem, U::AbsAffineScheme) = restrictions(f)[domain(f)[U]] + diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Constructors.jl similarity index 57% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Constructors.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Constructors.jl index c8a6932c4a73..8781f1b2c067 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Constructors.jl @@ -1,10 +1,10 @@ ######################################################################## -# Constructors for SpecOpenRing # +# Constructors for AffineSchemeOpenSubschemeRing # ######################################################################## @doc raw""" - OO(U::SpecOpen) -> SpecOpenRing + OO(U::AffineSchemeOpenSubscheme) -> AffineSchemeOpenSubschemeRing Given a Zariski open subset `U` of an affine scheme `X`, return the ring `𝒪(X, U)` of regular functions on `U`. @@ -15,12 +15,12 @@ julia> P, (x, y, z) = polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> A = Spec(P) +julia> A = spec(P) Spectrum of multivariate polynomial ring in 3 variables x, y, z over rational field -julia> Y = Spec(P, I) +julia> Y = spec(P, I) Spectrum of quotient of multivariate polynomial ring in 3 variables x, y, z @@ -47,65 +47,65 @@ with restriction patch 1: 1 ``` """ -function OO(U::SpecOpen) - if !isdefined(U, :ring_of_functions) - U.ring_of_functions = SpecOpenRing(ambient_scheme(U), U, check=false) +function OO(U::AffineSchemeOpenSubscheme) + if !isdefined(U, :ring_of_functions) + U.ring_of_functions = AffineSchemeOpenSubschemeRing(ambient_scheme(U), U, check=false) end - return U.ring_of_functions::SpecOpenRing - #return U.ring_of_functions::SpecOpenRing{affine_patch_type(U), typeof(U)} + return U.ring_of_functions::AffineSchemeOpenSubschemeRing + #return U.ring_of_functions::AffineSchemeOpenSubschemeRing{affine_patch_type(U), typeof(U)} end ######################################################################## -# Constructors for SpecOpenRingElem # +# Constructors for AffineSchemeOpenSubschemeRingElem # ######################################################################## ######################################################################## # Coercion # ######################################################################## -(R::SpecOpenRing)(f::RingElem; check::Bool=true) = SpecOpenRingElem(R, [OO(U)(f, check=check) for U in affine_patches(domain(R))]) -(R::SpecOpenRing)(f::MPolyQuoLocRingElem; check::Bool=true) = SpecOpenRingElem(R, [_cast_fraction(OO(U),lifted_numerator(f), lifted_denominator(f), check=check) for U in affine_patches(domain(R))], check=false) +(R::AffineSchemeOpenSubschemeRing)(f::RingElem; check::Bool=true) = AffineSchemeOpenSubschemeRingElem(R, [OO(U)(f, check=check) for U in affine_patches(domain(R))]) +(R::AffineSchemeOpenSubschemeRing)(f::MPolyQuoLocRingElem; check::Bool=true) = AffineSchemeOpenSubschemeRingElem(R, [_cast_fraction(OO(U),lifted_numerator(f), lifted_denominator(f), check=check) for U in affine_patches(domain(R))], check=false) -(R::SpecOpenRing)(f::Vector{T}; check::Bool=true) where {T<:RingElem} = SpecOpenRingElem(R, [OO(domain(R)[i])(f[i], check=check) for i in 1:length(f)]) +(R::AffineSchemeOpenSubschemeRing)(f::Vector{T}; check::Bool=true) where {T<:RingElem} = AffineSchemeOpenSubschemeRingElem(R, [OO(domain(R)[i])(f[i], check=check) for i in 1:length(f)]) -function (R::SpecOpenRing)(f::SpecOpenRingElem; check::Bool=true) +function (R::AffineSchemeOpenSubschemeRing)(f::AffineSchemeOpenSubschemeRingElem; check::Bool=true) parent(f) === R && return f - return SpecOpenRingElem(R, [restrict(f, U, check=check) for U in affine_patches(domain(R))]) + return AffineSchemeOpenSubschemeRingElem(R, [restrict(f, U, check=check) for U in affine_patches(domain(R))]) end ######################################################################## # Additional constructors for the Ring interface # ######################################################################## -one(R::SpecOpenRing) = SpecOpenRingElem(R, [one(OO(U)) for U in affine_patches(domain(R))], check=false) -zero(R::SpecOpenRing) = SpecOpenRingElem(R, [zero(OO(U)) for U in affine_patches(domain(R))], check=false) -(R::SpecOpenRing)() = zero(R) -(R::SpecOpenRing)(a::Integer) = SpecOpenRingElem(R, [OO(U)(a) for U in affine_patches(domain(R))], check=false) -(R::SpecOpenRing)(a::Int64) = SpecOpenRingElem(R, [OO(U)(a) for U in affine_patches(domain(R))], check=false) -(R::SpecOpenRing)(a::ZZRingElem) = SpecOpenRingElem(R, [OO(U)(a) for U in affine_patches(domain(R))], check=false) +one(R::AffineSchemeOpenSubschemeRing) = AffineSchemeOpenSubschemeRingElem(R, [one(OO(U)) for U in affine_patches(domain(R))], check=false) +zero(R::AffineSchemeOpenSubschemeRing) = AffineSchemeOpenSubschemeRingElem(R, [zero(OO(U)) for U in affine_patches(domain(R))], check=false) +(R::AffineSchemeOpenSubschemeRing)() = zero(R) +(R::AffineSchemeOpenSubschemeRing)(a::Integer) = AffineSchemeOpenSubschemeRingElem(R, [OO(U)(a) for U in affine_patches(domain(R))], check=false) +(R::AffineSchemeOpenSubschemeRing)(a::Int64) = AffineSchemeOpenSubschemeRingElem(R, [OO(U)(a) for U in affine_patches(domain(R))], check=false) +(R::AffineSchemeOpenSubschemeRing)(a::ZZRingElem) = AffineSchemeOpenSubschemeRingElem(R, [OO(U)(a) for U in affine_patches(domain(R))], check=false) ######################################################################## # Copying # ######################################################################## -function Base.deepcopy_internal(f::SpecOpenRingElem, dict::IdDict) - return SpecOpenRingElem(parent(f), copy(restrictions(f)), check=false) +function Base.deepcopy_internal(f::AffineSchemeOpenSubschemeRingElem, dict::IdDict) + return AffineSchemeOpenSubschemeRingElem(parent(f), copy(restrictions(f)), check=false) end ######################################################################## # Maximal extensions of rational functions on affine schemes # ######################################################################## @doc raw""" - maximal_extension(X::Spec, f::AbstractAlgebra.Generic.FracFieldElem) + maximal_extension(X::AffineScheme, f::AbstractAlgebra.Generic.FracFieldElem) Return the maximal extension of the restriction of ``f`` -to a rational function on ``X`` on a maximal domain of -definition ``U ⊂ X``. +to a rational function on ``X`` on a maximal domain of +definition ``U ⊂ X``. -**Note:** When ``X = Spec(R)`` with ``R = (𝕜[x₁,…,xₙ]/I)[S⁻¹]``, -the numerator and denominator of ``f`` have to be elements of +**Note:** When ``X = Spec(R)`` with ``R = (𝕜[x₁,…,xₙ]/I)[S⁻¹]``, +the numerator and denominator of ``f`` have to be elements of the ring ``𝕜[x₁,…,xₙ]``. """ function maximal_extension( - X::AbsSpec{<:Ring, <:MPolyLocRing}, + X::AbsAffineScheme{<:Ring, <:MPolyLocRing}, f::AbstractAlgebra.Generic.FracFieldElem{RET} ) where {RET<:MPolyRingElem} @@ -118,14 +118,14 @@ function maximal_extension( f = parent(f)(a,b) end W = OO(X) - U = SpecOpen(X, [b]) + U = AffineSchemeOpenSubscheme(X, [b]) g = [OO(V)(f) for V in affine_patches(U)] - R = SpecOpenRing(X, U) + R = AffineSchemeOpenSubschemeRing(X, U) return R(g) end function maximal_extension( - X::AbsSpec{<:Ring, <:MPolyQuoLocRing}, + X::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing}, f::AbstractAlgebra.Generic.FracFieldElem{RET} ) where {RET<:RingElem} @@ -133,57 +133,57 @@ function maximal_extension( b = denominator(f) W = localized_ring(OO(X)) I = quotient(ideal(W, b) + modulus(OO(X)), ideal(W, a)) - U = SpecOpen(X, I) + U = AffineSchemeOpenSubscheme(X, I) g = [OO(V)(f) for V in affine_patches(U)] - R = SpecOpenRing(X, U) + R = AffineSchemeOpenSubschemeRing(X, U) return R(g) end function maximal_extension( - X::AbsSpec{<:Ring, <:MPolyQuoRing}, + X::AbsAffineScheme{<:Ring, <:MPolyQuoRing}, f::AbstractAlgebra.Generic.FracFieldElem{RET} ) where {RET<:RingElem} a = numerator(f) b = denominator(f) W = ambient_coordinate_ring(X) I = quotient(ideal(W, b) + modulus(OO(X)), ideal(W, a)) - U = SpecOpen(X, I) + U = AffineSchemeOpenSubscheme(X, I) g = [OO(V)(f) for V in affine_patches(U)] - R = SpecOpenRing(X, U) + R = AffineSchemeOpenSubschemeRing(X, U) return R(g) end function maximal_extension( - X::AbsSpec{<:Ring, <:MPolyRing}, + X::AbsAffineScheme{<:Ring, <:MPolyRing}, f::AbstractAlgebra.Generic.FracFieldElem{RET} ) where {RET<:RingElem} a = numerator(f) b = denominator(f) W = ambient_coordinate_ring(X) I = quotient(ideal(W, b), ideal(W, a)) - U = SpecOpen(X, I) + U = AffineSchemeOpenSubscheme(X, I) g = [OO(V)(f) for V in affine_patches(U)] - R = SpecOpenRing(X, U) + R = AffineSchemeOpenSubschemeRing(X, U) return R(g) end @doc raw""" - maximal_extension(X::Spec, f::Vector{AbstractAlgebra.Generic.FracFieldElem}) + maximal_extension(X::AffineScheme, f::Vector{AbstractAlgebra.Generic.FracFieldElem}) Return the extension of the restriction of the ``fᵢ`` as a -set of rational functions on ``X`` as *regular* functions to a +set of rational functions on ``X`` as *regular* functions to a common maximal domain of definition ``U ⊂ X``. -**Note:** When ``X = Spec(R)`` with ``R = (𝕜[x₁,…,xₙ]/I)[S⁻¹]``, -the numerators and denominators of the entries of ``f`` have to +**Note:** When ``X = Spec(R)`` with ``R = (𝕜[x₁,…,xₙ]/I)[S⁻¹]``, +the numerators and denominators of the entries of ``f`` have to be elements of the ring ``𝕜[x₁,…,xₙ]``. """ function maximal_extension( - X::AbsSpec{<:Ring, <:AbsLocalizedRing}, + X::AbsAffineScheme{<:Ring, <:AbsLocalizedRing}, f::Vector{AbstractAlgebra.Generic.FracFieldElem{RET}} ) where {RET<:RingElem} if length(f) == 0 - return SpecOpen(X), Vector{structure_sheaf_elem_type(X)}() + return AffineSchemeOpenSubscheme(X), Vector{structure_sheaf_elem_type(X)}() end R = base_ring(parent(f[1])) for a in f @@ -197,19 +197,19 @@ function maximal_extension( for p in f I = intersect(quotient(ideal(W, denominator(p)), ideal(W, numerator(p))), I) end - U = SpecOpen(X, I) - S = SpecOpenRing(X, U) - # TODO: For some reason, the type of the inner vector is not inferred if it has no entries. + U = AffineSchemeOpenSubscheme(X, I) + S = AffineSchemeOpenSubschemeRing(X, U) + # TODO: For some reason, the type of the inner vector is not inferred if it has no entries. # Investigate why? Type instability? - return U, [SpecOpenRingElem(S, (elem_type(OO(X))[OO(V)(a) for V in affine_patches(U)])) for a in f] + return U, [AffineSchemeOpenSubschemeRingElem(S, (elem_type(OO(X))[OO(V)(a) for V in affine_patches(U)])) for a in f] end function maximal_extension( - X::AbsSpec{<:Ring, <:MPolyRing}, + X::AbsAffineScheme{<:Ring, <:MPolyRing}, f::Vector{AbstractAlgebra.Generic.FracFieldElem{RET}} ) where {RET<:RingElem} if length(f) == 0 - return SpecOpen(X), Vector{structure_sheaf_elem_type(X)}() + return AffineSchemeOpenSubscheme(X), Vector{structure_sheaf_elem_type(X)}() end R = base_ring(parent(f[1])) for a in f @@ -221,19 +221,19 @@ function maximal_extension( for p in f I = intersect(quotient(ideal(W, denominator(p)), ideal(W, numerator(p))), I) end - U = SpecOpen(X, I) - S = SpecOpenRing(X, U) - # TODO: For some reason, the type of the inner vector is not inferred if it has no entries. + U = AffineSchemeOpenSubscheme(X, I) + S = AffineSchemeOpenSubschemeRing(X, U) + # TODO: For some reason, the type of the inner vector is not inferred if it has no entries. # Investigate why? Type instability? - return U, [SpecOpenRingElem(S, [OO(V)(a) for V in affine_patches(U)]) for a in f] + return U, [AffineSchemeOpenSubschemeRingElem(S, [OO(V)(a) for V in affine_patches(U)]) for a in f] end function maximal_extension( - X::AbsSpec{<:Ring, <:MPolyQuoRing}, + X::AbsAffineScheme{<:Ring, <:MPolyQuoRing}, f::Vector{AbstractAlgebra.Generic.FracFieldElem{RET}} ) where {RET<:RingElem} if length(f) == 0 - return SpecOpen(X), Vector{structure_sheaf_elem_type(X)}() + return AffineSchemeOpenSubscheme(X), Vector{structure_sheaf_elem_type(X)}() end R = base_ring(parent(f[1])) for a in f @@ -245,18 +245,18 @@ function maximal_extension( for p in f I = intersect(quotient(ideal(W, denominator(p)), ideal(W, numerator(p))), I) end - U = SpecOpen(X, I) - S = SpecOpenRing(X, U) - # TODO: For some reason, the type of the inner vector is not inferred if it has no entries. + U = AffineSchemeOpenSubscheme(X, I) + S = AffineSchemeOpenSubschemeRing(X, U) + # TODO: For some reason, the type of the inner vector is not inferred if it has no entries. # Investigate why? Type instability? - return U, [SpecOpenRingElem(S, [OO(V)(a) for V in affine_patches(U)]) for a in f] + return U, [AffineSchemeOpenSubschemeRingElem(S, [OO(V)(a) for V in affine_patches(U)]) for a in f] end #TODO: implement the catchall versions of the above functions. ######################################################################## # Subscheme constructors # ######################################################################## -function subscheme(U::SpecOpen, g::Vector{T}) where {T<:SpecOpenRingElem} +function subscheme(U::AffineSchemeOpenSubscheme, g::Vector{T}) where {T<:AffineSchemeOpenSubschemeRingElem} all(x->(parent(x)==OO(U)), g) || error("elements do not belong to the correct ring") X = ambient_scheme(U) gen_list = Vector{elem_type(OO(X))}() @@ -264,6 +264,6 @@ function subscheme(U::SpecOpen, g::Vector{T}) where {T<:SpecOpenRingElem} gen_list = vcat(gen_list, OO(X).([lifted_numerator(f[i]) for i in 1:ngens(U)])) end Z = subscheme(X, gen_list) - return SpecOpen(Z, complement_equations(U)) + return AffineSchemeOpenSubscheme(Z, complement_equations(U)) end diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Methods.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Methods.jl similarity index 67% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Methods.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Methods.jl index bc36cbb8f881..327467b68d3e 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Methods.jl @@ -1,21 +1,21 @@ ######################################################################## -# Methods for SpecOpenRing # +# Methods for AffineSchemeOpenSubschemeRing # ######################################################################## -function ==(R::SpecOpenRing, S::SpecOpenRing) +function ==(R::AffineSchemeOpenSubschemeRing, S::AffineSchemeOpenSubschemeRing) return scheme(R)==scheme(S) && domain(R)==domain(S) end ######################################################################## -# Methods for SpecOpenRingElem # +# Methods for AffineSchemeOpenSubschemeRingElem # ######################################################################## ######################################################################## # Restrictions of regular functions # ######################################################################## function restrict( - f::SpecOpenRingElem, - V::AbsSpec{<:Ring, <:MPolyQuoLocRing}; + f::AffineSchemeOpenSubschemeRingElem, + V::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing}; check::Bool=true ) check && isempty(V) && return zero(OO(V)) @@ -34,8 +34,8 @@ function restrict( end function restrict( - f::SpecOpenRingElem, - V::AbsSpec{<:Ring, <:MPolyLocRing}; + f::AffineSchemeOpenSubschemeRingElem, + V::AbsAffineScheme{<:Ring, <:MPolyLocRing}; check::Bool=true ) check && isempty(V) && return zero(OO(V)) @@ -54,34 +54,34 @@ function restrict( end function restrict( - f::SpecOpenRingElem, - V::SpecOpen; + f::AffineSchemeOpenSubschemeRingElem, + V::AffineSchemeOpenSubscheme; check::Bool=true # Only for compatibility of the call signature ) V === domain(parent(f)) && return f fres = [restrict(f, V[i]) for i in 1:ngens(V)] - return SpecOpenRingElem(OO(V), fres, check=false) + return AffineSchemeOpenSubschemeRingElem(OO(V), fres, check=false) end ######################################################################## # Generic fractions # ######################################################################## @doc raw""" - generic_fraction(a::SpecOpenRingElem, U::SpecOpen) + generic_fraction(a::AffineSchemeOpenSubschemeRingElem, U::AffineSchemeOpenSubscheme) -Given a regular function ``a ∈ 𝒪(U)`` on a Zariski open -subset ``U ⊂ X`` of an affine scheme ``X``, return a +Given a regular function ``a ∈ 𝒪(U)`` on a Zariski open +subset ``U ⊂ X`` of an affine scheme ``X``, return a fraction ``p/q`` in `Quot(P)` (where ``P`` is the `ambient_coordinate_ring` of the `ambient` scheme ``X`` of ``U``) which represents ``a`` in the sense that the maximal extension of its restriction to ``U`` returns ``a``. -**Note:** The seemingly superfluous argument ``U`` is needed -to have a coherent syntax with the method for regular functions -``a`` on `PrincipalOpenSubset`s. There, the element ``a`` does +**Note:** The seemingly superfluous argument ``U`` is needed +to have a coherent syntax with the method for regular functions +``a`` on `PrincipalOpenSubset`s. There, the element ``a`` does not know about its scheme, so it has to be passed as an extra argument. """ -function generic_fraction(a::SpecOpenRingElem, U::SpecOpen) +function generic_fraction(a::AffineSchemeOpenSubschemeRingElem, U::AffineSchemeOpenSubscheme) U === domain(a) || error("domains are not compatible") X = ambient_scheme(U) d = find_non_zero_divisor(U) @@ -93,38 +93,38 @@ end ######################################################################## # Arithmetic # ######################################################################## -function +(a::T, b::T) where {T<:SpecOpenRingElem} +function +(a::T, b::T) where {T<:AffineSchemeOpenSubschemeRingElem} parent(a) === parent(b) || return a + (parent(a)(b)) - return SpecOpenRingElem(parent(a), [a[i] + b[i] for i in 1:length(restrictions(a))], check=false) + return AffineSchemeOpenSubschemeRingElem(parent(a), [a[i] + b[i] for i in 1:length(restrictions(a))], check=false) end -function -(a::T, b::T) where {T<:SpecOpenRingElem} +function -(a::T, b::T) where {T<:AffineSchemeOpenSubschemeRingElem} parent(a) === parent(b) || return a - (parent(a)(b)) - return SpecOpenRingElem(parent(a), [a[i] - b[i] for i in 1:length(restrictions(a))], check=false) + return AffineSchemeOpenSubschemeRingElem(parent(a), [a[i] - b[i] for i in 1:length(restrictions(a))], check=false) end -function -(a::T) where {T<:SpecOpenRingElem} - return SpecOpenRingElem(parent(a), [-a[i] for i in 1:length(restrictions(a))], check=false) +function -(a::T) where {T<:AffineSchemeOpenSubschemeRingElem} + return AffineSchemeOpenSubschemeRingElem(parent(a), [-a[i] for i in 1:length(restrictions(a))], check=false) end -function *(a::T, b::T) where {T<:SpecOpenRingElem} +function *(a::T, b::T) where {T<:AffineSchemeOpenSubschemeRingElem} parent(a) === parent(b) || return a * (parent(a)(b)) - return SpecOpenRingElem(parent(a), [a[i] * b[i] for i in 1:length(restrictions(a))], check=false) + return AffineSchemeOpenSubschemeRingElem(parent(a), [a[i] * b[i] for i in 1:length(restrictions(a))], check=false) end -#function *(a::RingElem, b::T) where {T<:SpecOpenRingElem} +#function *(a::RingElem, b::T) where {T<:AffineSchemeOpenSubschemeRingElem} # return b*(parent(b)(a)) #end -function *(a::Integer, b::T) where {T<:SpecOpenRingElem} +function *(a::Integer, b::T) where {T<:AffineSchemeOpenSubschemeRingElem} return b*(parent(b)(a)) end -#function *(b::T, a::RingElem) where {T<:SpecOpenRingElem} +#function *(b::T, a::RingElem) where {T<:AffineSchemeOpenSubschemeRingElem} # return a*b #end -function ==(a::T, b::T) where {T<:SpecOpenRingElem} +function ==(a::T, b::T) where {T<:AffineSchemeOpenSubschemeRingElem} parent(a) === parent(b) || return a == (parent(a)(b)) for i in 1:length(restrictions(a)) a[i] == b[i] || return false @@ -132,48 +132,48 @@ function ==(a::T, b::T) where {T<:SpecOpenRingElem} return true end -function ^(a::SpecOpenRingElem, i::Int64) - return SpecOpenRingElem(parent(a), [a[k]^i for k in 1:length(restrictions(a))]) +function ^(a::AffineSchemeOpenSubschemeRingElem, i::Int64) + return AffineSchemeOpenSubschemeRingElem(parent(a), [a[k]^i for k in 1:length(restrictions(a))]) end -function ^(a::SpecOpenRingElem, i::Integer) - return SpecOpenRingElem(parent(a), [a[k]^i for k in 1:length(restrictions(a))]) +function ^(a::AffineSchemeOpenSubschemeRingElem, i::Integer) + return AffineSchemeOpenSubschemeRingElem(parent(a), [a[k]^i for k in 1:length(restrictions(a))]) end -function ^(a::SpecOpenRingElem, i::ZZRingElem) - return SpecOpenRingElem(parent(a), [a[k]^i for k in 1:length(restrictions(a))]) +function ^(a::AffineSchemeOpenSubschemeRingElem, i::ZZRingElem) + return AffineSchemeOpenSubschemeRingElem(parent(a), [a[k]^i for k in 1:length(restrictions(a))]) end -function divexact(a::T, b::T; check::Bool=false) where {T<:SpecOpenRingElem} +function divexact(a::T, b::T; check::Bool=false) where {T<:AffineSchemeOpenSubschemeRingElem} parent(a) === parent(b) || return divexact(a, (parent(a)(b))) - return SpecOpenRingElem(parent(a), [divexact(a[i], b[i]) for i in 1:length(restrictions(a))]) + return AffineSchemeOpenSubschemeRingElem(parent(a), [divexact(a[i], b[i]) for i in 1:length(restrictions(a))]) end -function is_unit(a::SpecOpenRingElem) +function is_unit(a::AffineSchemeOpenSubschemeRingElem) return all(x->is_unit(x), restrictions(a)) end -inv(a::SpecOpenRingElem) = SpecOpenRingElem(parent(a), [inv(f) for f in restrictions(a)], check=false) +inv(a::AffineSchemeOpenSubschemeRingElem) = AffineSchemeOpenSubschemeRingElem(parent(a), [inv(f) for f in restrictions(a)], check=false) ######################################################################## # Promote rules for the ring interface # ######################################################################## -AbstractAlgebra.promote_rule(::Type{T}, ::Type{RET}) where {T<:SpecOpenRingElem, RET<:Integer} = T -AbstractAlgebra.promote_rule(::Type{RET}, ::Type{T}) where {T<:SpecOpenRingElem, RET<:Integer} = T +AbstractAlgebra.promote_rule(::Type{T}, ::Type{RET}) where {T<:AffineSchemeOpenSubschemeRingElem, RET<:Integer} = T +AbstractAlgebra.promote_rule(::Type{RET}, ::Type{T}) where {T<:AffineSchemeOpenSubschemeRingElem, RET<:Integer} = T -### Promote rules from and to other rings can not be made in a coherent -# way depending only on the types. One problem is that both, restricting -# from and to an affine scheme are valid operations, depending on the -# specific geometric configuration. Hence, we rely on the user to perform -# every coercion manually. +### Promote rules from and to other rings can not be made in a coherent +# way depending only on the types. One problem is that both, restricting +# from and to an affine scheme are valid operations, depending on the +# specific geometric configuration. Hence, we rely on the user to perform +# every coercion manually. -# Additional promotions to make (graded) polynomial rings and their quotients work over SpecOpenRings. -*(a::S, b::T) where {S<:SpecOpenRingElem, T<:MPolyRingElem{S}} = parent(b)(a)*b -*(a::S, b::T) where {S<:SpecOpenRingElem, T<:MPolyDecRingElem{S}} = parent(b)(a)*b -*(a::S, b::T) where {S<:SpecOpenRingElem, T<:MPolyQuoRingElem{MPolyDecRingElem{S}}} = parent(b)(a)*b -*(a::S, b::T) where {S<:SpecOpenRingElem, T<:MPolyQuoRingElem{MPolyRingElem{S}}} = parent(b)(a)*b +# Additional promotions to make (graded) polynomial rings and their quotients work over AffineSchemeOpenSubschemeRings. +*(a::S, b::T) where {S<:AffineSchemeOpenSubschemeRingElem, T<:MPolyRingElem{S}} = parent(b)(a)*b +*(a::S, b::T) where {S<:AffineSchemeOpenSubschemeRingElem, T<:MPolyDecRingElem{S}} = parent(b)(a)*b +*(a::S, b::T) where {S<:AffineSchemeOpenSubschemeRingElem, T<:MPolyQuoRingElem{MPolyDecRingElem{S}}} = parent(b)(a)*b +*(a::S, b::T) where {S<:AffineSchemeOpenSubschemeRingElem, T<:MPolyQuoRingElem{MPolyRingElem{S}}} = parent(b)(a)*b -*(b::T, a::S) where {S<:SpecOpenRingElem, T<:MPolyDecRingElem{S}} = parent(b)(a)*b -*(b::T, a::S) where {S<:SpecOpenRingElem, T<:MPolyQuoRingElem{MPolyDecRingElem{S}}} = parent(b)(a)*b -*(b::T, a::S) where {S<:SpecOpenRingElem, T<:MPolyQuoRingElem{MPolyRingElem{S}}} = parent(b)(a)*b +*(b::T, a::S) where {S<:AffineSchemeOpenSubschemeRingElem, T<:MPolyDecRingElem{S}} = parent(b)(a)*b +*(b::T, a::S) where {S<:AffineSchemeOpenSubschemeRingElem, T<:MPolyQuoRingElem{MPolyDecRingElem{S}}} = parent(b)(a)*b +*(b::T, a::S) where {S<:AffineSchemeOpenSubschemeRingElem, T<:MPolyQuoRingElem{MPolyRingElem{S}}} = parent(b)(a)*b ######################################################################## # Additional methods for compatibility and coherence # @@ -191,7 +191,7 @@ function _cast_fraction(R::Union{<:MPolyLocRing, <:MPolyQuoLocRing}, a, b; check end ######################################################################## -# Restrictions of regular functions from SpecOpens to AbsSpecs # +# Restrictions of regular functions from AffineSchemeOpenSubschemes to AbsAffineSchemes # # and vice versa # ######################################################################## @@ -199,17 +199,17 @@ end # complement X = D(h) ⊂ Y with X ⊂ U this returns the restriction # map ρ : 𝒪(U) → 𝒪(X) function restriction_map( - U::SpecOpen, - X::AbsSpec{<:Ring, <:AbsLocalizedRing}, - h::MPolyRingElem; + U::AffineSchemeOpenSubscheme, + X::AbsAffineScheme{<:Ring, <:AbsLocalizedRing}, + h::MPolyRingElem; check::Bool=true ) Y = ambient_scheme(U) - # handle the shortcut + # handle the shortcut if any(x->(x===X), affine_patches(U)) i = findfirst(x->(x === X), affine_patches(U)) - function mymap(f::SpecOpenRingElem) + function mymap(f::AffineSchemeOpenSubschemeRingElem) return f[i] end return MapFromFunc(OO(U), OO(X), mymap) @@ -224,28 +224,28 @@ function restriction_map( # first find some basic relation hᵏ= ∑ᵢ aᵢ⋅dᵢ d = complement_equations(U) I = complement_ideal(U) - # _minimal_power_such_that(P, h) returns a tuple (k, h^k) with + # _minimal_power_such_that(P, h) returns a tuple (k, h^k) with # k the minimal exponent such that the property P(h^k) returns `true`. (k, poh) = Oscar._minimal_power_such_that(h, x->(base_ring(I)(x) in I)) a = coordinates(base_ring(I)(poh), I) r = length(d) # the local representatives of the input f will be of the form gᵢ⋅1//dᵢˢ⁽ⁱ⁾ - # with gᵢ∈ 𝒪(Y). For higher powers s(i) > 1 we need other coefficients - # cᵢ for the relation + # with gᵢ∈ 𝒪(Y). For higher powers s(i) > 1 we need other coefficients + # cᵢ for the relation # # hˡ = ∑ᵢ cᵢ⋅dˢ⁽ⁱ⁾ # # for some power hˡ. To this end, we set up a polynomial ring 𝒪(Y)[t₁,…,tᵣ] - # and take powers of the element ∑ᵢaᵢ⋅tᵢ with the coefficients aᵢ of the basic - # relation. Eventually, all terms appearing in that expression will have - # monomials t₁ᵉ⁽¹⁾⋅…⋅tᵣᵉ⁽ʳ⁾ with some e(i) ≥ s(i). Substituting and grouping + # and take powers of the element ∑ᵢaᵢ⋅tᵢ with the coefficients aᵢ of the basic + # relation. Eventually, all terms appearing in that expression will have + # monomials t₁ᵉ⁽¹⁾⋅…⋅tᵣᵉ⁽ʳ⁾ with some e(i) ≥ s(i). Substituting and grouping # the terms accordingly, we derive the desired expressions for the cᵢ's. #W = localized_ring(OO(Y)) W = OO(Y) S, t = polynomial_ring(W, ["t$i" for i in 1:r]) ta = length(a) == 0 ? zero(S) : sum([t*a for (t, a) in zip(t, a)]) - function mysecondmap(f::SpecOpenRingElem) + function mysecondmap(f::AffineSchemeOpenSubschemeRingElem) sep = [pull_from_denominator(f[i], d[i]) for i in 1:r] # the following takes care of oddities from zero divisors. for i in 1:r-1 @@ -297,10 +297,10 @@ function restriction_map( return MapFromFunc(OO(U), OO(X), mysecondmap) end -# Automatically find a hypersurface equation h such that X = D(h) in -# the ambient scheme Y of U. -function restriction_map(U::SpecOpen{<:AbsSpec{<:Ring, <:AbsLocalizedRing}}, - X::AbsSpec{<:Ring, <:AbsLocalizedRing}; +# Automatically find a hypersurface equation h such that X = D(h) in +# the ambient scheme Y of U. +function restriction_map(U::AffineSchemeOpenSubscheme{<:AbsAffineScheme{<:Ring, <:AbsLocalizedRing}}, + X::AbsAffineScheme{<:Ring, <:AbsLocalizedRing}; check::Bool=true ) Y = ambient_scheme(U) @@ -323,8 +323,8 @@ end # Automatically find a hypersurface equation h such that X = D(h) in # the ambient scheme Y of U. -function restriction_map(U::SpecOpen{<:AbsSpec{<:Ring, <:MPolyQuoRing}}, - X::AbsSpec{<:Ring, <:AbsLocalizedRing}; +function restriction_map(U::AffineSchemeOpenSubscheme{<:AbsAffineScheme{<:Ring, <:MPolyQuoRing}}, + X::AbsAffineScheme{<:Ring, <:AbsLocalizedRing}; check::Bool=true ) Y = ambient_scheme(U) @@ -338,8 +338,8 @@ function restriction_map(U::SpecOpen{<:AbsSpec{<:Ring, <:MPolyQuoRing}}, return restriction_map(U, X, h, check=false) end -function restriction_map(U::SpecOpen{<:AbsSpec{<:Ring, <:MPolyRing}}, - X::AbsSpec{<:Ring, <:AbsLocalizedRing}; +function restriction_map(U::AffineSchemeOpenSubscheme{<:AbsAffineScheme{<:Ring, <:MPolyRing}}, + X::AbsAffineScheme{<:Ring, <:AbsLocalizedRing}; check::Bool=true ) Y = ambient_scheme(U) @@ -354,8 +354,8 @@ function restriction_map(U::SpecOpen{<:AbsSpec{<:Ring, <:MPolyRing}}, end -# For f = p//q and d this computes a decomposition p', q', d^k, k -# such that f = p'//(q'⋅d^k) and q' and d have no common factors. +# For f = p//q and d this computes a decomposition p', q', d^k, k +# such that f = p'//(q'⋅d^k) and q' and d have no common factors. function pull_from_denominator(f::MPolyQuoLocRingElem, d::MPolyRingElem) p = lifted_numerator(f) q = lifted_denominator(f) @@ -374,20 +374,20 @@ function pull_from_denominator(f::MPolyLocRingElem, d::MPolyRingElem) return b*p, o, pod, k end -function restriction_map(X::Spec, U::SpecOpen; check::Bool=true) +function restriction_map(X::AffineScheme, U::AffineSchemeOpenSubscheme; check::Bool=true) Y = ambient_scheme(U) @check all(V->is_subscheme(V, X), affine_patches(U)) "$U is not a subset of $X" function mymap(f::MPolyQuoLocRingElem) - return SpecOpenRingElem(OO(U), [OO(V)(f) for V in affine_patches(U)]) + return AffineSchemeOpenSubschemeRingElem(OO(U), [OO(V)(f) for V in affine_patches(U)]) end return MapFromFunc(OO(X), OO(U), mymap) end -function restriction_map(U::SpecOpen, V::SpecOpen; check::Bool=true) +function restriction_map(U::AffineSchemeOpenSubscheme, V::AffineSchemeOpenSubscheme; check::Bool=true) @check is_subscheme(V, U) "$V is not a subset of $U" if U === V - function mymap(f::SpecOpenRingElem) + function mymap(f::AffineSchemeOpenSubschemeRingElem) return f end return MapFromFunc(OO(U), OO(V), mymap) @@ -395,29 +395,29 @@ function restriction_map(U::SpecOpen, V::SpecOpen; check::Bool=true) if ambient_scheme(U) === ambient_scheme(V) g = [restriction_map(U, W, d, check=false) for (W, d) in zip(affine_patches(V), complement_equations(V))] - function mysecondmap(f::SpecOpenRingElem) - return SpecOpenRingElem(OO(V), [h(f) for h in g], check=false) + function mysecondmap(f::AffineSchemeOpenSubschemeRingElem) + return AffineSchemeOpenSubschemeRingElem(OO(V), [h(f) for h in g], check=false) end return MapFromFunc(OO(U), OO(V), mysecondmap) end - + g = [restriction_map(U, W, check=false) for W in affine_patches(V)] - function mythirdmap(f::SpecOpenRingElem) - return SpecOpenRingElem(OO(V), [g(f) for g in g], check=false) + function mythirdmap(f::AffineSchemeOpenSubschemeRingElem) + return AffineSchemeOpenSubschemeRingElem(OO(V), [g(f) for g in g], check=false) end return MapFromFunc(OO(U), OO(V), mythirdmap) end ######################################################################## -# Maps of SpecOpenRings # +# Maps of AffineSchemeOpenSubschemeRings # ######################################################################## -function is_identity_map(f::Map{DomType, CodType}) where {DomType<:SpecOpenRing, CodType<:SpecOpenRing} +function is_identity_map(f::Map{DomType, CodType}) where {DomType<:AffineSchemeOpenSubschemeRing, CodType<:AffineSchemeOpenSubschemeRing} domain(f) === codomain(f) || return false R = ambient_coordinate_ring(scheme(domain(f))) return all(x->(domain(f)(x) == f(domain(f)(x))), gens(R)) end -function canonical_isomorphism(S::SpecOpenRing, T::SpecOpenRing; check::Bool=true) +function canonical_isomorphism(S::AffineSchemeOpenSubschemeRing, T::AffineSchemeOpenSubschemeRing; check::Bool=true) X = scheme(S) Y = scheme(T) R = ambient_coordinate_ring(X) @@ -428,18 +428,18 @@ function canonical_isomorphism(S::SpecOpenRing, T::SpecOpenRing; check::Bool=tru pb_to_Vs = [restriction_map(domain(S), V) for V in affine_patches(domain(T))] pb_to_Us = [restriction_map(domain(T), U) for U in affine_patches(domain(S))] - function mymap(a::SpecOpenRingElem) - return SpecOpenRingElem(T, [g(a) for g in pb_to_Vs], check=false) + function mymap(a::AffineSchemeOpenSubschemeRingElem) + return AffineSchemeOpenSubschemeRingElem(T, [g(a) for g in pb_to_Vs], check=false) end - function myinvmap(b::SpecOpenRingElem) - return SpecOpenRingElem(S, [g(b) for g in pb_to_Us], check=false) + function myinvmap(b::AffineSchemeOpenSubschemeRingElem) + return AffineSchemeOpenSubschemeRingElem(S, [g(b) for g in pb_to_Us], check=false) end return MapFromFunc(S, T, mymap, myinvmap) end -# Special override for a case where even ideal membership and ring flattenings -# are not implemented. -function simplify(f::MPolyQuoRingElem{<:MPolyDecRingElem{<:SpecOpenRingElem}}) +# Special override for a case where even ideal membership and ring flattenings +# are not implemented. +function simplify(f::MPolyQuoRingElem{<:MPolyDecRingElem{<:AffineSchemeOpenSubschemeRingElem}}) return f end @@ -449,7 +449,7 @@ end # ############################################################################### -function Base.show(io::IO, R::SpecOpenRing) +function Base.show(io::IO, R::AffineSchemeOpenSubschemeRing) if get(io, :supercompact, false) print(io, "Ring of regular functions") else @@ -459,7 +459,7 @@ function Base.show(io::IO, R::SpecOpenRing) end # Here we just need some details on the domain `U`. -function Base.show(io::IO, ::MIME"text/plain", R::SpecOpenRing) +function Base.show(io::IO, ::MIME"text/plain", R::AffineSchemeOpenSubschemeRing) io = pretty(io) println(io, "Ring of regular functions") print(io, Indent(), "on ", Lowercase()) @@ -467,7 +467,7 @@ function Base.show(io::IO, ::MIME"text/plain", R::SpecOpenRing) print(io, Dedent()) end -function Base.show(io::IO, a::SpecOpenRingElem) +function Base.show(io::IO, a::AffineSchemeOpenSubschemeRingElem) if get(io, :supercompact, false) print(io, "Reguler function") else @@ -480,7 +480,7 @@ end # on which they are defined, we need to extract details about the affine patches # on `U` and label them so that one can see how the regular function is defined # on each patch -function Base.show(io::IO, ::MIME"text/plain", a::SpecOpenRingElem) +function Base.show(io::IO, ::MIME"text/plain", a::AffineSchemeOpenSubschemeRingElem) io = pretty(io) R = parent(a) U = domain(R) @@ -504,4 +504,4 @@ function Base.show(io::IO, ::MIME"text/plain", a::SpecOpenRingElem) print(io, Dedent()) end end - + diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Properties.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Properties.jl new file mode 100644 index 000000000000..0045c8d5e868 --- /dev/null +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Properties.jl @@ -0,0 +1,16 @@ +######################################################################## +# Properties of AffineSchemeOpenSubschemeRingElem # +######################################################################## + +######################################################################## +# Required functionality for the ring interface # +######################################################################## +is_domain_type(::Type{T}) where {T<:AffineSchemeOpenSubschemeRingElem} = true +is_domain_type(a::AffineSchemeOpenSubschemeRingElem) = is_domain_type(typeof(a)) +is_exact_type(::Type{T}) where {T<:AffineSchemeOpenSubschemeRingElem} = true +is_exact_type(a::AffineSchemeOpenSubschemeRingElem) = is_exact_type(typeof(a)) +is_domain_type(::Type{T}) where {T<:AffineSchemeOpenSubschemeRing} = true +is_domain_type(R::AffineSchemeOpenSubschemeRing) = is_domain_type(typeof(R)) +is_exact_type(::Type{T}) where {T<:AffineSchemeOpenSubschemeRing} = true +is_exact_type(R::AffineSchemeOpenSubschemeRing) = is_exact_type(typeof(R)) + diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Types.jl b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Types.jl similarity index 57% rename from src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Types.jl rename to src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Types.jl index ae23fbc93296..3a52446991f2 100644 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Types.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme/Rings/Types.jl @@ -3,53 +3,53 @@ # Rings of regular functions on Zariski open sets of affine schemes # ######################################################################## @doc raw""" - SpecOpenRing{SpecType, OpenType} + AffineSchemeOpenSubschemeRing{AffineSchemeType, OpenType} The ring of regular functions ``𝒪(X, U)`` on an open subset ``U`` of an affine scheme ``X``. - * `SpecType` is the type of the affine scheme ``X`` on which + * `AffineSchemeType` is the type of the affine scheme ``X`` on which this sheaf is defined; * `OpenType` is the type of the (Zariski) open subsets of ``U``. """ -mutable struct SpecOpenRing{SpecType, OpenType} <: Ring - scheme::SpecType +mutable struct AffineSchemeOpenSubschemeRing{AffineSchemeType, OpenType} <: Ring + scheme::AffineSchemeType domain::OpenType - function SpecOpenRing( - X::SpecType, + function AffineSchemeOpenSubschemeRing( + X::AffineSchemeType, U::OpenType; check::Bool=true - ) where {SpecType<:AbsSpec, OpenType<:SpecOpen} + ) where {AffineSchemeType<:AbsAffineScheme, OpenType<:AffineSchemeOpenSubscheme} @check is_subscheme(U, X) "open set does not lay in the scheme" - return new{SpecType, OpenType}(X, U) + return new{AffineSchemeType, OpenType}(X, U) end end ######################################################################## -# Elements of SpecOpenRings # +# Elements of AffineSchemeOpenSubschemeRings # ######################################################################## @doc raw""" - SpecOpenRingElem{SpecOpenType} + AffineSchemeOpenSubschemeRingElem{AffineSchemeOpenSubschemeType} An element ``f ∈ 𝒪(X, U)`` of the ring of regular functions on an open set ``U`` of an affine scheme ``X``. -The type parameter `SpecOpenType` is the type of the open set +The type parameter `AffineSchemeOpenSubschemeType` is the type of the open set ``U`` of ``X``. """ -mutable struct SpecOpenRingElem{ - SpecOpenRingType<:SpecOpenRing +mutable struct AffineSchemeOpenSubschemeRingElem{ + AffineSchemeOpenSubschemeRingType<:AffineSchemeOpenSubschemeRing } <: RingElem - parent::SpecOpenRingType + parent::AffineSchemeOpenSubschemeRingType restrictions::Vector{<:RingElem} - function SpecOpenRingElem( - R::SpecOpenRingType, + function AffineSchemeOpenSubschemeRingElem( + R::AffineSchemeOpenSubschemeRingType, f::Vector{<:RingElem}; check::Bool=true ) where { - SpecOpenRingType<:SpecOpenRing + AffineSchemeOpenSubschemeRingType<:AffineSchemeOpenSubschemeRing } n = length(f) U = domain(R) @@ -63,7 +63,7 @@ mutable struct SpecOpenRingElem{ end end end - return new{SpecOpenRingType}(R, g) + return new{AffineSchemeOpenSubschemeRingType}(R, g) end end diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Attributes.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Attributes.jl index f60e75d9ba2c..5e00d1ebc382 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Attributes.jl @@ -2,18 +2,18 @@ ######################################################################## -# (1) Properties for AbsSpecMor +# (1) Properties for AbsAffineSchemeMor ######################################################################## -# In an attempt to mimic inheritance, any new concrete instance of AbsSpecMor -# can internally store a SpecMor instance and must implement the method -# underlying_morphism to access it. Then, all functionality for SpecMor is +# In an attempt to mimic inheritance, any new concrete instance of AbsAffineSchemeMor +# can internally store a AffineSchemeMor instance and must implement the method +# underlying_morphism to access it. Then, all functionality for AffineSchemeMor is # automatically forwarded. -underlying_morphism(f::AbsSpecMor) = error("`underlying_morphism(f)` not implemented for `f` of type $(typeof(f))") +underlying_morphism(f::AbsAffineSchemeMor) = error("`underlying_morphism(f)` not implemented for `f` of type $(typeof(f))") @doc raw""" - domain(f::AbsSpecMor) + domain(f::AbsAffineSchemeMor) On a morphism ``f : X → Y`` of affine schemes, this returns ``X``. @@ -58,11 +58,11 @@ Spectrum by ideal (x1) ``` """ -domain(f::AbsSpecMor) = domain(underlying_morphism(f)) +domain(f::AbsAffineSchemeMor) = domain(underlying_morphism(f)) @doc raw""" - codomain(f::AbsSpecMor) + codomain(f::AbsAffineSchemeMor) On a morphism ``f : X → Y`` of affine schemes, this returns ``Y``. @@ -105,11 +105,11 @@ Affine space of dimension 3 with coordinates [x1, x2, x3] ``` """ -codomain(f::AbsSpecMor) = codomain(underlying_morphism(f)) +codomain(f::AbsAffineSchemeMor) = codomain(underlying_morphism(f)) @doc raw""" - pullback(f::AbsSpecMor) + pullback(f::AbsAffineSchemeMor) On a morphism ``f : X → Y`` of affine schemes ``X = Spec(S)`` and ``Y = Spec(R)``, this returns the ring homomorphism ``f^* : R → S``. @@ -148,17 +148,17 @@ defined by x3 -> x3 ``` """ -pullback(f::AbsSpecMor) = pullback(underlying_morphism(f)) +pullback(f::AbsAffineSchemeMor) = pullback(underlying_morphism(f)) ######################################################################## -# (2) Properties for SpecMor +# (2) Properties for AffineSchemeMor ######################################################################## -pullback(phi::SpecMor) = phi.pullback -domain(phi::SpecMor) = phi.domain -codomain(phi::SpecMor) = phi.codomain +pullback(phi::AffineSchemeMor) = phi.pullback +domain(phi::AffineSchemeMor) = phi.domain +codomain(phi::AffineSchemeMor) = phi.codomain @@ -176,8 +176,8 @@ complement_scheme(f::OpenInclusion) = f.Z ######################################################################## function preimage( - phi::AbsSpecMor, - Z::AbsSpec{<:Ring, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, + phi::AbsAffineSchemeMor, + Z::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}; check::Bool=true ) @@ -193,19 +193,19 @@ function preimage( return hypersurface_complement(subscheme(X, new_gens), new_units) end -function preimage(f::AbsSpecMor, Z::AbsSpec{<:Ring, <:MPolyRing}; check::Bool=true) +function preimage(f::AbsAffineSchemeMor, Z::AbsAffineScheme{<:Ring, <:MPolyRing}; check::Bool=true) OO(Z) == ambient_coordinate_ring(codomain(f)) || error("schemes can not be compared") return subscheme(domain(f), ideal(OO(domain(f)), [zero(OO(domain(f)))])) end -function preimage(f::AbsSpecMor, - Z::AbsSpec{<:Ring, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, +function preimage(f::AbsAffineSchemeMor, + Z::AbsAffineScheme{<:Ring, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}; check::Bool=true) return hypersurface_complement(domain(f), pullback(f).(denominators(inverted_set(OO(Z))))) end -function preimage(f::AbsSpecMor, Z::AbsSpec; check::Bool=true) +function preimage(f::AbsAffineSchemeMor, Z::AbsAffineScheme; check::Bool=true) pbf = pullback(f) R = OO(codomain(f)) S = OO(domain(f)) @@ -221,7 +221,7 @@ end ############################################## @doc raw""" - graph(f::AbsSpecMor) + graph(f::AbsAffineSchemeMor) Return the graph of ``f : X → Y`` as a subscheme of ``X×Y`` as well as the two projections to ``X`` and ``Y``. @@ -262,7 +262,7 @@ julia> graph(f) (scheme(x1, -x1, x2 - x2, x3 - x3), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> scheme(x1), Hom: scheme(x1, -x1, x2 - x2, x3 - x3) -> affine 3-space over QQ with coordinates [x1, x2, x3]) ``` """ -function graph(f::AbsSpecMor{<:AbsSpec{BRT}, <:AbsSpec{BRT}}) where {BRT} +function graph(f::AbsAffineSchemeMor{<:AbsAffineScheme{BRT}, <:AbsAffineScheme{BRT}}) where {BRT} X = domain(f) Y = codomain(f) XxY, prX, prY = product(X, Y) @@ -280,7 +280,7 @@ end # (6) The inverse of a morphism ############################################## -@attr AbsSpecMor function inverse(f::AbsSpecMor) +@attr AbsAffineSchemeMor function inverse(f::AbsAffineSchemeMor) is_isomorphism(f) || error("the given morphism is not an isomorphism") return get_attribute(f, :inverse)::morphism_type(codomain(f), domain(f)) end @@ -290,31 +290,31 @@ end ######################################################################## ### Type getters -pullback_type(::Type{T}) where {DomType, CodType, PbType, T<:AbsSpecMor{DomType, CodType, PbType}} = PbType -pullback_type(f::AbsSpecMor) = pullback_type(typeof(f)) -domain_type(::Type{T}) where {DomType, CodType, PbType, T<:AbsSpecMor{DomType, CodType, PbType}} = DomType -domain_type(f::AbsSpecMor) = domain_type(typeof(f)) -codomain_type(::Type{T}) where {DomType, CodType, PbType, T<:AbsSpecMor{DomType, CodType, PbType}} = CodType -codomain_type(f::AbsSpecMor) = codomain_type(typeof(f)) - -function morphism_type(::Type{SpecType1}, ::Type{SpecType2}) where {SpecType1<:AbsSpec, SpecType2<:AbsSpec} - return SpecMor{SpecType1, SpecType2, morphism_type(ring_type(SpecType2), ring_type(SpecType1))} +pullback_type(::Type{T}) where {DomType, CodType, PbType, T<:AbsAffineSchemeMor{DomType, CodType, PbType}} = PbType +pullback_type(f::AbsAffineSchemeMor) = pullback_type(typeof(f)) +domain_type(::Type{T}) where {DomType, CodType, PbType, T<:AbsAffineSchemeMor{DomType, CodType, PbType}} = DomType +domain_type(f::AbsAffineSchemeMor) = domain_type(typeof(f)) +codomain_type(::Type{T}) where {DomType, CodType, PbType, T<:AbsAffineSchemeMor{DomType, CodType, PbType}} = CodType +codomain_type(f::AbsAffineSchemeMor) = codomain_type(typeof(f)) + +function morphism_type(::Type{AffineSchemeType1}, ::Type{AffineSchemeType2}) where {AffineSchemeType1<:AbsAffineScheme, AffineSchemeType2<:AbsAffineScheme} + return AffineSchemeMor{AffineSchemeType1, AffineSchemeType2, morphism_type(ring_type(AffineSchemeType2), ring_type(AffineSchemeType1))} end -morphism_type(X::AbsSpec, Y::AbsSpec) = morphism_type(typeof(X), typeof(Y)) +morphism_type(X::AbsAffineScheme, Y::AbsAffineScheme) = morphism_type(typeof(X), typeof(Y)) @doc raw""" - isomorphism_on_open_subsets(f::AbsSpecMor) + isomorphism_on_open_subsets(f::AbsAffineSchemeMor) -For a birational morphism ``f : X → Y`` of `AbsSpec`s this +For a birational morphism ``f : X → Y`` of `AbsAffineScheme`s this returns an isomorphism of affine schemes ``f' : U → V`` which is the restriction of ``f`` to two dense open subsets ``U ⊂ X`` and ``V ⊂ Y``. """ -function isomorphism_on_open_subsets(f::AbsSpecMor) +function isomorphism_on_open_subsets(f::AbsAffineSchemeMor) if !has_attribute(f, :iso_on_open_subset) is_birational(f) # Should compute and store the attribute end - return get_attribute(f, :iso_on_open_subset)::AbsSpecMor + return get_attribute(f, :iso_on_open_subset)::AbsAffineSchemeMor end diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Constructors.jl index bc8eb2f6d2b3..506c17030a3e 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Constructors.jl @@ -6,7 +6,7 @@ ######################################################################## @doc raw""" - morphism(X::AbsSpec, Y::AbsSpec, f::Vector{<:RingElem}; check::Bool=true) + morphism(X::AbsAffineScheme, Y::AbsAffineScheme, f::Vector{<:RingElem}; check::Bool=true) This method constructs a morphism from the scheme ``X`` to the scheme ``Y``. For this one has to specify the images @@ -38,8 +38,8 @@ given by the pullback function ``` """ function morphism( - X::AbsSpec, - Y::AbsSpec, + X::AbsAffineScheme, + Y::AbsAffineScheme, f::Vector{<:RingElem}; check::Bool=true ) @@ -47,8 +47,8 @@ function morphism( end function morphism( - X::AbsSpec, - Y::AbsSpec{<:Ring, <:MPolyRing}, + X::AbsAffineScheme, + Y::AbsAffineScheme{<:Ring, <:MPolyRing}, f::Vector{<:RingElem}; check::Bool=true ) @@ -56,8 +56,8 @@ function morphism( end function morphism( - X::AbsSpec, - Y::AbsSpec, + X::AbsAffineScheme, + Y::AbsAffineScheme, f::Vector; check::Bool=true ) @@ -71,7 +71,7 @@ end ######################################################################## @doc raw""" - identity_map(X::AbsSpec{<:Any, <:MPolyRing}) + identity_map(X::AbsAffineScheme{<:Any, <:MPolyRing}) This method constructs the identity morphism from an affine scheme to itself. @@ -92,14 +92,14 @@ given by the pullback function x3 -> x3 ``` """ -identity_map(X::AbsSpec{<:Any, <:MPolyRing}) = morphism(X, X, hom(OO(X), OO(X), gens(OO(X)), check=false), check=false) -identity_map(X::AbsSpec{<:Any, <:MPolyQuoLocRing}) = morphism(X, X, hom(OO(X), OO(X), gens(ambient_coordinate_ring(X)), check=false), check=false) -identity_map(X::AbsSpec{<:Any, <:MPolyLocRing}) = morphism(X, X, hom(OO(X), OO(X), gens(ambient_coordinate_ring(X)), check=false), check=false) -identity_map(X::AbsSpec{<:Any, <:MPolyQuoRing}) = morphism(X, X, hom(OO(X), OO(X), gens(ambient_coordinate_ring(X)), check=false), check=false) +identity_map(X::AbsAffineScheme{<:Any, <:MPolyRing}) = morphism(X, X, hom(OO(X), OO(X), gens(OO(X)), check=false), check=false) +identity_map(X::AbsAffineScheme{<:Any, <:MPolyQuoLocRing}) = morphism(X, X, hom(OO(X), OO(X), gens(ambient_coordinate_ring(X)), check=false), check=false) +identity_map(X::AbsAffineScheme{<:Any, <:MPolyLocRing}) = morphism(X, X, hom(OO(X), OO(X), gens(ambient_coordinate_ring(X)), check=false), check=false) +identity_map(X::AbsAffineScheme{<:Any, <:MPolyQuoRing}) = morphism(X, X, hom(OO(X), OO(X), gens(ambient_coordinate_ring(X)), check=false), check=false) @doc raw""" - inclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true) + inclusion_morphism(X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true) Return the inclusion map from ``X`` to ``Y``. @@ -144,11 +144,11 @@ julia> base_ring(I) == OO(X) true ``` """ -inclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true) = morphism(X, Y, gens(ambient_coordinate_ring(Y)), check=check) +inclusion_morphism(X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true) = morphism(X, Y, gens(ambient_coordinate_ring(Y)), check=check) @doc raw""" - compose(f::AbsSpecMor, g::AbsSpecMor) + compose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) This method computes the composition of two morphisms. @@ -207,14 +207,14 @@ julia> compose(m3, compose(m1, m2)) == m1 true ``` """ -function compose(f::AbsSpecMor, g::AbsSpecMor) +function compose(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) codomain(f) === domain(g) || error("Morphisms can not be composed") return morphism(domain(f), codomain(g), compose(pullback(g), pullback(f)), check=false) end @doc raw""" - restrict(f::SpecMor, U::AbsSpec, V::AbsSpec) + restrict(f::AffineSchemeMor, U::AbsAffineScheme, V::AbsAffineScheme) This method restricts the domain of the morphism ``f`` to ``U`` and its codomain to ``V``. @@ -247,7 +247,7 @@ julia> restrict(identity_map(X), Y, Y) == identity_map(Y) true ``` """ -function restrict(f::SpecMor, U::AbsSpec, V::AbsSpec; check::Bool=true) +function restrict(f::AffineSchemeMor, U::AbsAffineScheme, V::AbsAffineScheme; check::Bool=true) @check is_subscheme(U, domain(f)) "second argument does not lie in the domain of the map" @check is_subscheme(V, codomain(f)) "third argument does not lie in the codomain of the map" @check is_subscheme(U, preimage(f, V)) "the image of the restriction is not contained in the restricted codomain" diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Methods.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Methods.jl index 6112f141be06..e1495e202db6 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Methods.jl @@ -3,7 +3,7 @@ ########################################################### @doc raw""" - fiber_product(f::AbsSpecMor, g::AbsSpecMor) + fiber_product(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) For morphisms ``f : X → Z`` and ``g : Y → Z`` return the fiber product ``X×Y`` over ``Z`` together with its two canonical projections. @@ -13,8 +13,8 @@ a commutative square with `f` and `g`, you can use `induced_map_to_fiber_product` to create the resulting map `W → X×Y`. """ function fiber_product( - f::AbsSpecMor, - g::AbsSpecMor + f::AbsAffineSchemeMor, + g::AbsAffineSchemeMor ) Y = domain(f) X = codomain(f) @@ -36,7 +36,7 @@ end # it is important that the resulting fiber product is a PrincipalOpenSubset of # the domain of `g` (or the domain of `f` when it's the other way around), so that # the ancestry-tree for patches is preserved. -function fiber_product(f::PrincipalOpenEmbedding, g::AbsSpecMor) +function fiber_product(f::PrincipalOpenEmbedding, g::AbsAffineSchemeMor) @assert codomain(f) === codomain(g) "codomains are not the same" A = domain(f) B = domain(g) @@ -50,7 +50,7 @@ function fiber_product(f::PrincipalOpenEmbedding, g::AbsSpecMor) return result, gg, ff end -function fiber_product(f::AbsSpecMor, g::PrincipalOpenEmbedding) +function fiber_product(f::AbsAffineSchemeMor, g::PrincipalOpenEmbedding) result, ff, gg = fiber_product(g, f) return result, gg, ff end @@ -74,9 +74,9 @@ end @doc raw""" induced_map_to_fiber_product( - a::AbsSpecMor, b::AbsSpecMor, - f::AbsSpecMor, g::AbsSpecMor; - fiber_product::Tuple{<:AbsSpec, <:AbsSpecMor, <:AbsSpecMor}=fiber_product(f, g) + a::AbsAffineSchemeMor, b::AbsAffineSchemeMor, + f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; + fiber_product::Tuple{<:AbsAffineScheme, <:AbsAffineSchemeMor, <:AbsAffineSchemeMor}=fiber_product(f, g) ) In a commutative diagram @@ -94,9 +94,9 @@ In a commutative diagram this computes the canonical map `W -> X x Y`. """ function induced_map_to_fiber_product( - a::AbsSpecMor, b::AbsSpecMor, - f::AbsSpecMor, g::AbsSpecMor; - fiber_product::Tuple{<:AbsSpec, <:AbsSpecMor, <:AbsSpecMor}=fiber_product(f, g), + a::AbsAffineSchemeMor, b::AbsAffineSchemeMor, + f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; + fiber_product::Tuple{<:AbsAffineScheme, <:AbsAffineSchemeMor, <:AbsAffineSchemeMor}=fiber_product(f, g), check::Bool=true ) # All checks are done here. The actual computations are carried out @@ -121,9 +121,9 @@ function induced_map_to_fiber_product( end function _induced_map_to_fiber_product( - a::AbsSpecMor, b::AbsSpecMor, - f::AbsSpecMor, g::AbsSpecMor; - fiber_product::Tuple{<:AbsSpec, <:AbsSpecMor, <:AbsSpecMor}=fiber_product(f, g), + a::AbsAffineSchemeMor, b::AbsAffineSchemeMor, + f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; + fiber_product::Tuple{<:AbsAffineScheme, <:AbsAffineSchemeMor, <:AbsAffineSchemeMor}=fiber_product(f, g), check::Bool=true ) # The ambient scheme of XxY is the actual product of X and Y @@ -146,9 +146,9 @@ end # then the construction did not proceed via the `product` of `X` and `Y`. # In this case, the induced map must be created differently. function _induced_map_to_fiber_product( - a::AbsSpecMor, b::AbsSpecMor, - f::PrincipalOpenEmbedding, g::AbsSpecMor; - fiber_product::Tuple{<:AbsSpec, <:AbsSpecMor, <:PrincipalOpenEmbedding}=fiber_product(f, g), + a::AbsAffineSchemeMor, b::AbsAffineSchemeMor, + f::PrincipalOpenEmbedding, g::AbsAffineSchemeMor; + fiber_product::Tuple{<:AbsAffineScheme, <:AbsAffineSchemeMor, <:PrincipalOpenEmbedding}=fiber_product(f, g), check::Bool=true ) # XxY is a principal open subset of Y. @@ -160,9 +160,9 @@ function _induced_map_to_fiber_product( end function _induced_map_to_fiber_product( - a::AbsSpecMor, b::AbsSpecMor, - f::AbsSpecMor, g::PrincipalOpenEmbedding; - fiber_product::Tuple{<:AbsSpec, <:PrincipalOpenEmbedding, <:AbsSpecMor}=fiber_product(f, g), + a::AbsAffineSchemeMor, b::AbsAffineSchemeMor, + f::AbsAffineSchemeMor, g::PrincipalOpenEmbedding; + fiber_product::Tuple{<:AbsAffineScheme, <:PrincipalOpenEmbedding, <:AbsAffineSchemeMor}=fiber_product(f, g), check::Bool=true ) # XxY is a principal open subset of X. @@ -175,9 +175,9 @@ end # additional method to remove ambiguity function _induced_map_to_fiber_product( - a::AbsSpecMor, b::AbsSpecMor, + a::AbsAffineSchemeMor, b::AbsAffineSchemeMor, f::PrincipalOpenEmbedding, g::PrincipalOpenEmbedding; - fiber_product::Tuple{<:AbsSpec, <:PrincipalOpenEmbedding, <:PrincipalOpenEmbedding}=fiber_product(f, g), + fiber_product::Tuple{<:AbsAffineScheme, <:PrincipalOpenEmbedding, <:PrincipalOpenEmbedding}=fiber_product(f, g), check::Bool=true ) W = domain(a) @@ -189,20 +189,20 @@ function _induced_map_to_fiber_product( end ### Some helper functions -function _restrict_domain(f::AbsSpecMor, D::PrincipalOpenSubset; check::Bool=true) +function _restrict_domain(f::AbsAffineSchemeMor, D::PrincipalOpenSubset; check::Bool=true) D === domain(f) && return f ambient_scheme(D) === domain(f) && return morphism(D, codomain(f), OO(D).(pullback(f).(gens(OO(codomain(f))))), check=false) @check is_subscheme(D, domain(f)) "domain incompatible" return morphism(D, codomain(f), OO(D).(pullback(f).(gens(OO(codomain(f))))), check=check) end -function _restrict_domain(f::AbsSpecMor, D::AbsSpec; check::Bool=true) +function _restrict_domain(f::AbsAffineSchemeMor, D::AbsAffineScheme; check::Bool=true) D === domain(f) && return f @check is_subscheme(D, domain(f)) "domain incompatible" return morphism(D, codomain(f), OO(D).(pullback(f).(gens(OO(codomain(f))))), check=check) end -function _restrict_codomain(f::AbsSpecMor, D::PrincipalOpenSubset; check::Bool=true) +function _restrict_codomain(f::AbsAffineSchemeMor, D::PrincipalOpenSubset; check::Bool=true) D === codomain(f) && return f if ambient_scheme(D) === codomain(f) @check is_unit(pullback(f)(complement_equation(D))) "complement equation does not pull back to a unit" @@ -213,18 +213,18 @@ function _restrict_codomain(f::AbsSpecMor, D::PrincipalOpenSubset; check::Bool=t return morphism(domain(f), D, OO(domain(f)).(pullback(f).(gens(OO(codomain(f))))), check=check) end -function _restrict_codomain(f::AbsSpecMor, D::AbsSpec; check::Bool=true) +function _restrict_codomain(f::AbsAffineSchemeMor, D::AbsAffineScheme; check::Bool=true) @check is_subscheme(D, codomain(f)) "codomain incompatible" @check is_subscheme(domain(f), preimage(f, D)) return morphism(domain(f), D, OO(domain(f)).(pullback(f).(gens(OO(codomain(f))))), check=check) end -function restrict(f::AbsSpecMor, D::AbsSpec, Z::AbsSpec; check::Bool=true) +function restrict(f::AbsAffineSchemeMor, D::AbsAffineScheme, Z::AbsAffineScheme; check::Bool=true) interm = _restrict_domain(f, D; check) return _restrict_codomain(interm, Z; check) end -function Base.:(==)(f::AbsSpecMor, g::AbsSpecMor) +function Base.:(==)(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) domain(f) === domain(g) || return false codomain(f) === codomain(g) || return false return pullback(f) == pullback(g) @@ -235,7 +235,7 @@ end ########################################################### # First the product of the ambient spaces. Documented below. -function product(X::AbsSpec{BRT, RT}, Y::AbsSpec{BRT, RT}; +function product(X::AbsAffineScheme{BRT, RT}, Y::AbsAffineScheme{BRT, RT}; change_var_names_to::Vector{String}=["", ""] ) where {BRT, RT<:MPolyRing} K = OO(X) @@ -259,20 +259,20 @@ function product(X::AbsSpec{BRT, RT}, Y::AbsSpec{BRT, RT}; new_symb = vcat(new_symb, Symbol.([change_var_names_to[2]*"$i" for i in 1:ngens(L)])) end KL, z = polynomial_ring(k, new_symb) - XxY = Spec(KL) + XxY = spec(KL) pr1 = morphism(XxY, X, gens(KL)[1:m], check=false) pr2 = morphism(XxY, Y, gens(KL)[m+1:m+n], check=false) return XxY, pr1, pr2 end @doc raw""" - product(X::AbsSpec, Y::AbsSpec) + product(X::AbsAffineScheme, Y::AbsAffineScheme) Return a triple ``(X×Y, p₁, p₂)`` consisting of the product ``X×Y`` over the common base ring ``𝕜`` and the two projections ``p₁ : X×Y → X`` and ``p₂ : X×Y → Y``. """ -function product(X::AbsSpec, Y::AbsSpec; +function product(X::AbsAffineScheme, Y::AbsAffineScheme; change_var_names_to::Vector{String}=["", ""] ) # take the product of the ambient spaces and restrict @@ -289,7 +289,7 @@ end #= -function product(X::StdSpec, Y::StdSpec; +function product(X::StdAffineScheme, Y::StdAffineScheme; change_var_names_to::Vector{String}=["", ""] ) K = OO(X) @@ -321,7 +321,7 @@ function product(X::StdSpec, Y::StdSpec; IY = ideal(RS, inc2.(gens(modulus(underlying_quotient(OO(Y)))))) UX = MPolyPowersOfElement(RS, inc1.(denominators(inverted_set(OO(X))))) UY = MPolyPowersOfElement(RS, inc2.(denominators(inverted_set(OO(Y))))) - XxY = Spec(RS, IX + IY, UX*UY) + XxY = spec(RS, IX + IY, UX*UY) pr1 = morphism(XxY, X, gens(RS)[1:m], check=false) pr2 = morphism(XxY, Y, gens(RS)[m+1:m+n], check=false) return XxY, pr1, pr2 @@ -335,7 +335,7 @@ end # (4) Equality ######################################## -function ==(f::SpecMorType, g::SpecMorType) where {SpecMorType<:AbsSpecMor} +function ==(f::AffineSchemeMorType, g::AffineSchemeMorType) where {AffineSchemeMorType<:AbsAffineSchemeMor} X = domain(f) X == domain(g) || return false codomain(f) == codomain(g) || return false @@ -351,7 +351,7 @@ end # Since the morphism is given in terms of pullback on the local coordinates, # we need to adapt the printing to have everything aligned. -function Base.show(io::IO, ::MIME"text/plain", f::AbsSpecMor) +function Base.show(io::IO, ::MIME"text/plain", f::AbsAffineSchemeMor) io = pretty(io) X = domain(f) cX = coordinates(X) @@ -388,7 +388,7 @@ function Base.show(io::IO, ::MIME"text/plain", f::AbsSpecMor) print(io, Dedent()) end -function Base.show(io::IO, f::AbsSpecMor) +function Base.show(io::IO, f::AbsAffineSchemeMor) if get(io, :supercompact, false) print(io, "Affine scheme morphism") else @@ -403,9 +403,9 @@ end ######################################################################## @doc raw""" - base_change(phi::Any, f::AbsSpecMor) - domain_map::AbsSpecMor=base_change(phi, domain(f))[2], - codomain_map::AbsSpecMor=base_change(phi, codomain(f))[2] + base_change(phi::Any, f::AbsAffineSchemeMor) + domain_map::AbsAffineSchemeMor=base_change(phi, domain(f))[2], + codomain_map::AbsAffineSchemeMor=base_change(phi, codomain(f))[2] ) For a morphism ``f : X → Y`` between two schemes over a `base_ring` ``𝕜`` @@ -421,9 +421,9 @@ and a ring homomorphism ``φ : 𝕜 → 𝕂`` this returns a triple The optional arguments `domain_map` and `codomain_map` can be used to specify the morphisms `b₁` and `b₂`, respectively. """ -function base_change(phi::Any, f::AbsSpecMor; - domain_map::AbsSpecMor=base_change(phi, domain(f))[2], - codomain_map::AbsSpecMor=base_change(phi, codomain(f))[2] +function base_change(phi::Any, f::AbsAffineSchemeMor; + domain_map::AbsAffineSchemeMor=base_change(phi, domain(f))[2], + codomain_map::AbsAffineSchemeMor=base_change(phi, codomain(f))[2] ) X = domain(f) Y = codomain(f) @@ -447,15 +447,15 @@ function base_change(phi::Any, f::AbsSpecMor; return domain_map, morphism(XX, YY, pbF, check=false), codomain_map # TODO: Set to false after testing end -function _register_birationality!(f::AbsSpecMor, - g::AbsSpecMor, ginv::AbsSpecMor) +function _register_birationality!(f::AbsAffineSchemeMor, + g::AbsAffineSchemeMor, ginv::AbsAffineSchemeMor) set_attribute!(g, :inverse, ginv) set_attribute!(ginv, :inverse, g) return _register_birationality(f, g) end -function _register_birationality!(f::AbsSpecMor, - g::AbsSpecMor +function _register_birationality!(f::AbsAffineSchemeMor, + g::AbsAffineSchemeMor ) set_attribute!(f, :is_birational, true) set_attribute!(f, :iso_on_open_subset, g) diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Properties.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Properties.jl index 449a3e13bef4..d9567cebf032 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Properties.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Properties.jl @@ -5,11 +5,11 @@ ######################################## @doc raw""" - is_isomorphism(f::AbsSpecMor) + is_isomorphism(f::AbsAffineSchemeMor) This method checks if a morphism is an isomorphism. """ -@attr Bool function is_isomorphism(f::AbsSpecMor) +@attr Bool function is_isomorphism(f::AbsAffineSchemeMor) has_attribute(f, :inverse) && return true is_isomorphism(pullback(f)) || return false set_attribute!(f, :inverse, morphism(codomain(f), domain(f), inverse(pullback(f)))) @@ -17,16 +17,16 @@ This method checks if a morphism is an isomorphism. end @doc raw""" - is_inverse_of(f::AbsSpecMor, g::AbsSpecMor) + is_inverse_of(f::AbsAffineSchemeMor, g::AbsAffineSchemeMor) This method checks if a morphism ``f`` is the inverse of a morphism ``g``. """ -function is_inverse_of(f::S, g::T) where {S<:AbsSpecMor, T<:AbsSpecMor} +function is_inverse_of(f::S, g::T) where {S<:AbsAffineSchemeMor, T<:AbsAffineSchemeMor} return is_isomorphism(f) && (inverse(f) == g) end @doc raw""" - is_identity_map(f::AbsSpecMor) + is_identity_map(f::AbsAffineSchemeMor) This method checks if a morphism is the identity map. @@ -58,9 +58,9 @@ julia> is_identity_map(inclusion_morphism(Y, X)) false ``` """ -is_identity_map(f::AbsSpecMor) = (domain(f) == codomain(f)) && all(x->(pullback(f)(x) == x), gens(OO(domain(f)))) +is_identity_map(f::AbsAffineSchemeMor) = (domain(f) == codomain(f)) && all(x->(pullback(f)(x) == x), gens(OO(domain(f)))) -@attr Bool function is_birational(f::AbsSpecMor) +@attr Bool function is_birational(f::AbsAffineSchemeMor) error("verification of birationality not implemented") end diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Types.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Types.jl index 09ac42a8631a..547c7c8f15d5 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Types.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Morphisms/Types.jl @@ -5,28 +5,28 @@ ######################################################################## @doc raw""" - AbsSpecMor{DomainType<:AbsSpec, - CodomainType<:AbsSpec, + AbsAffineSchemeMor{DomainType<:AbsAffineScheme, + CodomainType<:AbsAffineScheme, PullbackType<:Map, - MorphismType, + MorphismType, BaseMorType } Abstract type for morphisms ``f : X → Y`` of affine schemes where - * ``X = Spec(S)`` is of type `DomainType`, - * ``Y = Spec(R)`` is of type `CodomainType`, - * ``f^* : R → S`` is a ring homomorphism of type `PullbackType`, + * ``X = Spec(S)`` is of type `DomainType`, + * ``Y = Spec(R)`` is of type `CodomainType`, + * ``f^* : R → S`` is a ring homomorphism of type `PullbackType`, * ``f`` itself is of type `MorphismType` (required for the Map interface), - * if ``f`` is defined over a morphism of base schemes ``BX → BY`` - (e.g. a field extension), then this base scheme morphism is of + * if ``f`` is defined over a morphism of base schemes ``BX → BY`` + (e.g. a field extension), then this base scheme morphism is of type `BaseMorType`; otherwise, this can be set to `Nothing`. """ -abstract type AbsSpecMor{ - DomainType<:AbsSpec, - CodomainType<:AbsSpec, +abstract type AbsAffineSchemeMor{ + DomainType<:AbsAffineScheme, + CodomainType<:AbsAffineScheme, PullbackType<:Map, - MorphismType, + MorphismType, BaseMorType }<:SchemeMor{DomainType, CodomainType, MorphismType, BaseMorType} end @@ -38,36 +38,36 @@ end ######################################################################## @doc raw""" - SpecMor{DomainType<:AbsSpec, - CodomainType<:AbsSpec, + AffineSchemeMor{DomainType<:AbsAffineScheme, + CodomainType<:AbsAffineScheme, PullbackType<:Map } -A morphism ``f : X → Y`` of affine schemes ``X = Spec(S)`` of type -`DomainType` and ``Y = Spec(R)`` of type `CodomainType`, both defined -over the same `base_ring`, with underlying ring homomorphism +A morphism ``f : X → Y`` of affine schemes ``X = Spec(S)`` of type +`DomainType` and ``Y = Spec(R)`` of type `CodomainType`, both defined +over the same `base_ring`, with underlying ring homomorphism ``f^* : R → S`` of type `PullbackType`. """ -@attributes mutable struct SpecMor{ - DomainType<:AbsSpec, - CodomainType<:AbsSpec, +@attributes mutable struct AffineSchemeMor{ + DomainType<:AbsAffineScheme, + CodomainType<:AbsAffineScheme, PullbackType<:Map - } <: AbsSpecMor{DomainType, - CodomainType, - PullbackType, - SpecMor, + } <: AbsAffineSchemeMor{DomainType, + CodomainType, + PullbackType, + AffineSchemeMor, Nothing } domain::DomainType codomain::CodomainType pullback::PullbackType - function SpecMor( + function AffineSchemeMor( X::DomainType, Y::CodomainType, pullback::PullbackType; check::Bool=true - ) where {DomainType<:AbsSpec, CodomainType<:AbsSpec, PullbackType<:Map} + ) where {DomainType<:AbsAffineScheme, CodomainType<:AbsAffineScheme, PullbackType<:Map} OO(X) == codomain(pullback) || error("the coordinate ring of the domain does not coincide with the codomain of the pullback") OO(Y) == domain(pullback) || error("the coordinate ring of the codomain does not coincide with the domain of the pullback") @check begin @@ -77,28 +77,28 @@ over the same `base_ring`, with underlying ring homomorphism return new{DomainType, CodomainType, PullbackType}(X, Y, pullback) end end - + function morphism(X::DomainType, Y::CodomainType, pullback::PullbackType; check::Bool=true - ) where {DomainType<:AbsSpec, CodomainType<:AbsSpec, PullbackType<:Map} - return SpecMor(X, Y, pullback; check) + ) where {DomainType<:AbsAffineScheme, CodomainType<:AbsAffineScheme, PullbackType<:Map} + return AffineSchemeMor(X, Y, pullback; check) end ######################################################################## # A special type for open inclusions # ######################################################################## @doc raw""" - OpenInclusion{DomainType, CodomainType, PullbackType} <: AbsSpecMor + OpenInclusion{DomainType, CodomainType, PullbackType} <: AbsAffineSchemeMor -An open inclusion ``ι : U ↪ X`` of one affine scheme ``U`` into another -one ``X``. +An open inclusion ``ι : U ↪ X`` of one affine scheme ``U`` into another +one ``X``. """ -@attributes mutable struct OpenInclusion{DomainType, CodomainType, PullbackType} <: AbsSpecMor{DomainType, CodomainType, PullbackType, OpenInclusion, Nothing} - inc::SpecMor{DomainType, CodomainType, PullbackType} +@attributes mutable struct OpenInclusion{DomainType, CodomainType, PullbackType} <: AbsAffineSchemeMor{DomainType, CodomainType, PullbackType, OpenInclusion, Nothing} + inc::AffineSchemeMor{DomainType, CodomainType, PullbackType} I::Ideal - Z::Spec + Z::AffineScheme - function OpenInclusion(f::AbsSpecMor, I::Ideal; check::Bool=true) + function OpenInclusion(f::AbsAffineSchemeMor, I::Ideal; check::Bool=true) U = domain(f) X = codomain(f) Z = subscheme(X, I) diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Attributes.jl index 79b2f1e928d6..dd9f4ed4119b 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Attributes.jl @@ -1,12 +1,12 @@ ######################################################################## -# (1) Attributes of AbsSpec +# (1) Attributes of AbsAffineScheme # coordinate ring and ambient space related methods ######################################################################## -# Here is the interface for AbsSpec +# Here is the interface for AbsAffineScheme @doc raw""" - coordinate_ring(X::AbsSpec) + coordinate_ring(X::AbsAffineScheme) On an affine scheme ``X = Spec(R)``, return the ring ``R``. @@ -34,32 +34,32 @@ Multivariate polynomial ring in 3 variables x1, x2, x3 over rational field ``` """ -coordinate_ring(X::AbsSpec) = OO(X) +coordinate_ring(X::AbsAffineScheme) = OO(X) @doc raw""" - OO(X::AbsSpec) + OO(X::AbsAffineScheme) On an affine scheme ``X = Spec(R)``, return the ring ``R``. """ -function OO(X::AbsSpec{BRT, RT}) where {BRT, RT} +function OO(X::AbsAffineScheme{BRT, RT}) where {BRT, RT} OO(underlying_scheme(X))::RT end @doc raw""" - total_ring_of_fractions(X::AbsSpec) + total_ring_of_fractions(X::AbsAffineScheme) Return the total ring of fractions of the coordinate ring of `X`. """ -@attr function total_ring_of_fractions(X::AbsSpec) +@attr function total_ring_of_fractions(X::AbsAffineScheme) return total_ring_of_fractions(OO(X)) end @doc raw""" - ambient_space(X::AbsSpec) + ambient_space(X::AbsAffineScheme) -Return the ambient affine space of ``X``. +Return the ambient affine space of ``X``. -Use [`ambient_embedding(::AbsSpec)`](@ref) to obtain the embedding of ``X`` in +Use [`ambient_embedding(::AbsAffineScheme)`](@ref) to obtain the embedding of ``X`` in its ambient affine space. # Examples @@ -118,7 +118,7 @@ In each case the ambient affine space is given by `Spec(P)`. julia> P, (x, y) = polynomial_ring(QQ, [:x, :y]) (Multivariate polynomial ring in 2 variables over QQ, QQMPolyRingElem[x, y]) -julia> X = Spec(P) +julia> X = spec(P) Spectrum of multivariate polynomial ring in 2 variables x, y over rational field @@ -129,7 +129,7 @@ Ideal generated by julia> RmodI, quotient_map = quo(P, I); -julia> Y = Spec(RmodI) +julia> Y = spec(RmodI) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -143,7 +143,7 @@ julia> J = ideal(RmodI, y); julia> RmodJ, quotient_map2 = quo(RmodI, J); -julia> Z = Spec(RmodJ) +julia> Z = spec(RmodJ) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -160,7 +160,7 @@ Multiplicative subset julia> URmodI, _ = localization(RmodI, U); -julia> V = Spec(URmodI) +julia> V = spec(URmodI) Spectrum of localization of quotient @@ -188,28 +188,28 @@ julia> AX === AY false ``` """ -function ambient_space(X::AbsSpec) +function ambient_space(X::AbsAffineScheme) error("$X does not have an ambient affine space") end -function ambient_space(X::AbsSpec{BRT, RT}) where {BRT, RT<:MPolyRing} +function ambient_space(X::AbsAffineScheme{BRT, RT}) where {BRT, RT<:MPolyRing} return X end -@attr function ambient_space(X::Spec{BRT,RT}) where {BRT<:Field, RT <: Union{MPolyQuoRing,MPolyLocRing,MPolyQuoLocRing}} - return variety(Spec(ambient_coordinate_ring(X)), check=false) +@attr function ambient_space(X::AffineScheme{BRT,RT}) where {BRT<:Field, RT <: Union{MPolyQuoRing,MPolyLocRing,MPolyQuoLocRing}} + return variety(spec(ambient_coordinate_ring(X)), check=false) end -@attr function ambient_space(X::Spec{BRT,RT}) where {BRT, RT <: Union{MPolyQuoRing,MPolyLocRing,MPolyQuoLocRing}} - return Spec(ambient_coordinate_ring(X)) +@attr function ambient_space(X::AffineScheme{BRT,RT}) where {BRT, RT <: Union{MPolyQuoRing,MPolyLocRing,MPolyQuoLocRing}} + return spec(ambient_coordinate_ring(X)) end -@attr function ambient_space(X::AbsSpec{BRT,RT}) where {BRT, RT <: Union{MPolyQuoRing,MPolyLocRing,MPolyQuoLocRing}} +@attr function ambient_space(X::AbsAffineScheme{BRT,RT}) where {BRT, RT <: Union{MPolyQuoRing,MPolyLocRing,MPolyQuoLocRing}} return ambient_space(underlying_scheme(X)) end @doc raw""" - ambient_embedding(X::AbsSpec) + ambient_embedding(X::AbsAffineScheme) Return the embedding of ``X`` in its ambient affine space. @@ -241,16 +241,16 @@ julia> inc == inclusion_morphism(Y, X) true ``` """ -function ambient_embedding(X::AbsSpec) +function ambient_embedding(X::AbsAffineScheme) return inclusion_morphism(X, ambient_space(X), check=false) end @doc raw""" - ambient_coordinate_ring(X::AbsSpec) + ambient_coordinate_ring(X::AbsAffineScheme) Return the coordinate ring of the ambient affine space of ``X``. -See also [`ambient_space(::AbsSpec)`](@ref). +See also [`ambient_space(::AbsAffineScheme)`](@ref). # Examples ```jldoctest @@ -273,16 +273,16 @@ Multivariate polynomial ring in 2 variables x, y over rational field ``` """ -function ambient_coordinate_ring(X::AbsSpec) +function ambient_coordinate_ring(X::AbsAffineScheme) return ambient_coordinate_ring(underlying_scheme(X))::MPolyRing end @doc raw""" - ambient_coordinates(X::AbsSpec) + ambient_coordinates(X::AbsAffineScheme) Return the coordinate functions of the ambient affine space of ``X``. -See also [`ambient_space(::AbsSpec)`](@ref). +See also [`ambient_space(::AbsAffineScheme)`](@ref). # Examples ```jldoctest @@ -308,10 +308,10 @@ true ``` """ -ambient_coordinates(X::AbsSpec) = gens(ambient_coordinate_ring(X)) +ambient_coordinates(X::AbsAffineScheme) = gens(ambient_coordinate_ring(X)) @doc raw""" - coordinates(X::AbsSpec) + coordinates(X::AbsAffineScheme) Return the coordinate functions of ``X`` as elements of its coordinate ring. @@ -346,10 +346,10 @@ julia> parent(xY) == coordinate_ring(Y) true ``` """ -coordinates(X::AbsSpec) = gens(OO(X)) +coordinates(X::AbsAffineScheme) = gens(OO(X)) @doc raw""" - base_ring(X::AbsSpec) + base_ring(X::AbsAffineScheme) On an affine scheme ``X/𝕜`` over ``𝕜`` this returns the ring ``𝕜``. @@ -364,17 +364,17 @@ julia> base_ring(X) Rational field ``` """ -function base_ring(X::AbsSpec{BRT, RT}) where {BRT, RT} +function base_ring(X::AbsAffineScheme{BRT, RT}) where {BRT, RT} return base_ring(underlying_scheme(X))::BRT end ############################################################################## -# (2) Attributes of AbsSpec +# (2) Attributes of AbsAffineScheme # dimension, codimension, name ############################################################################## @doc raw""" - dim(X::AbsSpec) + dim(X::AbsAffineScheme) Return the dimension the affine scheme ``X = Spec(R)``. @@ -399,17 +399,17 @@ julia> dim(Y) # one dimension comes from ZZ and two from x1 and x2 3 ``` """ -dim(X::AbsSpec) +dim(X::AbsAffineScheme) -@attr function dim(X::AbsSpec{<:Ring, <:MPolyQuoLocRing}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing}) error("Not implemented") end -@attr function dim(X::AbsSpec{<:Ring, <:MPolyQuoLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:MPolyPowersOfElement}}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:MPolyPowersOfElement}}) return dim(closure(X)) end -@attr function dim(X::AbsSpec{<:Ring, <:MPolyQuoLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:Union{MPolyComplementOfPrimeIdeal, MPolyComplementOfKPointIdeal}}}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:Union{MPolyComplementOfPrimeIdeal, MPolyComplementOfKPointIdeal}}}) # Spec (R / I)_P R = OO(X) P = prime_ideal(inverted_set(R)) @@ -417,30 +417,30 @@ end return dim(I) - dim(P) end -@attr function dim(X::AbsSpec{<:Ring, <:MPolyLocRing}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyLocRing}) error("Not implemented") end -@attr function dim(X::AbsSpec{<:Ring, <:MPolyLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:MPolyPowersOfElement}}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:MPolyPowersOfElement}}) # zariski open subset of A^n return dim(closure(X)) end -@attr function dim(X::AbsSpec{<:Ring, <:MPolyLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:Union{MPolyComplementOfPrimeIdeal, MPolyComplementOfKPointIdeal}}}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyLocRing{<:Any,<:Any,<:MPolyRing,<:MPolyRingElem, <:Union{MPolyComplementOfPrimeIdeal, MPolyComplementOfKPointIdeal}}}) P = prime_ideal(inverted_set(OO(X))) return codim(P) end -@attr function dim(X::AbsSpec{<:Ring, <:MPolyRing}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyRing}) return dim(ideal(ambient_coordinate_ring(X), [zero(ambient_coordinate_ring(X))])) end -@attr function dim(X::AbsSpec{<:Ring, <:MPolyQuoRing}) +@attr function dim(X::AbsAffineScheme{<:Ring, <:MPolyQuoRing}) return dim(modulus(OO(X))) end @doc raw""" - codim(X::AbsSpec) + codim(X::AbsAffineScheme) Return the codimension of ``X`` in its ambient affine space. @@ -477,13 +477,13 @@ julia> codim(Y) 1 ``` """ -@attr function codim(X::AbsSpec) +@attr function codim(X::AbsAffineScheme) return dim(ideal(ambient_coordinate_ring(X), [zero(ambient_coordinate_ring(X))])) - dim(X) end @doc raw""" - name(X::AbsSpec) + name(X::AbsAffineScheme) Return the current name of an affine scheme. @@ -505,28 +505,28 @@ julia> name(X) "affine 3-dimensional space" ``` """ -@attr String function name(X::AbsSpec) +@attr String function name(X::AbsAffineScheme) return "unnamed affine variety" end -function set_name!(X::AbsSpec, name::String) +function set_name!(X::AbsAffineScheme, name::String) return set_attribute!(X, :name, name) end ############################################################################# -# (3) Attributes of AbsSpec +# (3) Attributes of AbsAffineScheme # reduced scheme and singular locus ############################################################################# # TODO: projective schemes, covered schemes @doc raw""" - reduced_scheme(X::AbsSpec{<:Field, <:MPolyAnyRing}) + reduced_scheme(X::AbsAffineScheme{<:Field, <:MPolyAnyRing}) Return the induced reduced scheme of `X`. Currently, this command is available for affine schemes and space germs. - + This command relies on [`radical`](@ref). # Examples @@ -538,7 +538,7 @@ julia> J = ideal(R,[(x-y)^2]) Ideal generated by x^2 - 2*x*y + y^2 -julia> X = Spec(R,J) +julia> X = spec(R,J) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -550,7 +550,7 @@ Complement of maximal ideal corresponding to rational point with coordinates (0, 0) in multivariate polynomial ring in 2 variables over QQ -julia> Y = Spec(R,J,U) +julia> Y = spec(R,J,U) Spectrum of localization of quotient @@ -567,7 +567,7 @@ julia> reduced_scheme(Y) ``` """ -@attr function reduced_scheme(X::AbsSpec{<:Field, <:MPolyQuoLocRing}) +@attr function reduced_scheme(X::AbsAffineScheme{<:Field, <:MPolyQuoLocRing}) if has_attribute(X, :is_reduced) && is_reduced(X) return X, identity_map(X) end @@ -579,7 +579,7 @@ julia> reduced_scheme(Y) return Xred, inc end -@attr function reduced_scheme(X::AbsSpec{<:Field, <:MPolyQuoRing}) +@attr function reduced_scheme(X::AbsAffineScheme{<:Field, <:MPolyQuoRing}) if has_attribute(X, :is_reduced) && is_reduced(X) return X, identity_map(X) end @@ -591,22 +591,22 @@ end end ## to make reduced_scheme agnostic for quotient ring -@attr function reduced_scheme(X::AbsSpec{<:Field, <:MPAnyNonQuoRing}) +@attr function reduced_scheme(X::AbsAffineScheme{<:Field, <:MPAnyNonQuoRing}) return X, ClosedEmbedding(X, ideal(OO(X), one(OO(X))), check=false) end -function reduced_scheme(X::AbsSpec) +function reduced_scheme(X::AbsAffineScheme) error("method 'reduced_scheme(X)' currently only implemented for affine Schemes and Space Germs over a field") end -### TODO: The following two functions (singular_locus, -### singular_locus_reduced) need to be made type-sensitive -### and reduced=true needs to be set automatically for varieties +### TODO: The following two functions (singular_locus, +### singular_locus_reduced) need to be made type-sensitive +### and reduced=true needs to be set automatically for varieties ### as soon as not only schemes, but also varieties as separate ### type have been introduced in OSCAR ### TODO: Make singular locus also available for projective schemes and ### for covered schemes (using the workhorse here...). - + @doc raw""" singular_locus(X::Scheme{<:Field}) -> (Scheme, SchemeMor) @@ -631,12 +631,12 @@ julia> I = ideal(R, [x^2 - y^2 + z^2]) Ideal generated by x^2 - y^2 + z^2 -julia> A3 = Spec(R) +julia> A3 = spec(R) Spectrum of multivariate polynomial ring in 3 variables x, y, z over rational field -julia> X = Spec(R,I) +julia> X = spec(R,I) Spectrum of quotient of multivariate polynomial ring in 3 variables x, y, z @@ -654,7 +654,7 @@ Complement of maximal ideal corresponding to rational point with coordinates (0, 0, 0) in multivariate polynomial ring in 3 variables over QQ -julia> Y = Spec(R,I,U) +julia> Y = spec(R,I,U) Spectrum of localization of quotient @@ -668,7 +668,7 @@ julia> singular_locus(Y) ``` """ -function singular_locus(X::AbsSpec{<:Field, <:MPAnyQuoRing}) +function singular_locus(X::AbsAffineScheme{<:Field, <:MPAnyQuoRing}) comp = _singular_locus_with_decomposition(X,false) if length(comp) == 0 set_attribute!(X, :is_smooth, true) @@ -684,7 +684,7 @@ function singular_locus(X::AbsSpec{<:Field, <:MPAnyQuoRing}) end # make singular_locus agnostic to quotient -function singular_locus(X::AbsSpec{<:Field, <:MPAnyNonQuoRing}) +function singular_locus(X::AbsAffineScheme{<:Field, <:MPAnyNonQuoRing}) set_attribute!(X, :is_smooth,true) inc = ClosedEmbedding(X, ideal(OO(X), one(OO(X)))) return domain(inc), inc @@ -697,7 +697,7 @@ end Return the singular locus of the reduced scheme ``X_{red}`` induced by `X`. -For computing the singular locus of `X` itself, please use +For computing the singular locus of `X` itself, please use ['singular_locus](@ref)'. Currently this command is available for affine schemes and for space germs. @@ -716,7 +716,7 @@ julia> I = ideal(R, [(x^2 - y^2 + z^2)^2]) Ideal generated by x^4 - 2*x^2*y^2 + 2*x^2*z^2 + y^4 - 2*y^2*z^2 + z^4 -julia> X = Spec(R,I) +julia> X = spec(R,I) Spectrum of quotient of multivariate polynomial ring in 3 variables x, y, z @@ -731,7 +731,7 @@ julia> singular_locus(X) ``` """ -function singular_locus_reduced(X::AbsSpec{<:Field, <:MPAnyQuoRing}) +function singular_locus_reduced(X::AbsAffineScheme{<:Field, <:MPAnyQuoRing}) comp = _singular_locus_with_decomposition(X, true) I= ideal(ambient_coordinate_ring(X),one(ambient_coordinate_ring(X))) for Z in comp @@ -744,13 +744,13 @@ function singular_locus_reduced(X::AbsSpec{<:Field, <:MPAnyQuoRing}) end # make singular_locus_reduced agnostic to quotient -function singular_locus_reduced(X::AbsSpec{<:Field, <:MPAnyNonQuoRing}) +function singular_locus_reduced(X::AbsAffineScheme{<:Field, <:MPAnyNonQuoRing}) inc = ClosedEmbedding(X, ideal(OO(X), one(OO(X)))) return domain(inc), inc end # internal workhorse, not user-facing -function _singular_locus_with_decomposition(X::AbsSpec{<:Field, <:MPAnyQuoRing}, reduced::Bool=true) +function _singular_locus_with_decomposition(X::AbsAffineScheme{<:Field, <:MPAnyQuoRing}, reduced::Bool=true) I = saturated_ideal(modulus(OO(X))) empty = typeof(X)[] result = empty @@ -758,9 +758,9 @@ function _singular_locus_with_decomposition(X::AbsSpec{<:Field, <:MPAnyQuoRing}, # equidimensional decomposition to allow Jacobian criterion on each component P = Ideal[] - if has_attribute(X, :is_equidimensional) && is_equidimensional(X) && !reduced + if has_attribute(X, :is_equidimensional) && is_equidimensional(X) && !reduced push!(P, I) - else + else if reduced P = equidimensional_decomposition_radical(I) else @@ -772,7 +772,7 @@ function _singular_locus_with_decomposition(X::AbsSpec{<:Field, <:MPAnyQuoRing}, if length(P)==1 && !reduced d = dim(X) R = base_ring(I) - n = nvars(R) + n = nvars(R) M = _jacobian_matrix_modulus(X) minvec = minors(M, n-d) J = ideal(R, minvec) @@ -785,7 +785,7 @@ function _singular_locus_with_decomposition(X::AbsSpec{<:Field, <:MPAnyQuoRing}, for i in 1:length(components) for j in (i+1):length(components) W = intersect(components[i],components[j]) - if !isempty(W) + if !isempty(W) push!(result, W) end end @@ -803,7 +803,7 @@ end ## compute *some* representative of the Jacobian matrix of gens(modulus), ## forgetting about the denominators (contribution killed by modulus anyway) -function _jacobian_matrix_modulus(X::AbsSpec{<:Ring, <:MPAnyQuoRing}) +function _jacobian_matrix_modulus(X::AbsAffineScheme{<:Ring, <:MPAnyQuoRing}) g = gens(modulus(underlying_quotient(OO(X)))) L = base_ring(underlying_quotient(OO(X))) n = nvars(L) @@ -812,12 +812,12 @@ function _jacobian_matrix_modulus(X::AbsSpec{<:Ring, <:MPAnyQuoRing}) end ######################################################################## -# (X) Attributes for AbsSpec -# +# (X) Attributes for AbsAffineScheme +# ######################################################################## @doc raw""" - defining_ideal(X::AbsSpec) + defining_ideal(X::AbsAffineScheme) Return the ideal `I` defining `X` in an appropriate ambient space. @@ -828,8 +828,8 @@ If `X = Spec(R)` and `R` is... - a localized polynomial ring `R[U⁻¹]`, then this returns the zero ideal in that ring; - a quotient of a localized polynomial ring `(R[U⁻¹])/J`, then this returns the ideal `J` in the ring `R[U⁻¹]`. -This behavior is streamlined with the return values of `modulus` on the algebraic side. -If you are looking for an ideal `I` in the polynomial `ambient_ring` of `X` defining +This behaviour is streamlined with the return values of `modulus` on the algebraic side. +If you are looking for an ideal `I` in the polynomial `ambient_ring` of `X` defining the closure of `X` in its `ambient_space`, use for instance `saturated_ideal(defining_ideal(X))`. ```jldoctest julia> X = affine_space(QQ,3) @@ -865,23 +865,23 @@ julia> base_ring(I) == R true ``` """ -defining_ideal(X::AbsSpec) = error("method not implemented for input of type $(typeof(X))") -@attr defining_ideal(X::AbsSpec{<:Any, <:MPolyRing}) = ideal(OO(X), [zero(OO(X))]) -defining_ideal(X::AbsSpec{<:Any, <:MPolyQuoRing}) = modulus(OO(X)) -defining_ideal(X::AbsSpec{<:Any, <:MPolyLocRing}) = modulus(OO(X)) -defining_ideal(X::AbsSpec{<:Any, <:MPolyQuoLocRing}) = modulus(OO(X)) +defining_ideal(X::AbsAffineScheme) = error("method not implemented for input of type $(typeof(X))") +@attr defining_ideal(X::AbsAffineScheme{<:Any, <:MPolyRing}) = ideal(OO(X), [zero(OO(X))]) +defining_ideal(X::AbsAffineScheme{<:Any, <:MPolyQuoRing}) = modulus(OO(X)) +defining_ideal(X::AbsAffineScheme{<:Any, <:MPolyLocRing}) = modulus(OO(X)) +defining_ideal(X::AbsAffineScheme{<:Any, <:MPolyQuoLocRing}) = modulus(OO(X)) ######################################################################## -# (4) Implementation of the AbsSpec interface for the basic Spec +# (4) Implementation of the AbsAffineScheme interface for the basic AffineScheme ######################################################################## -OO(X::Spec) = X.OO -base_ring(X::Spec) = X.kk -ambient_coordinate_ring(X::Spec{<:Any, <:MPolyRing}) = OO(X) -ambient_coordinate_ring(X::Spec{<:Any, <:MPolyQuoRing}) = base_ring(OO(X)) -ambient_coordinate_ring(X::Spec{<:Any, <:MPolyLocRing}) = base_ring(OO(X)) -ambient_coordinate_ring(X::Spec{<:Any, <:MPolyQuoLocRing}) = base_ring(OO(X)) -ambient_coordinate_ring(X::Spec{T, T}) where {T<:Field} = base_ring(X) +OO(X::AffineScheme) = X.OO +base_ring(X::AffineScheme) = X.kk +ambient_coordinate_ring(X::AffineScheme{<:Any, <:MPolyRing}) = OO(X) +ambient_coordinate_ring(X::AffineScheme{<:Any, <:MPolyQuoRing}) = base_ring(OO(X)) +ambient_coordinate_ring(X::AffineScheme{<:Any, <:MPolyLocRing}) = base_ring(OO(X)) +ambient_coordinate_ring(X::AffineScheme{<:Any, <:MPolyQuoLocRing}) = base_ring(OO(X)) +ambient_coordinate_ring(X::AffineScheme{T, T}) where {T<:Field} = base_ring(X) @@ -891,22 +891,22 @@ ambient_coordinate_ring(X::Spec{T, T}) where {T<:Field} = base_ring(X) # TODO: Needed? -ring_type(::Type{SpecType}) where {BRT, RT, SpecType<:AbsSpec{BRT, RT}} = RT -ring_type(X::AbsSpec) = ring_type(typeof(X)) +ring_type(::Type{AffineSchemeType}) where {BRT, RT, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = RT +ring_type(X::AbsAffineScheme) = ring_type(typeof(X)) -base_ring_type(::Type{SpecType}) where {BRT, RT, SpecType<:AbsSpec{BRT, RT}} = BRT -base_ring_type(X::AbsSpec) = base_ring_type(typeof(X)) -base_ring_elem_type(::Type{SpecType}) where {BRT, RT, SpecType<:AbsSpec{BRT, RT}} = elem_type(BRT) -base_ring_elem_type(X::AbsSpec) = base_ring_elem_type(typeof(X)) +base_ring_type(::Type{AffineSchemeType}) where {BRT, RT, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = BRT +base_ring_type(X::AbsAffineScheme) = base_ring_type(typeof(X)) +base_ring_elem_type(::Type{AffineSchemeType}) where {BRT, RT, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = elem_type(BRT) +base_ring_elem_type(X::AbsAffineScheme) = base_ring_elem_type(typeof(X)) -poly_type(::Type{SpecType}) where {BRT, RT<:MPolyRing, SpecType<:AbsSpec{BRT, RT}} = elem_type(RT) -poly_type(::Type{SpecType}) where {BRT, T, RT<:MPolyQuoRing{T}, SpecType<:AbsSpec{BRT, RT}} = T -poly_type(::Type{SpecType}) where {BRT, T, RT<:MPolyLocRing{<:Any, <:Any, <:Any, T}, SpecType<:AbsSpec{BRT, RT}} = T -poly_type(::Type{SpecType}) where {BRT, T, RT<:MPolyQuoLocRing{<:Any, <:Any, <:Any, T}, SpecType<:AbsSpec{BRT, RT}} = T -poly_type(X::AbsSpec) = poly_type(typeof(X)) +poly_type(::Type{AffineSchemeType}) where {BRT, RT<:MPolyRing, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = elem_type(RT) +poly_type(::Type{AffineSchemeType}) where {BRT, T, RT<:MPolyQuoRing{T}, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = T +poly_type(::Type{AffineSchemeType}) where {BRT, T, RT<:MPolyLocRing{<:Any, <:Any, <:Any, T}, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = T +poly_type(::Type{AffineSchemeType}) where {BRT, T, RT<:MPolyQuoLocRing{<:Any, <:Any, <:Any, T}, AffineSchemeType<:AbsAffineScheme{BRT, RT}} = T +poly_type(X::AbsAffineScheme) = poly_type(typeof(X)) -ring_type(::Type{Spec{BRT, RT}}) where {BRT, RT} = RT -ring_type(X::Spec) = ring_type(typeof(X)) -base_ring_type(::Type{Spec{BRT, RT}}) where {BRT, RT} = BRT -base_ring_type(X::Spec) = base_ring_type(typeof(X)) +ring_type(::Type{AffineScheme{BRT, RT}}) where {BRT, RT} = RT +ring_type(X::AffineScheme) = ring_type(typeof(X)) +base_ring_type(::Type{AffineScheme{BRT, RT}}) where {BRT, RT} = BRT +base_ring_type(X::AffineScheme) = base_ring_type(typeof(X)) diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl index 8a9ecf0b0651..dfd85beb8495 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl @@ -4,10 +4,33 @@ # (1) Generic constructors ######################################################## -spec(R::Ring) = Spec(R) +@doc raw""" + affine_scheme -> AffineScheme + affine_scheme(::Ring) + affine_scheme(::Ring, ::Ideal) + affine_scheme(::Ideal) + +Return the affine scheme defined by the input. +""" +affine_scheme + + +spec(I::Ideal) = affine_scheme(base_ring(I),I) +affine_scheme(I::Ideal) = affine_scheme(base_ring(I),I) + +@doc raw""" + spec(R::Ring) -> AffineScheme + +Return the spectrum of the given ring `R` as an affine scheme. +""" +spec(R::Ring) = AffineScheme(R) +affine_scheme(R::Ring) = AffineScheme(R) + +spec(kk::Ring, R::Ring) = AffineScheme(kk, R) +affine_scheme(kk::Ring, R::Ring) = AffineScheme(kk, R) @doc raw""" - Spec(R::MPolyRing, I::MPolyIdeal) + spec(R::MPolyRing, I::MPolyIdeal) Constructs the affine scheme of the ideal ``I`` in the ring ``R``. This is the spectrum of the quotient ring ``R/I``. @@ -18,7 +41,7 @@ julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]); julia> I = ideal(R, [x]); -julia> Spec(R, I) +julia> spec(R, I) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -26,11 +49,12 @@ Spectrum by ideal (x) ``` """ -Spec(R::MPolyRing, I::MPolyIdeal) = Spec(quo(R, I)[1]) +spec(R::MPolyRing, I::MPolyIdeal) = AffineScheme(quo(R, I)[1]) +affine_scheme(R::MPolyRing, I::MPolyIdeal) = AffineScheme(quo(R, I)[1]) @doc raw""" - Spec(R::MPolyRing, U::AbsMPolyMultSet) + spec(R::MPolyRing, U::AbsMPolyMultSet) Given a polynomial ring ``R``, we can localize that polynomial ring at a multiplicatively closed subset ``U`` of ``R``. The spectrum @@ -44,7 +68,7 @@ julia> I = ideal(R, [x]); julia> U = complement_of_prime_ideal(I); -julia> Spec(R, U) +julia> spec(R, U) Spectrum of localization of multivariate polynomial ring in 2 variables x, y @@ -52,11 +76,12 @@ Spectrum at complement of prime ideal (x) ``` """ -Spec(R::MPolyRing, U::AbsMPolyMultSet) = Spec(localization(R, U)[1]) +spec(R::MPolyRing, U::AbsMPolyMultSet) = AffineScheme(localization(R, U)[1]) +affine_scheme(R::MPolyRing, U::AbsMPolyMultSet) = AffineScheme(localization(R, U)[1]) @doc raw""" - Spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) + spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) We allow to combine quotients and localizations at the same time. That is, consider a polynomial ring ``R``, an ideal ``I`` of ``R`` and @@ -71,7 +96,7 @@ julia> I = ideal(R, [x]); julia> U = complement_of_prime_ideal(ideal(R, [y])); -julia> Spec(R, I, U) +julia> spec(R, I, U) Spectrum of localization of quotient @@ -81,7 +106,8 @@ Spectrum at complement of prime ideal (y) ``` """ -Spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) = Spec(MPolyQuoLocRing(R, I, U)) +spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) = AffineScheme(MPolyQuoLocRing(R, I, U)) +affine_scheme(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) = AffineScheme(MPolyQuoLocRing(R, I, U)) @@ -91,9 +117,9 @@ Spec(R::MPolyRing, I::MPolyIdeal, U::AbsMPolyMultSet) = Spec(MPolyQuoLocRing(R, #TODO: Do we need this? It is quite unusual. @doc raw""" - Spec(X::Spec) + spec(X::AffineScheme) -For convenience, an affine spectrum can be passed to `Spec` +For convenience, an affine spectrum can be passed to `AffineScheme` to create a new spectrum. This can be particularly useful when in need to copy an affine spectrum. @@ -103,14 +129,14 @@ julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]); julia> I = ideal(R, [x]); -julia> X = Spec(R, I) +julia> X = spec(R, I) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y over rational field by ideal (x) -julia> Y = Spec(X) +julia> Y = spec(X) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -118,9 +144,10 @@ Spectrum by ideal (x) ``` """ -Spec(X::Spec) = Spec(OO(X)) +spec(X::AffineScheme) = AffineScheme(OO(X)) +affine_scheme(X::AffineScheme) = AffineScheme(OO(X)) -Base.deepcopy_internal(X::Spec, dict::IdDict) = Spec(deepcopy_internal(OO(X), dict)) +Base.deepcopy_internal(X::AffineScheme, dict::IdDict) = AffineScheme(deepcopy_internal(OO(X), dict)) @@ -150,7 +177,7 @@ with coordinates [y1, y2, y3, y4, y5] """ function affine_space(kk::BRT, n::Int; variable_name="x") where {BRT<:Ring} R, _ = polynomial_ring(kk, [variable_name * "$i" for i in 1:n]) - return Spec(R) + return spec(R) end @@ -171,33 +198,33 @@ with coordinates [y1, z2, a] """ function affine_space(kk::BRT, var_symbols::Vector{Symbol}) where {BRT<:Ring} R, _ = polynomial_ring(kk, var_symbols) - return variety(Spec(R), check=false) + return variety(spec(R), check=false) end function affine_space(kk::BRT, n::Int; variable_name="x") where {BRT<:Field} R, _ = polynomial_ring(kk, [variable_name * "$i" for i in 1:n]) - return variety(Spec(R), check=false) + return variety(spec(R), check=false) end function affine_space(kk::BRT, var_symbols::Vector{Symbol}) where {BRT<:Field} R, _ = polynomial_ring(kk, var_symbols) - return variety(Spec(R), check=false) + return variety(spec(R), check=false) end ######################################################## -# (4) StdSpec (needed?) +# (4) StdAffineScheme (needed?) # Calling this in a constructor should be avoided # since we want to support all types of affine schemes. -# But StdSpec can be useful when implementing some +# But StdAffineScheme can be useful when implementing some # comparison or properties. ######################################################## @doc raw""" - standard_spec(X::AbsSpec) + standard_spec(X::AbsAffineScheme) -For an affine spectrum with coordinate ring of type `MPolyRing`, +For an affine scheme with coordinate ring of type `MPolyRing`, `MPolyQuoRing`, or `MPolyLocRing`, return the canonical -transform to a `Spec` of an `MPolyQuoLocRing`. +transform to an `AffineScheme` of an `MPolyQuoLocRing`. # Examples ```jldoctest @@ -214,7 +241,7 @@ julia> R, (x, y) = polynomial_ring(QQ, ["x", "y"]); julia> I = ideal(R, [x]); -julia> X = Spec(R, I) +julia> X = spec(R, I) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -234,7 +261,7 @@ julia> I = ideal(R, [x]); julia> U = complement_of_prime_ideal(I); -julia> X = Spec(R, U) +julia> X = spec(R, U) Spectrum of localization of multivariate polynomial ring in 2 variables x, y @@ -251,26 +278,26 @@ Spectrum at complement of prime ideal (x) ``` """ -function standard_spec(X::AbsSpec) +function standard_spec(X::AbsAffineScheme) error("not implemented for input of type $(typeof(X))") end -standard_spec(X::AbsSpec{<:Any, <:MPolyRing}) = Spec(MPolyQuoLocRing(OO(X), ideal(OO(X), [zero(OO(X))]), units_of(OO(X)))) +standard_spec(X::AbsAffineScheme{<:Any, <:MPolyRing}) = spec(MPolyQuoLocRing(OO(X), ideal(OO(X), [zero(OO(X))]), units_of(OO(X)))) # documented above -function standard_spec(X::AbsSpec{<:Any, <:MPolyQuoRing}) +function standard_spec(X::AbsAffineScheme{<:Any, <:MPolyQuoRing}) A = OO(X) R = base_ring(A) - return Spec(MPolyQuoLocRing(R, modulus(A), units_of(R))) + return AffineScheme(MPolyQuoLocRing(R, modulus(A), units_of(R))) end # documented above -standard_spec(X::AbsSpec{<:Any, <:MPolyLocRing}) = Spec(MPolyQuoLocRing(ambient_coordinate_ring(X), ideal(ambient_coordinate_ring(X), [zero(ambient_coordinate_ring(X))]), inverted_set(OO(X)))) +standard_spec(X::AbsAffineScheme{<:Any, <:MPolyLocRing}) = AffineScheme(MPolyQuoLocRing(ambient_coordinate_ring(X), ideal(ambient_coordinate_ring(X), [zero(ambient_coordinate_ring(X))]), inverted_set(OO(X)))) #documented above -standard_spec(X::AbsSpec{<:Any, <:MPolyQuoLocRing}) = Spec(OO(X)) +standard_spec(X::AbsAffineScheme{<:Any, <:MPolyQuoLocRing}) = AffineScheme(OO(X)) @@ -279,7 +306,7 @@ standard_spec(X::AbsSpec{<:Any, <:MPolyQuoLocRing}) = Spec(OO(X)) ######################################################## @doc raw""" - subscheme(X::AbsSpec, f::Vector{<:RingElem}) + subscheme(X::AbsAffineScheme, f::Vector{<:RingElem}) For an affine spectrum ``X`` and elements ``f_1``, ``f_2``, etc. of the coordinate ring of ``X``, this method computes @@ -317,16 +344,16 @@ Spectrum by ideal (x1, x2) ``` """ -subscheme(X::AbsSpec, f::Vector{<:RingElem}) = subscheme(X, ideal(OO(X), f)) -function subscheme(X::Spec, f::Vector{<:RingElem}) +subscheme(X::AbsAffineScheme, f::Vector{<:RingElem}) = subscheme(X, ideal(OO(X), f)) +function subscheme(X::AffineScheme, f::Vector{<:RingElem}) all(x->(parent(x) == OO(X)), f) || return subscheme(X, OO(X).(f)) return subscheme(X, ideal(OO(X), f)) end -subscheme(X::AbsSpec, f::RingElem) = subscheme(X, ideal(OO(X), [f])) +subscheme(X::AbsAffineScheme, f::RingElem) = subscheme(X, ideal(OO(X), [f])) @doc raw""" - subscheme(X::AbsSpec, I::Ideal) + subscheme(X::AbsAffineScheme, I::Ideal) For a scheme ``X = Spec(R)`` and an ideal ``I ⊂ 𝒪(X)``, return the closed subscheme defined by ``I``. @@ -356,19 +383,19 @@ Spectrum by ideal (x1*x2) ``` """ -function subscheme(X::AbsSpec, I::Ideal) +function subscheme(X::AbsAffineScheme, I::Ideal) base_ring(I) == OO(X) || return subscheme(X, ideal(OO(X), OO(X).(gens(I)))) # this will throw if coercion is not possible - Y = Spec(quo(OO(X), I)[1]) + Y = spec(quo(OO(X), I)[1]) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end -function sub(X::AbsSpec, a) +function sub(X::AbsAffineScheme, a) (a isa RingElem && parent(a) === OO(X)) || return sub(X, OO(X)(a)) return sub(X, ideal(OO(X), a)) end -function sub(X::AbsSpec, a::Vector) +function sub(X::AbsAffineScheme, a::Vector) all(a->a isa RingElem && parent(a) === OO(X), a) || return sub(X, OO(X).(a)) return sub(X, ideal(OO(X), a)) end @@ -379,7 +406,7 @@ end ######################################################## @doc raw""" - hypersurface_complement(X::AbsSpec, f::RingElem) + hypersurface_complement(X::AbsAffineScheme, f::RingElem) For a scheme ``X = Spec(R)`` and an element ``f ∈ R``, return the open subscheme ``U = Spec(R[f⁻¹]) = X ∖ V(f)`` @@ -410,55 +437,55 @@ Spectrum at products of (x1) ``` """ -function hypersurface_complement(X::AbsSpec, f::RingElem) - return hypersurface_complement(underlying_scheme(X), f)::AbsSpec +function hypersurface_complement(X::AbsAffineScheme, f::RingElem) + return hypersurface_complement(underlying_scheme(X), f)::AbsAffineScheme end -function hypersurface_complement(X::SpecType, f::RingElem) where {SpecType<:AbsSpec{<:Any, <:MPolyQuoLocRing}} +function hypersurface_complement(X::AffineSchemeType, f::RingElem) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyQuoLocRing}} parent(f) == OO(X) || return hypersurface_complement(X, OO(X)(f)) h = lifted_numerator(f) U = MPolyPowersOfElement(h) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end -function hypersurface_complement(X::SpecType, f::RingElem) where {SpecType<:AbsSpec{<:Any, <:MPolyLocRing}} +function hypersurface_complement(X::AffineSchemeType, f::RingElem) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyLocRing}} parent(f) == OO(X) || return hypersurface_complement(X, OO(X)(f)) h = numerator(f) U = MPolyPowersOfElement(h) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end -function hypersurface_complement(X::SpecType, f::RingElem) where {SpecType<:AbsSpec{<:Any, <:MPolyRing}} +function hypersurface_complement(X::AffineSchemeType, f::RingElem) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyRing}} parent(f) == OO(X) || return hypersurface_complement(X, OO(X)(f)) U = MPolyPowersOfElement(f) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end -function hypersurface_complement(X::SpecType, f::RingElem) where {SpecType<:AbsSpec{<:Any, <:MPolyQuoRing}} +function hypersurface_complement(X::AffineSchemeType, f::RingElem) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyQuoRing}} parent(f) == OO(X) || return hypersurface_complement(X, OO(X)(f)) U = MPolyPowersOfElement(lift(f)) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end @doc raw""" - hypersurface_complement(X::AbsSpec, f::Vector{<:RingElem}) + hypersurface_complement(X::AbsAffineScheme, f::Vector{<:RingElem}) For a scheme ``X = Spec(R)`` and elements ``f₁, f₂, ... ∈ R``, return the open subscheme ``U = Spec(R[f₁⁻¹,f₂⁻¹, ...]) = X ∖ V(f₁⋅f₂⋅…)`` @@ -489,48 +516,48 @@ Spectrum at products of (x1,x2) ``` """ -function hypersurface_complement(X::AbsSpec, f::Vector{<:RingElem}) - return hypersurface_complement(underlying_scheme(X), f)::AbsSpec +function hypersurface_complement(X::AbsAffineScheme, f::Vector{<:RingElem}) + return hypersurface_complement(underlying_scheme(X), f)::AbsAffineScheme end -function hypersurface_complement(X::SpecType, f::Vector{<:RingElem}) where {SpecType<:AbsSpec{<:Any, <:MPolyQuoLocRing}} +function hypersurface_complement(X::AffineSchemeType, f::Vector{<:RingElem}) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyQuoLocRing}} all(x->(parent(x) == OO(X)), f) || return hypersurface_complement(X, OO(X).(f)) h = lifted_numerator.(f) U = MPolyPowersOfElement(ambient_coordinate_ring(X), h) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end -function hypersurface_complement(X::SpecType, f::Vector{<:RingElem}) where {SpecType<:AbsSpec{<:Any, <:MPolyLocRing}} +function hypersurface_complement(X::AffineSchemeType, f::Vector{<:RingElem}) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyLocRing}} all(x->(parent(x) == OO(X)), f) || return hypersurface_complement(X, OO(X).(f)) h = numerator.(f) U = MPolyPowersOfElement(ambient_coordinate_ring(X), h) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end -function hypersurface_complement(X::SpecType, f::Vector{<:RingElem}) where {SpecType<:AbsSpec{<:Any, <:MPolyRing}} +function hypersurface_complement(X::AffineSchemeType, f::Vector{<:RingElem}) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyRing}} all(x->(parent(x) == OO(X)), f) || return hypersurface_complement(X, OO(X).(f)) U = MPolyPowersOfElement(ambient_coordinate_ring(X), f) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end -function hypersurface_complement(X::SpecType, f::Vector{<:RingElem}) where {SpecType<:AbsSpec{<:Any, <:MPolyQuoRing}} +function hypersurface_complement(X::AffineSchemeType, f::Vector{<:RingElem}) where {AffineSchemeType<:AbsAffineScheme{<:Any, <:MPolyQuoRing}} all(x->(parent(x) == OO(X)), f) || return hypersurface_complement(X, OO(X).(f)) U = MPolyPowersOfElement(ambient_coordinate_ring(X), lift.(f)) simplify!(U) W, _ = localization(OO(X), U) - Y = Spec(W) + Y = spec(W) set_attribute!(Y, :ambient_space, ambient_space(X)) return Y end @@ -550,12 +577,12 @@ Base.intersect(X::EmptyScheme{BRT}, E::EmptyScheme{BRT}) where {BRT<:Ring} = E # 7.2 Intersection methods not involving empty schemes -### For Specs of MPolyRings +### For AffineSchemes of MPolyRings # TODO intersect X,Y for X AbsSpec + closure(X::AbsAffineScheme) -> AbsAffineScheme Return the closure of `X` in its ambient affine space. """ -closure(X::AbsSpec) = closure(X, ambient_space(X), check= true) +closure(X::AbsAffineScheme) = closure(X, ambient_space(X), check= true) @@ -856,20 +883,20 @@ closure(X::AbsSpec) = closure(X, ambient_space(X), check= true) # Unions ###################################################################### -function union(X::AbsSpec{BRT,RT}, Y::AbsSpec{BRT,RT}) where {BRT, RT<:MPolyQuoRing} +function union(X::AbsAffineScheme{BRT,RT}, Y::AbsAffineScheme{BRT,RT}) where {BRT, RT<:MPolyQuoRing} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || error("schemes can not be compared") IX = modulus(OO(X)) IY = modulus(OO(Y)) - return Spec(R, intersect(IX, IY)) + return spec(R, intersect(IX, IY)) end -function union(X::AbsSpec{BRT,<:MPolyQuoRing}, Y::AbsSpec{BRT,<:MPolyRing}) where {BRT} +function union(X::AbsAffineScheme{BRT,<:MPolyQuoRing}, Y::AbsAffineScheme{BRT,<:MPolyRing}) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || error("schemes can not be compared") return X end -function union(X::AbsSpec{BRT,<:MPolyRing}, Y::AbsSpec{BRT,<:MPolyQuoRing}) where {BRT} +function union(X::AbsAffineScheme{BRT,<:MPolyRing}, Y::AbsAffineScheme{BRT,<:MPolyQuoRing}) where {BRT} return union(Y,X) end diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl index 9ab7d971caaf..71ca2d2847c6 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl @@ -6,23 +6,23 @@ # TODO: Add further cross-type comparison methods as needed. -function ==(X::T, Y::T) where {T<:AbsSpec{<:Ring, <:MPolyRing}} +function ==(X::T, Y::T) where {T<:AbsAffineScheme{<:Ring, <:MPolyRing}} return OO(X) === OO(Y) end -function ==(X::AbsSpec, Y::AbsSpec) +function ==(X::AbsAffineScheme, Y::AbsAffineScheme) X === Y && return true return is_subscheme(X, Y) && is_subscheme(Y, X) end -function ==(X::AbsSpec, Y::EmptyScheme) +function ==(X::AbsAffineScheme, Y::EmptyScheme) return is_subscheme(X, Y) end -==(X::EmptyScheme, Y::AbsSpec) = (Y == X) +==(X::EmptyScheme, Y::AbsAffineScheme) = (Y == X) ######################################################## @@ -32,7 +32,7 @@ end # We show a detailed version of the coordinate ring since they are all the # details we can get.. Otherwise our detailed printing is quite poor and # "useless". -function Base.show(io::IO, ::MIME"text/plain", X::AbsSpec) +function Base.show(io::IO, ::MIME"text/plain", X::AbsAffineScheme) io = pretty(io) println(io, "Spectrum") print(io, Indent(), "of ", Lowercase()) @@ -40,7 +40,7 @@ function Base.show(io::IO, ::MIME"text/plain", X::AbsSpec) print(io, Dedent()) end -function Base.show(io::IO, X::AbsSpec) +function Base.show(io::IO, X::AbsAffineScheme) if has_attribute(X, :name) print(io, name(X)) elseif get(io, :supercompact, false) @@ -52,17 +52,17 @@ function Base.show(io::IO, X::AbsSpec) end end -function _show(io::IO, X::AbsSpec) +function _show(io::IO, X::AbsAffineScheme) io = pretty(io) print(io, LowercaseOff(), "Spec of ") print(io, Lowercase(), OO(X)) end -function _show(io::IO, X::AbsSpec{<:Any,<:MPolyRing}) +function _show(io::IO, X::AbsAffineScheme{<:Any,<:MPolyRing}) print(io, "Affine ", ngens(OO(X)), "-space") end -function _show(io::IO, X::AbsSpec{<:Any,<:MPolyQuoRing}) +function _show(io::IO, X::AbsAffineScheme{<:Any,<:MPolyQuoRing}) io = pretty(io) print(io, "scheme(") I = modulus(OO(X)) @@ -70,7 +70,7 @@ function _show(io::IO, X::AbsSpec{<:Any,<:MPolyQuoRing}) print(io, ")") end -function _show(io::IO, X::AbsSpec{<:Any, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}) +function _show(io::IO, X::AbsAffineScheme{<:Any, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}) io = pretty(io) print(io, "scheme(") I = modulus(OO(X)) @@ -81,7 +81,7 @@ function _show(io::IO, X::AbsSpec{<:Any, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, print(io, ")") end -function _show(io::IO, X::AbsSpec{<:Any, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}) +function _show(io::IO, X::AbsAffineScheme{<:Any, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}) io = pretty(io) print(io, LowercaseOff(), "AA^", ngens(OO(X))) S = inverted_set(OO(X)) @@ -95,7 +95,7 @@ end ######################################################## @doc raw""" - is_non_zero_divisor(f::RingElem, X::AbsSpec) + is_non_zero_divisor(f::RingElem, X::AbsAffineScheme) Checks if a ring element is a non-zero divisor in the coordinate ring of an affine scheme. @@ -120,26 +120,26 @@ julia> is_non_zero_divisor(zero(OO(X)), X) false ``` """ -function is_non_zero_divisor(f::RingElem, X::AbsSpec) +function is_non_zero_divisor(f::RingElem, X::AbsAffineScheme) error("method not implemented for affine schemes of type $(typeof(X))") end -function is_non_zero_divisor(f::RingElem, X::AbsSpec{<:Ring, <:MPolyRing}) +function is_non_zero_divisor(f::RingElem, X::AbsAffineScheme{<:Ring, <:MPolyRing}) return !iszero(OO(X)(f)) end -function is_non_zero_divisor(f::MPolyQuoRingElem, X::AbsSpec{<:Ring, <:MPolyQuoRing}) +function is_non_zero_divisor(f::MPolyQuoRingElem, X::AbsAffineScheme{<:Ring, <:MPolyQuoRing}) R = ambient_coordinate_ring(X) I = modulus(OO(X)) J = ideal(R, lift(f)) return I == quotient(I, J) end -function is_non_zero_divisor(f::RingElem, X::AbsSpec{<:Ring, <:MPolyLocRing}) +function is_non_zero_divisor(f::RingElem, X::AbsAffineScheme{<:Ring, <:MPolyLocRing}) return !iszero(OO(X)(f)) end -function is_non_zero_divisor(f::RingElem, X::AbsSpec{<:Ring, <:MPolyQuoLocRing}) +function is_non_zero_divisor(f::RingElem, X::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing}) I = ideal(OO(X), [zero(OO(X))]) zero_ideal = Oscar.pre_image_ideal(I) J = Oscar.pre_image_ideal(ideal(OO(X), [f])) @@ -151,7 +151,7 @@ end # High level constructors of subschemes # ######################################################################## -function sub(X::AbsSpec, I::Ideal) +function sub(X::AbsAffineScheme, I::Ideal) inc = ClosedEmbedding(X, I) # Will complain if input is not compatible return domain(inc), inc end @@ -169,16 +169,16 @@ end # TODO: The method below is necessary for a temporary hotfix; see #1882. -# It seems likely that the implementation can be tuned so that, for -# instance, the massive use of primary decompositions can be avoided. -# This should eventually be addressed. +# It seems likely that the implementation can be tuned so that, for +# instance, the massive use of primary decompositions can be avoided. +# This should eventually be addressed. @doc raw""" - connected_components(X::AbsSpec) + connected_components(X::AbsAffineScheme) Return a decomposition of ``X`` into its connected components ``X = U₁ ∪ U₂ ∪ … ∪ Uₙ`` with ``Uᵢ`` a `PrincipalOpenSubset` of ``X``. """ -function connected_components(X::AbsSpec) +function connected_components(X::AbsAffineScheme) I = saturated_ideal(modulus(OO(X))) l = primary_decomposition(I) comp = [subscheme(X, Q) for (Q, _) in l] @@ -202,8 +202,8 @@ function connected_components(X::AbsSpec) end end - # We need to reproduce the components of X as `PrincipalOpenSubset`s. - # To this end, we first determine separating equations between pairs + # We need to reproduce the components of X as `PrincipalOpenSubset`s. + # To this end, we first determine separating equations between pairs # of components. n = length(comp) @@ -216,18 +216,18 @@ function connected_components(X::AbsSpec) separating_equations[i, j] = one(OO(X)) continue end - + v = OO(X).(gens(saturated_ideal(modulus(OO(C1))))) w = OO(X).(gens(saturated_ideal(modulus(OO(C2))))) J = ideal(OO(X), vcat(v, w)) # The idea is to write 1 = f + g with f ∈ I(C1) and g ∈ I(C2). - # Then 1 - f = g vanishes identically on C2, but is a unit in OO(C1) - # and vice versa. + # Then 1 - f = g vanishes identically on C2, but is a unit in OO(C1) + # and vice versa. c = coordinates(one(OO(X)), J) - # Conversion to assure compatibility. - # This can be removed, once the ideal interface is streamlined. + # Conversion to assure compatibility. + # This can be removed, once the ideal interface is streamlined. if c isa MatrixElem c = [c[1, i] for i in 1:ncols(c)]::Vector end @@ -254,18 +254,18 @@ end ######################################################################## @doc raw""" - base_change(phi::Any, X::AbsSpec) + base_change(phi::Any, X::AbsAffineScheme) -For an affine scheme `X` over a `base_ring` ``𝕜`` and a morphism -``φ : 𝕜 → 𝕂`` this computes ``Y = X × Spec(𝕂)`` and returns a pair +For an affine scheme `X` over a `base_ring` ``𝕜`` and a morphism +``φ : 𝕜 → 𝕂`` this computes ``Y = X × Spec(𝕂)`` and returns a pair `(Y, psi)` where `psi` is the canonical map ``Y → X``. """ -function base_change(phi::Any, X::AbsSpec) +function base_change(phi::Any, X::AbsAffineScheme) kk = base_ring(X) kk_red = parent(phi(zero(kk))) R = OO(X) R_red, Phi = _change_base_ring(phi, R) - Y = Spec(R_red) + Y = spec(R_red) return Y, morphism(Y, X, Phi) end @@ -288,8 +288,8 @@ function _change_base_ring(phi::Any, A::MPolyQuoRing) return Q, Phi_bar end -function _change_base_ring(phi::Any, - W::MPolyLocRing{<:Any, <:Any, <:Any, <:Any, +function _change_base_ring(phi::Any, + W::MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement} ) R = base_ring(W) @@ -300,8 +300,8 @@ function _change_base_ring(phi::Any, return W_red, hom(W, W_red, compose(Phi, loc_map), check=false) end -function _change_base_ring(phi::Any, - L::MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, +function _change_base_ring(phi::Any, + L::MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement} ) R = base_ring(L) diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl index 6c3607dd39bb..ce423a97161a 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Properties.jl @@ -3,7 +3,7 @@ #################################################################################### @doc raw""" - is_empty(X::AbsSpec) + is_empty(X::AbsAffineScheme) Check whether the affine scheme ``X`` is empty. @@ -24,7 +24,7 @@ julia> isempty(EmptyScheme(QQ)) true ``` """ -Base.isempty(X::AbsSpec) = iszero(one(OO(X))) +Base.isempty(X::AbsAffineScheme) = iszero(one(OO(X))) is_empty(X::EmptyScheme) = true @@ -38,10 +38,10 @@ is_empty(X::EmptyScheme) = true @doc raw""" - is_subscheme(X::AbsSpec, Y::AbsSpec) + is_subscheme(X::AbsAffineScheme, Y::AbsAffineScheme) Check whether ``X`` is a subset of ``Y`` based on the comparison of their coordinate rings. -See [`inclusion_morphism(::AbsSpec, ::AbsSpec)`](@ref) for the corresponding morphism. +See [`inclusion_morphism(::AbsAffineScheme, ::AbsAffineScheme)`](@ref) for the corresponding morphism. # Examples ```jldoctest @@ -74,13 +74,13 @@ julia> is_subscheme(Y, X) true ``` """ -function is_subscheme(X::AbsSpec, Y::AbsSpec) +function is_subscheme(X::AbsAffineScheme, Y::AbsAffineScheme) error("method `is_subscheme(X, Y)` not implemented for `X` of type $(typeof(X)) and `Y` of type $(typeof(Y))") end is_subscheme(X::EmptyScheme{BRT}, Y::Scheme{BRT}) where {BRT} = true -function is_subscheme(Y::AbsSpec{BRT, <:Any}, X::EmptyScheme{BRT}) where {BRT} +function is_subscheme(Y::AbsAffineScheme{BRT, <:Any}, X::EmptyScheme{BRT}) where {BRT} return iszero(one(OO(Y))) end @@ -88,16 +88,16 @@ end # (2.1) MPolyRing in first argument function is_subscheme( - X::AbsSpec{BRT, RT}, - Y::AbsSpec{BRT, RT} + X::AbsAffineScheme{BRT, RT}, + Y::AbsAffineScheme{BRT, RT} ) where {BRT, RT<:MPolyRing} return OO(X) === OO(Y) end function is_subscheme( - X::AbsSpec{BRT, <:MPolyRing}, - Y::AbsSpec{BRT, <:MPolyQuoRing} + X::AbsAffineScheme{BRT, <:MPolyRing}, + Y::AbsAffineScheme{BRT, <:MPolyQuoRing} ) where {BRT} R = OO(X) R === ambient_coordinate_ring(Y) || return false @@ -106,8 +106,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyRing}, - Y::AbsSpec{BRT, <:MPolyLocRing} + X::AbsAffineScheme{BRT, <:MPolyRing}, + Y::AbsAffineScheme{BRT, <:MPolyLocRing} ) where {BRT} R = OO(X) R === ambient_coordinate_ring(Y) || return false @@ -116,8 +116,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyRing}, - Y::AbsSpec{BRT, <:MPolyQuoLocRing} + X::AbsAffineScheme{BRT, <:MPolyRing}, + Y::AbsAffineScheme{BRT, <:MPolyQuoLocRing} ) where {BRT} R = OO(X) R === ambient_coordinate_ring(Y) || return false @@ -128,8 +128,8 @@ end # (2.2) MPolyQuoRing in first argument function is_subscheme( - X::AbsSpec{BRT, <:MPolyQuoRing}, - Y::AbsSpec{BRT, <:MPolyRing} + X::AbsAffineScheme{BRT, <:MPolyQuoRing}, + Y::AbsAffineScheme{BRT, <:MPolyRing} ) where {BRT} R = ambient_coordinate_ring(Y) R === ambient_coordinate_ring(X) || return false @@ -138,8 +138,8 @@ end function is_subscheme( - X::AbsSpec{BRT, RT}, - Y::AbsSpec{BRT, RT} + X::AbsAffineScheme{BRT, RT}, + Y::AbsAffineScheme{BRT, RT} ) where {BRT, RT<:MPolyQuoRing} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -148,8 +148,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyQuoRing}, - Y::AbsSpec{BRT, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} + X::AbsAffineScheme{BRT, <:MPolyQuoRing}, + Y::AbsAffineScheme{BRT, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} ) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -159,8 +159,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyQuoRing}, - Y::AbsSpec{BRT, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} + X::AbsAffineScheme{BRT, <:MPolyQuoRing}, + Y::AbsAffineScheme{BRT, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} ) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -172,8 +172,8 @@ end # (2.3) MPolyLocRing in first argument function is_subscheme( - X::AbsSpec{BRT, <:MPolyLocRing}, - Y::AbsSpec{BRT, <:MPolyRing} + X::AbsAffineScheme{BRT, <:MPolyLocRing}, + Y::AbsAffineScheme{BRT, <:MPolyRing} ) where {BRT} R = OO(Y) R == ambient_coordinate_ring(X) || return false @@ -182,8 +182,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyLocRing}, - Y::AbsSpec{BRT, <:MPolyQuoRing} + X::AbsAffineScheme{BRT, <:MPolyLocRing}, + Y::AbsAffineScheme{BRT, <:MPolyQuoRing} ) where {BRT} R = ambient_coordinate_ring(Y) R == ambient_coordinate_ring(X) || return false @@ -192,8 +192,8 @@ end function is_subscheme( - X::AbsSpec{BRT, RT}, - Y::AbsSpec{BRT, RT} + X::AbsAffineScheme{BRT, RT}, + Y::AbsAffineScheme{BRT, RT} ) where {BRT, RT<:MPolyLocRing} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -204,8 +204,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyLocRing}, - Y::AbsSpec{BRT, <:MPolyQuoLocRing} + X::AbsAffineScheme{BRT, <:MPolyLocRing}, + Y::AbsAffineScheme{BRT, <:MPolyQuoLocRing} ) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -218,8 +218,8 @@ end # (2.4) MPolyQuoLocRing in first argument function is_subscheme( - X::AbsSpec{BRT, <:MPolyQuoLocRing}, - Y::AbsSpec{BRT, <:MPolyRing} + X::AbsAffineScheme{BRT, <:MPolyQuoLocRing}, + Y::AbsAffineScheme{BRT, <:MPolyRing} ) where {BRT} R = OO(Y) R == ambient_coordinate_ring(X) || return false @@ -228,8 +228,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyQuoLocRing}, - Y::AbsSpec{BRT, <:MPolyQuoRing} + X::AbsAffineScheme{BRT, <:MPolyQuoLocRing}, + Y::AbsAffineScheme{BRT, <:MPolyQuoRing} ) where {BRT} R = ambient_coordinate_ring(Y) R == ambient_coordinate_ring(X) || return false @@ -239,8 +239,8 @@ end function is_subscheme( - X::AbsSpec{BRT, <:MPolyQuoLocRing}, - Y::AbsSpec{BRT, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} + X::AbsAffineScheme{BRT, <:MPolyQuoLocRing}, + Y::AbsAffineScheme{BRT, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} ) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -257,8 +257,8 @@ end function is_subscheme( - X::AbsSpec{BRT, RT}, - Y::AbsSpec{BRT, RT} + X::AbsAffineScheme{BRT, RT}, + Y::AbsAffineScheme{BRT, RT} ) where {BRT, RT<:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -275,8 +275,8 @@ function is_subscheme( end function is_subscheme( - X::AbsSpec{BRT, <:MPolyQuoLocRing}, - Y::AbsSpec{BRT, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyComplementOfKPointIdeal}}) where {BRT} + X::AbsAffineScheme{BRT, <:MPolyQuoLocRing}, + Y::AbsAffineScheme{BRT, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyComplementOfKPointIdeal}}) where {BRT} R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false UX = inverted_set(OO(X)) @@ -294,7 +294,7 @@ end #TODO: Add more cross-type methods as needed. @doc raw""" - is_open_embedding(X::AbsSpec, Y::AbsSpec) + is_open_embedding(X::AbsAffineScheme, Y::AbsAffineScheme) Checks whether ``X`` is openly embedded in ``Y``. @@ -336,14 +336,14 @@ julia> is_open_embedding(Z, X) true ``` """ -function is_open_embedding(X::AbsSpec, Y::AbsSpec) +function is_open_embedding(X::AbsAffineScheme, Y::AbsAffineScheme) return is_open_embedding(standard_spec(X), standard_spec(Y)) end function is_open_embedding( - X::Spec{BRT, RT}, - Y::Spec{BRT, RT} + X::AffineScheme{BRT, RT}, + Y::AffineScheme{BRT, RT} ) where {BRT, RT<:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} R = ambient_coordinate_ring(X) @@ -357,8 +357,8 @@ end function is_open_embedding( - X::Spec{BRT, <:MPolyQuoLocRing}, - Y::Spec{BRT, <:MPolyRing} + X::AffineScheme{BRT, <:MPolyQuoLocRing}, + Y::AffineScheme{BRT, <:MPolyRing} ) where {BRT} return OO(Y) == ambient_coordinate_ring(X) && all(iszero, gens(modulus(OO(X)))) end @@ -370,7 +370,7 @@ end #################################################################################### @doc raw""" - is_closed_embedding(X::AbsSpec, Y::AbsSpec) + is_closed_embedding(X::AbsAffineScheme, Y::AbsAffineScheme) Checks whether ``X`` is closed embedded in ``Y``. @@ -412,22 +412,22 @@ julia> is_closed_embedding(Z, X) false ``` """ -function is_closed_embedding(X::AbsSpec, Y::AbsSpec) +function is_closed_embedding(X::AbsAffineScheme, Y::AbsAffineScheme) error("`is_closed_embedding(X, Y)` not implemented for X of type $(typeof(X)) and Y of type $(typeof(Y))") end function is_closed_embedding( - X::AbsSpec{<:Ring, <:MPolyQuoRing}, - Y::AbsSpec{<:Ring, <:MPolyRing} + X::AbsAffineScheme{<:Ring, <:MPolyQuoRing}, + Y::AbsAffineScheme{<:Ring, <:MPolyRing} ) return ambient_coordinate_ring(X) === ambient_coordinate_ring(Y) end function is_closed_embedding( - X::AbsSpec{<:Ring, <:MPolyRing}, - Y::AbsSpec{<:Ring, <:MPolyQuoRing} + X::AbsAffineScheme{<:Ring, <:MPolyRing}, + Y::AbsAffineScheme{<:Ring, <:MPolyQuoRing} ) R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -436,8 +436,8 @@ end function is_closed_embedding( - X::AbsSpec{<:Ring, <:MPolyQuoRing}, - Y::AbsSpec{<:Ring, <:MPolyQuoRing} + X::AbsAffineScheme{<:Ring, <:MPolyQuoRing}, + Y::AbsAffineScheme{<:Ring, <:MPolyQuoRing} ) R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -446,8 +446,8 @@ end function is_closed_embedding( - X::AbsSpec{<:Ring, <:MPolyRing}, - Y::AbsSpec{<:Ring, <:MPolyRing} + X::AbsAffineScheme{<:Ring, <:MPolyRing}, + Y::AbsAffineScheme{<:Ring, <:MPolyRing} ) R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -456,10 +456,10 @@ end function is_closed_embedding( - X::AbsSpec{<:Ring, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, + X::AbsAffineScheme{<:Ring, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}, - Y::AbsSpec{<:Ring, <:MPolyRing} + Y::AbsAffineScheme{<:Ring, <:MPolyRing} ) R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -471,10 +471,10 @@ end function is_closed_embedding( - X::AbsSpec{<:Ring, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, + X::AbsAffineScheme{<:Ring, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}, - Y::AbsSpec{<:Ring, <:MPolyQuoRing} + Y::AbsAffineScheme{<:Ring, <:MPolyQuoRing} ) R = ambient_coordinate_ring(X) R === ambient_coordinate_ring(Y) || return false @@ -489,8 +489,8 @@ end function is_closed_embedding( - X::AbsSpec{BRT, RT}, - Y::AbsSpec{BRT, RT} + X::AbsAffineScheme{BRT, RT}, + Y::AbsAffineScheme{BRT, RT} ) where {BRT, RT<:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} R = ambient_coordinate_ring(X) @@ -502,8 +502,8 @@ end function is_closed_embedding( - X::Spec{BRT, <:MPolyQuoRing}, - Y::Spec{BRT, <:MPolyRing} + X::AffineScheme{BRT, <:MPolyQuoRing}, + Y::AffineScheme{BRT, <:MPolyRing} ) where {BRT} OO(Y) === ambient_coordinate_ring(X) || return false return true @@ -511,8 +511,8 @@ end function is_closed_embedding( - X::Spec{BRT, <:MPolyQuoRing}, - Y::Spec{BRT, <:RT} + X::AffineScheme{BRT, <:MPolyQuoRing}, + Y::AffineScheme{BRT, <:RT} ) where {BRT, RT<:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} R = ambient_coordinate_ring(X) @@ -522,12 +522,12 @@ function is_closed_embedding( end ############################################################################# -# (5) Check, if a Spec is equidimensional +# (5) Check, if an AffineScheme is equidimensional ############################################################################# # TODO: projective schemes, covered schemes @doc raw""" - is_equidimensional(X::AbsSpec{<:Field, <:MPolyAnyRing}) + is_equidimensional(X::AbsAffineScheme{<:Field, <:MPolyAnyRing}) Check whether the scheme `X` is equidimensional. @@ -549,14 +549,14 @@ Ideal generated by x - 1 y - 2 -julia> X = Spec(R,I) +julia> X = spec(R,I) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y over rational field by ideal (x - y) -julia> Y = Spec(R,I*J) +julia> Y = spec(R,I*J) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -570,7 +570,7 @@ julia> is_equidimensional(Y) false ``` """ -@attr Bool function is_equidimensional(X::AbsSpec{<:Field, <:MPAnyQuoRing}) +@attr Bool function is_equidimensional(X::AbsAffineScheme{<:Field, <:MPAnyQuoRing}) I = modulus(OO(X)) # equidimensional decomposition only available for schemes over a field P = equidimensional_decomposition_radical(saturated_ideal(I)) @@ -579,7 +579,7 @@ false end # make is_equidimensional agnostic to quotient -@attr Bool function is_equidimensional(X::AbsSpec{<:Field, <:MPAnyNonQuoRing}) +@attr Bool function is_equidimensional(X::AbsAffineScheme{<:Field, <:MPAnyNonQuoRing}) return true end @@ -589,25 +589,25 @@ end # TODO: projective schemes @doc raw""" - is_reduced(X::AbsSpec{<:Field, <:MPolyAnyRing}) + is_reduced(X::AbsAffineScheme{<:Field, <:MPolyAnyRing}) Check whether the affine scheme `X` is reduced. """ -@attr Bool function is_reduced(X::AbsSpec{<:Field, <:MPAnyQuoRing}) +@attr Bool function is_reduced(X::AbsAffineScheme{<:Field, <:MPAnyQuoRing}) I = saturated_ideal(modulus(OO(X))) return is_reduced(quo(base_ring(I), I)[1]) end ## make is_reduced agnostic to quotient ring -@attr Bool function is_reduced(X::AbsSpec{<:Field, <:MPAnyNonQuoRing}) +@attr Bool function is_reduced(X::AbsAffineScheme{<:Field, <:MPAnyNonQuoRing}) return true end -@attr Bool function is_geometrically_reduced(X::AbsSpec{<:Field, <:MPAnyNonQuoRing}) +@attr Bool function is_geometrically_reduced(X::AbsAffineScheme{<:Field, <:MPAnyNonQuoRing}) return true end -@attr Bool function is_geometrically_reduced(X::AbsSpec{<:Field, <:MPAnyQuoRing}) +@attr Bool function is_geometrically_reduced(X::AbsAffineScheme{<:Field, <:MPAnyQuoRing}) F = base_ring(X) # is_perfect(F) # needs new AbstractAlgebra version if characteristic(F) == 0 || F isa FinField # F is perfect @@ -624,7 +624,7 @@ end # TODO: is_regular using Hironaka's criterion @doc raw""" - is_smooth(X::AbsSpec{<:Field, <:MPolyAnyRing}) + is_smooth(X::AbsAffineScheme{<:Field, <:MPolyAnyRing}) Check whether the scheme `X` is smooth. @@ -651,7 +651,7 @@ julia> J = ideal(R,[x^2-y^2]) Ideal generated by x^2 - y^2 -julia> X = Spec(R, I) +julia> X = spec(R, I) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -661,7 +661,7 @@ Spectrum julia> is_smooth(X) true -julia> Y = Spec(R, J) +julia> Y = spec(R, J) Spectrum of quotient of multivariate polynomial ring in 2 variables x, y @@ -676,7 +676,7 @@ Complement of maximal ideal corresponding to rational point with coordinates (1, 1) in multivariate polynomial ring in 2 variables over QQ -julia> Z = Spec(R, J, U) +julia> Z = spec(R, J, U) Spectrum of localization of quotient @@ -690,7 +690,7 @@ true ``` """ -@attr Bool function is_smooth(X::AbsSpec{<:Field, <:MPolyQuoLocRing}) +@attr Bool function is_smooth(X::AbsAffineScheme{<:Field, <:MPolyQuoLocRing}) R = base_ring(OO(X)) L = localized_ring(OO(X)) I = modulus(OO(X)) @@ -701,7 +701,7 @@ true return success end -@attr Bool function is_smooth(X::AbsSpec{<:Field, <:MPolyQuoRing}) +@attr Bool function is_smooth(X::AbsAffineScheme{<:Field, <:MPolyQuoRing}) R = base_ring(OO(X)) I = modulus(OO(X)) f = gens(I) @@ -712,8 +712,8 @@ end end ## make is_smooth agnostic to quotient ring -is_smooth(X::AbsSpec{<:Field, <:MPolyRing}) = true -is_smooth(X::AbsSpec{<:Field, <:MPolyLocRing}) = true +is_smooth(X::AbsAffineScheme{<:Field, <:MPolyRing}) = true +is_smooth(X::AbsAffineScheme{<:Field, <:MPolyLocRing}) = true ################################################################### # Irreducibility and Integrality # @@ -722,7 +722,7 @@ is_smooth(X::AbsSpec{<:Field, <:MPolyLocRing}) = true # irreducible = nilradical of OO(X) is prime # ################################################################### @doc raw""" - is_irreducible(X::AbsSpec) + is_irreducible(X::AbsAffineScheme) Check whether the affine scheme `X` is irreducible. @@ -730,22 +730,22 @@ Check whether the affine scheme `X` is irreducible. Irreducibility is checked over the (computable) base field of the affine scheme as specified upon creation of the ring, not over the algebraic closure thereof. """ -@attr Bool function is_irreducible(X::AbsSpec{<:Field, <:MPolyAnyRing}) +@attr Bool function is_irreducible(X::AbsAffineScheme{<:Field, <:MPolyAnyRing}) !is_empty(X) || return false !get_attribute(X, :is_integral, false) || return true ## integral = irreducible + reduced return (length(minimal_primes(saturated_ideal(modulus(OO(X))))) == 1) end -is_irreducible(X::AbsSpec{<:Field,<:MPolyRing}) = true -is_irreducible(X::AbsSpec{<:Field,<:MPolyLocRing}) = true +is_irreducible(X::AbsAffineScheme{<:Field,<:MPolyRing}) = true +is_irreducible(X::AbsAffineScheme{<:Field,<:MPolyLocRing}) = true @doc raw""" - is_integral(X::AbsSpec) + is_integral(X::AbsAffineScheme) Check whether the affine scheme `X` is integral, i.e. irreducible and reduced. """ -@attr Bool function is_integral(X::AbsSpec{<:Field, <:MPolyAnyRing}) +@attr Bool function is_integral(X::AbsAffineScheme{<:Field, <:MPolyAnyRing}) !is_empty(X) || return false if has_attribute(X,:is_reduced) && has_attribute(X,:is_irreducible) return get_attribute(X,:is_reduced) && get_attribute(X,:is_irreducible) @@ -754,18 +754,18 @@ Check whether the affine scheme `X` is integral, i.e. irreducible and reduced. end @doc raw""" - is_geometrically_integral(X::AbsSpec) + is_geometrically_integral(X::AbsAffineScheme) Test if ``X/k`` is geometrically integral. That is if ``X`` is integral when base changed to any field extension of ``k``. """ -@attr Bool function is_geometrically_integral(X::AbsSpec{<:Field,<:MPolyAnyRing}) +@attr Bool function is_geometrically_integral(X::AbsAffineScheme{<:Field,<:MPolyAnyRing}) is_integral(X) || return false throw(NotImplementedError(:is_geometrically_integral, "absolute primary decomposition is currently only available over the rationals")) end -@attr Bool function is_geometrically_integral(X::AbsSpec{<:QQField, <:MPolyAnyRing}) +@attr Bool function is_geometrically_integral(X::AbsAffineScheme{<:QQField, <:MPolyAnyRing}) is_integral(X) || return false I = saturated_ideal(defining_ideal(X)) AI = absolute_primary_decomposition(I) @@ -777,11 +777,11 @@ end # Connectedness # ################################################################### @doc raw""" - is_connected(X::AbsSpec) + is_connected(X::AbsAffineScheme) Check whether the affine scheme `X` is connected. """ -@attr Bool function is_connected(X::AbsSpec) +@attr Bool function is_connected(X::AbsAffineScheme) error("not implemented yet") ## note for future implementation: expensive property ## 1) do primary decomposition diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Types.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Types.jl index 490e86d1fce8..d0a7bbce8d37 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Types.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Types.jl @@ -17,12 +17,12 @@ ########################################### #@doc raw""" -# AbsSpec{BaseRingType, RingType<:Ring} +# AbsAffineScheme{BaseRingType, RingType<:Ring} # #An affine scheme ``X = Spec(R)`` with ``R`` of type `RingType` over #a ring ``𝕜`` of type `BaseRingType`. #""" -#abstract type AbsSpec{BaseRingType, RingType<:Ring} <: Scheme{BaseRingType} end +#abstract type AbsAffineScheme{BaseRingType, RingType<:Ring} <: Scheme{BaseRingType} end # # Moved to src/forward_declarations.jl @@ -31,42 +31,42 @@ ############################################ @doc raw""" - Spec{BaseRingType, RingType} + AffineScheme{BaseRingType, RingType} An affine scheme ``X = Spec(R)`` with ``R`` a Noetherian ring of type `RingType` over a base ring ``𝕜`` of type `BaseRingType`. """ -@attributes mutable struct Spec{BaseRingType, RingType<:Ring} <: AbsSpec{BaseRingType, RingType} +@attributes mutable struct AffineScheme{BaseRingType, RingType<:Ring} <: AbsAffineScheme{BaseRingType, RingType} # the basic fields OO::RingType kk::BaseRingType - function Spec(OO::MPolyQuoLocRing) + function AffineScheme(OO::MPolyQuoLocRing) kk = coefficient_ring(base_ring(OO)) return new{typeof(kk), typeof(OO)}(OO, kk) end - function Spec(OO::MPolyLocRing) + function AffineScheme(OO::MPolyLocRing) kk = coefficient_ring(base_ring(OO)) return new{typeof(kk), typeof(OO)}(OO, kk) end - function Spec(OO::MPolyRing) + function AffineScheme(OO::MPolyRing) kk = coefficient_ring(OO) return new{typeof(kk), typeof(OO)}(OO, kk) end - function Spec(OO::MPolyQuoRing) + function AffineScheme(OO::MPolyQuoRing) kk = coefficient_ring(base_ring(OO)) return new{typeof(kk), typeof(OO)}(OO, kk) end - function Spec(R::Ring) + function AffineScheme(R::Ring) return new{typeof(ZZ), typeof(R)}(R, ZZ) end - function Spec(kk::Ring, R::Ring) + function AffineScheme(kk::Ring, R::Ring) return new{typeof(kk), typeof(R)}(R, kk) end - function Spec(kk::Field) + function AffineScheme(kk::Field) return new{typeof(kk), typeof(kk)}(kk, kk) end end @@ -77,5 +77,5 @@ end # (3) Auxiliary types ########################################### -StdSpec = AbsSpec{<:Ring, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} +StdAffineScheme = AbsAffineScheme{<:Ring, <:MPolyQuoLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}} diff --git a/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Attributes.jl index 132b0281b1bb..144898c54a62 100644 --- a/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Attributes.jl @@ -1,6 +1,6 @@ ######################################################################## # -# (1) AbsSpec interface +# (1) AbsAffineScheme interface # ######################################################################## diff --git a/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Constructors.jl index 08c8e8aa8643..f5b948b5db93 100644 --- a/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineVariety/Objects/Constructors.jl @@ -2,13 +2,13 @@ # (1) Generic constructors ######################################################## @doc raw""" - variety(X::AbsSpec; is_reduced::false, check::Bool=true) -> AffineVariety + variety(X::AbsAffineScheme; is_reduced::false, check::Bool=true) -> AffineVariety Convert ``X`` to an affine variety. If `is_reduced` is set, assume that `X` is already reduced. """ -function variety(X::AbsSpec{<:Field}; is_reduced=false, check::Bool=true) +function variety(X::AbsAffineScheme{<:Field}; is_reduced=false, check::Bool=true) X = algebraic_set(X, is_reduced=is_reduced, check=check) return variety(X, check=check) end @@ -76,7 +76,7 @@ defined by ideal (x, y) ``` """ -variety(R::MPolyAnyRing; check=true) = variety(Spec(R), check=check) +variety(R::MPolyAnyRing; check=true) = variety(spec(R), check=check) @doc raw""" variety(f::MPolyRingElem{<:Field}; check::Bool=true) diff --git a/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Attributes.jl b/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Attributes.jl index 6c344c4ba831..1044febf2107 100644 --- a/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Attributes.jl @@ -15,7 +15,7 @@ image_ideal(f::ClosedEmbedding) = f.I::ideal_type(OO(codomain(f))) function complement(f::ClosedEmbedding) if !isdefined(f, :U) - U = SpecOpen(codomain(f), image_ideal(f)) + U = AffineSchemeOpenSubscheme(codomain(f), image_ideal(f)) f.U = U end return f.U diff --git a/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Types.jl b/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Types.jl index 8aed3dd9e290..6ef052357634 100644 --- a/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Types.jl +++ b/src/AlgebraicGeometry/Schemes/ClosedEmbedding/Types.jl @@ -9,31 +9,31 @@ A closed embedding ``f : X → Y`` of affine schemes ``X = Spec(S)`` into ``Y = Spec(R)`` such that ``S ≅ R/I`` via ``f`` for some ideal ``I ⊂ R``. """ -@attributes mutable struct ClosedEmbedding{DomainType<:AbsSpec, - CodomainType<:AbsSpec, +@attributes mutable struct ClosedEmbedding{DomainType<:AbsAffineScheme, + CodomainType<:AbsAffineScheme, PullbackType<:Map - }<:AbsSpecMor{DomainType, + }<:AbsAffineSchemeMor{DomainType, CodomainType, PullbackType, ClosedEmbedding, Nothing } - inc::SpecMor{DomainType, CodomainType, PullbackType} + inc::AffineSchemeMor{DomainType, CodomainType, PullbackType} I::Ideal - U::SpecOpen + U::AffineSchemeOpenSubscheme # On an affine scheme X return the subscheme defined by I ⊂ 𝒪(X). - function ClosedEmbedding(X::AbsSpec, I::Ideal; check=true) + function ClosedEmbedding(X::AbsAffineScheme, I::Ideal; check=true) base_ring(I) === OO(X) || error("ideal does not belong to the correct ring") Y = subscheme(X, I) inc = morphism(Y, X, hom(OO(X), OO(Y), gens(OO(Y)), check=false), check=false) return new{typeof(Y), typeof(X), pullback_type(inc)}(inc, I) end - # Turn a dummy SpecMor for a canonical inclusion into a ClosedEmbedding. + # Turn a dummy AffineSchemeMor for a canonical inclusion into a ClosedEmbedding. # This requires specifying an ideal I such that the domain of the # map is naturally isomorphic to the subscheme defined by that ideal. - function ClosedEmbedding(f::SpecMor, I::Ideal; check::Bool=true) + function ClosedEmbedding(f::AffineSchemeMor, I::Ideal; check::Bool=true) Y = domain(f) X = codomain(f) base_ring(I) == OO(X) || error("ideal does not belong to the correct ring") diff --git a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl index 28fd59935ecd..1f662e64e86d 100644 --- a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Attributes.jl @@ -2,7 +2,7 @@ ######################################################################## # Interface for AbsCoveredSchemeMorphism # ######################################################################## -### essential getters +### essential getters function domain(f::AbsCoveredSchemeMorphism{T}) where {T<:AbsCoveredScheme} return domain(underlying_morphism(f))::T end @@ -63,7 +63,7 @@ end ### generically derived getters domain_covering(f::AbsCoveredSchemeMorphism) = domain(covering_morphism(f)) codomain_covering(f::AbsCoveredSchemeMorphism) = codomain(covering_morphism(f)) -getindex(f::AbsCoveredSchemeMorphism, U::Spec) = covering_morphism(f)[U] +getindex(f::AbsCoveredSchemeMorphism, U::AffineScheme) = covering_morphism(f)[U] ######################################################################## # Basic getters for CoveredSchemeMorphism # @@ -75,16 +75,16 @@ covering_morphism(f::CoveredSchemeMorphism) = f.f @doc raw""" isomorphism_on_open_subsets(f::AbsCoveredSchemeMorphism) -For a birational morphism ``f : X → Y`` of `AbsCoveredScheme`s this -returns an isomorphism of affine schemes ``fᵣₑₛ : U → V`` which is -the restriction of ``f`` to two dense open subsets ``U ⊂ X`` and +For a birational morphism ``f : X → Y`` of `AbsCoveredScheme`s this +returns an isomorphism of affine schemes ``fᵣₑₛ : U → V`` which is +the restriction of ``f`` to two dense open subsets ``U ⊂ X`` and ``V ⊂ Y``. """ function isomorphism_on_open_subsets(f::AbsCoveredSchemeMorphism) if !has_attribute(f, :iso_on_open_subset) is_birational(f) # Should compute and store the attribute end - return get_attribute(f, :iso_on_open_subset)::AbsSpecMor + return get_attribute(f, :iso_on_open_subset)::AbsAffineSchemeMor end @attr AbsCoveredSchemeMorphism function inverse(f::AbsCoveredSchemeMorphism) diff --git a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Methods.jl b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Methods.jl index 1489be0c9b1b..18b124db39ad 100644 --- a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Morphisms/Methods.jl @@ -90,9 +90,9 @@ function compose(f::AbsCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism) end end -function maps_with_given_codomain(f::AbsCoveredSchemeMorphism, V::AbsSpec) +function maps_with_given_codomain(f::AbsCoveredSchemeMorphism, V::AbsAffineScheme) fcov = covering_morphism(f) - result = Vector{AbsSpecMor}() + result = Vector{AbsAffineSchemeMor}() for U in keys(morphisms(fcov)) floc = morphisms(fcov)[U] codomain(floc) === V || continue @@ -133,14 +133,14 @@ function base_change(phi::Any, f::AbsCoveredSchemeMorphism; end function _register_birationality!(f::AbsCoveredSchemeMorphism, - g::AbsSpecMor, ginv::AbsSpecMor) + g::AbsAffineSchemeMor, ginv::AbsAffineSchemeMor) set_attribute!(g, :inverse, ginv) set_attribute!(ginv, :inverse, g) return _register_birationality(f, g) end function _register_birationality!(f::AbsCoveredSchemeMorphism, - g::AbsSpecMor + g::AbsAffineSchemeMor ) set_attribute!(f, :is_birational, true) set_attribute!(f, :iso_on_open_subset, g) diff --git a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Attributes.jl index cba66897ec41..6dcb117377bd 100644 --- a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Attributes.jl @@ -132,7 +132,7 @@ with default covering 3: [(s0//s2), (s1//s2)] julia> affine_charts(Xcov) -3-element Vector{Spec{QQField, MPolyQuoRing{QQMPolyRingElem}}}: +3-element Vector{AffineScheme{QQField, MPolyQuoRing{QQMPolyRingElem}}}: scheme((s1//s0) - (s2//s0)^2) scheme((s0//s1) - (s2//s1)^2) scheme((s0//s2)*(s1//s2) - 1) @@ -166,7 +166,7 @@ has_name(X::AbsCoveredScheme) = has_attribute(X, :name) ######################################################################## # Auxiliary attributes # ######################################################################## -function dim(X::AbsCoveredScheme) +function dim(X::AbsCoveredScheme) if !has_attribute(X, :dim) d = -1 is_equidimensional=true @@ -180,8 +180,8 @@ function dim(X::AbsCoveredScheme) set_attribute!(X, :dim, d) if !is_equidimensional # the above is not an honest check for equidimensionality, - # because in each chart the output of `dim` is only the - # supremum of all components. Thus we can only infer + # because in each chart the output of `dim` is only the + # supremum of all components. Thus we can only infer # non-equidimensionality in case this is already visible # from comparing the different charts set_attribute!(X, :is_equidimensional, false) @@ -191,7 +191,7 @@ function dim(X::AbsCoveredScheme) end @attr function singular_locus_reduced(X::AbsCoveredScheme) - D = IdDict{AbsSpec, Ideal}() + D = IdDict{AbsAffineScheme, Ideal}() for U in affine_charts(X) _, inc_sing = singular_locus_reduced(U) D[U] = image_ideal(inc_sing) @@ -260,7 +260,7 @@ given by the pullback function @attr function singular_locus( X::AbsCoveredScheme; ) - D = IdDict{AbsSpec, Ideal}() + D = IdDict{AbsAffineScheme, Ideal}() covering = get_attribute(X, :simplified_covering, default_covering(X)) for U in covering _, inc_sing = singular_locus(U) @@ -274,7 +274,7 @@ end @attr function ideal_sheaf_of_singular_locus( X::AbsCoveredScheme; ) - D = IdDict{AbsSpec, Ideal}() + D = IdDict{AbsAffineScheme, Ideal}() covering = get_attribute(X, :simplified_covering, default_covering(X)) for U in covering _, inc_sing = singular_locus(U) diff --git a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Constructors.jl index f9eb98f24894..6fa74959e125 100644 --- a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Constructors.jl @@ -16,9 +16,9 @@ julia> P1, (x,y) = QQ["x", "y"]; julia> P2, (u,v) = QQ["u", "v"]; -julia> U1 = Spec(P1); +julia> U1 = spec(P1); -julia> U2 = Spec(P2); +julia> U2 = spec(P2); julia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts Covering @@ -69,7 +69,7 @@ function CoveredScheme(C::Covering) end ### Conversion of an affine scheme into a covered scheme -CoveredScheme(X::AbsSpec) = CoveredScheme(Covering(X)) +CoveredScheme(X::AbsAffineScheme) = CoveredScheme(Covering(X)) ### Construct the empty covered scheme over the ring R function empty_covered_scheme(R::RT) where {RT<:AbstractAlgebra.Ring} diff --git a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Methods.jl index 7a952242c676..815138f7ebac 100644 --- a/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/CoveredSchemes/Objects/Methods.jl @@ -3,11 +3,11 @@ # Required methods for AbsCoveredScheme # ######################################################################## ### Forwarding of the non-documented getters -Base.in(U::AbsSpec, X::AbsCoveredScheme) = (U in underlying_scheme(X))::Bool +Base.in(U::AbsAffineScheme, X::AbsCoveredScheme) = (U in underlying_scheme(X))::Bool getindex(X::AbsCoveredScheme, i::Int) = coverings(underlying_scheme(X))[i]::Covering getindex(X::AbsCoveredScheme, C::Covering, D::Covering) = getindex(underlying_scheme(X), C, D)::CoveringMorphism #setindex(X::AbsCoveredScheme, f::CoveringMorphism, C::Covering, D::Covering) = setindex(underlying_scheme(X), f, C, D)::CoveringMorphism -gluings(X::AbsCoveredScheme) = gluings(underlying_scheme(X))::IdDict{<:Tuple{<:AbsSpec, <:AbsSpec}, <:AbsGluing} +gluings(X::AbsCoveredScheme) = gluings(underlying_scheme(X))::IdDict{<:Tuple{<:AbsAffineScheme, <:AbsAffineScheme}, <:AbsGluing} ######################################################################## # Finding coverings, patches, and gluings # @@ -26,7 +26,7 @@ end getindex(X::AbsCoveredScheme, i::Int, j::Int) = X[X[i], X[j]] -Base.in(U::AbsSpec, X::CoveredScheme) = any(C->(U in C), coverings(X)) +Base.in(U::AbsAffineScheme, X::CoveredScheme) = any(C->(U in C), coverings(X)) ######################################################################## # Printing # diff --git a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Attributes.jl b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Attributes.jl index bc90e581cfc3..815a151c70ba 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Attributes.jl @@ -4,6 +4,6 @@ ######################################################################## domain(f::CoveringMorphism) = f.domain codomain(f::CoveringMorphism) = f.codomain -getindex(f::CoveringMorphism, U::AbsSpec) = f.morphisms[U] +getindex(f::CoveringMorphism, U::AbsAffineScheme) = f.morphisms[U] morphisms(f::CoveringMorphism) = f.morphisms diff --git a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Constructors.jl b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Constructors.jl index 62ce2b436961..3bdb5ae1abc4 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Constructors.jl @@ -52,7 +52,7 @@ given by the pullback functions ``` """ function identity_map(C::Covering) - map_dict = IdDict{AbsSpec, AbsSpecMor}() + map_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(C) map_dict[U] = identity_map(U) end @@ -70,7 +70,7 @@ This function produces the inclusion map `ref -> orig` which is realized on all `patches` as `PrincipalOpenEmbedding`s. """ function refinement_morphism(ref::Covering, orig::Covering) - map_dict = IdDict{AbsSpec, AbsSpecMor}() + map_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(ref) inc, h = _find_chart(U, orig) # TODO: construct and cache the inverse on image diff --git a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Methods.jl b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Methods.jl index 89e9e5ccdef2..e12cc0c34277 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Methods.jl @@ -3,7 +3,7 @@ ######################################################################## function compose(f::CoveringMorphism, g::CoveringMorphism) domain(g) === codomain(f) || error("morphisms can not be composed") - morphism_dict = IdDict{AbsSpec, AbsSpecMor}() + morphism_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(domain(f)) morphism_dict[U] = compose(f[U], g[codomain(f[U])]) end @@ -23,9 +23,9 @@ resulting covering ``C'`` and the identifying isomorphism """ function simplify(C::Covering) n = n_patches(C) - new_patches = AbsSpec[simplify(X) for X in patches(C)] + new_patches = AbsAffineScheme[simplify(X) for X in patches(C)] GD = gluings(C) - new_gluings = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() + new_gluings = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() for (X, Y) in keys(GD) Xsimp = new_patches[C[X]] iX, jX = identification_maps(Xsimp) @@ -37,8 +37,8 @@ function simplify(C::Covering) RestrictionDataIsomorphism(G, jX, jY) ) end - iDict = IdDict{AbsSpec, AbsSpecMor}() - jDict = IdDict{AbsSpec, AbsSpecMor}() + iDict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() + jDict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for i in 1:length(new_patches) iDict[new_patches[i]] = identification_maps(new_patches[i])[1] jDict[C[i]] = identification_maps(new_patches[i])[2] @@ -70,7 +70,7 @@ function base_change(phi::Any, f::CoveringMorphism; C = codomain(f) DD = domain(domain_map) CC = domain(codomain_map) - mor_dict = IdDict{AbsSpec, AbsSpecMor}() + mor_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for UU in patches(DD) U = codomain(domain_map[UU]) V = codomain(f[U]) @@ -254,10 +254,10 @@ function fiber_product(f::CoveringMorphism, g::CoveringMorphism) C = codomain(f) @assert C === codomain(g) "codomains do not agree" - new_patches = AbsSpec[] - cache = IdDict{AbsSpec, Tuple{<:AbsSpecMor, <:AbsSpecMor}}() - maps_to_A = IdDict{AbsSpec, AbsSpecMor}() - maps_to_B = IdDict{AbsSpec, AbsSpecMor}() + new_patches = AbsAffineScheme[] + cache = IdDict{AbsAffineScheme, Tuple{<:AbsAffineSchemeMor, <:AbsAffineSchemeMor}}() + maps_to_A = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() + maps_to_B = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(A) f_U = f[U] W = codomain(f_U) diff --git a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Types.jl b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Types.jl index d935f099d27b..39d4f6b074cc 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Types.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Morphisms/Types.jl @@ -6,7 +6,7 @@ CoveringMorphism A morphism ``f : C → D`` of two coverings. For every patch ``U`` of ``C`` this -provides a map `f[U']` of type `SpecMorType` from ``U' ⊂ U`` to +provides a map `f[U']` of type `AffineSchemeMorType` from ``U' ⊂ U`` to some patch `codomain(f[U])` in `D` for some affine patches ``U'`` covering ``U``. **Note:** For two affine patches ``U₁, U₂ ⊂ U`` the codomains of `f[U₁]` and `f[U₂]` @@ -15,24 +15,24 @@ have to coincide on their overlaps. """ mutable struct CoveringMorphism{DomainType<:Covering, CodomainType<:Covering, - MorphismType<:AbsSpecMor, + MorphismType<:AbsAffineSchemeMor, BaseMorType } domain::DomainType codomain::CodomainType - morphisms::IdDict{<:AbsSpec, <:MorphismType} # on a patch X of the domain covering, this + morphisms::IdDict{<:AbsAffineScheme, <:MorphismType} # on a patch X of the domain covering, this # returns the morphism φ : X → Y to the corresponding # patch Y of the codomain covering. function CoveringMorphism( dom::DomainType, cod::CodomainType, - mor::IdDict{<:AbsSpec, MorphismType}; + mor::IdDict{<:AbsAffineScheme, MorphismType}; check::Bool=true ) where { DomainType<:Covering, CodomainType<:Covering, - MorphismType<:AbsSpecMor + MorphismType<:AbsAffineSchemeMor } # TODO: check domain/codomain compatibility # TODO: if check is true, check that all morphisms glue and that the domain patches diff --git a/src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl index 9de713960257..4730bc9364ea 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Objects/Attributes.jl @@ -6,8 +6,8 @@ base_ring_type(::Type{Covering{T}}) where {T} = T base_ring_type(C::Covering) = base_ring_type(typeof(C)) ### type constructors -#covering_type(::Type{T}) where {T<:Spec} = Covering{T, gluing_type(T)} -#covering_type(X::Spec) = covering_type(typeof(X)) +#covering_type(::Type{T}) where {T<:AffineScheme} = Covering{T, gluing_type(T)} +#covering_type(X::AffineScheme) = covering_type(typeof(X)) ######################################################################## # Basic getters # @@ -26,17 +26,17 @@ number_of_patches(C::Covering) = length(C.patches) Return a dictionary of gluings of the `affine_chart`s of `C`. -The keys are pairs `(U, V)` of `affine_chart`s. +The keys are pairs `(U, V)` of `affine_chart`s. One can also use `C[U, V]` to obtain the respective gluing. -**Note:** Gluings are lazy in the sense that they are in general -only computed when asked for. This method only returns the internal +**Note:** Gluings are lazy in the sense that they are in general +only computed when asked for. This method only returns the internal cache, but does not try to compute new gluings. """ gluings(C::Covering) = C.gluings getindex(C::Covering, i::Int) = C.patches[i] getindex(C::Covering, i::Int, j::Int) = gluings(C)[(patches(C)[i], patches(C)[j])] -getindex(C::Covering, X::AbsSpec, Y::AbsSpec) = gluings(C)[(X, Y)] +getindex(C::Covering, X::AbsAffineScheme, Y::AbsAffineScheme) = gluings(C)[(X, Y)] #edge_dict(C::Covering) = C.edge_dict function gluing_graph(C::Covering; all_dense::Bool=false) @@ -49,17 +49,17 @@ end @doc raw""" decomposition_info(C::Covering) -Return an `IdDict` `D` with the `patches` ``Uᵢ`` of `C` as keys and values a list -of elements ``fᵢ₁,…,fᵢᵣ ∈ 𝒪(Uᵢ)``. These elements are chosen so that for every -affine patch `Uᵢ` of ``X`` in the covering `C` the closed subvarieties ``Zᵢ ⊂ Uᵢ`` -defined by the ``fᵢⱼ`` give rise to a decomposition of ``X`` as a **disjoint** union -``X = \bigcup_{i} Z_i`` of locally closed subvarieties. - -This information can be used for local computations in any chart ``Uᵢ`` of ``X`` -as above to focus on phenomena occurring exclusively along ``Zᵢ`` and assuming -that other cases have been handled by computations in other charts. A key -application is counting points of zero-dimensional subschemes: To avoid overcounting, -we need to only consider points in ``Uᵢ`` which are located within ``Zᵢ`` and +Return an `IdDict` `D` with the `patches` ``Uᵢ`` of `C` as keys and values a list +of elements ``fᵢ₁,…,fᵢᵣ ∈ 𝒪(Uᵢ)``. These elements are chosen so that for every +affine patch `Uᵢ` of ``X`` in the covering `C` the closed subvarieties ``Zᵢ ⊂ Uᵢ`` +defined by the ``fᵢⱼ`` give rise to a decomposition of ``X`` as a **disjoint** union +``X = \bigcup_{i} Z_i`` of locally closed subvarieties. + +This information can be used for local computations in any chart ``Uᵢ`` of ``X`` +as above to focus on phenomena occurring exclusively along ``Zᵢ`` and assuming +that other cases have been handled by computations in other charts. A key +application is counting points of zero-dimensional subschemes: To avoid overcounting, +we need to only consider points in ``Uᵢ`` which are located within ``Zᵢ`` and then sum these up to all points in ``X``. !!! note This attribute might not be defined! Use `has_decomposition_info(C)` to check whether this information is available for the given covering. @@ -68,32 +68,32 @@ function decomposition_info(C::Covering) return C.decomp_info end -function set_decomposition_info!(C::Covering, U::AbsSpec, f::Vector{<:RingElem}) +function set_decomposition_info!(C::Covering, U::AbsAffineScheme, f::Vector{<:RingElem}) if !isdefined(C, :decomp_info) - C.decomp_info = IdDict{AbsSpec, Vector{RingElem}}() + C.decomp_info = IdDict{AbsAffineScheme, Vector{RingElem}}() end all(x->parent(x) === OO(U), f) || error("elements do not belong to the correct ring") decomposition_info(C)[U] = f end -function set_decomposition_info!(C::Covering, D::IdDict{<:AbsSpec, <:Vector{<:RingElem}}) +function set_decomposition_info!(C::Covering, D::IdDict{<:AbsAffineScheme, <:Vector{<:RingElem}}) C.decomp_info = D end -function has_decomposition_info(C::Covering) +function has_decomposition_info(C::Covering) isdefined(C, :decomp_info) || return false all(x->haskey(C.decomp_info, x), patches(C)) || return false return true end function inherit_decomposition_info!( - X::AbsCoveredScheme, ref_cov::Covering; + X::AbsCoveredScheme, ref_cov::Covering; orig_cov::Covering=default_covering(X) ) !has_decomposition_info(orig_cov) && return ref_cov OX = OO(X) - decomp_dict = IdDict{AbsSpec, Tuple{AbsSpec, Vector{RingElem}}}() + decomp_dict = IdDict{AbsAffineScheme, Tuple{AbsAffineScheme, Vector{RingElem}}}() for U in patches(ref_cov) inc_U, d_U = _find_chart(U, orig_cov) decomp_dict[U] = (codomain(inc_U), d_U) diff --git a/src/AlgebraicGeometry/Schemes/Covering/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/Covering/Objects/Constructors.jl index 76715cf91372..1325cf302d54 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Objects/Constructors.jl @@ -2,13 +2,13 @@ # Constructors for Covering # ######################################################################## ### The default constructor -# Returns a scheme in which every affine patch is only +# Returns a scheme in which every affine patch is only # glued to itself via the identity. @doc raw""" - Covering(patches::Vector{<:AbsSpec}) + Covering(patches::Vector{<:AbsAffineScheme}) -Return a `Covering` with pairwise disjoint affine charts ``Uᵢ`` given by -the entries of `patches`. This `Covering` will have no gluings except +Return a `Covering` with pairwise disjoint affine charts ``Uᵢ`` given by +the entries of `patches`. This `Covering` will have no gluings except those gluings along the identity of every affine chart to itself. # Examples @@ -17,9 +17,9 @@ julia> P1, (x,y) = QQ["x", "y"]; julia> P2, (u,v) = QQ["u", "v"]; -julia> U1 = Spec(P1); +julia> U1 = spec(P1); -julia> U2 = Spec(P2); +julia> U2 = spec(P2); julia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts Covering @@ -31,8 +31,8 @@ Covering 2: [u, v] ``` """ -function Covering(patches::Vector{<:AbsSpec}) - g = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() +function Covering(patches::Vector{<:AbsAffineScheme}) + g = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() for X in patches U = PrincipalOpenSubset(X) f = identity_map(U) @@ -42,7 +42,7 @@ function Covering(patches::Vector{<:AbsSpec}) end ### Turns an affine scheme into a trivial covering -Covering(X::AbsSpec) = Covering([X]) +Covering(X::AbsAffineScheme) = Covering([X]) ### The empty covering of the empty scheme over kk empty_covering(kk::Ring) = Covering(kk) @@ -50,7 +50,7 @@ empty_covering(kk::Ring) = Covering(kk) @doc raw""" disjoint_union(C1::Covering, C2::Covering) -Return the `Covering` corresponding to the disjoint union of `C1` and `C2`. +Return the `Covering` corresponding to the disjoint union of `C1` and `C2`. The charts and gluings of the disjoint union are given by the disjoint union of the charts and gluings of the covers `C1` and `C2`. @@ -60,9 +60,9 @@ julia> P1, (x,y) = QQ["x", "y"]; julia> P2, (u,v) = QQ["u", "v"]; -julia> U1 = Spec(P1); +julia> U1 = spec(P1); -julia> U2 = Spec(P2); +julia> U2 = spec(P2); julia> C1 = Covering(U1) # Set up the trivial covering with only one patch Covering diff --git a/src/AlgebraicGeometry/Schemes/Covering/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/Covering/Objects/Methods.jl index 9d31b0f943a8..3d529443bd03 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Objects/Methods.jl @@ -2,14 +2,14 @@ # Finding patches # ######################################################################## -function getindex(C::Covering, X::AbsSpec) +function getindex(C::Covering, X::AbsAffineScheme) for i in 1:length(patches(C)) X === patches(C)[i] && return i end error("affine scheme could not be found among the patches") end -function Base.in(U::AbsSpec, C::Covering) +function Base.in(U::AbsAffineScheme, C::Covering) for i in 1:n_patches(C) U === C[i] && return true end @@ -26,7 +26,7 @@ function Base.in(U::AbsSpec, C::Covering) # return false end -function Base.indexin(U::AbsSpec, C::Covering) +function Base.indexin(U::AbsAffineScheme, C::Covering) for i in 1:n_patches(C) U === C[i] && return (i, 0, 0) end @@ -49,7 +49,7 @@ end ######################################################################## # Functionality for lazy gluing # ######################################################################## -function neighbor_patches(C::Covering, U::AbsSpec) +function neighbor_patches(C::Covering, U::AbsAffineScheme) gg = gluing_graph(C) n = neighbors(gg, C[U]) return [C[i] for i in n] @@ -74,7 +74,7 @@ function update_gluing_graph(C::Covering; all_dense::Bool=false) end ## prune the covering by throwing away empty charts and then compute -## the gluing graph afterwards +## the gluing graph afterwards ## (relevant data for connectedness of gluing) function pruned_gluing_graph(C::Covering) v = findall(U->!is_empty(U), C.patches) @@ -124,10 +124,10 @@ function transition_graph(C::Covering) end ### fill transitions -# Whenever three schemes X ↩ U ↪ Y ↩ V ↪ Z are glued with -# U ∩ V dense in both U and V, one can infer a gluing of -# X and Z. This is done by crawling through the gluing graph, -# updating the gluings, and proceeding until nothing more +# Whenever three schemes X ↩ U ↪ Y ↩ V ↪ Z are glued with +# U ∩ V dense in both U and V, one can infer a gluing of +# X and Z. This is done by crawling through the gluing graph, +# updating the gluings, and proceeding until nothing more # can be done. function fill_transitions!(C::Covering) gg = gluing_graph(C) @@ -138,10 +138,10 @@ function fill_transitions!(C::Covering) W = neighbors(gg, v) for i in 1:length(W)-1 for j in i+1:length(W) - # TODO: replace the `is_dense` command by one that really checks that the - # intersection of U and V is dense in both U and V and not in their ambient - # variety. This implementation certainly works, but it is not as general - # as it could be, yet. + # TODO: replace the `is_dense` command by one that really checks that the + # intersection of U and V is dense in both U and V and not in their ambient + # variety. This implementation certainly works, but it is not as general + # as it could be, yet. if !has_edge(gg, W[i], W[j]) && is_dense(intersect(gluing_domains(C[W[i],v])[2], gluing_domains(C[v,W[j]])[1])) new_gluing = maximal_extension(compose(C[W[i], v], C[v, W[j]])) add_gluing!(C, new_gluing) @@ -172,7 +172,7 @@ function Base.length(C::Covering) end function all_patches(C::Covering) - result = Vector{AbsSpec}() + result = Vector{AbsAffineScheme}() for U in patches(C) push!(result, U) if haskey(affine_refinements(C), U) @@ -190,7 +190,7 @@ function Base.iterate(C::Covering, s::Int=1) return U[s], s+1 end -Base.eltype(C::Covering) = AbsSpec +Base.eltype(C::Covering) = AbsAffineScheme ######################################################################## # Building a Covering # @@ -198,7 +198,7 @@ Base.eltype(C::Covering) = AbsSpec @doc raw""" add_gluing!(C::Covering, G::AbsGluing) -Add a gluing `G` to the covering `C`. +Add a gluing `G` to the covering `C`. The `patches` of `G` must be among the `affine_charts` of `C`. @@ -208,9 +208,9 @@ julia> P1, (x,y) = QQ["x", "y"]; julia> P2, (u,v) = QQ["u", "v"]; -julia> U1 = Spec(P1); +julia> U1 = spec(P1); -julia> U2 = Spec(P2); +julia> U2 = spec(P2); julia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts Covering @@ -266,7 +266,7 @@ function Base.show(io::IO, ::MIME"text/plain", C::Covering) else l = ndigits(length(C)) println(io, "Covering") - print(io, Indent(), "described by patches") + print(io, Indent(), "described by patches") print(io, Indent()) for i in 1:length(C) li = ndigits(i) @@ -303,17 +303,17 @@ end @doc raw""" common_refinement(C::Covering, D::Covering) -For two `Covering`s `C` and `D`, calculate a common refinement -`E` and return a triple ``(E, φ, ψ)`` with ``φ : E → C`` -and ``ψ : E → D`` the `CoveringMorphism`s with the inclusion maps. +For two `Covering`s `C` and `D`, calculate a common refinement +`E` and return a triple ``(E, φ, ψ)`` with ``φ : E → C`` +and ``ψ : E → D`` the `CoveringMorphism`s with the inclusion maps. -!!! note Since the `Covering`s do not know about any `AbsCoveredScheme`, +!!! note Since the `Covering`s do not know about any `AbsCoveredScheme`, the computation of the refinement has to rely on the intrinsic tree -structure of their `patches`. Due to these limitations, only special +structure of their `patches`. Due to these limitations, only special cases are implemented; see the source code for details. """ function common_refinement(C::Covering, D::Covering) - if C === D + if C === D phi = identity_map(C) return C, phi, phi end @@ -329,8 +329,8 @@ function common_refinement(C::Covering, D::Covering) dirty_C = copy(patches(C)) dirty_D = copy(patches(D)) - map_dict_C = IdDict{AbsSpec, AbsSpecMor}() - map_dict_D = IdDict{AbsSpec, AbsSpecMor}() + map_dict_C = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() + map_dict_D = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in dirty_C if has_ancestor_in(patches(D), U) f, _ = _find_chart(U, D) @@ -349,7 +349,7 @@ function common_refinement(C::Covering, D::Covering) dirty_C = filter!(x->!(x in keys(map_dict_C)), dirty_C) dirty_D = filter!(x->!(x in keys(map_dict_D)), dirty_D) - #TODO: Check that all leftover dirty patches are already + #TODO: Check that all leftover dirty patches are already #covered by those in the keysets. What if this is not the case? E = Covering(collect(keys(map_dict_C))) @@ -359,7 +359,7 @@ function common_refinement(C::Covering, D::Covering) return E, phi, psi end -function has_ancestor_in(L::Vector, U::AbsSpec) +function has_ancestor_in(L::Vector, U::AbsAffineScheme) return has_ancestor(x->any(y->(y===x), L), U) end @@ -367,7 +367,7 @@ function is_refinement(D::Covering, C::Covering) if !all(x->has_ancestor(u->any(y->(u===y), patches(C)), x), patches(D)) return false, nothing end - map_dict = IdDict{AbsSpec, AbsSpecMor}() + map_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in patches(D) f, _ = _find_chart(U, C) map_dict[U] = f @@ -382,7 +382,7 @@ function base_change(phi::Any, C::Covering) U = patches(C) patch_change = [base_change(phi, V) for V in U] - gluing_dict = IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}() + gluing_dict = IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}() for i in 1:length(U) (A, map_A) = patch_change[i] for j in 1:length(U) @@ -394,13 +394,13 @@ function base_change(phi::Any, C::Covering) end CC = Covering([V for (V, _) in patch_change], gluing_dict) - mor_dict = IdDict{AbsSpec, AbsSpecMor}() + mor_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for (V, phi) in patch_change mor_dict[V] = phi end # Maintain decomposition information if applicable - decomp_dict = IdDict{AbsSpec, Vector{RingElem}}() + decomp_dict = IdDict{AbsAffineScheme, Vector{RingElem}}() if has_decomposition_info(C) for (U, psi) in patch_change V = codomain(psi) diff --git a/src/AlgebraicGeometry/Schemes/Covering/Objects/Types.jl b/src/AlgebraicGeometry/Schemes/Covering/Objects/Types.jl index 4a53d9f9df8a..1223ef8cdc7a 100644 --- a/src/AlgebraicGeometry/Schemes/Covering/Objects/Types.jl +++ b/src/AlgebraicGeometry/Schemes/Covering/Objects/Types.jl @@ -13,11 +13,11 @@ is made from their hashes. Thus, an affine scheme must not appear more than once in any covering! """ mutable struct Covering{BaseRingType} - patches::Vector{<:AbsSpec} # the basic affine patches of X - gluings::IdDict{Tuple{<:AbsSpec, <:AbsSpec}, <:AbsGluing} # the gluings of the basic affine patches - affine_refinements::IdDict{<:AbsSpec, <:Vector{<:Tuple{<:SpecOpen, Vector{<:RingElem}}}} # optional lists of refinements + patches::Vector{<:AbsAffineScheme} # the basic affine patches of X + gluings::IdDict{Tuple{<:AbsAffineScheme, <:AbsAffineScheme}, <:AbsGluing} # the gluings of the basic affine patches + affine_refinements::IdDict{<:AbsAffineScheme, <:Vector{<:Tuple{<:AffineSchemeOpenSubscheme, Vector{<:RingElem}}}} # optional lists of refinements # of the basic affine patches. - # These are stored as pairs (U, a) where U is a 'trivial' SpecOpen, + # These are stored as pairs (U, a) where U is a 'trivial' AffineSchemeOpenSubscheme, # meaning that its list of hypersurface equation (f₁,…,fᵣ) has empty # intersection in the basic affine patch X and hence satisfies # some equality 1 ≡ a₁⋅f₁ + a₂⋅f₂ + … + aᵣ⋅fᵣ on X. @@ -28,16 +28,16 @@ mutable struct Covering{BaseRingType} gluing_graph::Graph{Undirected} transition_graph::Graph{Undirected} edge_dict::Dict{Tuple{Int, Int}, Int} - decomp_info::IdDict{<:AbsSpec, <:Vector{<:RingElem}} + decomp_info::IdDict{<:AbsAffineScheme, <:Vector{<:RingElem}} function Covering( - patches::Vector{<:AbsSpec}, - gluings::IdDict{<:Tuple{<:AbsSpec, <:AbsSpec}, <:AbsGluing}; + patches::Vector{<:AbsAffineScheme}, + gluings::IdDict{<:Tuple{<:AbsAffineScheme, <:AbsAffineScheme}, <:AbsGluing}; check::Bool=true, affine_refinements::IdDict{ - <:AbsSpec, - <:Vector{<:Tuple{<:SpecOpen, <:Vector{<:RingElem}}} - }=IdDict{AbsSpec, Vector{Tuple{SpecOpen, Vector{RingElem}}}}() + <:AbsAffineScheme, + <:Vector{<:Tuple{<:AffineSchemeOpenSubscheme, <:Vector{<:RingElem}}} + }=IdDict{AbsAffineScheme, Vector{Tuple{AffineSchemeOpenSubscheme, Vector{RingElem}}}}() ) n = length(patches) n > 0 || error("can not glue the empty scheme") @@ -74,8 +74,8 @@ mutable struct Covering{BaseRingType} ### the empty covering function Covering(kk::Ring) - return new{typeof(kk)}(Vector{AbsSpec}(), IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}(), - IdDict{AbsSpec, Vector{Tuple{SpecOpen, Vector{RingElem}}}}()) + return new{typeof(kk)}(Vector{AbsAffineScheme}(), IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}(), + IdDict{AbsAffineScheme, Vector{Tuple{AffineSchemeOpenSubscheme, Vector{RingElem}}}}()) end end diff --git a/src/AlgebraicGeometry/Schemes/Gluing/Constructors.jl b/src/AlgebraicGeometry/Schemes/Gluing/Constructors.jl index d2b08d6b5680..f4129cf2d5d2 100644 --- a/src/AlgebraicGeometry/Schemes/Gluing/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/Gluing/Constructors.jl @@ -3,16 +3,16 @@ # Dummy constructor for documentation only # ######################################################################## @doc raw""" - Gluing(X::AbsSpec, Y::AbsSpec, f::SchemeMor, g::SchemeMor) + Gluing(X::AbsAffineScheme, Y::AbsAffineScheme, f::SchemeMor, g::SchemeMor) -Glue two affine schemes ``X`` and ``Y`` along mutual isomorphisms +Glue two affine schemes ``X`` and ``Y`` along mutual isomorphisms ``f`` and ``g`` of open subsets ``U`` of ``X`` and ``V`` of ``Y``. # Examples ```jldoctest julia> P1, (x,y) = QQ["x", "y"]; P2, (u,v) = QQ["u", "v"]; -julia> U1 = Spec(P1); U2 = Spec(P2); +julia> U1 = spec(P1); U2 = spec(P2); julia> V1 = PrincipalOpenSubset(U1, x); # Preparations for gluing @@ -36,13 +36,13 @@ given by the pullback function julia> G isa SimpleGluing # Since the gluing domains were `PrincipalOpenSubsets`, this defaults to a `SimpleGluing` true -julia> # Alternative using SpecOpens as gluing domains: +julia> # Alternative using AffineSchemeOpenSubschemes as gluing domains: -julia> W1 = SpecOpen(U1, [x]); W2 = SpecOpen(U2, [u]); +julia> W1 = AffineSchemeOpenSubscheme(U1, [x]); W2 = AffineSchemeOpenSubscheme(U2, [u]); -julia> h1 = SpecOpenMor(W1, W2, [1//x, y//x]); +julia> h1 = AffineSchemeOpenSubschemeMor(W1, W2, [1//x, y//x]); -julia> h2 = SpecOpenMor(W2, W1, [1//u, v//u]); +julia> h2 = AffineSchemeOpenSubschemeMor(W2, W1, [1//u, v//u]); julia> H = Gluing(U1, U2, h1, h2) Gluing @@ -63,7 +63,7 @@ julia> H isa Gluing true ``` """ -function Gluing(X::AbsSpec, Y::AbsSpec, f::SchemeMor, g::SchemeMor) +function Gluing(X::AbsAffineScheme, Y::AbsAffineScheme, f::SchemeMor, g::SchemeMor) error("constructor for `Gluing` not implemented for morphisms of type $(typeof(f)) and $(typeof(g))") end @@ -76,10 +76,10 @@ function Gluing(G::SimpleGluing) f, g = gluing_morphisms(G) incY = inclusion_morphism(V, Y) incX = inclusion_morphism(U, X) - Uo = SpecOpen(U) - Vo = SpecOpen(V) - fo = SpecOpenMor(Uo, Vo, [compose(f, incY)], check=false) - go = SpecOpenMor(Vo, Uo, [compose(g, incX)], check=false) + Uo = AffineSchemeOpenSubscheme(U) + Vo = AffineSchemeOpenSubscheme(V) + fo = AffineSchemeOpenSubschemeMor(Uo, Vo, [compose(f, incY)], check=false) + go = AffineSchemeOpenSubschemeMor(Vo, Uo, [compose(g, incX)], check=false) return Gluing(X, Y, fo, go, check=false) end @@ -93,9 +93,9 @@ end ######################################################################## function Gluing( - X::AbsSpec, Y::AbsSpec, - f::AbsSpecMor{<:PrincipalOpenSubset}, - g::AbsSpecMor{<:PrincipalOpenSubset}; + X::AbsAffineScheme, Y::AbsAffineScheme, + f::AbsAffineSchemeMor{<:PrincipalOpenSubset}, + g::AbsAffineSchemeMor{<:PrincipalOpenSubset}; check::Bool=true) return SimpleGluing(X, Y, f, g, check=check) end @@ -103,11 +103,11 @@ end ######################################################################## # Restrictions of Gluings to closed subschemes # ######################################################################## -function restrict(G::AbsGluing, X::AbsSpec, Y::AbsSpec; check::Bool=true) +function restrict(G::AbsGluing, X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true) return restrict(underlying_gluing(G), X, Y, check=check) end -function restrict(G::AbsGluing, X::AbsSpec, Y::AbsSpec, +function restrict(G::AbsGluing, X::AbsAffineScheme, Y::AbsAffineScheme, Ures::Scheme, Vres::Scheme; check::Bool=true ) @@ -115,7 +115,7 @@ function restrict(G::AbsGluing, X::AbsSpec, Y::AbsSpec, end -function restrict(G::Gluing, X::AbsSpec, Y::AbsSpec; check::Bool=true) +function restrict(G::Gluing, X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true) U, V = gluing_domains(G) f, g = gluing_morphisms(G) @check is_closed_embedding(intersect(X, ambient_scheme(U)), ambient_scheme(U)) "the scheme is not a closed in the ambient scheme of the open set" @@ -125,7 +125,7 @@ function restrict(G::Gluing, X::AbsSpec, Y::AbsSpec; check::Bool=true) return Gluing(X, Y, restrict(f, Ures, Vres, check=check), restrict(g, Vres, Ures, check=check), check=check) end -function restrict(G::SimpleGluing, X::AbsSpec, Y::AbsSpec; check::Bool=true) +function restrict(G::SimpleGluing, X::AbsAffineScheme, Y::AbsAffineScheme; check::Bool=true) U, V = gluing_domains(G) f, g = gluing_morphisms(G) @check is_closed_embedding(intersect(X, ambient_scheme(U)), ambient_scheme(U)) "the scheme is not a closed in the ambient scheme of the open set" @@ -137,8 +137,8 @@ function restrict(G::SimpleGluing, X::AbsSpec, Y::AbsSpec; check::Bool=true) return SimpleGluing(X, Y, f_res, g_res, check=check) end -function restrict(G::Gluing, X::AbsSpec, Y::AbsSpec, - Ures::SpecOpen, Vres::SpecOpen; +function restrict(G::Gluing, X::AbsAffineScheme, Y::AbsAffineScheme, + Ures::AffineSchemeOpenSubscheme, Vres::AffineSchemeOpenSubscheme; check::Bool=true ) U, V = gluing_domains(G) @@ -148,7 +148,7 @@ function restrict(G::Gluing, X::AbsSpec, Y::AbsSpec, return Gluing(X, Y, restrict(f, Ures, Vres, check=check), restrict(g, Vres, Ures, check=check), check=check) end -function restrict(G::SimpleGluing, X::AbsSpec, Y::AbsSpec, +function restrict(G::SimpleGluing, X::AbsAffineScheme, Y::AbsAffineScheme, UX::PrincipalOpenSubset, VY::PrincipalOpenSubset; check::Bool=true ) @@ -165,12 +165,12 @@ end # Identification of gluings under isomorphisms of patches # ######################################################################## @doc raw""" - restrict(G::AbsGluing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true) + restrict(G::AbsGluing, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; check::Bool=true) -Given a gluing ``X ↩ U ≅ V ↪ Y`` and isomorphisms ``f : X → X'`` and +Given a gluing ``X ↩ U ≅ V ↪ Y`` and isomorphisms ``f : X → X'`` and ``g: Y → Y'``, return the induced gluing of ``X'`` and ``Y'``. """ -function restrict(G::AbsGluing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true) +function restrict(G::AbsGluing, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor; check::Bool=true) (X1, Y1) = patches(G) X1 === domain(f) || error("maps not compatible") X2 = codomain(f) @@ -185,18 +185,18 @@ function restrict(G::AbsGluing, f::AbsSpecMor, g::AbsSpecMor; check::Bool=true) U2 = preimage(finv, domain(h1), check=check) V2 = preimage(ginv, domain(h2), check=check) - return Gluing(X2, Y2, - compose(restrict(finv, U2, domain(h1), check=check), + return Gluing(X2, Y2, + compose(restrict(finv, U2, domain(h1), check=check), compose(h1, restrict(g, domain(h2), V2, check=check)) ), - compose(restrict(ginv, V2, domain(h2), check=check), + compose(restrict(ginv, V2, domain(h2), check=check), compose(h2, restrict(f, domain(h1), U2, check=check)) ), check=check ) end -function restrict(G::AbsGluing, f::AbsSpecMor, g::AbsSpecMor, +function restrict(G::AbsGluing, f::AbsAffineSchemeMor, g::AbsAffineSchemeMor, f_res::SchemeMor, g_res::SchemeMor; check::Bool=true ) @@ -214,11 +214,11 @@ function restrict(G::AbsGluing, f::AbsSpecMor, g::AbsSpecMor, U2 = codomain(f_res) V2 = codomain(f_res) - return Gluing(X2, Y2, - compose(inverse(f_res), + return Gluing(X2, Y2, + compose(inverse(f_res), compose(h1, g_res) ), - compose(inverse(g_res), + compose(inverse(g_res), compose(h2, f_res) ), check=check diff --git a/src/AlgebraicGeometry/Schemes/Gluing/Methods.jl b/src/AlgebraicGeometry/Schemes/Gluing/Methods.jl index b76535ac9a3a..128414958512 100644 --- a/src/AlgebraicGeometry/Schemes/Gluing/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/Gluing/Methods.jl @@ -29,7 +29,7 @@ function Base.show(io::IO, ::MIME"text/plain", G::AbsGluing) k = max(k1, k2) println(io, co_str[1], " "^(k-k1+3), Lowercase(), domain(f)) print(io, co_str[2], " "^(k-k2+3), Lowercase(), codomain(f)) - if codomain(f) isa SpecOpen + if codomain(f) isa AffineSchemeOpenSubscheme mop = maps_on_patches(f) if length(mop) > 0 println(io) @@ -194,8 +194,8 @@ end struct BaseChangeGluingData{T1, T2} phi::T1 G::T2 - patch_change1::AbsSpecMor - patch_change2::AbsSpecMor + patch_change1::AbsAffineSchemeMor + patch_change2::AbsAffineSchemeMor end function _compute_gluing_base_change(gd::BaseChangeGluingData) @@ -216,8 +216,8 @@ function _compute_gluing_base_change(gd::BaseChangeGluingData) UU, map_U = base_change(phi, U, ambient_map=pc1) VV, map_V = base_change(phi, V, ambient_map=pc2) - # TODO: The following will not yet work for gluings along SpecOpens. - U isa PrincipalOpenSubset && V isa PrincipalOpenSubset || error("base change not implemented for gluings along SpecOpens") + # TODO: The following will not yet work for gluings along AffineSchemeOpenSubschemes. + U isa PrincipalOpenSubset && V isa PrincipalOpenSubset || error("base change not implemented for gluings along AffineSchemeOpenSubschemes") _, ff, _ = base_change(phi, f, domain_map=map_U, codomain_map=map_V) _, gg, _ = base_change(phi, g, domain_map=map_V, codomain_map=map_U) @@ -226,8 +226,8 @@ function _compute_gluing_base_change(gd::BaseChangeGluingData) end function base_change(phi::Any, G::AbsGluing; - patch_change1::AbsSpecMor=base_change(phi, gluing_domains(G)[1])[2], # The base change morphism for - patch_change2::AbsSpecMor=base_change(phi, gluing_domains(G)[2])[2] # the two gluing patches + patch_change1::AbsAffineSchemeMor=base_change(phi, gluing_domains(G)[1])[2], # The base change morphism for + patch_change2::AbsAffineSchemeMor=base_change(phi, gluing_domains(G)[2])[2] # the two gluing patches ) gd = BaseChangeGluingData{typeof(phi), typeof(G)}(phi, G, patch_change1, patch_change2) return LazyGluing(domain(patch_change1), domain(patch_change2), _compute_gluing_base_change, gd) diff --git a/src/AlgebraicGeometry/Schemes/Gluing/Types.jl b/src/AlgebraicGeometry/Schemes/Gluing/Types.jl index dcbf32628d2b..e058e17062cb 100644 --- a/src/AlgebraicGeometry/Schemes/Gluing/Types.jl +++ b/src/AlgebraicGeometry/Schemes/Gluing/Types.jl @@ -9,8 +9,8 @@ A gluing of two affine schemes ``X`` and ``Y`` (the `patches`) along open subsets ``U`` in ``X`` and ``V`` in ``Y`` (the `gluing_domains`) along mutual isomorphisms ``f : U ↔ V : g`` (the `gluing_morphisms`). """ -abstract type AbsGluing{LeftSpecType<:AbsSpec, - RightSpecType<:AbsSpec, +abstract type AbsGluing{LeftAffineSchemeType<:AbsAffineScheme, + RightAffineSchemeType<:AbsAffineScheme, LeftOpenType<:Scheme, RightOpenType<:Scheme, LeftMorType<:Map, @@ -24,32 +24,32 @@ abstract type AbsGluing{LeftSpecType<:AbsSpec, Gluing Concrete instance of an `AbsGluing` for gluings of affine schemes -``X ↩ U ≅ V ↪ Y`` along open subsets ``U`` and ``V`` of type `SpecOpen`. +``X ↩ U ≅ V ↪ Y`` along open subsets ``U`` and ``V`` of type `AffineSchemeOpenSubscheme`. """ @attributes mutable struct Gluing{ - LeftSpecType<:AbsSpec, - RightSpecType<:AbsSpec, - LeftOpenType<:SpecOpen, - RightOpenType<:SpecOpen, - LeftMorType<:SpecOpenMor, - RightMorType<:SpecOpenMor + LeftAffineSchemeType<:AbsAffineScheme, + RightAffineSchemeType<:AbsAffineScheme, + LeftOpenType<:AffineSchemeOpenSubscheme, + RightOpenType<:AffineSchemeOpenSubscheme, + LeftMorType<:AffineSchemeOpenSubschemeMor, + RightMorType<:AffineSchemeOpenSubschemeMor } <: AbsGluing{ - LeftSpecType, - RightSpecType, + LeftAffineSchemeType, + RightAffineSchemeType, LeftOpenType, RightOpenType, LeftMorType, RightMorType } - X::LeftSpecType - Y::RightSpecType + X::LeftAffineSchemeType + Y::RightAffineSchemeType U::LeftOpenType V::RightOpenType f::LeftMorType # f : U → V g::RightMorType function Gluing( - X::AbsSpec, Y::AbsSpec, f::SpecOpenMor, g::SpecOpenMor; check::Bool=true + X::AbsAffineScheme, Y::AbsAffineScheme, f::AffineSchemeOpenSubschemeMor, g::AffineSchemeOpenSubschemeMor; check::Bool=true ) ambient_scheme(domain(f)) === X || error("the domain of the gluing morphism is not an open subset of the first argument") ambient_scheme(codomain(f)) === Y || error("the codomain of the gluing morphism is not an open subset of the second argument") @@ -84,12 +84,12 @@ Concrete instance of an `AbsGluing` for gluings of affine schemes ``X ↩ U ≅ V ↪ Y`` along open subsets ``U`` and ``V`` of type `PrincipalOpenSubset`. """ -@attributes mutable struct SimpleGluing{LST<:AbsSpec, - RST<:AbsSpec, +@attributes mutable struct SimpleGluing{LST<:AbsAffineScheme, + RST<:AbsAffineScheme, LOT<:PrincipalOpenSubset, ROT<:PrincipalOpenSubset, - LMT<:AbsSpecMor, - RMT<:AbsSpecMor + LMT<:AbsAffineSchemeMor, + RMT<:AbsAffineSchemeMor } <: AbsGluing{LST, RST, LOT, ROT, LMT, RMT} X::LST Y::RST @@ -99,9 +99,9 @@ Concrete instance of an `AbsGluing` for gluings of affine schemes g::RMT function SimpleGluing( - X::AbsSpec, Y::AbsSpec, - f::AbsSpecMor{<:PrincipalOpenSubset}, - g::AbsSpecMor{<:PrincipalOpenSubset}; + X::AbsAffineScheme, Y::AbsAffineScheme, + f::AbsAffineSchemeMor{<:PrincipalOpenSubset}, + g::AbsAffineSchemeMor{<:PrincipalOpenSubset}; check::Bool=true ) U = domain(f) diff --git a/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Attributes.jl b/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Attributes.jl index 1261f2e64fe5..9f3488329496 100644 --- a/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Attributes.jl @@ -16,7 +16,7 @@ end function inverse_on_image(inc::PrincipalOpenEmbedding) if isdefined(inc, :inverse_on_image) - return inc.inverse_on_image::SpecMor + return inc.inverse_on_image::AffineSchemeMor end X = domain(inc) diff --git a/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Constructors.jl b/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Constructors.jl index 971114ab6ad0..b1d9dcd8e313 100644 --- a/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Constructors.jl @@ -1,4 +1,4 @@ -function complement(X::AbsSpec, h::Vector) +function complement(X::AbsAffineScheme, h::Vector) all(x -> x isa RingElem && parent(x) === OO(X), h) || return complement(X, OO(X).(h)) U = PrincipalOpenSubset(X, h) @@ -9,7 +9,7 @@ function complement(X::AbsSpec, h::Vector) return U, inc end -function complement(X::AbsSpec, h::Any) +function complement(X::AbsAffineScheme, h::Any) (h isa RingElem && parent(h) === OO(X)) || return complement(X, OO(X)(h)) return complement(X, [h]) end diff --git a/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Types.jl b/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Types.jl index f0562ccab0ec..f6567ea3e37f 100644 --- a/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Types.jl +++ b/src/AlgebraicGeometry/Schemes/PrincipalOpenInclusion/Types.jl @@ -3,20 +3,20 @@ # embedding into its ambient scheme. But this allows for an actual morphism of rings # in the background, so that the identification of the domain with a principal open # subset of its codomain can also be realized for schemes with different `ambient_coordinate_ring`s. -# This is important for the refinements, since we also allow `SimplifiedSpec`. +# This is important for the refinements, since we also allow `SimplifiedAffineScheme`. @doc raw""" - PrincipalOpenEmbedding{DomainType, CodomainType, PullbackType} <: AbsSpecMor + PrincipalOpenEmbedding{DomainType, CodomainType, PullbackType} <: AbsAffineSchemeMor An open inclusion ``ι : U ↪ X`` of one affine scheme ``U`` into another one ``X`` such that the image is a principal open subset. """ -@attributes mutable struct PrincipalOpenEmbedding{DomainType, CodomainType, PullbackType} <: AbsSpecMor{DomainType, CodomainType, PullbackType, OpenInclusion, Nothing} - inc::SpecMor{DomainType, CodomainType, PullbackType} +@attributes mutable struct PrincipalOpenEmbedding{DomainType, CodomainType, PullbackType} <: AbsAffineSchemeMor{DomainType, CodomainType, PullbackType, OpenInclusion, Nothing} + inc::AffineSchemeMor{DomainType, CodomainType, PullbackType} complement_equations::Vector{<:RingElem} image::PrincipalOpenSubset - inverse_on_image::AbsSpecMor + inverse_on_image::AbsAffineSchemeMor - function PrincipalOpenEmbedding(f::AbsSpecMor, complement_equations::Vector{T}; check::Bool=true) where {T<:RingElem} + function PrincipalOpenEmbedding(f::AbsAffineSchemeMor, complement_equations::Vector{T}; check::Bool=true) where {T<:RingElem} X = domain(f) Y = codomain(f) @assert all(x->parent(x) === OO(Y), complement_equations) diff --git a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Attributes.jl index 8780a927c39a..f0d2abc93d7a 100644 --- a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Attributes.jl @@ -6,16 +6,16 @@ underlying_scheme(U::PrincipalOpenSubset) = U.U @doc raw""" - ambient_scheme(U::PrincipalOpenSubset) -> Spec + ambient_scheme(U::PrincipalOpenSubset) -> AffineScheme -For ``U = D(f) ⊆ X`` a principal open subset of ``X`` this returns ``X``. +For ``U = D(f) ⊆ X`` a principal open subset of ``X`` this returns ``X``. This is not to be confused with the ambient affine space ``X ⊆ 𝔸 ⁿ``. """ ambient_scheme(U::PrincipalOpenSubset) = U.X complement_equation(U::PrincipalOpenSubset) = U.f::elem_type(OO(ambient_scheme(U))) -### assure compatibility with SpecOpen +### assure compatibility with AffineSchemeOpenSubscheme complement_equations(U::PrincipalOpenSubset) = [lifted_numerator(complement_equation(U))] number_of_complement_equations(U::PrincipalOpenSubset) = 1 number_of_generators(U::PrincipalOpenSubset) = 1 @@ -23,7 +23,7 @@ gens(U::PrincipalOpenSubset) = [U] gen(U::PrincipalOpenSubset, i::Int) = (i == 1 ? U : error("index out of range")) getindex(U::PrincipalOpenSubset, i::Int) = (i == 1 ? U : error("index out of range")) -function inclusion_morphism(U::PrincipalOpenSubset; check::Bool=false) +function inclusion_morphism(U::PrincipalOpenSubset; check::Bool=false) if !isdefined(U, :inc) X = ambient_scheme(U) inc = morphism(U, X, hom(OO(X), OO(U), gens(OO(U)), check=check), check=check) diff --git a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Constructors.jl index 0ade2be370b6..a5184743fd0f 100644 --- a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Constructors.jl @@ -2,5 +2,5 @@ # Constructors for PrincipalOpenSubsets # ######################################################################## -### Conversion of an arbitrary AbsSpec -PrincipalOpenSubset(X::AbsSpec) = PrincipalOpenSubset(X, one(OO(X))) +### Conversion of an arbitrary AbsAffineScheme +PrincipalOpenSubset(X::AbsAffineScheme) = PrincipalOpenSubset(X, one(OO(X))) diff --git a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Methods.jl index f481bfe99ada..1c0f9d82cbdc 100644 --- a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Methods.jl @@ -6,7 +6,7 @@ ######################################################################## # Preimages of PrincipalOpenSubsets # ######################################################################## -function preimage(f::AbsSpecMor, U::PrincipalOpenSubset; check::Bool=true) +function preimage(f::AbsAffineSchemeMor, U::PrincipalOpenSubset; check::Bool=true) if ambient_scheme(U) != codomain(f) Z = preimage(f, ambient_scheme(U), check=check) h = lifted_numerator(complement_equation(U)) @@ -20,7 +20,7 @@ function preimage(f::AbsSpecMor, U::PrincipalOpenSubset; check::Bool=true) return PrincipalOpenSubset(domain(f), prod(pbh; init=one(OO(domain(f))))) end -function preimage(f::AbsSpecMor{<:AbsSpec, <:PrincipalOpenSubset}, U::PrincipalOpenSubset; check::Bool=true) +function preimage(f::AbsAffineSchemeMor{<:AbsAffineScheme, <:PrincipalOpenSubset}, U::PrincipalOpenSubset; check::Bool=true) if ambient_scheme(U) === ambient_scheme(codomain(f)) h = lifted_numerator(complement_equation(U)) fac = factor(h) @@ -73,7 +73,7 @@ end ######################################################################## function base_change(phi::Any, U::PrincipalOpenSubset; - ambient_map::AbsSpecMor=base_change(phi, ambient_scheme(U))[2] # the base change on the ambient scheme + ambient_map::AbsAffineSchemeMor=base_change(phi, ambient_scheme(U))[2] # the base change on the ambient scheme ) Y = domain(ambient_map) pbf = pullback(ambient_map) diff --git a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Types.jl b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Types.jl index 64c1503bbd23..028c35614fb1 100644 --- a/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Types.jl +++ b/src/AlgebraicGeometry/Schemes/PrincipalOpenSubset/Objects/Types.jl @@ -1,20 +1,20 @@ ######################################################################## # Principal open subsets of affine schemes # ######################################################################## -@attributes mutable struct PrincipalOpenSubset{BRT, RT<:Ring, AmbientType} <: AbsSpec{BRT, RT} +@attributes mutable struct PrincipalOpenSubset{BRT, RT<:Ring, AmbientType} <: AbsAffineScheme{BRT, RT} X::AmbientType - U::Spec{BRT, RT} + U::AffineScheme{BRT, RT} f::RingElem - inc::AbsSpecMor # A PrincipalOpenInclusion, really; but this can not be + inc::AbsAffineSchemeMor # A PrincipalOpenInclusion, really; but this can not be # said here because of the inclusion order. - function PrincipalOpenSubset(X::AbsSpec, f::RingElem) + function PrincipalOpenSubset(X::AbsAffineScheme, f::RingElem) parent(f) == OO(X) || error("element does not belong to the correct ring") U = hypersurface_complement(X, [f]) return new{base_ring_type(X), ring_type(U), typeof(X)}(X, U, f) end - function PrincipalOpenSubset(X::AbsSpec, f::Vector{<:RingElem}) + function PrincipalOpenSubset(X::AbsAffineScheme, f::Vector{<:RingElem}) all(x->(parent(x) == OO(X)), f) || return PrincipalOpenSubset(X, OO(X).(f)) U = hypersurface_complement(X, f) return new{base_ring_type(X), ring_type(U), typeof(X)}(X, U, (length(f)>0 ? prod(f) : one(OO(X)))) @@ -22,14 +22,14 @@ # The following constructors allow to pass a ring as an extra argument. # It is assumed that the complement of f in X is isomorphic to Spec(R). - function PrincipalOpenSubset(X::AbsSpec, R::Ring, f::RingElem; + function PrincipalOpenSubset(X::AbsAffineScheme, R::Ring, f::RingElem; check::Bool=true ) - U = Spec(R) + U = spec(R) @check U == hypersurface_complement(X, f) "scheme is not isomorphic to the anticipated open subset" return new{base_ring_type(X), ring_type(U), typeof(X)}(X, U, f) end - function PrincipalOpenSubset(X::AbsSpec, R::Ring, f::Vector{T}; + function PrincipalOpenSubset(X::AbsAffineScheme, R::Ring, f::Vector{T}; check::Bool=true ) where {T<:RingElem} d = prod(length(f) > 0 ? f : one(OO(X))) diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveAlgebraicSet/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/ProjectiveAlgebraicSet/Objects/Constructors.jl index d28fb96638ae..4dc893b09d32 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveAlgebraicSet/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveAlgebraicSet/Objects/Constructors.jl @@ -12,7 +12,7 @@ If `is_reduced` is `true` assume that `X` is already reduced. ```jldoctest julia> P, (x0, x1, x2) = graded_polynomial_ring(QQ,[:x0,:x1,:x2]); -julia> X = projective_scheme(ideal([x0*x1^2, x2])) +julia> X = proj(ideal([x0*x1^2, x2])) Projective scheme over rational field defined by ideal (x0*x1^2, x2) @@ -46,7 +46,7 @@ defined by ideal (x1, x0) function algebraic_set(I::MPolyIdeal{<:MPolyDecRingElem}; is_radical::Bool=false, check::Bool=true) - X = ProjectiveScheme(base_ring(I), I) + X = proj(base_ring(I), I) return algebraic_set(X, is_reduced=is_radical, check=check) end diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Attributes.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Attributes.jl index 95367cb93014..e23ce611e07b 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Attributes.jl @@ -126,7 +126,7 @@ function map_on_affine_cones( imgs_fiber = [mP(g) for g in pullback(phi).(gens(S))] phi.map_on_affine_cones = morphism(CP, CQ, vcat(imgs_fiber, imgs_base), check=check) end - return phi.map_on_affine_cones::AbsSpecMor + return phi.map_on_affine_cones::AbsAffineSchemeMor end function map_on_affine_cones( @@ -141,10 +141,10 @@ function map_on_affine_cones( pb_res = hom(OO(C_cod), OO(C_dom), flat_dom.(pb_phi.(gens(homogeneous_coordinate_ring(codomain(phi))))), check=false) phi.map_on_affine_cones = morphism(C_dom, C_cod, pb_res) end - return phi.map_on_affine_cones::AbsSpecMor + return phi.map_on_affine_cones::AbsAffineSchemeMor end -function map_on_affine_cones(phi::ProjectiveSchemeMor{<:AbsProjectiveScheme{<:SpecOpenRing}, <:AbsProjectiveScheme{<:SpecOpenRing}}) +function map_on_affine_cones(phi::ProjectiveSchemeMor{<:AbsProjectiveScheme{<:AffineSchemeOpenSubschemeRing}, <:AbsProjectiveScheme{<:AffineSchemeOpenSubschemeRing}}) if !isdefined(phi, :map_on_affine_cones) X = domain(phi) CX, map_X = affine_cone(X) @@ -162,9 +162,9 @@ function map_on_affine_cones(phi::ProjectiveSchemeMor{<:AbsProjectiveScheme{<:Sp list = [restriction_map(CX, CX[i]).(coord_imgs) for i in 1:ngens(CX)] list = [morphism(CX[i], Q, restriction_map(CX, CX[i]).(coord_imgs)) for i in 1:ngens(CX)] - phi.map_on_affine_cones = SpecOpenMor(CX, CY, list, check=false) + phi.map_on_affine_cones = AffineSchemeOpenSubschemeMor(CX, CY, list, check=false) end - return phi.map_on_affine_cones::SpecOpenMor + return phi.map_on_affine_cones::AffineSchemeOpenSubschemeMor end diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Constructors.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Constructors.jl index 793bbeaf835c..71b3f7cc45b5 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Constructors.jl @@ -69,7 +69,7 @@ function fiber_product(f::Map{DomType, CodType}, P::AbsProjectiveScheme{DomType} end function fiber_product( - f::AbsSpecMor, + f::AbsAffineSchemeMor, P::AbsProjectiveScheme{<:Union{<:MPolyRing, <:MPolyQuoRing, <:MPolyLocRing, <:MPolyQuoLocRing}} ) codomain(f) == base_scheme(P) || error("codomain and base_scheme are incompatible") @@ -96,7 +96,7 @@ function fiber_product( ) end -fiber_product(X::AbsSpec, +fiber_product(X::AbsAffineScheme, P::AbsProjectiveScheme{<:Union{<:MPolyRing, <:MPolyQuoRing, <:MPolyLocRing, <:MPolyQuoLocRing}} ) = fiber_product(inclusion_morphism(X, base_scheme(P)), P) diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Methods.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Methods.jl index cc6b157c843d..e22f58df0728 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Methods.jl @@ -28,7 +28,7 @@ julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); julia> I = ideal([x^3-y^2*z]); -julia> Y = projective_scheme(P, I); +julia> Y = proj(P, I); julia> f = identity_map(Y) Projective scheme morphism @@ -61,7 +61,7 @@ with default covering X = covered_scheme(PX) Y = covered_scheme(PY) - mor_dict = IdDict{AbsSpec, AbsSpecMor}() + mor_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() U = affine_charts(X) for i in 1:ngens(SX) U_i = U[i] @@ -82,7 +82,7 @@ with default covering end # We skip the gluings for the time being. # Eventually, they should be made lazy. - CC = Covering(collect(keys(mor_dict)), IdDict{Tuple{AbsSpec, AbsSpec}, AbsGluing}()) + CC = Covering(collect(keys(mor_dict)), IdDict{Tuple{AbsAffineScheme, AbsAffineScheme}, AbsGluing}()) inherit_gluings!(CC, default_covering(X)) phi = CoveringMorphism(CC, default_covering(Y), mor_dict, check=false) push!(coverings(X), CC) @@ -101,7 +101,7 @@ end X = covered_scheme(PX) Y = covered_scheme(PY) - mor_dict = IdDict{AbsSpec, ClosedEmbedding}() + mor_dict = IdDict{AbsAffineScheme, ClosedEmbedding}() U = affine_charts(X) # TODO: The code below does not run when we have empty affine charts. Adjust accordingly when cleaning up! II = IdealSheaf(PY, image_ideal(f)) diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Types.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Types.jl index 9dec25c8f7d4..4518ec4094c6 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Types.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Morphisms/Types.jl @@ -1,5 +1,5 @@ ######################################################################## -# Abstract type for morphisms of projective schemes for which the +# Abstract type for morphisms of projective schemes for which the # generic interface is defined. ######################################################################## abstract type AbsProjectiveSchemeMorphism{ @@ -75,7 +75,7 @@ space over the same ring with the identity on the base. end return new{DomainType, CodomainType, PullbackType, Nothing}(P, Q, f) end - + ### Morphisms with an underlying base change function ProjectiveSchemeMor( P::DomainType, @@ -125,7 +125,7 @@ end DomainType<:AbsProjectiveScheme, CodomainType<:AbsProjectiveScheme, PullbackType<:Map, - BaseMorType, + BaseMorType, IdealType<:Ideal } <: AbsProjectiveSchemeMorphism{DomainType, CodomainType, ProjectiveClosedEmbedding, @@ -142,7 +142,7 @@ end S = homogeneous_coordinate_ring(P) @req base_ring(I) === S "ideal must be defined in the homogeneous coordinate ring of the scheme" T, pr = quo(S, I) - Q = ProjectiveScheme(T) + Q = proj(T) f = ProjectiveSchemeMor(Q, P, pr, check=false) return new{typeof(Q), DomainType, typeof(pr), Nothing, IdealType}(f, I) end @@ -153,7 +153,7 @@ end check::Bool=true ) Y = codomain(f) - SY = homogeneous_coordinate_ring(Y) + SY = homogeneous_coordinate_ring(Y) ambient_coordinate_ring(Y) === ambient_coordinate_ring(domain(f)) || error("ambient coordinate rings are not compatible") base_ring(I) === SY || error("ideal does not belong to the correct ring") @check begin diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Attributes.jl index 95149ca46017..06cef05839c1 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Attributes.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Attributes.jl @@ -32,7 +32,7 @@ julia> S, _ = grade(QQ["x", "y", "z"][1]); julia> I = ideal(S, S[1] + S[2]); -julia> X = ProjectiveScheme(S, I) +julia> X = proj(S, I) Projective scheme over rational field defined by ideal (x + y) @@ -62,7 +62,7 @@ julia> I = ideal(S, S[1] + S[2]) Ideal generated by x + y -julia> X = ProjectiveScheme(S, I) +julia> X = proj(S, I) Projective scheme over rational field defined by ideal (x + y) @@ -100,7 +100,7 @@ julia> I = ideal(S, S[1] + S[2]) Ideal generated by x + y -julia> X = ProjectiveScheme(S, I) +julia> X = proj(S, I) Projective scheme over rational field defined by ideal (x + y) @@ -141,7 +141,7 @@ julia> S, _ = grade(QQ["x", "y", "z"][1]); julia> I = ideal(S, S[1] + S[2]); -julia> X = ProjectiveScheme(S, I) +julia> X = proj(S, I) Projective scheme over rational field defined by ideal (x + y) @@ -153,7 +153,7 @@ with homogeneous coordinates [x, y, z] ``` """ @attr function ambient_space(X::AbsProjectiveScheme) - return projective_scheme(ambient_coordinate_ring(X)) + return proj(ambient_coordinate_ring(X)) end @@ -239,7 +239,7 @@ julia> Q, _ = quo(R, ideal(R, u^2 + v^2)); julia> S, _ = grade(Q["x", "y", "z"][1]); -julia> P = projective_scheme(S) +julia> P = proj(S) Projective space of dimension 2 over quotient of multivariate polynomial ring by ideal (u^2 + v^2) with homogeneous coordinates [x, y, z] @@ -275,7 +275,7 @@ julia> Q, _ = quo(R, ideal(R, u^2 + v^2)); julia> S, _ = grade(Q["x", "y", "z"][1]); -julia> P = projective_scheme(S) +julia> P = proj(S) Projective space of dimension 2 over quotient of multivariate polynomial ring by ideal (u^2 + v^2) with homogeneous coordinates [x, y, z] @@ -292,7 +292,7 @@ affine_cone(P::AbsProjectiveScheme) S = homogeneous_coordinate_ring(P) phi = RingFlattening(S) A = codomain(phi) - C = Spec(A) + C = spec(A) B = base_scheme(P) P.projection_to_base = morphism(C, B, hom(OO(B), OO(C), gens(OO(C))[ngens(S)+1:end], check=false), check=false) return C, phi @@ -308,7 +308,7 @@ end II = forget_grading(I) SS, _ = quo(PP, II) phi = hom(S, SS, gens(SS), check=false) - C = Spec(SS) + C = spec(SS) return C, phi end @@ -318,14 +318,14 @@ end S = homogeneous_coordinate_ring(P) PP = forget_grading(S) # the ungraded polynomial ring phi = hom(S, PP, gens(PP), check=false) - C = Spec(PP) + C = spec(PP) return C, phi end @attr function affine_cone( X::AbsProjectiveScheme{CRT, RT} ) where { - CRT<:SpecOpenRing, + CRT<:AffineSchemeOpenSubschemeRing, RT<:MPolyRing } S = ambient_coordinate_ring(X) @@ -352,7 +352,7 @@ end @attr function affine_cone( X::AbsProjectiveScheme{CRT, RT} ) where { - CRT<:SpecOpenRing, + CRT<:AffineSchemeOpenSubschemeRing, RT<:MPolyQuoRing } P = ambient_coordinate_ring(X) @@ -398,7 +398,7 @@ julia> Q, _ = quo(R, ideal(R, u^2 + v^2)); julia> S, _ = grade(Q["x", "y", "z"][1]); -julia> P = projective_scheme(S) +julia> P = proj(S) Projective space of dimension 2 over quotient of multivariate polynomial ring by ideal (u^2 + v^2) with homogeneous coordinates [x, y, z] @@ -437,25 +437,25 @@ base_ring(P::ProjectiveScheme) = P.A function base_scheme(X::ProjectiveScheme{CRT, RT}) where {CRT<:Ring, RT} if !isdefined(X, :Y) - X.Y = Spec(base_ring(X)) + X.Y = spec(base_ring(X)) end return X.Y end -function base_scheme(X::ProjectiveScheme{<:SpecOpenRing}) +function base_scheme(X::ProjectiveScheme{<:AffineSchemeOpenSubschemeRing}) return domain(base_ring(X)) end function set_base_scheme!( P::ProjectiveScheme{CRT, RT}, - X::Union{<:AbsSpec, <:SpecOpen} + X::Union{<:AbsAffineScheme, <:AffineSchemeOpenSubscheme} ) where {CRT<:Ring, RT} OO(X) === base_ring(P) || error("schemes are not compatible") P.Y = X return P end -function projection_to_base(X::ProjectiveScheme{CRT, RT}) where {CRT<:Union{<:MPolyRing, <:MPolyQuoRing, <:MPolyLocRing, <:MPolyQuoLocRing, <:SpecOpenRing}, RT} +function projection_to_base(X::ProjectiveScheme{CRT, RT}) where {CRT<:Union{<:MPolyRing, <:MPolyQuoRing, <:MPolyLocRing, <:MPolyQuoLocRing, <:AffineSchemeOpenSubschemeRing}, RT} if !isdefined(X, :projection_to_base) affine_cone(X) end @@ -464,14 +464,14 @@ end function _dehomogenization_cache(X::ProjectiveScheme) if !isdefined(X, :dehomogenization_cache) - X.dehomogenization_cache = IdDict{AbsSpec, Map}() + X.dehomogenization_cache = IdDict{AbsAffineScheme, Map}() end return X.dehomogenization_cache end function _homogenization_cache(X::ProjectiveScheme) if !isdefined(X, :homogenization_cache) - X.homogenization_cache = IdDict{AbsSpec, Function}() + X.homogenization_cache = IdDict{AbsAffineScheme, Function}() end return X.homogenization_cache end @@ -496,8 +496,8 @@ ring_type(::Type{ProjectiveScheme{S, T}}) where {S, T} = T ### type constructors # the type of a relative projective scheme over a given base scheme -projective_scheme_type(X::AbsSpec) = projective_scheme_type(typeof(X)) -projective_scheme_type(::Type{T}) where {T<:AbsSpec} = projective_scheme_type(ring_type(T)) +projective_scheme_type(X::AbsAffineScheme) = projective_scheme_type(typeof(X)) +projective_scheme_type(::Type{T}) where {T<:AbsAffineScheme} = projective_scheme_type(ring_type(T)) ######################################################################## @@ -545,19 +545,19 @@ function relative_cotangent_module(X::AbsProjectiveScheme{<:Ring, <:MPolyQuoRing # We follow the common procedure. For X ↪ ℙ ⁿ we have # # θ - # 0 → Ω¹ → ⊕ ⁿ⁺¹ 𝒪 (-1) → 𝒪 + # 0 → Ω¹ → ⊕ ⁿ⁺¹ 𝒪 (-1) → 𝒪 # - # the Euler sequence. Restricting to X we get + # the Euler sequence. Restricting to X we get # θ # 0 → Ω¹|_X → ⊕ ⁿ⁺¹ 𝒪 (-1)_X → 𝒪_X # - # Then for the defining ideal I of X in ℙⁿ we obtain + # Then for the defining ideal I of X in ℙⁿ we obtain # an exact sequence # # I/I² → Ω¹|_X → Ω¹_X → 0. # - # Note that for the associated graded modules we can - # not simply restrict the module for Ω¹|_X, but we have to + # Note that for the associated graded modules we can + # not simply restrict the module for Ω¹|_X, but we have to # recompute the kernel of the restricted θ. inc_X = ambient_embedding(X) phi = pullback(inc_X) @@ -570,7 +570,7 @@ function relative_cotangent_module(X::AbsProjectiveScheme{<:Ring, <:MPolyQuoRing theta = map(eu, 1) theta_res = _change_base_ring_and_preserve_gradings(phi, theta, domain_change = res_Omega1, codomain_change = res_Omega0) - + W1X, inc_W1X = kernel(theta_res) f = gens(defining_ideal(X)) df = exterior_derivative.(f) diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Constructors.jl index 1e300b340e8f..4ce4534c1b29 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Constructors.jl @@ -3,13 +3,18 @@ ################################################################################ projective_scheme(S::MPolyDecRing) = ProjectiveScheme(S) +proj(S::MPolyDecRing) = ProjectiveScheme(S) +projective_scheme(Q::MPolyQuoRing{<:MPolyDecRingElem}) = ProjectiveScheme(Q) +proj(Q::MPolyQuoRing{<:MPolyDecRingElem}) = ProjectiveScheme(Q) + + +proj(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem} = ProjectiveScheme(S, I) projective_scheme(S::MPolyDecRing, I::MPolyIdeal{T}) where {T<:MPolyDecRingElem} = ProjectiveScheme(S, I) +proj(I::MPolyIdeal{<:MPolyDecRingElem}) = ProjectiveScheme(base_ring(I), I) projective_scheme(I::MPolyIdeal{<:MPolyDecRingElem}) = ProjectiveScheme(base_ring(I), I) -projective_scheme(Q::MPolyQuoRing{MPolyDecRingElem{T, PT}}) where {T, PT<:MPolyRingElem{T}} = ProjectiveScheme(Q) - ################################################################################ # Subschemes ################################################################################ @@ -18,8 +23,8 @@ function subscheme(P::AbsProjectiveScheme, f::RingElem) S = homogeneous_coordinate_ring(P) parent(f) === S || return subscheme(P, S(f)) Q, _ = quo(S, ideal(S, [f])) - result = projective_scheme(Q) - if isdefined(P, :Y) + result = proj(Q) + if isdefined(P, :Y) set_base_scheme!(result, base_scheme(P)) end set_attribute!(result, :ambient_space, ambient_space(P)) @@ -27,7 +32,7 @@ function subscheme(P::AbsProjectiveScheme, f::RingElem) end function subscheme( - P::AbsProjectiveScheme, + P::AbsProjectiveScheme, f::Vector{T} ) where {T<:RingElem} length(f) == 0 && return P #TODO: Replace P by an honest copy! @@ -36,8 +41,8 @@ function subscheme( parent(f[i]) === S || return subscheme(P, S.(f)) end Q, _ = quo(S, ideal(S, f)) - result = projective_scheme(Q) - if isdefined(P, :Y) + result = proj(Q) + if isdefined(P, :Y) set_base_scheme!(result, base_scheme(P)) end set_attribute!(result, :ambient_space, ambient_space(P)) @@ -50,8 +55,8 @@ function subscheme(P::AbsProjectiveScheme, S = homogeneous_coordinate_ring(P) base_ring(I) === S || error("ideal does not belong to the correct ring") Q, _ = quo(S, I) - result = projective_scheme(Q) - if isdefined(P, :Y) + result = proj(Q) + if isdefined(P, :Y) set_base_scheme!(result, base_scheme(P)) end set_attribute!(result, :ambient_space, ambient_space(P)) @@ -65,7 +70,7 @@ end @doc raw""" projective_space(A::Ring, var_symb::Vector{VarName}) -Create the (relative) projective space `Proj(A[x₀,…,xₙ])` over `A` +Create the (relative) projective space `Proj(A[x₀,…,xₙ])` over `A` where `x₀,…,xₙ` is a list of variable names. # Examples @@ -85,34 +90,34 @@ Multivariate polynomial ring in 3 variables over QQ graded by function projective_space(A::Ring, var_symb::Vector{<:VarName}) n = length(var_symb) S, _ = graded_polynomial_ring(A, Symbol.(var_symb)) - return projective_scheme(S) + return proj(S) end @doc raw""" projective_space(A::Ring, r::Int; var_name::VarName=:s) -Create the (relative) projective space `Proj(A[s₀,…,sᵣ])` over `A` -where `s` is a string for the variable names. +Create the (relative) projective space `Proj(A[s₀,…,sᵣ])` over `A` +where `s` is a string for the variable names. """ function projective_space(A::Ring, r::Int; var_name::VarName=:s) S, _ = graded_polynomial_ring(A, [Symbol(var_name, i) for i in 0:r]) - return projective_scheme(S) + return proj(S) end function projective_space( - W::Union{<:SpecOpen, <:AbsSpec}, - r::Int; + W::Union{<:AffineSchemeOpenSubscheme, <:AbsAffineScheme}, + r::Int; var_name::VarName=:s - ) + ) P = projective_space(OO(W), r, var_name=var_name) set_base_scheme!(P, W) return P end function projective_space( - W::Union{<:SpecOpen, <:AbsSpec}, + W::Union{<:AffineSchemeOpenSubscheme, <:AbsAffineScheme}, var_names::Vector{<:VarName} - ) + ) P = projective_space(OO(W), var_names) set_base_scheme!(P, W) return P diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Methods.jl index d51b4a884c07..8eb7aa3d22fe 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Methods.jl @@ -73,7 +73,7 @@ end @doc raw""" - dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec) + dehomogenization_map(X::AbsProjectiveScheme, U::AbsAffineScheme) Return the restriction morphism from the graded coordinate ring of ``X`` to `𝒪(U)`. @@ -100,7 +100,7 @@ julia> phi(S[2]) ``` """ -function dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec) +function dehomogenization_map(X::AbsProjectiveScheme, U::AbsAffineScheme) cache = _dehomogenization_cache(X) if haskey(cache, U) return cache[U] @@ -113,7 +113,7 @@ function dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec) return compose(dehomogenization_map(X, V), OO(Y)(V, U)) end -function _dehomogenization_map(X::AbsProjectiveScheme, U::AbsSpec, i::Int) +function _dehomogenization_map(X::AbsProjectiveScheme, U::AbsAffineScheme, i::Int) S = homogeneous_coordinate_ring(X) s = vcat(gens(OO(U))[1:i-1], [one(OO(U))], gens(OO(U))[i:relative_ambient_dimension(X)]) phi = hom(S, OO(U), s, check=false) @@ -122,7 +122,7 @@ end function _dehomogenization_map( X::AbsProjectiveScheme{CRT}, - U::AbsSpec, + U::AbsAffineScheme, i::Int ) where { CRT<:Union{MPolyQuoLocRing, MPolyLocRing, MPolyRing, MPolyQuoRing} @@ -139,7 +139,7 @@ end #= function dehomogenization_map( X::AbsProjectiveScheme{CRT}, - U::AbsSpec + U::AbsAffineScheme ) where { CRT<:Union{MPolyQuoLocRing, MPolyLocRing, MPolyRing, MPolyQuoRing} } @@ -172,7 +172,7 @@ end @doc raw""" - homogenization_map(P::AbsProjectiveScheme, U::AbsSpec) + homogenization_map(P::AbsProjectiveScheme, U::AbsAffineScheme) Given an affine chart ``U ⊂ P`` of an `AbsProjectiveScheme` ``P``, return a method ``h`` for the homogenization of elements @@ -229,7 +229,7 @@ julia> phi.(gens(R)) (v, 1) ``` """ -function homogenization_map(P::AbsProjectiveScheme, U::AbsSpec) +function homogenization_map(P::AbsProjectiveScheme, U::AbsAffineScheme) # Projective schemes over a Field or ZZ or similar cache = _homogenization_cache(P) if haskey(cache, U) @@ -238,7 +238,7 @@ function homogenization_map(P::AbsProjectiveScheme, U::AbsSpec) error("patch not found or homogenization map not set") end -function _homogenization_map(P::AbsProjectiveScheme, U::AbsSpec, i::Int) +function _homogenization_map(P::AbsProjectiveScheme, U::AbsAffineScheme, i::Int) # Determine those variables which come from the homogeneous # coordinates S = homogeneous_coordinate_ring(P) @@ -273,7 +273,7 @@ function _homogenization_map(P::AbsProjectiveScheme, U::AbsSpec, i::Int) return my_dehom end -function _homogenization_map(P::AbsProjectiveScheme{<:MPolyAnyRing, <:MPolyDecRing}, U::AbsSpec, i::Int) +function _homogenization_map(P::AbsProjectiveScheme{<:MPolyAnyRing, <:MPolyDecRing}, U::AbsAffineScheme, i::Int) # Determine those variables which come from the homogeneous # coordinates S = homogeneous_coordinate_ring(P) @@ -318,7 +318,7 @@ function _homogenization_map(P::AbsProjectiveScheme{<:MPolyAnyRing, <:MPolyDecRi return my_dehom end -function _homogenization_map(P::AbsProjectiveScheme{<:MPolyAnyRing, <:MPolyQuoRing}, U::AbsSpec, i::Int) +function _homogenization_map(P::AbsProjectiveScheme{<:MPolyAnyRing, <:MPolyQuoRing}, U::AbsAffineScheme, i::Int) # Determine those variables which come from the homogeneous # coordinates S = homogeneous_coordinate_ring(P) @@ -363,7 +363,7 @@ function _homogenization_map(P::AbsProjectiveScheme{<:MPolyAnyRing, <:MPolyQuoRi return my_dehom end -function getindex(X::AbsProjectiveScheme, U::AbsSpec) +function getindex(X::AbsProjectiveScheme, U::AbsAffineScheme) Xcov = covered_scheme(X) for C in coverings(Xcov) for j in 1:n_patches(C) diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Properties.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Properties.jl index e1137d51751d..1191f878c3e1 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Properties.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Properties.jl @@ -47,7 +47,7 @@ julia> A, (x, y, z) = grade(QQ["x", "y", "z"][1]); julia> B, _ = quo(A, ideal(A, [x^2 + y^2])); -julia> C = projective_scheme(B) +julia> C = proj(B) Projective scheme over rational field defined by ideal (x^2 + y^2) diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Types.jl b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Types.jl index 2b1f9a0a55ba..15b4f0239371 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Types.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveSchemes/Objects/Types.jl @@ -16,7 +16,7 @@ julia> S, _ = QQ["x", "y", "z"]; julia> Sgr, _ = grade(S); -julia> P = ProjectiveScheme(Sgr) +julia> P = proj(Sgr) Projective space of dimension 2 over rational field with homogeneous coordinates [x, y, z] @@ -27,7 +27,7 @@ julia> I = ideal(Sgr, x^3 + y^3 + z^3); # a hyperplane section julia> Q, _ = quo(Sgr, I); -julia> C = ProjectiveScheme(Q) +julia> C = proj(Q) Projective scheme over rational field defined by ideal (x^3 + y^3 + z^3) diff --git a/src/AlgebraicGeometry/Schemes/ProjectiveVariety/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/ProjectiveVariety/Objects/Constructors.jl index d9942df6ebb0..8c157b76d8d1 100644 --- a/src/AlgebraicGeometry/Schemes/ProjectiveVariety/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/ProjectiveVariety/Objects/Constructors.jl @@ -62,9 +62,9 @@ We require that ``R`` is a finitely generated algebra over a field ``k`` and moreover that the base change of ``R`` to the algebraic closure ``\bar k`` is an integral domain. """ -variety(R::Ring; check::Bool=true) = ProjectiveVariety(ProjectiveScheme(R), check=check) +variety(R::Ring; check::Bool=true) = ProjectiveVariety(proj(R), check=check) -variety(R::MPolyDecRing; check::Bool=true) = ProjectiveVariety(ProjectiveScheme(R), check=check) +variety(R::MPolyDecRing; check::Bool=true) = ProjectiveVariety(proj(R), check=check) @doc raw""" @@ -95,7 +95,7 @@ end function projective_space(A::Field, var_symb::Vector{VarName}) n = length(var_symb) S, _ = graded_polynomial_ring(A, var_symb) - return variety(projective_scheme(S), check=false) + return variety(proj(S), check=false) end @@ -105,5 +105,5 @@ function projective_space( var_name::VarName=:s ) where {CoeffRingType<:Field} S, _ = graded_polynomial_ring(A, [Symbol(var_name,i) for i in 0:r]) - return variety(projective_scheme(S), check=false) + return variety(proj(S), check=false) end diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Attributes.jl b/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Attributes.jl deleted file mode 100644 index 3227c1f9ed2b..000000000000 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Objects/Attributes.jl +++ /dev/null @@ -1,155 +0,0 @@ - -######################################################################## -# (1) Type getters for SpecOpen # -######################################################################## -open_subset_type(::Type{SpecType}) where {BRT, RT, SpecType<:AbsSpec{BRT, RT}} = SpecOpen{SpecType, BRT} -open_subset_type(X::Spec) = open_subset_type(typeof(X)) - -ambient_type(U::SpecOpen{SpecType, BRT}) where {SpecType<:Spec, BRT} = SpecType -ambient_type(::Type{SpecOpen{SpecType, BRT}}) where {SpecType<:Spec, BRT} = SpecType - -poly_type(::Type{SpecOpenType}) where {SpecOpenType<:SpecOpen} = poly_type(ambient_type(SpecOpenType)) -poly_type(U::SpecOpen) = poly_type(typeof(U)) - -######################################################################## -# (2) Getter methods for the internally stored data # -######################################################################## -@doc raw""" - affine_patches(U::SpecOpen) - -Return a list of principal affine open subschemes covering ``U``. -TODO: Add example! -""" -function affine_patches(U::SpecOpen) - if !isdefined(U, :patches) - X = ambient_scheme(U) - U.patches = [PrincipalOpenSubset(X, OO(X)(f)) for f in complement_equations(U)] - end - return U.patches -end - -@doc raw""" - intersections(U::SpecOpen) - -Return a list of pairwise intersections of the -principal open subschemes covering ``U``. -TODO: Add example! -""" -function intersections(U::SpecOpen) - if !isdefined(U, :intersections) - X = ambient_scheme(U) - V = affine_patches(U) - for i in 1:length(V) - for j in 1:i-1 - U.intersections[(i,j)] = U.intersections[(j,i)] = intersect(V[i], V[j]) - end - end - end - return U.intersections -end - -@doc raw""" - ambient_scheme(U::SpecOpen) - -Return the ambient scheme ``X`` of a Zariski open subset ``U ⊂ X``. -TODO: Add example! -""" -ambient_scheme(U::SpecOpen) = U.X - -@doc raw""" - ambient_coordinate_ring(U::SpecOpen) - -For the open set `U = X \ V ` return the ambient coordinate ring of `X`. -TODO: Add example! -""" -ambient_coordinate_ring(U::SpecOpen) = ambient_coordinate_ring(ambient_scheme(U)) - -@doc raw""" - ambient_space(U::SpecOpen) -> Spec - -For ``U ⊆ X \subseteq 𝔸 ⁿ`` return the affine space``𝔸 ⁿ``. -""" -ambient_space(U::SpecOpen) = ambient_space(ambient_scheme(U)) - -@doc raw""" - ambient_coordinates(U::SpecOpen) - -Return the coordinates of the ambient affine space of ``U``. -""" -ambient_coordinates(U::SpecOpen) = coordinates(ambient_space(U)) - -@doc raw""" - number_of_patches(U::SpecOpen) - -Return the number of generators stored for describing the complement of ``U``. -""" -number_of_patches(U::SpecOpen) = length(U.gens) - -@doc raw""" - complement_equations(U::SpecOpen) - -Return the generators ``[f₁,…,fᵣ]`` stored for the description -of the complement of ``U``. -""" -complement_equations(U::SpecOpen) = U.gens::Vector{elem_type(ambient_coordinate_ring(ambient_scheme(U)))} -number_of_complement_equations(U::SpecOpen) = length(U.gens) - -@doc raw""" - affine_patch(U::SpecOpen, i::Int) - -Return the hypersurface complement of ``fᵢ`` in the -ambient scheme ``X`` of ``U`` where ``f₁,…,fᵣ`` are -the generators stored for the description of the complement -of ``U``. This function can also be called using the -`getindex` method or simply via `U[i]`. -""" -affine_patch(U::SpecOpen, i::Int) = affine_patches(U)[i] -gens(U::SpecOpen) = affine_patches(U) -gen(U::SpecOpen, i::Int) = affine_patches(U)[i] -getindex(U::SpecOpen, i::Int) = affine_patches(U)[i] -number_of_generators(U::SpecOpen) = number_of_patches(U) - -function getindex(U::SpecOpen, X::AbsSpec) - for i in 1:n_patches(U) - X === U[i] && return i - end - error("scheme $X not found among the open patches in $U") -end - -function getindex(U::SpecOpen, i::Int, j::Int) - if !haskey(intersections(U), (i, j)) - intersections(U)[(i, j)] = hypersurface_complement(U[i], complement_equations(U)[j]) - intersections(U)[(j, i)] = intersections(U)[(i, j)] - end - return intersections(U)[(i,j)] -end - -#TODO: Add docstring. -function complement_ideal(U::SpecOpen) - if !isdefined(U, :complement_ideal) - I = ideal(OO(ambient_scheme(U)), complement_equations(U)) - U.complement_ideal = I - end - return U.complement_ideal::Ideal -end - -# TODO: Add docstring. -function complement(U::SpecOpen) - if !isdefined(U, :complement) - #I = radical(saturated_ideal(ideal(localized_ring(OO(ambient_scheme(U))), complement_equations(U)))) - #U.complement = subscheme(ambient_scheme(U), I) - U.complement = subscheme(ambient_scheme(U), complement_equations(U)) - end - return U.complement -end -function set_name!(U::SpecOpen, name::String) - U.name = name -end - -function name(U::SpecOpen) - if isdefined(U, :name) - return U.name - end - return "open subset of $(ambient_scheme(U))" -end - diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Attributes.jl b/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Attributes.jl deleted file mode 100644 index 0d7dc2cb88cc..000000000000 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Attributes.jl +++ /dev/null @@ -1,61 +0,0 @@ - -######################################################################## -# Attributes of SpecOpenRing # -######################################################################## - -######################################################################## -# Type getters # -######################################################################## -SpecOpenRing(U::SpecOpen) = SpecOpenRing(ambient_scheme(U), U) - -spec_open_ring_type(::Type{T}) where {T<:Spec} = SpecOpenRing{T, open_subset_type(T)} -spec_open_ring_type(X::AbsSpec) = spec_open_ring_type(typeof(X)) - -ring_type(::Type{SpecOpenType}) where {SpecOpenType<:SpecOpen} = SpecOpenRing{affine_patch_type(SpecOpenType), SpecOpenType} -ring_type(U::SpecOpen) = ring_type(typeof(U)) - -######################################################################## -# Basic attributes # -######################################################################## -@doc raw""" - scheme(R::SpecOpenRing) - -The ring ``R = 𝒪(X, U)`` belongs to a sheaf of rings ``𝒪(X, -)`` and this returns -the scheme ``X`` on which ``𝒪`` is defined. -""" -scheme(R::SpecOpenRing) = R.scheme - -gens(R::SpecOpenRing) = R.(gens(ambient_coordinate_ring(scheme(R)))) -number_of_generators(R::SpecOpenRing) = number_of_generators(ambient_coordinate_ring(scheme(R))) -gen(R::SpecOpenRing, i::Int) = R(gen(ambient_coordinate_ring(scheme(R)), i)) - - -@doc raw""" - domain(R::SpecOpenRing) - -For a ring ``R = 𝒪(X, U)``, return ``U``. -""" -domain(R::SpecOpenRing) = R.domain - -######################################################################## -# Attributes of SpecOpenRingElem # -######################################################################## - -######################################################################## -# Type getters # -######################################################################## -elem_type(::Type{SpecOpenRing{S, T}}) where {S, T} = SpecOpenRingElem{SpecOpenRing{S, T}} -parent_type(::Type{SpecOpenRingElem{S}}) where {S} = S - -######################################################################## -# Basic getters # -######################################################################## -parent(f::SpecOpenRingElem) = f.parent -scheme(f::SpecOpenRingElem) = scheme(parent(f)) -domain(f::SpecOpenRingElem) = domain(parent(f)) -restrictions(f::SpecOpenRingElem) = f.restrictions -affine_patches(f::SpecOpenRingElem) = affine_patches(domain(f)) -number_of_patches(f::SpecOpenRingElem) = length(restrictions(f)) -getindex(f::SpecOpenRingElem, i::Int) = getindex(restrictions(f), i) -getindex(f::SpecOpenRingElem, U::AbsSpec) = restrictions(f)[domain(f)[U]] - diff --git a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Properties.jl b/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Properties.jl deleted file mode 100644 index 7175e208b24d..000000000000 --- a/src/AlgebraicGeometry/Schemes/SpecOpen/Rings/Properties.jl +++ /dev/null @@ -1,16 +0,0 @@ -######################################################################## -# Properties of SpecOpenRingElem # -######################################################################## - -######################################################################## -# Required functionality for the ring interface # -######################################################################## -is_domain_type(::Type{T}) where {T<:SpecOpenRingElem} = true -is_domain_type(a::SpecOpenRingElem) = is_domain_type(typeof(a)) -is_exact_type(::Type{T}) where {T<:SpecOpenRingElem} = true -is_exact_type(a::SpecOpenRingElem) = is_exact_type(typeof(a)) -is_domain_type(::Type{T}) where {T<:SpecOpenRing} = true -is_domain_type(R::SpecOpenRing) = is_domain_type(typeof(R)) -is_exact_type(::Type{T}) where {T<:SpecOpenRing} = true -is_exact_type(R::SpecOpenRing) = is_exact_type(typeof(R)) - diff --git a/src/AlgebraicGeometry/Schemes/Types.jl b/src/AlgebraicGeometry/Schemes/Types.jl index 04dfe7afbc28..26f23a489e65 100644 --- a/src/AlgebraicGeometry/Schemes/Types.jl +++ b/src/AlgebraicGeometry/Schemes/Types.jl @@ -2,7 +2,7 @@ ### Abstract type for arbitrary schemes ############################### #@doc raw""" -# Scheme{BaseRingType<:Ring} +# Scheme{BaseRingType<:Ring} # #A scheme over a ring ``𝕜`` of type `BaseRingType`. #""" @@ -10,24 +10,24 @@ # # Moved to src/forward_declarations.jl -@attr Spec{S,S} function base_scheme(X::Scheme{S}) where {S<:Ring} - return Spec(base_ring(X)) +@attr AffineScheme{S,S} function base_scheme(X::Scheme{S}) where {S<:Ring} + return spec(base_ring(X)) end ### Abstract type for morphisms of arbitrary schemes ################## @doc raw""" SchemeMor{DomainType, CodomainType, MorphismType, BaseMorType} -A morphism of schemes ``f : X → Y`` of type `MorphismType` with -``X`` of type `DomainType` and ``Y`` of type `CodomainType`. +A morphism of schemes ``f : X → Y`` of type `MorphismType` with +``X`` of type `DomainType` and ``Y`` of type `CodomainType`. -When ``X`` and ``Y`` are defined over schemes ``BX`` and ``BY`` other -than ``Spec(𝕜)``, `BaseMorType` is the type of the underlying +When ``X`` and ``Y`` are defined over schemes ``BX`` and ``BY`` other +than ``Spec(𝕜)``, `BaseMorType` is the type of the underlying morphism ``BX → BY``; otherwise, it can be set to `Nothing`. """ abstract type SchemeMor{ - DomainType, - CodomainType, + DomainType, + CodomainType, MorphismType, BaseMorType } <: Map{ @@ -40,7 +40,7 @@ end ### The empty scheme over a base ring ################################# -struct EmptyScheme{BaseRingType}<:Scheme{BaseRingType} +struct EmptyScheme{BaseRingType}<:Scheme{BaseRingType} k::BaseRingType function EmptyScheme(k::BaseRingType) where {BaseRingType<:Ring} return new{BaseRingType}(k) diff --git a/src/AlgebraicGeometry/Schemes/main.jl b/src/AlgebraicGeometry/Schemes/main.jl index 7a9c018eac21..643ffc34cf10 100644 --- a/src/AlgebraicGeometry/Schemes/main.jl +++ b/src/AlgebraicGeometry/Schemes/main.jl @@ -14,10 +14,10 @@ include("AffineSchemes/Objects/Types.jl") include("AffineSchemes/Morphisms/Types.jl") include("PrincipalOpenSubset/Objects/Types.jl") include("PrincipalOpenInclusion/Types.jl") -include("SpecOpen/Objects/Types.jl") -include("SpecOpen/Rings/Types.jl") -include("SpecOpen/Morphisms/Types.jl") -include("ClosedEmbedding/Types.jl") # Needs SpecOpen for their complements +include("AffineSchemeOpenSubscheme/Objects/Types.jl") +include("AffineSchemeOpenSubscheme/Rings/Types.jl") +include("AffineSchemeOpenSubscheme/Morphisms/Types.jl") +include("ClosedEmbedding/Types.jl") # Needs AffineSchemeOpenSubscheme for their complements include("Gluing/Types.jl") include("Covering/Objects/Types.jl") include("Covering/Morphisms/Types.jl") @@ -71,19 +71,19 @@ include("PrincipalOpenInclusion/Attributes.jl") ######################################################################## # Open subsets of affine schemes # ######################################################################## -include("SpecOpen/Objects/Constructors.jl") -include("SpecOpen/Objects/Properties.jl") -include("SpecOpen/Objects/Attributes.jl") -include("SpecOpen/Objects/Methods.jl") +include("AffineSchemeOpenSubscheme/Objects/Constructors.jl") +include("AffineSchemeOpenSubscheme/Objects/Properties.jl") +include("AffineSchemeOpenSubscheme/Objects/Attributes.jl") +include("AffineSchemeOpenSubscheme/Objects/Methods.jl") -include("SpecOpen/Rings/Constructors.jl") -include("SpecOpen/Rings/Properties.jl") -include("SpecOpen/Rings/Attributes.jl") -include("SpecOpen/Rings/Methods.jl") +include("AffineSchemeOpenSubscheme/Rings/Constructors.jl") +include("AffineSchemeOpenSubscheme/Rings/Properties.jl") +include("AffineSchemeOpenSubscheme/Rings/Attributes.jl") +include("AffineSchemeOpenSubscheme/Rings/Methods.jl") -include("SpecOpen/Morphisms/Constructors.jl") -include("SpecOpen/Morphisms/Attributes.jl") -include("SpecOpen/Morphisms/Methods.jl") +include("AffineSchemeOpenSubscheme/Morphisms/Constructors.jl") +include("AffineSchemeOpenSubscheme/Morphisms/Attributes.jl") +include("AffineSchemeOpenSubscheme/Morphisms/Methods.jl") ######################################################################## # ClosedEmbeddings of affine schemes # diff --git a/src/AlgebraicGeometry/Surfaces/SurfacesP4.jl b/src/AlgebraicGeometry/Surfaces/SurfacesP4.jl index 59b269779f78..0a7d98221c02 100644 --- a/src/AlgebraicGeometry/Surfaces/SurfacesP4.jl +++ b/src/AlgebraicGeometry/Surfaces/SurfacesP4.jl @@ -52,7 +52,7 @@ function surface(n::String) I = load(n) S = base_ring(I) R = grade(S)[1] - return ProjectiveScheme(R, ideal(R, map(R, gens(I)))) + return proj(R, ideal(R, map(R, gens(I)))) end ############################### @@ -88,7 +88,7 @@ The returned surface is defined over a prime field of characteristic 31991. abelian_d15_pi21_quintic_1() = surface("abelian_d15_pi21_quintic_1") F = GF(31991) R, (x,y,z,u,v) = graded_polynomial_ring(F, ["x", "y", "z", "u", "v"]) - return ProjectiveScheme(R, ideal([F(5)/8*x^3*y^3+2992*x^4*y*z-F(121)/98*x*y^2*z^3-F(96)/29*x^2*z^4+F(121)/89*x*y^3*z*u-4353*x^2*y*z^2*u+F(1)/2*z^5*u-F(8)/99*x^2*y^2*u^2-1983*x^3*z*u^2-117*y*z^3*u^2+F(6)/35*y^2*z*u^3-F(2)/5*x*z^2*u^3-1983*x*y*u^4+2992*x*y^4*v+F(96)/79*x^2*y^2*z*v+F(1)/2*x^3*z^2*v-F(5)/8*y*z^4*v+F(121)/89*x^3*y*u*v+F(19)/62*y^2*z^2*u*v-6369*x*z^3*u*v-1983*y^3*u^2*v-F(17)/42*x*y*z*u^2*v+F(6)/35*x^2*u^3*v-F(23)/11*z*u^4*v+F(1)/2*y^3*z*v^2+F(79)/60*x*y*z^2*v^2-4353*x*y^2*u*v^2+F(19)/62*x^2*z*u*v^2+14197*z^2*u^2*v^2-F(2)/5*y*u^3*v^2-F(121)/98*x^2*y*v^3+F(120)/29*z^3*v^3-6369*y*z*u*v^3-117*x*u^2*v^3-F(96)/29*y^2*v^4-F(5)/8*x*z*v^4+F(1)/2*u*v^5,F(1)/2*y^5*z-117*x*y^3*z^2+F(6)/35*x^2*y*z^3-F(5)/8*x*y^4*u+F(19)/62*x^2*y^2*z*u-1983*x^3*z^2*u-F(23)/11*y*z^4*u+F(1)/2*x^3*y*u^2+14197*y^2*z^2*u^2-F(2)/5*x*z^3*u^2+F(120)/29*y^3*u^3-6369*x*y*z*u^3-F(96)/29*x^2*u^4+F(1)/2*z*u^5-F(121)/98*x^2*y^3*v+F(121)/89*x^3*y*z*v-F(2)/5*y^2*z^3*v-1983*x*z^4*v+2992*x^4*u*v-6369*y^3*z*u*v-F(17)/42*x*y*z^2*u*v+F(79)/60*x*y^2*u^2*v-4353*x^2*z*u^2*v-117*z^2*u^3*v-F(5)/8*y*u^4*v-F(96)/29*y^4*v^2-4353*x*y^2*z*v^2-F(8)/99*x^2*z^2*v^2+F(96)/79*x^2*y*u*v^2+F(6)/35*z^3*u*v^2+F(19)/62*y*z*u^2*v^2-F(121)/98*x*u^3*v^2+F(5)/8*x^3*v^3-1983*y*z^2*v^3+F(1)/2*y^2*u*v^3+F(121)/89*x*z*u*v^3+2992*x*y*v^4,-x^2*y^3*z+1611*x^3*y*z^2+F(65)/99*y^2*z^4-F(21)/121*x*z^5+F(5)/4*x^3*y^2*u-F(19)/31*x^4*z*u-F(21)/121*y^3*z^2*u-10148*x*y*z^3*u-F(46)/11*x*y^2*z*u^2+3471*x^2*z^2*u^2-F(16)/99*x^2*y*u^3+F(97)/93*z^3*u^3+F(12)/35*y*z*u^4-F(21)/121*x*u^5-x^4*y*v-F(52)/99*y^4*z*v+F(122)/99*x*y^2*z^2*v-F(16)/99*x^2*z^3*v+F(13)/59*x*y^3*u*v+F(124)/101*x^2*y*z*u*v+F(12)/35*z^4*u*v+1611*x^3*u^2*v+9919*y*z^2*u^2*v+F(3)/7*y^2*u^3*v-10148*x*z*u^3*v+234*x^2*y^2*v^2+F(5)/4*x^3*z*v^2+F(3)/7*y*z^3*v^2+F(11)/4*y^2*z*u*v^2-F(46)/11*x*z^2*u*v^2+F(122)/99*x*y*u^2*v^2+F(65)/99*u^4*v^2-F(12)/35*y^3*v^3+F(13)/59*x*y*z*v^3-x^2*u*v^3-F(21)/121*z*u^2*v^3-F(52)/99*y*u*v^4,y^4*z^2-234*x*y^2*z^3+F(12)/35*x^2*z^4-F(90)/121*x*y^3*z*u+57*x^2*y*z^2*u-F(46)/11*z^5*u-F(99)/52*x^2*y^2*u^2-650*x^3*z*u^2-F(109)/4*y*z^3*u^2-2683*y^2*z*u^3-4373*x*z^2*u^3+F(16)/65*x*y*u^4+1611*u^6-F(72)/49*x^2*y^2*z*v+10613*x^3*z^2*v+6526*y*z^4*v-F(90)/121*x^3*y*u*v-3237*y^2*z^2*u*v-7261*x*z^3*u*v-650*y^3*u^2*v-F(4)/103*x*y*z*u^2*v-2683*x^2*u^3*v+F(11)/126*z*u^4*v+x^4*v^2+10613*y^3*z*v^2+3249*x*y*z^2*v^2+57*x*y^2*u*v^2-3237*x^2*z*u*v^2-F(70)/57*z^2*u^2*v^2-4373*y*u^3*v^2-234*x^2*y*v^3+9744*z^3*v^3-7261*y*z*u*v^3-F(109)/4*x*u^2*v^3+F(12)/35*y^2*v^4+6526*x*z*v^4-F(46)/11*u*v^5,-F(4)/5*y^6-F(113)/79*x*y^4*z-11797*x^2*y^2*z^2+F(96)/29*x^3*z^3+13879*x^2*y^3*u-15044*x^3*y*z*u-12643*y^2*z^3*u-F(1)/2*x*z^4*u+F(21)/121*x^4*u^2-F(121)/23*y^3*z*u^2+F(17)/38*x*y*z^2*u^2+3639*x*y^2*u^3+5300*x^2*z*u^3-F(5)/8*z^2*u^4+F(93)/109*y*u^5-12643*x^3*y^2*v-F(1)/2*x^4*z*v+13879*y^3*z^2*v-15044*x*y*z^3*v-F(69)/31*y^4*u*v-9826*x*y^2*z*u*v-F(22)/29*x^2*z^2*u*v-F(100)/23*x^2*y*u^2*v+9933*z^3*u^2*v-F(7)/80*y*z*u^3*v+3908*x*u^4*v-F(121)/23*x*y^3*v^2+F(17)/38*x^2*y*z*v^2+F(21)/121*z^4*v^2+9933*x^3*u*v^2-F(100)/23*y*z^2*u*v^2+F(49)/53*y^2*u^2*v^2+2111*x*z*u^2*v^2+3639*y^2*z*v^3+5300*x*z^2*v^3-F(7)/80*x*y*u*v^3-12076*u^3*v^3-F(5)/8*x^2*v^4+3908*z*u*v^4+F(93)/109*y*v^5,-F(5)/8*x^2*y^4+9933*x^3*y^2*z+F(21)/121*x^4*z^2-12076*y^3*z^3+3908*x*y*z^4-F(1)/2*x^4*y*u+3908*y^4*z*u+2111*x*y^2*z^2*u+5300*x^2*z^3*u+5300*x*y^3*u^2-F(22)/29*x^2*y*z*u^2-F(5)/8*z^4*u^2+F(96)/29*x^3*u^3+9933*y*z^2*u^3+F(21)/121*y^2*u^4-F(1)/2*x*z*u^4+F(93)/109*y^5*v-F(7)/80*x*y^3*z*v-F(100)/23*x^2*y*z^2*v+F(93)/109*z^5*v+F(17)/38*x^2*y^2*u*v-15044*x^3*z*u*v-F(7)/80*y*z^3*u*v-F(100)/23*y^2*z*u^2*v+F(17)/38*x*z^2*u^2*v-15044*x*y*u^3*v-12643*x^3*y*v^2+F(49)/53*y^2*z^2*v^2+3639*x*z^3*v^2+3639*y^3*u*v^2-9826*x*y*z*u*v^2-11797*x^2*u^2*v^2-12643*z*u^3*v^2-F(121)/23*x*y^2*v^3+13879*x^2*z*v^3-F(121)/23*z^2*u*v^3+13879*y*u^2*v^3-F(69)/31*y*z*v^4-F(113)/79*x*u*v^4-F(4)/5*v^6,F(33)/122*x^3*y^2*z+4022*x^4*z^2+F(52)/99*y^3*z^3-F(122)/117*x*y*z^4-F(52)/99*x^4*y*u-F(122)/117*y^4*z*u+F(83)/26*x*y^2*z^2*u+F(89)/58*x^2*z^3*u+F(89)/58*x*y^3*u^2+F(99)/70*x^2*y*z*u^2-F(12)/35*x^3*u^3+F(33)/122*y*z^2*u^3+4022*y^2*u^4-F(52)/99*x*z*u^4-F(89)/58*y^5*v-F(100)/71*x*y^3*z*v+F(78)/101*x^2*y*z^2*v-F(89)/58*z^5*v+F(63)/94*x^2*y^2*u*v-F(17)/31*x^3*z*u*v-F(100)/71*y*z^3*u*v+F(78)/101*y^2*z*u^2*v+F(63)/94*x*z^2*u^2*v-F(17)/31*x*y*u^3*v-2602*x^3*y*v^2+11793*y^2*z^2*v^2+8051*x*z^3*v^2+8051*y^3*u*v^2+12945*x*y*z*u*v^2+F(108)/109*x^2*u^2*v^2-2602*z*u^3*v^2-2520*x*y^2*v^3-F(95)/52*x^2*z*v^3-2520*z^2*u*v^3-F(95)/52*y*u^2*v^3+8051*y*z*v^4-F(65)/83*x*u*v^4-F(89)/58*v^6,-F(89)/58*y^6-F(65)/83*x*y^4*z+F(108)/109*x^2*y^2*z^2-F(12)/35*x^3*z^3-F(95)/52*x^2*y^3*u-F(17)/31*x^3*y*z*u-2602*y^2*z^3*u-F(52)/99*x*z^4*u+4022*x^4*u^2-2520*y^3*z*u^2+F(63)/94*x*y*z^2*u^2+8051*x*y^2*u^3+F(89)/58*x^2*z*u^3-F(89)/58*y*u^5-2602*x^3*y^2*v-F(52)/99*x^4*z*v-F(95)/52*y^3*z^2*v-F(17)/31*x*y*z^3*v+8051*y^4*u*v+12945*x*y^2*z*u*v+F(99)/70*x^2*z^2*u*v+F(78)/101*x^2*y*u^2*v+F(33)/122*z^3*u^2*v-F(100)/71*y*z*u^3*v-F(122)/117*x*u^4*v-2520*x*y^3*v^2+F(63)/94*x^2*y*z*v^2+4022*z^4*v^2+F(33)/122*x^3*u*v^2+F(78)/101*y*z^2*u*v^2+11793*y^2*u^2*v^2+F(83)/26*x*z*u^2*v^2+8051*y^2*z*v^3+F(89)/58*x*z^2*v^3-F(100)/71*x*y*u*v^3+F(52)/99*u^3*v^3-F(122)/117*z*u*v^4-F(89)/58*y*v^5,x^4*y^2+1611*y^5*z-F(77)/60*x*y^3*z^2+F(76)/69*x^2*y*z^3+1611*z^6-F(4)/5*x*y^4*u-15475*x^2*y^2*z*u+F(86)/19*x^3*z^2*u-F(77)/60*y*z^4*u-11038*x^3*y*u^2+F(58)/25*y^2*z^2*u^2+F(112)/43*x*z^3*u^2-F(21)/121*y^3*u^3-11234*x*y*z*u^3+1611*z*u^5-1611*x^2*y^3*v+F(55)/73*x^3*y*z*v+F(112)/43*y^2*z^3*v-11235*x*z^4*v+F(21)/121*x^4*u*v-11234*y^3*z*u*v-F(43)/2*x*y*z^2*u*v-12177*x*y^2*u^2*v+F(18)/107*x^2*z*u^2*v-F(77)/60*z^2*u^3*v-F(4)/5*y*u^4*v+F(18)/107*x*y^2*z*v^2+10973*x^2*z^2*v^2+2311*x^2*y*u*v^2+F(76)/69*z^3*u*v^2-15475*y*z*u^2*v^2-1611*x*u^3*v^2-F(65)/99*x^3*v^3+F(86)/19*y*z^2*v^3-11038*y^2*u*v^3+F(55)/73*x*z*u*v^3+F(21)/121*x*y*v^4+u^2*v^4,-x*y^5+234*x^2*y^3*z-F(12)/35*x^3*y*z^2+F(4)/5*x^3*y^2*u+F(21)/121*x^4*z*u+F(121)/49*y^3*z^2*u+F(25)/123*x*y*z^3*u+11038*y^4*u^2+8706*x*y^2*z*u^2+F(16)/99*x^2*z^2*u^2+F(21)/121*x^2*y*u^3-F(5)/4*z^3*u^3-5984*y*z*u^4+F(46)/11*x^4*y*v+F(5)/4*y^4*z*v-F(19)/31*x*y^2*z^2*v+F(21)/121*x^2*z^3*v+F(91)/108*x*y^3*u*v+F(17)/21*x^2*y*z*u*v-5984*z^4*u*v-F(12)/35*x^3*u^2*v+12551*y*z^2*u^2*v-y^2*u^3*v+F(25)/123*x*z*u^3*v+3597*x^2*y^2*v^2+F(4)/5*x^3*z*v^2-y*z^3*v^2-F(79)/30*y^2*z*u*v^2+8706*x*z^2*u*v^2-F(19)/31*x*y*u^2*v^2+2198*y^3*v^3+F(91)/108*x*y*z*v^3+234*x^2*u*v^3+F(121)/49*z*u^2*v^3+11038*z^2*v^4+F(5)/4*y*u*v^4-x*v^5,-x^5-y^5+7884*x*y^3*z-F(99)/23*x^2*y*z^2-z^5-3570*x^2*y^2*u+F(3)/100*x^3*z*u+7884*y*z^3*u-F(99)/23*y^2*z*u^2-3570*x*z^2*u^2+F(3)/100*x*y*u^3-u^5+7884*x^3*y*v-3570*y^2*z^2*v+F(3)/100*x*z^3*v+F(3)/100*y^3*u*v+F(125)/81*x*y*z*u*v-F(99)/23*x^2*u^2*v+7884*z*u^3*v-F(99)/23*x*y^2*v^2-3570*x^2*z*v^2-F(99)/23*z^2*u*v^2-3570*y*u^2*v^2+F(3)/100*y*z*v^3+7884*x*u*v^3-v^5])) + return proj(R, ideal([F(5)/8*x^3*y^3+2992*x^4*y*z-F(121)/98*x*y^2*z^3-F(96)/29*x^2*z^4+F(121)/89*x*y^3*z*u-4353*x^2*y*z^2*u+F(1)/2*z^5*u-F(8)/99*x^2*y^2*u^2-1983*x^3*z*u^2-117*y*z^3*u^2+F(6)/35*y^2*z*u^3-F(2)/5*x*z^2*u^3-1983*x*y*u^4+2992*x*y^4*v+F(96)/79*x^2*y^2*z*v+F(1)/2*x^3*z^2*v-F(5)/8*y*z^4*v+F(121)/89*x^3*y*u*v+F(19)/62*y^2*z^2*u*v-6369*x*z^3*u*v-1983*y^3*u^2*v-F(17)/42*x*y*z*u^2*v+F(6)/35*x^2*u^3*v-F(23)/11*z*u^4*v+F(1)/2*y^3*z*v^2+F(79)/60*x*y*z^2*v^2-4353*x*y^2*u*v^2+F(19)/62*x^2*z*u*v^2+14197*z^2*u^2*v^2-F(2)/5*y*u^3*v^2-F(121)/98*x^2*y*v^3+F(120)/29*z^3*v^3-6369*y*z*u*v^3-117*x*u^2*v^3-F(96)/29*y^2*v^4-F(5)/8*x*z*v^4+F(1)/2*u*v^5,F(1)/2*y^5*z-117*x*y^3*z^2+F(6)/35*x^2*y*z^3-F(5)/8*x*y^4*u+F(19)/62*x^2*y^2*z*u-1983*x^3*z^2*u-F(23)/11*y*z^4*u+F(1)/2*x^3*y*u^2+14197*y^2*z^2*u^2-F(2)/5*x*z^3*u^2+F(120)/29*y^3*u^3-6369*x*y*z*u^3-F(96)/29*x^2*u^4+F(1)/2*z*u^5-F(121)/98*x^2*y^3*v+F(121)/89*x^3*y*z*v-F(2)/5*y^2*z^3*v-1983*x*z^4*v+2992*x^4*u*v-6369*y^3*z*u*v-F(17)/42*x*y*z^2*u*v+F(79)/60*x*y^2*u^2*v-4353*x^2*z*u^2*v-117*z^2*u^3*v-F(5)/8*y*u^4*v-F(96)/29*y^4*v^2-4353*x*y^2*z*v^2-F(8)/99*x^2*z^2*v^2+F(96)/79*x^2*y*u*v^2+F(6)/35*z^3*u*v^2+F(19)/62*y*z*u^2*v^2-F(121)/98*x*u^3*v^2+F(5)/8*x^3*v^3-1983*y*z^2*v^3+F(1)/2*y^2*u*v^3+F(121)/89*x*z*u*v^3+2992*x*y*v^4,-x^2*y^3*z+1611*x^3*y*z^2+F(65)/99*y^2*z^4-F(21)/121*x*z^5+F(5)/4*x^3*y^2*u-F(19)/31*x^4*z*u-F(21)/121*y^3*z^2*u-10148*x*y*z^3*u-F(46)/11*x*y^2*z*u^2+3471*x^2*z^2*u^2-F(16)/99*x^2*y*u^3+F(97)/93*z^3*u^3+F(12)/35*y*z*u^4-F(21)/121*x*u^5-x^4*y*v-F(52)/99*y^4*z*v+F(122)/99*x*y^2*z^2*v-F(16)/99*x^2*z^3*v+F(13)/59*x*y^3*u*v+F(124)/101*x^2*y*z*u*v+F(12)/35*z^4*u*v+1611*x^3*u^2*v+9919*y*z^2*u^2*v+F(3)/7*y^2*u^3*v-10148*x*z*u^3*v+234*x^2*y^2*v^2+F(5)/4*x^3*z*v^2+F(3)/7*y*z^3*v^2+F(11)/4*y^2*z*u*v^2-F(46)/11*x*z^2*u*v^2+F(122)/99*x*y*u^2*v^2+F(65)/99*u^4*v^2-F(12)/35*y^3*v^3+F(13)/59*x*y*z*v^3-x^2*u*v^3-F(21)/121*z*u^2*v^3-F(52)/99*y*u*v^4,y^4*z^2-234*x*y^2*z^3+F(12)/35*x^2*z^4-F(90)/121*x*y^3*z*u+57*x^2*y*z^2*u-F(46)/11*z^5*u-F(99)/52*x^2*y^2*u^2-650*x^3*z*u^2-F(109)/4*y*z^3*u^2-2683*y^2*z*u^3-4373*x*z^2*u^3+F(16)/65*x*y*u^4+1611*u^6-F(72)/49*x^2*y^2*z*v+10613*x^3*z^2*v+6526*y*z^4*v-F(90)/121*x^3*y*u*v-3237*y^2*z^2*u*v-7261*x*z^3*u*v-650*y^3*u^2*v-F(4)/103*x*y*z*u^2*v-2683*x^2*u^3*v+F(11)/126*z*u^4*v+x^4*v^2+10613*y^3*z*v^2+3249*x*y*z^2*v^2+57*x*y^2*u*v^2-3237*x^2*z*u*v^2-F(70)/57*z^2*u^2*v^2-4373*y*u^3*v^2-234*x^2*y*v^3+9744*z^3*v^3-7261*y*z*u*v^3-F(109)/4*x*u^2*v^3+F(12)/35*y^2*v^4+6526*x*z*v^4-F(46)/11*u*v^5,-F(4)/5*y^6-F(113)/79*x*y^4*z-11797*x^2*y^2*z^2+F(96)/29*x^3*z^3+13879*x^2*y^3*u-15044*x^3*y*z*u-12643*y^2*z^3*u-F(1)/2*x*z^4*u+F(21)/121*x^4*u^2-F(121)/23*y^3*z*u^2+F(17)/38*x*y*z^2*u^2+3639*x*y^2*u^3+5300*x^2*z*u^3-F(5)/8*z^2*u^4+F(93)/109*y*u^5-12643*x^3*y^2*v-F(1)/2*x^4*z*v+13879*y^3*z^2*v-15044*x*y*z^3*v-F(69)/31*y^4*u*v-9826*x*y^2*z*u*v-F(22)/29*x^2*z^2*u*v-F(100)/23*x^2*y*u^2*v+9933*z^3*u^2*v-F(7)/80*y*z*u^3*v+3908*x*u^4*v-F(121)/23*x*y^3*v^2+F(17)/38*x^2*y*z*v^2+F(21)/121*z^4*v^2+9933*x^3*u*v^2-F(100)/23*y*z^2*u*v^2+F(49)/53*y^2*u^2*v^2+2111*x*z*u^2*v^2+3639*y^2*z*v^3+5300*x*z^2*v^3-F(7)/80*x*y*u*v^3-12076*u^3*v^3-F(5)/8*x^2*v^4+3908*z*u*v^4+F(93)/109*y*v^5,-F(5)/8*x^2*y^4+9933*x^3*y^2*z+F(21)/121*x^4*z^2-12076*y^3*z^3+3908*x*y*z^4-F(1)/2*x^4*y*u+3908*y^4*z*u+2111*x*y^2*z^2*u+5300*x^2*z^3*u+5300*x*y^3*u^2-F(22)/29*x^2*y*z*u^2-F(5)/8*z^4*u^2+F(96)/29*x^3*u^3+9933*y*z^2*u^3+F(21)/121*y^2*u^4-F(1)/2*x*z*u^4+F(93)/109*y^5*v-F(7)/80*x*y^3*z*v-F(100)/23*x^2*y*z^2*v+F(93)/109*z^5*v+F(17)/38*x^2*y^2*u*v-15044*x^3*z*u*v-F(7)/80*y*z^3*u*v-F(100)/23*y^2*z*u^2*v+F(17)/38*x*z^2*u^2*v-15044*x*y*u^3*v-12643*x^3*y*v^2+F(49)/53*y^2*z^2*v^2+3639*x*z^3*v^2+3639*y^3*u*v^2-9826*x*y*z*u*v^2-11797*x^2*u^2*v^2-12643*z*u^3*v^2-F(121)/23*x*y^2*v^3+13879*x^2*z*v^3-F(121)/23*z^2*u*v^3+13879*y*u^2*v^3-F(69)/31*y*z*v^4-F(113)/79*x*u*v^4-F(4)/5*v^6,F(33)/122*x^3*y^2*z+4022*x^4*z^2+F(52)/99*y^3*z^3-F(122)/117*x*y*z^4-F(52)/99*x^4*y*u-F(122)/117*y^4*z*u+F(83)/26*x*y^2*z^2*u+F(89)/58*x^2*z^3*u+F(89)/58*x*y^3*u^2+F(99)/70*x^2*y*z*u^2-F(12)/35*x^3*u^3+F(33)/122*y*z^2*u^3+4022*y^2*u^4-F(52)/99*x*z*u^4-F(89)/58*y^5*v-F(100)/71*x*y^3*z*v+F(78)/101*x^2*y*z^2*v-F(89)/58*z^5*v+F(63)/94*x^2*y^2*u*v-F(17)/31*x^3*z*u*v-F(100)/71*y*z^3*u*v+F(78)/101*y^2*z*u^2*v+F(63)/94*x*z^2*u^2*v-F(17)/31*x*y*u^3*v-2602*x^3*y*v^2+11793*y^2*z^2*v^2+8051*x*z^3*v^2+8051*y^3*u*v^2+12945*x*y*z*u*v^2+F(108)/109*x^2*u^2*v^2-2602*z*u^3*v^2-2520*x*y^2*v^3-F(95)/52*x^2*z*v^3-2520*z^2*u*v^3-F(95)/52*y*u^2*v^3+8051*y*z*v^4-F(65)/83*x*u*v^4-F(89)/58*v^6,-F(89)/58*y^6-F(65)/83*x*y^4*z+F(108)/109*x^2*y^2*z^2-F(12)/35*x^3*z^3-F(95)/52*x^2*y^3*u-F(17)/31*x^3*y*z*u-2602*y^2*z^3*u-F(52)/99*x*z^4*u+4022*x^4*u^2-2520*y^3*z*u^2+F(63)/94*x*y*z^2*u^2+8051*x*y^2*u^3+F(89)/58*x^2*z*u^3-F(89)/58*y*u^5-2602*x^3*y^2*v-F(52)/99*x^4*z*v-F(95)/52*y^3*z^2*v-F(17)/31*x*y*z^3*v+8051*y^4*u*v+12945*x*y^2*z*u*v+F(99)/70*x^2*z^2*u*v+F(78)/101*x^2*y*u^2*v+F(33)/122*z^3*u^2*v-F(100)/71*y*z*u^3*v-F(122)/117*x*u^4*v-2520*x*y^3*v^2+F(63)/94*x^2*y*z*v^2+4022*z^4*v^2+F(33)/122*x^3*u*v^2+F(78)/101*y*z^2*u*v^2+11793*y^2*u^2*v^2+F(83)/26*x*z*u^2*v^2+8051*y^2*z*v^3+F(89)/58*x*z^2*v^3-F(100)/71*x*y*u*v^3+F(52)/99*u^3*v^3-F(122)/117*z*u*v^4-F(89)/58*y*v^5,x^4*y^2+1611*y^5*z-F(77)/60*x*y^3*z^2+F(76)/69*x^2*y*z^3+1611*z^6-F(4)/5*x*y^4*u-15475*x^2*y^2*z*u+F(86)/19*x^3*z^2*u-F(77)/60*y*z^4*u-11038*x^3*y*u^2+F(58)/25*y^2*z^2*u^2+F(112)/43*x*z^3*u^2-F(21)/121*y^3*u^3-11234*x*y*z*u^3+1611*z*u^5-1611*x^2*y^3*v+F(55)/73*x^3*y*z*v+F(112)/43*y^2*z^3*v-11235*x*z^4*v+F(21)/121*x^4*u*v-11234*y^3*z*u*v-F(43)/2*x*y*z^2*u*v-12177*x*y^2*u^2*v+F(18)/107*x^2*z*u^2*v-F(77)/60*z^2*u^3*v-F(4)/5*y*u^4*v+F(18)/107*x*y^2*z*v^2+10973*x^2*z^2*v^2+2311*x^2*y*u*v^2+F(76)/69*z^3*u*v^2-15475*y*z*u^2*v^2-1611*x*u^3*v^2-F(65)/99*x^3*v^3+F(86)/19*y*z^2*v^3-11038*y^2*u*v^3+F(55)/73*x*z*u*v^3+F(21)/121*x*y*v^4+u^2*v^4,-x*y^5+234*x^2*y^3*z-F(12)/35*x^3*y*z^2+F(4)/5*x^3*y^2*u+F(21)/121*x^4*z*u+F(121)/49*y^3*z^2*u+F(25)/123*x*y*z^3*u+11038*y^4*u^2+8706*x*y^2*z*u^2+F(16)/99*x^2*z^2*u^2+F(21)/121*x^2*y*u^3-F(5)/4*z^3*u^3-5984*y*z*u^4+F(46)/11*x^4*y*v+F(5)/4*y^4*z*v-F(19)/31*x*y^2*z^2*v+F(21)/121*x^2*z^3*v+F(91)/108*x*y^3*u*v+F(17)/21*x^2*y*z*u*v-5984*z^4*u*v-F(12)/35*x^3*u^2*v+12551*y*z^2*u^2*v-y^2*u^3*v+F(25)/123*x*z*u^3*v+3597*x^2*y^2*v^2+F(4)/5*x^3*z*v^2-y*z^3*v^2-F(79)/30*y^2*z*u*v^2+8706*x*z^2*u*v^2-F(19)/31*x*y*u^2*v^2+2198*y^3*v^3+F(91)/108*x*y*z*v^3+234*x^2*u*v^3+F(121)/49*z*u^2*v^3+11038*z^2*v^4+F(5)/4*y*u*v^4-x*v^5,-x^5-y^5+7884*x*y^3*z-F(99)/23*x^2*y*z^2-z^5-3570*x^2*y^2*u+F(3)/100*x^3*z*u+7884*y*z^3*u-F(99)/23*y^2*z*u^2-3570*x*z^2*u^2+F(3)/100*x*y*u^3-u^5+7884*x^3*y*v-3570*y^2*z^2*v+F(3)/100*x*z^3*v+F(3)/100*y^3*u*v+F(125)/81*x*y*z*u*v-F(99)/23*x^2*u^2*v+7884*z*u^3*v-F(99)/23*x*y^2*v^2-3570*x^2*z*v^2-F(99)/23*z^2*u*v^2-3570*y*u^2*v^2+F(3)/100*y*z*v^3+7884*x*u*v^3-v^5])) diff --git a/src/AlgebraicGeometry/ToricVarieties/Proj/constructors.jl b/src/AlgebraicGeometry/ToricVarieties/Proj/constructors.jl index 670c6e1b6ddd..3303c3c18ef0 100644 --- a/src/AlgebraicGeometry/ToricVarieties/Proj/constructors.jl +++ b/src/AlgebraicGeometry/ToricVarieties/Proj/constructors.jl @@ -1,5 +1,5 @@ @doc raw""" - proj(E::ToricLineBundle...) + projectivization(E::ToricLineBundle...) This function computes the projectivization of a direct sum of line bundles or divisors. Please see [OM78](@cite) for more background information. @@ -13,30 +13,30 @@ julia> D0 = toric_divisor(P1, [0,0]); julia> D1 = toric_divisor(P1, [1,0]); -julia> X = proj(D0, D1) +julia> X = projectivization(D0, D1) Normal toric variety julia> L0 = toric_line_bundle(P1, [0]); julia> L1 = toric_line_bundle(P1, [2]); -julia> Y = proj(L0, L1) +julia> Y = projectivization(L0, L1) Normal toric variety ``` """ -function proj(E::ToricLineBundle...) - return _proj_and_total_space(true, [E...]) +function projectivization(E::ToricLineBundle...) + return _projectivization_and_total_space(true, [E...]) end -function proj(E::ToricDivisor...) - return _proj_and_total_space(true, [E...]) +function projectivization(E::ToricDivisor...) + return _projectivization_and_total_space(true, [E...]) end -function proj() +function projectivization() error("The direct sum is empty") end -function _proj_and_total_space(is_proj::Bool, E::Vector{T}) where T <: Union{ToricDivisor, ToricLineBundle} +function _projectivization_and_total_space(is_proj::Bool, E::Vector{T}) where T <: Union{ToricDivisor, ToricLineBundle} v = toric_variety(E[1]) @@ -132,11 +132,11 @@ julia> degree(canonical_bundle(Y)) ``` """ function total_space(E::ToricLineBundle...) - return _proj_and_total_space(false, [E...]) + return _projectivization_and_total_space(false, [E...]) end function total_space(E::ToricDivisor...) - return _proj_and_total_space(false, [E...]) + return _projectivization_and_total_space(false, [E...]) end function total_space() diff --git a/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl b/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl index 787e5ce82c32..f9fcd02bec27 100644 --- a/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl +++ b/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl @@ -223,7 +223,7 @@ Covering image_cones = [positive_hull(matrix(ZZ, rays(c)) * A) for c in domain_cones] # construct the corresponding morphism of rings - morphism_dict = IdDict{AbsSpec, AbsSpecMor}() + morphism_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() domain_cov = default_covering(X) # ordering of the patches must be the same as `maximal_cones` codomain_cov = default_covering(Y) for i in 1:n_maximal_cones(X) diff --git a/src/AlgebraicGeometry/ToricVarieties/ToricSchemes/attributes.jl b/src/AlgebraicGeometry/ToricVarieties/ToricSchemes/attributes.jl index 28ff7875bd29..f1fb6feea73f 100644 --- a/src/AlgebraicGeometry/ToricVarieties/ToricSchemes/attributes.jl +++ b/src/AlgebraicGeometry/ToricVarieties/ToricSchemes/attributes.jl @@ -5,7 +5,7 @@ @doc raw""" forget_toric_structure(X::AffineNormalToricVariety) -Returns a pair `(Y, iso)` where `Y` is a scheme without toric structure, +Returns a pair `(Y, iso)` where `Y` is a scheme without toric structure, together with an isomorphism `iso : Y → X`. # Examples @@ -32,7 +32,7 @@ end @doc raw""" forget_toric_structure(X::NormalToricVariety) -Returns a pair `(Y, iso)` where `Y` is a scheme without toric structure, +Returns a pair `(Y, iso)` where `Y` is a scheme without toric structure, together with an isomorphism `iso : Y → X`. # Examples @@ -46,14 +46,14 @@ julia> forget_toric_structure(P2) """ function forget_toric_structure(X::NormalToricVariety) # Collect all the isomorphisms forgetting the toric structure - iso_dict = IdDict{AbsSpec, AbsSpecMor}() + iso_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for U in affine_charts(X) iso_dict[U] = forget_toric_structure(U)[2] # store only the isomorphism end cov = Covering([domain(phi) for (U, phi) in iso_dict]) # Prepare a dictionary that can be used in the constructor of the covering morphism - iso_dict_covariant = IdDict{AbsSpec, AbsSpecMor}() + iso_dict_covariant = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for (U, phi) in iso_dict iso_dict_covariant[domain(phi)] = phi end @@ -67,7 +67,7 @@ function forget_toric_structure(X::NormalToricVariety) # Prepare the underlying covering morphisms for the identifying isomorphisms iso_cov = CoveringMorphism(cov, default_covering(X), iso_dict_covariant) - inv_dict = IdDict{AbsSpec, AbsSpecMor}() + inv_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for (U, phi) in iso_dict inv_dict[U] = inverse(phi) end @@ -79,7 +79,7 @@ function forget_toric_structure(X::NormalToricVariety) # Make the identifying isomorphisms iso = CoveredSchemeMorphism(Y, X, iso_cov) iso_inv = CoveredSchemeMorphism(X, Y, iso_cov_inv) - + set_attribute!(iso, :inverse => iso_inv) set_attribute!(iso_inv, :inverse => iso) @@ -115,9 +115,9 @@ Spectrum by ideal (0) ``` """ -@attr Spec{QQField, MPolyQuoRing{QQMPolyRingElem}} underlying_scheme(X::AffineNormalToricVariety) = Spec(base_ring(toric_ideal(X)), toric_ideal(X)) +@attr AffineScheme{QQField, MPolyQuoRing{QQMPolyRingElem}} underlying_scheme(X::AffineNormalToricVariety) = spec(base_ring(toric_ideal(X)), toric_ideal(X)) -### +### # Some additional structure to make computation of toric gluings lazy struct ToricGluingData X::NormalToricVariety @@ -142,31 +142,31 @@ function _compute_toric_gluing(gd::ToricGluingData) sigma_2_dual = weight_cone(V) tau_dual = polarize(tau) - # We do the following. There is a commutative diagram of rings + # We do the following. There is a commutative diagram of rings # - # ℚ [σ₁̌] ↪ ℚ [τ ̌] ↩ ℚ [σ₂̌] + # ℚ [σ₁̌] ↪ ℚ [τ ̌] ↩ ℚ [σ₂̌] # - # given by localization maps. The cone τ ̌ has lineality L. + # given by localization maps. The cone τ ̌ has lineality L. # We need to find a Hilbert basis for both L ∩ σ₁̌ and L ∩ σ₂̌. - # Then the localization maps are given by inverting the - # elements of these Hilbert bases. The gluing isomorphisms - # are then obtained by expressing the generators on the one - # side in terms of the others. + # Then the localization maps are given by inverting the + # elements of these Hilbert bases. The gluing isomorphisms + # are then obtained by expressing the generators on the one + # side in terms of the others. - # We are using Proposition 1.2.10 in Cox-Little-Schenck here: - # "If τ is a face of a polyhedral cone σ and τ* = σ ̌ ∩ τ⟂, + # We are using Proposition 1.2.10 in Cox-Little-Schenck here: + # "If τ is a face of a polyhedral cone σ and τ* = σ ̌ ∩ τ⟂, # then τ* is a face of σ ̌." - degs1 = hilbert_basis(U) + degs1 = hilbert_basis(U) non_local_indices_1 = filter(i->!(vec(-degs1[i,:]) in tau_dual), 1:nrows(degs1)) - degs2 = hilbert_basis(V) + degs2 = hilbert_basis(V) non_local_indices_2 = filter(i->!(vec(-degs2[i,:]) in tau_dual), 1:nrows(degs2)) x = gens(OO(U)) UV = PrincipalOpenSubset(U, [x[i] for i in 1:length(x) if !(i in non_local_indices_1)]) y = gens(OO(V)) VU = PrincipalOpenSubset(V, [y[i] for i in 1:length(y) if !(i in non_local_indices_2)]) - + y_to_x = _convert_degree_system(degs1, degs2, non_local_indices_1) x_to_y = _convert_degree_system(degs2, degs1, non_local_indices_2) @@ -181,7 +181,7 @@ function _compute_toric_gluing(gd::ToricGluingData) return result end -# Write the elements in `degs2` as linear combinations of `degs1`, allowing only non-negative +# Write the elements in `degs2` as linear combinations of `degs1`, allowing only non-negative # coefficients for the vectors vᵢ of `degs1` with index i ∈ `non_local_indices`. function _convert_degree_system(degs1::ZZMatrix, degs2::ZZMatrix, non_local_indices_1::Vector{Int}) result = Vector{ZZMatrix}() @@ -231,7 +231,7 @@ with default covering set_attribute!(A, :toric_ideal, toric_ideal(R, A)) end cov = Covering(patch_list) - + for i in 1:(length(patch_list)-1) for j in i+1:length(patch_list) X = patch_list[i] @@ -247,7 +247,7 @@ with default covering add_gluing!(cov, _compute_gluings(X, Y, vmat, U, V)) end end - + # TODO: Improve the gluing (lazy gluing) or try to use the Hasse diagram. # TODO: For now, we conjecture, that the composition of the computed gluings is sufficient to deduce all gluings. #fill_transitions!(cov) @@ -305,6 +305,6 @@ end is_irreducible(X::NormalToricVariety) = true is_reduced(X::NormalToricVariety) = true -is_empty(X::NormalToricVariety) = false +is_empty(X::NormalToricVariety) = false is_integral(X::NormalToricVariety) = true is_connected(X::NormalToricVariety) = true diff --git a/src/Groups/directproducts.jl b/src/Groups/directproducts.jl index f42176403477..4882d0158686 100644 --- a/src/Groups/directproducts.jl +++ b/src/Groups/directproducts.jl @@ -343,7 +343,7 @@ Base.:^(H::DirectProductGroup, y::GAPGroupElem) = sub([h^y for h in gens(H)]...) ################################################################################ # # Semidirect products -# +# ################################################################################ """ @@ -454,7 +454,7 @@ end ################################################################################ # # Wreath products -# +# ################################################################################ """ diff --git a/src/Modules/UngradedModules/SubQuoHom.jl b/src/Modules/UngradedModules/SubQuoHom.jl index 96ed1a31225c..879ec95a8ea2 100644 --- a/src/Modules/UngradedModules/SubQuoHom.jl +++ b/src/Modules/UngradedModules/SubQuoHom.jl @@ -88,14 +88,14 @@ image_of_generator(phi::SubQuoHom, i::Int) = phi.im[i]::elem_type(codomain(phi)) @doc raw""" hom(M::SubquoModule{T}, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}) where T -Given a vector `V` of `ngens(M)` elements of `N`, +Given a vector `V` of `ngens(M)` elements of `N`, return the homomorphism `M` $\to$ `N` which sends the `i`-th generator `M[i]` of `M` to the `i`-th entry of `V`. hom(M::SubquoModule{T}, N::ModuleFP{T}, A::MatElem{T})) where T Given a matrix `A` with `ngens(M)` rows and `ngens(N)` columns, return the -homomorphism `M` $\to$ `N` which sends the `i`-th generator `M[i]` of `M` to +homomorphism `M` $\to$ `N` which sends the `i`-th generator `M[i]` of `M` to the linear combination $\sum_j A[i,j]*N[j]$ of the generators `N[j]` of `N`. !!! note @@ -106,7 +106,7 @@ the linear combination $\sum_j A[i,j]*N[j]$ of the generators `N[j]` of `N`. !!! warning The functions do not check whether the resulting homomorphism is well-defined, - that is, whether it sends the relations of `M` into the relations of `N`. + that is, whether it sends the relations of `M` into the relations of `N`. If you are uncertain with regard to well-definedness, use the function below. Note, however, that the check performed by the function requires a Gröbner basis computation. This may take some time. @@ -267,22 +267,22 @@ julia> is_welldefined(c) false ``` """ -hom(M::SubquoModule, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; check::Bool=true) where T = SubQuoHom(M, N, V; check) +hom(M::SubquoModule, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; check::Bool=true) where T = SubQuoHom(M, N, V; check) hom(M::SubquoModule, N::ModuleFP{T}, A::MatElem{T}; check::Bool=true) where T = SubQuoHom(M, N, A; check) @doc raw""" hom(M::SubquoModule, N::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}, h::RingMapType) where {T, RingMapType} -Given a vector `V` of `ngens(M)` elements of `N`, +Given a vector `V` of `ngens(M)` elements of `N`, return the homomorphism `M` $\to$ `N` which sends the `i`-th -generator `M[i]` of `M` to the `i`-th entry of `V`, and the +generator `M[i]` of `M` to the `i`-th entry of `V`, and the scalars in `base_ring(M)` to their images under `h`. hom(M::SubquoModule, N::ModuleFP{T}, A::MatElem{T}, h::RingMapType) where {T, RingMapType} Given a matrix `A` with `ngens(M)` rows and `ngens(N)` columns, return the -homomorphism `M` $\to$ `N` which sends the `i`-th generator `M[i]` of `M` to +homomorphism `M` $\to$ `N` which sends the `i`-th generator `M[i]` of `M` to the linear combination $\sum_j A[i,j]*N[j]$ of the generators `N[j]` of `N`, and the scalars in `base_ring(M)` to their images under `h`. @@ -294,7 +294,7 @@ and the scalars in `base_ring(M)` to their images under `h`. !!! warning The functions do not check whether the resulting homomorphism is well-defined, - that is, whether it sends the relations of `M` into the relations of `N`. + that is, whether it sends the relations of `M` into the relations of `N`. If you are uncertain with regard to well-definedness, use the function below. Note, however, that the check performed by the function requires a Gröbner basis computation. This may take some time. @@ -325,7 +325,7 @@ function is_welldefined(H::SubQuoHom) phi = hom(F0, N, elem_type(N)[H(eps(v)) for v in gens(F0)]; check=false) # now phi ∘ g : F1 --> N has to be zero. return iszero(compose(g, phi)) - + C = present_as_cokernel(M).quo n = ngens(C) m = rank(C.F) @@ -364,7 +364,7 @@ function Base.hash(f::ModuleFPHom, h::UInt) h = hash(typeof(f), h) h = hash(domain(f), h) h = hash(codomain(f), h) - # We can not assume that the images of generators + # We can not assume that the images of generators # have a hash in general return xor(h, b) end @@ -374,7 +374,7 @@ end matrix(a::SubQuoHom) Given a homomorphism `a` of type `SubQuoHom` with domain `M` -and codomain `N`, return a matrix `A` with `ngens(M)` rows and +and codomain `N`, return a matrix `A` with `ngens(M)` rows and `ngens(N)` columns such that `a == hom(M, N, A)`. # Examples @@ -478,9 +478,9 @@ Return the image $a(m)$. function image(f::SubQuoHom, a::SubquoModuleElem) @assert a.parent === domain(f) iszero(a) && return zero(codomain(f)) - # The code in the comment below was an attempt to make - # evaluation of maps faster. However, it turned out that - # for the average use case the comparison was more expensive + # The code in the comment below was an attempt to make + # evaluation of maps faster. However, it turned out that + # for the average use case the comparison was more expensive # than the gain for mappings. The flag should be set by constructors # nevertheless when applicable. #if f.generators_map_to_generators === nothing @@ -532,7 +532,7 @@ function preimage(f::SubQuoHom{<:SubquoModule, <:ModuleFP}, a::Union{SubquoModul return i end -function preimage(f::SubQuoHom{<:SubquoModule, <:ModuleFP, Nothing}, +function preimage(f::SubQuoHom{<:SubquoModule, <:ModuleFP, Nothing}, a::Union{SubquoModuleElem,FreeModElem}) @assert parent(a) === codomain(f) D = domain(f) @@ -923,9 +923,9 @@ end function *(h::ModuleFPHom{T1, T2, <:Any}, g::ModuleFPHom{T2, T3, <:Any}) where {T1, T2, T3} @assert codomain(h) === domain(g) - return hom(domain(h), codomain(g), - Vector{elem_type(codomain(g))}([g(h(x)) for x = gens(domain(h))]), - MapFromFunc(base_ring(domain(h)), + return hom(domain(h), codomain(g), + Vector{elem_type(codomain(g))}([g(h(x)) for x = gens(domain(h))]), + MapFromFunc(base_ring(domain(h)), base_ring(codomain(g)), x->(base_ring_map(g)(base_ring_map(h)(x)))), check=false @@ -990,7 +990,7 @@ end restrict_domain(H::SubQuoHom, M::SubquoModule) Restrict the morphism `H` to `M`. For this `M` has to be a submodule -of the domain of `H`. The relations of `M` must be the relations of +of the domain of `H`. The relations of `M` must be the relations of the domain of `H`. """ function restrict_domain(H::SubQuoHom, M::SubquoModule) @@ -1061,7 +1061,7 @@ end @doc raw""" preimage(H::SubQuoHom,N::SubquoModule{T}, task::Symbol = :none) where {T} -Return the preimage of the submodule `N` under the morphism `H` +Return the preimage of the submodule `N` under the morphism `H` as a subquotient, as well as the injection homomorphism into the domain of $H$. """ function preimage(H::SubQuoHom,N::SubquoModule{T}, task::Symbol = :none) where {T} @@ -1095,7 +1095,7 @@ function preimage(H::SubQuoHom,elems::Vector{SubquoModuleElem{T}}, task::Symbol elems_in_coker = map(x->i_cod_coker(x),elems) cokernel_modulo_elmes,projection = quo(cod_coker,elems_in_coker) preimage, emb = kernel(H*i_cod_coker*projection) - + if task != :none return preimage, emb else @@ -1123,10 +1123,10 @@ end simplify_light(M::SubquoModule) Simplify the given subquotient `M` and return the simplified subquotient `N` along -with the injection map $N \to M$ and the projection map $M \to N$. These maps are +with the injection map $N \to M$ and the projection map $M \to N$. These maps are isomorphisms. -The only simplifications which are done are the following: -- Remove all generators which are represented by the zero element in the ambient +The only simplifications which are done are the following: +- Remove all generators which are represented by the zero element in the ambient free module. - Remove all generators which are in the generating set of the relations. - Remove all duplicates in the generators and relations sets. @@ -1153,7 +1153,7 @@ end simplify_with_same_ambient_free_module(M::SubquoModule) Simplify the given subquotient `M` and return the simplified subquotient `N` along -with the injection map $N \to M$ and the projection map $M \to N$. These maps are +with the injection map $N \to M$ and the projection map $M \to N$. These maps are isomorphisms. The ambient free module of `N` is the same as that of `M`. """ function simplify_with_same_ambient_free_module(M::SubquoModule) @@ -1167,10 +1167,10 @@ end simplify(M::SubquoModule) Simplify the given subquotient `M` and return the simplified subquotient `N` along -with the injection map $N \to M$ and the projection map $M \to N$. These maps are -isomorphisms. +with the injection map $N \to M$ and the projection map $M \to N$. These maps are +isomorphisms. The simplifcation is heuristical and includes steps like for example removing -zero-generators or removing the i-th component of all vectors if those are +zero-generators or removing the i-th component of all vectors if those are reduced by a relation. """ function simplify(M::SubquoModule) @@ -1311,11 +1311,11 @@ end @doc raw""" map(F::FreeMod{T}, A::MatrixElem{T}) where T -Converts a given $n \times m$-matrix into the corresponding morphism $A : R^n \to F$, +Converts a given $n \times m$-matrix into the corresponding morphism $A : R^n \to F$, with `rank(F) == m`. """ function map(F::FreeMod{T}, A::MatrixElem{T}) where {T <: RingElement} - if is_graded(F) + if is_graded(F) return graded_map(F,A) end R = base_ring(F) diff --git a/src/Modules/UngradedModules/SubquoModuleElem.jl b/src/Modules/UngradedModules/SubquoModuleElem.jl index b81aa401a465..b59fdf355817 100644 --- a/src/Modules/UngradedModules/SubquoModuleElem.jl +++ b/src/Modules/UngradedModules/SubquoModuleElem.jl @@ -14,7 +14,7 @@ SubquoModuleElem(v::SRow{R}, SQ::SubquoModule) where {R} = SubquoModuleElem{R}(v Construct an element $v \in SQ$ that is represented by $a$. """ -SubquoModuleElem(a::FreeModElem{R}, SQ::SubquoModule; is_reduced::Bool=false) where {R} = SubquoModuleElem{R}(a, SQ; is_reduced) +SubquoModuleElem(a::FreeModElem{R}, SQ::SubquoModule; is_reduced::Bool=false) where {R} = SubquoModuleElem{R}(a, SQ; is_reduced) elem_type(::Type{SubquoModule{T}}) where {T} = SubquoModuleElem{T} parent_type(::Type{SubquoModuleElem{T}}) where {T} = SubquoModule{T} @@ -44,7 +44,7 @@ Given an element `m` of a subquotient $M$ over a ring $R$, say, return the coefficients of an $R$-linear combination of the generators of $M$ which gives $m$. -Return the coefficients of `m` with respect to the basis of standard unit vectors. +Return the coefficients of `m` with respect to the basis of standard unit vectors. The result is returned as a sparse row. @@ -102,7 +102,7 @@ end # - if el is zero, v is zero # - if el is homogeneous, but the current representative is not # then a homogeneous representative is returned. -# - it sets the field is_reduced to true. +# - it sets the field is_reduced to true. function simplify(el::SubquoModuleElem{<:MPolyRingElem{T}}) where {T<:Union{<:FieldElem, <:ZZRingElem}} el.is_reduced && return el if is_zero(el) # We have to do this check because otherwise the coordinates of the representative are not reset. @@ -140,7 +140,7 @@ end # The default only checks whether an element is zero. function simplify(el::SubquoModuleElem) el.is_reduced && return el - if is_zero(el) + if is_zero(el) result = zero(parent(el)) result.is_reduced = true # Todo: Should be done in zero(...) return result @@ -151,7 +151,7 @@ end function simplify!(el::SubquoModuleElem) el.is_reduced && return el - if is_zero(el) + if is_zero(el) el.coeffs = sparse_row(base_ring(parent(el))) el.repres = zero(ambient_free_module(parent(el))) el.is_reduced = true @@ -166,7 +166,7 @@ end @doc raw""" ambient_representative(m::SubquoModuleElem) -Given an element `m` of a subquotient $M$, say, return +Given an element `m` of a subquotient $M$, say, return # Examples ```jldoctest @@ -220,7 +220,7 @@ end standard_basis(F::ModuleGens{T}, reduced::Bool=false) where {T <: MPolyRingElem} Return a standard basis of `F` as an object of type `ModuleGens`. -If `reduced` is set to `true` and the ordering of the underlying ring is global, +If `reduced` is set to `true` and the ordering of the underlying ring is global, a reduced Gröbner basis is computed. """ function standard_basis(F::ModuleGens{T}, reduced::Bool=false) where {T <: MPolyRingElem} @@ -238,7 +238,7 @@ end @doc raw""" lift_std(M::ModuleGens{T}) where {T <: MPolyRingElem} -Return a standard basis `G` of `F` as an object of type `ModuleGens` along with +Return a standard basis `G` of `F` as an object of type `ModuleGens` along with a transformation matrix `T` such that `T*matrix(M) = matrix(G)`. """ function lift_std(M::ModuleGens{T}) where {T <: MPolyRingElem} @@ -258,7 +258,7 @@ end lift_std(M::ModuleGens{T}, ordering::ModuleOrdering) where {T <: MPolyRingElem} Return a standard basis `G` of `F` with respect to the given `ordering` -as an object of type `ModuleGens` along with a transformation +as an object of type `ModuleGens` along with a transformation matrix `T` such that `T*matrix(M) = matrix(G)`. """ function lift_std(M::ModuleGens{T}, ordering::ModuleOrdering) where {T <: MPolyRingElem} @@ -300,7 +300,7 @@ parent(b::SubquoModuleElem) = b.parent @doc raw""" (M::SubquoModule{T})(f::FreeModElem{T}) where T -Given an element `f` of the ambient free module of `M` which represents an element of `M`, +Given an element `f` of the ambient free module of `M` which represents an element of `M`, return the represented element. """ function (M::SubquoModule{T})(f::FreeModElem{T}) where T @@ -312,7 +312,7 @@ function (M::SubquoModule{T})(f::FreeModElem{T}) where T end @doc raw""" - (M::SubquoModule{T})(c::SRow{T}) where T + (M::SubquoModule{T})(c::SRow{T}) where T Return the subquotient element $\sum_i a[i] \cdot M[i]\in M$. """ @@ -322,7 +322,7 @@ end @doc raw""" SubquoModuleElem(c::Vector{T}, parent::SubquoModule{T}) where T - + Return the element of `parent` defined as a linear combination of the generators of $parent$ with coefficients given by the entries of `c`. """ @@ -370,7 +370,7 @@ end function check_parent(a::Union{AbstractFreeModElem,SubquoModuleElem}, b::Union{AbstractFreeModElem,SubquoModuleElem}) if parent(a) !== parent(b) error("elements not compatible") - end + end end function +(a::SubquoModuleElem, b::SubquoModuleElem) @@ -382,7 +382,7 @@ function +(a::SubquoModuleElem, b::SubquoModuleElem) end end -function -(a::SubquoModuleElem, b::SubquoModuleElem) +function -(a::SubquoModuleElem, b::SubquoModuleElem) check_parent(a,b) if isdefined(a, :coeffs) && isdefined(b, :coeffs) return SubquoModuleElem(coordinates(a)-coordinates(b), a.parent) @@ -393,7 +393,7 @@ end -(a::SubquoModuleElem) = SubquoModuleElem(-coordinates(a), a.parent) -function *(a::MPolyDecRingElem, b::SubquoModuleElem) +function *(a::MPolyDecRingElem, b::SubquoModuleElem) if parent(a) !== base_ring(parent(b)) return base_ring(parent(b))(a)*b # this will throw if conversion is not possible end @@ -401,7 +401,7 @@ function *(a::MPolyDecRingElem, b::SubquoModuleElem) return SubquoModuleElem(a*repres(b), b.parent) end -function *(a::MPolyRingElem, b::SubquoModuleElem) +function *(a::MPolyRingElem, b::SubquoModuleElem) if parent(a) !== base_ring(parent(b)) return base_ring(parent(b))(a)*b # this will throw if conversion is not possible end @@ -409,7 +409,7 @@ function *(a::MPolyRingElem, b::SubquoModuleElem) return SubquoModuleElem(a*repres(b), b.parent) end -function *(a::RingElem, b::SubquoModuleElem) +function *(a::RingElem, b::SubquoModuleElem) if parent(a) !== base_ring(parent(b)) return base_ring(parent(b))(a)*b # this will throw if conversion is not possible end @@ -421,7 +421,7 @@ end *(a::Integer, b::SubquoModuleElem) = SubquoModuleElem(a*coordinates(b), b.parent) *(a::QQFieldElem, b::SubquoModuleElem) = SubquoModuleElem(a*coordinates(b), b.parent) -function (==)(a::SubquoModuleElem, b::SubquoModuleElem) +function (==)(a::SubquoModuleElem, b::SubquoModuleElem) if parent(a) !== parent(b) return false end @@ -450,11 +450,11 @@ end @doc raw""" sub(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}; cache_morphism::Bool=false) where {T} -Given a vector `V` of (homogeneous) elements of `F`, return a pair `(I, inc)` -consisting of the (graded) submodule `I` of `F` generated by these elements +Given a vector `V` of (homogeneous) elements of `F`, return a pair `(I, inc)` +consisting of the (graded) submodule `I` of `F` generated by these elements and its inclusion map `inc : I ↪ F`. -When `cache_morphism` is set to true, then `inc` will be cached and available +When `cache_morphism` is set to true, then `inc` will be cached and available for `transport` and friends. If only the submodule itself is desired, use `sub_object` instead. @@ -472,20 +472,20 @@ function sub_object(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}) where {T} end @doc raw""" - sub(F::FreeMod{T}, A::MatElem{T}; cache_morphism::Bool=false) where {T} + sub(F::FreeMod{T}, A::MatElem{T}; cache_morphism::Bool=false) where {T} -Given a (homogeneous) matrix `A` interpret the rows of `A` as elements -of the free module `F` and return a pair `(I, inc)` -consisting of the (graded) submodule `I` of `F` generated by these row vectors, +Given a (homogeneous) matrix `A` interpret the rows of `A` as elements +of the free module `F` and return a pair `(I, inc)` +consisting of the (graded) submodule `I` of `F` generated by these row vectors, together with its inclusion map `inc : I ↪ F`. -When `cache_morphism` is set to true, then `inc` will be cached and available +When `cache_morphism` is set to true, then `inc` will be cached and available for `transport` and friends. If only the submodule itself is desired, use `sub_object` instead. """ function sub(F::FreeMod{T}, A::MatElem{T}; cache_morphism::Bool=false) where {T} - M = SubquoModule(SubModuleOfFreeModule(F, A)) + M = SubquoModule(SubModuleOfFreeModule(F, A)) #M = SubquoModule(F, A, zero_matrix(base_ring(F), 1, rank(F))) emb = hom(M, F, ambient_representatives_generators(M); check=false) emb.matrix = A @@ -495,19 +495,19 @@ function sub(F::FreeMod{T}, A::MatElem{T}; cache_morphism::Bool=false) where {T} end function sub_object(F::FreeMod{T}, A::MatElem{T}) where {T} - return SubquoModule(SubModuleOfFreeModule(F, A)) + return SubquoModule(SubModuleOfFreeModule(F, A)) end @doc raw""" sub(F::FreeMod{T}, O::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T -Suppose the `ambient_free_module` of the `parent` `M` of the elements `v_i` -in `O` is `F` and `M` is a submodule (i.e. no relations are present). -Then this returns a pair `(I, inc)` consisting of the submodule `I` -generated by the elements in `O` in `F`, together with its inclusion +Suppose the `ambient_free_module` of the `parent` `M` of the elements `v_i` +in `O` is `F` and `M` is a submodule (i.e. no relations are present). +Then this returns a pair `(I, inc)` consisting of the submodule `I` +generated by the elements in `O` in `F`, together with its inclusion morphism `inc : I ↪ F`. -When `cache_morphism` is set to true, then `inc` will be cached and available +When `cache_morphism` is set to true, then `inc` will be cached and available for `transport` and friends. If only the submodule itself is desired, use `sub_object` instead. @@ -524,13 +524,13 @@ end @doc raw""" sub(F::FreeMod{T}, M::SubquoModule{T}; cache_morphism::Bool=false) where T -Return `M` as a submodule of `F`, together with its inclusion morphism -`inc : M ↪ F`. +Return `M` as a submodule of `F`, together with its inclusion morphism +`inc : M ↪ F`. -When `cache_morphism` is set to true, then `inc` will be cached and available +When `cache_morphism` is set to true, then `inc` will be cached and available for `transport` and friends. -The `ambient_free_module` of `M` needs to be `F` and `M` has to have no +The `ambient_free_module` of `M` needs to be `F` and `M` has to have no relations. If only the submodule itself is desired, use `sub_object` instead. @@ -557,7 +557,7 @@ end Given a vector `V` of (homogeneous) elements of `M`, return the (graded) submodule `I` of `M` generated by these elements together with its inclusion map `inc : I ↪ M. -When `cache_morphism` is set to true, then `inc` will be cached and available +When `cache_morphism` is set to true, then `inc` will be cached and available for `transport` and friends. If only the submodule itself is desired, use `sub_object` instead. @@ -591,7 +591,7 @@ end Given a vector `V` of (homogeneous) elements of `M`, return the (graded) submodule `I` of `M` generated by these elements together with its inclusion map `inc : I ↪ M. -When `cache_morphism` is set to true, then `inc` will be cached and available +When `cache_morphism` is set to true, then `inc` will be cached and available for `transport` and friends. If only the submodule itself is desired, use `sub_object` instead. @@ -641,7 +641,7 @@ to `task`. function return_sub_wrt_task(M::SubquoModule, emb::SubQuoHom, task::Symbol) (task == :none || task == :module) && return M task == :cache_morphism && register_morphism!(emb) - task == :only_morphism && return emb + task == :only_morphism && return emb (task == :cache_morphism || task == :both || task == :with_morphism) && return M, emb error("No valid option for task.") end @@ -650,7 +650,7 @@ end @doc raw""" quo(F::FreeMod{T}, V::Vector{<:FreeModElem{T}}; cache_morphism::Bool=false) where T -Given a vector `V` of (homogeneous) elements of `F`, return a pair `(M, pr)` consisting +Given a vector `V` of (homogeneous) elements of `F`, return a pair `(M, pr)` consisting of the quotient `M = F/⟨V⟩` and the projection map `pr : F → M`. If one is only interested in the actual object `M`, but not the map, use `quo_object` instead. @@ -674,10 +674,10 @@ end @doc raw""" quo(F::FreeMod{T}, A::MatElem{T}; cache_morphism::Bool=false) where {T} -Given a matrix `A`, interpret the row vectors `v_i` of `A` as elements of `F` -and return a pair `(M, pr)` consisting of the quotient `M = F/I` of `F` by the -submodule `I ⊂ F` generated by the rows of `A`, together with the projection -map `pr : F → M`. +Given a matrix `A`, interpret the row vectors `v_i` of `A` as elements of `F` +and return a pair `(M, pr)` consisting of the quotient `M = F/I` of `F` by the +submodule `I ⊂ F` generated by the rows of `A`, together with the projection +map `pr : F → M`. If one is only interested in the actual object `M`, but not the map, use `quo_object` instead. @@ -701,8 +701,8 @@ end @doc raw""" quo(F::FreeMod{T}, O::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T -Given a vector `O` of (homogeneous) elements of some submodule `I` of `F`, -return a pair `(M, pr)` consisting of the quotient `M = F/⟨V⟩` and +Given a vector `O` of (homogeneous) elements of some submodule `I` of `F`, +return a pair `(M, pr)` consisting of the quotient `M = F/⟨V⟩` and the projection map `pr : F → M`. If one is only interested in the actual object `M`, but not the map, use `quo_object` instead. @@ -715,7 +715,7 @@ If `cache_morphism` is set to `true`, the projection is cached and available to function quo(F::FreeMod{T}, O::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T S = SubquoModule(F, basis(F)) Q = SubquoModule(S, [repres(x) for x = O]) - + phi = hom(F, Q, gens(Q), check=false) cache_morphism && register_morphism!(phi) return Q, phi @@ -730,12 +730,12 @@ end @doc raw""" quo(S::SubquoModule{T}, O::Vector{<:FreeModElem{T}}; cache_morphism::Bool=false) where T -Given a vector `V` of (homogeneous) elements of `S`, return a pair `(M, pr)` consisting +Given a vector `V` of (homogeneous) elements of `S`, return a pair `(M, pr)` consisting of the quotient `M = S/⟨V⟩` and the projection map `pr : S → M`. If one is only interested in the actual object `M`, but not the map, use `quo_object` instead. -Note that the elements of `O` must belong to the `ambient_free_module` of `S` and represent +Note that the elements of `O` must belong to the `ambient_free_module` of `S` and represent elements of `S`. If `cache_morphism` is set to `true`, the projection is cached and available to `transport` and friends. @@ -775,7 +775,7 @@ end @doc raw""" quo(S::SubquoModule{T}, V::Vector{<:SubquoModuleElem{T}}; cache_morphism::Bool=false) where T -Given a vector `V` of (homogeneous) elements of `S`, return a pair `(M, pr)` consisting +Given a vector `V` of (homogeneous) elements of `S`, return a pair `(M, pr)` consisting of the quotient `M = S/⟨V⟩` and the projection map `pr : S → M`. If one is only interested in the actual object `M`, but not the map, use `quo_object` instead. @@ -793,7 +793,7 @@ end @doc raw""" quo(M::ModuleFP{T}, V::Vector{<:ModuleFPElem{T}}; cache_morphism::Bool=false) where T -Given a vector `V` of (homogeneous) elements of `M`, return a pair `(N, pr)` consisting +Given a vector `V` of (homogeneous) elements of `M`, return a pair `(N, pr)` consisting of the quotient `N = M/⟨V⟩` and the projection map `pr : M → N`. If one is only interested in the actual object `M`, but not the map, use `quo_object` instead. @@ -841,7 +841,7 @@ end @doc raw""" quo(M::SubquoModule{T}, U::SubquoModule{T}) where T -Return a pair `(N, pr)` consisting of the quotient $N = M / U$ together with the projection +Return a pair `(N, pr)` consisting of the quotient $N = M / U$ together with the projection map `pr : M → N`. If one is only interested in the actual object `N`, but not the map, use `quo_object` instead. @@ -852,7 +852,7 @@ function quo(M::SubquoModule{T}, U::SubquoModule{T}; cache_morphism::Bool=false) if isdefined(M, :quo) && isdefined(U, :quo) F = ambient_free_module(M) @assert F === ambient_free_module(U) - # We can not assume that the SubModuleOfFreeModule layer is implemented in general, + # We can not assume that the SubModuleOfFreeModule layer is implemented in general, # so we deflect to the Subquo-layer instead. @assert SubquoModule(F, relations(M)) == SubquoModule(F, relations(U)) else @@ -868,7 +868,7 @@ function quo_object(M::SubquoModule{T}, U::SubquoModule{T}) where T if isdefined(M, :quo) && isdefined(U, :quo) F = ambient_free_module(M) @assert F === ambient_free_module(U) - # We can not assume that the SubModuleOfFreeModule layer is implemented in general, + # We can not assume that the SubModuleOfFreeModule layer is implemented in general, # so we deflect to the Subquo-layer instead. @assert SubquoModule(F, relations(M)) == SubquoModule(F, relations(U)) else @@ -901,7 +901,7 @@ end @doc raw""" quo(F::FreeMod{R}, T::SubquoModule{R}; cache_morphism::Bool=false) where R -Return a pair `(N, pr)` consisting of the quotient $N = F / T$ together with the projection +Return a pair `(N, pr)` consisting of the quotient $N = F / T$ together with the projection map `pr : F → N`. If one is only interested in the actual object `N`, but not the map, use `quo_object` instead. @@ -1015,7 +1015,7 @@ function iterate(F::ModuleGens, i::Int = 1) return F[i], i+1 end end -eltype(::ModuleGens{T}) where {T} = FreeModElem{T} +eltype(::ModuleGens{T}) where {T} = FreeModElem{T} #??? A scalar product.... function *(a::FreeModElem, b::Vector{FreeModElem}) diff --git a/src/Rings/MPolyQuo.jl b/src/Rings/MPolyQuo.jl index 239d7985472e..f963acb156e8 100644 --- a/src/Rings/MPolyQuo.jl +++ b/src/Rings/MPolyQuo.jl @@ -871,7 +871,7 @@ end # The above method for `simplify` assume that there is a singular backend which # can be used. However, we are using (graded) quotient rings also with coefficient # rings R which can not be translated to Singular; for instance when R is again -# a polynomial ring, or a quotient/localization thereof, or even a `SpecOpenRing`. +# a polynomial ring, or a quotient/localization thereof, or even an `AffineSchemeOpenSubschemeRing`. # Still in many of those cases, we can use `RingFlattening` to bind a computational # backend. In particular, this allows us to do ideal_membership tests; see # the file `flattenings.jl` for details. diff --git a/src/Rings/ReesAlgebra.jl b/src/Rings/ReesAlgebra.jl index 855abf45bdd7..c6ff2849d24f 100644 --- a/src/Rings/ReesAlgebra.jl +++ b/src/Rings/ReesAlgebra.jl @@ -1,20 +1,20 @@ ######################################################################## -# Rees algebras of modules +# Rees algebras of modules # -# Following Eisenbud, Huneke, Ulrich: "What is the Rees algebra +# Following Eisenbud, Huneke, Ulrich: "What is the Rees algebra # of a module?"; arXiv:math/0209187v1 ######################################################################## @doc raw""" rees_algebra(f::ModuleFPHom{<:ModuleFP, <:FreeMod}; check::Bool=true) -For a *versal* [^1] morphism ``f : M → F`` of a module ``M`` into a free -module ``F`` this computes the Rees algebra of ``M`` according to +For a *versal* [^1] morphism ``f : M → F`` of a module ``M`` into a free +module ``F`` this computes the Rees algebra of ``M`` according to [EHU03](@cite)[^2]. !!! note If `check` is set to `true`, the method will check the sufficient -criterion "``fᵀ : F* → M*`` surjective" to verify that ``f`` is versal. -Since no general criterion is known, this will abort with an error message +criterion "``fᵀ : F* → M*`` surjective" to verify that ``f`` is versal. +Since no general criterion is known, this will abort with an error message in the non-affirmative case. [^1]: A morphism of ``M`` into a free module ``F`` as above is called versal if any other morphism ``g : M → F'`` from ``M`` to another free module ``F'`` factors through ``f``. @@ -52,7 +52,7 @@ function rees_algebra(f::ModuleFPHom{<:ModuleFP, <:FreeMod, Nothing}; return rees end -function rees_algebra(M::FreeMod; +function rees_algebra(M::FreeMod; var_names::Vector{String}=["s$i" for i in 0:ngens(M)-1] ) R = base_ring(M) @@ -61,46 +61,46 @@ function rees_algebra(M::FreeMod; return S end -function rees_algebra(M::SubquoModule; +function rees_algebra(M::SubquoModule; var_names::Vector{String}=["s$i" for i in 0:ngens(M)-1], check::Bool=true ) success, p, sigma = is_projective(M) if success - # The easy case: The Rees algebra is simply a polynomial ring + # The easy case: The Rees algebra is simply a polynomial ring # modulo linear equations in the variables parametrized by the base. R = base_ring(M) r = ngens(M) S, s = polynomial_ring(R, Symbol.(var_names)) A = matrix(compose(sigma, p)) # The projector matrix: # M is a direct summand of a free module via p : F ↔ M : sigma. - # Hence, the composition sigma ∘ p is the internal projection - # of F onto M as a direct summand. + # Hence, the composition sigma ∘ p is the internal projection + # of F onto M as a direct summand. # # For a point x ∈ Spec(R) one has A(x) a matrix with entries in a field 𝕜 - # Its span is the subspace M(x) ⊂ 𝕜ʳ, the fiber of M at x. - # Polynomial functions on that fiber are polynomial functions - # on 𝕜ⁿ in variables s₀,…,sᵣ₋₁, but restricted to M(x). Hence, we - # can calculate modulo the ideal generated by linear forms - # l = a₁s₁ + … + aᵣ₋₁sᵣ₋₁ vanishing on M(x). - # + # Its span is the subspace M(x) ⊂ 𝕜ʳ, the fiber of M at x. + # Polynomial functions on that fiber are polynomial functions + # on 𝕜ⁿ in variables s₀,…,sᵣ₋₁, but restricted to M(x). Hence, we + # can calculate modulo the ideal generated by linear forms + # l = a₁s₁ + … + aᵣ₋₁sᵣ₋₁ vanishing on M(x). + # # Since A(x) is a projector (A² = A), we find that the span M(x) - # is annihilated by the matrix B = 1 - A and that the columns of B - # generate that ideal. + # is annihilated by the matrix B = 1 - A and that the columns of B + # generate that ideal. B = one(A) - A I = ideal(S, [sum(B[j, i]*s[j] for j in 1:length(s)) for i in 1:ncols(B)]) Q, sq = quo(S, I) return Q end - # The complicated case. We construct a versal morphism f : M → F to a + # The complicated case. We construct a versal morphism f : M → F to a # free module along the lines of Proposition 1.3 of [1] (in its published version). return rees_algebra(_versal_morphism_to_free_module(M), check=false) end ### Auxiliary methods needed for the Rees algebras -### The following function is implemented along the lines of Proposition 1.3 of [1] in +### The following function is implemented along the lines of Proposition 1.3 of [1] in # its published version. function _versal_morphism_to_free_module(M::SubquoModule) R = base_ring(M) @@ -113,17 +113,6 @@ function _versal_morphism_to_free_module(M::SubquoModule) return compose(psi, g_dual) end -function proj(S::MPolyDecRing) - is_standard_graded(S) || error("ring must be standard graded") - return ProjectiveScheme(S) -end - -function proj(Q::MPolyQuoRing{<:MPolyDecRingElem}) - S = base_ring(Q) - is_standard_graded(S) || error("ring must be standard graded") - return ProjectiveScheme(Q) -end - function is_isomorphism(f::ModuleFPHom) return is_injective(f) && is_surjective(f) end @@ -132,7 +121,7 @@ end function simplify!( a::MPolyQuoRingElem{AbstractAlgebra.Generic.MPoly{T}} - ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, + ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, <:MPolyLocRingElem, <:MPolyQuoLocRingElem} } @@ -141,7 +130,7 @@ end function iszero( a::MPolyQuoRingElem{AbstractAlgebra.Generic.MPoly{T}} - ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, + ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, <:MPolyLocRingElem, <:MPolyQuoLocRingElem} } @@ -152,7 +141,7 @@ end function isone( a::MPolyQuoRingElem{AbstractAlgebra.Generic.MPoly{T}} - ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, + ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, <:MPolyLocRingElem, <:MPolyQuoLocRingElem} } @@ -164,7 +153,7 @@ end function ==(a::MPolyQuoRingElem{AbstractAlgebra.Generic.MPoly{T}}, b::MPolyQuoRingElem{AbstractAlgebra.Generic.MPoly{T}} - ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, + ) where {T<:Union{<:MPolyRingElem, <:MPolyQuoRingElem, <:MPolyLocRingElem, <:MPolyQuoLocRingElem} } diff --git a/src/Rings/localization_interface.jl b/src/Rings/localization_interface.jl index 0d3bff66f4aa..94bae70624f8 100644 --- a/src/Rings/localization_interface.jl +++ b/src/Rings/localization_interface.jl @@ -12,7 +12,7 @@ import AbstractAlgebra: expressify, show_via_expressify @doc raw""" AbsMultSet{RingType, RingElemType} -The abstract type for a multiplicatively closed subset of a commutative ring +The abstract type for a multiplicatively closed subset of a commutative ring of type `RingType` with elements of type `RingElemType`. """ abstract type AbsMultSet{RingType<:Ring, RingElemType<:RingElem} end @@ -56,9 +56,9 @@ function Base.in(f::RingElemType, S::AbsMultSet{RingType, RingElemType}) where { end ### iterator over the multiplicative set -# This can (and should) be used to iterate over some set of generators -# of the multiplicative set whenever possible. For instance, this is -# used to check well-definedness of homomorphisms from localized rings. +# This can (and should) be used to iterate over some set of generators +# of the multiplicative set whenever possible. For instance, this is +# used to check well-definedness of homomorphisms from localized rings. # By default, however, this iteration does nothing. Base.iterate(U::T) where {T<:AbsMultSet} = (one(ring(U)), 1) Base.iterate(U::T, a::Tuple{<:RingElem, Int}) where {T<:AbsMultSet} = nothing @@ -71,17 +71,17 @@ Base.iterate(U::T, i::Int) where {T<:AbsMultSet} = nothing @doc raw""" AbsLocalizedRing{RingType, RingElemType, MultSetType} -The abstract type for modelling the localization R[U⁻¹] of a commutative ring R -of type `RingType` with elements of type `RingElemType` at a multiplicatively closed -subset S of type `MultSetType`. +The abstract type for modelling the localization R[U⁻¹] of a commutative ring R +of type `RingType` with elements of type `RingElemType` at a multiplicatively closed +subset S of type `MultSetType`. -It is recommended to implement the arithmetic of a concrete instance of such a localized +It is recommended to implement the arithmetic of a concrete instance of such a localized ring R[U⁻¹] using the concept of fractions of elements in the original ring R. To check -whether a given denominator is admissible for the specific localization, use the +whether a given denominator is admissible for the specific localization, use the `ìn` function. -Depending on the actual type of R and U, further functionality can be provided using -various Gröbner basis driven backends. +Depending on the actual type of R and U, further functionality can be provided using +various Gröbner basis driven backends. """ abstract type AbsLocalizedRing{RingType, RingElemType, MultSetType} <: Ring end @@ -150,7 +150,7 @@ end @doc raw""" localization(U::AbsMultSet) -Given a multiplicatively closed subset of a multivariate polynomial ring ``R``, say, +Given a multiplicatively closed subset of a multivariate polynomial ring ``R``, say, return the localization of ``R`` at ``U`` together with the localization map ``R`` ``\to`` ``R[U^{-1}]``. localization(R::Ring, U::AbsMultSet) @@ -200,21 +200,21 @@ function localization(R::Ring, U::AbsMultSet) end @doc raw""" - (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(f::AbstractAlgebra.Generic.FracFieldElem{RingElemType}) where {RingType, RingElemType, MultSetType} + (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(f::AbstractAlgebra.Generic.FracFieldElem{RingElemType}) where {RingType, RingElemType, MultSetType} Converts a fraction f = a//b to an element of the localized ring W. """ -function (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(f::AbstractAlgebra.Generic.FracFieldElem{RingElemType}) where {RingType, RingElemType, MultSetType} +function (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(f::AbstractAlgebra.Generic.FracFieldElem{RingElemType}) where {RingType, RingElemType, MultSetType} error("conversion for fractions to elements of type $(typeof(W)) is not implemented") end ### required conversions @doc raw""" - (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(a::RingElemType) where {RingType, RingElemType, MultSetType} + (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(a::RingElemType) where {RingType, RingElemType, MultSetType} Converts an element `a` to an element of `W`. """ -function (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(a::RingElemType) where {RingType, RingElemType, MultSetType} +function (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(a::RingElemType) where {RingType, RingElemType, MultSetType} error("conversion of elements of type $(RingElemType) to elements of $(typeof(W)) is not implemented") end @@ -223,11 +223,11 @@ end Converts a pair `(a, b)` to an element `a//b` in `W`. -**Note:** When the flag `check=true` is set, then it will be checked -whether the fraction `a//b` is admissible for `W`. Since those checks +**Note:** When the flag `check=true` is set, then it will be checked +whether the fraction `a//b` is admissible for `W`. Since those checks are usually expensive, it should be disabled for safe internal usage. """ -function (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(a::RingElemType, b::RingElemType; check::Bool=true) where {RingType, RingElemType, MultSetType} +function (W::AbsLocalizedRing{RingType, RingElemType, MultSetType})(a::RingElemType, b::RingElemType; check::Bool=true) where {RingType, RingElemType, MultSetType} error("conversion of pairs `(a, b)` of elements of type $(RingElemType) to fractions `a/b` in a ring of type $(typeof(W)) is not implemented") end @@ -243,17 +243,17 @@ end @doc raw""" AbsLocalizedRingElem{RingType, RingElemType, MultSetType} -The abstract type of an element of the localization R[S⁻¹] of a commutative ring -R of type `RingType` with elements of type `RingElemType` at a multiplicatively +The abstract type of an element of the localization R[S⁻¹] of a commutative ring +R of type `RingType` with elements of type `RingElemType` at a multiplicatively closed set S of type `MultSetType`. """ abstract type AbsLocalizedRingElem{ - RingType <: AbstractAlgebra.Ring, - RingElemType <: AbstractAlgebra.RingElem, + RingType <: AbstractAlgebra.Ring, + RingElemType <: AbstractAlgebra.RingElem, MultSetType <: AbsMultSet } <: AbstractAlgebra.RingElem end -### required getter functions +### required getter functions @doc raw""" numerator(f::AbsLocalizedRingElem) @@ -281,7 +281,7 @@ function parent(f::AbsLocalizedRingElem) error("`parent` is not implemented for the type $(typeof(f))") end -function expressify(f::AbsLocalizedRingElem; context=nothing) +function expressify(f::AbsLocalizedRingElem; context=nothing) isone(denominator(f)) && return expressify(numerator(f), context=context) return Expr(:call, :/, expressify(numerator(f), context=context), expressify(denominator(f), context=context)) end @@ -311,7 +311,7 @@ end function +(a::T, b::T) where {T<:AbsLocalizedRingElem} parent(a) == parent(b) || error("the arguments do not have the same parent ring") - if denominator(a) == denominator(b) + if denominator(a) == denominator(b) return reduce_fraction((parent(a))(numerator(a) + numerator(b), denominator(a), check=false)) end return reduce_fraction((parent(a))(numerator(a)*denominator(b) + numerator(b)*denominator(a), denominator(a)*denominator(b), check=false)) @@ -319,7 +319,7 @@ end function -(a::T, b::T) where {T<:AbsLocalizedRingElem} parent(a) == parent(b) || error("the arguments do not have the same parent ring") - if denominator(a) == denominator(b) + if denominator(a) == denominator(b) return reduce_fraction((parent(a))(numerator(a) - numerator(b), denominator(a), check=false)) end return reduce_fraction((parent(a))(numerator(a)*denominator(b) - numerator(b)*denominator(a), denominator(a)*denominator(b), check=false)) @@ -363,11 +363,11 @@ function ^(a::AbsLocalizedRingElem, i::Integer) return parent(a)(numerator(a)^i, denominator(a)^i, check=false) end -function divexact(a::T, b::T; check::Bool=false) where {T<:AbsLocalizedRingElem} +function divexact(a::T, b::T; check::Bool=false) where {T<:AbsLocalizedRingElem} error("method `divexact` not implemented for arguments of type $(typeof(a))") end -function inv(a::AbsLocalizedRingElem) +function inv(a::AbsLocalizedRingElem) return divexact(parent(a)(denominator(a)), parent(a)(numerator(a))) end @@ -383,7 +383,7 @@ is_domain_type(T::Type{U}) where {U<:AbsLocalizedRingElem} = false # default set is_exact_type(T::Type{U}) where {U<:AbsLocalizedRingElem} = false # default set to false -function Base.hash(f::T, h::UInt) where {T<:AbsLocalizedRingElem} +function Base.hash(f::T, h::UInt) where {T<:AbsLocalizedRingElem} r = 0x78a97cd90 r = xor(r, hash(numerator(f), h)) return xor(r, hash(denominator(f), h)) @@ -423,17 +423,17 @@ function Base.show(io::IO, W::AbsLocalizedRing) end end -function zero!(a::AbsLocalizedRingElem) +function zero!(a::AbsLocalizedRingElem) a = zero(parent(a)) return a end -function mul!(c::T, a::T, b::T) where {T<:AbsLocalizedRingElem} +function mul!(c::T, a::T, b::T) where {T<:AbsLocalizedRingElem} c = a*b return c end -function add!(c::T, a::T, b::T) where {T<:AbsLocalizedRingElem} +function add!(c::T, a::T, b::T) where {T<:AbsLocalizedRingElem} c = a+b return c end @@ -446,7 +446,7 @@ end ### promotion rules AbstractAlgebra.promote_rule(::Type{S}, ::Type{S}) where {S<:AbsLocalizedRingElem} = S -function AbstractAlgebra.promote_rule(::Type{S}, ::Type{T}) where {RT, RET, MST, S<:AbsLocalizedRingElem{RT, RET, MST}, T<:RingElement} +function AbstractAlgebra.promote_rule(::Type{S}, ::Type{T}) where {RT, RET, MST, S<:AbsLocalizedRingElem{RT, RET, MST}, T<:RingElement} AbstractAlgebra.promote_rule(RET, T) == RET ? S : Union{} end @@ -466,7 +466,7 @@ iszero(a::AbsLocalizedRingElem) = iszero(numerator(a)) @doc raw""" AbsLocalizedIdeal{LocRingElemType} -Abstract type for finitely generated ideals ``I ⊂ R[S⁻¹]`` in localized rings. +Abstract type for finitely generated ideals ``I ⊂ R[S⁻¹]`` in localized rings. """ abstract type AbsLocalizedIdeal{LocRingElemType} <: Ideal{LocRingElemType} end @@ -518,10 +518,10 @@ function ==(I::IdealType, J::IdealType) where {IdealType<:AbsLocalizedIdeal} return issubset(I, J) && issubset(J, I) end -### A catchall implementation for the ideal arithmetic +### A catchall implementation for the ideal arithmetic # Return the product of the ideals `I` and `J`. function Base.:*(I::T, J::T) where {T<:AbsLocalizedIdeal} - W = base_ring(I) + W = base_ring(I) W == base_ring(J) || error("the given ideals do not belong to the same ring") new_gens = [ f*g for f in gens(I) for g in gens(J)] return ideal(W, new_gens) @@ -529,7 +529,7 @@ end # Return the sum of the ideals `I` and `J`. function Base.:+(I::T, J::T) where {T<:AbsLocalizedIdeal} - W = base_ring(I) + W = base_ring(I) W == base_ring(J) || error("the given ideals do not belong to the same ring") return ideal(W, vcat(gens(I), gens(J))) end @@ -565,11 +565,11 @@ end AbsLocalizedRingHom } -Homomorphism ``ϕ : R[U⁻¹] → S`` from the localization ``R[U⁻¹]`` of type -``DomainType`` to an arbitrary ring `S` of type `CodomainType`. Such a -homomorphism is completely determined by its 'restriction' -``ϕ' : R → R[U⁻¹] → S`` to the `base_ring` ``R`` before localization and -the type parameter `RestrictedMapType` is reserved for that map. +Homomorphism ``ϕ : R[U⁻¹] → S`` from the localization ``R[U⁻¹]`` of type +``DomainType`` to an arbitrary ring `S` of type `CodomainType`. Such a +homomorphism is completely determined by its 'restriction' +``ϕ' : R → R[U⁻¹] → S`` to the `base_ring` ``R`` before localization and +the type parameter `RestrictedMapType` is reserved for that map. """ abstract type AbsLocalizedRingHom{ DomainType<:AbsLocalizedRing, @@ -586,30 +586,30 @@ end ### required getter functions @doc raw""" - domain(f::AbsLocalizedRingHom) + domain(f::AbsLocalizedRingHom) Return the domain of definition of `f`. """ -function domain(f::AbsLocalizedRingHom) +function domain(f::AbsLocalizedRingHom) error("`domain(f)` not implemented for `f` of type $(typeof(f))") end @doc raw""" - codomain(f::AbsLocalizedRingHom) + codomain(f::AbsLocalizedRingHom) Return the codomain of `f`. """ -function codomain(f::AbsLocalizedRingHom) +function codomain(f::AbsLocalizedRingHom) error("`codomain(f)` not implemented for `f` of type $(typeof(f))") end @doc raw""" - restricted_map(f::AbsLocalizedRingHom) + restricted_map(f::AbsLocalizedRingHom) -For a ring homomorphism ``ϕ : R[U⁻¹] → S`` return the underlying +For a ring homomorphism ``ϕ : R[U⁻¹] → S`` return the underlying restriction ``ϕ' : R → S``. """ -function restricted_map(f::AbsLocalizedRingHom) +function restricted_map(f::AbsLocalizedRingHom) error("`restricted_map(f)` not implemented for `f` of type $(typeof(f))") end diff --git a/src/deprecations.jl b/src/deprecations.jl index 260154d3585b..b854970dcaf2 100644 --- a/src/deprecations.jl +++ b/src/deprecations.jl @@ -93,3 +93,17 @@ end @deprecate conjugacy_classes_subgroups(G::T) where T <: Union{GAPGroup, FinGenAbGroup} subgroup_classes(G) @deprecate labelled_matrix_formatted labeled_matrix_formatted + +@deprecate Spec AffineScheme +@deprecate proj(E::ToricLineBundle...) projectivization +@deprecate proj(E::ToricDivisor...) projectivization +@deprecate AbsSpec AbsAffineScheme +@deprecate SpecMor AffineSchemeMor +@deprecate AbsSpecMor AbsAffineSchemeMor +@deprecate SimplifiedSpec SimplifiedAffineScheme +@deprecate SpecOpen AffineSchemeOpenSubscheme +@deprecate SpecOpenMor AffineSchemeOpenSubschemeMor +@deprecate SpecOpenRing AffineSchemeOpenSubschemeRing +@deprecate SpecOpenRingElem AffineSchemeOpenSubschemeRingElem +@deprecate SpecSubset AffineSchemeSubset +@deprecate StdSpec StdAffineScheme diff --git a/src/exports.jl b/src/exports.jl index f9ebe608bd4d..cefb0b501504 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -1,5 +1,5 @@ # Entries are sorted with uppercase before lowercase. To resort it, -# execute: sort < src/exports.jl > dummy ; mv dummy src/exports.jl +# execute: LC_COLLATE=C sort < src/exports.jl > dummy ; mv dummy src/exports.jl export * export @check export @pbw_relations @@ -11,6 +11,8 @@ export ANTIC export AbsAffineAlgebraicSet export AbsAffineCurve export AbsAffineRationalPoint +export AbsAffineScheme +export AbsAffineSchemeMor export AbsAffineVariety export AbsCoveredCurve export AbsCoveredScheme @@ -26,14 +28,17 @@ export AbsProjectiveAlgebraicSet export AbsProjectiveCurve export AbsProjectiveScheme export AbsProjectiveVariety -export AbsSpec -export AbsSpecMor export AbstractAlgebra export AffineAlgebraicSet export AffineHalfspace export AffineHyperplane export AffineNormalToricVariety export AffinePlaneCurve +export AffineScheme +export AffineSchemeOpenSubscheme +export AffineSchemeOpenSubschemeMor +export AffineSchemeOpenSubschemeRing +export AffineSchemeOpenSubschemeRingElem export AffineVariety export AutomorphismGroup export AutomorphismGroupElem @@ -149,11 +154,6 @@ export SimplicialComplex export Singular export Sp export SpaceGerm -export Spec -export SpecOpen -export SpecOpenMor -export SpecOpenRing -export SpecOpenRingElem export SubObjectIterator export SubQuoHom export SubdivisionOfPoints, subdivision_of_points @@ -203,6 +203,8 @@ export affine_normal_toric_variety export affine_open_covering export affine_patch export affine_patches +export affine_scheme +export affine_scheme_open_subscheme_ring_type export affine_space export alexander_dual export algebraic_ideal @@ -1117,8 +1119,8 @@ export orbit_polytope export orbit_representatives_and_stabilizers export orbits export order, has_order, set_order -export ordering export order_field_of_definition +export ordering export orders_centralizers export orders_class_representatives export orders_perfect_groups @@ -1211,6 +1213,7 @@ export projective_special_orthogonal_group export projective_special_unitary_group export projective_symplectic_group export projective_unitary_group +export projectivization export prune_with_map export pseudo_del_pezzo_polytope export pullback @@ -1224,6 +1227,7 @@ export quotient_ring_as_module export radical export radical_membership export rand +export rand01_polytope export rand_box_polytope export rand_cyclic_polytope export rand_homogeneous @@ -1233,7 +1237,6 @@ export rand_normal_polytope export rand_pseudo export rand_spherical_polytope export rand_subpolytope -export rand01_polytope export rank export rank_action export rational_equivalence_class @@ -1376,7 +1379,6 @@ export solve_mixed export solve_non_negative export spanning_sets export spec -export spec_open_ring_type export special_linear_group export special_orthogonal_group export special_unitary_group @@ -1395,9 +1397,9 @@ export star_triangulations export strongly_connected_components export structure_sheaf export sub +export sub_object export subalgebra_membership export subalgebra_membership_homogeneous -export sub_object export subgroup_classes export subquo_type export subquotient diff --git a/src/forward_declarations.jl b/src/forward_declarations.jl index 80c721c9cb3b..52cb07156df9 100644 --- a/src/forward_declarations.jl +++ b/src/forward_declarations.jl @@ -10,12 +10,12 @@ A scheme over a ring ``𝕜`` of type `BaseRingType`. abstract type Scheme{BaseRingType} end @doc raw""" - AbsSpec{BaseRingType, RingType<:Ring} + AbsAffineScheme{BaseRingType, RingType<:Ring} An affine scheme ``X = Spec(R)`` with ``R`` of type `RingType` over a ring ``𝕜`` of type `BaseRingType`. """ -abstract type AbsSpec{BaseRingType, RingType<:Ring} <: Scheme{BaseRingType} end +abstract type AbsAffineScheme{BaseRingType, RingType<:Ring} <: Scheme{BaseRingType} end @doc raw""" AbsCoveredScheme{BaseRingType} @@ -46,7 +46,7 @@ abstract type AbsWeilDivisor{CoveredSchemeType, CoefficientRingType} <: AbsAlgeb NormalToricVariety(polymakeNTV::Polymake.BigObject) = new(polymakeNTV) end -@attributes mutable struct AffineNormalToricVariety <: AbsSpec{QQField, MPolyQuoRing} +@attributes mutable struct AffineNormalToricVariety <: AbsAffineScheme{QQField, MPolyQuoRing} polymakeNTV::Polymake.BigObject AffineNormalToricVariety(polymakeNTV::Polymake.BigObject) = new(polymakeNTV) end diff --git a/test/AlgebraicGeometry/Schemes/AffineRationalPoint.jl b/test/AlgebraicGeometry/Schemes/AffineRationalPoint.jl index 2d7805388410..e4c684a27f06 100644 --- a/test/AlgebraicGeometry/Schemes/AffineRationalPoint.jl +++ b/test/AlgebraicGeometry/Schemes/AffineRationalPoint.jl @@ -53,8 +53,8 @@ k = GF(2) L = GF(2,2) A2 = affine_space(k ,2) - A2k = Oscar.RationalPointSet(Spec(k), A2) - A2L = Oscar.RationalPointSet(Spec(L), A2) + A2k = Oscar.RationalPointSet(spec(k), A2) + A2L = Oscar.RationalPointSet(spec(L), A2) pk = A2k([1,1]) pL = A2L(pk) # conversion @test_throws ErrorException pk == pL @@ -64,8 +64,8 @@ k = ZZ L = GF(2,2) A2 = affine_space(k ,2) - A2k = Oscar.RationalPointSet(Spec(k), A2) - A2L = Oscar.RationalPointSet(Spec(L), A2) + A2k = Oscar.RationalPointSet(spec(k), A2) + A2L = Oscar.RationalPointSet(spec(L), A2) pk = A2k([1,1]) pL = A2L(pk) # conversion @test !(pk == pL) # no automatic coercion -> consistent with hom interpretation since the domains differ diff --git a/test/AlgebraicGeometry/Schemes/SpecOpen.jl b/test/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme.jl similarity index 83% rename from test/AlgebraicGeometry/Schemes/SpecOpen.jl rename to test/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme.jl index 63fa662eb185..751adbaa67bb 100644 --- a/test/AlgebraicGeometry/Schemes/SpecOpen.jl +++ b/test/AlgebraicGeometry/Schemes/AffineSchemeOpenSubscheme.jl @@ -1,11 +1,11 @@ -@testset "SpecOpen_1" begin +@testset "AffineSchemeOpenSubscheme1" begin R, (x,y,z) = QQ["x", "y", "z"] f = x^2 + y^2 + z^2 - A = Spec(R) - X = Spec(quo(R, ideal(R, [x*f, y*f]))[1]) + A = spec(R) + X = spec(quo(R, ideal(R, [x*f, y*f]))[1]) @test is_subscheme(X, A) - U = SpecOpen(A, [x, y]) + U = AffineSchemeOpenSubscheme(A, [x, y]) UX = intersect(X, U) Y = closure(UX) @@ -15,30 +15,30 @@ @test isempty(complement(Y,Y)) end -@testset "SpecOpen_2" begin +@testset "AffineSchemeOpenSubscheme2" begin R, (x,y,z) = QQ["x", "y", "z"] - X = Spec(R) + X = spec(R) N = subscheme(X, [x,y]) U = complement(X, N) - V = SpecOpen(X, [x^2, y-x]) + V = AffineSchemeOpenSubscheme(X, [x^2, y-x]) I = ideal(R, [x*y-z^2]) Y = subscheme(X, I) Xx = hypersurface_complement(X, x) Yx = hypersurface_complement(Y, x) @test !is_closed_embedding(Y, Yx) - U = SpecOpen(Y, [x^5, y-7*x^7]) + U = AffineSchemeOpenSubscheme(Y, [x^5, y-7*x^7]) f = maximal_extension(Y, x//z) intersections(U) set_name!(U, "U") @test name(U) == "U" S, (u, v) = polynomial_ring(QQ, ["u", "v"]) - Z = Spec(S) + Z = spec(S) g = maximal_extension(Y, Z, [x//z, y]) - g = restrict(g, domain(g), SpecOpen(Z, [v])) + g = restrict(g, domain(g), AffineSchemeOpenSubscheme(Z, [v])) R, (x,y,z) = QQ["x", "y", "z"] - X = hypersurface_complement(Spec(R),x) + X = hypersurface_complement(spec(R),x) F = fraction_field(R) f = x//y g = F(x,x) @@ -47,13 +47,13 @@ end @test X ==domain(maximal_extension(X, g)) end -@testset "SpecOpen_3" begin +@testset "AffineSchemeOpenSubscheme3" begin R, (x,y,u,v) = QQ["x", "y", "u","v"] - A = Spec(R) + A = spec(R) O = subscheme(A, [x,y,u,v]) U = complement(A, O) @test A==closure(U) - Oscar.SpecOpenRing(U) + Oscar.AffineSchemeOpenSubschemeRing(U) OU = OO(U) gens(OO(U)) f = OO(U)(x) @@ -79,26 +79,26 @@ end X = subscheme(A, h) XU = intersect(X, U) S, (a,b) = QQ["a", "b"] - B = Spec(S) + B = spec(S) maximal_extension(X, x//u) maximal_extension(A, x//u) maximal_extension(X, [x//u]) f = maximal_extension(X, B, [x//y, x//u]) end -@testset "SpecOpen_4" begin +@testset "AffineSchemeOpenSubscheme4" begin R, (x,y) = QQ["x", "y"] S, (t) = polynomial_ring(QQ, ["t"]) t = t[1] - A = Spec(R) - B = Spec(S) + A = spec(R) + B = spec(S) f = x^2+x^3 -y^2 C = subscheme(A, f) phi = maximal_extension(C, B, [x//y]) psi = maximal_extension(B, C, [(1-t^2)//t^2, (1-t^2)//t^3]) - psi = restrict(psi, SpecOpen(B, [t*(1-t^2)]), domain(phi)) + psi = restrict(psi, AffineSchemeOpenSubscheme(B, [t*(1-t^2)]), domain(phi)) phi_res = restrict(phi, domain(phi), domain(psi)) #psi_res = restrict(psi, domain(psi), domain(phi)) p = compose(psi, phi) @@ -111,8 +111,8 @@ end @testset "restriction_maps" begin R, (x, y, z) = QQ["x", "y", "z"] - X = Spec(R, ideal(R, x*y)) - U = SpecOpen(X, [x^7, y^8]) + X = spec(R, ideal(R, x*y)) + U = AffineSchemeOpenSubscheme(X, [x^7, y^8]) f = OO(U)([7*x//x^2, 5*y//y^2]) h = 5*x - 7*y+ 98*x*y^4 V = hypersurface_complement(X, h) @@ -122,8 +122,8 @@ end LY = U[2] @test f[LX] == OO(LX)(result) && f[U[2]] == OO(U[2])(result) - X = Spec(R, ideal(R, x*(x+1)-y*z)) - U = SpecOpen(X, [y^9, (x+1)^3]) + X = spec(R, ideal(R, x*(x+1)-y*z)) + U = AffineSchemeOpenSubscheme(X, [y^9, (x+1)^3]) f = OO(U)([x//y, z//(x+1)]) h = 3*y + x+1 V = hypersurface_complement(X, h) @@ -131,7 +131,7 @@ end result = pb(f) @test f[U[1]] == OO(U[1])(result) && f[U[2]] == OO(U[2])(result) - V = SpecOpen(X, [((x+1)-y)^7, ((x+1)+y)^5]) + V = AffineSchemeOpenSubscheme(X, [((x+1)-y)^7, ((x+1)+y)^5]) resUV = restriction_map(U, V) resVU = restriction_map(V, U) resVU(resUV(f)) == f @@ -140,16 +140,16 @@ end end @testset "pullbacks" begin R, (x,y,z) = QQ["x", "y", "z"] - X = Spec(R, ideal(R, [x^2-y*z])) - U = SpecOpen(X, [x, y]) - V = SpecOpen(X, [(x+y)^2, x^2 - y^2, (x-y)^2]) - f = SpecOpenMor(U, V, [x, y, z]) + X = spec(R, ideal(R, [x^2-y*z])) + U = AffineSchemeOpenSubscheme(X, [x, y]) + V = AffineSchemeOpenSubscheme(X, [(x+y)^2, x^2 - y^2, (x-y)^2]) + f = AffineSchemeOpenSubschemeMor(U, V, [x, y, z]) f[affine_patches(domain(f))[1]] pbf = pullback(f) @test pbf(OO(V)(x)) == OO(V)(x) @test pbf(OO(V)(y)) == OO(V)(y) @test pbf(OO(V)(z)) == OO(V)(z) - g = SpecOpenMor(V, U, [x, y, z]) + g = AffineSchemeOpenSubschemeMor(V, U, [x, y, z]) @test Oscar.is_identity_map(compose(pullback(f), pullback(g))) @test Oscar.is_identity_map(pullback(compose(f,g))) W = subscheme(X, x) @@ -158,10 +158,10 @@ end S, (u, v) = QQ["u", "v"] - B = Spec(S) + B = spec(S) p = morphism(X, B, [x, y]) - U = SpecOpen(X, [x, y]) - V = SpecOpen(B, [u, v]) + U = AffineSchemeOpenSubscheme(X, [x, y]) + V = AffineSchemeOpenSubscheme(B, [u, v]) pres = restrict(p, U, V) @test U == preimage(p, V) @@ -171,13 +171,13 @@ end @test g(OO(V)(v)) == OO(U)(y) end -@testset "SpecOpenRings" begin +@testset "AffineSchemeOpenSubschemeRings" begin R, (x, y, z) = QQ["x", "y", "z"] I = ideal(R, [x^2-y*z]) - X = Spec(R, I) - U = SpecOpen(X, [x, y]) + X = spec(R, I) + U = AffineSchemeOpenSubscheme(X, [x, y]) subscheme(U, ideal(R,[x,y])) - V = SpecOpen(X, [x+y, x^2 - y^2, (x-y)^5]) + V = AffineSchemeOpenSubscheme(X, [x+y, x^2 - y^2, (x-y)^5]) f = canonical_isomorphism(OO(U), OO(V)) a = OO(U)([x//y, z//x]) b = f(a) @@ -186,25 +186,25 @@ end @testset "restriction map" begin R, (x, y) = QQ["x", "y", "z"] - X = Spec(R) - U = SpecOpen(X,[x]) + X = spec(R) + U = AffineSchemeOpenSubscheme(X,[x]) restriction_map(U, hypersurface_complement(X,x)) end @testset "is_subscheme" begin R, (x, y) = QQ["x", "y", "z"] - # Spec{..., MPolyRing} - A2 = Spec(R) - # Spec{..., MPolyQuoRing} + # AffineScheme{..., MPolyRing} + A2 = spec(R) + # AffineScheme{..., MPolyQuoRing} Vxy = subscheme(A2, x*y) - # Spec{MPolyLocRing} + # AffineScheme{MPolyLocRing} A2_minus_Vxy = hypersurface_complement(A2, x*y) A2_minus_Vxy_p = PrincipalOpenSubset(A2, x*y) - # SpecOpen{Spec{...,MPolyRing},...} - A2_minus_origin = SpecOpen(A2, [x,y]) - # SpecOpen{Spec{MPolyQuoRing},...} - Vxy_minus_origin = SpecOpen(Vxy, [x,y]) + # AffineSchemeOpenSubscheme{AffineScheme{...,MPolyRing},...} + A2_minus_origin = AffineSchemeOpenSubscheme(A2, [x,y]) + # AffineSchemeOpenSubscheme{AffineScheme{MPolyQuoRing},...} + Vxy_minus_origin = AffineSchemeOpenSubscheme(Vxy, [x,y]) # PrincipalOpenSubset{MPolyQuoLocalized....} Vxy_minus_origin_p = PrincipalOpenSubset(Vxy, OO(Vxy)(x+y)) @@ -266,17 +266,17 @@ end @testset "is_open_embedding" begin R, (x, y) = QQ["x", "y", "z"] - # Spec{..., MPolyRing} - A2 = Spec(R) - # Spec{..., MPolyQuoRing} + # AffineScheme{..., MPolyRing} + A2 = spec(R) + # AffineScheme{..., MPolyQuoRing} Vxy = subscheme(A2, x*y) - # Spec{MPolyLocRing} + # AffineScheme{MPolyLocRing} A2_minus_Vxy = hypersurface_complement(A2, x*y) A2_minus_Vxy_p = PrincipalOpenSubset(A2, x*y) - # SpecOpen{Spec{...,MPolyRing},...} - A2_minus_origin = SpecOpen(A2, [x,y]) - # SpecOpen{Spec{MPolyQuoRing},...} - Vxy_minus_origin = SpecOpen(Vxy, [x,y]) + # AffineSchemeOpenSubscheme{AffineScheme{...,MPolyRing},...} + A2_minus_origin = AffineSchemeOpenSubscheme(A2, [x,y]) + # AffineSchemeOpenSubscheme{AffineScheme{MPolyQuoRing},...} + Vxy_minus_origin = AffineSchemeOpenSubscheme(Vxy, [x,y]) # PrincipalOpenSubset{MPolyQuoLocalized....} Vxy_minus_origin_p = PrincipalOpenSubset(Vxy, OO(Vxy)(x+y)) @@ -340,17 +340,17 @@ end @testset "is_closed_embedding" begin R, (x, y) = QQ["x", "y", "z"] - # Spec{..., MPolyRing} - A2 = Spec(R) - # Spec{..., MPolyQuoRing} + # AffineScheme{..., MPolyRing} + A2 = spec(R) + # AffineScheme{..., MPolyQuoRing} Vxy = subscheme(A2, x*y) - # Spec{MPolyLocRing} + # AffineScheme{MPolyLocRing} A2_minus_Vxy = hypersurface_complement(A2, x*y) A2_minus_Vxy_p = PrincipalOpenSubset(A2, x*y) - # SpecOpen{Spec{...,MPolyRing},...} - A2_minus_origin = SpecOpen(A2, [x,y]) - # SpecOpen{Spec{MPolyQuoRing},...} - Vxy_minus_origin = SpecOpen(Vxy, [x,y]) + # AffineSchemeOpenSubscheme{AffineScheme{...,MPolyRing},...} + A2_minus_origin = AffineSchemeOpenSubscheme(A2, [x,y]) + # AffineSchemeOpenSubscheme{AffineScheme{MPolyQuoRing},...} + Vxy_minus_origin = AffineSchemeOpenSubscheme(Vxy, [x,y]) # PrincipalOpenSubset{MPolyQuoLocalized....} Vxy_minus_origin_p = PrincipalOpenSubset(Vxy, OO(Vxy)(x+y)) @@ -416,8 +416,8 @@ end R, (x,y) = QQ["x", "y"] I = ideal(R, x) Q, _ = quo(R, I) - X = Spec(Q) - U = SpecOpen(X, [y]) + X = spec(Q) + U = AffineSchemeOpenSubscheme(X, [y]) W = OO(U) P, (u,v) = W["u", "v"] diff --git a/test/AlgebraicGeometry/Schemes/AffineSchemes.jl b/test/AlgebraicGeometry/Schemes/AffineSchemes.jl index a4e6f9165c63..0d9a8f571903 100644 --- a/test/AlgebraicGeometry/Schemes/AffineSchemes.jl +++ b/test/AlgebraicGeometry/Schemes/AffineSchemes.jl @@ -58,7 +58,7 @@ @test closure(UZ, X)==Z S, (u,v) = QQ["u", "v"] - A2 = Spec(S) + A2 = spec(S) set_name!(A2, "𝔸²") @test OO(UX)(y//z) == OO(UX)(z//x) phi = morphism(UX, A2, [y//z, z]) @@ -87,7 +87,7 @@ end # ideal or powers of an element @testset "dimensions of affine schemes" begin R, (x,y,z) = QQ["x", "y", "z"] - A3 = Spec(R) + A3 = spec(R) X = subscheme(A3, x*y) U = hypersurface_complement(A3, z) @test dim(A3) == 3 @@ -100,7 +100,7 @@ end plane = hypersurface_complement(disjoint_plane_and_line, y) @test dim(line) == 1 @test dim(plane) == 2 - A3_localized_along_line = Spec(localization(R, complement_of_prime_ideal(ideal(R, [x, y])))[1]) + A3_localized_along_line = spec(localization(R, complement_of_prime_ideal(ideal(R, [x, y])))[1]) @test dim(A3_localized_along_line) == 2 @test dim(Oscar.standard_spec(A3_localized_along_line)) == 2 @@ -108,12 +108,12 @@ end I = ideal(R, [x-1, y-1])*ideal(R, z) L, _ = localization(R, S) W, _ = quo(L, L(I)) - @test dim(Spec(W)) == 1 + @test dim(spec(W)) == 1 end @testset "dimensions of affine schemes over the integers" begin R, (x,y,z) = ZZ["x", "y", "z"] - A3 = Spec(R) + A3 = spec(R) X = subscheme(A3, x*y) U = hypersurface_complement(A3, z) @test dim(A3) == 4 @@ -125,30 +125,30 @@ end plane = hypersurface_complement(disjoint_plane_and_line, y) @test dim(line) == 2 @test dim(plane) == 3 - A3_localized_along_line = Spec(localization(R, complement_of_prime_ideal(ideal(R, [x, y])))[1]) + A3_localized_along_line = spec(localization(R, complement_of_prime_ideal(ideal(R, [x, y])))[1]) @test dim(A3_localized_along_line) == 2 @test dim(Oscar.standard_spec(A3_localized_along_line)) == 2 P = ideal(R, R(5)) @test is_prime(P) S = complement_of_prime_ideal(P) - Y = Spec(R, S) + Y = spec(R, S) @test dim(Y) == 1 Q = ideal(R, R.([7, x, y, z])) S = complement_of_prime_ideal(Q) - Z = Spec(R, S) + Z = spec(R, S) @test dim(Z) == 4 S = complement_of_point_ideal(R, [1, 1, 1]) I = ideal(R, [x-1, y-1])*ideal(R, z) L, _ = localization(R, S) W, _ = quo(L, L(I)) - @test dim(Spec(W)) == 1 + @test dim(spec(W)) == 1 end @testset "dimensions of affine schemes over quotients of the integers" begin kk, _ = quo(ZZ, 4) R, (x,y,z) = kk["x", "y", "z"] - A3 = Spec(R) + A3 = spec(R) X = subscheme(A3, x*y) U = hypersurface_complement(A3, z) @test dim(A3) == 3 @@ -169,20 +169,20 @@ end M = R[x y+1 z-2 x+y; y z-3 x-y+5 y-z; z x-y z-2 x+y+z] I = ideal(R, minors(M, 3)) Q, _ = quo(R, I) - X = Spec(Q) + X = spec(Q) @test is_smooth(X) end -@testset "AbsSpec interface" begin +@testset "AbsAffineScheme interface" begin R, (x,y,z) = QQ["x", "y", "z"] - A3 = Spec(R) + A3 = spec(R) set_name!(A3, "𝔸³") f = x*y-z^2 I = ideal(R, f) S = powers_of_element(x) - Spec(R,S) + spec(R,S) S = complement_of_prime_ideal(I) - Spec(R,I) + spec(R,I) X = subscheme(A3, I) set_name!(X, "X") @test iszero(OO(X)(f)) @@ -215,18 +215,18 @@ end inclusion_morphism(A3,A3) end -@testset "Spec ZZ" begin - Spec(ZZ) - Spec(QQ) +@testset "spec ZZ" begin + spec(ZZ) + spec(QQ) end @testset "fiber product" begin R, _ = QQ["x","t"] S, _ = QQ["y","t"] T, _ = polynomial_ring(QQ,["t"]) - X = Oscar.standard_spec(Spec(R)) - Y = Oscar.standard_spec(Spec(S)) - B = Oscar.standard_spec(Spec(T)) + X = Oscar.standard_spec(spec(R)) + Y = Oscar.standard_spec(spec(S)) + B = Oscar.standard_spec(spec(T)) phi1 = hom(OO(B), OO(X), [gens(OO(X))[2]]) phi2 = hom(OO(B), OO(Y), [gens(OO(Y))[2]]) Phi1 = morphism(X, B, phi1) @@ -234,13 +234,13 @@ end Z = fiber_product(Phi1, Phi2)[1] A = ambient_coordinate_ring(Z) a = gens(A) - fib = subscheme(Spec(A), ideal(A, [a[2]-a[4]])) + fib = subscheme(spec(A), ideal(A, [a[2]-a[4]])) @test fib==Z end @testset "ClosedEmbedding" begin R, (x, y) = QQ["x", "y"] - X = Spec(R) + X = spec(R) h = x^2 + y^2 -1 I = ideal(R, [h]) Y, inc = sub(X, I) @@ -249,7 +249,7 @@ end @test pullback(inc)(x) == OO(Y)(x) @test pullback(inc)(y) == OO(Y)(y) @test image_ideal(inc) == modulus(OO(Y)) - @test complement(inc) == SpecOpen(X, [h]) + @test complement(inc) == AffineSchemeOpenSubscheme(X, [h]) end @testset "fix for is_smooth" begin @@ -258,7 +258,7 @@ end I2 = ideal(R, [z]); I3 = ideal(R, [x, z-1]) I = intersect(I1, I2, I3) - X = Spec(R, I) + X = spec(R, I) @test !is_smooth(X) end @@ -293,9 +293,9 @@ end UU, f = base_change(pr, U) @test UU isa PrincipalOpenSubset - W = SpecOpen(IA2, [x, y]) + W = AffineSchemeOpenSubscheme(IA2, [x, y]) WW, f = base_change(pr, W) - @test WW isa SpecOpen + @test WW isa AffineSchemeOpenSubscheme end @testset "principal open embeddings" begin @@ -357,4 +357,3 @@ end @test is_isomorphism(h) @test compose(p1, there) == compose(p2, there) end - diff --git a/test/AlgebraicGeometry/Schemes/AffineVariety.jl b/test/AlgebraicGeometry/Schemes/AffineVariety.jl index c611380c9e93..ba8c3ba8360d 100644 --- a/test/AlgebraicGeometry/Schemes/AffineVariety.jl +++ b/test/AlgebraicGeometry/Schemes/AffineVariety.jl @@ -6,7 +6,7 @@ P, (x,y) = polynomial_ring(QQ, [:x, :y]) p = x^2 + y^2 + 1 X = variety(p) - Y = variety(Spec(P, ideal([p^2]))) + Y = variety(spec(P, ideal([p^2]))) @test X == Y q = x^2 + y^2 # irreducible but not geometrically irreducible. @test_throws ErrorException variety(q) diff --git a/test/AlgebraicGeometry/Schemes/BlowupMorphism.jl b/test/AlgebraicGeometry/Schemes/BlowupMorphism.jl index 42c723899844..57797f80da96 100644 --- a/test/AlgebraicGeometry/Schemes/BlowupMorphism.jl +++ b/test/AlgebraicGeometry/Schemes/BlowupMorphism.jl @@ -1,7 +1,7 @@ @testset "basics about blowups" begin R, (x,y,z) = QQ["x", "y", "z"] f = x^2 + y^3 + z^5 - X = CoveredScheme(Spec(R, ideal(R, f))) + X = CoveredScheme(spec(R, ideal(R, f))) U = X[1][1] # the first chart IZ = IdealSheaf(X, U, OO(U).([x, y, z])) @@ -66,7 +66,7 @@ end C_up, inc_C_up, p_res = strict_transform(p, inc_C) @test is_isomorphism(Oscar.isomorphism_on_open_subset(p_res)) - + KC_up = function_field(C_up) KC = function_field(C) aa = KC(a[affine_charts(Y)[3]]) diff --git a/test/AlgebraicGeometry/Schemes/CartierDivisor.jl b/test/AlgebraicGeometry/Schemes/CartierDivisor.jl index 03d78ac24364..ff96a5f79d8c 100644 --- a/test/AlgebraicGeometry/Schemes/CartierDivisor.jl +++ b/test/AlgebraicGeometry/Schemes/CartierDivisor.jl @@ -11,7 +11,7 @@ X = covered_scheme(P) - D = IdDict{AbsSpec, RingElem}() + D = IdDict{AbsAffineScheme, RingElem}() H = x^2 + y^2 + z^2 for U in affine_charts(X) D[U] = dehomogenization_map(P, U)(H) diff --git a/test/AlgebraicGeometry/Schemes/CoherentSheaves.jl b/test/AlgebraicGeometry/Schemes/CoherentSheaves.jl index c6f0db690bd1..131a37192bbf 100644 --- a/test/AlgebraicGeometry/Schemes/CoherentSheaves.jl +++ b/test/AlgebraicGeometry/Schemes/CoherentSheaves.jl @@ -14,7 +14,7 @@ rrr = L(U21, W) @test rr == compose(rho, rrr) WW = simplify(W) - @test WW isa Oscar.SimplifiedSpec + @test WW isa Oscar.SimplifiedAffineScheme rrWW = L(U[1], WW) rrrWW = L(U21, WW) @test rrWW == compose(rho, rrrWW) @@ -24,7 +24,7 @@ @test rho(M1(U[1])[1]) in M1(U21) T = Oscar.tangent_sheaf(X) rho = T(U[1], U21) - g = rho(T(U[1])[1]) + g = rho(T(U[1])[1]) @test g in T(U21) @test element_to_homomorphism(g)(domain(T)(U21)[1]) in codomain(T)(U21) @@ -95,7 +95,7 @@ end @test rho isa ModuleFPHom # Test pullbacks along blowup maps. - # This is particularly simple, because the underlying CoveringMorphism + # This is particularly simple, because the underlying CoveringMorphism # of the projection map is given on the default_covering of its domain. J = ideal(S, [x-z, y]) JJ = IdealSheaf(IP, J) @@ -142,7 +142,7 @@ end I = ideal(R, [x-1, y]) * ideal(R, [x]) # A line and a plane, disjoint. - X = CoveredScheme(Spec(R, I)) + X = CoveredScheme(spec(R, I)) @test is_smooth(X) diff --git a/test/AlgebraicGeometry/Schemes/CoveredProjectiveSchemes.jl b/test/AlgebraicGeometry/Schemes/CoveredProjectiveSchemes.jl index 3991f685dc9b..f913c6bf2a5a 100644 --- a/test/AlgebraicGeometry/Schemes/CoveredProjectiveSchemes.jl +++ b/test/AlgebraicGeometry/Schemes/CoveredProjectiveSchemes.jl @@ -15,7 +15,7 @@ end @testset "Oscar.blow_up_chart" begin R, (x,y,z) = QQ["x", "y", "z"] - A3 = Spec(R) + A3 = spec(R) M = R[x y z; y-1 z-2 x-3] I = ideal(R, minors(M, 2)) BlA3 = Oscar.blow_up_chart(A3, I) @@ -34,12 +34,12 @@ end @testset "winter school presentation" begin P, (x,y,z) = QQ["x", "y", "z"] - IA3 = Spec(P) + IA3 = spec(P) f = x^2-y*z^2 I = ideal(P, f) X = subscheme(IA3, I) S, inc = singular_locus(X); - @test S isa AbsSpec + @test S isa AbsAffineScheme @test inc isa ClosedEmbedding B1 = Oscar.blow_up_chart(X, ideal(OO(X), [x,y,z])) @test B1 isa AbsProjectiveScheme @@ -56,7 +56,7 @@ end @test is_smooth(Z) end -@testset "K3 surface reconstructed" begin +@testset "K3 surface reconstructed" begin IP1 = projective_space(GF(29), ["s", "t"]) O1 = twisting_sheaf(IP1, -1) diff --git a/test/AlgebraicGeometry/Schemes/CoveredScheme.jl b/test/AlgebraicGeometry/Schemes/CoveredScheme.jl index bdc8a28467fd..34a70ade8d9a 100644 --- a/test/AlgebraicGeometry/Schemes/CoveredScheme.jl +++ b/test/AlgebraicGeometry/Schemes/CoveredScheme.jl @@ -1,12 +1,12 @@ @testset "Covered schemes 1" begin R, (x,y) = polynomial_ring(QQ, ["x", "y"]) - X = subscheme(Spec(R), [x^2+y^2]) + X = subscheme(spec(R), [x^2+y^2]) P = projective_space(X, 3) S = homogeneous_coordinate_ring(P) (u, v) = gen(S, 1), gen(S, 2) - h = u^3 + h = u^3 h = u^3 + u^2 - h = u^3 + (u^2)*v + h = u^3 + (u^2)*v h = u^3 + u^2*v - OO(X)(x)*v^3 Z = subscheme(P, h) C = standard_covering(Z) @@ -25,7 +25,7 @@ end Y = subscheme(P, [x*z,y*z]) @test dim(covered_scheme(Y)) == 2 C = standard_covering(X) - D, i, j = simplify(C) + D, i, j = simplify(C) @test all( x->(ngens(ambient_coordinate_ring(x)) == 2), collect(D)) @test Oscar.transition_graph(Pc[1]) isa Graph @test Oscar.transition_graph(C) isa Graph @@ -33,7 +33,7 @@ end @testset "standard_covering" begin R, t = polynomial_ring(QQ,["t"]) - T = Oscar.standard_spec(subscheme(Spec(R),t)) + T = Oscar.standard_spec(subscheme(spec(R),t)) Pt= projective_space(T, 2) X = covered_scheme(Pt) @test dim(X) == 2 @@ -50,7 +50,7 @@ end R = base_ring(OO(Ccov[1][2])) L, _ = localization(R, R[1]) - @test Oscar.poly_type(Spec(R)) === Oscar.poly_type(Spec(L)) === Oscar.poly_type(Ccov[1][2]) + @test Oscar.poly_type(spec(R)) === Oscar.poly_type(spec(L)) === Oscar.poly_type(Ccov[1][2]) Lnew, f, g = simplify(L) @test !(L == Lnew) @test compose(f, g) == identity_map(L) @@ -59,7 +59,7 @@ end C1 = default_covering(Ccov) C2, f, g = simplify(C1) tmp1 = compose(f, g) - tmp2 = compose(g, f) + tmp2 = compose(g, f) @test domain(tmp1) === codomain(tmp1) === C2 @test domain(tmp2) === codomain(tmp2) === C1 @test length(C2) == 3 @@ -70,7 +70,7 @@ end U = C1[2] x = gens(ambient_coordinate_ring(U))[1] - W = SpecOpen(U, [x, x-1]) + W = AffineSchemeOpenSubscheme(U, [x, x-1]) W1, W2 = affine_patches(W) #add_affine_refinement!(C1, W) @@ -155,7 +155,7 @@ end @test is_integral(Ycov) R = forget_grading(S) - A = Spec(R) + A = spec(R) @test is_integral(A) @test is_integral(hypersurface_complement(A, R[1])) @@ -222,7 +222,7 @@ end kk, pr = quo(ZZ, 5) IP1 = covered_scheme(projective_space(ZZ, 1)) IP1_red, red_map = base_change(pr, IP1) - + IP2 = projective_space(ZZ, 2) S = homogeneous_coordinate_ring(IP2) (x, y, z) = gens(S) @@ -246,7 +246,7 @@ end x, y, z = gens(OO(U)) V2 = PrincipalOpenSubset(U, x) V1 = PrincipalOpenSubset(U, x-1) - new_cov = Covering(append!(AbsSpec[V1, V2], patches(orig_cov)[2:end])) + new_cov = Covering(append!(AbsAffineScheme[V1, V2], patches(orig_cov)[2:end])) Oscar.inherit_gluings!(new_cov, orig_cov) Oscar.inherit_decomposition_info!(X, new_cov, orig_cov=orig_cov) @test Oscar.decomposition_info(new_cov)[V2] == [OO(V2)(x-1)] diff --git a/test/AlgebraicGeometry/Schemes/FunctionFields.jl b/test/AlgebraicGeometry/Schemes/FunctionFields.jl index 5ea930efd022..ea77b8a14934 100644 --- a/test/AlgebraicGeometry/Schemes/FunctionFields.jl +++ b/test/AlgebraicGeometry/Schemes/FunctionFields.jl @@ -1,10 +1,10 @@ @testset "fraction fields of varieties" begin R, (x,y,z) = QQ["x", "y", "z"] - @test is_irreducible(Spec(R)) - @test is_irreducible(Spec(R, ideal(R, x))) - @test !is_irreducible(Spec(R, ideal(R, x*y))) - @test is_irreducible(Spec(localization(R, units_of(R))[1])) - @test !is_irreducible(Spec(R, ideal(R, x*y), units_of(R))) + @test is_irreducible(spec(R)) + @test is_irreducible(spec(R, ideal(R, x))) + @test !is_irreducible(spec(R, ideal(R, x*y))) + @test is_irreducible(spec(localization(R, units_of(R))[1])) + @test !is_irreducible(spec(R, ideal(R, x*y), units_of(R))) P = projective_space(QQ, 2) S = homogeneous_coordinate_ring(P) @@ -27,7 +27,7 @@ end # Set up the base ℙ¹ with coordinates s and t S, _ = graded_polynomial_ring(kk, ["s", "t"]) - base_P1 = ProjectiveScheme(S) + base_P1 = proj(S) # split this into the standard covering base_covering = standard_covering(base_P1) @@ -35,7 +35,7 @@ end A1s = patches(base_covering)[1] A1t = patches(base_covering)[2] - # Set up relative projective space of relative dimension 2 + # Set up relative projective space of relative dimension 2 # over both base patches P2_s = projective_space(OO(A1s), ["xs", "ys", "zs"]) @@ -45,7 +45,7 @@ end Ct = standard_covering(P2_t) - # Join the resulting schemes in a disjoint union with two + # Join the resulting schemes in a disjoint union with two # components C = disjoint_union(Cs, Ct) diff --git a/test/AlgebraicGeometry/Schemes/Gluing.jl b/test/AlgebraicGeometry/Schemes/Gluing.jl index 10043f55f784..19605ad296d9 100644 --- a/test/AlgebraicGeometry/Schemes/Gluing.jl +++ b/test/AlgebraicGeometry/Schemes/Gluing.jl @@ -1,16 +1,16 @@ @testset "gluings" begin R, (x,y,z) = QQ["x", "y", "z"] - A3 = Spec(R) + A3 = spec(R) set_name!(A3, "𝔸³") f = (x*y-z^2) #f = (x*y-z^2)*(x+y+2*z) X = subscheme(A3, f) set_name!(X, "X") - U = SpecOpen(A3, [x,y,z]) + U = AffineSchemeOpenSubscheme(A3, [x,y,z]) UX = intersect(X, U) d = Oscar.find_non_zero_divisor(UX) S, (u,v) = QQ["u", "v"] - A2 = Spec(S) + A2 = spec(S) set_name!(A2, "𝔸²") f = maximal_extension(X, A2, [x, z//y]) a = Oscar.generic_fractions(f) @@ -20,9 +20,9 @@ Sy, (xy, zy) = QQ["xy", "zy"] Sz, (xz, yz) = QQ["xz", "yz"] - Ax = Spec(Sx) - Ay = Spec(Sy) - Az = Spec(Sz) + Ax = spec(Sx) + Ay = spec(Sy) + Az = spec(Sz) fxy = maximal_extension(Ax, Ay, [1//yx, zx//yx]) fyx = maximal_extension(Ay, Ax, [1//xy, zy//xy]) @@ -44,9 +44,9 @@ end S, (u, v) = QQ["u", "v"] T, (a, b) = QQ["a", "b"] - X = Spec(R) - Y = Spec(S) - Z = Spec(T) + X = spec(R) + Y = spec(S) + Z = spec(T) Ux = PrincipalOpenSubset(X, x) Vu = PrincipalOpenSubset(Y, u) @@ -66,15 +66,15 @@ end f = morphism(Vv, Wb, [u, 1//v]) g = morphism(Wb, Vv, [a, 1//b]) - Vvo = SpecOpen(Vv) - Wbo = SpecOpen(Wb) + Vvo = AffineSchemeOpenSubscheme(Vv) + Wbo = AffineSchemeOpenSubscheme(Wb) simpleG2 = SimpleGluing(Y, Z, f, g) @test compose(simpleG, simpleG2) == compose(simpleG, inverse(simpleG2)) @test compose(inverse(simpleG), simpleG2) == compose(simpleG, inverse(simpleG2)) @test compose(inverse(simpleG), inverse(simpleG2)) == compose(simpleG, inverse(simpleG2)) - G2 = Gluing(Y, Z, - SpecOpenMor(Vvo, Wbo, [compose(f, inclusion_morphism(Wb, Z))]), - SpecOpenMor(Wbo, Vvo, [compose(g, inclusion_morphism(Vv, Y))])) + G2 = Gluing(Y, Z, + AffineSchemeOpenSubschemeMor(Vvo, Wbo, [compose(f, inclusion_morphism(Wb, Z))]), + AffineSchemeOpenSubschemeMor(Wbo, Vvo, [compose(g, inclusion_morphism(Vv, Y))])) G3 = compose(G1, G2) @test G3 == compose(G1, inverse(G2)) @@ -87,15 +87,15 @@ end ### test the abstract interface @attributes mutable struct DummyGluing{ - LeftSpecType<:AbsSpec, - RightSpecType<:AbsSpec, - LeftOpenType<:SpecOpen, - RightOpenType<:SpecOpen, - LeftMorType<:SpecOpenMor, - RightMorType<:SpecOpenMor + LeftAffineSchemeType<:AbsAffineScheme, + RightAffineSchemeType<:AbsAffineScheme, + LeftOpenType<:AffineSchemeOpenSubscheme, + RightOpenType<:AffineSchemeOpenSubscheme, + LeftMorType<:AffineSchemeOpenSubschemeMor, + RightMorType<:AffineSchemeOpenSubschemeMor } <: AbsGluing{ - LeftSpecType, - RightSpecType, + LeftAffineSchemeType, + RightAffineSchemeType, LeftOpenType, RightOpenType, LeftMorType, diff --git a/test/AlgebraicGeometry/Schemes/IdealSheaves.jl b/test/AlgebraicGeometry/Schemes/IdealSheaves.jl index 55cffa849088..62a7a0607361 100644 --- a/test/AlgebraicGeometry/Schemes/IdealSheaves.jl +++ b/test/AlgebraicGeometry/Schemes/IdealSheaves.jl @@ -4,7 +4,7 @@ # Set up the base ℙ¹ with coordinates s and t S, _ = graded_polynomial_ring(kk, ["s", "t"]) - base_P1 = ProjectiveScheme(S) + base_P1 = proj(S) # split this into the standard covering base_covering = standard_covering(base_P1) @@ -12,7 +12,7 @@ A1s = patches(base_covering)[1] A1t = patches(base_covering)[2] - # Set up relative projective space of relative dimension 2 + # Set up relative projective space of relative dimension 2 # over both base patches P2_s = projective_space(OO(A1s), ["xs", "ys", "zs"]) @@ -22,7 +22,7 @@ Ct = standard_covering(P2_t) - # Join the resulting schemes in a disjoint union with two + # Join the resulting schemes in a disjoint union with two # components C = disjoint_union(Cs, Ct) @@ -61,9 +61,9 @@ end I3 = IdealSheaf(IP2, gen(Ihom, 1)) @test I == I2 == I3 U = patches(default_covering(X)) - @test I(U[1]) isa Oscar.Ideal - @test I(U[2]) isa Oscar.Ideal - @test I(U[3]) isa Oscar.Ideal + @test I(U[1]) isa Oscar.Ideal + @test I(U[2]) isa Oscar.Ideal + @test I(U[3]) isa Oscar.Ideal V = PrincipalOpenSubset(U[1], gens(OO(U[1]))[1]) rho = I(U[1], V) @test I(V) == ideal(OO(V), rho.(gens(I(U[1])))) @@ -71,7 +71,7 @@ end simplify!(I) # run the check block in extend! - ID = IdDict{AbsSpec, Oscar.Ideal}() + ID = IdDict{AbsAffineScheme, Oscar.Ideal}() ID[X[1][1]] = I(X[1][1]) J = IdealSheaf(X, extend!(default_covering(X), ID), check=true) ID[X[1][1]] = I(X[1][1]) diff --git a/test/AlgebraicGeometry/Schemes/K3.jl b/test/AlgebraicGeometry/Schemes/K3.jl index dd27c40a4756..0a35c483eec7 100644 --- a/test/AlgebraicGeometry/Schemes/K3.jl +++ b/test/AlgebraicGeometry/Schemes/K3.jl @@ -131,7 +131,7 @@ # # ref_patches = [x for x in U if !(x===V1) && !(x===V2)] # -# id_dict = IdDict{AbsSpec, Ideal}() +# id_dict = IdDict{AbsAffineScheme, Ideal}() # for x in ref_patches # id_dict[x] = I_sing_X4(x) # end diff --git a/test/AlgebraicGeometry/Schemes/MorphismFromRationalFunctions.jl b/test/AlgebraicGeometry/Schemes/MorphismFromRationalFunctions.jl index 6d835ae148ca..28443b181e9e 100644 --- a/test/AlgebraicGeometry/Schemes/MorphismFromRationalFunctions.jl +++ b/test/AlgebraicGeometry/Schemes/MorphismFromRationalFunctions.jl @@ -78,7 +78,7 @@ end Oscar.inherit_gluings!(dom_cov, default_covering(X)) Oscar.inherit_gluings!(cod_cov, default_covering(X)) - mor_dict = IdDict{AbsSpec, AbsSpecMor}() + mor_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for phi in realizations mor_dict[domain(phi)] = phi end @@ -101,7 +101,7 @@ end Oscar.inherit_gluings!(dom_cov, default_covering(X)) Oscar.inherit_gluings!(cod_cov, default_covering(X)) - mor_dict = IdDict{AbsSpec, AbsSpecMor}() + mor_dict = IdDict{AbsAffineScheme, AbsAffineSchemeMor}() for phi in realizations mor_dict[domain(phi)] = phi end diff --git a/test/AlgebraicGeometry/Schemes/ProjectiveSchemes.jl b/test/AlgebraicGeometry/Schemes/ProjectiveSchemes.jl index 47c5ec8fdac0..686a20c5ecf8 100644 --- a/test/AlgebraicGeometry/Schemes/ProjectiveSchemes.jl +++ b/test/AlgebraicGeometry/Schemes/ProjectiveSchemes.jl @@ -4,7 +4,7 @@ S, (u,v) = graded_polynomial_ring(R, ["u", "v"]) I = ideal(S, [x*v - y*u]) - X = ProjectiveScheme(S, I) + X = proj(S, I) CX, id = affine_cone(X) p = covered_projection_to_base(X) @test OO(CX).(Oscar.homogeneous_coordinates_on_affine_cone(X)) == [id(g) for g in gens(S)] @@ -19,7 +19,7 @@ S, (u,v) = graded_polynomial_ring(QQ, ["u", "v"]) I = ideal(S, [u]) - X = ProjectiveScheme(S, I) + X = proj(S, I) CX, id = affine_cone(X) @test OO(CX).(Oscar.homogeneous_coordinates_on_affine_cone(X)) == [id(g) for g in gens(S)] hc = Oscar.homogeneous_coordinates_on_affine_cone(X) @@ -31,10 +31,10 @@ #@test is_well_defined(phi) # deprecated # test for relative projective space over MPolyQuoLocalizedRings - Y = Spec(R) + Y = spec(R) Q = OO(Y) S, (u,v) = graded_polynomial_ring(Q, ["u", "v"]) - X = ProjectiveScheme(S) + X = proj(S) phi = ProjectiveSchemeMor(X, X, [u^2, v^2]) @@ -46,8 +46,8 @@ end @testset "projective_schemes_2" begin R, (x, y, z) = QQ["x", "y", "z"] I = ideal(R, [x^2-y*z]) - X = Spec(R, I) - U = SpecOpen(X, [x, y]) + X = spec(R, I) + U = AffineSchemeOpenSubscheme(X, [x, y]) P = projective_space(OO(U), 1) S = homogeneous_coordinate_ring(P) Y = subscheme(P, [OO(U)(x)*S[1]- OO(U)(y)*S[2], OO(U)(z)*S[1] - OO(U)(x)*S[2]]) # Coercion needs to be carried out manually. @@ -72,11 +72,11 @@ end @testset "singular schemes" begin A, (x, y, z) = grade(QQ["x", "y", "z"][1]); B, _ = quo(A, ideal(A, [x^2 + y^2])); - C = projective_scheme(B) + C = proj(B) @test !is_smooth(C; algorithm=:projective_jacobian) - C = projective_scheme(B) + C = proj(B) @test !is_smooth(C; algorithm=:covered_jacobian) - C = projective_scheme(B) + C = proj(B) @test !is_smooth(C; algorithm=:affine_cone) end @@ -186,12 +186,12 @@ end @test sprint(show, IP2_U) isa String @test sprint(show, IP2_UY) isa String - W = SpecOpen(UY, [x-1, y-1]) + W = AffineSchemeOpenSubscheme(UY, [x-1, y-1]) IP2_W = projective_space(W, 2, var_name="w") CW = affine_cone(IP2_W) pCW = projection_to_base(IP2_W) - WY = SpecOpen(Y, [x-y, x+y-2]) + WY = AffineSchemeOpenSubscheme(Y, [x-y, x+y-2]) WtoWY = inclusion_morphism(W, WY) IP2_WY = projective_space(WY, 2, var_name="w") _, map = fiber_product(pullback(WtoWY), IP2_WY) @@ -273,17 +273,17 @@ end @testset "properties of projective schemes" begin R, (x,y,z) = QQ["x", "y", "z"] S, _ = grade(R) - X = ProjectiveScheme(S) + X = proj(S) I = ideal(S, x^2 - y*z) Q, _ = quo(S, I) - C = ProjectiveScheme(Q) + C = proj(Q) @test homogeneous_coordinate_ring(C) === Q @test dim(C) == 1 @test degree(C) == 2 @test is_smooth(C; algorithm=:projective_jacobian) - C = ProjectiveScheme(Q) + C = proj(Q) @test is_smooth(C; algorithm=:covered_jacobian) - C = ProjectiveScheme(Q) + C = proj(Q) @test is_smooth(C; algorithm=:affine_cone) @test arithmetic_genus(C) == 0 @@ -291,14 +291,14 @@ end S, _ = grade(R) I = ideal(S, [x^4 + y^4 + z^4 + w^4]) Q, _ = quo(S, I) - Y = ProjectiveScheme(Q) + Y = proj(Q) @test homogeneous_coordinate_ring(Y) === Q @test dim(Y) == 2 @test degree(Y) == 4 @test is_smooth(Y; algorithm=:projective_jacobian) - Y = ProjectiveScheme(Q) + Y = proj(Q) @test is_smooth(Y; algorithm=:covered_jacobian) - Y = ProjectiveScheme(Q) + Y = proj(Q) @test is_smooth(Y; algorithm=:affine_cone) @test arithmetic_genus(Y) == 1 @test is_reduced(Y) diff --git a/test/AlgebraicGeometry/Schemes/ProjectiveVarieties.jl b/test/AlgebraicGeometry/Schemes/ProjectiveVarieties.jl index 07303eec38e2..f6dafb63b944 100644 --- a/test/AlgebraicGeometry/Schemes/ProjectiveVarieties.jl +++ b/test/AlgebraicGeometry/Schemes/ProjectiveVarieties.jl @@ -3,7 +3,7 @@ p = x^2 + y^2 + z^2 X = variety(p) @test_throws ErrorException variety(p^2) - Y = projective_scheme(G, ideal([p^2])) + Y = proj(G, ideal([p^2])) @test X != Y Y1 = variety(ideal([p]),check=false) Y1 = variety(ideal([p]),check=true) diff --git a/test/AlgebraicGeometry/Schemes/Sheaves.jl b/test/AlgebraicGeometry/Schemes/Sheaves.jl index bdc25e9f152d..29fc0ad7abdf 100644 --- a/test/AlgebraicGeometry/Schemes/Sheaves.jl +++ b/test/AlgebraicGeometry/Schemes/Sheaves.jl @@ -1,19 +1,19 @@ -@testset "constant sheaf of integers on Spec" begin +@testset "constant sheaf of integers on AffineScheme" begin R, x = QQ["x", "y", "z"] - X = Spec(R) + X = spec(R) - is_open_func(U::AbsSpec, V::AbsSpec) = is_open_embedding(U, V) + is_open_func(U::AbsAffineScheme, V::AbsAffineScheme) = is_open_embedding(U, V) - function production_func(F::AbsPreSheaf, U::AbsSpec) + function production_func(F::AbsPreSheaf, U::AbsAffineScheme) return ZZ end - function restriction_func(F::AbsPreSheaf, V::AbsSpec, U::AbsSpec) + function restriction_func(F::AbsPreSheaf, V::AbsAffineScheme, U::AbsAffineScheme) return identity_map(ZZ) end const_sheaf_ZZ= PreSheafOnScheme(X, production_func, restriction_func, - OpenType=AbsSpec, OutputType=typeof(ZZ), + OpenType=AbsAffineScheme, OutputType=typeof(ZZ), RestrictionType=typeof(identity_map(ZZ)), is_open_func=is_open_func ) @@ -56,10 +56,10 @@ end h = compose(tmp1, tmp2) @test h(gens(OO(W))[1]) == gens(OO(W))[1] - O = SpecOpen(U[1], lifted_numerator.([yx*(yx-1), yx*(zx-1)])) + O = AffineSchemeOpenSubscheme(U[1], lifted_numerator.([yx*(yx-1), yx*(zx-1)])) @test F(U[1], O)(OO(U[1])[1]) == OO(O)(OO(U[1])[1]) @test F(U[2], O)(OO(U[2])[1]) == inv(OO(O)(OO(U[1])[1])) - + # To test the other gluings, we repeat the above with a new gluing. P = projective_space(QQ, 2) PC = covered_scheme(P) @@ -86,7 +86,7 @@ end @test rho(zy) == OO(W)(zx)*inv(OO(W)(yx)) rho2 = F(U[1], W) @test rho2.(gens(OO(U[1]))) == OO(W).(gens(OO(U[1]))) - + B = PrincipalOpenSubset(U[2], gens(OO(U[2]))[1]) eta = F(U[1], B) @test eta === F(U[1], B) @@ -96,8 +96,8 @@ end @test tmp2(gens(OO(B))[1])== inv(gens(OO(W))[1]) h = compose(tmp1, tmp2) @test h(gens(OO(W))[1]) == gens(OO(W))[1] - - O = SpecOpen(U[1], lifted_numerator.([yx*(yx-1), yx*(zx-1)])) + + O = AffineSchemeOpenSubscheme(U[1], lifted_numerator.([yx*(yx-1), yx*(zx-1)])) @test F(U[1], O)(OO(U[1])[1]) == OO(O)(OO(U[1])[1]) @test F(U[2], O)(OO(U[2])[1]) == inv(OO(O)(OO(U[1])[1])) @@ -106,7 +106,7 @@ end O2 = preimage(g, O) @test F(O2, O)(gens(OO(O2))[1]) == inv(OO(O)(OO(U[1])[1])) @test F(O, O2)(inv(OO(O)(OO(U[1])[1]))) == gens(OO(O2))[1] - O3 = SpecOpen(U[1], lifted_numerator.([yx*(yx-1)^3, yx*(zx-1)])) + O3 = AffineSchemeOpenSubscheme(U[1], lifted_numerator.([yx*(yx-1)^3, yx*(zx-1)])) @test F(O, O3)(one(OO(O))) == one(OO(O3)) @test F(O2, O3)(one(OO(O2))) == one(OO(O3)) end diff --git a/test/AlgebraicGeometry/Schemes/SimplifiedSpec.jl b/test/AlgebraicGeometry/Schemes/SimplifiedAffineScheme.jl similarity index 86% rename from test/AlgebraicGeometry/Schemes/SimplifiedSpec.jl rename to test/AlgebraicGeometry/Schemes/SimplifiedAffineScheme.jl index 4cbd746b004a..04a2f6f83bc2 100644 --- a/test/AlgebraicGeometry/Schemes/SimplifiedSpec.jl +++ b/test/AlgebraicGeometry/Schemes/SimplifiedAffineScheme.jl @@ -1,5 +1,5 @@ @testset "simplified spectra" begin - @test Oscar.SimplifiedSpec <: AbsSpec + @test Oscar.SimplifiedAffineScheme <: AbsAffineScheme IP = projective_space(QQ, 2) S = ambient_coordinate_ring(IP) (x,y,z) = gens(S) diff --git a/test/AlgebraicGeometry/Schemes/SpaceGerms.jl b/test/AlgebraicGeometry/Schemes/SpaceGerms.jl index 87e4a19f9ca8..1f12ffd02e6f 100644 --- a/test/AlgebraicGeometry/Schemes/SpaceGerms.jl +++ b/test/AlgebraicGeometry/Schemes/SpaceGerms.jl @@ -2,8 +2,8 @@ R, (x,y,z) = QQ["x", "y", "z"] I = ideal(R, [x^2 - y^2 + z^2]) J = ideal(R, [x-1, y-2]) - X = Spec(R, I*J, units_of(R)) - Y = Spec(R, I, units_of(R)) + X = spec(R, I*J, units_of(R)) + Y = spec(R, I, units_of(R)) X0 = SpaceGerm(X,[0,0,0]) X1 = SpaceGerm(X,[1,2,1]) Y0 = SpaceGerm(Y,[0,0,0]) @@ -21,13 +21,13 @@ @test isempty(Y1) @test milnor_number(Z0) == 1 @test milnor_number(Z1) == 0 - XG = Spec(R,I) + XG = spec(R,I) @test milnor_number(XG) == 1 K = ideal(R,[x^2+y^2-z^2,x*y]) - YG = Spec(R,K) + YG = spec(R,K) @test milnor_number(YG) == 5 K = ideal(R,[x*y,x^2+y^2-z^2]) - ZG = Spec(R,K) + ZG = spec(R,K) @test milnor_number(YG) == 5 end @@ -52,16 +52,16 @@ end @test_broken dim(Z) == 1 end -@testset "Space Germ constructors Spec-Ideal" begin +@testset "Space Germ constructors AffineScheme-Ideal" begin R, (x,y,z) = QQ["x", "y", "z"] J = ideal(R, [x-y]) U0 = Oscar.MPolyComplementOfKPointIdeal(R,[0,0,0]) U1 = Oscar.MPolyComplementOfKPointIdeal(R,[1,2,2]) - Xg = Spec(R) - Xgq = Spec(R,J) - Xl1 = Spec(R, U0) - Xl2 = Spec(R, U1) - Xlq = Spec(R, J ,U0) + Xg = spec(R) + Xgq = spec(R,J) + Xl1 = spec(R, U0) + Xl2 = spec(R, U1) + Xlq = spec(R, J ,U0) Yg = SpaceGerm(Xg,ideal(OO(Xg),[x,y,z])) Ygq = SpaceGerm(Xgq, ideal(OO(Xgq),[x,y,z])) Yl1 = SpaceGerm(Xl1, ideal(OO(Xl1),[x,y,z])) @@ -74,8 +74,8 @@ end S, (u,v,w) = QQ["u", "v", "w"] I = ideal(R, [x^2 - y^2 + z^2]) J = ideal(R, [x-1, y-2]) - X = Spec(R, I*J, units_of(R)) - Y = Spec(R, I, units_of(R)) + X = spec(R, I*J, units_of(R)) + Y = spec(R, I, units_of(R)) X0 = SpaceGerm(X,ideal(R,[x,y,z])) X1 = SpaceGerm(X,ideal(R,[x-1,y-2,z-2])) Y0 = SpaceGerm(Y,ideal(R,[x,y,z])) @@ -94,7 +94,7 @@ end Q,_= quo(R,ideal(R,[z-y])) I = ideal(R, [x^2 - y^2 + z^2]) J = ideal(R, [x-1, y-2]) - Z = Spec(R, ideal(R,[z-y])) + Z = spec(R, ideal(R,[z-y])) X = subscheme(Z, I*J) Y = subscheme(Z, I) @test_throws ErrorException("rings are incompatible") Z0 = SpaceGerm(Z,ideal(Q,[x,y,z])) @@ -111,8 +111,8 @@ end S, (u,v,w) = QQ["u", "v", "w"] I = ideal(R, [x^2 - y^2 + z^2]) J = ideal(R, [x-1, y-2]) - X = Spec(R, I*J, units_of(R)) - @test_throws ArgumentError("Base rings must be the same.") Spec(R,ideal(S,[u,v,w])) + X = spec(R, I*J, units_of(R)) + @test_throws ArgumentError("Base rings must be the same.") spec(R,ideal(S,[u,v,w])) @test_throws ErrorException("rings are not compatible") SpaceGerm(X,ideal(S,[u,v,w])) @test_throws ErrorException("the number of variables in the ring does not coincide with the number of coordinates") SpaceGerm(X,[1,1,1,1]) X0,phi0 = germ_at_point(X,ideal(R,[x,y,z])) @@ -165,18 +165,18 @@ end @test ambient_germ(X0) == X0 end -@testset "SpaceGerm from Spec" begin +@testset "SpaceGerm from AffineScheme" begin R, (x,y,z) = QQ["x", "y", "z"] I = ideal(R, [x^2 - y^2 + z^2]) J = ideal(R, [x-1, y-2]) K = ideal(R, [x,y]) L = ideal(R, [x,y,z^2]) - X = Spec(R, I*J, units_of(R)) - Y = Spec(R, I, units_of(R)) - Z = Spec(R, J ,units_of(R)) - W = Spec(R, K ,units_of(R)) - V = Spec(R, L ,units_of(R)) - SY = Spec(R, ideal(R,[x,y,z])) + X = spec(R, I*J, units_of(R)) + Y = spec(R, I, units_of(R)) + Z = spec(R, J ,units_of(R)) + W = spec(R, K ,units_of(R)) + V = spec(R, L ,units_of(R)) + SY = spec(R, ideal(R,[x,y,z])) X0 = SpaceGerm(X,[0,0,0]) Y0 = SpaceGerm(Y,[0,0,0]) Z0 = SpaceGerm(Z,[0,0,0]) diff --git a/test/AlgebraicGeometry/Schemes/SpecialTypes.jl b/test/AlgebraicGeometry/Schemes/SpecialTypes.jl index f4f50ac1c7f1..d8ae10c57939 100644 --- a/test/AlgebraicGeometry/Schemes/SpecialTypes.jl +++ b/test/AlgebraicGeometry/Schemes/SpecialTypes.jl @@ -1,6 +1,6 @@ @testset "tests for SpecialTypes.jl" begin R, (x,y,z) = QQ["x", "y", "z"] - X = Spec(R) + X = spec(R) h = x^2 - y^2 + z^2 - 1 U = PrincipalOpenSubset(X, h) @test complement_equations(U)[1] == h diff --git a/test/AlgebraicGeometry/Schemes/WeilDivisor.jl b/test/AlgebraicGeometry/Schemes/WeilDivisor.jl index 9cf8078eedfa..9639b5caed77 100644 --- a/test/AlgebraicGeometry/Schemes/WeilDivisor.jl +++ b/test/AlgebraicGeometry/Schemes/WeilDivisor.jl @@ -4,7 +4,7 @@ # Set up the base ℙ¹ with coordinates s and t S, (s, t) = graded_polynomial_ring(kk, ["s", "t"]) - base_P1 = ProjectiveScheme(S) + base_P1 = proj(S) # split this into the standard covering bc = standard_covering(base_P1) @@ -12,7 +12,7 @@ A1s = patches(bc)[1] A1t = patches(bc)[2] - # Set up relative projective space of relative dimension 2 + # Set up relative projective space of relative dimension 2 # over both base patches P2_s = projective_space(OO(A1s), ["xs", "ys", "zs"]) @@ -22,7 +22,7 @@ Ct = standard_covering(P2_t) - # Join the resulting schemes in a disjoint union with two + # Join the resulting schemes in a disjoint union with two # components C = disjoint_union(Cs, Ct) @@ -49,7 +49,7 @@ Oscar.maximal_associated_points(I) D = WeilDivisor(I) E = WeilDivisor(J) - + @test D + 2*E == D + E + E KK = VarietyFunctionField(X) @@ -102,7 +102,7 @@ end @testset "orders on divisors" begin kk = QQ R, (s,t) = polynomial_ring(kk, ["s", "t"]) - X = Spec(R) + X = spec(R) Xc = CoveredScheme(X) KK = VarietyFunctionField(Xc) f = s^2 + t^2-1 @@ -157,7 +157,7 @@ end KK = function_field(X) U = X[1][2] u, v = gens(OO(U)) - f = KK(u, v) + f = KK(u, v) @test !in_linear_system(f, D) end @@ -177,7 +177,7 @@ end @test intersect(D2, D3) == 1 end -@testset "decomposition" begin +@testset "decomposition" begin P3 = projective_space(QQ, 3) S = homogeneous_coordinate_ring(P3) (x, y, z, w) = gens(S) diff --git a/test/AlgebraicGeometry/Schemes/duValSing.jl b/test/AlgebraicGeometry/Schemes/duValSing.jl index cf876d2912cc..dc1d62707811 100644 --- a/test/AlgebraicGeometry/Schemes/duValSing.jl +++ b/test/AlgebraicGeometry/Schemes/duValSing.jl @@ -2,8 +2,8 @@ R,(x,y,z,w) = QQ["x","y","z","w"] I = ideal(R,[w,(x^2+1)^2*x^3+(y^2+2)^3*y^2+z^4]) I2 = ideal(R,[w,x^2+y^2*z + z^7]) - X = Spec(quo(R,I)[1]) - X2 = Spec(quo(R,I2)[1]) + X = spec(quo(R,I)[1]) + X2 = spec(quo(R,I2)[1]) J1 = ideal(R,[x,y,z,w]) J2 = ideal(R,[x^2+1,y,z,w]) J3 = ideal(R,[x,y^2+2,z,w]) @@ -17,7 +17,7 @@ @test decide_du_val_singularity(X2,J1)[1][3] == (:D, 8) Rg,(x,y,z,w) = graded_polynomial_ring(QQ,["x","y","z","w"]) - X = projective_scheme(Rg) + X = proj(Rg) I = ideal(Rg,[x^2*w+y^2*z+z^3]) Y = subscheme(X,I) @test has_du_val_singularities(Y) == true diff --git a/test/AlgebraicGeometry/Schemes/singular_locus.jl b/test/AlgebraicGeometry/Schemes/singular_locus.jl index 43ed7e092db4..09bcb17acfd1 100644 --- a/test/AlgebraicGeometry/Schemes/singular_locus.jl +++ b/test/AlgebraicGeometry/Schemes/singular_locus.jl @@ -2,39 +2,39 @@ R, (x,y,z) = QQ["x", "y", "z"] I = ideal(R, [x^2 - y^2 + z^2]) J = ideal(R, [x-1, y-2]) - X = Spec(R, I*J, units_of(R)) + X = spec(R, I*J, units_of(R)) Z, _ = singular_locus(X) @test is_subscheme(subscheme(X, [x,y,z]), Z) @test is_subscheme(subscheme(X, [z^2-3, y-2, x-1]), Z) @test !is_smooth(X) - @test is_smooth(Spec(R)) - Y = Spec(R, ideal(R, [x^2 - y^2 + z^2 - 1])) + @test is_smooth(spec(R)) + Y = spec(R, ideal(R, [x^2 - y^2 + z^2 - 1])) @test is_smooth(Y) U1 = complement_of_point_ideal(R, [0, 0, 0]) - X1 = Spec(R, I * J, U1) + X1 = spec(R, I * J, U1) Z1, _ = singular_locus(X1) @test is_subscheme(subscheme(X1, [x, y, z]), Z1) - @test is_smooth(Spec(R, U1)) + @test is_smooth(spec(R, U1)) U2 = complement_of_point_ideal(R, [1, 1, 0]) - X2 = Spec(R, I * J, U2) + X2 = spec(R, I * J, U2) Z2, _ = singular_locus(X2) @test is_empty(Z2) @test is_smooth(X2) - X3 = Spec(R, ideal(R,[x,y,z]), units_of(R)) + X3 = spec(R, ideal(R,[x,y,z]), units_of(R)) is_smooth(X3) - @test singular_locus(Spec(R))[1] == Spec(R,ideal(R,[one(R)])) + @test singular_locus(spec(R))[1] == spec(R,ideal(R,[one(R)])) end @testset "singular_locus_reduced" begin R, (x,y,z) = QQ["x", "y", "z"] I = ideal(R, [(x^2 + y^2 + z^2)*(x-y)^2]) - X = Spec(R, I, units_of(R)) + X = spec(R, I, units_of(R)) Y, _ = singular_locus(X) Yr, _ = singular_locus_reduced(X) ISL1 = ideal(R, [x-y]) ISL2 = ideal(R, [x-y,2y^2+z^2]) - SL1 = Spec(R, ISL1,units_of(R)) - SL2= Spec(R,ISL2,units_of(R)) + SL1 = spec(R, ISL1,units_of(R)) + SL2= spec(R,ISL2,units_of(R)) @test reduced_scheme(Y)[1] == SL1 @test reduced_scheme(Yr)[1] == SL2 end @@ -44,9 +44,9 @@ end I = ideal(R, [x^2 - y^2 + z^2]) I2 = ideal(R, [(x^2 - y^2 + z^2)^2]) J = ideal(R, [x-1, y-2]) - X = Spec(R, I , units_of(R)) - X2 = Spec(R, I2 , units_of(R)) - Y = Spec(R, I*J, units_of(R)) + X = spec(R, I , units_of(R)) + X2 = spec(R, I2 , units_of(R)) + Y = spec(R, I*J, units_of(R)) @test is_equidimensional(X) @test is_equidimensional(X) ## if caching works, this tests a different line of code @test is_equidimensional(X2) @@ -55,27 +55,27 @@ end @test !is_reduced(X2) @test reduced_scheme(X2)[1] == X U = complement_of_point_ideal(R,[0,0,0]) - X1 = Spec(R, I ,U) - X12 = Spec(R, I2, U) - Y1 = Spec(R, I*J, U) + X1 = spec(R, I ,U) + X12 = spec(R, I2, U) + Y1 = spec(R, I*J, U) @test is_equidimensional(X1) @test is_equidimensional(X12) @test is_equidimensional(Y1) # pther component does not pass through point @test is_reduced(X1) @test !is_reduced(X12) @test reduced_scheme(X12)[1] == X1 - @test is_equidimensional(Spec(R)) - @test is_equidimensional(Spec(R,U)) - @test is_reduced(Spec(R)) - @test is_reduced(Spec(R,U)) - Z = Spec(R) + @test is_equidimensional(spec(R)) + @test is_equidimensional(spec(R,U)) + @test is_reduced(spec(R)) + @test is_reduced(spec(R,U)) + Z = spec(R) @test reduced_scheme(Z)[1] == Z end @testset "derivative in localized ring" begin R, (x,y) = QQ["x","y"] U = complement_of_point_ideal(R,[0,0]) - X = Spec(R, U) + X = spec(R, U) L = OO(X) I = ideal(L, [1//(1+x), (1-y)^2//((y-1)*(1-x))]) @test denominator(derivative(gen(I, 1),1)) == (x^2 + 2*x + 1) @@ -85,7 +85,7 @@ end @test denominator(derivative(gen(I, 2),2)) == (x - 1) @test numerator(derivative(gen(I, 2),2)) == -1 J=ideal(R, [x^2+y^2]) - X2 = Spec(R, J ,U) + X2 = spec(R, J ,U) L2 = OO(X2) I2 = ideal(L2, [1//(1+x), (1-y)^2//((y-1)*(1-x))]) @test denominator(derivative(gen(I2, 1),1)) == (x^2 + 2*x + 1) diff --git a/test/AlgebraicGeometry/Schemes/transforms.jl b/test/AlgebraicGeometry/Schemes/transforms.jl index da8256722d9d..73a75569ed3b 100644 --- a/test/AlgebraicGeometry/Schemes/transforms.jl +++ b/test/AlgebraicGeometry/Schemes/transforms.jl @@ -18,7 +18,7 @@ Istrict = strict_transform(bl,Isheaf) @test is_smooth(subscheme(Istrict)) - + Iweak = weak_transform(bl,Isheaf) Iweak2,mult = Oscar.weak_transform_with_multiplicity(bl, Isheaf) @test Iweak == Iweak2 @@ -37,7 +37,7 @@ end @testset "associated_points" begin # set up standard P2 S, _ = graded_polynomial_ring(QQ,["x","y","z"]) - P2 = ProjectiveScheme(S) + P2 = proj(S) X = covered_scheme(P2) C = standard_covering(P2) @@ -59,7 +59,7 @@ end Iz = ideal(Rz,[y]) # glue together to an ideal sheaf on P2 - ID = IdDict{AbsSpec, Oscar.Ideal}() + ID = IdDict{AbsAffineScheme, Oscar.Ideal}() ID[Ux]=Ix ID[Uy]=Iy ID[Uz]=Iz diff --git a/test/AlgebraicGeometry/ToricVarieties/proj.jl b/test/AlgebraicGeometry/ToricVarieties/projectivization.jl similarity index 84% rename from test/AlgebraicGeometry/ToricVarieties/proj.jl rename to test/AlgebraicGeometry/ToricVarieties/projectivization.jl index 3fe27fc1a8b7..49e54cc85bcd 100644 --- a/test/AlgebraicGeometry/ToricVarieties/proj.jl +++ b/test/AlgebraicGeometry/ToricVarieties/projectivization.jl @@ -4,7 +4,7 @@ for a in 0:10 Da = toric_divisor(P1, [a,0]) D0 = toric_divisor(P1, [0,0]) - X = proj(D0, Da) + X = projectivization(D0, Da) @test is_smooth(X) == true @test (a < 2) == is_fano(X) @test rank(picard_group(X)) == 2 @@ -14,15 +14,15 @@ # We will test the rank of the Picard group and the constant (-K_X)^3 # Our reference is https://www.fanography.info/toric - + # Let us start from the projective bundle over P2 P2 = projective_space(NormalToricVariety, 2) D0 = toric_divisor(P2, [0,0,0]) - X1_P2 = proj(D0, D0) + X1_P2 = projectivization(D0, D0) D1 = toric_divisor(P2, [0,0,1]) - X2_P2 = proj(D0, D1) + X2_P2 = projectivization(D0, D1) D2 = toric_divisor(P2, [0,2,0]) - X3_P2 = proj(D0, D2) + X3_P2 = projectivization(D0, D2) @testset "Test of some Fano projective bundles of dimension 3 over P2" begin @test rank(picard_group(X1_P2)) == 2 @test is_fano(X1_P2) == true @@ -34,32 +34,32 @@ @test is_fano(X3_P2) == true @test integrate(cohomology_class(anticanonical_divisor(X3_P2))^dim(X3_P2)) == 62 end - + # Projective bundle over F1 = hirzebruch_surface(1) D0 = toric_divisor(P1, [0,0]) D1 = toric_divisor(P1, [-1,0]) - F1 = proj(D0, D1) - X1_F1 = proj(toric_divisor(F1, [1,1,0,0]), toric_divisor(F1, [1,1,0,0])) + F1 = projectivization(D0, D1) + X1_F1 = projectivization(toric_divisor(F1, [1,1,0,0]), toric_divisor(F1, [1,1,0,0])) l1_F1 = toric_line_bundle(F1, [0,1]) - X2_F1 = proj(toric_line_bundle(F1, [0,0]), l1_F1) + X2_F1 = projectivization(toric_line_bundle(F1, [0,0]), l1_F1) @testset "Test of some Fano projective bundles of dimension 3 over F1" begin @test rank(picard_group(X1_F1)) == 3 @test is_fano(X1_F1) == true - @test integrate(cohomology_class(anticanonical_divisor(X1_F1))^dim(X1_F1)) == 48 + @test integrate(cohomology_class(anticanonical_divisor(X1_F1))^dim(X1_F1)) == 48 @test integrate(cohomology_class(l1_F1)^2) == 1 @test rank(picard_group(X2_F1)) == 3 @test is_fano(X2_F1) == true @test integrate(cohomology_class(anticanonical_divisor(X2_F1))^dim(X2_F1)) == 50 end - - P1xP1 = proj(D0, D0) + + P1xP1 = projectivization(D0, D0) O00 = toric_line_bundle(P1xP1, [0,0]) O10 = toric_line_bundle(P1xP1, [1,0]) O01 = toric_line_bundle(P1xP1, [0,1]) O11 = toric_line_bundle(P1xP1, [1,1]) - X1_P1xP1 = proj(O10, O01) - X2_P1xP1 = proj(O10, O10) - X3_P1xP1 = proj(O00, O11) + X1_P1xP1 = projectivization(O10, O01) + X2_P1xP1 = projectivization(O10, O10) + X3_P1xP1 = projectivization(O00, O11) @testset "Test of some Fano projective bundles of dimension 3 over P1 * P1" begin @test rank(picard_group(X1_P1xP1)) == 3 @test is_fano(X1_P1xP1) == true @@ -71,5 +71,5 @@ @test is_fano(X3_P1xP1) == true @test integrate(cohomology_class(anticanonical_divisor(X3_P1xP1))^dim(X3_P1xP1)) == 52 end - + end diff --git a/test/Groups/directproducts.jl b/test/Groups/directproducts.jl index ccd8e885da62..bc71c9ecd0cb 100644 --- a/test/Groups/directproducts.jl +++ b/test/Groups/directproducts.jl @@ -14,12 +14,12 @@ @test is_full_direct_product(G) @test permutation_group(G) isa PermGroup - G,emb,proj = direct_product(S,C; morphisms=true) + G,emb,pr = direct_product(S,C; morphisms=true) @test G==direct_product(S,C) @test emb[1]==canonical_injection(G,1) @test emb[2]==canonical_injection(G,2) - @test proj[1]==canonical_projection(G,1) - @test proj[2]==canonical_projection(G,2) + @test pr[1]==canonical_projection(G,1) + @test pr[2]==canonical_projection(G,2) x = rand(G) @test x in G @@ -96,12 +96,12 @@ @test Le[i]*Lp[i]==id_hom(L[i]) end - G1,Le1,Lp1 = inner_cartesian_power(A,3; morphisms=true) + G1,Le1,Lp1 = inner_cartesian_power(A,3; morphisms=true) @test G1==G @test Le1==Le @test Lp1==Lp end - + @testset "Cartesian Power" begin diff --git a/test/Modules/ModulesGraded.jl b/test/Modules/ModulesGraded.jl index 4ddb4a75f3b1..6a016b33c02e 100644 --- a/test/Modules/ModulesGraded.jl +++ b/test/Modules/ModulesGraded.jl @@ -166,7 +166,7 @@ end B = Rg[x^2; y^3; z^4] M = SubquoModule(F, A, B) N = M; - # Problem with the previous test: V[2] is zero and + # Problem with the previous test: V[2] is zero and # the homomorphism is hence not graded. # V = [y^2*N[1], x^2*N[2]] V = [y^2*N[1], x*y*N[2]] @@ -405,10 +405,10 @@ end F1 = graded_free_module(Rg, 1) F2 = graded_free_module(Rg, 2) F2v, ev = dual(F2, codomain=F1) - @test ev(F2v[1])(F2[1]) == F1[1] + @test ev(F2v[1])(F2[1]) == F1[1] FF, psi = double_dual(F2) @test degrees_of_generators(FF) == [Z[0], Z[0]] - @test is_injective(psi) + @test is_injective(psi) M, inc = sub(F2, [x*F2[1], y*F2[1]]) F1 = graded_free_module(Rg, 1) Mv, ev = dual(M, codomain=F1) @@ -436,7 +436,7 @@ end ddM, g = double_dual(M) @test is_graded(ddM) @test degrees_of_generators(ddM) == [Z[0]] - @test codomain(g)== ddM + @test codomain(g)== ddM @test is_injective(g) end @@ -556,7 +556,7 @@ end F = graded_free_module(Rg,1) V1 = [p * F[1] for p in V] M = quo(F, V1)[1] - # Free resolution via Singular gives wrong result + # Free resolution via Singular gives wrong result free_res1 = free_resolution(M) @test is_graded(free_res1) @test all(iszero, homology(free_res1.C)) @@ -823,30 +823,30 @@ end @test domain(emb[2]) === M2 @test codomain(emb[1]) === sum_M @test codomain(emb[2]) === sum_M - sum_M, proj = direct_sum(M1,M2, task=:prod) + sum_M, pr = direct_sum(M1,M2, task=:prod) @test is_graded(sum_M) - @test is_homogeneous(proj[1]) - @test is_homogeneous(proj[2]) - @test codomain(proj[1]) === M1 - @test codomain(proj[2]) === M2 - @test domain(proj[1]) === sum_M - @test domain(proj[2]) === sum_M - prod_M, emb, proj = direct_sum(M1,M2,task=:both) + @test is_homogeneous(pr[1]) + @test is_homogeneous(pr[2]) + @test codomain(pr[1]) === M1 + @test codomain(pr[2]) === M2 + @test domain(pr[1]) === sum_M + @test domain(pr[2]) === sum_M + prod_M, emb, pr = direct_sum(M1,M2,task=:both) @test is_graded(sum_M) @test is_homogeneous(emb[1]) @test is_homogeneous(emb[2]) - @test is_homogeneous(proj[1]) - @test is_homogeneous(proj[2]) - @test length(proj) == length(emb) == 2 + @test is_homogeneous(pr[1]) + @test is_homogeneous(pr[2]) + @test length(pr) == length(emb) == 2 @test ngens(prod_M) == ngens(M1) + ngens(M2) for g in gens(prod_M) - @test g == sum([emb[i](proj[i](g)) for i=1:length(proj)]) + @test g == sum([emb[i](pr[i](g)) for i=1:length(pr)]) end for g in gens(M1) - @test g == proj[1](emb[1](g)) + @test g == pr[1](emb[1](g)) end for g in gens(M2) - @test g == proj[2](emb[2](g)) + @test g == pr[2](emb[2](g)) end A1 = Rg[4*x*y^2*z^2 + 6*x*z^4 9*x^2*z^3; 5*x^2*y*z + 12*x*y^3 8*x^2*y^2 + z^4; @@ -926,7 +926,7 @@ end for coefficients in ([c1,c2,c3] for c1 in coeff_generator for c2 in coeff_generator for c3 in coeff_generator) v = sparse_row(Rg, [(i,sum(coefficients[i][j]*monomials[j] for j=1:2)) for i=1:3]) v_as_FreeModElem = sum([v[i]*repres(M[i]) for i=1:ngens(M)]) - elem1 = SubquoModuleElem(v_as_FreeModElem,M) + elem1 = SubquoModuleElem(v_as_FreeModElem,M) elem2 = SubquoModuleElem(v,M) @test elem1 == elem2 end @@ -1034,14 +1034,14 @@ end for v in gens(H) @test v == homomorphism_to_element(H, element_to_homomorphism(v)) end - + phi = H[1] v = x[1]*F[1] + F[2] @test degree(phi) == degree(element_to_homomorphism(phi)(v)) - degree(v) end @testset "minimal Betti tables" begin - # The Veronese surface in IP^4 due to Wolfram + # The Veronese surface in IP^4 due to Wolfram F = GF(31991) R, (x,y,z,u,v) = graded_polynomial_ring(F, ["x", "y", "z", "u", "v"]) I = ideal([F(45)/16*x^3-8565*x^2*y-7937*x*y^2+14060*x^2*z+F(53)/113*x*y*z-F(125)/17*x*z^2-15712*x^2*u-5990*x*y*u-F(71)/88*x*z*u-6141*x*u^2+F(49)/104*x^2*v-194*x*y*v+F(63)/103*y^2*v+F(74)/103*x*z*v+11618*y*z*v+F(41)/111*z^2*v+14387*x*u*v-F(64)/9*y*u*v+13097*z*u*v+F(84)/101*u^2*v+12211*x*v^2+F(85)/63*y*v^2-F(119)/100*z*v^2-6247*u*v^2-F(74)/51*v^3,-F(45)/16*x^2*y+8565*x*y^2+7937*y^3-14060*x*y*z-F(53)/113*y^2*z+F(125)/17*y*z^2+15712*x*y*u+5990*y^2*u+F(71)/88*y*z*u+6141*y*u^2-x^2*v+3340*x*y*v+F(111)/40*y^2*v+F(22)/37*x*z*v-F(110)/29*y*z*v-F(71)/25*z^2*v-F(71)/87*x*u*v+F(112)/55*y*u*v+F(103)/80*z*u*v-F(100)/7*u^2*v-5013*x*v^2+15010*y*v^2+F(52)/51*z*v^2+F(126)/5*u*v^2-6580*v^3,-F(45)/16*x^2*z+8565*x*y*z+7937*y^2*z-14060*x*z^2-F(53)/113*y*z^2+F(125)/17*z^3+15712*x*z*u+5990*y*z*u+F(71)/88*z^2*u+6141*z*u^2+F(41)/79*x^2*v+F(121)/48*x*y*v+9621*y^2*v+F(105)/83*x*z*v+F(27)/26*y*z*v-649*z^2*v-12278*x*u*v+14655*y*u*v+10594*z*u*v+10462*u^2*v+F(76)/13*x*v^2+F(97)/50*y*v^2-7761*z*v^2+F(52)/31*u*v^2-6636*v^3,-F(45)/16*x^2*u+8565*x*y*u+7937*y^2*u-14060*x*z*u-F(53)/113*y*z*u+F(125)/17*z^2*u+15712*x*u^2+5990*y*u^2+F(71)/88*z*u^2+6141*u^3-F(40)/31*x^2*v+13297*x*y*v+F(126)/113*y^2*v-F(51)/100*x*z*v-F(97)/38*y*z*v+10372*z^2*v-F(4)/31*x*u*v+F(32)/9*y*u*v-F(1)/7*z*u*v+15473*u^2*v+F(101)/36*x*v^2+F(97)/109*y*v^2-14100*z*v^2+F(109)/32*u*v^2-F(5)/111*v^3,-F(40)/31*x^3+13297*x^2*y+F(126)/113*x*y^2-F(51)/100*x^2*z-F(97)/38*x*y*z+10372*x*z^2+F(26)/105*x^2*u-3745*x*y*u+F(63)/103*y^2*u-F(98)/61*x*z*u+11618*y*z*u+F(41)/111*z^2*u+F(26)/15*x*u^2-F(64)/9*y*u^2+13097*z*u^2+F(84)/101*u^3+F(101)/36*x^2*v+F(97)/109*x*y*v-14100*x*z*v-14778*x*u*v+F(85)/63*y*u*v-F(119)/100*z*u*v-6247*u^2*v-F(5)/111*x*v^2-F(74)/51*u*v^2,F(40)/31*x^2*y-13297*x*y^2-F(126)/113*y^3+F(51)/100*x*y*z+F(97)/38*y^2*z-10372*y*z^2-x^2*u+F(103)/30*x*y*u+2754*y^2*u+F(22)/37*x*z*u+F(126)/95*y*z*u-F(71)/25*z^2*u-F(71)/87*x*u^2-F(109)/7*y*u^2+F(103)/80*z*u^2-F(100)/7*u^3-F(101)/36*x*y*v-F(97)/109*y^2*v+14100*y*z*v-5013*x*u*v+10008*y*u*v+F(52)/51*z*u*v+F(126)/5*u^2*v+F(5)/111*y*v^2-6580*u*v^2,F(40)/31*x^2*z-13297*x*y*z-F(126)/113*y^2*z+F(51)/100*x*z^2+F(97)/38*y*z^2-10372*z^3+F(41)/79*x^2*u+F(121)/48*x*y*u+9621*y^2*u+5671*x*z*u-F(42)/71*y*z*u-5219*z^2*u-12278*x*u^2+14655*y*u^2+F(58)/59*z*u^2+10462*u^3-F(101)/36*x*z*v-F(97)/109*y*z*v+14100*z^2*v+F(76)/13*x*u*v+F(97)/50*y*u*v-12763*z*u*v+F(52)/31*u^2*v+F(5)/111*z*v^2-6636*u*v^2,F(41)/79*x^3+F(121)/48*x^2*y+9621*x*y^2-F(22)/109*x^2*z+F(25)/19*x*y*z+F(63)/103*y^2*z+F(23)/45*x*z^2+11618*y*z^2+F(41)/111*z^3-12278*x^2*u+14655*x*y*u+F(126)/73*x*z*u-F(64)/9*y*z*u+13097*z^2*u+10462*x*u^2+F(84)/101*z*u^2+F(76)/13*x^2*v+F(97)/50*x*y*v-F(106)/115*x*z*v+F(85)/63*y*z*v-F(119)/100*z^2*v+F(52)/31*x*u*v-6247*z*u*v-6636*x*v^2-F(74)/51*z*v^2,-F(41)/79*x^2*y-F(121)/48*x*y^2-9621*y^3-x^2*z-F(22)/89*x*y*z-F(32)/17*y^2*z+F(22)/37*x*z^2-F(86)/111*y*z^2-F(71)/25*z^3+12278*x*y*u-14655*y^2*u-F(71)/87*x*z*u+F(74)/47*y*z*u+F(103)/80*z^2*u-10462*y*u^2-F(100)/7*z*u^2-F(76)/13*x*y*v-F(97)/50*y^2*v-5013*x*z*v-9220*y*z*v+F(52)/51*z^2*v-F(52)/31*y*u*v+F(126)/5*z*u*v+6636*y*v^2-6580*z*v^2,x^3+11117*x^2*y+991*x*y^2-F(63)/103*y^3-F(22)/37*x^2*z-F(35)/13*x*y*z-11618*y^2*z+F(71)/25*x*z^2-F(41)/111*y*z^2+F(71)/87*x^2*u+F(68)/115*x*y*u+F(64)/9*y^2*u-F(103)/80*x*z*u-13097*y*z*u+F(100)/7*x*u^2-F(84)/101*y*u^2+5013*x^2*v-F(67)/114*x*y*v-F(85)/63*y^2*v-F(52)/51*x*z*v+F(119)/100*y*z*v-F(126)/5*x*u*v+6247*y*u*v+6580*x*v^2+F(74)/51*y*v^2]) @@ -1050,13 +1050,13 @@ end sub_F, inc = sub(F, [g*F[1] for g in gens(I)]) M = cokernel(inc) A, _ = quo(R, I) - # To reproduce the string on the right hand side, evaluate - # `"$(Oscar.minimal_betti_table(M))"` + # To reproduce the string on the right hand side, evaluate + # `"$(Oscar.minimal_betti_table(M))"` # and insert the result here; after verification of the result! @test "$(Oscar.minimal_betti_table(A))" == " 0 1 2 3 4\n---------------------\n0 : 1 - - - -\n1 : - - - - -\n2 : - 7 10 5 1\n---------------------\ntotal: 1 7 10 5 1\n" @test "$(Oscar.minimal_betti_table(M))" == " 0 1 2 3 4\n---------------------\n0 : 1 - - - -\n1 : - - - - -\n2 : - 7 10 5 1\n---------------------\ntotal: 1 7 10 5 1\n" - + @test "$(Oscar.minimal_betti_table(I))" == "$(Oscar.minimal_betti_table(sub_F))" # small example due to Janko @@ -1064,7 +1064,7 @@ end I = ideal(R, [x[1]*x[2]*x[5], x[1]*x[2]*x[6], x[3]*x[4]*x[6], x[3]*x[4]*x[7], x[5]*x[7]]) A, _ = quo(R, I) @test "$(Oscar.minimal_betti_table(A))" == " 0 1 2 3\n-----------------\n0 : 1 - - -\n1 : - 1 - -\n2 : - 4 4 -\n3 : - - 1 -\n4 : - - - 1\n-----------------\ntotal: 1 5 5 1\n" - + # another example due to Wolfram R, (x, y, z, w) = graded_polynomial_ring(QQ, [:x, :y, :z, :w]) I = ideal(R, [w^2 - x*z, w*x - y*z, x^2 - w*y, x*y - z^2, y^2 - w*z]) diff --git a/test/Modules/UngradedModules.jl b/test/Modules/UngradedModules.jl index 22d20853d51b..cd91897662c5 100644 --- a/test/Modules/UngradedModules.jl +++ b/test/Modules/UngradedModules.jl @@ -70,7 +70,7 @@ end M = subquotient(a1,a2) m3 = x*M[1]+M[2]+x*M[3] @test repres(simplify(m3)) == x*G[1] + (y - z)*G[2] -end +end @testset "Intersection of modules" begin Oscar.set_seed!(235) @@ -280,7 +280,7 @@ end N, phi = prune_with_map(M) @test rank(ambient_free_module(N)) == 2 @test (phi).(gens(N)) == gens(M)[2:3] - + M = SubquoModule(identity_matrix(R, 3), R[x 1 x]) N, phi = prune_with_map(M) @test rank(ambient_free_module(N)) == 2 @@ -424,7 +424,7 @@ end R[8*x^2*y^2*z^2+13*x*y*z^2 12*x^2+7*y^2*z; 13*x*y^2+12*y*z^2 4*x^2*y^2*z+8*x*y*z; 9*x*y^2+4*z 12*x^2*y*z^2+9*x*y^2*z]] - kernels = [R[x^2-x*y+y -x^2+x*y -x^2+x*y-y^2-y], R[R(0) R(0)], + kernels = [R[x^2-x*y+y -x^2+x*y -x^2+x*y-y^2-y], R[R(0) R(0)], R[-36*x^3*y^4*z+156*x^3*y^3*z^2+144*x^2*y^2*z^4+117*x^2*y^4*z+108*x*y^3*z^3-72*x^2*y^3*z-16*x^2*y^2*z^2-32*x*y*z^2 -96*x^4*y^3*z^4-72*x^3*y^4*z^3-156*x^3*y^2*z^4-117*x^2*y^3*z^3+63*x*y^4*z+108*x^3*y^2+28*y^2*z^2+48*x^2*z 32*x^4*y^4*z^3+116*x^3*y^3*z^3+104*x^2*y^2*z^3-91*x*y^4*z-84*y^3*z^3-156*x^3*y^2-144*x^2*y*z^2]] for (A,Ker) in zip(matrices, kernels) F1 = FreeMod(R, nrows(A)) @@ -544,7 +544,7 @@ end @test Q1 == SubquoModule(F3,R[x^2*y^3-x*y y^3 x^2*y],R[x^4*y^5 x*y y^4; x^4*y^5-4*x^2 -6*x*y^2+x*y y^4-8]) @test p1 == find_morphism(M1, Q1) for k=1:5 - elem = SubquoModuleElem(sparse_row(matrix([randpoly(R) for _=1:1,i=1:2])), M1) + elem = SubquoModuleElem(sparse_row(matrix([randpoly(R) for _=1:1,i=1:2])), M1) @test p1(elem) == transport(Q1, elem) end @@ -716,7 +716,7 @@ end A1 = matrix([randpoly(R,0:15,4,3) for i=1:3,j=1:2]) B1 = matrix([randpoly(R,0:15,2,1) for i=1:1,j=1:2]) - + A2 = matrix([randpoly(R,0:15,2,1) for i=1:3,j=1:3]) B2 = matrix([randpoly(R,0:15,2,1) for i=1:1,j=1:3]) @@ -751,7 +751,7 @@ end @testset "direct product" begin Oscar.set_seed!(235) R, (x,y,z) = polynomial_ring(QQ, ["x", "y", "z"]) - + F2 = FreeMod(R,2) F3 = FreeMod(R,3) @@ -770,24 +770,24 @@ end @test codomain(emb[1]) === sum_M @test codomain(emb[2]) === sum_M - sum_M, proj = direct_sum(M1,M2, task=:prod) - @test codomain(proj[1]) === M1 - @test codomain(proj[2]) === M2 - @test domain(proj[1]) === sum_M - @test domain(proj[2]) === sum_M + sum_M, pr = direct_sum(M1,M2, task=:prod) + @test codomain(pr[1]) === M1 + @test codomain(pr[2]) === M2 + @test domain(pr[1]) === sum_M + @test domain(pr[2]) === sum_M - prod_M, emb, proj = direct_sum(M1,M2,task=:both) - @test length(proj) == length(emb) == 2 + prod_M, emb, pr = direct_sum(M1,M2,task=:both) + @test length(pr) == length(emb) == 2 @test ngens(prod_M) == ngens(M1) + ngens(M2) for g in gens(prod_M) - @test g == sum([emb[i](proj[i](g)) for i=1:length(proj)]) + @test g == sum([emb[i](pr[i](g)) for i=1:length(pr)]) end for g in gens(M1) - @test g == proj[1](emb[1](g)) + @test g == pr[1](emb[1](g)) end for g in gens(M2) - @test g == proj[2](emb[2](g)) + @test g == pr[2](emb[2](g)) end A1 = matrix([randpoly(R,0:15,2,2) for i=1:3,j=1:2]) @@ -866,7 +866,7 @@ end v = sparse_row(R, [(i,sum(coefficients[i][j]*monomials[j] for j=1:2)) for i=1:3]) v_as_FreeModElem = sum([v[i]*repres(M[i]) for i=1:ngens(M)]) - elem1 = SubquoModuleElem(v_as_FreeModElem,M) + elem1 = SubquoModuleElem(v_as_FreeModElem,M) elem2 = SubquoModuleElem(v,M) @test elem1 == elem2 @@ -1123,9 +1123,9 @@ end @test ev(F2v[1])(F2[1]) == F1[1] # the first generator FF, psi = Oscar.double_dual(F2) - @test is_injective(psi) + @test is_injective(psi) @test is_surjective(psi) - + M, inc = sub(F2, [x*F2[1], y*F2[1]]) F1 = FreeMod(R, 1) Mv, ev = dual(M, codomain=F1) @@ -1133,7 +1133,7 @@ end Mvv, psi = Oscar.double_dual(M, codomain=F1) @test matrix(psi) == R[x; y] - + ### Quotient rings A = R[x y; z x-1] @@ -1143,15 +1143,15 @@ end F2 = FreeMod(Q, 2) F2v, ev = Oscar.dual(F2, codomain=F1) @test ev(F2v[1])(F2[1]) == F1[1] # the first generator - + FF, psi = Oscar.double_dual(F2) - @test is_injective(psi) - @test is_surjective(psi) + @test is_injective(psi) + @test is_surjective(psi) M, pr = quo(F2, [sum(A[i, j]*F2[j] for j in 1:ngens(F2)) for i in 1:nrows(A)]) Mv, ev = Oscar.dual(M, codomain=F1) Mvv, psi = Oscar.double_dual(M, codomain=F1) - @test is_injective(psi) + @test is_injective(psi) @test is_surjective(psi) # works correctly! end @@ -1203,7 +1203,7 @@ end F = FreeMod(R, 1) - # we need to wrap the creation of I in a scope of its own so + # we need to wrap the creation of I in a scope of its own so # that gc works within the test suite. function dummy(F::FreeMod) I, inc = sub(F, [x*F[1]], cache_morphism=true) @@ -1212,7 +1212,7 @@ end @test Oscar._recreate_morphism(I, F, F.incoming[I]) == inc @test haskey(I.outgoing, F) - @test Oscar._recreate_morphism(I, F, I.outgoing[F]) == inc + @test Oscar._recreate_morphism(I, F, I.outgoing[F]) == inc I = 5 inc = "a" @@ -1224,13 +1224,13 @@ end @test length(keys(F.incoming)) == 0 # The other way around it will not work, because I has a reference to its ambient_free_module f. - + function dummy2(F::FreeMod) I, inc_I = sub(F, [x*F[1]], cache_morphism=true) J, inc_J = sub(I, [x^2*I[1]], cache_morphism=true) @test haskey(J.outgoing, I) - @test haskey(I.incoming, J) + @test haskey(I.incoming, J) @test Oscar._recreate_morphism(J, I, J.outgoing[I]) == inc_J @test Oscar._recreate_morphism(J, I, I.incoming[J]) == inc_J @@ -1245,7 +1245,7 @@ end # The inclusion map J -> I is still stored in the attributes of J as :canonical_inclusion. # However, even removing that and calling gc() again does not remove the entry in J.outgoing. # So there is still a memory leak somewhere! - @test_broken length(keys(J.outgoing)) == 0 + @test_broken length(keys(J.outgoing)) == 0 end From 8b5f11686662b5eab96182b931b9a386218867c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Mon, 26 Feb 2024 16:45:28 +0100 Subject: [PATCH 05/30] Remove two mentions of `Arb_jll` (#3431) (cherry picked from commit 8afc6a884a17188f745bde19d02cc353454a4a94) --- src/Serialization/Fields.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Serialization/Fields.jl b/src/Serialization/Fields.jl index 6df50bdc2bcb..e0b86b6b3887 100644 --- a/src/Serialization/Fields.jl +++ b/src/Serialization/Fields.jl @@ -403,7 +403,7 @@ end # elements function save_object(s::SerializerState, r::ArbFieldElem) - c_str = ccall((:arb_dump_str, Nemo.Arb_jll.libarb), Ptr{UInt8}, (Ref{ArbFieldElem},), r) + c_str = ccall((:arb_dump_str, Nemo.libarb), Ptr{UInt8}, (Ref{ArbFieldElem},), r) save_object(s, unsafe_string(c_str)) # free memory @@ -413,7 +413,7 @@ end function load_object(s::DeserializerState, ::Type{ArbFieldElem}, parent::ArbField) r = Nemo.ArbFieldElem() load_node(s) do str - ccall((:arb_load_str, Nemo.Arb_jll.libarb), + ccall((:arb_load_str, Nemo.libarb), Int32, (Ref{ArbFieldElem}, Ptr{UInt8}), r, str) end r.parent = parent From 633ab20d5ae24fac697be182c955c68561d2efa7 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 26 Feb 2024 17:44:25 +0100 Subject: [PATCH 06/30] Tweak epimorphism_from_free_group (#3430) ... to ensure rank of the free group is set. (cherry picked from commit 4cea177e98505f2711b1192462cc0aaca6e43a9c) --- src/Groups/sub.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Groups/sub.jl b/src/Groups/sub.jl index bc05e667d226..26e2087149ee 100644 --- a/src/Groups/sub.jl +++ b/src/Groups/sub.jl @@ -1003,7 +1003,7 @@ julia> G = symmetric_group(4); julia> epi = epimorphism_from_free_group(G) Group homomorphism - from free group + from free group of rank 2 to Sym(4) julia> pi = G([2,4,3,1]) @@ -1018,6 +1018,7 @@ julia> map_word(w, gens(G)) function epimorphism_from_free_group(G::GAPGroup) mfG = GAP.Globals.EpimorphismFromFreeGroup(G.X) fG = FPGroup(GAPWrap.Source(mfG)) + GAP.Globals.RankOfFreeGroup(fG.X) # force rank computation return Oscar.GAPGroupHomomorphism(fG, G, mfG) end From 1a621a1cc2eeba7941952a0def2a909156caebda Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 26 Feb 2024 21:04:26 +0100 Subject: [PATCH 07/30] Add `all_perfect_groups` (#3434) (cherry picked from commit 6308dd76b0d17752b02730079006b33131156cfb) --- docs/src/Groups/grouplib.md | 1 + src/Groups/libraries/perfectgroups.jl | 70 ++++++++++++++++++++++++++- src/exports.jl | 1 + test/Groups/libraries.jl | 15 ++++++ 4 files changed, 86 insertions(+), 1 deletion(-) diff --git a/docs/src/Groups/grouplib.md b/docs/src/Groups/grouplib.md index 142e2bb0e6ab..7cc62d1b7b28 100644 --- a/docs/src/Groups/grouplib.md +++ b/docs/src/Groups/grouplib.md @@ -76,6 +76,7 @@ not have a faithful permutation representation of small degree. Computations in these groups may be rather time consuming. ```@docs +all_perfect_groups has_number_of_perfect_groups has_perfect_group_identification has_perfect_groups diff --git a/src/Groups/libraries/perfectgroups.jl b/src/Groups/libraries/perfectgroups.jl index 2f4db6185f5a..2ae68f00905c 100644 --- a/src/Groups/libraries/perfectgroups.jl +++ b/src/Groups/libraries/perfectgroups.jl @@ -178,7 +178,75 @@ function number_of_perfect_groups(n::IntegerUnion) return res::Int end -# TODO: add all_perfect_groups() iterator + +""" + all_perfect_groups(L...) + +Return the list of all perfect groups (up to permutation isomorphism) +satisfying the conditions described by the arguments. These conditions +may be of one of the following forms: + +- `func => intval` selects groups for which the function `func` returns `intval` +- `func => list` selects groups for which the function `func` returns any element inside `list` +- `func` selects groups for which the function `func` returns `true` +- `!func` selects groups for which the function `func` returns `false` + +As a special case, the first argument may also be one of the following: +- `intval` selects groups whose order equals `intval`; this is equivalent to `order => intval` +- `intlist` selects groups whose order is in `intlist`; this is equivalent to `order => intlist` + +The following functions are currently supported as values for `func`: +- `is_quasisimple` +- `is_simple` +- `is_sporadic_simple` +- `number_of_conjugacy_classes` +- `order` + +The type of the returned groups is `PermGroup`. + +# Examples +```jldoctest +julia> all_perfect_groups(7200) +2-element Vector{PermGroup}: + Permutation group of degree 29 and order 7200 + Permutation group of degree 288 and order 7200 + +julia> all_perfect_groups(order => 1:200, !is_simple) +2-element Vector{PermGroup}: + Permutation group of degree 1 and order 1 + Permutation group of degree 24 and order 120 +``` +""" +function all_perfect_groups(L...) + @req !isempty(L) "must specify at least one filter" + if L[1] isa IntegerUnion || L[1] isa AbstractVector{<:IntegerUnion} + L = (order => L[1], L[2:end]...) + end + # first get all order restrictions + ordsL = [x for x in L if x isa Pair && x[1] == order] + @req !isempty(ordsL) "must restrict the order" + conds = [x for x in L if !(x isa Pair && x[1] == order)] + orders = intersect([x[2] for x in ordsL]...) + @req has_perfect_groups(maximum(orders)) "only orders up to 2 million are supported" + res = PermGroup[] + for n in orders, i in 1:number_of_perfect_groups(n) + G = perfect_group(n, i) + ok = true + for c in conds + if c isa Pair + val = c[1](G) + ok = (val == c[2] || val in c[2]) + elseif c isa Function + ok = c(G) + else + throw(ArgumentError("expected a function or a pair, got $arg")) + end + ok || break + end + ok && push!(res, G) + end + return res +end function __init_extraperfect() for i in [27, 33] diff --git a/src/exports.jl b/src/exports.jl index cefb0b501504..a79f6df4a89b 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -217,6 +217,7 @@ export all_blocks export all_character_table_names export all_cohomologies export all_neighbors +export all_perfect_groups export all_primitive_groups export all_small_groups export all_subsets_matroid diff --git a/test/Groups/libraries.jl b/test/Groups/libraries.jl index 2c703aa3dcd2..70b7d59b81e3 100644 --- a/test/Groups/libraries.jl +++ b/test/Groups/libraries.jl @@ -111,6 +111,21 @@ end @test_throws ArgumentError number_of_perfect_groups(0) # invalid argument @test_throws ArgumentError number_of_perfect_groups(ZZRingElem(60)^10) # result not known + Gs = all_perfect_groups(order => 1:200) + @test length(Gs) == sum(number_of_perfect_groups, 1:200) + @test Gs == all_perfect_groups(1:200) + @test length(all_perfect_groups(7200)) == number_of_perfect_groups(7200) + + # all_perfect_groups with additional attributse + @test filter(G -> number_of_conjugacy_classes(G) in 5:8, Gs) == all_perfect_groups(1:200, number_of_conjugacy_classes => 5:8) + @test filter(is_simple, Gs) == all_perfect_groups(1:200, is_simple) + @test filter(is_simple, Gs) == all_perfect_groups(1:200, is_simple => true) + @test filter(!is_simple, Gs) == all_perfect_groups(1:200, !is_simple) + @test filter(!is_simple, Gs) == all_perfect_groups(1:200, is_simple => false) + + # all_perfect_groups with multiple order specifications + @test all_perfect_groups(order => 1:5:200, order => 25:50) == all_perfect_groups(order => intersect(1:5:200, 25:50)) + # lazy artifact loading (needs network access, see https://github.com/oscar-system/Oscar.jl/issues/2480) #@test perfect_group(1376256, 1) isa PermGroup end From 62e71ad5e5a20158c87c493990a4480777c5402f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Thu, 22 Feb 2024 16:34:46 +0100 Subject: [PATCH 08/30] Add `all_primitive_groups` and `all_transitive_groups` variants taking a single int or int range (#3404) (cherry picked from commit 83f05750497b654dfabafc210919f88dfbea534c) --- src/Groups/libraries/primitivegroups.jl | 20 ++++++++++++++++++++ src/Groups/libraries/transitivegroups.jl | 23 +++++++++++++++++++++++ test/Groups/libraries.jl | 8 ++++++++ 3 files changed, 51 insertions(+) diff --git a/src/Groups/libraries/primitivegroups.jl b/src/Groups/libraries/primitivegroups.jl index 6e28c2bd5ebf..a06f067f7487 100644 --- a/src/Groups/libraries/primitivegroups.jl +++ b/src/Groups/libraries/primitivegroups.jl @@ -184,8 +184,16 @@ The following functions are currently supported as values for `func`: The type of the returned groups is `PermGroup`. +If no conditions beside the degree are used, one can also use the shorthand +`all_primitive_groups(degree)` where `degree` is an integer or a list or range of integers. + # Examples ```jldoctest +julia> all_primitive_groups(4) +2-element Vector{PermGroup}: + Alt(4) + Sym(4) + julia> all_primitive_groups(degree => 3:5, is_abelian) 2-element Vector{PermGroup}: Alt(3) @@ -200,4 +208,16 @@ function all_primitive_groups(L...) return [PermGroup(x) for x in K] end +function all_primitive_groups(deg::Integer) + return all_primitive_groups(degree => deg) +end + +function all_primitive_groups(degs::Vector{<:Integer}) + return all_primitive_groups(degree => degs) +end + +function all_primitive_groups(degs::AbstractRange{<:Integer}) + return all_primitive_groups(degree => degs) +end + # TODO: turn this into an iterator, possibly using PrimitiveGroupsIterator diff --git a/src/Groups/libraries/transitivegroups.jl b/src/Groups/libraries/transitivegroups.jl index 87e8c393f925..4ea05ef7bf81 100644 --- a/src/Groups/libraries/transitivegroups.jl +++ b/src/Groups/libraries/transitivegroups.jl @@ -180,8 +180,19 @@ The following functions are currently supported as values for `func`: The type of the returned groups is `PermGroup`. +If no conditions beside the degree are used, one can also use the shorthand +`all_transitive_groups(degree)` where `degree` is an integer or a list or range of integers. + # Examples ```jldoctest +julia> all_transitive_groups(4) +5-element Vector{PermGroup}: + Permutation group of degree 4 + Permutation group of degree 4 + Permutation group of degree 4 + Alt(4) + Sym(4) + julia> all_transitive_groups(degree => 3:5, is_abelian) 4-element Vector{PermGroup}: Alt(3) @@ -197,4 +208,16 @@ function all_transitive_groups(L...) return [PermGroup(x) for x in K] end +function all_transitive_groups(deg::Integer) + return all_transitive_groups(degree => deg) +end + +function all_transitive_groups(degs::Vector{<:Integer}) + return all_transitive_groups(degree => degs) +end + +function all_transitive_groups(degs::AbstractRange{<:Integer}) + return all_transitive_groups(degree => degs) +end + # TODO: turn this into an iterator, possibly using PrimitiveGroupsIterator diff --git a/test/Groups/libraries.jl b/test/Groups/libraries.jl index 70b7d59b81e3..81bec96db549 100644 --- a/test/Groups/libraries.jl +++ b/test/Groups/libraries.jl @@ -83,6 +83,10 @@ end @test is_regular(H,[1,2]) @test_throws ArgumentError transitive_group(1, 2) + + @test issetequal(all_transitive_groups(3:2:9), all_transitive_groups(degree => 3:2:9)) + @test issetequal(all_transitive_groups(collect(3:2:9)), all_transitive_groups(3:2:9)) + @test issetequal(reduce(vcat, (all_transitive_groups(i) for i in 3:2:9)), all_transitive_groups(3:2:9)) end @testset "Perfect groups" begin @@ -156,6 +160,10 @@ end @test has_primitive_groups(50) @test_throws ArgumentError primitive_group(1, 1) @test number_of_primitive_groups(50) == 9 + + @test issetequal(all_primitive_groups(3:2:9), all_primitive_groups(degree => 3:2:9)) + @test issetequal(all_primitive_groups(collect(3:2:9)), all_primitive_groups(3:2:9)) + @test issetequal(reduce(vcat, (all_primitive_groups(i) for i in 3:2:9)), all_primitive_groups(3:2:9)) end @testset "Atlas groups" begin From 8efba739221ca6236af9f736550a66ae05b80715 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Mon, 26 Feb 2024 22:07:17 +0100 Subject: [PATCH 09/30] Align all_*_groups methods some more (#3433) For `all_small_groups` we allow specifying the order as a single integer or abstract vector, followed by any number of additional filters. For transitive and primitive groups, we also allowed specifying the degree as a single integer or abstract vector, but this then could not be followed by filters. With this patch the additional filters work in all cases. (cherry picked from commit dd7913bc1ecbb643175989f98eecab3e4dd8b17c) --- src/Groups/libraries/primitivegroups.jl | 23 +++++++---------------- src/Groups/libraries/transitivegroups.jl | 24 ++++++++---------------- test/Groups/libraries.jl | 6 ++++++ 3 files changed, 21 insertions(+), 32 deletions(-) diff --git a/src/Groups/libraries/primitivegroups.jl b/src/Groups/libraries/primitivegroups.jl index a06f067f7487..fcab27b2286e 100644 --- a/src/Groups/libraries/primitivegroups.jl +++ b/src/Groups/libraries/primitivegroups.jl @@ -163,6 +163,10 @@ may be of one of the following forms: - `func` selects groups for which the function `func` returns `true` - `!func` selects groups for which the function `func` returns `false` +As a special case, the first argument may also be one of the following: +- `intval` selects groups whose degree equals `intval`; this is equivalent to `degree => intval` +- `intlist` selects groups whose degree is in `intlist`; this is equivalent to `degree => intlist` + The following functions are currently supported as values for `func`: - `degree` - `is_abelian` @@ -184,9 +188,6 @@ The following functions are currently supported as values for `func`: The type of the returned groups is `PermGroup`. -If no conditions beside the degree are used, one can also use the shorthand -`all_primitive_groups(degree)` where `degree` is an integer or a list or range of integers. - # Examples ```jldoctest julia> all_primitive_groups(4) @@ -199,25 +200,15 @@ julia> all_primitive_groups(degree => 3:5, is_abelian) Alt(3) Permutation group of degree 5 and order 5 ``` -returns the list of all abelian primitive permutation groups acting on 3, 4 or 5 points. """ function all_primitive_groups(L...) @req !isempty(L) "must specify at least one filter" + if L[1] isa IntegerUnion || L[1] isa AbstractVector{<:IntegerUnion} + L = (degree => L[1], L[2:end]...) + end gapargs = translate_group_library_args(L; filter_attrs = _permgroup_filter_attrs) K = GAP.Globals.AllPrimitiveGroups(gapargs...) return [PermGroup(x) for x in K] end -function all_primitive_groups(deg::Integer) - return all_primitive_groups(degree => deg) -end - -function all_primitive_groups(degs::Vector{<:Integer}) - return all_primitive_groups(degree => degs) -end - -function all_primitive_groups(degs::AbstractRange{<:Integer}) - return all_primitive_groups(degree => degs) -end - # TODO: turn this into an iterator, possibly using PrimitiveGroupsIterator diff --git a/src/Groups/libraries/transitivegroups.jl b/src/Groups/libraries/transitivegroups.jl index 4ea05ef7bf81..a6e1d50c2be3 100644 --- a/src/Groups/libraries/transitivegroups.jl +++ b/src/Groups/libraries/transitivegroups.jl @@ -159,6 +159,10 @@ may be of one of the following forms: - `func` selects groups for which the function `func` returns `true` - `!func` selects groups for which the function `func` returns `false` +As a special case, the first argument may also be one of the following: +- `intval` selects groups whose degree equals `intval`; this is equivalent to `degree => intval` +- `intlist` selects groups whose degree is in `intlist`; this is equivalent to `degree => intlist` + The following functions are currently supported as values for `func`: - `degree` - `is_abelian` @@ -180,9 +184,6 @@ The following functions are currently supported as values for `func`: The type of the returned groups is `PermGroup`. -If no conditions beside the degree are used, one can also use the shorthand -`all_transitive_groups(degree)` where `degree` is an integer or a list or range of integers. - # Examples ```jldoctest julia> all_transitive_groups(4) @@ -200,24 +201,15 @@ julia> all_transitive_groups(degree => 3:5, is_abelian) Permutation group of degree 4 Permutation group of degree 5 ``` -returns the list of all abelian transitive groups acting on 3, 4 or 5 points. """ function all_transitive_groups(L...) + @req !isempty(L) "must specify at least one filter" + if L[1] isa IntegerUnion || L[1] isa AbstractVector{<:IntegerUnion} + L = (degree => L[1], L[2:end]...) + end gapargs = translate_group_library_args(L; filter_attrs = _permgroup_filter_attrs) K = GAP.Globals.AllTransitiveGroups(gapargs...) return [PermGroup(x) for x in K] end -function all_transitive_groups(deg::Integer) - return all_transitive_groups(degree => deg) -end - -function all_transitive_groups(degs::Vector{<:Integer}) - return all_transitive_groups(degree => degs) -end - -function all_transitive_groups(degs::AbstractRange{<:Integer}) - return all_transitive_groups(degree => degs) -end - # TODO: turn this into an iterator, possibly using PrimitiveGroupsIterator diff --git a/test/Groups/libraries.jl b/test/Groups/libraries.jl index 81bec96db549..62d388c26c86 100644 --- a/test/Groups/libraries.jl +++ b/test/Groups/libraries.jl @@ -87,6 +87,9 @@ end @test issetequal(all_transitive_groups(3:2:9), all_transitive_groups(degree => 3:2:9)) @test issetequal(all_transitive_groups(collect(3:2:9)), all_transitive_groups(3:2:9)) @test issetequal(reduce(vcat, (all_transitive_groups(i) for i in 3:2:9)), all_transitive_groups(3:2:9)) + + @test issetequal(all_transitive_groups(3:2:9, is_abelian), all_transitive_groups(degree => 3:2:9, is_abelian)) + @test issetequal(all_transitive_groups(9, is_abelian), all_transitive_groups(degree => 9, is_abelian)) end @testset "Perfect groups" begin @@ -164,6 +167,9 @@ end @test issetequal(all_primitive_groups(3:2:9), all_primitive_groups(degree => 3:2:9)) @test issetequal(all_primitive_groups(collect(3:2:9)), all_primitive_groups(3:2:9)) @test issetequal(reduce(vcat, (all_primitive_groups(i) for i in 3:2:9)), all_primitive_groups(3:2:9)) + + @test issetequal(all_primitive_groups(3:2:9, is_abelian), all_primitive_groups(degree => 3:2:9, is_abelian)) + @test issetequal(all_primitive_groups(9, is_abelian), all_primitive_groups(degree => 9, is_abelian)) end @testset "Atlas groups" begin From 6e1af5555aaf240401affcfdd0d41b2439587581 Mon Sep 17 00:00:00 2001 From: Thomas Breuer Date: Mon, 26 Feb 2024 21:08:20 +0100 Subject: [PATCH 10/30] support `gen(G::GAPGroup, 0)` (#3332) * support `gen(G::GAPGroup, 0)` This was already supported for `FinGenAbGroup`. (The delegations between methods are not the same: For `FinGenAbGroup`, there is special code for `getindex(A, i)`, and `gen(A, i)` calls `getindes(A, i)`. For `GAPGroup`, there is special code for `gen(G, i)`, and the generic `getindex` method from AbstractAlgebra calls `gen(G, i)`.) * support negative indices, meaning inverses (cherry picked from commit 58566cc5f165cf74800ee3a78fa74e5d3b6cae4e) --- src/Groups/GAPGroups.jl | 24 +++++++++++++++++++----- src/Groups/matrices/MatGrp.jl | 10 +++++++++- test/Groups/conformance.jl | 7 +++++++ test/Groups/elements.jl | 7 +++++-- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/Groups/GAPGroups.jl b/src/Groups/GAPGroups.jl index f6f442c7a799..ddbbb226e0f9 100644 --- a/src/Groups/GAPGroups.jl +++ b/src/Groups/GAPGroups.jl @@ -445,16 +445,30 @@ has_gens(G::GAPGroup) = GAP.Globals.HasGeneratorsOfGroup(G.X)::Bool """ gen(G::GAPGroup, i::Int) -Return the `i`-th element of the vector `gens(G)`. -This is equivalent to `G[i]`, and returns `gens(G)[i]` +Return `one(G)` if `i == 0`, +the `i`-th element of the vector `gens(G)` if `i` is positive, +and the inverse of the `i`-th element of `gens(G)` if `i` is negative. + +For positive `i`, this is equivalent to `G[i]`, and returns `gens(G)[i]` but may be more efficient than the latter. -An exception is thrown if `i` is larger than the length of `gens(G)`. +An exception is thrown if `abs(i)` is larger than the length of `gens(G)`. + +# Examples +```jldoctest +julia> g = symmetric_group(5); gen(g, 1) +(1,2,3,4,5) + +julia> g[-1] +(1,5,4,3,2) +``` """ function gen(G::GAPGroup, i::Int) + i == 0 && return one(G) L = GAPWrap.GeneratorsOfGroup(G.X)::GapObj - @assert length(L) >= i "The number of generators is lower than the given index" - return group_element(G, L[i]::GapObj) + 0 < i && i <= length(L) && return group_element(G, L[i]::GapObj) + i < 0 && -i <= length(L) && return group_element(G, inv(L[-i])::GapObj) + @req false "i must be in the range -$(length(L)):$(length(L))" end """ diff --git a/src/Groups/matrices/MatGrp.jl b/src/Groups/matrices/MatGrp.jl index 92896f6d0339..d33caf09a926 100644 --- a/src/Groups/matrices/MatGrp.jl +++ b/src/Groups/matrices/MatGrp.jl @@ -505,7 +505,15 @@ function gens(G::MatrixGroup) return G.gens end -gen(G::MatrixGroup, i::Int) = gens(G)[i] +# Note that the `gen(G::GAPGroup, i::Int)` method cannot be used +# for `MatrixGroup` because of the `:gens` attribute. +function gen(G::MatrixGroup, i::Int) + i == 0 && return one(G) + L = gens(G) + 0 < i && i <= length(L) && return L[i] + i < 0 && -i <= length(L) && return inv(L[-i]) + @req false "i must be in the range -$(length(L)):$(length(L))" +end number_of_generators(G::MatrixGroup) = length(gens(G)) diff --git a/test/Groups/conformance.jl b/test/Groups/conformance.jl index 9f53c15767aa..e92c09bf2530 100644 --- a/test/Groups/conformance.jl +++ b/test/Groups/conformance.jl @@ -33,6 +33,13 @@ include(joinpath(dirname(pathof(AbstractAlgebra)), "..", "test", "Groups-conform @test ngens(G) isa Int @test gens(G) isa Vector{typeof(g)} + @test G[0] == one(G) + l = ngens(G) + @test G[l] == gen(G, l) + @test G[-l] == inv(gen(G, l)) + @test_throws ArgumentError G[l+1] + @test_throws ArgumentError G[-l-1] + if is_finite(G) @test order(G) isa ZZRingElem @test order(G) > 0 diff --git a/test/Groups/elements.jl b/test/Groups/elements.jl index e72549e4bff0..8c4f036be432 100644 --- a/test/Groups/elements.jl +++ b/test/Groups/elements.jl @@ -138,11 +138,14 @@ end @test K[i] == G[i] @test K[i] == gen(G,i) end + @test G[0] == gen(G, 0) + @test G[0] == one(G) + @test_throws BoundsError K[0] end G = free_group(2) - @test_throws AssertionError gen(G, 3) - @test_throws ErrorException gen(G, 0) + @test_throws ArgumentError gen(G, 3) + @test_throws ArgumentError gen(G, -3) end @testset "deepcopy" begin From 28e5dab319adcd534ea23a49887b6e35f49d036f Mon Sep 17 00:00:00 2001 From: Benjamin Lorenz Date: Tue, 27 Feb 2024 11:17:10 +0100 Subject: [PATCH 11/30] CI: re-enable nightly (#3435) (cherry picked from commit bb7fe0817f0805a5400754a0204627176d2809cb) --- .github/workflows/CI.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8e54e01828a1..6773b5b79097 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -32,7 +32,7 @@ jobs: - '1.9' # to be removed in the near future - '1.10' - '1.11-nightly' - #- 'nightly' + - 'nightly' group: [ 'short', 'long' ] os: - ubuntu-latest @@ -114,7 +114,7 @@ jobs: - '1.9' # to be removed in the near future - '1.10' - '1.11-nightly' - #- 'nightly' + - 'nightly' os: - ubuntu-latest depwarn: [ '' ] From b7a68b78f4d0d009c52f23805a8c37129632eb3f Mon Sep 17 00:00:00 2001 From: Thomas Breuer Date: Tue, 27 Feb 2024 12:41:26 +0100 Subject: [PATCH 12/30] fix a docstring (#3436) (cherry picked from commit 52a2a88358b02f51f92ec76d7602948d9614bb44) --- src/Groups/gsets.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 4c67812fb99c..4e42d56293ec 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -111,7 +111,7 @@ Note that the indexing of points in `Omega` is used by ```jldoctest julia> G = symmetric_group(4); -julia> length(gset(G, [[1]])) # natural action +julia> length(gset(G, [1])) # natural action 4 julia> length(gset(G, [[1, 2]])) # action on ordered pairs From 78cfbc12b0aa1688ecb51afc8198bd847cb80a2f Mon Sep 17 00:00:00 2001 From: ederc Date: Tue, 27 Feb 2024 13:07:07 +0100 Subject: [PATCH 13/30] Fixes multivariate division (#3396) * uses new divrem from Singular, fits Singular's reduce * adds test case from issue #3105 * bump Singular to v0.22.4 for divrem2 * fixes doctests (cherry picked from commit 2cc501355073731e46eb7384cf55bb62b23b50a7) --- Project.toml | 2 +- src/Rings/groebner.jl | 17 ++++++----------- test/Rings/groebner.jl | 7 +++++++ 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/Project.toml b/Project.toml index 83742a388679..62644e446997 100644 --- a/Project.toml +++ b/Project.toml @@ -42,7 +42,7 @@ Preferences = "1" Random = "1.6" RandomExtensions = "0.4.3" Serialization = "1.6" -Singular = "0.22.3" +Singular = "0.22.4" TOPCOM_jll = "0.17.8" UUIDs = "1.6" cohomCalg_jll = "0.32.0" diff --git a/src/Rings/groebner.jl b/src/Rings/groebner.jl index 27f78a457047..6436a60ecc7b 100644 --- a/src/Rings/groebner.jl +++ b/src/Rings/groebner.jl @@ -719,8 +719,8 @@ julia> U [ 0 y + 1] julia> Q -[x^3 - x*y^2*z^2 + x*y + y^2*z^2 0 y*z^2 + z^2] -[ -3*y^2*z^2 - y*z x*y + x 0] +[ x^3 - x*y^2*z^2 + x*y + y^2*z^2 0 y*z^2 + z^2] +[x*y*z^2 + y^3*z - 3*y^2*z^2 - y*z -x^2*y*z - x^2*z + x*y + x 0] julia> H 2-element Vector{QQMPolyRingElem}: @@ -798,7 +798,7 @@ julia> reduce_with_quotients_and_unit(f, F) ([1], [x*y 10*x+1], x^4 + 10*x^3 + 1) julia> unit, M, res = reduce_with_quotients_and_unit(f, F, ordering=lex(R)) -([1], [0 y^2], y^6 + 10*y^4 + 1) +([1], [x*y 0], x*y^4 + 10*y^4 + 1) julia> M * F + [res] == unit * [f] true @@ -855,7 +855,7 @@ julia> reduce_with_quotients_and_unit(f, F) ([1], [x*y 10*x+1], x^4 + 10*x^3 + 1) julia> unit, M, res = reduce_with_quotients_and_unit(f, F, ordering=lex(R)) -([1], [0 y^2], y^6 + 10*y^4 + 1) +([1], [x*y 0], x*y^4 + 10*y^4 + 1) julia> M * F + [res] == unit * [f] true @@ -881,11 +881,6 @@ Return a `Vector` which contains, for each element `g` of `G`, quotients and a r !!! note The returned remainders are fully reduced if `complete_reduction` is set to `true` and `ordering` is global. -!!! note - The reduction strategy behind the `reduce` function and the reduction strategy behind the functions - `reduce_with_quotients` and `reduce_with_quotients_and_unit` differ. As a consequence, the computed - remainders may differ. - # Examples ```jldoctest @@ -898,7 +893,7 @@ julia> g = x^3*y+x^5+x^2*y^2*z^2+z^6; julia> Q, h = reduce_with_quotients(g, [f1,f2, f3], ordering = lex(R)); julia> h --z^9 + z^7 + z^6 + z^4 +x^5 - x^3 + y^6 + z^6 julia> g == Q[1]*f1+Q[2]*f2+Q[3]*f3+h true @@ -929,7 +924,7 @@ function _reduce_with_quotients_and_unit(I::IdealGens, J::IdealGens, ordering::M @assert base_ring(J) == base_ring(I) sI = singular_generators(I, ordering) sJ = singular_generators(J, ordering) - res = Singular.divrem(sI, sJ, complete_reduction=complete_reduction) + res = Singular.divrem2(sI, sJ, complete_reduction=complete_reduction) return matrix(base_ring(I), res[3]), matrix(base_ring(I), res[1]), [J.gens.Ox(x) for x = gens(res[2])] end diff --git a/test/Rings/groebner.jl b/test/Rings/groebner.jl index a06d2e390259..37a592d6692a 100644 --- a/test/Rings/groebner.jl +++ b/test/Rings/groebner.jl @@ -59,6 +59,13 @@ @test q * F + [r] != [f] u, q, r = reduce_with_quotients_and_unit(f, F, ordering=neglex(R)) @test q * F + [r] == u * [f] + # Issue 3105 + R, (x,y,z) = QQ[:x, :y, :z] + f = x^3 - x^2*y - x^2*z + x + f1 = x^2*y - z + f2 = x*y - 1 + _,r = reduce_with_quotients(f, [f1, f2], ordering = deglex(R)) + @test r == x^3-x^2*z I = ideal(R,[y^2 - x, x^3 - 2*y^2]) @test is_groebner_basis(I.gens, ordering=degrevlex(R)) == true @test is_groebner_basis(I.gens, ordering=lex(R)) == false From 0a84f77f23bb0976e330795cbbc1ea6f2c9260a2 Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Tue, 27 Feb 2024 16:13:30 +0100 Subject: [PATCH 14/30] Docu invariants tori (#3428) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add test example to PR #3412 as requested by @thofma * docu invariants tori * readd algebraic.md * typo * Update docs/doc.main * add one more functions and corrections * correction * correction * addressing review * forgot to add corrected file --------- Co-authored-by: Lars Göttgens (cherry picked from commit 3c5f7fe06f36d1ba33878104a2ef251e275a8284) --- docs/doc.main | 3 +- docs/src/InvariantTheory/finite_groups.md | 2 +- docs/src/InvariantTheory/intro.md | 13 +- docs/src/InvariantTheory/tori.md | 52 ++++ .../src/TorusInvariantsFast.jl | 258 ++++++++++++++++-- 5 files changed, 292 insertions(+), 36 deletions(-) create mode 100644 docs/src/InvariantTheory/tori.md diff --git a/docs/doc.main b/docs/doc.main index 68d4dc4eab16..46971f090551 100644 --- a/docs/doc.main +++ b/docs/doc.main @@ -57,7 +57,7 @@ "Nemo/qadic.md", ], "Nemo/finitefield.md", - "Nemo/algebraic.md", + "Nemo/algebraic.md", "Fields/algebraic_closure_fp.md", ], @@ -153,6 +153,7 @@ "Invariant Theory" => [ "InvariantTheory/intro.md", "InvariantTheory/finite_groups.md", + "InvariantTheory/tori.md", "InvariantTheory/reductive_groups.md", ], diff --git a/docs/src/InvariantTheory/finite_groups.md b/docs/src/InvariantTheory/finite_groups.md index 486fbadde0dc..04e67f731cf2 100644 --- a/docs/src/InvariantTheory/finite_groups.md +++ b/docs/src/InvariantTheory/finite_groups.md @@ -41,7 +41,7 @@ We discuss the relevant OSCAR functionality below. ## Creating Invariant Rings -### How Groups are Given +### How Finite Groups are Given The invariant theory part of OSCAR distinguishes two ways of how finite groups and their actions on $K[x_1, \dots, x_n]\cong K[V]$ are specified: diff --git a/docs/src/InvariantTheory/intro.md b/docs/src/InvariantTheory/intro.md index 6833e31c2dbb..8f84884d9e99 100644 --- a/docs/src/InvariantTheory/intro.md +++ b/docs/src/InvariantTheory/intro.md @@ -9,11 +9,11 @@ of group actions, focusing on finite and linearly reductive groups, respectively The basic setting in this context consists of a group $G$, a field $K$, a vector space $V$ over $K$ of finite dimension $n,$ and a representation $\rho: G \to \text{GL}(V)$ of $G$ on $V$. -The induced action on the dual vector space $V^\ast$, +The induced right action on the dual vector space $V^\ast$, $V^\ast \times G \to V^\ast, (f, \pi)\mapsto f \;\! . \;\! \pi := f\circ \rho(\pi),$ -extends to an action of $G$ on the graded symmetric algebra +extends to a right action of $G$ on the graded symmetric algebra $K[V]:=S(V^*)=\bigoplus_{d\geq 0} S^d V^*$ @@ -23,12 +23,11 @@ The *invariants* of $G$ are the fixed points of this action, its *invariant ring $K[V]^G:=\{f\in K[V] \mid f \;\! . \;\! \pi =f {\text { for any }} \pi\in G\} \subset K[V].$ -Explicitly, the choice of a basis of $V$ and its dual basis, say, $\{x_1, \dots, x_n\}$ of $V^*$ -gives rise to isomorphisms $\text{GL}(V) \cong \text{GL}_n(K)$ and $K[V]\cong K[x_1, \dots, x_n]$. -After identifying $\text{GL}(V)$ with $\text{GL}_n(K)$ and $K[V]$ with $K[x_1, \dots, x_n]$ by means of -these isomorphisms, the action of $G$ on $K[V]$ is given as follows: +Explicitly, fixing a basis of $V$ and its dual basis, say, $\{x_1, \dots, x_n\}$ of $V^*$, +we may identify $\GL(V) \cong \GL_n(K)$ and $K[V]\cong K[x_1, \dots, x_n]$. +Then the action of an element $\pi \in G$ with $\rho(\pi) = (a_{i, j})$ on a polynomial $f\in K[x_1,\dots, x_n]$ is given as follows: -$(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f((x_1, \dots, x_n) \cdot \rho(\pi)).$ +$(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f\bigl(\sum_j a_{1, j}x_j, \dots, \sum_j a_{n, j}x_j\bigr).$ Accordingly, $K[V]^G$ may be regarded as a graded subalgebra of $K[x_1, \dots, x_n]$: diff --git a/docs/src/InvariantTheory/tori.md b/docs/src/InvariantTheory/tori.md new file mode 100644 index 000000000000..ef9fbdbfc939 --- /dev/null +++ b/docs/src/InvariantTheory/tori.md @@ -0,0 +1,52 @@ +```@meta +CurrentModule = Oscar +``` + +# Invariants of Tori +In this section, with notation as in the introduction to this chapter, $T =(K^{\ast})^m$ will be a torus of rank $m$ +over a field $K$. To compute invariants of diagonal torus actions, OSCAR makes use of Algorithm 4.3.1 in [DK15](@cite) which, +in particular, relies on algorithmic means from polyhedral geometry. + +## Creating Invariant Rings + +### How Tori and Their Representations are Given + +```@docs + torus_group(F::Field, n::Int) +``` + +```@docs +rank(T::TorusGroup) +``` + +```@docs +field(T::TorusGroup) +``` + +```@docs +representation_from_weights(T::TorusGroup, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}}) +``` + +```@docs +group(r::RepresentationTorusGroup) +``` + +### Constructor for Invariant Rings + +```@docs +invariant_ring(r::RepresentationTorusGroup) +``` + + +## Fundamental Systems of Invariants + +```@docs +fundamental_invariants(RT::TorGrpInvRing) +``` + + +## Invariant Rings as Affine Algebras + +```@docs +affine_algebra(RT::TorGrpInvRing) +``` diff --git a/experimental/InvariantTheory/src/TorusInvariantsFast.jl b/experimental/InvariantTheory/src/TorusInvariantsFast.jl index f778f19f2549..05c90697852f 100644 --- a/experimental/InvariantTheory/src/TorusInvariantsFast.jl +++ b/experimental/InvariantTheory/src/TorusInvariantsFast.jl @@ -1,20 +1,62 @@ -export torus_group, rank, field, representation_from_weights, weights, group, invariant_ring, poly_ring, representation, fundamental_invariants +export torus_group, rank, field, representation_from_weights, weights, group, invariant_ring, poly_ring, representation, fundamental_invariants, affine_algebra ##################### -#Setting up reductive groups for fast torus algorithm +#Setting up tori for fast torus algorithm ##################### -struct ReductiveGroupFastTorus +struct TorusGroup field::Field - rank::Int + rank::Int #weights::Vector{Vector{ZZRingElem}} end -torus_group(F::Field, n::Int) = ReductiveGroupFastTorus(F,n) -rank(G::ReductiveGroupFastTorus) = G.rank -field(G::ReductiveGroupFastTorus) = G.field +@doc raw""" + torus_group(K::Field, m::Int) -function Base.show(io::IO, G::ReductiveGroupFastTorus) +Return the torus $(K^{\ast})^m$. + +!!! note + In the context of computing invariant rings, there is no need to deal with the group structure of a torus: The torus $(K^{\ast})^m$ is specified by just giving $K$ and $m$. +# Examples +```jldoctest +julia> T = torus_group(QQ,2) +Torus of rank 2 + over QQ +``` +""" +torus_group(F::Field, n::Int) = TorusGroup(F,n) + +@doc raw""" + rank(T::TorusGroup) + +Return the rank of `T`. + +# Examples +```jldoctest +julia> T = torus_group(QQ,2); + +julia> rank(T) +2 +``` +""" +rank(G::TorusGroup) = G.rank + +@doc raw""" + field(T::TorusGroup) + +Return the field over which `T` is defined. + +# Examples +```jldoctest +julia> T = torus_group(QQ,2); + +julia> field(T) +Rational field +``` +""" +field(G::TorusGroup) = G.field + +function Base.show(io::IO, G::TorusGroup) io = pretty(io) println(io, "Torus of rank ", rank(G)) print(IOContext(io, :supercompact => true), Indent(), "over ", Lowercase(), field(G)) @@ -25,15 +67,30 @@ end #Setting up weights for fast torus algorithm ##################### -struct RepresentationReductiveGroupFastTorus - group::ReductiveGroupFastTorus +struct RepresentationTorusGroup + group::TorusGroup weights::Vector{Vector{ZZRingElem}} end -function representation_from_weights(G::ReductiveGroupFastTorus, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}}) +@doc raw""" + representation_from_weights(T::TorusGroup, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}}) + +Return the diagonal action of `T` with weights given by `W`. + +# Examples +```jldoctest +julia> T = torus_group(QQ,2); + +julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]) +Representation of torus of rank 2 + over QQ and weights + Vector{ZZRingElem}[[-1, 1], [-1, 1], [2, -2], [0, -1]] +``` +""" +function representation_from_weights(G::TorusGroup, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}}) n = rank(G) V = weights_from_matrix(n,W) - return RepresentationReductiveGroupFastTorus(G,V) + return RepresentationTorusGroup(G,V) end function weights_from_matrix(n::Int, W::Union{ZZMatrix, Matrix{<:Integer}, Vector{<:Int}}) @@ -53,10 +110,44 @@ function weights_from_matrix(n::Int, W::Union{ZZMatrix, Matrix{<:Integer}, Vecto return V end -weights(R::RepresentationReductiveGroupFastTorus) = R.weights -group(R::RepresentationReductiveGroupFastTorus) = R.group +@doc raw""" + weights(r::RepresentationTorusGroup) + +# Examples +```jldoctest +julia> T = torus_group(QQ,2); + +julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]); + +julia> weights(r) +4-element Vector{Vector{ZZRingElem}}: + [-1, 1] + [-1, 1] + [2, -2] + [0, -1] +``` +""" +weights(R::RepresentationTorusGroup) = R.weights + +@doc raw""" + group(r::RepresentationTorusGroup) + +Return the torus group represented by `r`. -function Base.show(io::IO, R::RepresentationReductiveGroupFastTorus) +# Examples +```jldoctest +julia> T = torus_group(QQ,2); + +julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]); + +julia> group(r) +Torus of rank 2 + over QQ +``` +""" +group(R::RepresentationTorusGroup) = R.group + +function Base.show(io::IO, R::RepresentationTorusGroup) io = pretty(io) println(io, "Representation of torus of rank ", rank(group(R))) println(IOContext(io, :supercompact => true), Indent(), "over ", Lowercase(), field(group(R)), " and weights ") @@ -68,24 +159,24 @@ end #Setting up invariant ring for fast torus algorithm. ##################### -mutable struct InvariantRingFastTorus +mutable struct TorGrpInvRing field::Field poly_ring::MPolyDecRing #graded - group::ReductiveGroupFastTorus - representation::RepresentationReductiveGroupFastTorus + group::TorusGroup + representation::RepresentationTorusGroup fundamental::Vector{MPolyDecRingElem} #Invariant ring of reductive group G (in representation R), no other input. - function InvariantRingFastTorus(R::RepresentationReductiveGroupFastTorus) #here G already contains information n and rep_mat + function TorGrpInvRing(R::RepresentationTorusGroup) #here G already contains information n and rep_mat n = length(weights(R)) super_ring, __ = graded_polynomial_ring(field(group(R)), "X"=>1:n) - return InvariantRingFastTorus(R, super_ring) + return TorGrpInvRing(R, super_ring) end #to compute invariant ring ring^G where G is the reductive group of R. - function InvariantRingFastTorus(R::RepresentationReductiveGroupFastTorus, ring_::MPolyDecRing) + function TorGrpInvRing(R::RepresentationTorusGroup, ring_::MPolyDecRing) z = new() n = length(weights(R)) z.field = field(group(R)) @@ -96,12 +187,84 @@ mutable struct InvariantRingFastTorus end end -invariant_ring(R::RepresentationReductiveGroupFastTorus) = InvariantRingFastTorus(R) -poly_ring(R::InvariantRingFastTorus) = R.poly_ring -group(R::InvariantRingFastTorus) = R.group -representation(R::InvariantRingFastTorus) = R.representation +@doc raw""" + invariant_ring(r::RepresentationTorusGroup) + +Return the invariant ring of the torus group represented by `r`. + +!!! note + The creation of invariant rings is lazy in the sense that no explicit computations are done until specifically invoked (for example, by the `fundamental_invariants` function). + +# Examples +```jldoctest +julia> T = torus_group(QQ,2); -function fundamental_invariants(z::InvariantRingFastTorus) +julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]); + +julia> RT = invariant_ring(r) +Invariant Ring of +graded multivariate polynomial ring in 4 variables over QQ under group action of torus of rank2 +``` +""" +invariant_ring(R::RepresentationTorusGroup) = TorGrpInvRing(R) + +@doc raw""" + poly_ring(RT::TorGrpInvRing) + +# Examples +```jldoctest +julia> T = torus_group(QQ,2) +Torus of rank 2 + over QQ +``` +""" +poly_ring(R::TorGrpInvRing) = R.poly_ring + +@doc raw""" + group(RT::TorGrpInvRing) + +# Examples +```jldoctest +julia> T = torus_group(QQ,2) +Torus of rank 2 + over QQ +``` +""" +group(R::TorGrpInvRing) = R.group + +@doc raw""" + representation(RT::TorGrpInvRing) + +# Examples +```jldoctest +julia> T = torus_group(QQ,2) +Torus of rank 2 + over QQ +``` +""" +representation(R::TorGrpInvRing) = R.representation + +@doc raw""" + fundamental_invariants(RT::TorGrpInvRing) + +Return a system of fundamental invariants for `RT`. + +# Examples +```jldoctest +julia> T = torus_group(QQ,2); + +julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]); + +julia> RT = invariant_ring(r); + +julia> fundamental_invariants(RT) +3-element Vector{MPolyDecRingElem}: + X[1]^2*X[3] + X[1]*X[2]*X[3] + X[2]^2*X[3] +``` +""" +function fundamental_invariants(z::TorGrpInvRing) if isdefined(z, :fundamental) return z.fundamental else @@ -111,7 +274,7 @@ function fundamental_invariants(z::InvariantRingFastTorus) end end -function Base.show(io::IO, R::InvariantRingFastTorus) +function Base.show(io::IO, R::TorGrpInvRing) io = pretty(io) println(io, "Invariant Ring of") print(io, Lowercase(), R.poly_ring) @@ -123,6 +286,7 @@ end #fast algorithm for invariants of tori ########################## #Algorithm 4.3.1 from Derksen and Kemper. Computes Torus invariants without Reynolds operator. + function torus_invariants_fast(W::Vector{Vector{ZZRingElem}}, R::MPolyRing) #no check that length(W[i]) for all i is the same length(W) == ngens(R) || error("number of weights must be equal to the number of generators of the polynomial ring") @@ -206,3 +370,43 @@ function torus_invariants_fast(W::Vector{Vector{ZZRingElem}}, R::MPolyRing) end end end + +#####################Invariant rings as affine algebras + +@doc raw""" + affine_algebra(RT::TorGrpInvRing) + +Return the invariant ring `RT` as an affine algebra (this amounts to compute the algebra syzygies among the fundamental invariants of `RT`). + +In addition, if `A` is this algebra, and `R` is the polynomial ring of which `RT` is a subalgebra, +return the inclusion homomorphism `A` $\hookrightarrow$ `R` whose image is `RT`. + +# Examples +```jldoctest +julia> T = torus_group(QQ,2); + +julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]); + +julia> RT = invariant_ring(r); + +julia> fundamental_invariants(RT) +3-element Vector{MPolyDecRingElem}: + X[1]^2*X[3] + X[1]*X[2]*X[3] + X[2]^2*X[3] + +julia> affine_algebra(RT) +(Quotient of multivariate polynomial ring by ideal (-t[1]*t[3] + t[2]^2), Hom: quotient of multivariate polynomial ring -> graded multivariate polynomial ring) +``` +""" +function affine_algebra(R::TorGrpInvRing) + V = fundamental_invariants(R) + s = length(V) + S,t = polynomial_ring(field(group(representation(R))), "t"=>1:s) + R_ = poly_ring(R) + StoR = hom(S,R_,V) + I = kernel(StoR) + Q, StoQ = quo(S,I) + QtoR = hom(Q,R_,V) + return Q, QtoR +end From 1bcfe916c903ad0fa84adf58d1ad3527adad3254 Mon Sep 17 00:00:00 2001 From: Matthias Zach <85350711+HechtiDerLachs@users.noreply.github.com> Date: Tue, 27 Feb 2024 20:09:17 +0100 Subject: [PATCH 15/30] Bugfix for printing of affine schemes (#3437) * Fix printing of of affine schemes. (cherry picked from commit 2a87512f7477d06831f6b2084c2ff096d3d156f8) --- .../Schemes/MorphismFromRationalFunctions.jl | 2 +- .../AffineSchemes/Objects/Constructors.jl | 2 +- .../Schemes/AffineSchemes/Objects/Methods.jl | 24 ++++++++++++++----- src/Rings/mpoly-localizations.jl | 2 +- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/experimental/Schemes/MorphismFromRationalFunctions.jl b/experimental/Schemes/MorphismFromRationalFunctions.jl index 22187071e7f5..3c7746fc872e 100644 --- a/experimental/Schemes/MorphismFromRationalFunctions.jl +++ b/experimental/Schemes/MorphismFromRationalFunctions.jl @@ -134,7 +134,7 @@ julia> realizations = Oscar.realize_on_patch(Phi, U); julia> realizations[3] Affine scheme morphism - from [(t//s)] AA^1 \ scheme() + from [(t//s)] AA^1 to [(x//z), (y//z)] affine 2-space given by the pullback function (x//z) -> (t//s)^2 diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl index dfd85beb8495..8bb117f648af 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Constructors.jl @@ -513,7 +513,7 @@ Spectrum of localization of multivariate polynomial ring in 3 variables x1, x2, x3 over rational field - at products of (x1,x2) + at products of (x1, x2) ``` """ function hypersurface_complement(X::AbsAffineScheme, f::Vector{<:RingElem}) diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl index 71ca2d2847c6..ee8e90981a93 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl @@ -76,18 +76,30 @@ function _show(io::IO, X::AbsAffineScheme{<:Any, <:MPolyQuoLocRing{<:Any, <:Any, I = modulus(OO(X)) S = inverted_set(OO(X)) join(io, gens(I), ", ") - print(io, raw") \ scheme(") - join(io, denominators(S), ",") - print(io, ")") + if is_empty(denominators(S)) + print(io, raw")") + elseif isone(length(denominators(S))) + print(io, raw") \ scheme(", first(denominators(S)), ")") + else + print(io, raw") \ scheme((") + join(io, denominators(S), ")*(") + print(io, "))") + end end function _show(io::IO, X::AbsAffineScheme{<:Any, <:MPolyLocRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}) io = pretty(io) print(io, LowercaseOff(), "AA^", ngens(OO(X))) S = inverted_set(OO(X)) - print(io, raw" \ scheme(") - join(io, denominators(S), ",") - print(io, ")") + if is_empty(denominators(S)) + # do nothing more + elseif isone(length(denominators(S))) + print(io, raw" \ scheme(", first(denominators(S)), ")") + else + print(io, raw" \ scheme((") + join(io, denominators(S), ")*(") + print(io, "))") + end end ######################################################## diff --git a/src/Rings/mpoly-localizations.jl b/src/Rings/mpoly-localizations.jl index 60ec70c6e97e..38da6198582f 100644 --- a/src/Rings/mpoly-localizations.jl +++ b/src/Rings/mpoly-localizations.jl @@ -125,7 +125,7 @@ function Base.show(io::IO, S::MPolyPowersOfElement) print(io, ItemQuantity(length(denominators(S)), "element")) else print(io, "Products of (") - join(io, denominators(S), ",") + join(io, denominators(S), ", ") print(io, ")") end end From b4bb046c05b198472c00d8213789e8f31fe04a65 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Wed, 28 Feb 2024 09:31:54 +0100 Subject: [PATCH 16/30] Improve docstrings for `is_conjugate`/`is_conjugate_with_data`. (#3384) (cherry picked from commit 95a1e27478b5a30fc3023d7cfd84a336c13013bc) --- src/Groups/GAPGroups.jl | 18 +++++++++++++----- src/Groups/gsets.jl | 6 ++++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/Groups/GAPGroups.jl b/src/Groups/GAPGroups.jl index ddbbb226e0f9..81e5fc9af723 100644 --- a/src/Groups/GAPGroups.jl +++ b/src/Groups/GAPGroups.jl @@ -724,7 +724,8 @@ end is_conjugate(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem) Return whether `x` and `y` are conjugate elements in `G`, -i.e., there is an element $z$ in `G` such that `x^`$z$ equals `y`. +i.e., there is an element `z` in `G` such that `x^z` equals `y`. +To also return the element `z`, use [`is_conjugate_with_data`](@ref). """ function is_conjugate(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem) if isdefined(G,:descr) && (G.descr == :GL || G.descr == :SL) @@ -739,6 +740,8 @@ end If `x` and `y` are conjugate in `G`, return `(true, z)`, where `x^z == y` holds; otherwise, return `(false, nothing)`. +If the conjugating element `z` is not needed, +use [`is_conjugate`](@ref). """ function is_conjugate_with_data(G::GAPGroup, x::GAPGroupElem, y::GAPGroupElem) if isdefined(G,:descr) && (G.descr == :GL || G.descr == :SL) @@ -925,10 +928,13 @@ Base.:^(H::GAPGroup, y::GAPGroupElem) = conjugate_group(H, y) # (The name is confusing because it is not clear *of which group* the result # shall be a subgroup.) -""" +@doc raw""" is_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup) -Return whether `H` and `K` are conjugate subgroups in `G`. +Return whether `H` and `K` are conjugate subgroups in `G`, +i.e., whether there exists an element `z` in `G` such that +`H^z` equals `K`. To also return the element `z` +use [`is_conjugate_with_data`](@ref). # Examples ```jldoctest @@ -956,8 +962,10 @@ is_conjugate(G::GAPGroup, H::GAPGroup, K::GAPGroup) = GAPWrap.IsConjugate(G.X,H. """ is_conjugate_with_data(G::Group, H::Group, K::Group) -If `H` and `K` are conjugate subgroups in `G`, return `true, z` -where `H^z = K`; otherwise, return `false, nothing`. +If `H` and `K` are conjugate subgroups in `G`, return `(true, z)` +where `H^z = K`; otherwise, return `(false, nothing)`. +If the conjugating element `z` is not needed, use +[`is_conjugate`](@ref). # Examples ```jldoctest diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 4e42d56293ec..3ed5d2aa1464 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -687,6 +687,7 @@ end Return `true` if `omega1`, `omega2` are in the same orbit of `Omega`, and `false` otherwise. +To also obtain a conjugating element use [`is_conjugate_with_data`](@ref). # Examples ```jldoctest @@ -709,9 +710,10 @@ is_conjugate(Omega::GSet, omega1, omega2) = omega2 in orbit(Omega, omega1) is_conjugate_with_data(Omega::GSet, omega1, omega2) Determine whether `omega1`, `omega2` are in the same orbit of `Omega`. -If yes, return `true, g` where `g` is an element in the group `G` of +If yes, return `(true, g)` where `g` is an element in the group `G` of `Omega` that maps `omega1` to `omega2`. -If not, return `false, nothing`. +If not, return `(false, nothing)`. +If the conjugating element `g` is not needed, use [`is_conjugate`](@ref). # Examples ```jldoctest From 9bcd11945946d91785d18d69d4caa25e365500c4 Mon Sep 17 00:00:00 2001 From: Tommy Hofmann Date: Wed, 28 Feb 2024 10:46:23 +0100 Subject: [PATCH 17/30] Bugfix for bugfix for printing of affine schemes (#3445) (cherry picked from commit 62d3c125ff06c83e029181fe86dfc62d6dbe2e34) --- .../Schemes/AffineSchemes/Objects/Methods.jl | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl index ee8e90981a93..dac6bc6efb00 100644 --- a/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl +++ b/src/AlgebraicGeometry/Schemes/AffineSchemes/Objects/Methods.jl @@ -78,12 +78,18 @@ function _show(io::IO, X::AbsAffineScheme{<:Any, <:MPolyQuoLocRing{<:Any, <:Any, join(io, gens(I), ", ") if is_empty(denominators(S)) print(io, raw")") - elseif isone(length(denominators(S))) - print(io, raw") \ scheme(", first(denominators(S)), ")") else - print(io, raw") \ scheme((") - join(io, denominators(S), ")*(") - print(io, "))") + AA = AbstractAlgebra + PP = AbstractAlgebra.PrettyPrinting + print(io, raw") \ ") + AA.show_obj(io, + MIME("text/plain"), + PP.canonicalize(Expr(:call, + :scheme, + Expr(:call, :*, PP.expressify.(denominators(S))...) + ) + ) + ) end end @@ -93,12 +99,18 @@ function _show(io::IO, X::AbsAffineScheme{<:Any, <:MPolyLocRing{<:Any, <:Any, <: S = inverted_set(OO(X)) if is_empty(denominators(S)) # do nothing more - elseif isone(length(denominators(S))) - print(io, raw" \ scheme(", first(denominators(S)), ")") else - print(io, raw" \ scheme((") - join(io, denominators(S), ")*(") - print(io, "))") + AA = AbstractAlgebra + PP = AbstractAlgebra.PrettyPrinting + print(io, raw" \ ") + AA.show_obj(io, + MIME("text/plain"), + PP.canonicalize(Expr(:call, + :scheme, + Expr(:call, :*, PP.expressify.(denominators(S))...) + ) + ) + ) end end From 64177dcf175de80f2b13c775524d09b440123653 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 28 Feb 2024 10:51:26 +0100 Subject: [PATCH 18/30] Fix ambient_module(M::SubquoModule) (#3448) (cherry picked from commit 318a2c5cc1868e717f555e71e309f4e9b7f669fe) --- src/Modules/UngradedModules/SubquoModule.jl | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/Modules/UngradedModules/SubquoModule.jl b/src/Modules/UngradedModules/SubquoModule.jl index 23befe8994db..83821631c1d2 100644 --- a/src/Modules/UngradedModules/SubquoModule.jl +++ b/src/Modules/UngradedModules/SubquoModule.jl @@ -1657,8 +1657,23 @@ If $M = (P + Q) / Q$ then return $F / Q$ where `F == ambient_free_module(M)`. If $M$ is a submodule of a free module, then the (ambient) free module is returned. If `task == :with_morphism`, return also the canonical inclusion. + +# Examples + +```jldoctest +julia> mat = matrix(QQ, [0 -1; 0 0]); + +julia> U = image(mat) +Submodule with 1 generator +1 -> -e[2] +represented as subquotient with no relations. + +julia> ambient_module(U) +Free module of rank 2 over Rational field +``` """ function ambient_module(M::SubquoModule, task = :none) + F = ambient_free_module(M) if !isdefined(M, :quo) if task == :none return F @@ -1666,7 +1681,6 @@ function ambient_module(M::SubquoModule, task = :none) return F, hom(M,F,[repres(v) for v in gens(M)]) end end - F = ambient_free_module(M) g = SubModuleOfFreeModule(F,basis(F)) SQ = SubquoModule(g, M.quo) if task == :none From 79bc563195e5f80dcafc0d0226b01d6470a00c44 Mon Sep 17 00:00:00 2001 From: Erik Paemurru <143521159+paemurru@users.noreply.github.com> Date: Wed, 28 Feb 2024 11:41:50 +0100 Subject: [PATCH 19/30] Update OSCAR banner (#3410) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --------- Co-authored-by: Max Horn Co-authored-by: Lars Göttgens (cherry picked from commit f468cca29c06d5cfb94b1c4b87566988bef7924b) --- README.md | 24 ++++++++---------------- src/Oscar.jl | 27 ++++++++++----------------- 2 files changed, 18 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index b06251ec8445..c9f057676b74 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Polymake, Antic and Singular. OSCAR requires Julia 1.6 or newer. In principle it can be installed and used like any other Julia package; doing so will take a couple of minutes: -```julia +``` julia> using Pkg julia> Pkg.add("Oscar") julia> using Oscar @@ -31,21 +31,13 @@ in the OSCAR manual to learn more on how to contribute to OSCAR. ## Examples of usage -```julia +``` julia> using Oscar - ----- ----- ----- - ----- -| | | | | | | | | | -| | | | | | | | -| | ----- | | | |----- -| | | | |-----| | | -| | | | | | | | | | - ----- ----- ----- - - - - - -...combining (and extending) ANTIC, GAP, Polymake and Singular -Version 1.0.0-rc1 ... -... which comes with absolutely no warranty whatsoever -Type: '?Oscar' for more information -(c) 2019-2024 by The OSCAR Development Team + ___ ____ ____ _ ____ + / _ \ / ___| / ___| / \ | _ \ | Combining ANTIC, GAP, Polymake, Singular +| | | |\___ \| | / _ \ | |_) | | Type "?Oscar" for more information +| |_| | ___) | |___ / ___ \| _ < | Manual: https://docs.oscar-system.org + \___/ |____/ \____/_/ \_\_| \_\ | Version 1.0.0-rc1 julia> k, a = quadratic_field(-5) (Imaginary quadratic field defined by x^2 + 5, sqrt(-5)) @@ -107,7 +99,7 @@ by Submodule with 1 generator Of course, the cornerstones are also available directly: -```julia +``` julia> C = Polymake.polytope.cube(3); julia> C.F_VECTOR diff --git a/src/Oscar.jl b/src/Oscar.jl index 751cda8469d0..4ee5ec1f943e 100644 --- a/src/Oscar.jl +++ b/src/Oscar.jl @@ -39,25 +39,18 @@ if Sys.iswindows() end function _print_banner() - println(" ----- ----- ----- - ----- ") - println("| | | | | | | | | | ") - println("| | | | | | | | ") - println("| | ----- | | | |----- ") - println("| | | | |-----| | | ") - println("| | | | | | | | | | ") - println(" ----- ----- ----- - - - - ") - println() - println("...combining (and extending) ANTIC, GAP, Polymake and Singular") - print("Version") - printstyled(" $VERSION_NUMBER ", color = :green) - print("... \n ... which comes with absolutely no warranty whatsoever") - println() - println("Type: '?Oscar' for more information") - println("(c) 2019-2024 by The OSCAR Development Team") + if displaysize(stdout)[2] >= 79 + println( + raw""" ___ ____ ____ _ ____ + / _ \ / ___| / ___| / \ | _ \ | Combining ANTIC, GAP, Polymake, Singular + | | | |\___ \| | / _ \ | |_) | | Type "?Oscar" for more information + | |_| | ___) | |___ / ___ \| _ < | Manual: https://docs.oscar-system.org + \___/ |____/ \____/_/ \_\_| \_\ | Version """ * "$VERSION_NUMBER") + else + println("OSCAR $VERSION_NUMBER https://docs.oscar-system.org Type \"?Oscar\" for help") + end end - - function __init__() if Sys.iswindows() windows_error() From 4139960db97d84a7a70fa72d1e8fa45a1b032e05 Mon Sep 17 00:00:00 2001 From: Thomas Breuer Date: Wed, 28 Feb 2024 12:55:07 +0100 Subject: [PATCH 20/30] support group properties for character tables (#3449) and character value access by class names (cherry picked from commit e86fe099fce2a0b6f5d92b121178d3a6ab625fd4) --- docs/src/Groups/basics.md | 18 +-- docs/src/Groups/group_characters.md | 18 +++ src/Groups/group_characters.jl | 215 +++++++++++++++++++++++++++- test/Groups/group_characters.jl | 16 +++ 4 files changed, 257 insertions(+), 10 deletions(-) diff --git a/docs/src/Groups/basics.md b/docs/src/Groups/basics.md index d088222e052e..e63004cd2fb6 100644 --- a/docs/src/Groups/basics.md +++ b/docs/src/Groups/basics.md @@ -70,17 +70,17 @@ is_finite(G::GAPGroup) is_trivial(G::GAPGroup) is_cyclic(G::GAPGroup) is_abelian(G::GAPGroup) -is_elementary_abelian -is_pgroup -is_pgroup_with_prime -is_nilpotent -is_supersolvable -is_solvable -is_perfect +is_elementary_abelian(G::GAPGroup) +is_pgroup(G::GAPGroup) +is_pgroup_with_prime(::Type{T}, G::GAPGroup) where T <: IntegerUnion +is_nilpotent(G::GAPGroup) +is_supersolvable(G::GAPGroup) +is_solvable(G::GAPGroup) +is_perfect(G::GAPGroup) is_simple(G::GAPGroup) is_almost_simple(G::GAPGroup) -is_quasisimple -is_sporadic_simple +is_quasisimple(G::GAPGroup) +is_sporadic_simple(G::GAPGroup) is_finitely_generated(G::GAPGroup) ``` diff --git a/docs/src/Groups/group_characters.md b/docs/src/Groups/group_characters.md index f7618467996b..ae1a3c3482b4 100644 --- a/docs/src/Groups/group_characters.md +++ b/docs/src/Groups/group_characters.md @@ -142,6 +142,24 @@ ordinary_table(tbl::GAPGroupCharacterTable) trivial_character(tbl::GAPGroupCharacterTable) ``` +The following properties of a group can be read off from its +character table. +Therefore it is supported to call these functions with a character table. + +```@docs +is_abelian(tbl::GAPGroupCharacterTable) +is_almost_simple(tbl::GAPGroupCharacterTable) +is_cyclic(tbl::GAPGroupCharacterTable) +is_elementary_abelian(tbl::GAPGroupCharacterTable) +is_nilpotent(tbl::GAPGroupCharacterTable) +is_perfect(tbl::GAPGroupCharacterTable) +is_quasisimple(tbl::GAPGroupCharacterTable) +is_simple(tbl::GAPGroupCharacterTable) +is_solvable(tbl::GAPGroupCharacterTable) +is_sporadic_simple(tbl::GAPGroupCharacterTable) +is_supersolvable(tbl::GAPGroupCharacterTable) +``` + ## Construct group characters from groups ```@docs diff --git a/src/Groups/group_characters.jl b/src/Groups/group_characters.jl index aa84b833ee1d..3e77558903b6 100644 --- a/src/Groups/group_characters.jl +++ b/src/Groups/group_characters.jl @@ -1642,6 +1642,212 @@ function known_class_fusions(tbl::GAPGroupCharacterTable) end +############################################################################## +## +## mathematical properties of a group that can be read off from its +## character table +## + +""" + is_abelian(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of an abelian group, +see [`is_abelian(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_abelian(character_table("A5")) +false + +julia> is_abelian(character_table("C2")) +true +``` +""" +@gapattribute is_abelian(tbl::GAPGroupCharacterTable) = GAP.Globals.IsAbelian(GAPTable(tbl))::Bool + + +""" + is_almost_simple(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of an almost simple group, +see [`is_almost_simple(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_almost_simple(character_table("S5")) +true + +julia> is_almost_simple(character_table("S4")) +false +``` +""" +@gapattribute is_almost_simple(tbl::GAPGroupCharacterTable) = GAP.Globals.IsAlmostSimple(GAPTable(tbl))::Bool + + +""" + is_cyclic(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of a cyclic group, +see [`is_cyclic(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_cyclic(character_table("C2")) +true + +julia> is_cyclic(character_table("S4")) +false +``` +""" +@gapattribute is_cyclic(tbl::GAPGroupCharacterTable) = GAP.Globals.IsCyclic(GAPTable(tbl))::Bool + + +""" + is_elementary_abelian(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of +an elementary abelian group, +see [`is_elementary_abelian(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_elementary_abelian(character_table("C2")) +true + +julia> is_elementary_abelian(character_table("S4")) +false +``` +""" +@gapattribute is_elementary_abelian(tbl::GAPGroupCharacterTable) = GAP.Globals.IsElementaryAbelian(GAPTable(tbl))::Bool + + +""" + is_nilpotent(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of a nilpotent group, +see [`is_nilpotent(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_nilpotent(character_table("C2")) +true + +julia> is_nilpotent(character_table("S4")) +false +``` +""" +@gapattribute is_nilpotent(tbl::GAPGroupCharacterTable) = GAP.Globals.IsNilpotent(GAPTable(tbl))::Bool + + +""" + is_perfect(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of a perfect group, +see [`is_perfect(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_perfect(character_table("A5")) +true + +julia> is_perfect(character_table("S4")) +false +``` +""" +@gapattribute is_perfect(tbl::GAPGroupCharacterTable) = GAP.Globals.IsPerfect(GAPTable(tbl))::Bool + + +""" + is_quasisimple(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of a quasisimple group, +see [`is_quasisimple(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_quasisimple(character_table("A5")) +true + +julia> is_quasisimple(character_table("S4")) +false +``` +""" +@gapattribute is_quasisimple(tbl::GAPGroupCharacterTable) = GAP.Globals.IsQuasisimple(GAPTable(tbl))::Bool + + +""" + is_simple(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of a simple group, +see [`is_simple(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_simple(character_table("A5")) +true + +julia> is_simple(character_table("S4")) +false +``` +""" +@gapattribute is_simple(tbl::GAPGroupCharacterTable) = GAP.Globals.IsSimple(GAPTable(tbl))::Bool + + +""" + is_solvable(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of a solvable group, +see [`is_solvable(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_solvable(character_table("A5")) +false + +julia> is_solvable(character_table("S4")) +true +``` +""" +@gapattribute is_solvable(tbl::GAPGroupCharacterTable) = GAP.Globals.IsSolvable(GAPTable(tbl))::Bool + + +""" + is_sporadic_simple(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of +a sporadic simple group, +see [`is_sporadic_simple(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_sporadic_simple(character_table("A5")) +false + +julia> is_sporadic_simple(character_table("M11")) +true +``` +""" +@gapattribute is_sporadic_simple(tbl::GAPGroupCharacterTable) = GAP.Globals.IsSporadicSimple(GAPTable(tbl))::Bool + + +""" + is_supersolvable(tbl::GAPGroupCharacterTable) + +Return whether `tbl` is the ordinary character table of a supersolvable group, +see [`is_supersolvable(G::GAPGroup)`](@ref). + +# Examples +```jldoctest +julia> is_supersolvable(character_table("A5")) +false + +julia> is_supersolvable(character_table("S3")) +true +``` +""" +@gapattribute is_supersolvable(tbl::GAPGroupCharacterTable) = GAP.Globals.IsSupersolvable(GAPTable(tbl))::Bool + + ############################################################################# ## ## class functions (and characters) @@ -2019,12 +2225,19 @@ Nemo.degree(::Type{QQAbElem}, chi::GAPGroupClassFunction) = values(chi)[1]::QQAb Nemo.degree(::Type{T}, chi::GAPGroupClassFunction) where T <: IntegerUnion = T(Nemo.degree(ZZRingElem, chi))::T -# access character values +# access character values by position function Base.getindex(chi::GAPGroupClassFunction, i::Int) vals = GAPWrap.ValuesOfClassFunction(chi.values) return QQAbElem(vals[i]) end +# access character values by class name +function Base.getindex(chi::GAPGroupClassFunction, nam::String) + i = findfirst(is_equal(nam), class_names(parent(chi))) + @req i != nothing "$nam is not a class name" + return chi[i] +end + # arithmetic with class functions function Base.:(==)(chi::GAPGroupClassFunction, psi::GAPGroupClassFunction) @req parent(chi) === parent(psi) "character tables must be identical" diff --git a/test/Groups/group_characters.jl b/test/Groups/group_characters.jl index 1b03f38d7f71..0beec6634456 100644 --- a/test/Groups/group_characters.jl +++ b/test/Groups/group_characters.jl @@ -848,6 +848,7 @@ end @test chi isa Oscar.GAPGroupClassFunction @test chi[4] == t[2,4] @test [chi[i] for i in 1:5] == values(chi) + @test [chi[nam] for nam in class_names(t)] == values(chi) @test [2*chi[i] for i in 1:5] == values(chi + chi) @test [chi[i]^2 for i in 1:5] == values(chi * chi) @test [chi[i]^2 for i in 1:5] == values(chi^2) @@ -1277,3 +1278,18 @@ end end end end + +@testset "read off group properties from character tables" begin + t = character_table("A5") + @test ! is_abelian(t) + @test is_almost_simple(t) + @test ! is_cyclic(t) + @test ! is_elementary_abelian(t) + @test ! is_nilpotent(t) + @test is_perfect(t) + @test is_quasisimple(t) + @test is_simple(t) + @test ! is_solvable(t) + @test ! is_sporadic_simple(t) + @test ! is_supersolvable(t) +end From b5da7dd513132a30cbe7302cfa4277cbb2c37984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Wed, 28 Feb 2024 16:24:12 +0100 Subject: [PATCH 21/30] Unexport normalise (#3453) (cherry picked from commit e45ff24a2ddfb02d44151157649a8bc26e18941a) --- experimental/ModStd/ModStdQt.jl | 1 - src/imports.jl | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/experimental/ModStd/ModStdQt.jl b/experimental/ModStd/ModStdQt.jl index 2f86499b666b..28caa59a5012 100644 --- a/experimental/ModStd/ModStdQt.jl +++ b/experimental/ModStd/ModStdQt.jl @@ -21,7 +21,6 @@ function Oscar.evaluate(f::FracElem{<:MPolyRingElem}, v::Vector{<:RingElem}; Err return n//d end -Oscar.normalise(f::QQPolyRingElem, ::Int64) = error("no normalise") #length(f) #Oscar.set_length!(f::QQPolyRingElem, ::Int64) = error("no set_length") #f #= diff --git a/src/imports.jl b/src/imports.jl index f2df7ed9bc66..9c7ff7555fb8 100644 --- a/src/imports.jl +++ b/src/imports.jl @@ -167,6 +167,7 @@ let exclude_hecke = [ :leading_term, :monomials, :narrow_class_group, + :normalise, :number_of_partitions, :Partition, :perm, From 5223042fe69a4e66b49811ba9948c8a8b0a1aab9 Mon Sep 17 00:00:00 2001 From: Thomas Breuer Date: Wed, 28 Feb 2024 17:27:52 +0100 Subject: [PATCH 22/30] add `od_from_atlas_group`, `od_from_p_subgroup`, and helpers (#3444) * add `conductor` for class functions * add `:constituents` key (if available) to the dictionaries returned by `all_atlas_group_infos` * support `min_char` in `isomorphic_group_over_finite_field` i.e., prescribe a minimal characteristic for the returned group, in order to guarantee that the reduction of an irreducible group is also irreducible * better handling of quadratic fields - improve coercion from quadratic fields into `QQAbField`; the check for `is_quadratic_field` is not general enough, and evaluation of a field element requires not just some polynomial ring but the underlying polynomial ring of the number field - and add `_embedding` of `QQ` into `QQAbField`, for convenience * added `orbits_group_automorphisms` and helpers * add `od_from_atlas_group` and helper * add p-group criterion - add `known_class_fusions` - add optional argument to `induced_cyclic` - add `od_from_p_subgroup` - add helper `possible_permutation_characters_from_sylow_subgroup` * adjust to the changes in Oscar since November * now the tests pass again * `FiniteField` does no longer exist * use `number_of_conjugacy_classes` * omit some tests that require AtlasRep at least 2.1.7 * for the moment, leave out tests that need web access (cherry picked from commit 556be5ae27a4fe3d45dfd26e536101e535085d0b) --- docs/src/Groups/group_characters.md | 1 + .../docs/src/compute.md | 7 + .../src/OrthogonalDiscriminants.jl | 1 + .../OrthogonalDiscriminants/src/direct.jl | 223 +++++++++++++ .../src/theoretical.jl | 154 ++++++++- .../OrthogonalDiscriminants/src/utils.jl | 301 +++++++++++++++++- .../OrthogonalDiscriminants/test/data.jl | 6 + .../OrthogonalDiscriminants/test/direct.jl | 18 ++ .../test/theoretical.jl | 16 + .../OrthogonalDiscriminants/test/utils.jl | 66 ++++ src/GAP/wrappers.jl | 3 +- src/Groups/group_characters.jl | 53 ++- src/Groups/libraries/atlasgroups.jl | 13 +- src/Groups/matrices/iso_nf_fq.jl | 24 +- src/Rings/AbelianClosure.jl | 56 +++- test/Groups/group_characters.jl | 3 + test/Groups/matrixgroups.jl | 10 + 17 files changed, 931 insertions(+), 24 deletions(-) create mode 100644 experimental/OrthogonalDiscriminants/src/direct.jl create mode 100644 experimental/OrthogonalDiscriminants/test/direct.jl diff --git a/docs/src/Groups/group_characters.md b/docs/src/Groups/group_characters.md index ae1a3c3482b4..5a02461722bf 100644 --- a/docs/src/Groups/group_characters.md +++ b/docs/src/Groups/group_characters.md @@ -109,6 +109,7 @@ all_character_table_names ```@docs character_field +conductor(chi::GAPGroupClassFunction) conj(chi::GAPGroupClassFunction) Nemo.degree(chi::GAPGroupClassFunction) indicator diff --git a/experimental/OrthogonalDiscriminants/docs/src/compute.md b/experimental/OrthogonalDiscriminants/docs/src/compute.md index ea48331dd33f..20e465a4d1e4 100644 --- a/experimental/OrthogonalDiscriminants/docs/src/compute.md +++ b/experimental/OrthogonalDiscriminants/docs/src/compute.md @@ -7,10 +7,17 @@ end # Criteria for computing orthogonal discriminants +## Direct methods + +```@docs +od_from_atlas_group +``` + ## Character-theoretical criteria ```@docs od_from_order od_from_eigenvalues od_for_specht_module +od_from_p_subgroup(chi::GAPGroupClassFunction, p::Int) ``` diff --git a/experimental/OrthogonalDiscriminants/src/OrthogonalDiscriminants.jl b/experimental/OrthogonalDiscriminants/src/OrthogonalDiscriminants.jl index 67b73618bf50..82a46ac66a53 100644 --- a/experimental/OrthogonalDiscriminants/src/OrthogonalDiscriminants.jl +++ b/experimental/OrthogonalDiscriminants/src/OrthogonalDiscriminants.jl @@ -26,6 +26,7 @@ end include("utils.jl") include("data.jl") include("gram_det.jl") +include("direct.jl") include("theoretical.jl") include("exports.jl") diff --git a/experimental/OrthogonalDiscriminants/src/direct.jl b/experimental/OrthogonalDiscriminants/src/direct.jl new file mode 100644 index 000000000000..ad8a171414a7 --- /dev/null +++ b/experimental/OrthogonalDiscriminants/src/direct.jl @@ -0,0 +1,223 @@ + +# methods working with representations + +# We assume that `G` is abs. irreducible and +# respects a nondegenerate quadratic form. +# In even characteristic (0 or 2), we assume that `G` is written over its +# character field. +# In odd characteristic, we assume that `G` is written over an odd degree +# extension of its character field. +# +# In characteristic zero, we have to interpret the result computed in +# `base_ring(G)` as an element of the character field. +# Thus we have to specify `embG` and `embF`, where +# `embG` is the embedding of `base_ring(G)` into the abelian closure of `QQ` +# and `embF` is the embedding of the character field of `G` into the abelian +# closure of `QQ`. +function od_from_generators(G::MatrixGroup, embG = nothing, embF = nothing) + FG = base_ring(G) + p = characteristic(FG) + if p != 2 + # Compute the determinant of the invariant form as the determinant + # of a skew-symmetric endomorphism w.r.t. the invariant form, + # of full rank. + # (In particular, do not compute the invariant form.) + # The idea is that for each matrix `M` in `G`, + # `Y = M - inv(M)` is such an endomorphism, i.e., satisfies + # `B Y^{tr} inv(B) == -Y`, where `B` is the matrix of the invariant + # bilinear form for `G`, i.e., `M B M^{tr} == B` holds for all `M` in `G`. + # Thus we try to find a linear combination of such matrices `M - inv(M)` + # that is invertible. + # (In practice, very often three summands suffice.) + M = matrix(rand_pseudo(G)) +#T initialization is expensive if the matrices are large + E = M - inv(M) + for i in 1:100 + d = det(E) + if is_zero(d) + # Add/subtract another random element + M = matrix(rand_pseudo(G)) + c = rand([1, -1]) + E = E + c * (M - inv(M)) + else + # We have found an invertible skew-symmetric endomorphism. + if p == 0 + # Switch from determinant to discriminant. + if mod(degree(G), 4) == 2 + d = - d + end + + # Coerce `d` into the character field of `G`. + od = preimage(embF, embG(d)) + + # Reduce the representative `od` mod obvious squares + # in the character field. + od = reduce_mod_squares(od) + + # Embed this value into the alg. closure. + od = embF(od) + + # Turn the value into a string (using Atlas notation). + return true, atlas_description(od) + else + # Decide if `d` is a square in the char. field. + # By our assumptions, we can simply test whether `d` is a square + # (in its parent, i.e., `base_ring(G)`). + str = is_square(d) ? "O+" : "O-" + end + end + end + end + + # We known no better method than the MeatAxe approach. + sgn = orthogonal_sign(G) + if sgn == 1 + return true, "O+" + elseif sgn == -1 + return true, "O-" + end + + # This should not happen. + error("assumptions not satisfied") +end + + +@doc raw""" + od_from_atlas_group(chi::GAPGroupClassFunction) + +Return `(flag, val)` where `flag` is `true` if the function can compute +the orthogonal discriminant of `chi`. +In this case, `val` is a string that describes the +orthogonal discriminant of `chi`. + +Otherwise `flag` is `false` and `val` is `""`. + +The former case happens if `chi` is absolutely irreducible, +has even degree and indicator `+`, +and the Atlas of Group Representations contains a representation +affording `chi`, over the character field of `chi` or (in odd characteristic) +a suitable extension field. + +If the characteristic of `chi` is $2$ then we know no better method than +calling [`orthogonal_sign`](@ref). +Otherwise we try to find an invertible skew-symmetric endomorphism w.r.t. +the invariant bilinear form of the representation, with random methods. + +```jldoctest +julia> t = character_table("A6"); + +julia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(t[7]) +(true, "-1") + +julia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(mod(t, 3)[4]) +(true, "O-") + +julia> t = character_table("L2(27)"); + +julia> Oscar.OrthogonalDiscriminants.od_from_atlas_group(t[4]) +(false, "") +``` +""" +function od_from_atlas_group(chi::GAPGroupClassFunction) + tbl = parent(chi) + chipos = findfirst(isequal(chi), tbl) + chipos == nothing && return false, "" + p = characteristic(chi) + if p == 0 + id = identifier(tbl) + else + id = identifier(ordinary_table(tbl)) + end + + # Collect candidates that may afford `chi`. + # Prefer an entry that knows to belong to `chi` or a member from its + # orbit under group automorphisms, + # but admit also other entries that do not know their characters, + # provided that characteristic and degree determine the representation + # up to group automorphisms. +#TODO: Improve by ruling out candidates via their character fields. + d = degree(Int, chi) + infos1 = [] + infos2 = [] + orbs = orbits_group_automorphisms(tbl) + orb = orbs[findfirst(x -> chipos in x, orbs)] + unique_orbit = all(x -> chipos in x || degree(Int, tbl[x[1]]) != d, orbs) + for info in all_atlas_group_infos(id, characteristic => p, dim => d) + if haskey(info, :constituents) + # We trust in the precomputed data. + if length(info[:constituents]) == 1 && info[:constituents][1] in orb + push!(infos1, info) + end + elseif unique_orbit + # Any abs. irred. character of degree `d` will be good. + push!(infos2, info) + end + end + + # Run over the candidates (usually just one). + for info in vcat(infos1, infos2) + G = atlas_group(info) + G == nothing && continue + F = base_ring(G) + K, embK = character_field(chi) + if degree(F) != degree(K) + if p == 2 || p == 0 + # For even `p`, we need representations over the character field. + # Thus try to write the matrices over the character field. + V = free_module(F, degree(G)) + M = gmodule(G, [hom(V, V, x) for x in [matrix(x) for x in gens(G)]]) + Mmin = Oscar.GModuleFromGap.gmodule_minimal_field(M) +#TODO: For p == 0, we need also the (!) embedding of `base_ring(Mmin)` +# into `F == base_ring(M)`, because we know the embedding of `F` +# into a cyclotomic field, and we will need this embedding in the end. + F = base_ring(Mmin) + (degree(F) != degree(K)) && continue + G = matrix_group([matrix(x) for x in Mmin.ac]) + elseif is_even(degree(F) // degree(K)) + # For odd p, it is sufficient that `F` is an odd degree extension + # of the character field. + V = free_module(F, degree(G)) + M = gmodule(G, [hom(V, V, x) for x in [matrix(x) for x in gens(G)]]) + Mmin = Oscar.GModuleFromGap.gmodule_minimal_field(M) + F = base_ring(Mmin) + is_even(degree(F) // degree(K)) && continue + G = matrix_group([matrix(x) for x in Mmin.ac]) + end + end + + if ! haskey(info, :constituents) + # We do not yet know that `G` has character `chi`. + # Check whether the representation is abs. irred. + if p == 0 + # We can check abs. irred. if we can reduce the repres. + # modulo a prime l that does not divide the group order. +#TODO: Better create the natural module for G, +#T and ask it whether it is abs. irreducible. + l = next_prime(max([x[1] for x in factor(order(tbl))]...)) + Gbar, _ = Oscar.isomorphic_group_over_finite_field(G, min_char = Int(l)) + GG = Gbar.X + else + GG = G.X + end + M = GAP.Globals.GModuleByMats(GAP.Globals.GeneratorsOfGroup(GG), + GAP.Globals.FieldOfMatrixGroup(GG)) + GAP.Globals.MTX.IsAbsolutelyIrreducible(M) || continue + end + + # Now we are sure that `G` affords `chi`. + if p == 0 +#TODO: Add the relevant metadata to the Atlas of Group Representations. +if !(degree(F) <= 2 || Hecke.is_cyclotomic_type(F)[1]) + println( "missing field embedding info for ", info) + continue +end + KK, _ = abelian_closure(QQ) + embG = Oscar.AbelianClosure._embedding(F, KK, KK(gen(F))) + return od_from_generators(G, embG, embK) + else + return od_from_generators(G) + end + end + + return false, "" +end diff --git a/experimental/OrthogonalDiscriminants/src/theoretical.jl b/experimental/OrthogonalDiscriminants/src/theoretical.jl index de9857e90fa3..2b6ec191236f 100644 --- a/experimental/OrthogonalDiscriminants/src/theoretical.jl +++ b/experimental/OrthogonalDiscriminants/src/theoretical.jl @@ -104,7 +104,9 @@ function od_from_eigenvalues(chi::GAPGroupClassFunction) str = atlas_description(od) else # Decide if the reduction mod `p` is a square in the char. field. - str = is_square(reduce(K(od), character_field(chi)[1])) ? "O+" : "O-" + red = reduce(K(od), character_field(chi)[1]) + is_zero(red) && error("reduction mod $p is zero?") + str = is_square(red) ? "O+" : "O-" end return true, str @@ -113,6 +115,7 @@ function od_from_eigenvalues(chi::GAPGroupClassFunction) return false, "" end + @doc raw""" od_for_specht_module(chi::GAPGroupClassFunction) @@ -172,3 +175,152 @@ function od_for_specht_module(chi::GAPGroupClassFunction) return true, string(res) end + + +@doc raw""" + od_from_p_subgroup(chi::GAPGroupClassFunction, p::Int[, pi::GAPGroupClassFunction]) + +Let `chi` be an irreducible (ordinary or Brauer) character of the group $G$, +and `p` be an odd prime integer. + +Return `(flag, val)` where `flag` is `true` if and only if +enough information can be computed to prove that the restriction of `chi` +to a Sylow `p`-subgroup $P$ is orthogonally stable. +In this case, +`val` is a string that describes the orthogonal discriminant of `chi`. + +If `flag` is `false` then `val` is equal to `""`. + +If a character is given as the optional argument `pi` then it is assumed +that `pi` is the permutation character of $G$ induced from $P$. +Otherwise the function tries to compute the possible permutation characters. + +# Examples +```jldoctest +julia> t = character_table("A5"); + +julia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(t[4], 5) +(true, "5") + +julia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(mod(t, 3)[4], 5) +(true, "O-") + +julia> Oscar.OrthogonalDiscriminants.od_from_p_subgroup(mod(t, 2)[4], 5) +(true, "O-") +``` +""" +function od_from_p_subgroup(chi::GAPGroupClassFunction, p::Int) + cand = possible_permutation_characters_from_sylow_subgroup(parent(chi), p) + if cand != nothing + res = collect(Set([od_from_p_subgroup(chi, p, pi) for pi in cand])) + length(res) == 1 && return res[1] + end + return false, "" +end + +function od_from_p_subgroup(chi::GAPGroupClassFunction, p::Int, + pi::GAPGroupClassFunction) + tbl = parent(chi) + Porder = div(order(tbl), degree(ZZRingElem, pi)) + flag, _, l = is_prime_power_with_data(Porder) + @req (flag && l == p) "pi is not induced from a p-subgroup" + p == 2 && return (false, "") + + l = characteristic(chi) + l == p && return (false, "") + + # If `chi` is a Brauer character and `pi` is an ordinary character + # then restrict `pi` to the `l`-regular classes. + if characteristic(pi) == 0 && characteristic(chi) != 0 + pi = restrict(pi, tbl) + end + if scalar_product(chi, pi) != 0 + # The restriction of `chi` to P is not orthogonally stable. + return false, "" + end + + fus = filter(i -> pi[i] != 0, 1:number_of_conjugacy_classes(tbl)) + res = Oscar.GAPWrap.ELMS_LIST(chi.values, GAP.GapObj(fus)) + + if l != 0 + # possible shortcut: + # `chi` itself can have a larger character field + # than its restriction to P. + # If this field contains a quadratic extension of the field of 'rest' + # then we conclude that its OD is "O+", + # no matter what the OD of the restriction to P is. + Fchi = order_field_of_definition(chi) + Fres = Oscar.GAPWrap.SizeOfFieldOfDefinition(res, l) +# We cannot form a class function object because we have no character table +# of the subgroup P (and we are happy that we do not need this table). +# Thus we cannot call `order_field_of_definition`. +# However, we know that the restriction to the non-vanishing classes of `pi` +# is closed under Galois conjugation, +# thus we would like to call `GAPWrap.SizeOfFieldOfDefinition` with this +# information. +#TODO: Let GAP support this. + _, expchi, _ = is_prime_power_with_data(Fchi) + _, expres, _ = is_prime_power_with_data(Fres) + if mod(expchi, 2*expres) == 0 + return true, "O+" + end + end + + # We have to work. + # First compute the ordinary OD of the restriction to P. + # Compute the degree of the field `K` generated by the restriction, + # and the degree of the enveloping cyclotomic field of `K` + # or of the `p`-th cyclotomic field if `K` is the rational field. + K = GAP.Globals.Field(GAP.Globals.Rationals, res)::GapObj + pf = Oscar.GAPWrap.Conductor(K) + if pf == 1 + pf = p + end + a = div(euler_phi(pf), GAP.Globals.Dimension(K)) + deg = degree(ZZRingElem, chi) + @assert mod(deg, a) == 0 + KK, z = abelian_closure(QQ) + if is_even(div(deg, a)) + # The value is a square in 'K'. + od = KK(1) + else + # Compute \delta_K, as a `QQAbElem`. + # We need the norm of `z(p) + z(p)^-1 -2` w.r.t. the field extension + # given by the real subfield of `cyclotomic_field(pf)` over `K`. + # We compute this in the extension of `cyclotomic_field(p)` over + # its intersection with `K`. + # Note that this intersection is uniquely determined by `a`. + # We compute the Galois group of the field extension. + z = z(p) + zinv = inv(z) + od = z + zinv - 2 + galgen = GAP.Globals.PrimitiveRootMod(p)::Int + galgen = powermod(galgen, Int(div(p-1, a)), p) + e = galgen + for k in 2:(a//2) + od = od * (z^e + zinv^e - 2) + e = mod(e * galgen, p) + end + end + + if l == 0 + # Turn the value into a string (using Atlas notation). + return true, atlas_description(od) + end + + # Reduce the ord. OD mod `l`. + if conductor(od) == 1 + intod = ZZ(od) + if is_odd(l) + F = GF(l) + return is_square(F(intod)) ? (true, "O+") : (true, "O-") + elseif mod(intod, 8) == 1 + return (true, "O+") + elseif mod(intod, 8) == 5 + return (true, "O-") + else + error("wrong congruence for OD of rational character") + end + end + return (false, "") +end diff --git a/experimental/OrthogonalDiscriminants/src/utils.jl b/experimental/OrthogonalDiscriminants/src/utils.jl index b9fe437dbb1d..0d1c75fe9dec 100644 --- a/experimental/OrthogonalDiscriminants/src/utils.jl +++ b/experimental/OrthogonalDiscriminants/src/utils.jl @@ -77,12 +77,14 @@ function reduce_mod_squares(val::AbsSimpleNumFieldElem) if ! isone(d) val = val * d^2 end + F = parent(val) if is_integer(val) intval = ZZ(val) sgn = sign(intval) good = [x[1] for x in collect(factor(intval)) if is_odd(x[2])] - F = parent(val) return F(prod(good, init = sgn)) + elseif is_square(val) + return F(1) end # Just get rid of the square part of the gcd of the coefficients. c = map(numerator, coefficients(val)) @@ -98,6 +100,303 @@ function reduce_mod_squares(val::AbsSimpleNumFieldElem) end +@doc raw""" + possible_permutation_characters_from_sylow_subgroup(tbl::Oscar.GAPGroupCharacterTable, p::Int) + +Return either `nothing` or the vector of all those characters of `tbl` that +may be equal to the permutation character $1_P^G$, +where $G$ is the group of `tbl` and $P$ is a Sylow `p`-subgroup of $G$. + +# Examples +```jldoctest +julia> tbl = character_table("A5"); + +julia> l = Oscar.OrthogonalDiscriminants.possible_permutation_characters_from_sylow_subgroup(tbl, 2); + +julia> length(l) +1 + +julia> println(coordinates(Int, l[1])) +[1, 0, 0, 1, 2] +``` +""" +function possible_permutation_characters_from_sylow_subgroup(tbl::Oscar.GAPGroupCharacterTable, p::Int) + @req is_prime(p) "p must be a prime integer" + l = characteristic(tbl) + if l == p + # The permutation character is zero on all + # nonidentity `p`-regular classes. + pi = fill(0, nrows(tbl)) + # index of the Sylow `p`-subgroup + _, n = remove(order(tbl), p) + pi[1] = n + return [Oscar.class_function(tbl, GapObj(pi, true))] + elseif l != 0 + # Compute the corresponding ordinary characters, and restrict them. + pi = possible_permutation_characters_from_sylow_subgroup( + ordinary_table(tbl), p) + if pi != nothing + pi = [restrict(x, tbl) for x in pi] + end + return pi + end + + # index of the Sylow 'p'-subgroup + q, n = remove(order(tbl), p) + q = p^q + + # Perhaps the Sylow `p`-subgroup is cyclic. + pos = findfirst(x -> x == q, orders_class_representatives(tbl)) + pos != nothing && return [induced_cyclic(tbl, [pos])[1]] + + # Do we have the table of marks? + tom = GAP.Globals.TableOfMarks(Oscar.GAPTable(tbl)) + if tom != GAP.Globals.fail + pos = findfirst(x -> x == q, Vector{Int}(GAP.Globals.OrdersTom(tom))) + return [Oscar.class_function(tbl, GAP.Globals.PermCharsTom(Oscar.GAPTable(tbl), tom)[pos])] + end + + # Does the table have a nontrivial 'p'-core + # such that the table of the factor is a library table? + # If yes and if we can compute the result for the factor + # then inflate it to 'tbl'. + npos = class_positions_of_pcore(tbl, p) + if length(npos) != 1 + for d in known_class_fusions(tbl) + if class_positions_of_kernel(d[2]) == npos + s = character_table(d[1]) + if s != nothing && characteristic(s) == 0 + # Try to recurse. + pi = possible_permutation_characters_from_sylow_subgroup(s, p) + if pi != nothing + return [restrict(x, tbl) for x in pi] + end + end + end + end + end + + candlist = nothing + for name in names_of_fusion_sources(tbl) + s = character_table(name) + if s != nothing && characteristic(s) == 0 + flag, fus = known_class_fusion(s, tbl) + if flag && length(class_positions_of_kernel(fus)) == 1 + if mod(order(s), q) == 0 + # Run over the known character tables of subgroups + # that contain Sylow subgroups of `tbl`. + npos = class_positions_of_pcore(s, p) + if sum(class_lengths(s)[npos]) == q + # The Sylow `p`-subgroup of `tbl` is normal in `s`. + pi = fill(0, nrows(s)) + index = div(order(s), q) + for i in npos + pi[i] = index + end + pi = GAP.Globals.ClassFunction(Oscar.GAPTable(s), GapObj(pi, true)) + return [Oscar.class_function(s, pi)^tbl] + else + # Try to recurse. + pi = possible_permutation_characters_from_sylow_subgroup(s, p) + if pi != nothing + pi = collect(Set([x^tbl for x in pi])) + if candlist == nothing + candlist = pi + else + intersect!(candlist, pi) + end + length(candlist) == 1 && return candlist + end + end + elseif mod(div(order(tbl), order(s)), p) == 0 && + is_prime_power_with_data(div(order(tbl), order(s)))[1] + # Compute the perm. char. of the Sylow p-subgroup in the subgroup, + # and then try to extend the character uniquely to G. + cand = possible_permutation_characters_from_sylow_subgroup(s, p) + if cand != nothing + extcand = [] + for pi in cand + pi = GAP.Globals.CompositionMaps(pi.values, + GAP.Globals.InverseMap(GapObj(fus))) + union!(extcand, [Oscar.class_function(tbl, x) for x in + GAP.Globals.PermChars(Oscar.GAPTable(tbl), + GAP.GapObj(Dict(:torso => pi), true))]) + end + if candlist == nothing + candlist = extcand + else + intersect!(candlist, extcand) + end + length(candlist) == 1 && return candlist + end + end + end + end + end + + isdefined(tbl, :group) && return [trivial_character(sylow_subgroup(group(tbl), p)[1])^tbl] + + # If we arrive here, + # we can try to recurse to subgroups for which fusions must be composed, + # or to compute candidates. + # (Eventually a function that returns all candidates might be useful then.) + return candlist +end + + +# helper function: +# array of identifiers of available character tables of (non-dashed) +# automorphic extensions of a simple character table. +function _identifiers_of_almost_simple_tables(simplename::String) + gapname = GapObj(simplename) + nams = GAP.Globals.CTblLib.DisplayAtlasMap_ComputePortions( + gapname, 0).identifiers[1] + return filter(x -> x == gapname || x[end] != '\'', Vector{String}(nams)) +end + +# helper function: +# Let `M` be a vector of vectors representing a *regular* matrix +# (this is not checked), +# and let `column_orbits` be the set of orbits of some group `G` +# of matrix automorphisms of `M` on the positions of columns. +# Return the set of orbits of the corresponding action of `G` +# on the rows of `M`. +function _row_orbits_from_column_orbits(M::Vector, column_orbits::Vector{Vector{Int}}) + # Compute the auxiliary matrix of orbit sums. + n = length(M) + MM = [[] for _ in 1:n] + for omega in column_orbits + for i in 1:n + push!(MM[i], sum(M[i][omega])) + end + end + + # Compute the orbits on rows. + row_orbits = Vector{Int}[] + reps = [] + poss = [] + for i in 1:n + pos = findfirst(isequal(MM[i]), reps) + if pos == nothing + push!(row_orbits, [i]) + push!(reps, MM[i]) + push!(poss, length(row_orbits)) + else + push!(row_orbits[poss[pos]], i) + end + end + + return row_orbits +end + +# helper function: +# Compute the orbits obtained by joining the orbits in `orbs1` +# with those in `orbs2`. +function _common_orbits(orbs1::Vector{Vector{Int}}, orbs2::Vector{Vector{Int}}) + local orbs, orb, pos; + + orbs = orbs1 + for orb in orbs2 + inter = Int[] + l = length(orbs) + for i in 1:l + is_empty(intersect(orb, orbs[i])) && continue + push!(inter, i) + end + orbs = union([union(orbs[inter]...)], orbs[setdiff(1:l, inter)]) + end + return sort!(map(sort!, orbs)) +end + +# helper function: +# Compute the inverse of a class fusion `fus`, +# that is, the vector of length `n` that contains at position `i` +# the (perhaps empty) vector of all those indices `j` in `fus` +# such that `fus[j] == i` holds. +# We assume that `n` is not smaller than the maximum of `fus`. +function _inverse_fusion(fus::Vector{Int}, n::Int) + inv = [Int[] for i in 1:n] + for i in 1:length(fus) + push!(inv[fus[i]], i) + end + return inv +end + +@doc raw""" + orbits_group_automorphisms(tbl::Oscar.GAPGroupCharacterTable) + +Return an array of arrays, each entry listing an orbit under the action of +those group automorphisms which are described by class fusions +that are stored on `tbl`, such that the group of `tbl` is a normal subgroup +of the group given by the image of the fusion. + +The result describes the action of the full automorphism group only if +the relevant tables of automorphic extensions and the fusions to them +are available. + +We assume that `tbl` is almost simple. + +# Examples +```jldoctest +julia> Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("L2(8)")) +5-element Vector{Vector{Int64}}: + [1] + [2] + [3, 4, 5] + [6] + [7, 8, 9] +``` +""" +function orbits_group_automorphisms(tbl::Oscar.GAPGroupCharacterTable) + # 'tbl' is an upwards extension of the table of a simple group. + # We compute the almost simple tables for this simple group, + # and then take only those that correspond to automorphisms of 'tbl'. + p = characteristic(tbl) + if p == 0 + ordtbl = tbl + else + ordtbl = ordinary_table(tbl) + end + name = identifier(ordtbl) + pos = findfirst('.', name) + if pos != nothing + simpname = name[1:(pos-1)] + else + simpname = name + end + n = nrows(tbl) + orbs = [[i] for i in 1:n] + ordauttbls = [character_table(x) for x in _identifiers_of_almost_simple_tables(simpname)] + for ordauttbl in ordauttbls + (order(ordauttbl) == order(tbl) || mod(order(ordauttbl), order(tbl)) != 0) && continue + if p == 0 + auttbl = ordauttbl + else + auttbl = mod(ordauttbl, p) + auttbl == nothing && continue + end + + fl, fus = known_class_fusion(tbl, auttbl) + if ! fl + # If 'auttbl' does not count for 'ordtbl' then this is o.k. + if length(possible_class_fusions(ordtbl, ordauttbl)) != 0 + # This criterion is sufficient for our almost simple tables. + error("class fusion from $tbl to $auttbl missing?") + end + continue + end + + colorbs = _inverse_fusion(fus, max(fus...)) + colorbs = filter(x -> length(x) != 0, colorbs) + roworbs = _row_orbits_from_column_orbits(map(collect, collect(tbl)), colorbs) + orbs = _common_orbits(orbs, roworbs) + end + + return orbs +end + + @doc raw""" is_orthogonally_stable(chi::GAPGroupClassFunction; check::Bool = true) diff --git a/experimental/OrthogonalDiscriminants/test/data.jl b/experimental/OrthogonalDiscriminants/test/data.jl index 8ce0ee4aa24b..ca5d9069a42b 100644 --- a/experimental/OrthogonalDiscriminants/test/data.jl +++ b/experimental/OrthogonalDiscriminants/test/data.jl @@ -69,6 +69,12 @@ end using Documenter +# Make sure that the tests start without cached character tables. +# (Running the tests will store information that changes some test outputs, +# thus running the tests twice needs these calls.) +GAP.Globals.UnloadCharacterTableData() +empty!(Oscar.character_tables_by_id) + # # This module only exists to "host" a doctest used by the test suite. # diff --git a/experimental/OrthogonalDiscriminants/test/direct.jl b/experimental/OrthogonalDiscriminants/test/direct.jl new file mode 100644 index 000000000000..66e6f2143df5 --- /dev/null +++ b/experimental/OrthogonalDiscriminants/test/direct.jl @@ -0,0 +1,18 @@ +@testset "compute via the Atlas of Group Representations" begin +#TODO: How can we test functions that need web access? +# # Check equality of positive results in small cases. +# l = all_od_infos(comment_matches => "AGR", dim => 1:8); +# for entry in l +# chi = Oscar.OrthogonalDiscriminants.character_of_entry(entry) +# comp = Oscar.OrthogonalDiscriminants.od_from_atlas_group(chi) +# @test comp == (true, entry[:valuestring]) +# end +# +# # Check negative results. +# t = character_table("L2(17)") +# chi = t[10] +# @test Oscar.OrthogonalDiscriminants.od_from_atlas_group(chi) == (false, "") +# t = character_table("L2(13)", 3) +# chi = t[4] +# @test Oscar.OrthogonalDiscriminants.od_from_atlas_group(chi) == (false, "") +end diff --git a/experimental/OrthogonalDiscriminants/test/theoretical.jl b/experimental/OrthogonalDiscriminants/test/theoretical.jl index cd2f42f66b8d..5498b9dcdfe5 100644 --- a/experimental/OrthogonalDiscriminants/test/theoretical.jl +++ b/experimental/OrthogonalDiscriminants/test/theoretical.jl @@ -49,3 +49,19 @@ end end end end + +@testset "p-groups" begin + rx = r"syl\((?

\d+)\)" + info = all_od_infos(characteristic => 0, + comment_matches => (x -> any(y -> startswith(y, "syl"), x))) + for entry in info[1:100] + chi = Oscar.OrthogonalDiscriminants.character_of_entry(entry) + c = filter(x -> startswith(x, "syl"), entry[:comment]) + for e in c + p = parse(Int, match(rx, e)[:p]) + (flag, valstring) = Oscar.OrthogonalDiscriminants.od_from_p_subgroup(chi, p) + @test flag + @test valstring == entry[:valuestring] + end + end +end diff --git a/experimental/OrthogonalDiscriminants/test/utils.jl b/experimental/OrthogonalDiscriminants/test/utils.jl index cbcfa8f4ced0..ee493b5b8d8d 100644 --- a/experimental/OrthogonalDiscriminants/test/utils.jl +++ b/experimental/OrthogonalDiscriminants/test/utils.jl @@ -34,3 +34,69 @@ end @test Oscar.OrthogonalDiscriminants._orthogonal_discriminant_indicator0(mod(t, 3)[2]) == "O-" @test_throws ArgumentError Oscar.OrthogonalDiscriminants._orthogonal_discriminant_indicator0(t[4]) end + +@testset "orbits under automorphisms" begin + # _row_orbits_from_column_orbits + M = identity_matrix(QQ, 5) + M = M = [[M[i,j] for j in 1:5] for i in 1:5] + orbs = [[1], [2, 3], [4, 5]] + @test Oscar.OrthogonalDiscriminants._row_orbits_from_column_orbits(M, orbs) == orbs + M = M[[2, 1, 4, 5, 3]] + @test Oscar.OrthogonalDiscriminants._row_orbits_from_column_orbits(M, orbs) == [[1, 5], [2], [3, 4]] + + # _common_orbits + @test Oscar.OrthogonalDiscriminants._common_orbits( + [[1, 2], [3, 4]], [[1], [2, 3], [4]]) == [[1, 2, 3, 4]] + @test Oscar.OrthogonalDiscriminants._common_orbits( + [[1], [2, 3], [4]], [[1, 2], [3, 4]]) == [[1, 2, 3, 4]] + @test Oscar.OrthogonalDiscriminants._common_orbits( + [[1], [2], [3, 4], [5, 6]], [[1, 3], [2, 6], [4], [5]]) == + [[1, 3, 4], [2, 5, 6]] + @test Oscar.OrthogonalDiscriminants._common_orbits( + [[1, 3], [2, 6], [4], [5]], [[1], [2], [3, 4], [5, 6]]) == + [[1, 3, 4], [2, 5, 6]] + + # _inverse_fusion + @test Oscar.OrthogonalDiscriminants._inverse_fusion(Int[], 1) == [[]] + @test Oscar.OrthogonalDiscriminants._inverse_fusion([1, 2, 3, 3], 4) == + [[1], [2], [3, 4], []] + @test Oscar.OrthogonalDiscriminants._inverse_fusion([1, 3, 3], 4) == + [[1], [], [2, 3], []] + + # orbits_group_automorphisms for ordinary tables + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("A5")) == [[1], [2, 3], [4], [5]] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("A6")) == [[1], [2, 3], [4, 5], [6], [7]] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("L3(8)")) == [[1], [2], [3, 4, 5, 6, 7, 8], + [9, 10, 11, 12, 13, 14], [15, 16, 17, 18, 19, 20], + [21, 22, 23, 24, 25, 26], [27, 28, 29, 30, 31, 32], + [33], [34, 35, 36], [37, 38, 39, 40, 41, 42], + [43, 44, 45, 46, 47, 48], [49, 50, 51, 52, 53, 54], + [55, 56, 57, 58, 59, 60], [61], [62, 63, 64, 65, 66, 67], + [68, 69], [70, 71, 72]] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("M11")) == [[x] for x in 1:10] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("U3(5)")) == [[1], [2], [3], [4, 5, 6], [7], [8], + [9], [10], [11, 12], [13, 14]] + + # orbits_group_automorphisms for Brauer tables + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("A5", 2)) == [[1], [2, 3], [4]] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("A6", 2)) == [[1], [2, 3], [4, 5]] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("L3(8)", 2)) == [[1], [2, 3, 4, 5, 6, 7], + [8, 9, 10], [11, 12, 13, 14, 15, 16], [17, 18, 19, 20, 21, 22], + [23, 24, 25, 26, 27, 28], [29, 30, 31, 32, 33, 34], + [35, 36], [37, 38, 39, 40, 41, 42], [43, 44, 45], + [46, 47, 48, 49, 50, 51], [52, 53, 54, 55, 56, 57], + [58, 59, 60, 61, 62, 63], [64]] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("M11", 2)) == [[x] for x in 1:5] + @test Oscar.OrthogonalDiscriminants.orbits_group_automorphisms( + character_table("U3(5)", 2)) == [[1], [2], [3, 4, 5], [6], + [7, 8]] +end diff --git a/src/GAP/wrappers.jl b/src/GAP/wrappers.jl index 0902785352f2..f348ee4470cf 100644 --- a/src/GAP/wrappers.jl +++ b/src/GAP/wrappers.jl @@ -120,8 +120,9 @@ GAP.@wrap InducedClassFunction(x::GapObj, y::GapObj)::GapObj GAP.@wrap InducedClassFunctionsByFusionMap(x::GapObj, y::GapObj, z::GapObj, t::GapObj)::GapObj GAP.@wrap InducedCyclic(x::GapObj)::GapObj GAP.@wrap InitFusion(x::GapObj, y::GapObj)::GapObj -GAP.@wrap IntFFE(x::Any)::GapInt +GAP.@wrap InducedCyclic(x::GapObj, y::GapObj)::GapObj GAP.@wrap INT_FFE_DEFAULT(x::Any)::GapInt +GAP.@wrap IntFFE(x::Any)::GapInt GAP.@wrap Inverse(x::GapObj)::GapObj GAP.@wrap Irr(x::GapObj)::GapObj GAP.@wrap IsAbelian(x::Any)::Bool diff --git a/src/Groups/group_characters.jl b/src/Groups/group_characters.jl index 3e77558903b6..047023d2dfcc 100644 --- a/src/Groups/group_characters.jl +++ b/src/Groups/group_characters.jl @@ -1618,6 +1618,17 @@ conjugacy class of `tbl2`. If the group of `tbl2` is a *factor group* of the group of `tbl1` then the image of the $i$-th conjugacy class `tbl1` under the relevant epimorphism is the `fus`[$i$]-th conjugacy class of `tbl2`. + +# Examples +```jldoctest +julia> t1 = character_table("A5"); t2 = character_table("A6"); + +julia> known_class_fusion(t1, t2) +(true, [1, 2, 3, 6, 7]) + +julia> known_class_fusion(t2, t1) +(false, Int64[]) +``` """ function known_class_fusion(subtbl::GAPGroupCharacterTable, tbl::GAPGroupCharacterTable) map = GAPWrap.GetFusionMap(GAPTable(subtbl), GAPTable(tbl)) @@ -2126,13 +2137,25 @@ end @doc raw""" - induced_cyclic(tbl::GAPGroupCharacterTable) + induced_cyclic(tbl::GAPGroupCharacterTable, classes::AbstractVector{Int} = 1:nrows(tbl)) Return the vector of permutation characters of `tbl` that are induced from cyclic subgroups. +If `classes` is given then only the cyclic subgroups generated by elements +in the classes at positions in this vector are returned. + +# Examples +```jldoctest +julia> t = character_table("A5"); + +julia> ind = induced_cyclic(t); + +julia> all(x -> scalar_product(x, t[1]) == 1, ind) +true +``` """ -function induced_cyclic(tbl::GAPGroupCharacterTable) - return [GAPGroupClassFunction(tbl, chi) for chi in GAPWrap.InducedCyclic(GAPTable(tbl))] +function induced_cyclic(tbl::GAPGroupCharacterTable, classes::AbstractVector{Int} = 1:nrows(tbl)) + return [GAPGroupClassFunction(tbl, chi) for chi in GAPWrap.InducedCyclic(GAPTable(tbl), GapObj(classes))] end """ @@ -2211,7 +2234,7 @@ Base.iterate(chi::GAPGroupClassFunction, state = 1) = state > length(chi.values) @doc raw""" degree(::Type{T} = QQFieldElem, chi::GAPGroupClassFunction) - where T <: Union{IntegerUnion, ZZRingElem, QQFieldElem, QQAbElem} + where T <: Union{IntegerUnion, QQFieldElem, QQAbElem} Return `chi[1]`, as an instance of `T`. """ @@ -2782,6 +2805,28 @@ function order_field_of_definition(::Type{T}, chi::GAPGroupClassFunction) where end +@doc raw""" + conductor(::Type{T} = ZZRingElem, chi::GAPGroupClassFunction) + where T <: IntegerUnion + +Return the minimal integer `n`, as an instance of `T`, +such that all values of `chi` lie in the `n`-th cyclotomic field. + +# Examples +```jldoctest +julia> tbl = character_table("A5"); + +julia> println([conductor(chi) for chi in tbl]) +ZZRingElem[1, 5, 5, 1, 1] +``` +""" +conductor(chi::GAPGroupClassFunction) = conductor(ZZRingElem, chi) + +function conductor(::Type{T}, chi::GAPGroupClassFunction) where T <: IntegerUnion + return T(GAPWrap.Conductor(chi.values)) +end + + @doc raw""" schur_index(chi::GAPGroupClassFunction) -> Int diff --git a/src/Groups/libraries/atlasgroups.jl b/src/Groups/libraries/atlasgroups.jl index 8338733da08c..7dc792bc2662 100644 --- a/src/Groups/libraries/atlasgroups.jl +++ b/src/Groups/libraries/atlasgroups.jl @@ -56,7 +56,7 @@ Typically, `info` is obtained from [`all_atlas_group_infos`](@ref). ```jldoctest julia> info = all_atlas_group_infos("A5", degree => 5) 1-element Vector{Dict{Symbol, Any}}: - Dict(:repname => "A5G1-p5B0", :degree => 5, :name => "A5") + Dict(:constituents => [1, 4], :repname => "A5G1-p5B0", :degree => 5, :name => "A5") julia> atlas_group(info[1]) Permutation group of degree 5 and order 60 @@ -184,15 +184,15 @@ and for matrix groups ```jldoctest julia> info = all_atlas_group_infos("A5", degree => [5, 6]) 2-element Vector{Dict{Symbol, Any}}: - Dict(:repname => "A5G1-p5B0", :degree => 5, :name => "A5") - Dict(:repname => "A5G1-p6B0", :degree => 6, :name => "A5") + Dict(:constituents => [1, 4], :repname => "A5G1-p5B0", :degree => 5, :name => "A5") + Dict(:constituents => [1, 5], :repname => "A5G1-p6B0", :degree => 6, :name => "A5") julia> atlas_group(info[1]) Permutation group of degree 5 and order 60 julia> info = all_atlas_group_infos("A5", dim => 4, characteristic => 3) 1-element Vector{Dict{Symbol, Any}}: - Dict(:dim => 4, :repname => "A5G1-f3r4B0", :name => "A5") + Dict(:dim => 4, :constituents => [4], :repname => "A5G1-f3r4B0", :name => "A5") julia> atlas_group(info[1]) Matrix group of degree 4 @@ -244,6 +244,11 @@ function all_atlas_group_infos(name::String, L...) # groupname and repname are always present d = Dict{Symbol, Any}(:name => string(r.groupname), :repname => string(r.repname)) + # the character may be stored + if hasproperty(r, :constituents) + d[:constituents] = Vector{Int}(r.constituents) + end + # permutation groups have a degree if hasproperty(r, :p) d[:degree] = r.p diff --git a/src/Groups/matrices/iso_nf_fq.jl b/src/Groups/matrices/iso_nf_fq.jl index 2e7457e741cd..fb7c35c69287 100644 --- a/src/Groups/matrices/iso_nf_fq.jl +++ b/src/Groups/matrices/iso_nf_fq.jl @@ -1,6 +1,7 @@ # Detinko, Flannery, O'Brien "Recognizing finite matrix groups over infinite # fields", Section 4.2 -function _isomorphic_group_over_finite_field(matrices::Vector{<:MatrixElem{T}}; check::Bool = true) where T <: Union{ZZRingElem, QQFieldElem, AbsSimpleNumFieldElem} +# `min_char` is the minimal characteristic of the returned group +function _isomorphic_group_over_finite_field(matrices::Vector{<:MatrixElem{T}}; check::Bool = true, min_char::Int = 3) where T <: Union{ZZRingElem, QQFieldElem, AbsSimpleNumFieldElem} @assert !isempty(matrices) K = base_ring(matrices[1]) @@ -19,7 +20,7 @@ function _isomorphic_group_over_finite_field(matrices::Vector{<:MatrixElem{T}}; K = QQ end - Fq, matrices_Fq, OtoFq = good_reduction(matrices, 2) + Fq, matrices_Fq, OtoFq = good_reduction(matrices, min_char-1) G = matrix_group(Fq, n, matrices_Fq) N = order(G) @@ -62,7 +63,7 @@ function _reduce(M::MatrixElem{QQFieldElem}, Fp) return map_entries(Fp, M) end -function _isomorphic_group_over_finite_field(G::MatrixGroup{T}) where T <: Union{ZZRingElem, QQFieldElem, AbsSimpleNumFieldElem} +function _isomorphic_group_over_finite_field(G::MatrixGroup{T}; min_char::Int = 3) where T <: Union{ZZRingElem, QQFieldElem, AbsSimpleNumFieldElem} if is_empty(gens(G)) F2 = GF(2) @@ -79,7 +80,7 @@ function _isomorphic_group_over_finite_field(G::MatrixGroup{T}) where T <: Union matrices = map(x -> x.elm, gens(G)) - Gp, GptoF, F, OtoFq = _isomorphic_group_over_finite_field(matrices) + Gp, GptoF, F, OtoFq = _isomorphic_group_over_finite_field(matrices, min_char = min_char) img = function(x) return Gp(_reduce(x.elm, OtoFq)) @@ -96,10 +97,17 @@ function _isomorphic_group_over_finite_field(G::MatrixGroup{T}) where T <: Union return Gp, MapFromFunc(G, Gp, img, preimg) end -function isomorphic_group_over_finite_field(G::MatrixGroup{T}) where T <: Union{ZZRingElem, QQFieldElem, AbsSimpleNumFieldElem} - return get_attribute!(G, :isomorphic_group_over_fq) do - return _isomorphic_group_over_finite_field(G) - end +function isomorphic_group_over_finite_field(G::MatrixGroup{T}; min_char::Int = 3) where T <: Union{ZZRingElem, QQFieldElem, AbsSimpleNumFieldElem} + val = get_attribute(G, :isomorphic_group_over_fq) + if val == nothing + return get_attribute!(G, :isomorphic_group_over_fq) do + return _isomorphic_group_over_finite_field(G, min_char = min_char) + end + elseif characteristic(base_ring(val[1])) >= min_char + return val + else + return _isomorphic_group_over_finite_field(G, min_char = min_char) + end end # Detinko, Flannery, O'Brien "Recognizing finite matrix groups over infinite diff --git a/src/Rings/AbelianClosure.jl b/src/Rings/AbelianClosure.jl index c940c7a9aa3e..e97129d83245 100644 --- a/src/Rings/AbelianClosure.jl +++ b/src/Rings/AbelianClosure.jl @@ -284,13 +284,23 @@ end (K::QQAbField)() = zero(K) function (K::QQAbField)(a::AbsSimpleNumFieldElem) + F = parent(a) + # Cyclotomic fields are naturally embedded into `K`. - fl, f = Hecke.is_cyclotomic_type(parent(a)) + fl, f = Hecke.is_cyclotomic_type(F) fl && return QQAbElem(a, f) # Quadratic fields are naturally embedded into `K`. - fl, f = Hecke.is_quadratic_type(parent(a)) - if fl + if degree(F) == 2 + # If the defining polynomial of `F` is `X^2 + A X + B` then + # `D = A^2 - 4 B` is a square in `F` (cf. [Coh93, p. 218]). + pol = F.pol + A = coeff(pol, 1) + D = A^2 - 4*coeff(pol, 0) + Dn = numerator(D) + Dd = denominator(D) + f = Dn * Dd + x = coeff(a, 0) y = coeff(a, 1) iszero(y) && return QQAbElem(parent(a)(x), 1) @@ -311,7 +321,7 @@ function (K::QQAbField)(a::AbsSimpleNumFieldElem) N = 4*abs(d) end r = square_root_in_cyclotomic_field(K, Int(d), Int(N)) - return x + y*c*r + return (x - y*A//2) + (y*c//(2*Dd)) * r end # We have no natural embeddings for other (abelian) number fields. @@ -463,6 +473,16 @@ function minimize(::typeof(CyclotomicField), a::AbsSimpleNumFieldElem) return minimize(CyclotomicField, [a])[1] end +#TODO: +# Here we use conductor in the sense that +# an abelian number field K has conductor n iff the n-th cyclotomic field +# is the smallest cyclotomic field that contains K, +# and the conductor of a field element is the conductor of the field +# it generates. +# Claus says that the conductor of a field element can also be read +# w.r.t. an order. +# Do we have a naming problem? +# (If not then we can just add documentation.) conductor(a::AbsSimpleNumFieldElem) = conductor(parent(minimize(CyclotomicField, a))) function conductor(k::AbsSimpleNumField) @@ -473,6 +493,11 @@ end conductor(a::QQAbElem) = conductor(data(a)) +# What we want is the conductor of the domain of the map, but we need the map. +function conductor(phi::MapFromFunc{T, QQAbField{T}}) where T + return lcm([conductor(phi(x)) for x in gens(domain(phi))]) +end + ################################################################################ # # Conversions to `ZZRingElem` and `QQFieldElem` (like for `AbsSimpleNumFieldElem`) @@ -882,9 +907,29 @@ end # If `F` is a cyclotomic field with conductor `N` then assume that `gen(F)` # is mapped to `QQAbElem(gen(F), N)`. # (Use that the powers of this element form a basis of the field.) +function _embedding(F::QQField, K::QQAbField{AbsSimpleNumField}, + x::QQAbElem{AbsSimpleNumFieldElem}) + C1, z = cyclotomic_field(1) + + f = function(x::QQFieldElem) + return QQAbElem(C1(x), 1) + end + + finv = function(x::QQAbElem; check::Bool = false) + if conductor(x) == 1 + return Hecke.force_coerce_cyclo(C1, data(x)) + elseif check + return + else + error("element has no preimage") + end + end + + return MapFromFunc(F, K, f, finv) +end + function _embedding(F::AbsSimpleNumField, K::QQAbField{AbsSimpleNumField}, x::QQAbElem{AbsSimpleNumFieldElem}) - R, = polynomial_ring(QQ, "x") fl, n = Hecke.is_cyclotomic_type(F) if fl # This is cheaper. @@ -909,6 +954,7 @@ function _embedding(F::AbsSimpleNumField, K::QQAbField{AbsSimpleNumField}, powers = [Hecke.coefficients(Hecke.force_coerce_cyclo(Kn, x^i)) for i in 0:degree(F)-1] c = transpose(matrix(QQ, powers)) + R = parent(F.pol) f = function(z::AbsSimpleNumFieldElem) return QQAbElem(evaluate(R(z), x), n) diff --git a/test/Groups/group_characters.jl b/test/Groups/group_characters.jl index 0beec6634456..8194f3ea29f2 100644 --- a/test/Groups/group_characters.jl +++ b/test/Groups/group_characters.jl @@ -949,6 +949,7 @@ end indcyc = induced_cyclic(t) @test sort!([degree(chi) for chi in indcyc]) == [6, 8, 12, 12, 24] @test all(x -> scalar_product(trivial_character(t), x) == 1, indcyc) + @test indcyc == induced_cyclic(t, 1:nrows(t)) # `induce` for character tables with groups ind = [chi^t for chi in character_table(h)] @@ -1048,6 +1049,8 @@ end F3, _ = QQ[chi] @test degree(F1) == degree(F2) @test degree(F1) == degree(F3) + @test conductor(chi) == conductor(phi) + @test conductor(Int, chi) isa Int for i in 1:length(chi) x = chi[i] xF = preimage(phi, x) diff --git a/test/Groups/matrixgroups.jl b/test/Groups/matrixgroups.jl index 320606ddc62d..662fab864986 100644 --- a/test/Groups/matrixgroups.jl +++ b/test/Groups/matrixgroups.jl @@ -141,6 +141,16 @@ end G = matrix_group(QQ, 2, dense_matrix_type(QQ)[]) @test order(Oscar.isomorphic_group_over_finite_field(G)[1]) == 1 + + @testset "with prescribed minimal characteristic" begin + G0 = matrix_group(inputs[1]) + G, g = Oscar.isomorphic_group_over_finite_field(G0) + @test characteristic(base_ring(G)) == 3 + G7, g = Oscar.isomorphic_group_over_finite_field(G0, min_char = 7) + @test characteristic(base_ring(G7)) == 7 + G3, g = Oscar.isomorphic_group_over_finite_field(G0, min_char = 3) + @test G === G3 + end end @testset "matrix group over QQBar" begin From d4e9082c07b92e55b256d74317b8529c7438a247 Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Wed, 28 Feb 2024 17:32:52 +0100 Subject: [PATCH 23/30] Docu invariants lin. red. groups (Lakshmi Ramesh and Wolfram Decker) (#3443) Co-authored-by: Johannes Schmitt (cherry picked from commit 73ba78702948eb97806db7efab1545dbb41a15cf) --- docs/src/InvariantTheory/intro.md | 6 +- docs/src/InvariantTheory/reductive_groups.md | 66 ++++-- .../InvariantTheory/src/InvariantTheory.jl | 192 +++++++++++++++++- .../src/TorusInvariantsFast.jl | 10 +- experimental/InvariantTheory/test/runtests.jl | 2 +- 5 files changed, 246 insertions(+), 30 deletions(-) diff --git a/docs/src/InvariantTheory/intro.md b/docs/src/InvariantTheory/intro.md index 8f84884d9e99..87610955214e 100644 --- a/docs/src/InvariantTheory/intro.md +++ b/docs/src/InvariantTheory/intro.md @@ -19,7 +19,11 @@ $K[V]:=S(V^*)=\bigoplus_{d\geq 0} S^d V^*$ which preserves the grading. -The *invariants* of $G$ are the fixed points of this action, its *invariant ring* is the graded subalgebra +!!! note + In OSCAR, group actions are by convention assumed to be right actions and we follow this convention with our definition above. + Note, however, that the left action given by $\pi \;\! . \;\! f := f \circ \rho(\pi^{-1})$ is quite common in the literature. + +The *invariants* of $G$ are the fixed points of the action defined above, its *invariant ring* is the graded subalgebra $K[V]^G:=\{f\in K[V] \mid f \;\! . \;\! \pi =f {\text { for any }} \pi\in G\} \subset K[V].$ diff --git a/docs/src/InvariantTheory/reductive_groups.md b/docs/src/InvariantTheory/reductive_groups.md index c7c7c367beb6..d3009a892055 100644 --- a/docs/src/InvariantTheory/reductive_groups.md +++ b/docs/src/InvariantTheory/reductive_groups.md @@ -4,18 +4,23 @@ CurrentModule = Oscar # Invariants of Linearly Reductive Groups -In this section, with notation as in the introduction to this chapter, $G$ will be a *linearly algebraic group* over an algebraically closed field $K$, and ``\rho: G \to \text{GL}(V)\cong \text{GL}_n(K)`` will be a *rational* representation of $G$. As in the previous sections, ``G`` will act on $K[V]\cong K[x_1, \dots, x_n]$ by linear substitution: - -$(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f((x_1, \dots, x_n) \cdot \rho(\pi)) \text{ for all } \pi\in G.$ +In this section, with notation as in the introduction to this chapter, +$G$ will be a *linearly algebraic group* over an algebraically closed +field $K$, $\rho: G \to \text{GL}(V)\cong \text{GL}_n(K)$ will +be a *rational* representation of $G$, and +$G$ will act on $K[V]\cong K[x_1, \dots, x_n]$ by linear +substitution: If $\rho(\pi) = (a_{i, j})$, then +$(f \;\! . \;\! \pi) (x_1, \dots, x_n) = f\bigl(\sum_j a_{1, j}x_j, \dots, \sum_j a_{n, j}x_j\bigr).$ !!! note - The definition of linear reductivity guarantees the existence of a Reynolds operator $\mathcal R: K[V] \to K[V]$. - By Hilbert's celebrated finiteness theorem, $K[V]^G$ is finitely generated as a $K$-algebra. - - By a result of Hochster and Roberts, $K[V]^G$ is Cohen-Macaulay. + - By a result of Hochster and Roberts, $K[V]^G$ is Cohen-Macaulay. -In cases where the Reynold's operator can be explicitly handled, generators of invariant rings of linearly reductive groups can be found in two steps using Derksen's algorithm, see [Der99](@cite) : +In cases where the Reynold's operator is explicitly known, generators of invariant rings of linearly reductive groups +can be found in two steps using Derksen's algorithm, see [Der99](@cite) : - First, compute generators of Hilbert's null-cone ideal. - Then, apply the Reynold's operator to these generators. @@ -24,32 +29,59 @@ See also [DK15](@cite) and [DJ98](@cite). ## Creating Invariant Rings -There are no exact means to handle algebraically closed fields on the computer. For the computation of invariant rings in the above setting, on the other hand, there is no need to deal with explicit elements of ``G`` or with its group structure. The implementation of Derksen's algorithm in OSCAR can handle situations where both $G$ and the representation $\rho$ are defined over an exact subfield $k$ of $K$ which is supported by OSCAR: +### How Linearly Reductive Groups and Their Representations are Given + +For the computation of invariant rings in the above setting, there is no need to deal with explicit elements of ``G`` or with its group structure. +The implementation of Derksen's algorithm in OSCAR can handle situations where both $G$ and the representation $\rho$ are defined over an exact +subfield $k$ of $K$ which is supported by OSCAR: - ``G`` is specified as an affine algebraic variety by polynomials with coefficients in $k$; - ``\rho: G \to \text{GL}(V) \cong \text{GL}_n(K)`` is specified by an $n\times n$ matrix whose entries are polynomials in the same variables as those specifying $G$, with coefficients in $k$. -All computations are then performed over $k$. +!!! note + Proceeding as above is not a problem: Derksen's algorithms relies on Gröbner bases techniques and means to compute + Reynolds operators. It does, thus, not change the initial ground field $k$. That is, all computations are performed over $k$ + and computations over any extension field of $k$ would lead to the same results. -!!! warning - OSCAR does neither check whether the affine variety defined by the given equations carries a group structure which makes it a linearly reductive group nor does it check whether the given $n\times n$ matrix really defines a representation. - +In OSCAR, the basic set-up for a linearly reductive group in the context of Derksen's algorithm is provided by the +function `linearly_reductive_group`. At current state, this only supports rational actions of the special linear group +(in characteristic zero). For the action of this group by linear substitution on forms, an explicit Reynolds operator is +given by Cayley's Omega-process. We show this at work later in this section. + + +```@docs +linearly_reductive_group(sym::Symbol, m::Int, K::Field) +``` +```@docs +linearly_reductive_group(sym::Symbol, m::Int, R::MPolyRing) +``` -## Basic Data Associated to Invariant Rings +```@docs +representation_on_forms(G::LinearlyReductiveGroup, d::Int) +``` -## The Reynolds Operator +### Constructors for Invariant Rings -Omega-process +```@docs +invariant_ring(r::RepresentationLinearlyReductiveGroup) +``` -## Generators of Hilbert's Null-Cone Ideal +```@docs +invariant_ring(R::MPolyDecRing, r::RepresentationLinearlyReductiveGroup) +``` + + ### The Reynolds Operator -## Generators of the Invariant Ring +```@docs +reynolds_operator(R::RedGrpInvRing, f::MPolyRingElem) +``` ## Fundamental Systems of Invariants -## Invariant Rings as Affine Algebras - +```@docs +fundamental_invariants(RG::RedGrpInvRing) +``` diff --git a/experimental/InvariantTheory/src/InvariantTheory.jl b/experimental/InvariantTheory/src/InvariantTheory.jl index a5b895f6d20f..930b48407408 100644 --- a/experimental/InvariantTheory/src/InvariantTheory.jl +++ b/experimental/InvariantTheory/src/InvariantTheory.jl @@ -5,7 +5,7 @@ export LinearlyReductiveGroup, linearly_reductive_group, representation_matrix, group, reynolds_operator, group_ideal, canonical_representation, natural_representation export RepresentationLinearlyReductiveGroup, representation_reductive_group, representation_on_forms, representation_matrix, direct_sum, tensor -export RedGrpInvRing, invariant_ring, fundamental_invariants, NullConeIdeal, poly_ring, representation +export RedGrpInvRing, invariant_ring, fundamental_invariants, NullConeIdeal, polynomial_ring, representation, affine_algebra ########################## #Setting up Reductive Groups ########################## @@ -21,7 +21,7 @@ mutable struct LinearlyReductiveGroup function LinearlyReductiveGroup(sym::Symbol, m::Int, fld::Field) #have not decided the representation yet #check char(fld) - @assert sym == :SL + @assert sym == :SL && characteristic(fld) == 0 R, _ = polynomial_ring(fld, :z => (1:m,1:m)) return LinearlyReductiveGroup(sym, m, R) end @@ -29,14 +29,14 @@ mutable struct LinearlyReductiveGroup function LinearlyReductiveGroup(sym::Symbol, m::Int, pring::MPolyRing) #the ring input is the group ring #check char(field) G = new() - @assert sym == :SL fld = base_ring(pring) + @assert sym == :SL && characteristic(fld) == 0 characteristic(fld) == 0 || error("Characteristic should be 0 for linearly reductive groups") G.field = fld @req m^2 == ngens(pring) "ring not compatible" G.group = (sym,m) G.reynolds_operator = reynolds_slm - M = matrix(pring, m, m, gens(pring)) + M = transpose(matrix(pring, m, m, gens(pring))) G.canonical_representation = M G.group_ideal = ideal([det(M) - 1]) #base ring of M has to be the same as the representation matrix when that is created later. @@ -54,8 +54,51 @@ function Base.show(io::IO, G::LinearlyReductiveGroup) end #getter functions -linearly_reductive_group(sym::Symbol, m::Int, R::MPolyRing) = LinearlyReductiveGroup(sym,m,R) + +@doc raw""" + linearly_reductive_group(sym::Symbol, m::Int, K::Field) + +Return the linearly reductive group indicated by `sym`. + +Currently, the supported options for `sym` are: +* `:SL`, corresponding to the special linear group (of degree $m$ over the field $K$). + +# Examples +```jldoctest +julia> G = linearly_reductive_group(:SL, 2, QQ) +Reductive group SL2 + over QQ + +julia> group_ideal(G) +Ideal generated by + z[1, 1]*z[2, 2] - z[2, 1]*z[1, 2] - 1 +``` +""" linearly_reductive_group(sym::Symbol, m::Int, F::Field) = LinearlyReductiveGroup(sym,m,F) + +@doc raw""" + linearly_reductive_group(sym::Symbol, m::Int, R::MPolyRing) + +Return the linearly reductive group indicated by `sym`. + +Currently, the supported options for `sym` are: +* `:SL`, corresponding to the special linear group (of degree $m$ over the base field $K$ of $R$, where $R$ is the polynomial ring in which the defining ideal of SL$(m, K)$ lives). + +# Examples +```jldoctest +julia> S, z = polynomial_ring(QQ, "c"=> (1:2, 1:2)); + +julia> G = linearly_reductive_group(:SL,2,S) +Reductive group SL2 + over QQ + +julia> group_ideal(G) +Ideal generated by + c[1, 1]*c[2, 2] - c[2, 1]*c[1, 2] - 1 +``` +""" +linearly_reductive_group(sym::Symbol, m::Int, R::MPolyRing) = LinearlyReductiveGroup(sym,m,R) + group(G::LinearlyReductiveGroup) = G.group field(G::LinearlyReductiveGroup) = G.field reynolds_operator(G::LinearlyReductiveGroup) = G.reynolds_operator @@ -105,6 +148,25 @@ group(R::RepresentationLinearlyReductiveGroup) = R.group representation_matrix(R::RepresentationLinearlyReductiveGroup) = R.rep_mat vector_space_dimension(R::RepresentationLinearlyReductiveGroup) = ncols(R.rep_mat) +@doc raw""" + representation_on_forms(G::LinearlyReductiveGroup, d::Int) + +If `G` is the special linear group acting by linear substitution on forms of degree `d`, return the corresponding representation. + +# Examples +```jldoctest +julia> G = linearly_reductive_group(:SL, 2, QQ); + +julia> r = representation_on_forms(G, 2) +Representation of SL2 + on symmetric forms of degree 2 + +julia> representation_matrix(r) +[ z[1, 1]^2 2*z[1, 1]*z[2, 1] z[2, 1]^2] +[z[1, 1]*z[1, 2] z[1, 1]*z[2, 2] + z[2, 1]*z[1, 2] z[2, 1]*z[2, 2]] +[ z[1, 2]^2 2*z[1, 2]*z[2, 2] z[2, 2]^2] +``` +""" function representation_on_forms(G::LinearlyReductiveGroup, d::Int) @assert G.group[1] == :SL return RepresentationLinearlyReductiveGroup(G, d) @@ -271,7 +333,44 @@ end end end +@doc raw""" + invariant_ring(r::RepresentationLinearlyReductiveGroup) + +Return the invariant ring under the action defined by the representation `r` on an implicitly generated polynomial ring of appropriate dimension. + +# Examples +```jldoctest +julia> G = linearly_reductive_group(:SL, 2, QQ); + +julia> r = representation_on_forms(G, 2); + +julia> RG = invariant_ring(r) +Invariant Ring of +graded multivariate polynomial ring in 3 variables over QQ + under group action of SL2 +``` +""" invariant_ring(R::RepresentationLinearlyReductiveGroup) = RedGrpInvRing(R) + +@doc raw""" + invariant_ring(R::MPolyDecRing, r::RepresentationLinearlyReductiveGroup) + +Return the invariant subring of `R` under the action induced by the representation of `r` on `R`. + +# Examples +```jldoctest +julia> G = linearly_reductive_group(:SL, 3, QQ); + +julia> r = representation_on_forms(G, 3); + +julia> S, x = graded_polynomial_ring(QQ, "x" => 1:10); + +julia> RG = invariant_ring(S, r) +Invariant Ring of +graded multivariate polynomial ring in 10 variables over QQ + under group action of SL3 +``` +""" invariant_ring(ring::MPolyDecRing, R::RepresentationLinearlyReductiveGroup) = RedGrpInvRing(R, ring) @attr MPolyIdeal function NullConeIdeal(R::RedGrpInvRing) @@ -280,10 +379,31 @@ invariant_ring(ring::MPolyDecRing, R::RepresentationLinearlyReductiveGroup) = Re return ideal(generators(Z.group, I, Z.rep_mat)) end -poly_ring(R::RedGrpInvRing) = R.poly_ring +polynomial_ring(R::RedGrpInvRing) = R.poly_ring group(R::RedGrpInvRing) = R.group representation(R::RedGrpInvRing) = R.representation + + +@doc raw""" + fundamental_invariants(RG::RedGrpInvRing) + +Return a system of fundamental invariants for `RG`. + +# Examples +```jldoctest +julia> G = linearly_reductive_group(:SL, 2, QQ); + +julia> r = representation_on_forms(G, 2); + +julia> RG = invariant_ring(r); + +julia> fundamental_invariants(RG) +1-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}: + -X[1]*X[3] + X[2]^2 + +``` +""" @attr function fundamental_invariants(z::RedGrpInvRing) #unable to use abstract type R = z.representation I, M = proj_of_image_ideal(R.group, R.rep_mat) @@ -489,9 +609,69 @@ function reynolds_operator(X::RepresentationLinearlyReductiveGroup, elem::MPolyR return reverse_map(f) end +@doc raw""" + reynolds_operator(RG::RedGrpInvRing, f::MPolyRingElem) + +Return the image of `f` under the Reynolds operator corresponding to `RG`. + +# Examples +```jldoctest +julia> G = linearly_reductive_group(:SL, 3, QQ); + +julia> r = representation_on_forms(G, 3); + +julia> S, x = graded_polynomial_ring(QQ, "x" => 1:10); + +julia> RG = invariant_ring(S, r); + +julia> 75*reynolds_operator(RG, x[5]^4) +x[1]*x[4]*x[8]*x[10] - x[1]*x[4]*x[9]^2 - x[1]*x[5]*x[7]*x[10] + x[1]*x[5]*x[8]*x[9] + x[1]*x[6]*x[7]*x[9] - x[1]*x[6]*x[8]^2 - x[2]^2*x[8]*x[10] + x[2]^2*x[9]^2 + x[2]*x[3]*x[7]*x[10] - x[2]*x[3]*x[8]*x[9] + x[2]*x[4]*x[5]*x[10] - x[2]*x[4]*x[6]*x[9] - 2*x[2]*x[5]^2*x[9] + 3*x[2]*x[5]*x[6]*x[8] - x[2]*x[6]^2*x[7] - x[3]^2*x[7]*x[9] + x[3]^2*x[8]^2 - x[3]*x[4]^2*x[10] + 3*x[3]*x[4]*x[5]*x[9] - x[3]*x[4]*x[6]*x[8] - 2*x[3]*x[5]^2*x[8] + x[3]*x[5]*x[6]*x[7] + x[4]^2*x[6]^2 - 2*x[4]*x[5]^2*x[6] + x[5]^4 +``` +""" function reynolds_operator(R::RedGrpInvRing, elem::MPolyRingElem) X = R.representation return reynolds_operator(X, elem) end include("TorusInvariantsFast.jl") + + +#####################Invariant rings as affine algebras + +@doc raw""" + affine_algebra(RG::RedGrpInvRing) + +Return the invariant ring `RG` as an affine algebra (this amounts to compute the algebra syzygies among the fundamental invariants of `RG`). + +In addition, if `A` is this algebra, and `R` is the polynomial ring of which `RG` is a subalgebra, +return the inclusion homomorphism `A` $\hookrightarrow$ `R` whose image is `RG`. + +# Examples +```jldoctest +julia> G = linearly_reductive_group(:SL, 2, QQ); + +julia> r = representation_on_forms(G, 2); + +julia> S, x = graded_polynomial_ring(QQ, "x" => 1:3); + +julia> RG = invariant_ring(S, r); + +julia> A, AtoS = affine_algebra(RG) +(Quotient of multivariate polynomial ring by ideal (0), Hom: A -> S) +``` +""" +@attr function affine_algebra(R::RedGrpInvRing) + V = fundamental_invariants(R) + s = length(V) + weights_ = zeros(Int, s) + for i in 1:s + weights_[i] = total_degree(V[i]) + end + S,_ = graded_polynomial_ring(field(group(representation(R))), "t"=>1:s; weights = weights_) + R_ = polynomial_ring(R) + StoR = hom(S,R_,V) + I = kernel(StoR) + Q, StoQ = quo(S,I) + QtoR = hom(Q,R_,V) + return Q, QtoR +end diff --git a/experimental/InvariantTheory/src/TorusInvariantsFast.jl b/experimental/InvariantTheory/src/TorusInvariantsFast.jl index 05c90697852f..04b3a9f6f209 100644 --- a/experimental/InvariantTheory/src/TorusInvariantsFast.jl +++ b/experimental/InvariantTheory/src/TorusInvariantsFast.jl @@ -1,4 +1,4 @@ -export torus_group, rank, field, representation_from_weights, weights, group, invariant_ring, poly_ring, representation, fundamental_invariants, affine_algebra +export torus_group, rank, field, representation_from_weights, weights, group, invariant_ring, polynomial_ring, representation, fundamental_invariants, affine_algebra ##################### #Setting up tori for fast torus algorithm @@ -209,7 +209,7 @@ graded multivariate polynomial ring in 4 variables over QQ under group action of invariant_ring(R::RepresentationTorusGroup) = TorGrpInvRing(R) @doc raw""" - poly_ring(RT::TorGrpInvRing) + polynomial_ring(RT::TorGrpInvRing) # Examples ```jldoctest @@ -218,7 +218,7 @@ Torus of rank 2 over QQ ``` """ -poly_ring(R::TorGrpInvRing) = R.poly_ring +polynomial_ring(R::TorGrpInvRing) = R.poly_ring @doc raw""" group(RT::TorGrpInvRing) @@ -269,7 +269,7 @@ function fundamental_invariants(z::TorGrpInvRing) return z.fundamental else R = z.representation - z.fundamental = torus_invariants_fast(weights(R), poly_ring(z)) + z.fundamental = torus_invariants_fast(weights(R), polynomial_ring(z)) return z.fundamental end end @@ -403,7 +403,7 @@ function affine_algebra(R::TorGrpInvRing) V = fundamental_invariants(R) s = length(V) S,t = polynomial_ring(field(group(representation(R))), "t"=>1:s) - R_ = poly_ring(R) + R_ = polynomial_ring(R) StoR = hom(S,R_,V) I = kernel(StoR) Q, StoQ = quo(S,I) diff --git a/experimental/InvariantTheory/test/runtests.jl b/experimental/InvariantTheory/test/runtests.jl index 3de3a24b3bde..9e9412d0b130 100644 --- a/experimental/InvariantTheory/test/runtests.jl +++ b/experimental/InvariantTheory/test/runtests.jl @@ -52,7 +52,7 @@ T = torus_group(QQ,2) r = representation_from_weights(T, [1 0; 0 1; -1 -1; -1 1]) I = invariant_ring(r) - R = poly_ring(I) + R = polynomial_ring(I) X = gens(R) f = fundamental_invariants(I) @test f == [X[1]*X[2]*X[3], X[1]^2*X[3]*X[4]] From 27876bbc9e1da2041815d2fdb12a5259a449d8d9 Mon Sep 17 00:00:00 2001 From: Morgan Rodgers Date: Tue, 27 Feb 2024 22:22:41 +0100 Subject: [PATCH 24/30] add docstrings for `acting_group` and `action_function` (#3432) (cherry picked from commit c58c7ebed77925f8952df4c1301c1706923b8119) --- docs/src/Groups/action.md | 4 ++++ src/Groups/gsets.jl | 36 ++++++++++++++++++++++++++++++++++-- src/exports.jl | 1 + 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/docs/src/Groups/action.md b/docs/src/Groups/action.md index fc96b19cf79e..4d026caaa7ff 100644 --- a/docs/src/Groups/action.md +++ b/docs/src/Groups/action.md @@ -52,10 +52,14 @@ A G-set provides an explicit bijection between the elements of the set and the corresponding set of positive integers on which the induced permutation group acts, see [`action_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup`](@ref). +Note that the explicit elements of a G-set `Omega` can be obtained using +`collect(Omega)`. ```@docs gset(G::GAPGroup, fun::Function, Omega) permutation +acting_group(Omega::GSetByElements) +action_function(Omega::GSetByElements) action_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup orbit(Omega::GSetByElements{<:GAPGroup}, omega::T) where T orbit(G::PermGroup, omega) diff --git a/src/Groups/gsets.jl b/src/Groups/gsets.jl index 3ed5d2aa1464..e45a79aeeaba 100644 --- a/src/Groups/gsets.jl +++ b/src/Groups/gsets.jl @@ -69,8 +69,40 @@ function Base.show(io::IO, x::GSetByElements) end end -# TODO: document `acting_group`, `action_function` +""" + acting_group(Omega::GSetByElements) + +Return the group `G` acting on `Omega`. + +# Examples +```jldoctest +julia> G = symmetric_group(4); + +julia> acting_group(gset(G, [1])) == G +true +``` +""" acting_group(Omega::GSetByElements) = Omega.group + +@doc raw""" + action_function(Omega::GSetByElements) + +Return the function $f: \Omega \times G \to \Omega$ that defines the G-set. + +# Examples +```jldoctest +julia> G = symmetric_group(4); + +julia> action_function(gset(G, [1])) == ^ +true + +julia> action_function(gset(G, [[1, 2]])) == on_tuples +true + +julia> action_function(gset(G, on_sets, [[1, 2]])) == on_sets +true +``` +""" action_function(Omega::GSetByElements) = Omega.action_function # The following works for all G-set types that support attributes @@ -241,7 +273,7 @@ function ^(omega::ElementOfGSet, g::T) where {T<:AbstractAlgebra.GroupElem} return ElementOfGSet(Omega, fun(omega.obj, g)) end -==(omega1::ElementOfGSet, omega2::ElementOfGSet) = +==(omega1::ElementOfGSet, omega2::ElementOfGSet) = ((omega1.gset == omega2.gset) && (omega1.obj == omega2.obj)) function Base.hash(omega::ElementOfGSet, h::UInt) diff --git a/src/exports.jl b/src/exports.jl index a79f6df4a89b..01b91af6b1f4 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -182,6 +182,7 @@ export acting_domain export acting_group export acting_subgroup export action +export action_function export action_homomorphism export add_edge! export add_gluing! From 193a4a54a6d51b3a282f56531ae96f006a0b1df9 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 29 Feb 2024 16:50:02 +0100 Subject: [PATCH 25/30] Ensure fp_group(G) transfers group attributes (#3464) (cherry picked from commit 0e19721394c6069a9c8be9d482573560a37a2676) --- src/Groups/homomorphisms.jl | 3 +++ test/Groups/homomorphisms.jl | 32 +++++++++++++++++++++++--------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Groups/homomorphisms.jl b/src/Groups/homomorphisms.jl index 312f53b0b321..afe4e1e3b3a0 100644 --- a/src/Groups/homomorphisms.jl +++ b/src/Groups/homomorphisms.jl @@ -520,6 +520,9 @@ function isomorphism(::Type{T}, G::GAPGroup) where T <: Union{FPGroup, PcGroup, f = fun(G.X)::GapObj @req f !== GAP.Globals.fail "Could not convert group into a group of type $T" H = T(GAP.Globals.ImagesSource(f)::GapObj) + # TODO: remove the next line once https://github.com/gap-system/gap/pull/5660 + # is deployed to Oscar + GAP.Globals.UseIsomorphismRelation(G.X, H.X) return GAPGroupHomomorphism(G, H, f) end::GAPGroupHomomorphism{typeof(G), T} end diff --git a/test/Groups/homomorphisms.jl b/test/Groups/homomorphisms.jl index f922a9b81d4e..14baac3b4d83 100644 --- a/test/Groups/homomorphisms.jl +++ b/test/Groups/homomorphisms.jl @@ -326,15 +326,29 @@ end end @testset "Group types as constructors" begin - G = symmetric_group(4) - for (T, f) in [(FPGroup, fp_group), (PcGroup, pc_group), (PermGroup, permutation_group)] - H = T(G) - @test H isa T - @test is_isomorphic(G, H)[1] - - H = f(G) - @test H isa T - @test is_isomorphic(G, H)[1] + @testset "Source $G" for G in [ + cyclic_group(5), + dihedral_group(10), + symmetric_group(4), + transitive_group(5,2), + #abelian_group(5), # FIXME error in is_isomorphic + ] + @testset "Range type $T" for (T, f) in [ + (FPGroup, fp_group), + (PcGroup, pc_group), + (PermGroup, permutation_group), + #(FinGenAbGroup, FinGenAbGroup), # FIXME: errors + ] + H = T(G) + @test H isa T + @test has_order(H) + @test is_isomorphic(G, H)[1] + + H = f(G) + @test H isa T + @test has_order(H) + @test is_isomorphic(G, H)[1] + end end G = cyclic_group(5) From 38dc74af949950b3544c6725acdf85da287fa1cd Mon Sep 17 00:00:00 2001 From: Matthias Zach <85350711+HechtiDerLachs@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:13:55 +0100 Subject: [PATCH 26/30] Export weierstrass_chart_on_minimal_model and patch transform_to_weierstrass (#3458) * Export weierstrass_chart_on_minimal_model. * Repair transform_to_weierstrass. (cherry picked from commit 1a8e8e37ec9b3db16581f01641243005380d7043) --- experimental/Schemes/elliptic_surface.jl | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/experimental/Schemes/elliptic_surface.jl b/experimental/Schemes/elliptic_surface.jl index d4e926026435..6ae19a7cea0c 100644 --- a/experimental/Schemes/elliptic_surface.jl +++ b/experimental/Schemes/elliptic_surface.jl @@ -1,4 +1,4 @@ -export elliptic_surface, trivial_lattice, weierstrass_model, weierstrass_chart, algebraic_lattice, zero_section, section, weierstrass_contraction, fiber_components, generic_fiber, reducible_fibers, fibration_type, mordell_weil_lattice, elliptic_parameter, set_mordell_weil_basis!, EllipticSurface, weierstrass_chart, transform_to_weierstrass +export elliptic_surface, trivial_lattice, weierstrass_model, weierstrass_chart, algebraic_lattice, zero_section, section, weierstrass_contraction, fiber_components, generic_fiber, reducible_fibers, fibration_type, mordell_weil_lattice, elliptic_parameter, set_mordell_weil_basis!, EllipticSurface, weierstrass_chart_on_minimal_model, transform_to_weierstrass @doc raw""" EllipticSurface{BaseField<:Field, BaseCurveFieldType} <: AbsCoveredScheme{BaseField} @@ -1494,6 +1494,23 @@ on the curve defined by `g`, i.e. `g(P) == 0`. """ function transform_to_weierstrass(g::MPolyRingElem, x::MPolyRingElem, y::MPolyRingElem, P::Vector{<:RingElem}) R = parent(g) + F = fraction_field(R) + + # In case of variables in the wrong order, switch and transform the result. + if x == R[2] && y == R[1] + switch = hom(R, R, reverse(gens(R))) + g_trans, trans = transform_to_weierstrass(switch(g), y, x, reverse(P)) + new_trans = MapFromFunc(F, F, f->begin + switch_num = switch(numerator(f)) + switch_den = switch(denominator(f)) + interm_res = trans(F(switch_num))//trans(F(switch(den))) + num = numerator(interm_res) + den = denominator(interm_res) + switch(num)//switch(den) + end + ) + return switch(g_trans), new_trans + end @assert ngens(R) == 2 "input polynomial must be bivariate" @assert x in gens(R) "second argument must be a variable of the parent of the first" @assert y in gens(R) "third argument must be a variable of the parent of the first" @@ -1503,9 +1520,6 @@ function transform_to_weierstrass(g::MPolyRingElem, x::MPolyRingElem, y::MPolyRi kkxy, Y = polynomial_ring(kkx, :y, cached=false) imgs = [kkxy(X), Y] - if x == R[2] && y == R[1] - imgs = reverse(imgs) - end split_map = hom(R, kkxy, imgs) G = split_map(g) @@ -1558,7 +1572,6 @@ function transform_to_weierstrass(g::MPolyRingElem, x::MPolyRingElem, y::MPolyRi #@assert x == evaluate(x1, [x2, y2]) #@assert y == evaluate(y1, [x2, y2]) end - F = fraction_field(R) @assert F === parent(x1) "something is wrong with caching of fraction fields" # TODO: eventually add the inverse. trans = MapFromFunc(F, F, f->evaluate(numerator(f), [x1, y1])//evaluate(denominator(f), [x1, y1])) From 1a8d6276a2420e4c691c4894a25570c99a794dc8 Mon Sep 17 00:00:00 2001 From: Johannes Schmitt Date: Thu, 29 Feb 2024 17:22:54 +0100 Subject: [PATCH 27/30] Fix a doc signature (#3466) (cherry picked from commit 189a55fce5621ac901e1e655a4569949c1664f82) --- docs/src/NumberTheory/abelian_closure.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/NumberTheory/abelian_closure.md b/docs/src/NumberTheory/abelian_closure.md index 4b0ce54c8c4f..3efacf5231a1 100644 --- a/docs/src/NumberTheory/abelian_closure.md +++ b/docs/src/NumberTheory/abelian_closure.md @@ -20,7 +20,7 @@ abelian_closure(::QQField) Given the abelian closure, the generator can be recovered as follows: ```@docs -gen(::QQAbField) +gen(::QQAbField{AbsSimpleNumField}) atlas_irrationality atlas_description ``` From dee8a250e2b5088a80c9ef211f77317c21363992 Mon Sep 17 00:00:00 2001 From: Wolfram Decker Date: Thu, 29 Feb 2024 16:25:59 +0100 Subject: [PATCH 28/30] Added comment on convention (#3467) * Added comment on convention * Update experimental/InvariantTheory/src/InvariantTheory.jl Co-authored-by: Johannes Schmitt --------- Co-authored-by: Johannes Schmitt (cherry picked from commit 21d13c901dcc14d03e2613d76abd7094c049eb16) --- docs/src/InvariantTheory/reductive_groups.md | 3 ++- experimental/InvariantTheory/src/InvariantTheory.jl | 6 +++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/docs/src/InvariantTheory/reductive_groups.md b/docs/src/InvariantTheory/reductive_groups.md index d3009a892055..cc42ff60bbb9 100644 --- a/docs/src/InvariantTheory/reductive_groups.md +++ b/docs/src/InvariantTheory/reductive_groups.md @@ -45,7 +45,8 @@ subfield $k$ of $K$ which is supported by OSCAR: In OSCAR, the basic set-up for a linearly reductive group in the context of Derksen's algorithm is provided by the function `linearly_reductive_group`. At current state, this only supports rational actions of the special linear group -(in characteristic zero). For the action of this group by linear substitution on forms, an explicit Reynolds operator is +(in characteristic zero). For the action of this group by linear +substitution on, say, $n$-ary forms of degree $d$, an explicit Reynolds operator is given by Cayley's Omega-process. We show this at work later in this section. diff --git a/experimental/InvariantTheory/src/InvariantTheory.jl b/experimental/InvariantTheory/src/InvariantTheory.jl index 930b48407408..43d7dfe9ec9d 100644 --- a/experimental/InvariantTheory/src/InvariantTheory.jl +++ b/experimental/InvariantTheory/src/InvariantTheory.jl @@ -151,7 +151,11 @@ vector_space_dimension(R::RepresentationLinearlyReductiveGroup) = ncols(R.rep_ma @doc raw""" representation_on_forms(G::LinearlyReductiveGroup, d::Int) -If `G` is the special linear group acting by linear substitution on forms of degree `d`, return the corresponding representation. +If `G` is the special linear group acting by linear substitution on, say, `n`-ary forms of degree `d`, return the corresponding representation. + +!!! note + In accordance with classical papers, an $n$-ary form of degree $d$ in $K[x_1, \dots, x_n]$ is written as a $K$-linear combination + of the $K$-basis with elements $\binom{n}{I}x^I$. Here, $I = (i_1, \dots, i_n)\in\mathbb Z_{\geq 0}^n$ with $i_1+\dots +i_n =d$. # Examples ```jldoctest From 70616bbbdb051534c7379aa9b48c1da707b165bc Mon Sep 17 00:00:00 2001 From: Max Horn Date: Thu, 29 Feb 2024 20:30:16 +0100 Subject: [PATCH 29/30] Adjust to renaming of `rank(A::FinGenAbGroup)` to `torsion_free_rank(A::FinGenAbGroup)` (#3457) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Prepare for renaming of rank(A::FinGenAbGroup) ... to torsion_free_rank(A::FinGenAbGroup), see also . * Use is_z_graded in _regularity_bound * more rank -> torsion_free_rank * more * more more * Update experimental/GModule/Cohomology.jl * more more more * bump Hecke --------- Co-authored-by: Tommy Hofmann Co-authored-by: Lars Göttgens (cherry picked from commit 8b863edad17d4cd098a82a65e6f35b7a862a08ae) --- Project.toml | 2 +- experimental/FTheoryTools/src/auxiliary.jl | 4 ++-- experimental/GModule/Cohomology.jl | 5 ++++- experimental/GModule/GaloisCohomology.jl | 8 ++++---- .../NormalToricVarieties/attributes.jl | 10 +++++----- .../NormalToricVarieties/properties.jl | 2 +- .../ToricDivisors/constructors.jl | 2 +- .../ToricMorphisms/attributes.jl | 2 +- .../ToricMorphisms/constructors.jl | 6 +++--- .../cohomCalg/VanishingSets/constructors.jl | 2 +- .../ToricVarieties/cohomCalg/auxiliary.jl | 2 +- src/Modules/ModulesGraded.jl | 3 +-- src/Rings/mpoly-graded.jl | 12 +++++++----- src/imports.jl | 6 ++++++ .../ToricVarieties/affine_normal_varieties.jl | 8 ++++---- .../ToricVarieties/del_pezzo_surfaces.jl | 12 ++++++------ .../ToricVarieties/hirzebruch_surfaces.jl | 12 ++++++------ .../ToricVarieties/normal_toric_varieties.jl | 4 ++-- .../ToricVarieties/projectivization.jl | 18 +++++++++--------- .../ToricVarieties/toric_blowdowns.jl | 4 ++-- .../ToricVarieties/toric_blowups.jl | 2 +- .../ToricVarieties/toric_divisor_classes.jl | 2 +- .../ToricVarieties/total_space.jl | 6 +++--- test/Combinatorics/SimplicialComplexes.jl | 6 +++--- test/Rings/hilbert.jl | 6 +++--- 25 files changed, 78 insertions(+), 68 deletions(-) diff --git a/Project.toml b/Project.toml index 62644e446997..e02df96a9029 100644 --- a/Project.toml +++ b/Project.toml @@ -31,7 +31,7 @@ AlgebraicSolving = "0.4.11" Distributed = "1.6" DocStringExtensions = "0.8, 0.9" GAP = "0.10.2" -Hecke = "0.29.0" +Hecke = "0.30.0" JSON = "^0.20, ^0.21" JSON3 = "1.13.2" LazyArtifacts = "1.6" diff --git a/experimental/FTheoryTools/src/auxiliary.jl b/experimental/FTheoryTools/src/auxiliary.jl index a11ee072b3a9..127c3601715a 100644 --- a/experimental/FTheoryTools/src/auxiliary.jl +++ b/experimental/FTheoryTools/src/auxiliary.jl @@ -35,10 +35,10 @@ function _ambient_space(base::NormalToricVariety, fiber_amb_space::NormalToricVa # Compute divisor group and the class group of a_space a_space_divisor_group = free_abelian_group(nrows(a_rays)) - a_space_class_group = free_abelian_group(ncols(b_grades) + rank(class_group(fiber_amb_space))) + a_space_class_group = free_abelian_group(ncols(b_grades) + torsion_free_rank(class_group(fiber_amb_space))) # Compute grading of Cox ring of a_space - a_space_grading = zero_matrix(ZZ, rank(a_space_divisor_group), rank(a_space_class_group)) + a_space_grading = zero_matrix(ZZ, torsion_free_rank(a_space_divisor_group), torsion_free_rank(a_space_class_group)) a_space_grading[1:nrows(b_grades), 1:ncols(b_grades)] = b_grades a_space_grading[1+nrows(b_rays):nrows(b_rays) + nrows(f_grades), 1+ncols(b_grades):ncols(b_grades) + ncols(f_grades)] = f_grades a_space_grading[1+nrows(b_rays), 1:ncols(D1_coeffs)] = D1_coeffs diff --git a/experimental/GModule/Cohomology.jl b/experimental/GModule/Cohomology.jl index 183f4d1b6707..5111d967f340 100644 --- a/experimental/GModule/Cohomology.jl +++ b/experimental/GModule/Cohomology.jl @@ -474,7 +474,10 @@ export action, cohomology_group, extension, pc_group_with_isomorphism export induce, is_consistent, istwo_cocycle, all_extensions export split_extension, extension_with_abelian_kernel -Oscar.dim(C::GModule) = rank(C.M) +_rank(M::FinGenAbGroup) = torsion_free_rank(M) +_rank(M) = rank(M) + +Oscar.dim(C::GModule) = _rank(C.M) Oscar.base_ring(C::GModule) = base_ring(C.M) Oscar.group(C::GModule) = C.G diff --git a/experimental/GModule/GaloisCohomology.jl b/experimental/GModule/GaloisCohomology.jl index 7a8e8e928798..13d5891c181e 100644 --- a/experimental/GModule/GaloisCohomology.jl +++ b/experimental/GModule/GaloisCohomology.jl @@ -542,7 +542,7 @@ Follows Debeerst rather closely... function debeerst(M::FinGenAbGroup, sigma::Map{FinGenAbGroup, FinGenAbGroup}) @assert domain(sigma) == codomain(sigma) == M @assert all(x->sigma(sigma(x)) == x, gens(M)) - @assert is_free(M) && rank(M) == ngens(M) + @assert is_free(M) && torsion_free_rank(M) == ngens(M) K, mK = kernel(id_hom(M)+sigma) fl, mX = has_complement(mK) @@ -557,8 +557,8 @@ function debeerst(M::FinGenAbGroup, sigma::Map{FinGenAbGroup, FinGenAbGroup}) _K, _mK = snf(K) _S, _mS = snf(S) - @assert is_trivial(_S) || rank(_S) == ngens(_S) - @assert rank(_K) == ngens(_K) + @assert is_trivial(_S) || torsion_free_rank(_S) == ngens(_S) + @assert torsion_free_rank(_K) == ngens(_K) m = matrix(FinGenAbGroupHom(_mS * mSK * inv((_mK)))) # elt in S * m = elt in K @@ -1912,7 +1912,7 @@ function shrink(C::GModule{PermGroup, FinGenAbGroup}, attempts::Int = 10) o = Oscar.orbit(q, rand(gens(q.M))) if length(o) == order(group(q)) s, ms = sub(q.M, collect(o), false) - if rank(s) == length(o) + if torsion_free_rank(s) == length(o) q, _mq = quo(q, ms, false) if first mq = _mq diff --git a/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl b/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl index 515b816b5f58..f60dfe25bdf2 100644 --- a/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl +++ b/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/attributes.jl @@ -198,7 +198,7 @@ julia> coordinate_names(antv) ``` """ @attr Vector{String} function coordinate_names(v::NormalToricVarietyType) - return ["x$(i)" for i in 1:rank(torusinvariant_weil_divisor_group(v))] + return ["x$(i)" for i in 1:torsion_free_rank(torusinvariant_weil_divisor_group(v))] end @@ -679,8 +679,8 @@ julia> torusinvariant_prime_divisors(p2) @attr Vector{ToricDivisor} function torusinvariant_prime_divisors(v::NormalToricVarietyType) ti_divisors = torusinvariant_weil_divisor_group(v) prime_divisors = ToricDivisor[] - for i in 1:rank(ti_divisors) - coeffs = zeros(Int, rank(ti_divisors)) + for i in 1:torsion_free_rank(ti_divisors) + coeffs = zeros(Int, torsion_free_rank(ti_divisors)) coeffs[i] = 1 push!(prime_divisors, toric_divisor(v, coeffs)) end @@ -756,7 +756,7 @@ Map number_of_cones = size(max_cones)[1] # compute quantities needed to construct the matrices - rc = rank(character_lattice(v)) + rc = torsion_free_rank(character_lattice(v)) number_ray_is_part_of_max_cones = [length(max_cones[:, k].s) for k in 1:number_of_rays] s = sum(number_ray_is_part_of_max_cones) cones_ray_is_part_of = [filter(x -> max_cones[x, r], 1:number_of_cones) for r in 1:number_of_rays] @@ -784,7 +784,7 @@ Map end # compute the matrix for mapping to torusinvariant Weil divisors - map_to_weil_divisors = zero_matrix(ZZ, number_of_cones * rc, rank(torusinvariant_weil_divisor_group(v))) + map_to_weil_divisors = zero_matrix(ZZ, number_of_cones * rc, torsion_free_rank(torusinvariant_weil_divisor_group(v))) for i in 1:number_of_rays map_to_weil_divisors[(cones_ray_is_part_of[i][1]-1)*rc+1:cones_ray_is_part_of[i][1]*rc, i] = [ZZRingElem(-c) for c in fan_rays[:, i]] end diff --git a/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/properties.jl b/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/properties.jl index 99582ec6ce76..5ff27f7096bc 100644 --- a/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/properties.jl +++ b/src/AlgebraicGeometry/ToricVarieties/NormalToricVarieties/properties.jl @@ -68,7 +68,7 @@ true if is_projective(v) == false return false end - if rank(class_group(v)) > 1 + if torsion_free_rank(class_group(v)) > 1 return false end w = [[Int(x) for x in transpose(g.coeff)] for g in gens(class_group(v))] diff --git a/src/AlgebraicGeometry/ToricVarieties/ToricDivisors/constructors.jl b/src/AlgebraicGeometry/ToricVarieties/ToricDivisors/constructors.jl index b6f80358aa1d..1c90960f5540 100644 --- a/src/AlgebraicGeometry/ToricVarieties/ToricDivisors/constructors.jl +++ b/src/AlgebraicGeometry/ToricVarieties/ToricDivisors/constructors.jl @@ -68,7 +68,7 @@ Torus-invariant, non-prime divisor on a normal toric variety ``` """ function divisor_of_character(v::NormalToricVarietyType, character::Vector{T}) where {T <: IntegerUnion} - r = rank(character_lattice(v)) + r = torsion_free_rank(character_lattice(v)) @req length(character) == r "Character must consist of $r integers" f = map_from_character_lattice_to_torusinvariant_weil_divisor_group(v) char = sum(character .* gens(domain(f))) diff --git a/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl b/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl index f9fcd02bec27..04694ec3b961 100644 --- a/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl +++ b/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/attributes.jl @@ -73,7 +73,7 @@ Map cod = codomain(tm) cod_rays = matrix(ZZ, rays(cod)) images = matrix(ZZ, rays(d)) * matrix(grid_morphism(tm)) - mapping_matrix = matrix(ZZ, zeros(ZZ, rank(torusinvariant_weil_divisor_group(cod)), 0)) + mapping_matrix = matrix(ZZ, zeros(ZZ, torsion_free_rank(torusinvariant_weil_divisor_group(cod)), 0)) for i in 1:nrows(images) v = [images[i,k] for k in 1:ncols(images)] j = findfirst(x -> x == true, [(v in maximal_cones(cod)[j]) for j in 1:n_maximal_cones(cod)]) diff --git a/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/constructors.jl b/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/constructors.jl index b679f8db0867..d1b84870a325 100644 --- a/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/constructors.jl +++ b/src/AlgebraicGeometry/ToricVarieties/ToricMorphisms/constructors.jl @@ -109,10 +109,10 @@ function toric_morphism(domain::NormalToricVarietyType, grid_morphism::FinGenAbG @req (nrows(matrix(grid_morphism)) > 0 && ncols(matrix(grid_morphism)) > 0) "The mapping matrix must not be empty" # check for a well-defined map - @req nrows(matrix(grid_morphism)) == rank(character_lattice(domain)) "The number of rows of the mapping matrix must match the rank of the character lattice of the domain toric variety" + @req nrows(matrix(grid_morphism)) == torsion_free_rank(character_lattice(domain)) "The number of rows of the mapping matrix must match the rank of the character lattice of the domain toric variety" # compute the morphism - @req ncols(matrix(grid_morphism)) == rank(character_lattice(codomain)) "The number of columns of the mapping matrix must match the rank of the character lattice of the codomain toric variety" + @req ncols(matrix(grid_morphism)) == torsion_free_rank(character_lattice(codomain)) "The number of columns of the mapping matrix must match the rank of the character lattice of the codomain toric variety" if check codomain_cones = maximal_cones(codomain) image_cones = [positive_hull(matrix(ZZ, rays(c)) * matrix(grid_morphism)) for c in maximal_cones(domain)] @@ -144,7 +144,7 @@ Toric morphism ``` """ function toric_identity_morphism(variety::NormalToricVarietyType) - r = rank(character_lattice(variety)) + r = torsion_free_rank(character_lattice(variety)) identity_matrix = matrix(ZZ, [[if i==j 1 else 0 end for j in 1:r] for i in 1:r]) grid_morphism = hom(character_lattice(variety), character_lattice(variety), identity_matrix) return ToricMorphism(variety, grid_morphism, variety) diff --git a/src/AlgebraicGeometry/ToricVarieties/cohomCalg/VanishingSets/constructors.jl b/src/AlgebraicGeometry/ToricVarieties/cohomCalg/VanishingSets/constructors.jl index 35fd82e0a001..5dc2de519646 100644 --- a/src/AlgebraicGeometry/ToricVarieties/cohomCalg/VanishingSets/constructors.jl +++ b/src/AlgebraicGeometry/ToricVarieties/cohomCalg/VanishingSets/constructors.jl @@ -7,7 +7,7 @@ ps::Vector{Polyhedron{QQFieldElem}} cis::Vector{Int} function ToricVanishingSet(toric_variety::NormalToricVarietyType, ps::Vector{Polyhedron{QQFieldElem}}, cis::Vector{Int}) - if !all(p -> ambient_dim(p) == rank(picard_group(toric_variety)), ps) + if !all(p -> ambient_dim(p) == torsion_free_rank(picard_group(toric_variety)), ps) throw(ArgumentError("The ambient dimensions of the polyhedra must match the rank as the picard group of the toric variety")) end if !all(i -> 0 <= i <= dim(toric_variety), cis) diff --git a/src/AlgebraicGeometry/ToricVarieties/cohomCalg/auxiliary.jl b/src/AlgebraicGeometry/ToricVarieties/cohomCalg/auxiliary.jl index 9e65f0d505e7..ab3efcfb6f2b 100644 --- a/src/AlgebraicGeometry/ToricVarieties/cohomCalg/auxiliary.jl +++ b/src/AlgebraicGeometry/ToricVarieties/cohomCalg/auxiliary.jl @@ -29,7 +29,7 @@ function command_string(v::NormalToricVarietyType, c::Vector{ZZRingElem}) # Join and return return join(string_list, ";") end -command_string(v::NormalToricVarietyType) = command_string(v, [ZZRingElem(0) for i in 1:rank(picard_group(v))]) +command_string(v::NormalToricVarietyType) = command_string(v, [ZZRingElem(0) for i in 1:torsion_free_rank(picard_group(v))]) diff --git a/src/Modules/ModulesGraded.jl b/src/Modules/ModulesGraded.jl index f11731edbbd0..a7d257e9eb96 100644 --- a/src/Modules/ModulesGraded.jl +++ b/src/Modules/ModulesGraded.jl @@ -3077,8 +3077,7 @@ end function _regularity_bound(M::SubquoModule) @assert is_graded(M) "module must be graded" S = base_ring(M) - G = grading_group(S) - @assert is_free(G) && isone(rank(G)) "base ring must be ZZ-graded" + @assert is_z_graded(S) "base ring must be ZZ-graded" @assert all(x->degree(Int, x; check=false) >= 0, gens(S)) "base ring variables must be non-negatively graded" res = free_resolution(M) result = maximum((x->degree(Int, x; check=false)).(gens(res[0]))) diff --git a/src/Rings/mpoly-graded.jl b/src/Rings/mpoly-graded.jl index a779894feaec..479f1d0ae0a0 100644 --- a/src/Rings/mpoly-graded.jl +++ b/src/Rings/mpoly-graded.jl @@ -231,7 +231,8 @@ is_standard_graded(::MPolyRing) = false Return `true` if `R` is $\mathbb Z$-graded, `false` otherwise. !!! note - Writing `G = grading_group(R)`, we say that `R` is $\mathbb Z$-graded if `is_free(G) && ngens(G) == rank(G) == 1` evaluates to `true`. + Writing `G = grading_group(R)`, we say that `R` is $\mathbb Z$-graded if + `G` is free abelian of rank `1`, and `ngens(G) == 1`. # Examples ```jldoctest @@ -245,7 +246,7 @@ true function is_z_graded(R::MPolyDecRing) is_graded(R) || return false A = grading_group(R) - return ngens(A) == 1 && rank(A) == 1 && is_free(A) + return ngens(A) == 1 && torsion_free_rank(A) == 1 && is_free(A) end is_z_graded(::MPolyRing) = false @@ -256,7 +257,8 @@ is_z_graded(::MPolyRing) = false Return `true` if `R` is $\mathbb Z^m$-graded for some $m$, `false` otherwise. !!! note - Writing `G = grading_group(R)`, we say that `R` is $\mathbb Z^m$-graded if `is_free(G) && ngens(G) == rank(G) == m` evaluates to `true`. + Writing `G = grading_group(R)`, we say that `R` is $\mathbb Z^m$-graded + `G` is free abelian of rank `m`, and `ngens(G) == m`. # Examples ```jldoctest @@ -295,7 +297,7 @@ false function is_zm_graded(R::MPolyDecRing) is_graded(R) || return false A = grading_group(R) - return is_free(A) && ngens(A) == rank(A) + return is_free(A) && ngens(A) == torsion_free_rank(A) end is_zm_graded(::MPolyRing) = false @@ -340,7 +342,7 @@ false is_graded(R) || return false G = grading_group(R) is_free(G) || return false - if ngens(G) == rank(G) + if ngens(G) == torsion_free_rank(G) W = reduce(vcat, [x.coeff for x = R.d]) if is_positive_grading_matrix(transpose(W)) return true diff --git a/src/imports.jl b/src/imports.jl index 9c7ff7555fb8..bdb686fc6718 100644 --- a/src/imports.jl +++ b/src/imports.jl @@ -195,4 +195,10 @@ import Hecke: primitive_element, QQBar +# temporary workaround, see https://github.com/thofma/Hecke.jl/pull/1224 +if !isdefined(Hecke, :torsion_free_rank) + torsion_free_rank(A::FinGenAbGroup) = rank(A) + export torsion_free_rank +end + import cohomCalg_jll diff --git a/test/AlgebraicGeometry/ToricVarieties/affine_normal_varieties.jl b/test/AlgebraicGeometry/ToricVarieties/affine_normal_varieties.jl index 019216a78672..b412a3037c33 100644 --- a/test/AlgebraicGeometry/ToricVarieties/affine_normal_varieties.jl +++ b/test/AlgebraicGeometry/ToricVarieties/affine_normal_varieties.jl @@ -18,10 +18,10 @@ @test dim(cone(antv)) == 2 @test length(affine_open_covering(antv)) == 1 @test length(gens(toric_ideal(antv))) == 1 - @test rank(torusinvariant_weil_divisor_group(antv)) == 2 - @test rank(character_lattice(antv)) == 2 - @test rank(domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(antv))) == 2 - @test rank(codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(antv))) == 2 + @test torsion_free_rank(torusinvariant_weil_divisor_group(antv)) == 2 + @test torsion_free_rank(character_lattice(antv)) == 2 + @test torsion_free_rank(domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(antv))) == 2 + @test torsion_free_rank(codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(antv))) == 2 @test elementary_divisors(codomain(map_from_torusinvariant_weil_divisor_group_to_class_group(antv))) == [ 2 ] @test elementary_divisors(class_group(antv)) == [ 2 ] @test ngens(cox_ring(antv)) == 2 diff --git a/test/AlgebraicGeometry/ToricVarieties/del_pezzo_surfaces.jl b/test/AlgebraicGeometry/ToricVarieties/del_pezzo_surfaces.jl index 4fa34e96a80d..b51f03cbd1f2 100644 --- a/test/AlgebraicGeometry/ToricVarieties/del_pezzo_surfaces.jl +++ b/test/AlgebraicGeometry/ToricVarieties/del_pezzo_surfaces.jl @@ -23,8 +23,8 @@ @testset "Basic attributes of dP1" begin @test length(torusinvariant_prime_divisors(dP1)) == 4 - @test rank(torusinvariant_cartier_divisor_group(dP1)) == 4 - @test rank(picard_group(dP1)) == 2 + @test torsion_free_rank(torusinvariant_cartier_divisor_group(dP1)) == 4 + @test torsion_free_rank(picard_group(dP1)) == 2 @test transpose(matrix(ZZ,rays(dP1))) == matrix(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP1)) @test domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP1)) == character_lattice(dP1) @test codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP1)) == torusinvariant_weil_divisor_group(dP1) @@ -44,8 +44,8 @@ @testset "Basic attributes of dP2" begin @test length(torusinvariant_prime_divisors(dP2)) == 5 - @test rank(torusinvariant_cartier_divisor_group(dP2)) == 5 - @test rank(picard_group(dP2)) == 3 + @test torsion_free_rank(torusinvariant_cartier_divisor_group(dP2)) == 5 + @test torsion_free_rank(picard_group(dP2)) == 3 @test transpose(matrix(ZZ,rays(dP2))) == matrix(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP2)) @test domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP2)) == character_lattice(dP2) @test codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP2)) == torusinvariant_weil_divisor_group(dP2) @@ -65,8 +65,8 @@ @testset "Basic attributes of dP3" begin @test length(torusinvariant_prime_divisors(dP3)) == 6 - @test rank(torusinvariant_cartier_divisor_group(dP3)) == 6 - @test rank(picard_group(dP3)) == 4 + @test torsion_free_rank(torusinvariant_cartier_divisor_group(dP3)) == 6 + @test torsion_free_rank(picard_group(dP3)) == 4 @test transpose(matrix(ZZ,rays(dP3))) == matrix(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP3)) @test domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP3)) == character_lattice(dP3) @test codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(dP3)) == torusinvariant_weil_divisor_group(dP3) diff --git a/test/AlgebraicGeometry/ToricVarieties/hirzebruch_surfaces.jl b/test/AlgebraicGeometry/ToricVarieties/hirzebruch_surfaces.jl index 56d0675c66ae..1300caab0ab5 100644 --- a/test/AlgebraicGeometry/ToricVarieties/hirzebruch_surfaces.jl +++ b/test/AlgebraicGeometry/ToricVarieties/hirzebruch_surfaces.jl @@ -34,17 +34,17 @@ @test betti_number(F5, 4) == 1 @test length(affine_open_covering(F5)) == 4 @test dim(polyhedral_fan(F5)) == 2 - @test rank(torusinvariant_weil_divisor_group(F5)) == 4 - @test rank(character_lattice(F5)) == 2 + @test torsion_free_rank(torusinvariant_weil_divisor_group(F5)) == 4 + @test torsion_free_rank(character_lattice(F5)) == 2 @test ngens(cox_ring(F5)) == 4 @test length(stanley_reisner_ideal(F5).gens) == 2 @test length(irrelevant_ideal(F5).gens) == 4 @test dim(nef_cone(F5)) == 2 @test dim(mori_cone(F5)) == 2 - @test rank(domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(F5))) == 2 - @test rank(codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(F5))) == 4 - @test rank(class_group(F5)) == 2 - @test rank(codomain(map_from_torusinvariant_weil_divisor_group_to_class_group(F5))) == 2 + @test torsion_free_rank(domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(F5))) == 2 + @test torsion_free_rank(codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(F5))) == 4 + @test torsion_free_rank(class_group(F5)) == 2 + @test torsion_free_rank(codomain(map_from_torusinvariant_weil_divisor_group_to_class_group(F5))) == 2 @test transpose(matrix(ZZ,rays(F5))) == matrix(map_from_character_lattice_to_torusinvariant_weil_divisor_group(F5)) @test domain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(F5)) == character_lattice(F5) @test codomain(map_from_character_lattice_to_torusinvariant_weil_divisor_group(F5)) == torusinvariant_weil_divisor_group(F5) diff --git a/test/AlgebraicGeometry/ToricVarieties/normal_toric_varieties.jl b/test/AlgebraicGeometry/ToricVarieties/normal_toric_varieties.jl index b9472c48a085..f5de0c6d67c0 100644 --- a/test/AlgebraicGeometry/ToricVarieties/normal_toric_varieties.jl +++ b/test/AlgebraicGeometry/ToricVarieties/normal_toric_varieties.jl @@ -9,8 +9,8 @@ @testset "Basic properties" begin @test is_complete(ntv) == true @test is_projective_space(ntv) == false - @test rank(torusinvariant_cartier_divisor_group(ntv)) == 4 - @test rank(domain(map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(ntv))) == 4 + @test torsion_free_rank(torusinvariant_cartier_divisor_group(ntv)) == 4 + @test torsion_free_rank(domain(map_from_torusinvariant_cartier_divisor_group_to_torusinvariant_weil_divisor_group(ntv))) == 4 @test is_complete(ntv2) == true @test length(ntv3) == 1 @test is_projective_space(ntv3[1]) == true diff --git a/test/AlgebraicGeometry/ToricVarieties/projectivization.jl b/test/AlgebraicGeometry/ToricVarieties/projectivization.jl index 49e54cc85bcd..9191ac211eb3 100644 --- a/test/AlgebraicGeometry/ToricVarieties/projectivization.jl +++ b/test/AlgebraicGeometry/ToricVarieties/projectivization.jl @@ -7,7 +7,7 @@ X = projectivization(D0, Da) @test is_smooth(X) == true @test (a < 2) == is_fano(X) - @test rank(picard_group(X)) == 2 + @test torsion_free_rank(picard_group(X)) == 2 @test integrate(cohomology_class(anticanonical_divisor(X))^dim(X)) == integrate(cohomology_class(anticanonical_divisor(hirzebruch_surface(NormalToricVariety, a)))^2) end end @@ -24,13 +24,13 @@ D2 = toric_divisor(P2, [0,2,0]) X3_P2 = projectivization(D0, D2) @testset "Test of some Fano projective bundles of dimension 3 over P2" begin - @test rank(picard_group(X1_P2)) == 2 + @test torsion_free_rank(picard_group(X1_P2)) == 2 @test is_fano(X1_P2) == true @test integrate(cohomology_class(anticanonical_divisor(X1_P2))^dim(X1_P2)) == 54 - @test rank(picard_group(X2_P2)) == 2 + @test torsion_free_rank(picard_group(X2_P2)) == 2 @test is_fano(X2_P2) == true @test integrate(cohomology_class(anticanonical_divisor(X2_P2))^dim(X2_P2)) == 56 - @test rank(picard_group(X3_P2)) == 2 + @test torsion_free_rank(picard_group(X3_P2)) == 2 @test is_fano(X3_P2) == true @test integrate(cohomology_class(anticanonical_divisor(X3_P2))^dim(X3_P2)) == 62 end @@ -43,11 +43,11 @@ l1_F1 = toric_line_bundle(F1, [0,1]) X2_F1 = projectivization(toric_line_bundle(F1, [0,0]), l1_F1) @testset "Test of some Fano projective bundles of dimension 3 over F1" begin - @test rank(picard_group(X1_F1)) == 3 + @test torsion_free_rank(picard_group(X1_F1)) == 3 @test is_fano(X1_F1) == true @test integrate(cohomology_class(anticanonical_divisor(X1_F1))^dim(X1_F1)) == 48 @test integrate(cohomology_class(l1_F1)^2) == 1 - @test rank(picard_group(X2_F1)) == 3 + @test torsion_free_rank(picard_group(X2_F1)) == 3 @test is_fano(X2_F1) == true @test integrate(cohomology_class(anticanonical_divisor(X2_F1))^dim(X2_F1)) == 50 end @@ -61,13 +61,13 @@ X2_P1xP1 = projectivization(O10, O10) X3_P1xP1 = projectivization(O00, O11) @testset "Test of some Fano projective bundles of dimension 3 over P1 * P1" begin - @test rank(picard_group(X1_P1xP1)) == 3 + @test torsion_free_rank(picard_group(X1_P1xP1)) == 3 @test is_fano(X1_P1xP1) == true @test integrate(cohomology_class(anticanonical_divisor(X1_P1xP1))^dim(X1_P1xP1)) == 44 - @test rank(picard_group(X2_P1xP1)) == 3 + @test torsion_free_rank(picard_group(X2_P1xP1)) == 3 @test is_fano(X2_P1xP1) == true @test integrate(cohomology_class(anticanonical_divisor(X2_P1xP1))^dim(X2_P1xP1)) == 48 - @test rank(picard_group(X3_P1xP1)) == 3 + @test torsion_free_rank(picard_group(X3_P1xP1)) == 3 @test is_fano(X3_P1xP1) == true @test integrate(cohomology_class(anticanonical_divisor(X3_P1xP1))^dim(X3_P1xP1)) == 52 end diff --git a/test/AlgebraicGeometry/ToricVarieties/toric_blowdowns.jl b/test/AlgebraicGeometry/ToricVarieties/toric_blowdowns.jl index 0b56eaf9aeb1..153a8b40f01b 100644 --- a/test/AlgebraicGeometry/ToricVarieties/toric_blowdowns.jl +++ b/test/AlgebraicGeometry/ToricVarieties/toric_blowdowns.jl @@ -4,8 +4,8 @@ bl = blow_up(P2, [1, 1]) @testset "Basic tests for simple toric blowdown" begin - @test rank(domain(grid_morphism(bl))) == 2 - @test rank(codomain(grid_morphism(bl))) == 2 + @test torsion_free_rank(domain(grid_morphism(bl))) == 2 + @test torsion_free_rank(codomain(grid_morphism(bl))) == 2 @test matrix(morphism_on_torusinvariant_weil_divisor_group(bl)) == matrix(ZZ, [1 0 0; 0 1 0; 0 0 1; 1 1 0]) @test matrix(morphism_on_torusinvariant_cartier_divisor_group(bl)) == matrix(morphism_on_torusinvariant_weil_divisor_group(bl)) end diff --git a/test/AlgebraicGeometry/ToricVarieties/toric_blowups.jl b/test/AlgebraicGeometry/ToricVarieties/toric_blowups.jl index ca44960d0e88..b35169a82818 100644 --- a/test/AlgebraicGeometry/ToricVarieties/toric_blowups.jl +++ b/test/AlgebraicGeometry/ToricVarieties/toric_blowups.jl @@ -22,7 +22,7 @@ @test betti_number(BP2, 3) == 0 @test betti_number(BP2, 4) == 1 @test euler_characteristic(BP2) == 4 - @test rank(picard_group(BP2)) == 2 + @test torsion_free_rank(picard_group(BP2)) == 2 end @testset "Trigger issue of PR3006" begin diff --git a/test/AlgebraicGeometry/ToricVarieties/toric_divisor_classes.jl b/test/AlgebraicGeometry/ToricVarieties/toric_divisor_classes.jl index 8a185f7694bf..b72bc1c8d04e 100644 --- a/test/AlgebraicGeometry/ToricVarieties/toric_divisor_classes.jl +++ b/test/AlgebraicGeometry/ToricVarieties/toric_divisor_classes.jl @@ -20,7 +20,7 @@ end @testset "Basic attributes" begin - @test rank(parent(divisor_class(DC2))) == 2 + @test torsion_free_rank(parent(divisor_class(DC2))) == 2 @test dim(toric_variety(DC2)) == 2 end diff --git a/test/AlgebraicGeometry/ToricVarieties/total_space.jl b/test/AlgebraicGeometry/ToricVarieties/total_space.jl index 50bb4be053a9..0e8c110e8a10 100644 --- a/test/AlgebraicGeometry/ToricVarieties/total_space.jl +++ b/test/AlgebraicGeometry/ToricVarieties/total_space.jl @@ -9,7 +9,7 @@ @test is_smooth(X) == true @test !is_fano(X) @test !is_complete(X) - @test rank(picard_group(X)) == 1 + @test torsion_free_rank(picard_group(X)) == 1 @test dim(X) == 3 @test (degree(canonical_bundle(X)) == 0) == (a - b == -2) end @@ -23,7 +23,7 @@ @test is_smooth(X) == true @test !is_fano(X) @test !is_complete(X) - @test rank(picard_group(X)) == rank(picard_group(S)) + @test torsion_free_rank(picard_group(X)) == torsion_free_rank(picard_group(S)) @test dim(X) == 3 @test degree(canonical_bundle(X)) == 0 end @@ -35,7 +35,7 @@ X = total_space(canonical_divisor(S)) @test is_smooth(X) == true @test !is_fano(X) - @test rank(picard_group(X)) == rank(picard_group(S)) + @test torsion_free_rank(picard_group(X)) == torsion_free_rank(picard_group(S)) @test dim(X) == 3 @test degree(canonical_bundle(X)) == 0 end diff --git a/test/Combinatorics/SimplicialComplexes.jl b/test/Combinatorics/SimplicialComplexes.jl index fbbb8e463632..611809b746a0 100644 --- a/test/Combinatorics/SimplicialComplexes.jl +++ b/test/Combinatorics/SimplicialComplexes.jl @@ -55,9 +55,9 @@ @test !is_trivial(H0) @test !is_trivial(H1) @test !is_trivial(H2) - @test rank(H0) == 1 - @test rank(H1) == 2 - @test rank(H2) == 1 + @test torsion_free_rank(H0) == 1 + @test torsion_free_rank(H1) == 2 + @test torsion_free_rank(H2) == 1 end @testset "is_isomorphic" begin diff --git a/test/Rings/hilbert.jl b/test/Rings/hilbert.jl index 88d2a11c2e42..01a4c82ca5b5 100644 --- a/test/Rings/hilbert.jl +++ b/test/Rings/hilbert.jl @@ -104,13 +104,13 @@ end JJ = ideal(RR, X^2 - Y^6); A, _ = quo(base_ring(JJ), JJ); (numer1, denom1), (H, iso) = multi_hilbert_series(A); - @test is_free(H) && isone(rank(H)) + @test is_free(H) && isone(torsion_free_rank(H)) S, t = laurent_polynomial_ring(ZZ, "t"); (numer2, denom2), (H, iso) = multi_hilbert_series(A; parent=S); - @test is_free(H) && isone(rank(H)) + @test is_free(H) && isone(torsion_free_rank(H)) Smult, (T,) = polynomial_ring(ZZ, ["t"]); (numer3, denom3), (H, iso) = multi_hilbert_series(A; parent=Smult); - @test is_free(H) && isone(rank(H)) + @test is_free(H) && isone(torsion_free_rank(H)) @test numer1 == evaluate(numer2, T) @test numer3 == evaluate(numer2, first(gens(parent(numer3)))) end From deb325fe11bf77725529263d1454e1d662f01ccd Mon Sep 17 00:00:00 2001 From: Lax202 <115473549+Lax202@users.noreply.github.com> Date: Thu, 29 Feb 2024 23:57:16 +0100 Subject: [PATCH 30/30] Grading + caching for affine algebra of torus invariants (#3469) * TorGrpInvRing to attributes, added test for affine_algebra for tori * graded affine algebra ring * fix to doctest (cherry picked from commit b6f11d05ca68fb97ce4823dd727e26a373e285a5) --- .../src/TorusInvariantsFast.jl | 27 +++++++++---------- experimental/InvariantTheory/test/runtests.jl | 6 +++++ 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/experimental/InvariantTheory/src/TorusInvariantsFast.jl b/experimental/InvariantTheory/src/TorusInvariantsFast.jl index 04b3a9f6f209..8d6e2ce245e2 100644 --- a/experimental/InvariantTheory/src/TorusInvariantsFast.jl +++ b/experimental/InvariantTheory/src/TorusInvariantsFast.jl @@ -159,15 +159,13 @@ end #Setting up invariant ring for fast torus algorithm. ##################### -mutable struct TorGrpInvRing +@attributes mutable struct TorGrpInvRing field::Field poly_ring::MPolyDecRing #graded group::TorusGroup representation::RepresentationTorusGroup - fundamental::Vector{MPolyDecRingElem} - #Invariant ring of reductive group G (in representation R), no other input. function TorGrpInvRing(R::RepresentationTorusGroup) #here G already contains information n and rep_mat n = length(weights(R)) @@ -258,20 +256,15 @@ julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]); julia> RT = invariant_ring(r); julia> fundamental_invariants(RT) -3-element Vector{MPolyDecRingElem}: +3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}: X[1]^2*X[3] X[1]*X[2]*X[3] X[2]^2*X[3] ``` """ -function fundamental_invariants(z::TorGrpInvRing) - if isdefined(z, :fundamental) - return z.fundamental - else - R = z.representation - z.fundamental = torus_invariants_fast(weights(R), polynomial_ring(z)) - return z.fundamental - end +@attr function fundamental_invariants(z::TorGrpInvRing) + R = z.representation + return torus_invariants_fast(weights(R), polynomial_ring(z)) end function Base.show(io::IO, R::TorGrpInvRing) @@ -390,7 +383,7 @@ julia> r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]); julia> RT = invariant_ring(r); julia> fundamental_invariants(RT) -3-element Vector{MPolyDecRingElem}: +3-element Vector{MPolyDecRingElem{QQFieldElem, QQMPolyRingElem}}: X[1]^2*X[3] X[1]*X[2]*X[3] X[2]^2*X[3] @@ -399,10 +392,14 @@ julia> affine_algebra(RT) (Quotient of multivariate polynomial ring by ideal (-t[1]*t[3] + t[2]^2), Hom: quotient of multivariate polynomial ring -> graded multivariate polynomial ring) ``` """ -function affine_algebra(R::TorGrpInvRing) +@attr function affine_algebra(R::TorGrpInvRing) V = fundamental_invariants(R) s = length(V) - S,t = polynomial_ring(field(group(representation(R))), "t"=>1:s) + weights_ = zeros(Int, s) + for i in 1:s + weights_[i] = total_degree(V[i]) + end + S,_ = graded_polynomial_ring(field(group(representation(R))), "t"=>1:s; weights = weights_) R_ = polynomial_ring(R) StoR = hom(S,R_,V) I = kernel(StoR) diff --git a/experimental/InvariantTheory/test/runtests.jl b/experimental/InvariantTheory/test/runtests.jl index 9e9412d0b130..e793ccbcd965 100644 --- a/experimental/InvariantTheory/test/runtests.jl +++ b/experimental/InvariantTheory/test/runtests.jl @@ -57,4 +57,10 @@ f = fundamental_invariants(I) @test f == [X[1]*X[2]*X[3], X[1]^2*X[3]*X[4]] + #another example, with affine algebra computation + T = torus_group(QQ,2) + r = representation_from_weights(T, [-1 1; -1 1; 2 -2; 0 -1]) + RT = invariant_ring(r) + A, _ = affine_algebra(RT) + @test ngens(modulus(A)) == 1 end