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

Commit e83ba8f

Browse files
committed
feat(category_theory/limits/shapes/diagonal): The diagonal object of a morphism. (#15711)
Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com>
1 parent b604119 commit e83ba8f

File tree

2 files changed

+408
-0
lines changed

2 files changed

+408
-0
lines changed
Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
/-
2+
Copyright (c) 2022 Andrew Yang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Andrew Yang
5+
-/
6+
import category_theory.limits.shapes.pullbacks
7+
import category_theory.limits.shapes.kernel_pair
8+
import category_theory.limits.shapes.comm_sq
9+
10+
/-!
11+
# The diagonal object of a morphism.
12+
13+
We provide various API and isomorphisms considering the diagonal object `Δ_{Y/X} := pullback f f`
14+
of a morphism `f : X ⟶ Y`.
15+
16+
-/
17+
18+
open category_theory
19+
20+
noncomputable theory
21+
22+
namespace category_theory.limits
23+
24+
variables {C : Type*} [category C] {X Y Z : C}
25+
26+
namespace pullback
27+
28+
section diagonal
29+
30+
variables (f : X ⟶ Y) [has_pullback f f]
31+
32+
/-- The diagonal object of a morphism `f : X ⟶ Y` is `Δ_{X/Y} := pullback f f`. -/
33+
abbreviation diagonal_obj : C := pullback f f
34+
35+
/-- The diagonal morphism `X ⟶ Δ_{X/Y}` for a morphism `f : X ⟶ Y`. -/
36+
def diagonal : X ⟶ diagonal_obj f :=
37+
pullback.lift (𝟙 _) (𝟙 _) rfl
38+
39+
@[simp, reassoc] lemma diagonal_fst : diagonal f ≫ pullback.fst = 𝟙 _ :=
40+
pullback.lift_fst _ _ _
41+
42+
@[simp, reassoc] lemma diagonal_snd : diagonal f ≫ pullback.snd = 𝟙 _ :=
43+
pullback.lift_snd _ _ _
44+
45+
instance : is_split_mono (diagonal f) :=
46+
⟨⟨⟨pullback.fst, diagonal_fst f⟩⟩⟩
47+
48+
instance : is_split_epi (pullback.fst : pullback f f ⟶ X) :=
49+
⟨⟨⟨diagonal f, diagonal_fst f⟩⟩⟩
50+
51+
instance : is_split_epi (pullback.snd : pullback f f ⟶ X) :=
52+
⟨⟨⟨diagonal f, diagonal_snd f⟩⟩⟩
53+
54+
instance [mono f] : is_iso (diagonal f) :=
55+
begin
56+
rw (is_iso.inv_eq_of_inv_hom_id (diagonal_fst f)).symm,
57+
apply_instance
58+
end
59+
60+
/-- The two projections `Δ_{X/Y} ⟶ X` form a kernel pair for `f : X ⟶ Y`. -/
61+
def diagonal_is_kernel_pair :
62+
is_kernel_pair f (pullback.fst : diagonal_obj f ⟶ _) pullback.snd :=
63+
⟨pullback.condition, pullback_is_pullback _ _⟩
64+
65+
end diagonal
66+
67+
end pullback
68+
69+
variable [has_pullbacks C]
70+
71+
open pullback
72+
73+
section
74+
75+
variables {U V₁ V₂ : C} (f : X ⟶ Y) (i : U ⟶ Y)
76+
variables (i₁ : V₁ ⟶ pullback f i) (i₂ : V₂ ⟶ pullback f i)
77+
78+
@[simp, reassoc]
79+
lemma pullback_diagonal_map_snd_fst_fst :
80+
(pullback.snd : pullback (diagonal f) (map (i₁ ≫ snd) (i₂ ≫ snd) f f (i₁ ≫ fst) (i₂ ≫ fst) i
81+
(by simp [condition]) (by simp [condition])) ⟶ _) ≫ fst ≫ i₁ ≫ fst = pullback.fst :=
82+
begin
83+
conv_rhs { rw ← category.comp_id pullback.fst },
84+
rw [← diagonal_fst f, pullback.condition_assoc, pullback.lift_fst]
85+
end
86+
87+
@[simp, reassoc]
88+
lemma pullback_diagonal_map_snd_snd_fst :
89+
(pullback.snd : pullback (diagonal f) (map (i₁ ≫ snd) (i₂ ≫ snd) f f (i₁ ≫ fst) (i₂ ≫ fst) i
90+
(by simp [condition]) (by simp [condition])) ⟶ _) ≫ snd ≫ i₂ ≫ fst = pullback.fst :=
91+
begin
92+
conv_rhs { rw ← category.comp_id pullback.fst },
93+
rw [← diagonal_snd f, pullback.condition_assoc, pullback.lift_snd]
94+
end
95+
96+
variable [has_pullback i₁ i₂]
97+
98+
/--
99+
This iso witnesses the fact that
100+
given `f : X ⟶ Y`, `i : U ⟶ Y`, and `i₁ : V₁ ⟶ X ×[Y] U`, `i₂ : V₂ ⟶ X ×[Y] U`, the diagram
101+
102+
V₁ ×[X ×[Y] U] V₂ ⟶ V₁ ×[U] V₂
103+
| |
104+
| |
105+
↓ ↓
106+
X ⟶ X ×[Y] X
107+
108+
is a pullback square.
109+
Also see `pullback_fst_map_snd_is_pullback`.
110+
-/
111+
def pullback_diagonal_map_iso :
112+
pullback (diagonal f) (map (i₁ ≫ snd) (i₂ ≫ snd) f f (i₁ ≫ fst) (i₂ ≫ fst) i
113+
(by simp [condition]) (by simp [condition])) ≅ pullback i₁ i₂ :=
114+
{ hom := pullback.lift (pullback.snd ≫ pullback.fst) (pullback.snd ≫ pullback.snd)
115+
begin
116+
ext; simp only [category.assoc, pullback.condition, pullback_diagonal_map_snd_fst_fst,
117+
pullback_diagonal_map_snd_snd_fst],
118+
end,
119+
inv := pullback.lift (pullback.fst ≫ i₁ ≫ pullback.fst) (pullback.map _ _ _ _ (𝟙 _) (𝟙 _)
120+
pullback.snd (category.id_comp _).symm (category.id_comp _).symm)
121+
begin
122+
ext; simp only [diagonal_fst, diagonal_snd, category.comp_id, pullback.condition_assoc,
123+
category.assoc, lift_fst, lift_fst_assoc, lift_snd, lift_snd_assoc],
124+
end,
125+
hom_inv_id' := by ext; simp only [category.id_comp, category.assoc, lift_fst_assoc,
126+
pullback_diagonal_map_snd_fst_fst, lift_fst, lift_snd, category.comp_id],
127+
inv_hom_id' := by ext; simp }
128+
129+
@[simp, reassoc]
130+
lemma pullback_diagonal_map_iso_hom_fst :
131+
(pullback_diagonal_map_iso f i i₁ i₂).hom ≫ pullback.fst = pullback.snd ≫ pullback.fst :=
132+
by { delta pullback_diagonal_map_iso, simp }
133+
134+
@[simp, reassoc]
135+
lemma pullback_diagonal_map_iso_hom_snd :
136+
(pullback_diagonal_map_iso f i i₁ i₂).hom ≫ pullback.snd = pullback.snd ≫ pullback.snd :=
137+
by { delta pullback_diagonal_map_iso, simp }
138+
139+
@[simp, reassoc]
140+
lemma pullback_diagonal_map_iso_inv_fst :
141+
(pullback_diagonal_map_iso f i i₁ i₂).inv ≫ pullback.fst = pullback.fst ≫ i₁ ≫ pullback.fst :=
142+
by { delta pullback_diagonal_map_iso, simp }
143+
144+
@[simp, reassoc]
145+
lemma pullback_diagonal_map_iso_inv_snd_fst :
146+
(pullback_diagonal_map_iso f i i₁ i₂).inv ≫ pullback.snd ≫ pullback.fst = pullback.fst :=
147+
by { delta pullback_diagonal_map_iso, simp }
148+
149+
@[simp, reassoc]
150+
lemma pullback_diagonal_map_iso_inv_snd_snd :
151+
(pullback_diagonal_map_iso f i i₁ i₂).inv ≫ pullback.snd ≫ pullback.snd = pullback.snd :=
152+
by { delta pullback_diagonal_map_iso, simp }
153+
154+
lemma pullback_fst_map_snd_is_pullback :
155+
is_pullback
156+
(fst ≫ i₁ ≫ fst)
157+
(map i₁ i₂ (i₁ ≫ snd) (i₂ ≫ snd) _ _ _ (category.id_comp _).symm (category.id_comp _).symm)
158+
(diagonal f)
159+
(map (i₁ ≫ snd) (i₂ ≫ snd) f f (i₁ ≫ fst) (i₂ ≫ fst) i
160+
(by simp [condition]) (by simp [condition])) :=
161+
is_pullback.of_iso_pullback ⟨by ext; simp [condition_assoc]⟩
162+
(pullback_diagonal_map_iso f i i₁ i₂).symm (pullback_diagonal_map_iso_inv_fst f i i₁ i₂)
163+
(by ext1; simp)
164+
165+
end
166+
167+
section
168+
169+
variables {S T : C} (f : X ⟶ T) (g : Y ⟶ T) (i : T ⟶ S)
170+
variables [has_pullback i i] [has_pullback f g] [has_pullback (f ≫ i) (g ≫ i)]
171+
variable [has_pullback (diagonal i) (pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 _)
172+
(category.comp_id _) (category.comp_id _))]
173+
174+
/--
175+
This iso witnesses the fact that
176+
given `f : X ⟶ T`, `g : Y ⟶ T`, and `i : T ⟶ S`, the diagram
177+
178+
X ×ₜ Y ⟶ X ×ₛ Y
179+
| |
180+
| |
181+
↓ ↓
182+
T ⟶ T ×ₛ T
183+
184+
is a pullback square.
185+
Also see `pullback_map_diagonal_is_pullback`.
186+
-/
187+
def pullback_diagonal_map_id_iso :
188+
pullback (diagonal i) (pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 _)
189+
(category.comp_id _) (category.comp_id _)) ≅ pullback f g :=
190+
begin
191+
refine (as_iso $ pullback.map _ _ _ _ (𝟙 _) (pullback.congr_hom _ _).hom (𝟙 _) _ _) ≪≫
192+
pullback_diagonal_map_iso i (𝟙 _) (f ≫ inv pullback.fst) (g ≫ inv pullback.fst) ≪≫
193+
(as_iso $ pullback.map _ _ _ _ (𝟙 _) (𝟙 _) pullback.fst _ _),
194+
{ rw [← category.comp_id pullback.snd, ← condition, category.assoc, is_iso.inv_hom_id_assoc] },
195+
{ rw [← category.comp_id pullback.snd, ← condition, category.assoc, is_iso.inv_hom_id_assoc] },
196+
{ rw [category.comp_id, category.id_comp] },
197+
{ ext; simp },
198+
{ apply_instance },
199+
{ rw [category.assoc, category.id_comp, is_iso.inv_hom_id, category.comp_id] },
200+
{ rw [category.assoc, category.id_comp, is_iso.inv_hom_id, category.comp_id] },
201+
{ apply_instance },
202+
end
203+
204+
@[simp, reassoc]
205+
lemma pullback_diagonal_map_id_iso_hom_fst :
206+
(pullback_diagonal_map_id_iso f g i).hom ≫ pullback.fst = pullback.snd ≫ pullback.fst :=
207+
by { delta pullback_diagonal_map_id_iso, simp }
208+
209+
@[simp, reassoc]
210+
lemma pullback_diagonal_map_id_iso_hom_snd :
211+
(pullback_diagonal_map_id_iso f g i).hom ≫ pullback.snd = pullback.snd ≫ pullback.snd :=
212+
by { delta pullback_diagonal_map_id_iso, simp }
213+
214+
@[simp, reassoc]
215+
lemma pullback_diagonal_map_id_iso_inv_fst :
216+
(pullback_diagonal_map_id_iso f g i).inv ≫ pullback.fst = pullback.fst ≫ f :=
217+
begin
218+
rw [iso.inv_comp_eq, ← category.comp_id pullback.fst, ← diagonal_fst i, pullback.condition_assoc],
219+
simp,
220+
end
221+
222+
@[simp, reassoc]
223+
lemma pullback_diagonal_map_id_iso_inv_snd_fst :
224+
(pullback_diagonal_map_id_iso f g i).inv ≫ pullback.snd ≫ pullback.fst = pullback.fst :=
225+
by { rw iso.inv_comp_eq, simp }
226+
227+
@[simp, reassoc]
228+
lemma pullback_diagonal_map_id_iso_inv_snd_snd :
229+
(pullback_diagonal_map_id_iso f g i).inv ≫ pullback.snd ≫ pullback.snd = pullback.snd :=
230+
by { rw iso.inv_comp_eq, simp }
231+
232+
lemma pullback.diagonal_comp (f : X ⟶ Y) (g : Y ⟶ Z) [has_pullback f f] [has_pullback g g]
233+
[has_pullback (f ≫ g) (f ≫ g)] :
234+
diagonal (f ≫ g) = diagonal f ≫ (pullback_diagonal_map_id_iso f f g).inv ≫ pullback.snd :=
235+
by ext; simp
236+
237+
lemma pullback_map_diagonal_is_pullback : is_pullback (pullback.fst ≫ f)
238+
(pullback.map f g (f ≫ i) (g ≫ i) _ _ i (category.id_comp _).symm (category.id_comp _).symm)
239+
(diagonal i)
240+
(pullback.map (f ≫ i) (g ≫ i) i i f g (𝟙 _) (category.comp_id _) (category.comp_id _)) :=
241+
begin
242+
apply is_pullback.of_iso_pullback _ (pullback_diagonal_map_id_iso f g i).symm,
243+
{ simp },
244+
{ ext; simp },
245+
{ constructor, ext; simp [condition] },
246+
end
247+
248+
/-- The diagonal object of `X ×[Z] Y ⟶ X` is isomorphic to `Δ_{Y/Z} ×[Z] X`. -/
249+
def diagonal_obj_pullback_fst_iso {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
250+
diagonal_obj (pullback.fst : pullback f g ⟶ X) ≅
251+
pullback (pullback.snd ≫ g : diagonal_obj g ⟶ Z) f :=
252+
pullback_right_pullback_fst_iso _ _ _ ≪≫ pullback.congr_hom pullback.condition rfl ≪≫
253+
pullback_assoc _ _ _ _ ≪≫ pullback_symmetry _ _ ≪≫ pullback.congr_hom pullback.condition rfl
254+
255+
@[simp, reassoc] lemma diagonal_obj_pullback_fst_iso_hom_fst_fst {X Y Z : C} (f : X ⟶ Z)
256+
(g : Y ⟶ Z) :
257+
(diagonal_obj_pullback_fst_iso f g).hom ≫ pullback.fst ≫ pullback.fst =
258+
pullback.fst ≫ pullback.snd :=
259+
by { delta diagonal_obj_pullback_fst_iso, simp }
260+
261+
@[simp, reassoc] lemma diagonal_obj_pullback_fst_iso_hom_fst_snd {X Y Z : C} (f : X ⟶ Z)
262+
(g : Y ⟶ Z) :
263+
(diagonal_obj_pullback_fst_iso f g).hom ≫ pullback.fst ≫ pullback.snd =
264+
pullback.snd ≫ pullback.snd :=
265+
by { delta diagonal_obj_pullback_fst_iso, simp }
266+
267+
@[simp, reassoc] lemma diagonal_obj_pullback_fst_iso_hom_snd {X Y Z : C} (f : X ⟶ Z)
268+
(g : Y ⟶ Z) :
269+
(diagonal_obj_pullback_fst_iso f g).hom ≫ pullback.snd = pullback.fst ≫ pullback.fst :=
270+
by { delta diagonal_obj_pullback_fst_iso, simp }
271+
272+
@[simp, reassoc] lemma diagonal_obj_pullback_fst_iso_inv_fst_fst {X Y Z : C} (f : X ⟶ Z)
273+
(g : Y ⟶ Z) :
274+
(diagonal_obj_pullback_fst_iso f g).inv ≫ pullback.fst ≫ pullback.fst =
275+
pullback.snd :=
276+
by { delta diagonal_obj_pullback_fst_iso, simp }
277+
278+
@[simp, reassoc] lemma diagonal_obj_pullback_fst_iso_inv_fst_snd {X Y Z : C} (f : X ⟶ Z)
279+
(g : Y ⟶ Z) :
280+
(diagonal_obj_pullback_fst_iso f g).inv ≫ pullback.fst ≫ pullback.snd =
281+
pullback.fst ≫ pullback.fst :=
282+
by { delta diagonal_obj_pullback_fst_iso, simp }
283+
284+
@[simp, reassoc] lemma diagonal_obj_pullback_fst_iso_inv_snd_fst {X Y Z : C} (f : X ⟶ Z)
285+
(g : Y ⟶ Z) :
286+
(diagonal_obj_pullback_fst_iso f g).inv ≫ pullback.snd ≫ pullback.fst = pullback.snd :=
287+
by { delta diagonal_obj_pullback_fst_iso, simp }
288+
289+
@[simp, reassoc] lemma diagonal_obj_pullback_fst_iso_inv_snd_snd {X Y Z : C} (f : X ⟶ Z)
290+
(g : Y ⟶ Z) :
291+
(diagonal_obj_pullback_fst_iso f g).inv ≫ pullback.snd ≫ pullback.snd =
292+
pullback.fst ≫ pullback.snd :=
293+
by { delta diagonal_obj_pullback_fst_iso, simp }
294+
295+
lemma diagonal_pullback_fst {X Y Z : C} (f : X ⟶ Z) (g : Y ⟶ Z) :
296+
diagonal (pullback.fst : pullback f g ⟶ _) =
297+
(pullback_symmetry _ _).hom ≫ ((base_change f).map
298+
(over.hom_mk (diagonal g) (by simp) : over.mk g ⟶ over.mk (pullback.snd ≫ g))).left ≫
299+
(diagonal_obj_pullback_fst_iso f g).inv :=
300+
by ext; simp
301+
302+
end
303+
304+
/--
305+
Given the following diagram with `S ⟶ S'` a monomorphism,
306+
307+
X ⟶ X'
308+
↘ ↘
309+
S ⟶ S'
310+
↗ ↗
311+
Y ⟶ Y'
312+
313+
This iso witnesses the fact that
314+
315+
X ×[S] Y ⟶ (X' ×[S'] Y') ×[Y'] Y
316+
| |
317+
| |
318+
↓ ↓
319+
(X' ×[S'] Y') ×[X'] X ⟶ X' ×[S'] Y'
320+
321+
is a pullback square. The diagonal map of this square is `pullback.map`.
322+
Also see `pullback_lift_map_is_pullback`.
323+
-/
324+
@[simps]
325+
def pullback_fst_fst_iso {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S) (f' : X' ⟶ S')
326+
(g' : Y' ⟶ S') (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S') (e₁ : f ≫ i₃ = i₁ ≫ f')
327+
(e₂ : g ≫ i₃ = i₂ ≫ g') [mono i₃] :
328+
pullback (pullback.fst : pullback (pullback.fst : pullback f' g' ⟶ _) i₁ ⟶ _)
329+
(pullback.fst : pullback (pullback.snd : pullback f' g' ⟶ _) i₂ ⟶ _) ≅ pullback f g :=
330+
{ hom := pullback.lift (pullback.fst ≫ pullback.snd) (pullback.snd ≫ pullback.snd)
331+
begin
332+
rw [← cancel_mono i₃, category.assoc, category.assoc, category.assoc, category.assoc, e₁, e₂,
333+
← pullback.condition_assoc, pullback.condition_assoc, pullback.condition,
334+
pullback.condition_assoc]
335+
end,
336+
inv := pullback.lift
337+
(pullback.lift (pullback.map _ _ _ _ _ _ _ e₁ e₂) pullback.fst (pullback.lift_fst _ _ _))
338+
(pullback.lift (pullback.map _ _ _ _ _ _ _ e₁ e₂) pullback.snd (pullback.lift_snd _ _ _))
339+
begin
340+
rw [pullback.lift_fst, pullback.lift_fst]
341+
end,
342+
hom_inv_id' := by ext; simp only [category.assoc, category.id_comp, lift_fst, lift_snd,
343+
lift_fst_assoc, lift_snd_assoc, condition, ← condition_assoc],
344+
inv_hom_id' := by ext; simp only [category.assoc, category.id_comp, lift_fst, lift_snd,
345+
lift_fst_assoc, lift_snd_assoc], }
346+
347+
lemma pullback_map_eq_pullback_fst_fst_iso_inv {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S)
348+
(f' : X' ⟶ S')
349+
(g' : Y' ⟶ S') (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S') (e₁ : f ≫ i₃ = i₁ ≫ f')
350+
(e₂ : g ≫ i₃ = i₂ ≫ g') [mono i₃] :
351+
pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂ =
352+
(pullback_fst_fst_iso f g f' g' i₁ i₂ i₃ e₁ e₂).inv ≫ pullback.snd ≫ pullback.fst :=
353+
begin
354+
ext; simp only [category.assoc, category.id_comp, lift_fst, lift_snd, lift_fst_assoc,
355+
lift_snd_assoc, pullback_fst_fst_iso_inv, ← pullback.condition, ← pullback.condition_assoc],
356+
end
357+
358+
lemma pullback_lift_map_is_pullback {X Y S X' Y' S' : C} (f : X ⟶ S) (g : Y ⟶ S) (f' : X' ⟶ S')
359+
(g' : Y' ⟶ S') (i₁ : X ⟶ X') (i₂ : Y ⟶ Y') (i₃ : S ⟶ S') (e₁ : f ≫ i₃ = i₁ ≫ f')
360+
(e₂ : g ≫ i₃ = i₂ ≫ g') [mono i₃] :
361+
is_pullback
362+
(pullback.lift (pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂) fst (lift_fst _ _ _))
363+
(pullback.lift (pullback.map f g f' g' i₁ i₂ i₃ e₁ e₂) snd (lift_snd _ _ _))
364+
pullback.fst pullback.fst :=
365+
is_pullback.of_iso_pullback ⟨by rw [lift_fst, lift_fst]⟩
366+
(pullback_fst_fst_iso f g f' g' i₁ i₂ i₃ e₁ e₂).symm (by simp) (by simp)
367+
368+
369+
end category_theory.limits

0 commit comments

Comments
 (0)