|
| 1 | +/- |
| 2 | +Copyright (c) 2021 Justus Springer. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Justus Springer, Andrew Yang |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module algebraic_geometry.ringed_space |
| 7 | +! leanprover-community/mathlib commit d39590fc8728fbf6743249802486f8c91ffe07bc |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Algebra.Category.Ring.FilteredColimits |
| 12 | +import Mathlib.AlgebraicGeometry.SheafedSpace |
| 13 | +import Mathlib.Topology.Sheaves.Stalks |
| 14 | +import Mathlib.Algebra.Category.Ring.Colimits |
| 15 | +import Mathlib.Algebra.Category.Ring.Limits |
| 16 | + |
| 17 | +/-! |
| 18 | +# Ringed spaces |
| 19 | +
|
| 20 | +We introduce the category of ringed spaces, as an alias for `SheafedSpace CommRingCat`. |
| 21 | +
|
| 22 | +The facts collected in this file are typically stated for locally ringed spaces, but never actually |
| 23 | +make use of the locality of stalks. See for instance <https://stacks.math.columbia.edu/tag/01HZ>. |
| 24 | +
|
| 25 | +-/ |
| 26 | + |
| 27 | + |
| 28 | +universe v |
| 29 | + |
| 30 | +open CategoryTheory |
| 31 | + |
| 32 | +open TopologicalSpace |
| 33 | + |
| 34 | +open Opposite |
| 35 | + |
| 36 | +open TopCat |
| 37 | + |
| 38 | +open TopCat.Presheaf |
| 39 | + |
| 40 | +namespace AlgebraicGeometry |
| 41 | + |
| 42 | +/-- The type of Ringed spaces, as an abbreviation for `SheafedSpace CommRingCat`. -/ |
| 43 | +abbrev RingedSpace : Type _ := |
| 44 | + SheafedSpace CommRingCat |
| 45 | +set_option linter.uppercaseLean3 false in |
| 46 | +#align algebraic_geometry.RingedSpace AlgebraicGeometry.RingedSpace |
| 47 | + |
| 48 | +namespace RingedSpace |
| 49 | + |
| 50 | +open SheafedSpace |
| 51 | + |
| 52 | +variable (X : RingedSpace.{v}) |
| 53 | + |
| 54 | +-- Porting note : this was not necessary in mathlib3 |
| 55 | +instance : CoeSort RingedSpace (Type _) where |
| 56 | + coe X := X.carrier |
| 57 | + |
| 58 | +/-- |
| 59 | +If the germ of a section `f` is a unit in the stalk at `x`, then `f` must be a unit on some small |
| 60 | +neighborhood around `x`. |
| 61 | +-/ |
| 62 | +theorem isUnit_res_of_isUnit_germ (U : Opens X) (f : X.presheaf.obj (op U)) (x : U) |
| 63 | + (h : IsUnit (X.presheaf.germ x f)) : |
| 64 | + ∃ (V : Opens X) (i : V ⟶ U) (_ : x.1 ∈ V), IsUnit (X.presheaf.map i.op f) := by |
| 65 | + obtain ⟨g', heq⟩ := h.exists_right_inv |
| 66 | + obtain ⟨V, hxV, g, rfl⟩ := X.presheaf.germ_exist x.1 g' |
| 67 | + let W := U ⊓ V |
| 68 | + have hxW : x.1 ∈ W := ⟨x.2, hxV⟩ |
| 69 | + -- Porting note : `erw` can't write into `HEq`, so this is replaced with another `HEq` in the |
| 70 | + -- desired form |
| 71 | + replace heq : (X.presheaf.germ ⟨x.val, hxW⟩) ((X.presheaf.map (U.infLELeft V).op) f * |
| 72 | + (X.presheaf.map (U.infLERight V).op) g) = (X.presheaf.germ ⟨x.val, hxW⟩) 1 |
| 73 | + . dsimp [germ] |
| 74 | + erw [map_mul, map_one, show X.presheaf.germ ⟨x, hxW⟩ ((X.presheaf.map (U.infLELeft V).op) f) = |
| 75 | + X.presheaf.germ x f from X.presheaf.germ_res_apply (Opens.infLELeft U V) ⟨x.1, hxW⟩ f, |
| 76 | + show X.presheaf.germ ⟨x, hxW⟩ (X.presheaf.map (U.infLERight V).op g) = |
| 77 | + X.presheaf.germ ⟨x, hxV⟩ g from X.presheaf.germ_res_apply (Opens.infLERight U V) ⟨x.1, hxW⟩ g] |
| 78 | + exact heq |
| 79 | + obtain ⟨W', hxW', i₁, i₂, heq'⟩ := X.presheaf.germ_eq x.1 hxW hxW _ _ heq |
| 80 | + use W', i₁ ≫ Opens.infLELeft U V, hxW' |
| 81 | + -- Porting note : this `change` was not necessary in Lean3 |
| 82 | + change X.presheaf.map _ _ = X.presheaf.map _ _ at heq' |
| 83 | + rw [map_one, map_mul] at heq' |
| 84 | + -- Porting note : this `change` was not necessary in Lean3 |
| 85 | + change (X.presheaf.map _ ≫ X.presheaf.map _) _ * (X.presheaf.map _ ≫ _) _ = _ at heq' |
| 86 | + rw [←X.presheaf.map_comp, ←op_comp] at heq' |
| 87 | + exact isUnit_of_mul_eq_one _ _ heq' |
| 88 | +set_option linter.uppercaseLean3 false in |
| 89 | +#align algebraic_geometry.RingedSpace.is_unit_res_of_is_unit_germ AlgebraicGeometry.RingedSpace.isUnit_res_of_isUnit_germ |
| 90 | + |
| 91 | +/-- If a section `f` is a unit in each stalk, `f` must be a unit. -/ |
| 92 | +theorem isUnit_of_isUnit_germ (U : Opens X) (f : X.presheaf.obj (op U)) |
| 93 | + (h : ∀ x : U, IsUnit (X.presheaf.germ x f)) : IsUnit f := by |
| 94 | + -- We pick a cover of `U` by open sets `V x`, such that `f` is a unit on each `V x`. |
| 95 | + choose V iVU m h_unit using fun x : U => X.isUnit_res_of_isUnit_germ U f x (h x) |
| 96 | + have hcover : U ≤ iSup V |
| 97 | + . intro x hxU |
| 98 | + -- Porting note : in Lean3 `rw` is sufficient |
| 99 | + erw [Opens.mem_iSup] |
| 100 | + exact ⟨⟨x, hxU⟩, m ⟨x, hxU⟩⟩ |
| 101 | + -- Let `g x` denote the inverse of `f` in `U x`. |
| 102 | + choose g hg using fun x : U => IsUnit.exists_right_inv (h_unit x) |
| 103 | + have ic : IsCompatible (sheaf X).val V g |
| 104 | + -- swap |
| 105 | + · intro x y |
| 106 | + apply section_ext X.sheaf (V x ⊓ V y) |
| 107 | + rintro ⟨z, hzVx, hzVy⟩ |
| 108 | + erw [germ_res_apply, germ_res_apply] |
| 109 | + apply (IsUnit.mul_right_inj (h ⟨z, (iVU x).le hzVx⟩)).mp |
| 110 | + -- Porting note : now need explicitly typing the rewrites |
| 111 | + rw [←show X.presheaf.germ ⟨z, hzVx⟩ (X.presheaf.map (iVU x).op f) = |
| 112 | + X.presheaf.germ ⟨z, ((iVU x) ⟨z, hzVx⟩).2⟩ f from |
| 113 | + X.presheaf.germ_res_apply (iVU x) ⟨z, hzVx⟩ f] |
| 114 | + -- Porting note : change was not necessary in Lean3 |
| 115 | + change X.presheaf.germ ⟨z, hzVx⟩ _ * (X.presheaf.germ ⟨z, hzVx⟩ _) = |
| 116 | + X.presheaf.germ ⟨z, hzVx⟩ _ * X.presheaf.germ ⟨z, hzVy⟩ (g y) |
| 117 | + rw [← RingHom.map_mul, |
| 118 | + congr_arg (X.presheaf.germ (⟨z, hzVx⟩ : V x)) (hg x), |
| 119 | + -- Porting note : now need explicitly typing the rewrites |
| 120 | + show X.presheaf.germ ⟨z, hzVx⟩ (X.presheaf.map (iVU x).op f) = |
| 121 | + X.presheaf.germ ⟨z, ((iVU x) ⟨z, hzVx⟩).2⟩ f from X.presheaf.germ_res_apply _ _ f, |
| 122 | + -- Porting note : now need explicitly typing the rewrites |
| 123 | + ← show X.presheaf.germ ⟨z, hzVy⟩ (X.presheaf.map (iVU y).op f) = |
| 124 | + X.presheaf.germ ⟨z, ((iVU x) ⟨z, hzVx⟩).2⟩ f from |
| 125 | + X.presheaf.germ_res_apply (iVU y) ⟨z, hzVy⟩ f, |
| 126 | + ← RingHom.map_mul, |
| 127 | + congr_arg (X.presheaf.germ (⟨z, hzVy⟩ : V y)) (hg y), RingHom.map_one, RingHom.map_one] |
| 128 | + -- We claim that these local inverses glue together to a global inverse of `f`. |
| 129 | + obtain ⟨gl, gl_spec, -⟩ := X.sheaf.existsUnique_gluing' V U iVU hcover g ic |
| 130 | + apply isUnit_of_mul_eq_one f gl |
| 131 | + apply X.sheaf.eq_of_locally_eq' V U iVU hcover |
| 132 | + intro i |
| 133 | + -- Porting note : this `change` was not necessary in Lean3 |
| 134 | + change X.sheaf.1.map _ _ = X.sheaf.1.map _ 1 |
| 135 | + rw [RingHom.map_one, RingHom.map_mul] |
| 136 | + -- Porting note : this `change` was not necessary in Lean3 |
| 137 | + specialize gl_spec i |
| 138 | + change X.sheaf.1.map _ _ = _ at gl_spec |
| 139 | + rw [gl_spec] |
| 140 | + exact hg i |
| 141 | +set_option linter.uppercaseLean3 false in |
| 142 | +#align algebraic_geometry.RingedSpace.is_unit_of_is_unit_germ AlgebraicGeometry.RingedSpace.isUnit_of_isUnit_germ |
| 143 | + |
| 144 | +/-- The basic open of a section `f` is the set of all points `x`, such that the germ of `f` at |
| 145 | +`x` is a unit. |
| 146 | +-/ |
| 147 | +def basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : Opens X where |
| 148 | + -- Porting note : `coe` does not work |
| 149 | + carrier := Subtype.val '' { x : U | IsUnit (X.presheaf.germ x f) } |
| 150 | + is_open' := by |
| 151 | + rw [isOpen_iff_forall_mem_open] |
| 152 | + rintro _ ⟨x, hx, rfl⟩ |
| 153 | + obtain ⟨V, i, hxV, hf⟩ := X.isUnit_res_of_isUnit_germ U f x hx |
| 154 | + use V.1 |
| 155 | + refine' ⟨_, V.2, hxV⟩ |
| 156 | + intro y hy |
| 157 | + use (⟨y, i.le hy⟩ : U) |
| 158 | + rw [Set.mem_setOf_eq] |
| 159 | + constructor |
| 160 | + · convert RingHom.isUnit_map (X.presheaf.germ ⟨y, hy⟩) hf |
| 161 | + exact (X.presheaf.germ_res_apply i ⟨y, hy⟩ f).symm |
| 162 | + · rfl |
| 163 | +set_option linter.uppercaseLean3 false in |
| 164 | +#align algebraic_geometry.RingedSpace.basic_open AlgebraicGeometry.RingedSpace.basicOpen |
| 165 | + |
| 166 | +@[simp] |
| 167 | +theorem mem_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) (x : U) : |
| 168 | + ↑x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ x f) := by |
| 169 | + constructor |
| 170 | + · rintro ⟨x, hx, a⟩; cases Subtype.eq a; exact hx |
| 171 | + · intro h; exact ⟨x, h, rfl⟩ |
| 172 | +set_option linter.uppercaseLean3 false in |
| 173 | +#align algebraic_geometry.RingedSpace.mem_basic_open AlgebraicGeometry.RingedSpace.mem_basicOpen |
| 174 | + |
| 175 | +@[simp] |
| 176 | +theorem mem_top_basicOpen (f : X.presheaf.obj (op ⊤)) (x : X) : |
| 177 | + x ∈ X.basicOpen f ↔ IsUnit (X.presheaf.germ ⟨x, show x ∈ (⊤ : Opens X) by trivial⟩ f) := |
| 178 | + mem_basicOpen X f ⟨x, _⟩ |
| 179 | +set_option linter.uppercaseLean3 false in |
| 180 | +#align algebraic_geometry.RingedSpace.mem_top_basic_open AlgebraicGeometry.RingedSpace.mem_top_basicOpen |
| 181 | + |
| 182 | +theorem basicOpen_le {U : Opens X} (f : X.presheaf.obj (op U)) : X.basicOpen f ≤ U := by |
| 183 | + rintro _ ⟨x, _, rfl⟩; exact x.2 |
| 184 | +set_option linter.uppercaseLean3 false in |
| 185 | +#align algebraic_geometry.RingedSpace.basic_open_le AlgebraicGeometry.RingedSpace.basicOpen_le |
| 186 | + |
| 187 | +/-- The restriction of a section `f` to the basic open of `f` is a unit. -/ |
| 188 | +theorem isUnit_res_basicOpen {U : Opens X} (f : X.presheaf.obj (op U)) : |
| 189 | + IsUnit (X.presheaf.map (@homOfLE (Opens X) _ _ _ (X.basicOpen_le f)).op f) := by |
| 190 | + apply isUnit_of_isUnit_germ |
| 191 | + rintro ⟨_, ⟨x, (hx : IsUnit _), rfl⟩⟩ |
| 192 | + convert hx |
| 193 | + convert X.presheaf.germ_res_apply _ _ _ |
| 194 | +set_option linter.uppercaseLean3 false in |
| 195 | +#align algebraic_geometry.RingedSpace.is_unit_res_basic_open AlgebraicGeometry.RingedSpace.isUnit_res_basicOpen |
| 196 | + |
| 197 | +@[simp] |
| 198 | +theorem basicOpen_res {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) (f : X.presheaf.obj U) : |
| 199 | + @basicOpen X (unop V) (X.presheaf.map i f) = unop V ⊓ @basicOpen X (unop U) f := by |
| 200 | + induction U using Opposite.rec' |
| 201 | + induction V using Opposite.rec' |
| 202 | + let g := i.unop; have : i = g.op := rfl; clear_value g; subst this |
| 203 | + ext; constructor |
| 204 | + · rintro ⟨x, hx : IsUnit _, rfl⟩ |
| 205 | + -- Porting note : now need explicitly typing the rewrites and use `erw` |
| 206 | + erw [show X.presheaf.germ x ((X.presheaf.map g.op) f) = X.presheaf.germ (g x) f |
| 207 | + from X.presheaf.germ_res_apply _ _ _] at hx |
| 208 | + exact ⟨x.2, g x, hx, rfl⟩ |
| 209 | + · rintro ⟨hxV, x, hx, rfl⟩ |
| 210 | + refine' ⟨⟨x, hxV⟩, (_ : IsUnit _), rfl⟩ |
| 211 | + -- Porting note : now need explicitly typing the rewrites and use `erw` |
| 212 | + erw [show X.presheaf.germ ⟨x, hxV⟩ (X.presheaf.map g.op f) = X.presheaf.germ (g ⟨x, hxV⟩) f from |
| 213 | + X.presheaf.germ_res_apply _ _ _] |
| 214 | + exact hx |
| 215 | +set_option linter.uppercaseLean3 false in |
| 216 | +#align algebraic_geometry.RingedSpace.basic_open_res AlgebraicGeometry.RingedSpace.basicOpen_res |
| 217 | + |
| 218 | +-- This should fire before `basicOpen_res`. |
| 219 | +-- Porting note : this lemma is not in simple normal form because of `basicOpen_res`, as in Lean3 |
| 220 | +-- it is specifically said "This should fire before `basic_open_res`", this lemma is marked with |
| 221 | +-- high priority |
| 222 | +@[simp (high)] |
| 223 | +theorem basicOpen_res_eq {U V : (Opens X)ᵒᵖ} (i : U ⟶ V) [IsIso i] (f : X.presheaf.obj U) : |
| 224 | + @basicOpen X (unop V) (X.presheaf.map i f) = @RingedSpace.basicOpen X (unop U) f := by |
| 225 | + apply le_antisymm |
| 226 | + · rw [X.basicOpen_res i f]; exact inf_le_right |
| 227 | + · -- Porting note : now need explicitly typing the rewrites |
| 228 | + have : X.basicOpen ((X.presheaf.map _ ≫ X.presheaf.map _) f) = _ := |
| 229 | + X.basicOpen_res (inv i) (X.presheaf.map i f) |
| 230 | + rw [← X.presheaf.map_comp, IsIso.hom_inv_id, X.presheaf.map_id] at this |
| 231 | + erw [this] |
| 232 | + exact inf_le_right |
| 233 | +set_option linter.uppercaseLean3 false in |
| 234 | +#align algebraic_geometry.RingedSpace.basic_open_res_eq AlgebraicGeometry.RingedSpace.basicOpen_res_eq |
| 235 | + |
| 236 | +@[simp] |
| 237 | +theorem basicOpen_mul {U : Opens X} (f g : X.presheaf.obj (op U)) : |
| 238 | + X.basicOpen (f * g) = X.basicOpen f ⊓ X.basicOpen g := by |
| 239 | + ext1 |
| 240 | + dsimp [RingedSpace.basicOpen] |
| 241 | + rw [← Set.image_inter Subtype.coe_injective] |
| 242 | + congr |
| 243 | + ext x |
| 244 | + simp [map_mul, Set.mem_image] |
| 245 | +set_option linter.uppercaseLean3 false in |
| 246 | +#align algebraic_geometry.RingedSpace.basic_open_mul AlgebraicGeometry.RingedSpace.basicOpen_mul |
| 247 | + |
| 248 | +theorem basicOpen_of_isUnit {U : Opens X} {f : X.presheaf.obj (op U)} (hf : IsUnit f) : |
| 249 | + X.basicOpen f = U := by |
| 250 | + apply le_antisymm |
| 251 | + · exact X.basicOpen_le f |
| 252 | + intro x hx |
| 253 | + erw [X.mem_basicOpen f (⟨x, hx⟩ : U)] |
| 254 | + exact RingHom.isUnit_map _ hf |
| 255 | +set_option linter.uppercaseLean3 false in |
| 256 | +#align algebraic_geometry.RingedSpace.basic_open_of_is_unit AlgebraicGeometry.RingedSpace.basicOpen_of_isUnit |
| 257 | + |
| 258 | +end RingedSpace |
| 259 | + |
| 260 | +end AlgebraicGeometry |
0 commit comments