|
| 1 | +/- |
| 2 | +Copyright (c) 2026 Justus Springer. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Justus Springer |
| 5 | +-/ |
| 6 | +module |
| 7 | + |
| 8 | +public import Mathlib.AlgebraicGeometry.Birational.Dominant |
| 9 | + |
| 10 | +/-! |
| 11 | +# Composition of rational maps |
| 12 | +
|
| 13 | +This file defines composition for partial maps and rational maps between schemes. |
| 14 | +
|
| 15 | +## Main definitions |
| 16 | +
|
| 17 | +- `Scheme.PartialMap.comp`: given a dominant partial map `f : X.PartialMap Y` and any partial map |
| 18 | + `g : Y.PartialMap Z`, their composition `f.comp g : X.PartialMap Z` is defined on the preimage |
| 19 | + of `g`'s domain under `f`. |
| 20 | +- `Scheme.RationalMap.comp`: composition of rational maps, defined via a dominant representative. |
| 21 | +
|
| 22 | +## Main statements |
| 23 | +
|
| 24 | +- `Scheme.PartialMap.comp_equiv_of_equiv`: Composition respects equivalence of partial maps. |
| 25 | +- `Scheme.PartialMap.comp_assoc`: Composition of partial maps is associative. |
| 26 | +- `Scheme.RationalMap.comp_assoc`: Composition of rational maps is associative. |
| 27 | +
|
| 28 | +-/ |
| 29 | + |
| 30 | +@[expose] public section |
| 31 | + |
| 32 | +universe u |
| 33 | + |
| 34 | +open CategoryTheory |
| 35 | + |
| 36 | +namespace AlgebraicGeometry.Scheme |
| 37 | + |
| 38 | +variable {X Y Z : Scheme.{u}} |
| 39 | + |
| 40 | +section PreirreducibleSpace |
| 41 | + |
| 42 | +variable [PreirreducibleSpace X] [Nonempty Y] |
| 43 | + |
| 44 | +namespace PartialMap |
| 45 | + |
| 46 | +/-- Composition of partial maps. The domain of `f.comp g` is the preimage of `g.domain` under `f`, |
| 47 | +viewed as an open subscheme of `X`. Requires `f.hom` to be dominant so that the domain is dense. -/ |
| 48 | +@[simps] |
| 49 | +noncomputable def comp (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) : |
| 50 | + X.PartialMap Z where |
| 51 | + domain := f.domain.ι ''ᵁ f.hom ⁻¹ᵁ g.domain |
| 52 | + dense_domain := (f.domain.ι ''ᵁ f.hom ⁻¹ᵁ g.domain).2.dense <| by |
| 53 | + simpa [← Set.nonempty_preimage_iff] using |
| 54 | + f.hom.denseRange.inter_open_nonempty _ g.domain.2 g.dense_domain.nonempty |
| 55 | + hom := (f.domain.ι.isoImage _).inv ≫ f.hom ∣_ g.domain ≫ g.hom |
| 56 | + |
| 57 | +set_option backward.defeqAttrib.useBackward true in |
| 58 | +lemma comp_restrict_left (f : X.PartialMap Y) [IsDominant f.hom] (U : X.Opens) |
| 59 | + (hU : Dense (U : Set X)) (hU' : U ≤ f.domain) (g : Y.PartialMap Z) : |
| 60 | + (f.restrict U hU hU').comp g = (f.comp g).restrict (f.domain.ι ''ᵁ f.hom ⁻¹ᵁ g.domain ⊓ U) |
| 61 | + ((f.comp g).dense_domain.inter_of_isOpen_right hU U.2) inf_le_left := by |
| 62 | + ext |
| 63 | + · simp [ι_image_homOfLE_eq_ι_image_inf] |
| 64 | + · simp [morphismRestrict_comp, isoImage_ι_inv_morphismRestrict_homOfLE_assoc, isoOfEq_hom] |
| 65 | + |
| 66 | +set_option backward.defeqAttrib.useBackward true in |
| 67 | +lemma comp_restrict_right (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) |
| 68 | + (V : Y.Opens) (hV : Dense (V : Set Y)) (hV' : V ≤ g.domain) : |
| 69 | + f.comp (g.restrict V hV hV') = (f.comp g).restrict |
| 70 | + (f.domain.ι ''ᵁ (f.hom ⁻¹ᵁ V)) ((f.domain.ι ''ᵁ f.hom ⁻¹ᵁ V).2.dense <| by |
| 71 | + simpa [← Set.nonempty_preimage_iff] using |
| 72 | + f.hom.denseRange.inter_open_nonempty _ V.2 hV.nonempty) |
| 73 | + (f.domain.ι.image_mono (f.hom.preimage_mono hV')) := by |
| 74 | + ext |
| 75 | + · simp |
| 76 | + · simp [← f.domain.ι.isoImage_inv_homOfLE_assoc _ _ (f.hom.preimage_mono hV'), |
| 77 | + ← morphismRestrict_homOfLE_assoc f.hom _ _ hV'] |
| 78 | + |
| 79 | +set_option backward.defeqAttrib.useBackward true in |
| 80 | +/-- Composition respects equivalence of partial maps on the left. -/ |
| 81 | +lemma comp_equiv_of_equiv_left {f₁ f₂ : X.PartialMap Y} [IsDominant f₁.hom] [IsDominant f₂.hom] |
| 82 | + (h : f₁.equiv f₂) (g : Y.PartialMap Z) : |
| 83 | + (f₁.comp g).equiv (f₂.comp g) := by |
| 84 | + obtain ⟨W, hW, hW₁, hW₂, e⟩ := h |
| 85 | + replace e : f₁.restrict W hW hW₁ = f₂.restrict W hW hW₂ := |
| 86 | + PartialMap.ext _ _ rfl (by simpa using e) |
| 87 | + replace e := congr($(e).comp g) |
| 88 | + rw [comp_restrict_left, comp_restrict_left] at e |
| 89 | + exact equiv_of_restrict_eq _ _ e |
| 90 | + |
| 91 | +set_option backward.defeqAttrib.useBackward true in |
| 92 | +/-- Composition respects equivalence of partial maps on the right. -/ |
| 93 | +lemma comp_equiv_of_equiv_right (f : X.PartialMap Y) [IsDominant f.hom] {g₁ g₂ : Y.PartialMap Z} |
| 94 | + (h : g₁.equiv g₂) : (f.comp g₁).equiv (f.comp g₂) := by |
| 95 | + obtain ⟨W, hW, hW₁, hW₂, e⟩ := h |
| 96 | + replace e : g₁.restrict W hW hW₁ = g₂.restrict W hW hW₂ := |
| 97 | + PartialMap.ext _ _ rfl (by simpa using e) |
| 98 | + replace e := congr(f.comp $e) |
| 99 | + rw [comp_restrict_right, comp_restrict_right] at e |
| 100 | + exact equiv_of_restrict_eq _ _ e |
| 101 | + |
| 102 | +/-- Composition respects equivalence of partial maps in both arguments. -/ |
| 103 | +lemma comp_equiv_of_equiv (f₁ f₂ : X.PartialMap Y) [IsDominant f₁.hom] [IsDominant f₂.hom] |
| 104 | + (hf : f₁.equiv f₂) (g₁ g₂ : Y.PartialMap Z) (hg : g₁.equiv g₂) : |
| 105 | + (f₁.comp g₁).equiv (f₂.comp g₂) := |
| 106 | + equivalence_rel.trans (comp_equiv_of_equiv_left hf _) (comp_equiv_of_equiv_right _ hg) |
| 107 | + |
| 108 | +set_option backward.defeqAttrib.useBackward true in |
| 109 | +instance isDominant_comp_hom (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) |
| 110 | + [IsDominant g.hom] : IsDominant (f.comp g).hom := by |
| 111 | + dsimp only [comp_domain, comp_hom] |
| 112 | + have := IsZariskiLocalAtTarget.restrict ‹IsDominant f.hom› g.domain |
| 113 | + infer_instance |
| 114 | + |
| 115 | +set_option backward.defeqAttrib.useBackward true in |
| 116 | +@[simp] |
| 117 | +lemma comp_assoc {X₁ X₂ X₃ Y : Scheme.{u}} [PreirreducibleSpace X₁] [IrreducibleSpace X₂] |
| 118 | + [Nonempty X₃] (f : X₁.PartialMap X₂) [IsDominant f.hom] (g : X₂.PartialMap X₃) |
| 119 | + [IsDominant g.hom] (h : X₃.PartialMap Y) : |
| 120 | + (f.comp g).comp h = f.comp (g.comp h) := by |
| 121 | + ext |
| 122 | + · simp_rw [comp_domain, comp_hom, ← Category.assoc, Hom.comp_preimage, Hom.inv_preimage, |
| 123 | + ← Hom.comp_image, Hom.isoImage_hom_ι, Hom.comp_image, image_morphismRestrict_preimage] |
| 124 | + · dsimp |
| 125 | + simp_rw [morphismRestrict_comp, morphismRestrict_ι_image_ι_isoImage_inv_assoc, |
| 126 | + Hom.comp_preimage, Category.assoc] |
| 127 | + conv_lhs => rw [← Category.assoc] |
| 128 | + conv_rhs => rw [← Category.assoc, ← Category.assoc, ← Category.assoc] |
| 129 | + congr 1 |
| 130 | + simp [← cancel_mono (Opens.ι _)] |
| 131 | + |
| 132 | +set_option backward.defeqAttrib.useBackward true in |
| 133 | +@[simp] |
| 134 | +lemma comp_toPartialMap (f : X.PartialMap Y) [IsDominant f.hom] (g : Y ⟶ Z) : |
| 135 | + f.comp g.toPartialMap = f.compHom g := by |
| 136 | + ext1 |
| 137 | + · simp |
| 138 | + · simp_rw [comp_hom, Hom.toPartialMap_domain, Hom.toPartialMap_hom, compHom_hom, topIso_hom, |
| 139 | + morphismRestrict_ι_assoc, f.domain.isoImage_ι_inv_ι_assoc, isoOfEq_hom] |
| 140 | + rfl |
| 141 | + |
| 142 | +set_option backward.defeqAttrib.useBackward true in |
| 143 | +lemma comp_id (f : X.PartialMap Y) [IsDominant f.hom] : f.comp (PartialMap.id Y) = f := by simp |
| 144 | + |
| 145 | +end PartialMap |
| 146 | + |
| 147 | +namespace RationalMap |
| 148 | + |
| 149 | +-- If better def-eqs are required, consider refactoring this by using `Quotient.liftOn₂` |
| 150 | +-- and a bundled structure `DominantPartialMap`. |
| 151 | +/-- Composition of rational maps. Requires `f` to be dominant, so that we may choose |
| 152 | +a dominant representative. -/ |
| 153 | +noncomputable def comp (f : X ⤏ Y) [f.IsDominant] (g : Y ⤏ Z) : X ⤏ Z := |
| 154 | + Quotient.liftOn g (PartialMap.toRationalMap ∘ f.representative.comp) <| fun _ _ h ↦ by |
| 155 | + rw [Function.comp_apply, Function.comp_apply, PartialMap.toRationalMap_eq_iff] |
| 156 | + exact PartialMap.comp_equiv_of_equiv_right _ h |
| 157 | + |
| 158 | +lemma comp_def (f : X ⤏ Y) [f.IsDominant] (g : Y.PartialMap Z) : |
| 159 | + f.comp g.toRationalMap = (f.representative.comp g).toRationalMap := |
| 160 | + rfl |
| 161 | + |
| 162 | +lemma toRationalMap_comp (f : X.PartialMap Y) [IsDominant f.hom] (g : Y.PartialMap Z) : |
| 163 | + f.toRationalMap.comp g.toRationalMap = (f.comp g).toRationalMap := by |
| 164 | + rw [RationalMap.comp_def, PartialMap.toRationalMap_eq_iff] |
| 165 | + exact PartialMap.comp_equiv_of_equiv_left f.representative_toRationalMap_equiv _ |
| 166 | + |
| 167 | +@[simp] |
| 168 | +lemma comp_id (f : X ⤏ Y) [f.IsDominant] : f.comp (RationalMap.id Y) = f := by |
| 169 | + simp [RationalMap.comp_def] |
| 170 | + |
| 171 | +instance (f : X ⤏ Y) [f.IsDominant] (g : Y ⤏ Z) [g.IsDominant] : (f.comp g).IsDominant := by |
| 172 | + rw [← g.toRationalMap_representative, RationalMap.comp_def] |
| 173 | + infer_instance |
| 174 | + |
| 175 | +lemma comp_toRationalMap (f : X ⤏ Y) [f.IsDominant] (h : Y ⟶ Z) : |
| 176 | + f.comp h.toRationalMap = f.compHom h := by |
| 177 | + simp [comp_def, PartialMap.comp_toPartialMap] |
| 178 | + |
| 179 | +@[grind _=_] |
| 180 | +lemma comp_assoc {X₁ X₂ X₃ Y : Scheme.{u}} [PreirreducibleSpace X₁] [IrreducibleSpace X₂] |
| 181 | + [Nonempty X₃] (f₁ : X₁ ⤏ X₂) [f₁.IsDominant] (f₂ : X₂ ⤏ X₃) [f₂.IsDominant] (f₃ : X₃ ⤏ Y) : |
| 182 | + (f₁.comp f₂).comp f₃ = f₁.comp (f₂.comp f₃) := by |
| 183 | + rw [← f₃.toRationalMap_representative] |
| 184 | + simp_rw [comp_def, ← PartialMap.comp_assoc, PartialMap.toRationalMap_eq_iff] |
| 185 | + apply PartialMap.comp_equiv_of_equiv_left |
| 186 | + rw [← f₂.toRationalMap_representative, comp_def] |
| 187 | + apply (f₁.representative.comp f₂.representative).representative_toRationalMap_equiv.trans |
| 188 | + apply PartialMap.comp_equiv_of_equiv_right |
| 189 | + rw [toRationalMap_representative] |
| 190 | + |
| 191 | +instance isOver_comp {S : Scheme.{u}} [IrreducibleSpace Y] [Nonempty Z] [X.Over S] [Y.Over S] |
| 192 | + [Z.Over S] (f : X ⤏ Y) [f.IsDominant] [f.IsOver S] (g : Y ⤏ Z) [g.IsDominant] [g.IsOver S] : |
| 193 | + (f.comp g).IsOver S := by |
| 194 | + rw [isOver_iff, ← comp_toRationalMap, comp_assoc, comp_toRationalMap, |
| 195 | + isOver_iff.mp ‹g.IsOver S›, comp_toRationalMap, RationalMap.isOver_iff.mp ‹f.IsOver S›] |
| 196 | + |
| 197 | +end RationalMap |
| 198 | + |
| 199 | +end PreirreducibleSpace |
| 200 | + |
| 201 | +set_option backward.defeqAttrib.useBackward true in |
| 202 | +@[simp] |
| 203 | +lemma PartialMap.id_comp {X Y : Scheme.{u}} [IrreducibleSpace X] (f : X.PartialMap Y) : |
| 204 | + (PartialMap.id X).comp f = f := by |
| 205 | + ext1 |
| 206 | + · simp_rw [comp_domain, Hom.toPartialMap_domain, Hom.toPartialMap_hom, Category.comp_id, |
| 207 | + ← X.topIso_hom, ← Hom.inv_image, ← Hom.comp_image, Iso.inv_hom_id, Hom.id_image] |
| 208 | + · simp_rw [comp_hom, Hom.toPartialMap_hom, Hom.toPartialMap_domain, morphismRestrict_comp, |
| 209 | + morphismRestrict_id, ← X.topIso_hom, Hom.comp_preimage, Hom.id_preimage, |
| 210 | + Category.comp_id, ← X.topIso.hom.isoImage_preimage_hom_homOfLE, Category.assoc, |
| 211 | + Iso.inv_hom_id_assoc] |
| 212 | + rfl |
| 213 | + |
| 214 | +@[simp, grind =] |
| 215 | +lemma RationalMap.id_comp {X Y : Scheme.{u}} [IrreducibleSpace X] (f : X ⤏ Y) : |
| 216 | + (RationalMap.id X).comp f = f := by |
| 217 | + rw [← f.toRationalMap_representative, toRationalMap_comp, PartialMap.id_comp] |
| 218 | + |
| 219 | +end AlgebraicGeometry.Scheme |
0 commit comments