Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 52a270e

Browse files
committed
feat(category_theory/limits): bicartesian squares (#14375)
``` X ⊞ Y --fst--> X | | snd 0 | | v v Y Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent ae17d05 commit 52a270e

File tree

3 files changed

+473
-14
lines changed

3 files changed

+473
-14
lines changed
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
/-
2+
Copyright (c) 2022 Scott Morrison. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Scott Morrison
5+
-/
6+
import category_theory.limits.shapes.pullbacks
7+
import category_theory.limits.shapes.zero_morphisms
8+
import category_theory.limits.constructions.binary_products
9+
10+
/-!
11+
# Limits involving zero objects
12+
13+
Binary products and coproducts with a zero object always exist,
14+
and pullbacks/pushouts over a zero object are products/coproducts.
15+
-/
16+
17+
noncomputable theory
18+
19+
open category_theory
20+
21+
variables {C : Type*} [category C]
22+
23+
namespace category_theory.limits
24+
25+
variables [has_zero_object C] [has_zero_morphisms C]
26+
open_locale zero_object
27+
28+
/-- The limit cone for the product with a zero object. -/
29+
def binary_fan_zero_left (X : C) : binary_fan (0 : C) X :=
30+
binary_fan.mk 0 (𝟙 X)
31+
32+
/-- The limit cone for the product with a zero object is limiting. -/
33+
def binary_fan_zero_left_is_limit (X : C) : is_limit (binary_fan_zero_left X) :=
34+
binary_fan.is_limit_mk (λ s, binary_fan.snd s) (by tidy) (by tidy) (by tidy)
35+
36+
instance has_binary_product_zero_left (X : C) : has_binary_product (0 : C) X :=
37+
has_limit.mk ⟨_, binary_fan_zero_left_is_limit X⟩
38+
39+
/-- A zero object is a left unit for categorical product. -/
40+
def zero_prod_iso (X : C) : (0 : C) ⨯ X ≅ X :=
41+
limit.iso_limit_cone ⟨_, binary_fan_zero_left_is_limit X⟩
42+
43+
@[simp] lemma zero_prod_iso_hom (X : C) : (zero_prod_iso X).hom = prod.snd :=
44+
rfl
45+
@[simp] lemma zero_prod_iso_inv_snd (X : C) : (zero_prod_iso X).inv ≫ prod.snd = 𝟙 X :=
46+
by { dsimp [zero_prod_iso, binary_fan_zero_left], simp, }
47+
48+
/-- The limit cone for the product with a zero object. -/
49+
def binary_fan_zero_right (X : C) : binary_fan X (0 : C) :=
50+
binary_fan.mk (𝟙 X) 0
51+
52+
/-- The limit cone for the product with a zero object is limiting. -/
53+
def binary_fan_zero_right_is_limit (X : C) : is_limit (binary_fan_zero_right X) :=
54+
binary_fan.is_limit_mk (λ s, binary_fan.fst s) (by tidy) (by tidy) (by tidy)
55+
56+
instance has_binary_product_zero_right (X : C) : has_binary_product X (0 : C) :=
57+
has_limit.mk ⟨_, binary_fan_zero_right_is_limit X⟩
58+
59+
/-- A zero object is a right unit for categorical product. -/
60+
def prod_zero_iso (X : C) : X ⨯ (0 : C) ≅ X :=
61+
limit.iso_limit_cone ⟨_, binary_fan_zero_right_is_limit X⟩
62+
63+
@[simp] lemma prod_zero_iso_hom (X : C) : (prod_zero_iso X).hom = prod.fst :=
64+
rfl
65+
@[simp] lemma prod_zero_iso_iso_inv_snd (X : C) : (prod_zero_iso X).inv ≫ prod.fst = 𝟙 X :=
66+
by { dsimp [prod_zero_iso, binary_fan_zero_right], simp, }
67+
68+
/-- The colimit cocone for the coproduct with a zero object. -/
69+
def binary_cofan_zero_left (X : C) : binary_cofan (0 : C) X :=
70+
binary_cofan.mk 0 (𝟙 X)
71+
72+
/-- The colimit cocone for the coproduct with a zero object is colimiting. -/
73+
def binary_cofan_zero_left_is_colimit (X : C) : is_colimit (binary_cofan_zero_left X) :=
74+
binary_cofan.is_colimit_mk (λ s, binary_cofan.inr s) (by tidy) (by tidy) (by tidy)
75+
76+
instance has_binary_coproduct_zero_left (X : C) : has_binary_coproduct (0 : C) X :=
77+
has_colimit.mk ⟨_, binary_cofan_zero_left_is_colimit X⟩
78+
79+
/-- A zero object is a left unit for categorical coproduct. -/
80+
def zero_coprod_iso (X : C) : (0 : C) ⨿ X ≅ X :=
81+
colimit.iso_colimit_cocone ⟨_, binary_cofan_zero_left_is_colimit X⟩
82+
83+
@[simp] lemma inr_zero_coprod_iso_hom (X : C) : coprod.inr ≫ (zero_coprod_iso X).hom = 𝟙 X :=
84+
by { dsimp [zero_coprod_iso, binary_cofan_zero_left], simp, }
85+
@[simp] lemma zero_coprod_iso_inv (X : C) : (zero_coprod_iso X).inv = coprod.inr :=
86+
rfl
87+
88+
/-- The colimit cocone for the coproduct with a zero object. -/
89+
def binary_cofan_zero_right (X : C) : binary_cofan X (0 : C) :=
90+
binary_cofan.mk (𝟙 X) 0
91+
92+
/-- The colimit cocone for the coproduct with a zero object is colimiting. -/
93+
def binary_cofan_zero_right_is_colimit (X : C) : is_colimit (binary_cofan_zero_right X) :=
94+
binary_cofan.is_colimit_mk (λ s, binary_cofan.inl s) (by tidy) (by tidy) (by tidy)
95+
96+
instance has_binary_coproduct_zero_right (X : C) : has_binary_coproduct X (0 : C) :=
97+
has_colimit.mk ⟨_, binary_cofan_zero_right_is_colimit X⟩
98+
99+
/-- A zero object is a right unit for categorical coproduct. -/
100+
def coprod_zero_iso (X : C) : X ⨿ (0 : C) ≅ X :=
101+
colimit.iso_colimit_cocone ⟨_, binary_cofan_zero_right_is_colimit X⟩
102+
103+
@[simp] lemma inr_coprod_zeroiso_hom (X : C) : coprod.inl ≫ (coprod_zero_iso X).hom = 𝟙 X :=
104+
by { dsimp [coprod_zero_iso, binary_cofan_zero_right], simp, }
105+
@[simp] lemma coprod_zero_iso_inv (X : C) : (coprod_zero_iso X).inv = coprod.inl :=
106+
rfl
107+
108+
instance has_pullback_over_zero
109+
(X Y : C) [has_binary_product X Y] : has_pullback (0 : X ⟶ 0) (0 : Y ⟶ 0) :=
110+
has_limit.mk ⟨_, is_pullback_of_is_terminal_is_product _ _ _ _
111+
has_zero_object.zero_is_terminal (prod_is_prod X Y)⟩
112+
113+
/-- The pullback over the zeron object is the product. -/
114+
def pullback_zero_zero_iso (X Y : C) [has_binary_product X Y] :
115+
pullback (0 : X ⟶ 0) (0 : Y ⟶ 0) ≅ X ⨯ Y :=
116+
limit.iso_limit_cone ⟨_, is_pullback_of_is_terminal_is_product _ _ _ _
117+
has_zero_object.zero_is_terminal (prod_is_prod X Y)⟩
118+
119+
@[simp] lemma pullback_zero_zero_iso_inv_fst (X Y : C) [has_binary_product X Y] :
120+
(pullback_zero_zero_iso X Y).inv ≫ pullback.fst = prod.fst :=
121+
by { dsimp [pullback_zero_zero_iso], simp, }
122+
@[simp] lemma pullback_zero_zero_iso_inv_snd (X Y : C) [has_binary_product X Y] :
123+
(pullback_zero_zero_iso X Y).inv ≫ pullback.snd = prod.snd :=
124+
by { dsimp [pullback_zero_zero_iso], simp, }
125+
@[simp] lemma pullback_zero_zero_iso_hom_fst (X Y : C) [has_binary_product X Y] :
126+
(pullback_zero_zero_iso X Y).hom ≫ prod.fst = pullback.fst :=
127+
by { simp [←iso.eq_inv_comp], }
128+
@[simp] lemma pullback_zero_zero_iso_hom_snd (X Y : C) [has_binary_product X Y] :
129+
(pullback_zero_zero_iso X Y).hom ≫ prod.snd = pullback.snd :=
130+
by { simp [←iso.eq_inv_comp], }
131+
132+
instance has_pushout_over_zero
133+
(X Y : C) [has_binary_coproduct X Y] : has_pushout (0 : 0 ⟶ X) (0 : 0 ⟶ Y) :=
134+
has_colimit.mk ⟨_, is_pushout_of_is_initial_is_coproduct _ _ _ _
135+
has_zero_object.zero_is_initial (coprod_is_coprod X Y)⟩
136+
137+
/-- The pushout over the zero object is the coproduct. -/
138+
def pushout_zero_zero_iso
139+
(X Y : C) [has_binary_coproduct X Y] : pushout (0 : 0 ⟶ X) (0 : 0 ⟶ Y) ≅ X ⨿ Y :=
140+
colimit.iso_colimit_cocone ⟨_, is_pushout_of_is_initial_is_coproduct _ _ _ _
141+
has_zero_object.zero_is_initial (coprod_is_coprod X Y)⟩
142+
143+
@[simp] lemma inl_pushout_zero_zero_iso_hom (X Y : C) [has_binary_coproduct X Y] :
144+
pushout.inl ≫ (pushout_zero_zero_iso X Y).hom = coprod.inl :=
145+
by { dsimp [pushout_zero_zero_iso], simp, }
146+
@[simp] lemma inr_pushout_zero_zero_iso_hom (X Y : C) [has_binary_coproduct X Y] :
147+
pushout.inr ≫ (pushout_zero_zero_iso X Y).hom = coprod.inr :=
148+
by { dsimp [pushout_zero_zero_iso], simp, }
149+
@[simp] lemma inl_pushout_zero_zero_iso_inv (X Y : C) [has_binary_coproduct X Y] :
150+
coprod.inl ≫ (pushout_zero_zero_iso X Y).inv = pushout.inl :=
151+
by { simp [iso.comp_inv_eq], }
152+
@[simp] lemma inr_pushout_zero_zero_iso_inv (X Y : C) [has_binary_coproduct X Y] :
153+
coprod.inr ≫ (pushout_zero_zero_iso X Y).inv = pushout.inr :=
154+
by { simp [iso.comp_inv_eq], }
155+
156+
end category_theory.limits

src/category_theory/limits/shapes/binary_products.lean

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,36 @@ cones.ext (iso.refl _) (λ j, by discrete_cases; cases j; tidy)
219219
def iso_binary_cofan_mk {X Y : C} (c : binary_cofan X Y) : c ≅ binary_cofan.mk c.inl c.inr :=
220220
cocones.ext (iso.refl _) (λ j, by discrete_cases; cases j; tidy)
221221

222+
/--
223+
This is a more convenient formulation to show that a `binary_fan` constructed using
224+
`binary_fan.mk` is a limit cone.
225+
-/
226+
def binary_fan.is_limit_mk {W : C} {fst : W ⟶ X} {snd : W ⟶ Y}
227+
(lift : Π (s : binary_fan X Y), s.X ⟶ W)
228+
(fac_left : ∀ (s : binary_fan X Y), lift s ≫ fst = s.fst)
229+
(fac_right : ∀ (s : binary_fan X Y), lift s ≫ snd = s.snd)
230+
(uniq : ∀ (s : binary_fan X Y) (m : s.X ⟶ W)
231+
(w_fst : m ≫ fst = s.fst) (w_snd : m ≫ snd = s.snd), m = lift s) :
232+
is_limit (binary_fan.mk fst snd) :=
233+
{ lift := lift,
234+
fac' := λ s j, by { rcases j with ⟨⟨⟩⟩, exacts [fac_left s, fac_right s], },
235+
uniq' := λ s m w, uniq s m (w ⟨walking_pair.left⟩) (w ⟨walking_pair.right⟩) }
236+
237+
/--
238+
This is a more convenient formulation to show that a `binary_cofan` constructed using
239+
`binary_cofan.mk` is a colimit cocone.
240+
-/
241+
def binary_cofan.is_colimit_mk {W : C} {inl : X ⟶ W} {inr : Y ⟶ W}
242+
(desc : Π (s : binary_cofan X Y), W ⟶ s.X)
243+
(fac_left : ∀ (s : binary_cofan X Y), inl ≫ desc s = s.inl)
244+
(fac_right : ∀ (s : binary_cofan X Y), inr ≫ desc s = s.inr)
245+
(uniq : ∀ (s : binary_cofan X Y) (m : W ⟶ s.X)
246+
(w_inl : inl ≫ m = s.inl) (w_inr : inr ≫ m = s.inr), m = desc s) :
247+
is_colimit (binary_cofan.mk inl inr) :=
248+
{ desc := desc,
249+
fac' := λ s j, by { rcases j with ⟨⟨⟩⟩, exacts [fac_left s, fac_right s], },
250+
uniq' := λ s m w, uniq s m (w ⟨walking_pair.left⟩) (w ⟨walking_pair.right⟩) }
251+
222252
/-- If `s` is a limit binary fan over `X` and `Y`, then every pair of morphisms `f : W ⟶ X` and
223253
`g : W ⟶ Y` induces a morphism `l : W ⟶ s.X` satisfying `l ≫ s.fst = f` and `l ≫ s.snd = g`.
224254
-/

0 commit comments

Comments
 (0)