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

Tests for AffineSchemes #1582

Merged
merged 6 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 36 additions & 31 deletions experimental/Schemes/AffineSchemes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ struct EmptyScheme{BaseRingType}<:Scheme{BaseRingType}
end
end

is_empty(X::EmptyScheme) = true

########################################################################
#
# Interface for affine schemes
Expand Down Expand Up @@ -140,8 +142,8 @@ this returns the open subscheme ``U = Spec(R[f⁻¹]) = X ∖ V(f)``
defined by the complement of the vanishing
locus of ``f``.
"""
function hypersurface_complement(X::AbsSpec, f::RingElem)::AbsSpec
return hypersurface_complement(underlying_scheme(X), f)
function hypersurface_complement(X::AbsSpec, f::RingElem)
return hypersurface_complement(underlying_scheme(X), f)::AbsSpec
end

function hypersurface_complement(X::SpecType, f::RingElem) where {SpecType<:AbsSpec{<:Any, <:MPolyQuoLocalizedRing}}
Expand Down Expand Up @@ -353,7 +355,7 @@ function issubset(
end

function issubset(
X::AbsSpec{BRT, <:MPolyRing},
X::AbsSpec{BRT, <:MPolyRing},
Y::AbsSpec{BRT, <:MPolyLocalizedRing}
) where {BRT}
R = OO(X)
Expand All @@ -362,7 +364,7 @@ function issubset(
end

function issubset(
X::AbsSpec{BRT, <:MPolyRing},
X::AbsSpec{BRT, <:MPolyRing},
Y::AbsSpec{BRT, <:MPolyQuoLocalizedRing}
) where {BRT}
R = OO(X)
Expand All @@ -375,7 +377,7 @@ end
########################################################################

function issubset(
X::AbsSpec{BRT, <:MPolyQuo},
X::AbsSpec{BRT, <:MPolyQuo},
Y::AbsSpec{BRT, <:MPolyRing}
) where {BRT}
R = ambient_ring(Y)
Expand All @@ -384,7 +386,7 @@ function issubset(
end

function issubset(
X::AbsSpec{BRT, RT},
X::AbsSpec{BRT, RT},
Y::AbsSpec{BRT, RT}
) where {BRT, RT<:MPolyQuo}
R = base_ring(OO(X))
Expand All @@ -393,7 +395,7 @@ function issubset(
end

function issubset(
X::AbsSpec{BRT, <:MPolyQuo},
X::AbsSpec{BRT, <:MPolyQuo},
Y::AbsSpec{BRT, <:MPolyLocalizedRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}
) where {BRT}
R = base_ring(OO(X))
Expand All @@ -403,7 +405,7 @@ function issubset(
end

function issubset(
X::AbsSpec{BRT, <:MPolyQuo},
X::AbsSpec{BRT, <:MPolyQuo},
Y::AbsSpec{BRT, <:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}
) where {BRT}
R = base_ring(OO(X))
Expand All @@ -418,7 +420,7 @@ end

function issubset(
X::AbsSpec{BRT, <:MPolyLocalizedRing},
Y::AbsSpec{BRT, <:MPolyRing}
Y::AbsSpec{BRT, <:MPolyRing}
) where {BRT}
R = OO(Y)
R == base_ring(OO(X)) || error("schemes can not be compared")
Expand All @@ -427,15 +429,15 @@ end

function issubset(
X::AbsSpec{BRT, <:MPolyLocalizedRing},
Y::AbsSpec{BRT, <:MPolyQuo}
Y::AbsSpec{BRT, <:MPolyQuo}
) where {BRT}
R = ambient_ring(Y)
R == base_ring(OO(X)) || error("schemes can not be compared")
return all(x->(iszero(OO(X)(x))), gens(modulus(OO(Y))))
end

function issubset(
X::AbsSpec{BRT, RT},
X::AbsSpec{BRT, RT},
Y::AbsSpec{BRT, RT}
) where {BRT, RT<:MPolyLocalizedRing}
R = base_ring(OO(X))
Expand All @@ -446,7 +448,7 @@ function issubset(
end

function issubset(
X::AbsSpec{BRT, <:MPolyLocalizedRing},
X::AbsSpec{BRT, <:MPolyLocalizedRing},
Y::AbsSpec{BRT, <:MPolyQuoLocalizedRing}
) where {BRT}
R = base_ring(OO(X))
Expand All @@ -461,15 +463,15 @@ end
########################################################################
function issubset(
X::AbsSpec{BRT, <:MPolyQuoLocalizedRing},
Y::AbsSpec{BRT, <:MPolyRing}
Y::AbsSpec{BRT, <:MPolyRing}
) where {BRT}
R = OO(Y)
R == base_ring(OO(X)) || error("schemes can not be compared")
return true
end

function issubset(
X::AbsSpec{BRT, <:MPolyQuoLocalizedRing},
X::AbsSpec{BRT, <:MPolyQuoLocalizedRing},
Y::AbsSpec{BRT, <:MPolyQuo}
) where {BRT}
R = base_ring(OO(Y))
Expand All @@ -479,31 +481,31 @@ function issubset(
end

function issubset(
X::AbsSpec{BRT, <:MPolyQuoLocalizedRing},
X::AbsSpec{BRT, <:MPolyQuoLocalizedRing},
Y::AbsSpec{BRT, <:MPolyLocalizedRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}
) where {BRT}
R = base_ring(OO(X))
R == base_ring(OO(Y)) || error("schemes can not be compared")
UX = inverted_set(OO(X))
UY = inverted_set(OO(Y))
if !issubset(UY, UX)
if !issubset(UY, UX)
# check whether the inverted elements in Y are units anyway
for a in denominators(UY)
is_unit(OO(X)(a)) || return false
end
end
return iszero(OO(Y)(modulus(OO(X))))
return true
simonbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
simonbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
end

function issubset(
X::AbsSpec{BRT, RT},
X::AbsSpec{BRT, RT},
Y::AbsSpec{BRT, RT}
) where {BRT, RT<:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any, <:MPolyPowersOfElement}}
R = base_ring(OO(X))
R == base_ring(OO(Y)) || error("schemes can not be compared")
UX = inverted_set(OO(X))
UY = inverted_set(OO(Y))
if !issubset(UY, UX)
if !issubset(UY, UX)
# check whether the inverted elements in Y are units anyway
for a in denominators(UY)
is_unit(OO(X)(a)) || return false
Expand Down Expand Up @@ -542,24 +544,24 @@ function is_open_embedding(X::AbsSpec, Y::AbsSpec)
end

function is_open_embedding(
X::Spec{BRT, RT},
X::Spec{BRT, RT},
Y::Spec{BRT, RT}
) where {BRT, RT<:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any,
) where {BRT, RT<:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any,
<:MPolyPowersOfElement}}
R = base_ring(OO(X))
R == base_ring(OO(Y)) || return false
UX = inverted_set(OO(X))
UY = inverted_set(OO(Y))
issubset(UY, UX) || return false
J = localized_ring(OO(X))(modulus(OO(Y)))
return localized_modulus(OO(X)) == J
return localized_modulus(OO(X)) == J
end

function is_open_embedding(
X::Spec{BRT, <:MPolyQuoLocalizedRing},
X::Spec{BRT, <:MPolyQuoLocalizedRing},
Y::Spec{BRT, <:MPolyRing}
) where {BRT}
return OO(Y) == base_ring(OO(X)) && all(x->iszero(x), gens(modulus(OO(X))))
return OO(Y) == base_ring(OO(X)) && all(iszero, gens(modulus(OO(X))))
end

#TODO: Add more cross-type methods as needed.
Expand All @@ -574,9 +576,9 @@ function is_closed_embedding(X::AbsSpec, Y::AbsSpec)
end

function is_closed_embedding(
X::Spec{BRT, RT},
X::Spec{BRT, RT},
Y::Spec{BRT, RT}
) where {BRT, RT<:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any,
) where {BRT, RT<:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any,
<:MPolyPowersOfElement}}
R = base_ring(OO(X))
R == base_ring(OO(Y)) || return false
Expand All @@ -586,16 +588,16 @@ function is_closed_embedding(
end

function is_closed_embedding(
X::Spec{BRT, <:MPolyQuo},
X::Spec{BRT, <:MPolyQuo},
Y::Spec{BRT, <:MPolyRing}
) where {BRT}
return OO(Y) == base_ring(OO(X))
return OO(Y) == base_ring(OO(X))
end

function is_closed_embedding(
X::Spec{BRT, <:MPolyQuo},
X::Spec{BRT, <:MPolyQuo},
Y::Spec{BRT, <:RT}
) where {BRT, RT<:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any,
) where {BRT, RT<:MPolyQuoLocalizedRing{<:Any, <:Any, <:Any, <:Any,
<:MPolyPowersOfElement}}
R = base_ring(OO(X))
R == base_ring(OO(Y)) || error("schemes can not be compared")
Expand All @@ -612,6 +614,9 @@ Base.intersect(X::Scheme{BRT}, E::EmptyScheme{BRT}) where {BRT} = E
Base.intersect(X::EmptyScheme{BRT}, E::EmptyScheme{BRT}) where {BRT} = E

### For Specs of MPolyRings
# TODO intersect X,Y for X<Y should return a copy of X with === ambient_rings
# Spec(X) does not apply for instance to principal open subsets hence a change
# is necessary
function Base.intersect(
X::AbsSpec{BRT, <:MPolyRing},
Y::AbsSpec{BRT, <:MPolyRing}
Expand Down Expand Up @@ -905,7 +910,7 @@ identity_map(X::AbsSpec{<:Any, <:MPolyLocalizedRing}) = SpecMor(X, X, hom(OO(X),
identity_map(X::AbsSpec{<:Any, <:MPolyRing}) = SpecMor(X, X, hom(OO(X), OO(X), gens(OO(X))))
identity_map(X::AbsSpec{<:Any, <:MPolyQuo}) = SpecMor(X, X, hom(OO(X), OO(X), gens(ambient_ring(X))))
inclusion_map(X::AbsSpec, Y::AbsSpec) = SpecMor(X, Y, gens(base_ring(OO(Y)))) # TODO: Remove
inclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true) = SpecMor(X, Y, gens(base_ring(OO(Y))), check=check)
inclusion_morphism(X::AbsSpec, Y::AbsSpec; check::Bool=true) = SpecMor(X, Y, gens(ambient_ring(Y)), check=check)

function restrict(f::SpecMor, U::AbsSpec, V::AbsSpec; check::Bool=true)
if check
Expand Down
96 changes: 96 additions & 0 deletions test/Schemes/AffineSchemes.jl
Original file line number Diff line number Diff line change
@@ -1,20 +1,55 @@
@testset "affine schemes" begin
R, (x,y,z) = QQ["x", "y", "z"]
A3 = Spec(R)
deepcopy(A3)
set_name!(A3, "𝔸³")
@test iszero(defining_ideal(A3))
f = x*y-z^2
I = ideal(R, f)
J = ideal(R, [f, x])
A3empty = subscheme(A3,ideal(R,R(1)))
absempty = EmptyScheme(QQ)
@test is_canonically_isomorphic(A3empty, absempty)
@test is_canonically_isomorphic(absempty, A3empty)
X = subscheme(A3, I)
@test_broken !is_non_zero_divisor(f,X)
@test is_non_zero_divisor(f,A3)
Xsub = subscheme(A3,J)
@test !is_open_embedding(X,A3)
@test issubset(Xsub,X)
@test !issubset(X, Xsub)
set_name!(X, "X")
@test iszero(OO(X)(f))
U = hypersurface_complement(A3, x)
UX = hypersurface_complement(X,x)
@test is_non_zero_divisor(f,U)
@test !is_non_zero_divisor(f,UX)
@test !is_open_embedding(UX,U)
@test_broken is_closed_embedding(UX,U)
@test !is_open_embedding(UX,A3)
@test issubset(UX,U)
@test issubset(UX,X)
@test issubset(U,A3)
@test !issubset(A3,U)
line = subscheme(A3, x)
line_complement = hypersurface_complement(A3,x)
@test !issubset(line,line_complement)
@test !issubset(line_complement,line)
@test !issubset(line, X)
@test issubset(Xsub, line)
U1 = hypersurface_complement(A3, [x])
@test ambient_ring(U) === R
set_name!(U, "U")
UX = intersect(X, U)
set_name!(UX, "U ∩ X")
@test issubset(UX, X)
@test issubset(UX, U)
@test name(UX) == "U ∩ X"
@test is_canonically_isomorphic(X, closure(UX, A3))
@test is_open_embedding(UX, X)
@test is_closed_embedding(X, A3)
UZ = subscheme(UX, y^2)
subscheme(UX, [y^2])
Z = subscheme(X, y^2)
@test is_canonically_isomorphic(closure(UZ, X), Z)

Expand All @@ -34,6 +69,20 @@
mirr = SpecMor(Xstd, Xstd, [y, x, z])
@test is_isomorphism(mirr)
@test pullback(compose(inverse(mirr), mirr))(OO(Xstd)(x^2-34*z)) == OO(Xstd)(x^2-34*z+ f^2)
@test is_empty(EmptyScheme(QQ))
@test issubset(EmptyScheme(QQ),A3)
@test issubset(EmptyScheme(QQ),U)
@test !issubset(U,EmptyScheme(QQ))
@test issubset(X,A3)
@test !issubset(A3, X)
@test issubset(A3,A3)
@test issubset(intersect(A3,A3), A3)
@test dim(A3) == 3
@test dim(U) == 3
@test dim(X) == 2
@test codim(A3) == 0
@test_broken codim(V) == 0
@test codim(X) == 1
end

@testset "smoothness tests" begin
Expand All @@ -44,3 +93,50 @@ end
X = Spec(Q)
@test is_smooth(X)
end

@testset "AbsSpec interface" begin
R, (x,y,z) = QQ["x", "y", "z"]
A3 = Spec(R)
set_name!(A3, "𝔸³")
f = x*y-z^2
I = ideal(R, f)
S = powers_of_element(x)
Spec(R,S)
S = complement_of_ideal(I)
Spec(R,I)
X = subscheme(A3, I)
set_name!(X, "X")
@test iszero(OO(X)(f))
U = hypersurface_complement(A3, x)
@test issubset(intersect(A3,U),intersect(U,A3))
V = PrincipalOpenSubset(U)
simonbrandhorst marked this conversation as resolved.
Show resolved Hide resolved
@test dim(V) == 3
@test issubset(U,V)
@test issubset(V,V)

@test_broken issubset(intersect(A3,V),intersect(V,A3))
@test issubset(intersect(U,A3),V)
@test_broken issubset(intersect(A3,V),A3)
@test ambient_ring(V)===R
@test ambient_ring(U) === R
@test ring_type(V) == typeof(OO(V))
@test base_ring_type(typeof(V)) == typeof(QQ)
@test base_ring_elem_type(V) == fmpq
@test base_ring(V) == QQ
@test issubset(V,U)
@test issubset(U,V)
@test issubset(V,A3)
@test !issubset(A3, V)
h = gens(OO(V))[1]
hypersurface_complement(V, h)
hypersurface_complement(V, [h])
inclusion_morphism(X,A3)
inclusion_morphism(V,A3)
inclusion_morphism(U,A3)
inclusion_morphism(A3,A3)
end

@testset "Spec ZZ" begin
Spec(ZZ)
Spec(QQ)
end