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

Commit 7cd67b5

Browse files
committed
feat(category_theory/limits/shapes/terminal): is_terminal object (#3957)
Add language to talk about when an object is terminal, and generalise some results to use this
1 parent fc57cf4 commit 7cd67b5

File tree

2 files changed

+84
-23
lines changed

2 files changed

+84
-23
lines changed

src/category_theory/closed/cartesian.lean

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -240,33 +240,33 @@ def internal_hom [cartesian_closed C] : C ⥤ Cᵒᵖ ⥤ C :=
240240
map_id' := λ X, by { ext, apply functor.map_id },
241241
map_comp' := λ X Y Z f g, by { ext, apply functor.map_comp } }
242242

243-
/-- If an initial object `0` exists in a CCC, then `A ⨯ 00`. -/
243+
/-- If an initial object `I` exists in a CCC, then `A ⨯ II`. -/
244244
@[simps]
245-
def zero_mul [has_initial C] : A ⨯ ⊥_ C ≅ ⊥_ C :=
245+
def zero_mul {I : C} (t : is_initial I) : A ⨯ I ≅ I :=
246246
{ hom := limits.prod.snd,
247-
inv := default (⊥_ C ⟶ A ⨯ ⊥_ C),
247+
inv := t.to _,
248248
hom_inv_id' :=
249249
begin
250-
have: (limits.prod.snd : A ⨯ ⊥_ C ⟶ ⊥_ C) = uncurry (default _),
250+
have: (limits.prod.snd : A ⨯ I ⟶ I) = uncurry (t.to _),
251251
rw ← curry_eq_iff,
252-
apply subsingleton.elim,
252+
apply t.hom_ext,
253253
rw [this, ← uncurry_natural_right, ← eq_curry_iff],
254-
apply subsingleton.elim
254+
apply t.hom_ext,
255255
end,
256-
}
256+
inv_hom_id' := t.hom_ext _ _ }
257257

258258
/-- If an initial object `0` exists in a CCC, then `0 ⨯ A ≅ 0`. -/
259-
def mul_zero [has_initial C] : ⊥_ C ⨯ A ≅ ⊥_ C :=
260-
limits.prod.braiding _ _ ≪≫ zero_mul
259+
def mul_zero {I : C} (t : is_initial I) : I ⨯ A ≅ I :=
260+
limits.prod.braiding _ _ ≪≫ zero_mul t
261261

262262
/-- If an initial object `0` exists in a CCC then `0^B ≅ 1` for any `B`. -/
263-
def pow_zero [has_initial C] [cartesian_closed C] : ⊥_C ⟹ B ≅ ⊤_ C :=
263+
def pow_zero {I : C} (t : is_initial I) [cartesian_closed C] : I ⟹ B ≅ ⊤_ C :=
264264
{ hom := default _,
265-
inv := curry (mul_zero.hom ≫ default (⊥_ C ⟶ B)),
265+
inv := curry ((mul_zero t).hom ≫ t.to _),
266266
hom_inv_id' :=
267267
begin
268-
rw [← curry_natural_left, curry_eq_iff, ← cancel_epi mul_zero.inv],
269-
{ apply subsingleton.elim },
268+
rw [← curry_natural_left, curry_eq_iff, ← cancel_epi (mul_zero t).inv],
269+
{ apply t.hom_ext },
270270
{ apply_instance },
271271
{ apply_instance }
272272
end }
@@ -293,20 +293,28 @@ def prod_coprod_distrib [has_binary_coproducts C] [cartesian_closed C] (X Y Z :
293293
end }
294294

295295
/--
296-
If an initial object `0` exists in a CCC then it is a strict initial object,
297-
i.e. any morphism to `0` is an iso.
296+
If an initial object `I` exists in a CCC then it is a strict initial object,
297+
i.e. any morphism to `I` is an iso.
298+
This actually shows a slightly stronger version: any morphism to an initial object from an
299+
exponentiable object is an isomorphism.
298300
-/
299-
instance strict_initial [has_initial C] {f : A ⟶ ⊥_ C} : is_iso f :=
301+
def strict_initial {I : C} (t : is_initial I) (f : A ⟶ I) : is_iso f :=
300302
begin
301-
haveI : mono (limits.prod.lift (𝟙 A) f ≫ zero_mul.hom) := mono_comp _ _,
303+
haveI : mono (limits.prod.lift (𝟙 A) f ≫ (zero_mul t).hom) := mono_comp _ _,
302304
rw [zero_mul_hom, prod.lift_snd] at _inst,
303-
haveI: split_epi f := ⟨default _, subsingleton.elim _ _⟩,
305+
haveI: split_epi f := ⟨t.to _, t.hom_ext _ _⟩,
304306
apply is_iso_of_mono_of_split_epi
305307
end
306308

309+
instance [has_initial C] (f : A ⟶ ⊥_ C) : is_iso f :=
310+
strict_initial initial_is_initial _
311+
307312
/-- If an initial object `0` exists in a CCC then every morphism from it is monic. -/
308-
instance initial_mono (B : C) [has_initial C] [cartesian_closed C] : mono (initial.to B) :=
309-
⟨λ B g h _, eq_of_inv_eq_inv (subsingleton.elim (inv g) (inv h))⟩
313+
lemma initial_mono {I : C} (B : C) (t : is_initial I) [cartesian_closed C] : mono (t.to B) :=
314+
⟨λ B g h _, by { haveI := strict_initial t g, haveI := strict_initial t h, exact eq_of_inv_eq_inv (t.hom_ext _ _) }⟩
315+
316+
instance initial.mono_to [has_initial C] (B : C) [cartesian_closed C] : mono (initial.to B) :=
317+
initial_mono B initial_is_initial
310318

311319
variables {D : Type u₂} [category.{v} D]
312320
section functor

src/category_theory/limits/shapes/terminal.lean

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,43 @@ open category_theory
1616

1717
namespace category_theory.limits
1818

19-
variables (C : Type u) [category.{v} C]
19+
variables {C : Type u} [category.{v} C]
20+
21+
/-- Construct a cone for the empty diagram given an object. -/
22+
def as_empty_cone (X : C) : cone (functor.empty C) := { X := X, π := by tidy }
23+
/-- Construct a cocone for the empty diagram given an object. -/
24+
def as_empty_cocone (X : C) : cocone (functor.empty C) := { X := X, ι := by tidy }
25+
26+
/-- `X` is terminal if the cone it induces on the empty diagram is limiting. -/
27+
abbreviation is_terminal (X : C) := is_limit (as_empty_cone X)
28+
/-- `X` is initial if the cocone it induces on the empty diagram is colimiting. -/
29+
abbreviation is_initial (X : C) := is_colimit (as_empty_cocone X)
30+
31+
/-- Give the morphism to a terminal object from any other. -/
32+
def is_terminal.from {X : C} (t : is_terminal X) (Y : C) : Y ⟶ X :=
33+
t.lift (as_empty_cone Y)
34+
35+
/-- Any two morphisms to a terminal object are equal. -/
36+
lemma is_terminal.hom_ext {X Y : C} (t : is_terminal X) (f g : Y ⟶ X) : f = g :=
37+
t.hom_ext (by tidy)
38+
39+
/-- Give the morphism from an initial object to any other. -/
40+
def is_initial.to {X : C} (t : is_initial X) (Y : C) : X ⟶ Y :=
41+
t.desc (as_empty_cocone Y)
42+
43+
/-- Any two morphisms from an initial object are equal. -/
44+
lemma is_initial.hom_ext {X Y : C} (t : is_initial X) (f g : X ⟶ Y) : f = g :=
45+
t.hom_ext (by tidy)
46+
47+
/-- Any morphism from a terminal object is mono. -/
48+
lemma is_terminal.mono_from {X Y : C} (t : is_terminal X) (f : X ⟶ Y) : mono f :=
49+
⟨λ Z g h eq, t.hom_ext _ _⟩
50+
51+
/-- Any morphism to an initial object is epi. -/
52+
lemma is_initial.epi_to {X Y : C} (t : is_initial X) (f : Y ⟶ X) : epi f :=
53+
⟨λ Z g h eq, t.hom_ext _ _⟩
54+
55+
variable (C)
2056

2157
/--
2258
A category has a terminal object if it has a limit over the empty diagram.
@@ -64,10 +100,10 @@ def has_initial_of_unique (X : C) [h : Π Y : C, unique (X ⟶ Y)] : has_initial
64100

65101
/-- The map from an object to the terminal object. -/
66102
abbreviation terminal.from [has_terminal C] (P : C) : P ⟶ ⊤_ C :=
67-
limit.lift (functor.empty C) { X := P, π := by tidy }.
103+
limit.lift (functor.empty C) (as_empty_cone P)
68104
/-- The map to an object from the initial object. -/
69105
abbreviation initial.to [has_initial C] (P : C) : ⊥_ C ⟶ P :=
70-
colimit.desc (functor.empty C) { X := P, ι := by tidy }.
106+
colimit.desc (functor.empty C) (as_empty_cocone P)
71107

72108
instance unique_to_terminal [has_terminal C] (P : C) : unique (P ⟶ ⊤_ C) :=
73109
{ default := terminal.from P,
@@ -76,6 +112,23 @@ instance unique_to_terminal [has_terminal C] (P : C) : unique (P ⟶ ⊤_ C) :=
76112
instance unique_from_initial [has_initial C] (P : C) : unique (⊥_ C ⟶ P) :=
77113
{ default := initial.to P,
78114
uniq := λ m, by { apply colimit.hom_ext, rintro ⟨⟩ } }
115+
116+
/-- The chosen terminal object is terminal. -/
117+
def terminal_is_terminal [has_terminal C] : is_terminal (⊤_ C) :=
118+
{ lift := λ s, terminal.from _ }
119+
120+
/-- The chosen initial object is terminal. -/
121+
def initial_is_initial [has_initial C] : is_initial (⊥_ C) :=
122+
{ desc := λ s, initial.to _ }
123+
124+
/-- Any morphism from a terminal object is mono. -/
125+
instance terminal.mono_from {Y : C} [has_terminal C] (f : ⊤_ C ⟶ Y) : mono f :=
126+
is_terminal.mono_from terminal_is_terminal _
127+
128+
/-- Any morphism to an initial object is epi. -/
129+
instance initial.epi_to {Y : C} [has_initial C] (f : Y ⟶ ⊥_ C) : epi f :=
130+
is_initial.epi_to initial_is_initial _
131+
79132
end
80133

81134
end category_theory.limits

0 commit comments

Comments
 (0)