Skip to content

Commit bbc0ea7

Browse files
committed
feat: port AlgebraicGeometry.RingedSpace (#4499)
1 parent bac5670 commit bbc0ea7

File tree

2 files changed

+261
-0
lines changed

2 files changed

+261
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ import Mathlib.AlgebraicGeometry.PrimeSpectrum.IsOpenComapC
370370
import Mathlib.AlgebraicGeometry.PrimeSpectrum.Maximal
371371
import Mathlib.AlgebraicGeometry.PrimeSpectrum.Noetherian
372372
import Mathlib.AlgebraicGeometry.ProjectiveSpectrum.Topology
373+
import Mathlib.AlgebraicGeometry.RingedSpace
373374
import Mathlib.AlgebraicGeometry.SheafedSpace
374375
import Mathlib.AlgebraicGeometry.Stalks
375376
import Mathlib.AlgebraicGeometry.StructureSheaf
Lines changed: 260 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,260 @@
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

Comments
 (0)