diff --git a/src/AlgebraicGeometry/Schemes/Divisors/AlgebraicCycles.jl b/src/AlgebraicGeometry/Schemes/Divisors/AlgebraicCycles.jl index 5239e0a16fa5..6b9b5e55719e 100644 --- a/src/AlgebraicGeometry/Schemes/Divisors/AlgebraicCycles.jl +++ b/src/AlgebraicGeometry/Schemes/Divisors/AlgebraicCycles.jl @@ -201,8 +201,8 @@ algebraic_cycle(X::AbsCoveredScheme, R::Ring; check::Bool=true) = AlgebraicCycle @doc raw""" AlgebraicCycle(I::AbsIdealSheaf, R::Ring) -Return the `AlgebraicCycle` ``D = colength(I) ⋅ V(I)`` with coefficients -in ``R`` for an equidimensional sheaf of ideals ``I``. +Return the `AlgebraicCycle` ``D = 1 ⋅ I`` with coefficients +in ``R`` for a sheaf of equidimensional ideals ``I``. """ function AlgebraicCycle(I::AbsIdealSheaf, R::Ring; check::Bool=true) D = AlgebraicCycle(space(I), R; check) @@ -213,8 +213,11 @@ end @doc raw""" algebraic_cycle(I::AbsIdealSheaf, R::Ring) -> AlgebraicCycle -Return the `AlgebraicCycle` defined by the equidimensional ideal sheaf `I`. +Return the `AlgebraicCycle` ``D = 1 ⋅ I`` with coefficients +in ``R`` for a sheaf of equidimensional ideals ``I``. +Note that ``I`` must be equidimensional. + # Examples ```jldoctest julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); @@ -236,7 +239,7 @@ given as the formal sum of ``` """ -algebraic_cycle(I::AbsIdealSheaf, R::Ring) = AlgebraicCycle(I, R) +algebraic_cycle(I::AbsIdealSheaf, R::Ring; check::Bool=true) = AlgebraicCycle(I, R; check) @doc raw""" AlgebraicCycle(I::AbsIdealSheaf) @@ -244,8 +247,8 @@ algebraic_cycle(I::AbsIdealSheaf, R::Ring) = AlgebraicCycle(I, R) Return the `AlgebraicCycle` ``D = 1 ⋅ I`` with coefficients in ``ℤ`` for a sheaf of equidimensional ideals ``I``. """ -function AlgebraicCycle(I::AbsIdealSheaf) - D = AlgebraicCycle(space(I), ZZ) +function AlgebraicCycle(I::AbsIdealSheaf; check::Bool=true) + D = AlgebraicCycle(space(I), ZZ; check) D[I] = one(ZZ) return D end @@ -276,7 +279,7 @@ given as the formal sum of 1 * sheaf of ideals ``` """ -algebraic_cycle(I::AbsIdealSheaf) = AlgebraicCycle(I) +algebraic_cycle(I::AbsIdealSheaf; check::Bool=true) = AlgebraicCycle(I; check) ### copy constructor function copy(D::AlgebraicCycle) diff --git a/src/AlgebraicGeometry/Schemes/Divisors/CartierDivisor.jl b/src/AlgebraicGeometry/Schemes/Divisors/CartierDivisor.jl index 254c9bcc1f86..ca3917a12b98 100644 --- a/src/AlgebraicGeometry/Schemes/Divisors/CartierDivisor.jl +++ b/src/AlgebraicGeometry/Schemes/Divisors/CartierDivisor.jl @@ -268,12 +268,15 @@ end ### (specialized variant of associated_points, using pure codimension 1 ### and taking multiplicities into account) @doc raw""" - irreducible_decomposition(C::EffectiveCartierDivisor) + irreducible_decomposition(C::EffectiveCartierDivisor; check::Bool=true) -> AbsWeilDivisor -Return a `Vector` of pairs ``(I,k)`` corresponding to the irreducible components of ``C``. More precisely, each ``I`` is a prime `AbsIdealSheaf` corresponding to an irreducible component of ``C`` and ``k``is the multiplicity of this component in ``C``. +Return $C$ as a linear combination of prime Weil divisors. + +Assumes that the ambient scheme is integral and locally noetherian. """ -function irreducible_decomposition(C::EffectiveCartierDivisor) +function irreducible_decomposition(C::EffectiveCartierDivisor; check::Bool=true) X = ambient_scheme(C) + @check is_integral(X) "ambient scheme must be integral" cov = default_covering(X) OOX = OO(X) @@ -301,7 +304,8 @@ function irreducible_decomposition(C::EffectiveCartierDivisor) push!(associated_primes_temp, (I_sheaf_temp, saturation_index)) end end - return(associated_primes_temp) + D = WeilDivisor(X, ZZ, IdDict(associated_primes_temp); check=false) + return D end ### Conversion into WeilDivisors diff --git a/src/AlgebraicGeometry/Schemes/Divisors/Types.jl b/src/AlgebraicGeometry/Schemes/Divisors/Types.jl index ff82ed4b12c3..3bdd6ce89e53 100644 --- a/src/AlgebraicGeometry/Schemes/Divisors/Types.jl +++ b/src/AlgebraicGeometry/Schemes/Divisors/Types.jl @@ -31,7 +31,7 @@ #is_separated(X) || error("scheme must be separated") # We need to test this somehow, but how? d = isempty(coefficients) ? 0 : dim(first(keys(coefficients))) for D in keys(coefficients) - (is_equidimensional(D) && dim(D) == d) || error("components of a cycle must be sheaves of equidimensional ideals") + (is_equidimensional(D) && dim(D) == d) || error("components of a cycle must be sheaves of equidimensional ideals of the same dimension") end true end @@ -46,7 +46,7 @@ end @doc raw""" WeilDivisor <: AbsWeilDivisor -A Weil divisor on an integral separated `AbsCoveredScheme` ``X``; +A Weil divisor on an integral `AbsCoveredScheme` ``X``; stored as a formal linear combination over some ring ``R`` of ideal sheaves on ``X``. """ @@ -114,10 +114,9 @@ end @doc raw""" EffectiveCartierDivisor{CoveredSchemeType<:AbsCoveredScheme} -An effective Cartier divisor on a scheme $X$ is a closed subscheme $D \subseteq S$ whose ideal sheaf $\mathcal{I}_D \subseteq \mathcal{O}_S$ is an invertible $\mathcal{O}_S$-module. In particular, $\mathcal{I}_D$ is locally principal. +An effective Cartier divisor on a scheme $X$ is a closed subscheme $D \subseteq X$ whose ideal sheaf $\mathcal{I}_D \subseteq \mathcal{O}_X$ is an invertible $\mathcal{O}_X$-module. In particular, $\mathcal{I}_D$ is locally principal. - -See [`trivializing_covering(C::EffectiveCartierDivisor)`](@ref) for how to +Internally, $C$ stores a [`trivializing_covering(C::EffectiveCartierDivisor)`](@ref). The scheme $X$ is of type `CoveredSchemeType`. """ @attributes mutable struct EffectiveCartierDivisor{ diff --git a/src/AlgebraicGeometry/Schemes/Divisors/WeilDivisor.jl b/src/AlgebraicGeometry/Schemes/Divisors/WeilDivisor.jl index f9b0194f3601..43f804700142 100644 --- a/src/AlgebraicGeometry/Schemes/Divisors/WeilDivisor.jl +++ b/src/AlgebraicGeometry/Schemes/Divisors/WeilDivisor.jl @@ -71,10 +71,10 @@ coefficients in the integer ring. ```jldoctest julia> P, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]); -julia> I = ideal([x^3-y^2*z]); - julia> Y = proj(P); +julia> I = ideal([(x^3-y^2*z)]); + julia> II = IdealSheaf(Y, I); julia> weil_divisor(II) @@ -83,6 +83,23 @@ Effective weil divisor with coefficients in integer ring given as the formal sum of 1 * sheaf of ideals + +julia> JJ = II^2; + +julia> D = weil_divisor(JJ) +Effective weil divisor + on scheme over QQ covered with 3 patches +with coefficients in integer ring +given as the formal sum of + 1 * product of 2 ideal sheaves + +julia> irreducible_decomposition(D) +Effective weil divisor + on scheme over QQ covered with 3 patches +with coefficients in integer ring +given as the formal sum of + 2 * sheaf of prime ideals + ``` """ weil_divisor(I::AbsIdealSheaf; check::Bool=true) = WeilDivisor(I, check=check) diff --git a/src/AlgebraicGeometry/Schemes/Sheaves/IdealSheaves.jl b/src/AlgebraicGeometry/Schemes/Sheaves/IdealSheaves.jl index 81f808122a14..b3a347593522 100644 --- a/src/AlgebraicGeometry/Schemes/Sheaves/IdealSheaves.jl +++ b/src/AlgebraicGeometry/Schemes/Sheaves/IdealSheaves.jl @@ -1031,6 +1031,29 @@ function maximal_associated_points( return comps end +@doc raw""" + minimal_primes(I::AbsIdealSheaf; kwargs...) + +Return the minimal prime ideal sheaves of ``I``. + +These are the ideal sheaves of the maximal associated points of ``I``. + +See [`maximal_associated_points`](@ref) for possible keyword arguments. +""" +minimal_primes(I::AbsIdealSheaf; kwargs...) = maximal_associated_points(I; kwargs...) + +@doc raw""" + associated_primes(I::AbsIdealSheaf; kwargs...) + +Return the prime ideal sheaves associated to``I``. + +These are the ideal sheaves of the associated points of ``I``. + +See [`associated_points`](@ref) for possible keyword arguments. +""" +associated_primes(I::AbsIdealSheaf; kwargs...) = associated_points(I; kwargs...) + + @doc raw""" associated_points(I::AbsIdealSheaf) @@ -1283,9 +1306,7 @@ function Base.show(io::IO, ::MIME"text/plain", I::SumIdealSheaf) io = pretty(io) print(io, "Sum of \n") print(io, Indent()) - for J in summands(I) - print(io, J, "\n") - end + join(io, summands(I), "\n") print(io, Dedent()) end @@ -1293,30 +1314,18 @@ function Base.show(io::IO, ::MIME"text/plain", I::ProductIdealSheaf) io = pretty(io) print(io, "Product of \n") print(io, Indent()) - for J in factors(I) - print(io, J, "\n") - end + join(io, factors(I), "\n") print(io, Dedent()) end function Base.show(io::IO, I::SumIdealSheaf) io = pretty(io) - print(io, "Sum of \n") - print(io, Indent()) - for J in summands(I) - print(io, J, "\n") - end - print(io, Dedent()) + print(io, "Sum of $(length(summands(I))) ideal sheaves") end function Base.show(io::IO, I::ProductIdealSheaf) io = pretty(io) - print(io, "Product of \n") - print(io, Indent()) - for J in factors(I) - print(io, J, "\n") - end - print(io, Dedent()) + print(io, "Product of $(length(factors(I))) ideal sheaves") end function Base.show(io::IO, I::PrimeIdealSheafFromChart) diff --git a/src/exports.jl b/src/exports.jl index 5ade5feb235c..fab42ad7a681 100644 --- a/src/exports.jl +++ b/src/exports.jl @@ -276,6 +276,8 @@ export as_dictionary export as_gset export ascending_compositions export associahedron +export associated_primes +export associated_points export atlas_description export atlas_group export atlas_irrationality @@ -756,6 +758,7 @@ export invert_birational_map export inverted_set export invlex export irreducible_components +export irreducible_decomposition export irreducible_secondary_invariants export irreducibles export irrelevant_ideal @@ -1033,6 +1036,7 @@ export matroid_hex export max_GC_rank_polytope export maxes export maximal_abelian_quotient, has_maximal_abelian_quotient, set_maximal_abelian_quotient +export maximal_associated_points export maximal_blocks export maximal_cells export maximal_cones diff --git a/src/forward_declarations.jl b/src/forward_declarations.jl index 6f73729c1f66..1d5d67bda85c 100644 --- a/src/forward_declarations.jl +++ b/src/forward_declarations.jl @@ -38,6 +38,37 @@ For an equidimensional ideal sheaf $\mathcal{I}$ its interpretation as a cycle i Let $V(\mathcal{I})=E_{1} \cup \dots E_{n}$ be the decomposition of the vanishing locus of $\mathcal{I}$ into irreducible components $E_i=V(\mathcal{P}_i)$ with $\mathcal{P}_i$ prime. Then $E$ corresponds to the cycle $D = \sum_{i=1}^{n} \mathrm{colength}_{\mathcal{P}_i}(\mathcal{I})E_i$. + +# Examples +```jldoctest +julia> P2 = projective_space(QQ,2); (s0,s1,s2) = homogeneous_coordinates(P2); + +julia> I = ideal_sheaf(P2,ideal([s0,s1^2])) +Sheaf of ideals + on scheme over QQ covered with 3 patches + 1: [(s1//s0), (s2//s0)] affine 2-space + 2: [(s0//s1), (s2//s1)] affine 2-space + 3: [(s0//s2), (s1//s2)] affine 2-space +with restrictions + 1: Ideal (1, (s1//s0)^2) + 2: Ideal ((s0//s1), 1) + 3: Ideal ((s0//s2), (s1//s2)^2) + +julia> D = algebraic_cycle(I) +Effective algebraic cycle + on scheme over QQ covered with 3 patches +with coefficients in integer ring +given as the formal sum of + 1 * sheaf of ideals + +julia> irreducible_decomposition(D) +Effective algebraic cycle + on scheme over QQ covered with 3 patches +with coefficients in integer ring +given as the formal sum of + 2 * sheaf of prime ideals + +``` """ abstract type AbsAlgebraicCycle{ CoveredSchemeType<:AbsCoveredScheme, @@ -49,6 +80,41 @@ end AbsWeilDivisor{CoveredSchemeType, CoefficientRingType} <: AbsAlgebraicCycle{CoveredSchemeType, CoefficientRingType} A Weil divisor with coefficients of type `CoefficientRingType` on a (locally) Noetherian integral scheme ``X`` of type `CoveredSchemeType`. + +# Examples +```jldoctest +julia> P2 = projective_space(QQ,2); (s0,s1,s2) = homogeneous_coordinates(P2); + +julia> I = ideal((s0*s1)^2); + +julia> II = ideal_sheaf(P2, I); + +julia> D = weil_divisor(II) +Effective weil divisor + on scheme over QQ covered with 3 patches +with coefficients in integer ring +given as the formal sum of + 1 * sheaf of ideals + +julia> E = irreducible_decomposition(D) +Effective weil divisor + on scheme over QQ covered with 3 patches +with coefficients in integer ring +given as the formal sum of + 2 * prime ideal sheaf on scheme over QQ covered with 3 patches extended from ideal ((s1//s0)) on affine 2-space + 2 * prime ideal sheaf on scheme over QQ covered with 3 patches extended from ideal ((s0//s1)) on affine 2-space + +julia> P = components(E)[1] +Prime ideal sheaf on Scheme over QQ covered with 3 patches extended from Ideal ((s1//s0)) on Affine 2-space + +julia> components(D)[1] == II +true + +julia> D[II] # to get the coefficient +1 + +julia> P[I] +``` """ abstract type AbsWeilDivisor{CoveredSchemeType, CoefficientRingType} <: AbsAlgebraicCycle{CoveredSchemeType, CoefficientRingType} end diff --git a/test/AlgebraicGeometry/Schemes/WeilDivisor.jl b/test/AlgebraicGeometry/Schemes/WeilDivisor.jl index d32325e33136..4f92c3835723 100644 --- a/test/AlgebraicGeometry/Schemes/WeilDivisor.jl +++ b/test/AlgebraicGeometry/Schemes/WeilDivisor.jl @@ -123,11 +123,10 @@ end KK = function_field(X) R = ambient_coordinate_ring(representative_patch(KK)) x = gens(R) - @test in_linear_system(KK(x[1]), D) - @test !in_linear_system(KK(x[1]^2), D) - @test in_linear_system(KK(x[1]^2), 2*D) - # Not running at the moment; work in progress - #@test !in_linear_system(KK(x[1], x[2]), D) + @test is_in_linear_system(KK(x[1]), D) + @test !is_in_linear_system(KK(x[1]^2), D) + @test is_in_linear_system(KK(x[1]^2), 2*D) + @test !is_in_linear_system(KK(x[1], x[2]), D) L = LinearSystem(KK.([1, x[1], x[2], x[1]^2, x[1]*x[2], x[2]^2]), 2*D) H = S[1]+S[2]+S[3] @@ -160,7 +159,7 @@ end U = X[1][2] u, v = gens(OO(U)) f = KK(u, v) - @test !in_linear_system(f, D) + @test !is_in_linear_system(f, D) end @testset "intersections of weil divisors on surfaces" begin