# Morphisms of covered schemes

Suppose $f : X \to Y$ is a morphism of `AbsCoveredScheme`

s. Theoretically, and hence also technically, the required information behind $f$ is a list of morphisms of affine schemes $f_i : U_i \to V_{F(i)}$ for some pair of `Covering`

s $\left\{U_i\right\}_{i \in I}$ of $X$ and $\left\{V_j\right\}_{j \in J}$ of $Y$ and a map of indices $F : I \to J$ This information is held by a `CoveringMorphism`

:

`CoveringMorphism`

— Type`CoveringMorphism`

A morphism $f : C → D$ of two coverings. For every patch $U$ of $C$ this 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₂]`

do not need to coincide! However, given the gluings in `C`

and `D`

, all affine maps have to coincide on their overlaps.

The basic functionality of `CoveringMorphism`

s comprises `domain`

and `codomain`

which both return a `Covering`

, together with

`getindex(f::CoveringMorphism, U::AbsAffineScheme)`

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$. In fact, one will usually need to restrict to a refinement of the `default_covering`

of $X$ in order to realize the covering morphism in the first place.

## The interface for morphisms of covered schemes

Every `AbsCoveredSchemeMorphism`

$f : X \to Y$ is required to implement the following minimal interface.

```
domain(f::AbsCoveredSchemeMorphism) # returns X
codomain(f::AbsCoveredSchemeMorphism) # returns Y
covering_morphism(f::AbsCoveredSchemeMorphism) # returns the underlying covering morphism {f_i}
```

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::AbsAffineScheme)`

as `getindex(f::AbsCoveredSchemeMorphism, U::AbsAffineScheme)`

.

The minimal concrete type of an `AbsCoveredSchemeMorphism`

which implements this interface, is `CoveredSchemeMorphism`

.

## Special types of morphisms of covered schemes

### Morphisms from rational functions

Suppose $X$ and $Y$ are two irreducible and reduced varieties. Then a morphism $f : X \to Y$ might be given by means of the following data. Let $V \subset Y$ be some dense affine patch with `coordinates`

$x_1,\dots,x_n$ (i.e. the `gens`

of `OO(V)`

).

These $x_i$ extend to rational functions $v_i$ on $Y$ and these pull back to rational functions $f^* v_i = u_i$ on $X$. On every affine patch $U \subset X$ there now exists some maximal Zariski-open subset $W \subset U$ (which need not be affine), such that all the $f^* v_i$ extend to regular functions on $W$. Hence, one can realize the morphisms of affine schemes $f_j : W_j \to V$ for some open covering of $W$.

Similarly, for every other non-empty patch $V_2$ of $Y$ the pullback of `gens(OO(V_2))`

can be computed from the $f^* v_i$ and extended maximally to some $W \subset U$ for every patch $U$ of $X$. Altogether, this allows to compute a full `CoveringMorphism`

and – at least in theory – an instance of `CoveredSchemeMorphism`

. In practice, however, this computation is usually much too expensive to really be carried out, while the data necessary to compute various pullbacks and/or pushforwards of objects defined on $X$ and $Y$ can be extracted from the $f^* v_i$ more directly.

A lazy concrete data structure to house this kind of morphism is

`MorphismFromRationalFunctions`

— Type`MorphismFromRationalFunctions{DomainType<:AbsCoveredScheme, CodomainType<:AbsCoveredScheme}`

A lazy type for a dominant morphism $φ : X → Y$ of `AbsCoveredScheme`

s which is given by a set of rational functions $a₁,…,aₙ$ in the fraction field of the `base_ring`

of $𝒪(U)$ for one of the dense open `affine_chart`

s $U$ of $X$. The $aᵢ$ represent the pullbacks of the coordinates (`gens`

) of some `affine_chart`

$V$ of the codomain $Y$ under this map.

```
julia> IP1 = covered_scheme(projective_space(QQ, [:s, :t]))
Scheme
over rational field
with default covering
described by patches
1: affine 1-space
2: affine 1-space
in the coordinate(s)
1: [(t//s)]
2: [(s//t)]
julia> IP2 = projective_space(QQ, [:x, :y, :z]);
julia> S = homogeneous_coordinate_ring(IP2);
julia> x, y, z = gens(S);
julia> IPC, inc_IPC = sub(IP2, ideal(S, [x^2 - y*z]));
julia> C = covered_scheme(IPC);
julia> U = first(affine_charts(IP1))
Spectrum
of multivariate polynomial ring in 1 variable (t//s)
over rational field
julia> V = first(affine_charts(C))
Spectrum
of quotient
of multivariate polynomial ring in 2 variables (y//x), (z//x)
over rational field
by ideal (-(y//x)*(z//x) + 1)
julia> t = first(gens(OO(U)))
(t//s)
julia> Phi = MorphismFromRationalFunctions(IP1, C, U, V, [t//one(t), 1//t]);
julia> realizations = Oscar.realize_on_patch(Phi, U);
julia> realizations[3]
Affine scheme morphism
from [(t//s)] AA^1
to [(x//z), (y//z)] scheme((x//z)^2 - (y//z))
given by the pullback function
(x//z) -> (t//s)
(y//z) -> (t//s)^2
```

This function is part of the experimental code in Oscar. Please read here for more details.

Note that the key idea of this data type is to *not* use the `underlying_morphism`

together with its `covering_morphism`

, but to find cheaper ways to do computations! The computation of the `underlying_morphism`

is triggered by any call to functions which have not been overwritten with a special method for `f::MorphismFromRationalFunctions`

. However, this computation should be considered as way too expensive besides some small examples.

For instance, if one wants to pull back a prime ideal sheaf $\mathcal I$ on $Y$ along some *isomorphism* $f : X \to Y$, then one only needs to find one realization $f_j : U_j \to V_{F(j)}$ of $f$ on affine patches $U_j$ of $X$ and $V_{F(j)}$ of $Y$ such that $\mathcal I(V_{F(j)})\neq 0$ and $f_j^* \mathcal I(V_{F(j)}) \neq 0$. Then $f^* \mathcal I$ can be extended uniquely to all of $X$ from $U_j$ and 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:

`realize_on_patch`

— Method`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`

.

`realize_on_open_subset`

— Method`realize_on_open_subset(Phi::MorphismFromRationalFunctions, U::AbsAffineScheme, V::AbsAffineScheme)`

Return 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!

`realization_preview`

— Method`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`

.

`random_realization`

— Method`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.

`cheap_realization`

— Method`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 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.

This method is cheap in the sense that it simply inverts all representatives of the denominators occurring in the `realization_preview(Phi, U, V)`

.

`realize_maximally_on_open_subset`

— Method`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.

`realize`

— Method`realize(Phi::MorphismFromRationalFunctions)`

Computes a full realization of `Phi`

as a `CoveredSchemeMorphism`

. Note that this computation is very expensive and usage of this method should be avoided.