Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

various fixes for schemes #2508

Merged
merged 9 commits into from
Jul 3, 2023
22 changes: 22 additions & 0 deletions experimental/Schemes/AlgebraicCycles.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,28 @@ end
# implementation of the arithmetic.
coefficient_dict(D::AbsAlgebraicCycle) = coefficient_dict(underlying_cycle(D))

function coeff(D::AbsAlgebraicCycle, I::IdealSheaf)
d = coefficient_dict(D)
if I in keys(d)
return d[I]
else
return zero(coefficient_ring(D))
end
end

function is_effective(A::AbsAlgebraicCycle)
return all(coeff(A, I)>=0 for A in components(A))
end

function Base.:<=(A::AbsAlgebraicCycle,B::AbsAlgebraicCycle)
for I in components(A)
coeff(A, I) <= coeff(B, I) || return false
end
for I in components(B)
coeff(A, I) <= coeff(B, I) || return false
end
return true
end
### forwarding of the essential functionality

function underlying_cycle(D::AbsAlgebraicCycle)
Expand Down
10 changes: 10 additions & 0 deletions experimental/Schemes/Auxiliary.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ function pullback(f::AbsCoveredSchemeMorphism, C::EffectiveCartierDivisor)
return EffectiveCartierDivisor(X, triv_dict, trivializing_covering=triv_cov, check=false)
end

function pullback(f::AbsCoveredSchemeMorphism, C::CartierDivisor)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had this only been done for effective cartier divisors?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think so.

R = coefficient_ring(C)
C = CartierDivisor(domain(f), R)
pb = pullback(f)
for (c,D) in coefficient_dict(C)
C += c*pb(C)
end
return C
end

function pullback(f::AbsCoveredSchemeMorphism, CC::Covering)
psi = restrict(f, CC)
return domain(psi)
Expand Down
2 changes: 1 addition & 1 deletion experimental/Schemes/CartierDivisor.jl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ end
R::Ring
coeff_dict::IdDict{EffectiveCartierDivisor, CoeffType}

function CartierDivisor(X::AbsCoveredScheme, R::Ring, coeff_dict::IdDict{EffectiveCartierDivisor, CoeffType}) where {CoeffType<:RingElem}
function CartierDivisor(X::AbsCoveredScheme, R::Ring, coeff_dict::IdDict{<:EffectiveCartierDivisor, CoeffType}) where {CoeffType<:RingElem}
all(x->(scheme(x)===X), keys(coeff_dict)) || error("all effective divisors must be defined over the same scheme")
all(x->(parent(x) === R), values(coeff_dict)) || error("all coefficients must belong to the same parent")
return new{typeof(X), CoeffType}(X, R, coeff_dict)
Expand Down
5 changes: 5 additions & 0 deletions experimental/Schemes/CoveredProjectiveSchemes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ mutable struct ProjectiveGlueing{
) where {GlueingType<:AbsGlueing, IncType1<:ProjectiveSchemeMor,IncType2<:ProjectiveSchemeMor, IsoType1<:ProjectiveSchemeMor, IsoType2<:ProjectiveSchemeMor}
(X, Y) = patches(G)
(U, V) = glueing_domains(G)
@vprint :Glueing 1 "computing projective glueing\n"
@vprint :Glueing 2 "$(X), coordinates $(ambient_coordinates(X))\n"
@vprint :Glueing 2 "and\n"
@vprint :Glueing 2 "$(Y) coordinates $(ambient_coordinates(X))\n"
(fb, gb) = glueing_morphisms(G)
(PX, QY) = (codomain(incP), codomain(incQ))
(PU, QV) = (domain(incP), domain(incQ))
Expand All @@ -158,6 +162,7 @@ mutable struct ProjectiveGlueing{
# idQV = compose(g, f)
# all(t->(pullback(idQV)(t) == t), gens(SQV)) || error("composition of maps is not the identity")
end
@vprint :Glueing 1 "done computing the projective gluing\n"
return new{GlueingType, IsoType1, IncType1, IsoType2, IncType2}(G, incP, incQ, f, g)
end
end
Expand Down
17 changes: 11 additions & 6 deletions experimental/Schemes/FunctionFields.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,24 +27,23 @@ representative_field(KK::VarietyFunctionField) = KK.KK

### user facing constructors
@doc raw"""
function_field(X::CoveredScheme)
function_field(X::AbsCoveredScheme)

Return the function field of the irreducible variety `X`.

Internally, a rational function is represented by an element in the field of
fractions of the `ambient_coordinate_ring` of the `representative_patch`.
"""
@attr VarietyFunctionField function_field(X::CoveredScheme) = VarietyFunctionField(X)

@attr VarietyFunctionField function_field(X::AbsCoveredScheme) = VarietyFunctionField(X)

@doc raw"""
FunctionField(X::CoveredScheme; kw...)
FunctionField(X::AbsCoveredScheme; kw...)

Return the function field of the irreducible variety `X`.

See [`function_field(X::CoveredScheme)`](@ref).
See [`function_field(X::AbsCoveredScheme)`](@ref).
"""
FunctionField(X::CoveredScheme; kw... ) = function_field(X; kw...)
FunctionField(X::AbsCoveredScheme; kw... ) = function_field(X; kw...)

########################################################################
# Methods for VarietyFunctionFieldElem #
Expand Down Expand Up @@ -142,6 +141,12 @@ isunit(a::VarietyFunctionFieldElem) = !iszero(representative(a))
# Conversion of rational functions on arbitrary patches #
########################################################################

function (KK::VarietyFunctionField)(a::RingElem; check::Bool=true)
return KK(a, one(parent(a)), check=check)
end



function (KK::VarietyFunctionField)(a::MPolyQuoRingElem, b::MPolyQuoRingElem; check::Bool=true)
return KK(lift(a), lift(b), check=check)
end
Expand Down
55 changes: 41 additions & 14 deletions experimental/Schemes/IdealSheaves.jl
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,30 @@ function isone(I::IdealSheaf)
return all(x->isone(I(x)), affine_charts(scheme(I)))
end

function is_prime(I::IdealSheaf)
!isone(I) || return false
return all(U->(is_one(I(U)) || is_prime(I(U))), basic_patches(default_covering(space(I))))
@doc raw"""
is_prime(I::IdealSheaf) -> Bool

Return whether ``I`` is prime.

We say that a sheaf of ideals is prime if its support is irreducible and
``I`` is locally prime. (Note that the empty set is not irreducible.)
"""
function is_prime(I::IdealSheaf)
is_locally_prime(I) || return false
PD = maximal_associated_points(I)
return length(PD)==1
end

@doc raw"""
is_locally_prime(I::IdealSheaf) -> Bool

Return whether ``I`` is locally prime.

A sheaf of ideals $\mathcal{I}$ is locally prime if its stalk $\mathcal{I}_p$
at every point $p$ is one or prime.
"""
function is_locally_prime(I::IdealSheaf)
return all(U->is_prime(I(U)) || is_one(I(U)), basic_patches(default_covering(space(I))))
end

function _minimal_power_such_that(I::Ideal, P::PropertyType) where {PropertyType}
Expand Down Expand Up @@ -483,6 +504,7 @@ function order_on_divisor(
check::Bool=true
)
@check is_prime(I) "ideal sheaf must be a sheaf of prime ideals"

X = space(I)::AbsCoveredScheme
X == variety(parent(f)) || error("schemes not compatible")

Expand Down Expand Up @@ -517,14 +539,14 @@ function order_on_divisor(
end
R = ambient_coordinate_ring(V)
J = saturated_ideal(I(V))
K = ambient_closure_ideal(V)
floc = f[V]
aR = ideal(R, numerator(floc))
bR = ideal(R, denominator(floc))


# The following uses ArXiv:2103.15101, Lemma 2.18 (4):
num_mult = _minimal_power_such_that(J, x->(issubset(quotient(x, aR), J)))[1]-1
den_mult = _minimal_power_such_that(J, x->(issubset(quotient(x, bR), J)))[1]-1
num_mult = _minimal_power_such_that(J, x->(issubset(quotient(x+K, aR), J)))[1]-1
den_mult = _minimal_power_such_that(J, x->(issubset(quotient(x+K, bR), J)))[1]-1
return num_mult - den_mult
# # Deprecated code computing symbolic powers explicitly:
# L, map = Localization(OO(U),
Expand Down Expand Up @@ -612,6 +634,7 @@ function maximal_associated_points(I::IdealSheaf)

# run through all charts and try to match the components
while length(charts_todo) > 0
@vprint :MaximalAssociatedPoints 2 "length(charts_todo) remaining charts to go through\n"
U = pop!(charts_todo)
!is_one(I(U)) || continue ## supp(I) might not meet all components
components_here = minimal_primes(I(U))
Expand Down Expand Up @@ -721,7 +744,7 @@ function match_on_intersections(
I::Union{<:MPolyIdeal, <:MPolyQuoIdeal, <:MPolyQuoLocalizedIdeal, <:MPolyLocalizedIdeal},
associated_list::Vector{IdDict{AbsSpec,Ideal}},
check::Bool=true)

@vprint :MaximalAssociatedPoints 2 "matching $(I) \n and $(J)\n on $(U)\n"
matches = Int[]
OOX = OO(X)

Expand All @@ -746,7 +769,7 @@ function match_on_intersections(
end

## make sure we are working on consistent data
@check begin
@check begin
if match_found && match_contradicted
error("contradictory matching result!!") ## this should not be reached for ass. points
end
Expand Down Expand Up @@ -828,12 +851,16 @@ end
## show functions for Ideal sheaves
###########################################################################
function Base.show(io::IO, I::IdealSheaf)
X = scheme(I)

# If there is a simplified covering, use it!
covering = (has_attribute(X, :simplified_covering) ? simplified_covering(X) : default_covering(X))
n = npatches(covering)
println(io,"Ideal Sheaf on Covered Scheme with ",n," Charts")
X = scheme(I)
if has_attribute(I,:name)
println(io, get_attribute(I, :name))
else

# If there is a simplified covering, use it!
covering = (has_attribute(X, :simplified_covering) ? simplified_covering(X) : default_covering(X))
n = npatches(covering)
println(io,"Ideal Sheaf on Covered Scheme with ",n," Charts")
end
end

function show_details(I::IdealSheaf)
Expand Down