Skip to content

Commit 4bf4bb1

Browse files
committed
feat(AlgebraicGeometry): locally directed colimits in P.Over ⊤ S (#30140)
We lift the colimit properties of `Scheme` to `P.Over ⊤ S` if `IsLocalAtSource P`. In particular, `P.Over ⊤ S` has pushouts along open immersions and (small) coproducts. We also add two instances, that make ``` example {U X Y : Scheme.{u}} (f : U ⟶ X) (g : U ⟶ Y) [IsOpenImmersion f] [IsOpenImmersion g] : HasPushout f g := inferInstance ``` work.
1 parent ced1553 commit 4bf4bb1

File tree

6 files changed

+174
-4
lines changed

6 files changed

+174
-4
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1276,6 +1276,7 @@ public import Mathlib.AlgebraicGeometry.IdealSheaf.Basic
12761276
public import Mathlib.AlgebraicGeometry.IdealSheaf.Functorial
12771277
public import Mathlib.AlgebraicGeometry.IdealSheaf.Subscheme
12781278
public import Mathlib.AlgebraicGeometry.Limits
1279+
public import Mathlib.AlgebraicGeometry.LimitsOver
12791280
public import Mathlib.AlgebraicGeometry.Modules.Presheaf
12801281
public import Mathlib.AlgebraicGeometry.Modules.Sheaf
12811282
public import Mathlib.AlgebraicGeometry.Modules.Tilde

Mathlib/AlgebraicGeometry/Limits.lean

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,26 @@ instance [IsAffine X] [IsAffine Y] : IsAffine (X ⨿ Y) :=
516516

517517
end Coproduct
518518

519+
instance {U X Y : Scheme} (f : U ⟶ X) (g : U ⟶ Y) [IsOpenImmersion f] [IsOpenImmersion g]
520+
(i : WalkingPair) : Mono ((span f g ⋙ Scheme.forget).map (WidePushoutShape.Hom.init i)) := by
521+
rw [mono_iff_injective]
522+
cases i
523+
· simpa using f.isOpenEmbedding.injective
524+
· simpa using g.isOpenEmbedding.injective
525+
526+
instance {U X Y : Scheme} (f : U ⟶ X) (g : U ⟶ Y) [IsOpenImmersion f] [IsOpenImmersion g]
527+
{i j : WalkingSpan} (t : i ⟶ j) : IsOpenImmersion ((span f g).map t) := by
528+
obtain (a | (a | a)) := t
529+
· simp only [WidePushoutShape.hom_id, CategoryTheory.Functor.map_id]
530+
infer_instance
531+
· simpa
532+
· simpa
533+
534+
-- Test that instances on locally directed colimits fire correctly.
535+
example {U X Y : Scheme.{u}} (f : U ⟶ X) (g : U ⟶ Y)
536+
[IsOpenImmersion f] [IsOpenImmersion g] : HasPushout f g :=
537+
inferInstance
538+
519539
instance : CartesianMonoidalCategory Scheme := .ofHasFiniteProducts
520540
instance : BraidedCategory Scheme := .ofCartesianMonoidalCategory
521541

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/-
2+
Copyright (c) 2025 Christian Merten. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Christian Merten
5+
-/
6+
module
7+
8+
public import Mathlib.AlgebraicGeometry.Morphisms.Basic
9+
public import Mathlib.CategoryTheory.MorphismProperty.Comma
10+
11+
/-!
12+
# (Co)limits in over categories
13+
14+
We show that if `P` is a morphism property in `Scheme` that is local at the source, then
15+
colimits in `P.Over ⊤ X` for `X : Scheme` of locally directed diagrams of open immersions
16+
exist and agree with the colimit in `Scheme`.
17+
-/
18+
19+
@[expose] public section
20+
21+
universe u
22+
23+
open CategoryTheory Limits
24+
25+
namespace AlgebraicGeometry
26+
27+
variable (X : Scheme.{u})
28+
29+
variable (P : MorphismProperty Scheme.{u})
30+
31+
section Over
32+
33+
variable {S : Scheme.{u}} {J : Type*} [Category J] (F : J ⥤ Over S)
34+
[∀ {i j} (f : i ⟶ j), IsOpenImmersion (F.map f).left]
35+
[(F ⋙ Over.forget S ⋙ Scheme.forget).IsLocallyDirected]
36+
[Quiver.IsThin J] [Small.{u} J]
37+
38+
noncomputable instance : HasColimit F :=
39+
have {i j} (f : i ⟶ j) : IsOpenImmersion ((F ⋙ Over.forget S).map f) :=
40+
inferInstanceAs <| IsOpenImmersion (F.map f).left
41+
have : ((F ⋙ Over.forget S) ⋙ Scheme.forget).IsLocallyDirected := ‹_›
42+
hasColimit_of_created _ (Over.forget S)
43+
44+
end Over
45+
46+
section OverProp
47+
48+
instance {S : Scheme.{u}} {U X Y : P.Over ⊤ S} (f : U ⟶ X) (g : U ⟶ Y)
49+
[IsOpenImmersion f.left] [IsOpenImmersion g.left] (i : WalkingPair) :
50+
Mono ((span f g ⋙ MorphismProperty.Over.forget P ⊤ S ⋙ Over.forget S ⋙ Scheme.forget).map
51+
(WidePushoutShape.Hom.init i)) := by
52+
rw [mono_iff_injective]
53+
cases i
54+
· simpa using f.left.isOpenEmbedding.injective
55+
· simpa using g.left.isOpenEmbedding.injective
56+
57+
instance {S : Scheme.{u}} {U X Y : P.Over ⊤ S} (f : U ⟶ X) (g : U ⟶ Y)
58+
[IsOpenImmersion f.left] [IsOpenImmersion g.left]
59+
{i j : WalkingSpan} (t : i ⟶ j) :
60+
IsOpenImmersion ((span f g).map t).left := by
61+
obtain (a|(a|a)) := t
62+
· simp only [WidePushoutShape.hom_id, CategoryTheory.Functor.map_id]
63+
infer_instance
64+
· simpa
65+
· simpa
66+
67+
variable [IsZariskiLocalAtSource P] {S : Scheme.{u}} {J : Type*} [Category J] (F : J ⥤ P.Over ⊤ S)
68+
[∀ {i j} (f : i ⟶ j), IsOpenImmersion (F.map f).left]
69+
[(F ⋙ MorphismProperty.Over.forget P ⊤ S ⋙ Over.forget S ⋙ Scheme.forget).IsLocallyDirected]
70+
[Quiver.IsThin J] [Small.{u} J]
71+
72+
local instance :
73+
(((F ⋙ MorphismProperty.Over.forget P ⊤ S) ⋙ Over.forget S) ⋙
74+
Scheme.forget).IsLocallyDirected :=
75+
‹_›
76+
77+
local instance {i j} (f : i ⟶ j) :
78+
IsOpenImmersion <|
79+
((F ⋙ MorphismProperty.Over.forget P ⊤ S) ⋙ Over.forget S).map f :=
80+
inferInstanceAs <| IsOpenImmersion (F.map f).left
81+
82+
noncomputable instance : CreatesColimit F (MorphismProperty.Over.forget P ⊤ S) := by
83+
have : HasColimit (F ⋙ MorphismProperty.Over.forget P ⊤ S) :=
84+
hasColimit_of_created _ (Over.forget S)
85+
refine createsColimitOfFullyFaithfulOfIso
86+
{ toComma := colimit (F ⋙ MorphismProperty.Over.forget P ⊤ S)
87+
prop := ?_ } (Iso.refl _)
88+
let e : (colimit (F ⋙ MorphismProperty.Over.forget P ⊤ S)).left ≅
89+
colimit ((F ⋙ MorphismProperty.Over.forget P ⊤ S) ⋙ Over.forget S) :=
90+
preservesColimitIso (Over.forget S) _
91+
let 𝒰 : (colimit (F ⋙ MorphismProperty.Over.forget P ⊤ S)).left.OpenCover :=
92+
(Scheme.IsLocallyDirected.openCover _).pushforwardIso e.inv
93+
rw [IsZariskiLocalAtSource.iff_of_openCover (P := P) 𝒰]
94+
intro i
95+
simpa [𝒰, e] using (F.obj i).prop
96+
97+
instance : HasColimit F := hasColimit_of_created _ (MorphismProperty.Over.forget P ⊤ S)
98+
99+
instance : PreservesColimit F (MorphismProperty.Over.forget P ⊤ S) :=
100+
-- this is only `inferInstance` with the local instances above
101+
inferInstance
102+
103+
instance (j : J) : IsOpenImmersion (colimit.ι F j).left := by
104+
rw [← MorphismProperty.Over.forget_comp_forget_map]
105+
let e : (colimit F).left ≅ colimit (F ⋙ _) :=
106+
preservesColimitIso (MorphismProperty.Over.forget P ⊤ S ⋙ Over.forget S) F
107+
rw [← MorphismProperty.cancel_right_of_respectsIso (P := @IsOpenImmersion) _ e.hom]
108+
simp only [e, CategoryTheory.ι_preservesColimitIso_hom]
109+
exact inferInstanceAs <| IsOpenImmersion
110+
(colimit.ι ((F ⋙ MorphismProperty.Over.forget P ⊤ S) ⋙ Over.forget S) j)
111+
112+
instance {ι : Type*} [Small.{u} ι] : HasCoproductsOfShape ι (P.Over ⊤ S) where
113+
114+
instance : HasFiniteCoproducts (P.Over ⊤ S) where
115+
out := inferInstance
116+
117+
noncomputable instance (J : Type*) [Small.{u} J] :
118+
CreatesColimitsOfShape (Discrete J) (MorphismProperty.Over.forget P ⊤ S) where
119+
120+
end OverProp
121+
122+
end AlgebraicGeometry

Mathlib/CategoryTheory/Limits/MorphismProperty.lean

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,25 @@ instance CostructuredArrow.closedUnderLimitsOfShape_discrete_empty [L.Faithful]
108108
P.costructuredArrow_iso_iff e]
109109
simpa using P.id_mem (L.obj Y)
110110

111+
lemma CostructuredArrow.isClosedUnderColimitsOfShape {J : Type*} [Category J]
112+
{P : MorphismProperty T} [P.RespectsIso] [PreservesColimitsOfShape J L] [HasColimitsOfShape J A]
113+
(c : ∀ (D : J ⥤ T) [HasColimit D], Cocone D)
114+
(hc : ∀ (D : J ⥤ T) [HasColimit D], IsColimit (c D))
115+
(H : ∀ (D : J ⥤ T) [HasColimit D] {X : T} (s : D ⟶ (Functor.const J).obj X),
116+
(∀ j, P (s.app j)) → P ((hc D).desc (Cocone.mk X s))) (X : T) :
117+
(P.costructuredArrowObj L (X := X)).IsClosedUnderColimitsOfShape J where
118+
colimitsOfShape_le Y := by
119+
intro ⟨d⟩
120+
let hd : IsColimit ((CategoryTheory.CostructuredArrow.proj L X ⋙ L).mapCocone d.cocone) :=
121+
isColimitOfPreserves _ d.isColimit
122+
have heq : Y.hom = hd.desc { pt := X, ι := { app j := (d.diag.obj j).hom } } := by
123+
refine hd.hom_ext fun j ↦ ?_
124+
simp only [Functor.const_obj_obj, IsColimit.fac]
125+
simp
126+
rw [P.costructuredArrowObj_iff, heq, ← hd.coconePointUniqueUpToIso_hom_desc (hc _),
127+
P.cancel_left_of_respectsIso]
128+
exact H _ _ d.prop_diag_obj
129+
111130
end
112131

113132
section

Mathlib/CategoryTheory/Limits/Over.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@ Authors: Johan Commelin, Reid Barton, Bhavik Mehta
55
-/
66
module
77

8-
public import Mathlib.CategoryTheory.Comma.Over.Basic
98
public import Mathlib.CategoryTheory.Limits.Comma
109
public import Mathlib.CategoryTheory.Limits.ConeCategory
11-
public import Mathlib.CategoryTheory.Limits.Creates
12-
public import Mathlib.CategoryTheory.Limits.Preserves.Basic
13-
public import Mathlib.CategoryTheory.Limits.Shapes.FiniteLimits
10+
public import Mathlib.CategoryTheory.Limits.Shapes.FiniteProducts
1411

1512
/-!
1613
# Limits and colimits in the over and under categories
@@ -51,6 +48,9 @@ instance [HasFiniteColimits C] : HasFiniteColimits (Over X) where
5148
instance [HasColimits C] : HasColimits (Over X) :=
5249
⟨inferInstance⟩
5350

51+
instance [HasFiniteCoproducts C] : HasFiniteCoproducts (Over X) where
52+
out := inferInstance
53+
5454
instance createsColimitsOfSize : CreatesColimitsOfSize.{w, w'} (forget X) :=
5555
CostructuredArrow.createsColimitsOfSize
5656

Mathlib/CategoryTheory/MorphismProperty/Comma.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,10 @@ protected abbrev Over.forget : P.Over Q X ⥤ Over X :=
387387
instance : (Over.forget P ⊤ X).Faithful := inferInstanceAs <| (Comma.forget _ _ _ _ _).Faithful
388388
instance : (Over.forget P ⊤ X).Full := inferInstanceAs <| (Comma.forget _ _ _ _ _).Full
389389

390+
/-- Occasionally useful for rewriting in the backwards direction. -/
391+
lemma Over.forget_comp_forget_map {A B : P.Over Q X} (f : A ⟶ B) :
392+
(MorphismProperty.Over.forget P Q X ⋙ CategoryTheory.Over.forget X).map f = f.left := rfl
393+
390394
variable {P Q X}
391395

392396
/-- Construct a morphism in `P.Over Q X` from a morphism in `Over.X`. -/
@@ -448,6 +452,10 @@ protected abbrev Under.forget : P.Under Q X ⥤ Under X :=
448452
instance : (Under.forget P ⊤ X).Faithful := inferInstanceAs <| (Comma.forget _ _ _ _ _).Faithful
449453
instance : (Under.forget P ⊤ X).Full := inferInstanceAs <| (Comma.forget _ _ _ _ _).Full
450454

455+
/-- Occasionally useful for rewriting in the backwards direction. -/
456+
lemma Under.forget_comp_forget_map {A B : P.Under Q X} (f : A ⟶ B) :
457+
(MorphismProperty.Under.forget P Q X ⋙ CategoryTheory.Under.forget X).map f = f.right := rfl
458+
451459
variable {P Q X}
452460

453461
/-- Construct a morphism in `P.Under Q X` from a morphism in `Under.X`. -/

0 commit comments

Comments
 (0)