Covered schemes
Oscar supports modeling abstract schemes by means of a covering by affine charts.
Types
The abstract type for these is:
AbsCoveredScheme
— TypeAbsCoveredScheme{BaseRingType}
A scheme $X$ over some base_ring
$𝕜$ of type BaseRingType
, given by means of affine charts and their gluings.
The basic concrete instance of an AbsCoveredScheme
is:
CoveredScheme
— TypeCoveredScheme{BaseRingType}
A covered scheme $X$ given by means of at least one Covering
.
A scheme may possess several coverings which are partially ordered by refinement. Use default_covering(X)
to obtain one covering of $X$.
Constructors
You can manually construct a CoveredScheme
from a Covering
using
CoveredScheme
— MethodCoveredScheme(C::Covering)
Return a CoveredScheme
$X$ with C
as its default_covering
.
Examples
julia> P1, (x,y) = QQ[:x, :y];
julia> P2, (u,v) = QQ[:u, :v];
julia> U1 = spec(P1);
julia> U2 = spec(P2);
julia> C = Covering([U1, U2]) # A Covering with two disjoint affine charts
Covering
described by patches
1: affine 2-space
2: affine 2-space
in the coordinate(s)
1: [x, y]
2: [u, v]
julia> V1 = PrincipalOpenSubset(U1, x); # Preparations for gluing
julia> V2 = PrincipalOpenSubset(U2, u);
julia> f = morphism(V1, V2, [1//x, y//x]); # The gluing isomorphism
julia> g = morphism(V2, V1, [1//u, v//u]); # and its inverse
julia> G = Gluing(U1, U2, f, g); # Construct the gluing
julia> add_gluing!(C, G) # Make the gluing part of the Covering
Covering
described by patches
1: affine 2-space
2: affine 2-space
in the coordinate(s)
1: [x, y]
2: [u, v]
julia> X = CoveredScheme(C) # Create a CoveredScheme from the Gluing
Scheme
over rational field
with default covering
described by patches
1: affine 2-space
2: affine 2-space
in the coordinate(s)
1: [x, y]
2: [u, v]
In most cases, however, you may wish for the computer to provide you with a ready-made Covering
and use a more high-level constructor, such as, for instance,
covered_scheme
— Methodcovered_scheme(P::AbsProjectiveScheme)
Return a CoveredScheme
$X$ isomorphic to P
with standard affine charts given by dehomogenization.
Use dehomogenization_map
with U
one of the affine_charts
of $X$ to obtain the dehomogenization map from the homogeneous_coordinate_ring
of P
to the coordinate_ring
of U
.
Examples
julia> P = projective_space(QQ, 2);
julia> Pcov = covered_scheme(P)
Scheme
over rational field
with default covering
described by patches
1: affine 2-space
2: affine 2-space
3: affine 2-space
in the coordinate(s)
1: [(s1//s0), (s2//s0)]
2: [(s0//s1), (s2//s1)]
3: [(s0//s2), (s1//s2)]
Other constructors:
disjoint_union
— Methoddisjoint_union(Xs::Vector{<:AbsCoveredScheme}) -> (AbsCoveredScheme, Vector{<:AbsCoveredSchemeMor})
Return the disjoint union of the non-empty vector of covered schemes as a covered scheme.
Input:
- a vector
Xs
of covered schemes.
Output:
A pair $(X, \mathrm{injections})$ where $X$ is a covered scheme and $\mathrm{injections}$ is a vector of inclusion morphisms $ı_i\colon X_i \to X$, where $X$ is the disjoint union of the covered schemes $X_i$ in Xs
.
Examples
julia> R_1, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
julia> I_1 = ideal(R_1, z*x^2 + y^3);
julia> X_1 = covered_scheme(proj(R_1, I_1))
Scheme
over rational field
with default covering
described by patches
1: scheme((y//x)^3 + (z//x))
2: scheme((x//y)^2*(z//y) + 1)
3: scheme((x//z)^2 + (y//z)^3)
in the coordinate(s)
1: [(y//x), (z//x)]
2: [(x//y), (z//y)]
3: [(x//z), (y//z)]
julia> R_2, (u, v) = polynomial_ring(rational_field(), [:u, :v]);
julia> I_2 = ideal(R_2, u + v^2);
julia> X_2 = covered_scheme(spec(R_2, I_2))
Scheme
over rational field
with default covering
described by patches
1: scheme(u + v^2)
in the coordinate(s)
1: [u, v]
julia> X, injections = disjoint_union([X_1, X_2]);
julia> X
Scheme
over rational field
with default covering
described by patches
1: scheme((y//x)^3 + (z//x))
2: scheme((x//y)^2*(z//y) + 1)
3: scheme((x//z)^2 + (y//z)^3)
4: scheme(u + v^2)
in the coordinate(s)
1: [(y//x), (z//x)]
2: [(x//y), (z//y)]
3: [(x//z), (y//z)]
4: [u, v]
julia> injections
2-element Vector{CoveredSchemeMorphism{CoveredScheme{QQField}, CoveredScheme{QQField}, AbsAffineSchemeMor}}:
Hom: scheme over QQ covered with 3 patches -> scheme over QQ covered with 4 patches
Hom: scheme over QQ covered with 1 patch -> scheme over QQ covered with 4 patches
Attributes
To access the affine charts of a CoveredScheme
$X$ use
affine_charts
— Methodaffine_charts(X::AbsCoveredScheme)
Return the affine charts in the default_covering
of $X$.
Examples
julia> P = projective_space(QQ, 2);
julia> S = homogeneous_coordinate_ring(P);
julia> I = ideal(S, [S[1]*S[2]-S[3]^2]);
julia> X = subscheme(P, I)
Projective scheme
over rational field
defined by ideal (s0*s1 - s2^2)
julia> Xcov = covered_scheme(X)
Scheme
over rational field
with default covering
described by patches
1: scheme((s1//s0) - (s2//s0)^2)
2: scheme((s0//s1) - (s2//s1)^2)
3: scheme((s0//s2)*(s1//s2) - 1)
in the coordinate(s)
1: [(s1//s0), (s2//s0)]
2: [(s0//s1), (s2//s1)]
3: [(s0//s2), (s1//s2)]
julia> affine_charts(Xcov)
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)
Other attributes are the base_ring
over which the scheme is defined and
default_covering
— Methoddefault_covering(X::AbsCoveredScheme)
Return the default covering for $X$.
Examples
julia> P = projective_space(QQ, 2);
julia> S = homogeneous_coordinate_ring(P);
julia> I = ideal(S, [S[1]*S[2]-S[3]^2]);
julia> X = subscheme(P, I)
Projective scheme
over rational field
defined by ideal (s0*s1 - s2^2)
julia> Xcov = covered_scheme(X)
Scheme
over rational field
with default covering
described by patches
1: scheme((s1//s0) - (s2//s0)^2)
2: scheme((s0//s1) - (s2//s1)^2)
3: scheme((s0//s2)*(s1//s2) - 1)
in the coordinate(s)
1: [(s1//s0), (s2//s0)]
2: [(s0//s1), (s2//s1)]
3: [(s0//s2), (s1//s2)]
julia> default_covering(Xcov)
Covering
described by patches
1: scheme((s1//s0) - (s2//s0)^2)
2: scheme((s0//s1) - (s2//s1)^2)
3: scheme((s0//s2)*(s1//s2) - 1)
in the coordinate(s)
1: [(s1//s0), (s2//s0)]
2: [(s0//s1), (s2//s1)]
3: [(s0//s2), (s1//s2)]
Properties
An AbsCoveredScheme
may have different properties such as
is_empty(X::AbsCoveredScheme)
is_smooth(X::AbsCoveredScheme)
Methods
fiber_product
— Methodfiber_product(f::AbsCoveredSchemeMorphism, g::AbsCoveredSchemeMorphism)
For a diagram XxY ––> Y | | g V V X–––> Z f this computes the fiber product XxY
together with the canonical maps to X
and Y
and returns the resulting triple.
is_normal
— Methodis_normal(X::AbsCoveredScheme; check::Bool=true) -> Bool
Input:
- a reduced scheme $X$,
- if
check
istrue
, then confirm that $X$ is reduced; this is expensive.
Output:
Returns whether the scheme $X$ is normal.
Examples
julia> R, (x, y, z) = QQ[:x, :y, :z];
julia> X = covered_scheme(spec(R));
julia> is_normal(X)
true
normalization
— Methodnormalization(X::AbsCoveredScheme; check::Bool=true) -> (AbsCoveredScheme, AbsCoveredSchemeMor, Vector{<:AbsCoveredSchemeMor})
Return the normalization of the reduced scheme $X$.
Input:
- a reduced scheme $X$,
- if
check
istrue
, then confirm that $X$ is reduced; this is expensive.
Output:
A triple $(Y, \nu\colon Y \to X, \mathrm{injs})$ where $Y$ is a normal scheme, $\nu$ is the normalization, and $\mathrm{injs}$ is a vector of inclusion morphisms $ı_i\colon Y_i \to Y$, where $Y_i$ are the connected components of the scheme $Y$. See Tag 0CDV in [Stacks] or Definition 7.5.1 in [Liu06] for normalization of non-integral schemes.
Examples
julia> R, (x, y, z) = graded_polynomial_ring(QQ, [:x, :y, :z]);
julia> I = ideal(R, z*x^2 + y^3);
julia> X = covered_scheme(proj(R, I))
Scheme
over rational field
with default covering
described by patches
1: scheme((y//x)^3 + (z//x))
2: scheme((x//y)^2*(z//y) + 1)
3: scheme((x//z)^2 + (y//z)^3)
in the coordinate(s)
1: [(y//x), (z//x)]
2: [(x//y), (z//y)]
3: [(x//z), (y//z)]
julia> Y, pr_mor = normalization(X);
julia> Y
Scheme
over rational field
with default covering
described by patches
1: scheme((y//x)^3 + (z//x))
2: scheme((x//y)^2*(z//y) + 1)
3: scheme(-T(1)*y + x, T(1)*x + y^2, T(1)^2 + y, x^2 + y^3)
in the coordinate(s)
1: [(y//x), (z//x)]
2: [(x//y), (z//y)]
3: [T(1), x, y]
julia> pr_mor
Covered scheme morphism
from scheme over QQ covered with 3 patches
1a: [(y//x), (z//x)] scheme((y//x)^3 + (z//x))
2a: [(x//y), (z//y)] scheme((x//y)^2*(z//y) + 1)
3a: [T(1), x, y] scheme(-T(1)*y + x, T(1)*x + y^2, T(1)^2 + y, x^2 + y^3)
to scheme over QQ covered with 3 patches
1b: [(y//x), (z//x)] scheme((y//x)^3 + (z//x))
2b: [(x//y), (z//y)] scheme((x//y)^2*(z//y) + 1)
3b: [(x//z), (y//z)] scheme((x//z)^2 + (y//z)^3)
given by the pullback functions
1a -> 1b
(y//x) -> (y//x)
(z//x) -> (z//x)
----------------------------------------
2a -> 2b
(x//y) -> (x//y)
(z//y) -> (z//y)
----------------------------------------
3a -> 3b
(x//z) -> x
(y//z) -> y
julia> inclusion_morphisms(pr_mor)
1-element Vector{CoveredSchemeMorphism{CoveredScheme{QQField}, CoveredScheme{QQField}, AbsAffineSchemeMor}}:
Hom: scheme over QQ covered with 3 patches -> scheme over QQ covered with 3 patches
The modeling of covered schemes and their expected behavior
Any AbsCoveredScheme
may possess several Covering
s. This is necessary for several reasons; for instance, a morphism $f : X \to Y$ between AbsCoveredScheme
s will in general only be given on affine patches on a refinement of the default_covering
of X
. The list of available Covering
s can be obtained using
coverings
— Methodcoverings(X::AbsCoveredScheme)
Return the list of internally stored Covering
s of $X$.
Examples
julia> P = projective_space(QQ, 2);
julia> Pcov = covered_scheme(P)
Scheme
over rational field
with default covering
described by patches
1: affine 2-space
2: affine 2-space
3: affine 2-space
in the coordinate(s)
1: [(s1//s0), (s2//s0)]
2: [(s0//s1), (s2//s1)]
3: [(s0//s2), (s1//s2)]
julia> coverings(Pcov)
1-element Vector{Covering{QQField}}:
Covering with 3 patches
Every AbsCoveredScheme
$X$ has to be modeled using one original default_covering
$C$, simply to gather the data necessary to fully describe $X$. The affine_charts
of $X$ return the patches of this covering. For any refinement $D < C$, we require the following to hold: 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 theaffine_charts
of $C$; - a
SimplifiedAffineScheme
with some original in theaffine_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 and reused in different coverings and the latter should be merely seen as lists pointing to the objects involved.