Skip to content

Commit ce4bea0

Browse files
committed
feat(CategoryTheory): strong generators (#29519)
In this PR, we introduce a condition `IsStrongGenerator P` on `P : ObjectProperty C` which is stronger than `IsSeparating P` as we also require that for any proper subobject `A ⊂ X`, there exists a morphism `G ⟶ X` from an object satisfying `P` which does not factor through `A`. In case coproducts exists, we give a characterization of `IsStrongSeparator P` in terms of the existence, for each object `X : C` of an extremal epi to `X` from a coproduct of objects in `S`. In future works (#30241), this shall be used in order to characterize locally `κ`-presentable categories as cocomplete categories that have a strong generator consisting of `κ`-presentable objects.
1 parent 9123595 commit ce4bea0

File tree

4 files changed

+249
-27
lines changed

4 files changed

+249
-27
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,6 +2345,7 @@ import Mathlib.CategoryTheory.Generator.Indization
23452345
import Mathlib.CategoryTheory.Generator.Preadditive
23462346
import Mathlib.CategoryTheory.Generator.Presheaf
23472347
import Mathlib.CategoryTheory.Generator.Sheaf
2348+
import Mathlib.CategoryTheory.Generator.StrongGenerator
23482349
import Mathlib.CategoryTheory.GlueData
23492350
import Mathlib.CategoryTheory.GradedObject
23502351
import Mathlib.CategoryTheory.GradedObject.Associator

Mathlib/CategoryTheory/Comma/StructuredArrow/Small.lean

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,20 @@ be used in the proof of the Special Adjoint Functor Theorem.
1717
namespace CategoryTheory
1818

1919
-- morphism levels before object levels. See note [category theory universes].
20-
universe v₁ v₂ u₁ u₂
20+
universe w v₁ v₂ u₁ u₂
2121

2222
variable {C : Type u₁} [Category.{v₁} C] {D : Type u₂} [Category.{v₂} D]
2323

2424
namespace StructuredArrow
2525

2626
variable {S : D} {T : C ⥤ D}
2727

28+
instance [Small.{w} C] [LocallySmall.{w} D] : Small.{w} (StructuredArrow S T) :=
29+
small_of_surjective (f := fun (f : Σ (X : C), S ⟶ T.obj X) ↦ StructuredArrow.mk f.2)
30+
(fun f ↦ by
31+
obtain ⟨X, f, rfl⟩ := f.mk_surjective
32+
exact ⟨⟨X, f⟩, rfl⟩)
33+
2834
instance small_inverseImage_proj_of_locallySmall
2935
{P : ObjectProperty C} [ObjectProperty.Small.{v₁} P] [LocallySmall.{v₁} D] :
3036
ObjectProperty.Small.{v₁} (P.inverseImage (proj S T)) := by
@@ -45,6 +51,12 @@ namespace CostructuredArrow
4551

4652
variable {S : C ⥤ D} {T : D}
4753

54+
instance [Small.{w} C] [LocallySmall.{w} D] : Small.{w} (CostructuredArrow S T) :=
55+
small_of_surjective (f := fun (f : Σ (X : C), S.obj X ⟶ T) ↦ CostructuredArrow.mk f.2)
56+
(fun f ↦ by
57+
obtain ⟨X, f, rfl⟩ := f.mk_surjective
58+
exact ⟨⟨X, f⟩, rfl⟩)
59+
4860
instance small_inverseImage_proj_of_locallySmall
4961
{P : ObjectProperty C} [ObjectProperty.Small.{v₁} P] [LocallySmall.{v₁} D] :
5062
ObjectProperty.Small.{v₁} (P.inverseImage (proj S T)) := by

Mathlib/CategoryTheory/Generator/Basic.lean

Lines changed: 100 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Mathlib.CategoryTheory.Limits.EssentiallySmall
77
import Mathlib.CategoryTheory.Limits.Shapes.Opposites.Equalizers
88
import Mathlib.CategoryTheory.Subobject.Lattice
99
import Mathlib.CategoryTheory.ObjectProperty.Small
10+
import Mathlib.CategoryTheory.Comma.StructuredArrow.Small
1011

1112
/-!
1213
# Separating and detecting sets
@@ -287,31 +288,103 @@ lemma isCodetecting_bot_of_isGroupoid [IsGroupoid C] :
287288

288289
end Empty
289290

291+
lemma IsSeparating.mk_of_exists_epi
292+
(hP : ∀ (X : C), ∃ (ι : Type w) (s : ι → C) (_ : ∀ i, P (s i)) (c : Cofan s) (_ : IsColimit c)
293+
(p : c.pt ⟶ X), Epi p) :
294+
P.IsSeparating := by
295+
intro X Y f g h
296+
obtain ⟨ι, s, hs, c, hc, p, _⟩ := hP X
297+
rw [← cancel_epi p]
298+
exact Cofan.IsColimit.hom_ext hc _ _
299+
(fun i ↦ by simpa using h _ (hs i) (c.inj i ≫ p))
300+
301+
lemma IsCoseparating.mk_of_exists_mono
302+
(hP : ∀ (X : C), ∃ (ι : Type w) (s : ι → C) (_ : ∀ i, P (s i)) (c : Fan s) (_ : IsLimit c)
303+
(j : X ⟶ c.pt), Mono j) :
304+
P.IsCoseparating := by
305+
intro X Y f g h
306+
obtain ⟨ι, s, hs, c, hc, j, _⟩ := hP Y
307+
rw [← cancel_mono j]
308+
exact Fan.IsLimit.hom_ext hc _ _
309+
(fun i ↦ by simpa using h _ (hs i) (j ≫ c.proj i))
310+
290311
variable (P)
291312

313+
section
314+
315+
/-- Given `P : ObjectProperty C` and `X : C`, this is the map which
316+
sends `i : CostructuredArrow P.ι X` to `i.left.obj : C`. The coproduct
317+
of this family is the source of the morphism `P.coproductFrom X`. -/
318+
abbrev coproductFromFamily (X : C) (i : CostructuredArrow P.ι X) : C := i.left.obj
319+
320+
variable (X : C)
321+
322+
variable [HasCoproduct (P.coproductFromFamily X)]
323+
324+
/-- Given `P : ObjectProperty C` and `X : C`, this is the coproduct of
325+
all the morphisms `Y ⟶ X` such that `P Y` holds. -/
326+
noncomputable abbrev coproductFrom : ∐ (P.coproductFromFamily X) ⟶ X :=
327+
Sigma.desc (fun i ↦ i.hom)
328+
329+
variable {X} in
330+
/-- The inclusion morphisms to `∐ (P.coproductFromFamily X)`. -/
331+
noncomputable abbrev ιCoproductFrom {Y : C} (f : Y ⟶ X) (hY : P Y) :
332+
Y ⟶ ∐ (P.coproductFromFamily X) := by
333+
exact Sigma.ι (P.coproductFromFamily X) (CostructuredArrow.mk (Y := ⟨Y, hY⟩) (by exact f))
334+
335+
end
336+
337+
variable {P} in
338+
lemma IsSeparating.epi_coproductFrom (hP : P.IsSeparating)
339+
(X : C) [HasCoproduct (P.coproductFromFamily X)] :
340+
Epi (P.coproductFrom X) where
341+
left_cancellation u v huv :=
342+
hP _ _ (fun G hG h ↦ by simpa using P.ιCoproductFrom h hG ≫= huv)
343+
292344
theorem isSeparating_iff_epi
293-
[∀ A : C, HasCoproduct fun f : Σ G : Subtype P, G.1 ⟶ A ↦ f.1.1] :
294-
IsSeparating P ↔
295-
∀ A : C, Epi (Sigma.desc (Sigma.snd (β := fun (G : Subtype P) ↦ G.1 ⟶ A))) := by
296-
let β (A : C) (G : Subtype P) := G.1 ⟶ A
297-
let b (A : C) (x : Σ G, β A G) := x.1.1
298-
refine ⟨fun h A ↦ ⟨fun u v huv ↦ h _ _ fun G hG f ↦ ?_⟩, fun h X Y f g hh ↦ ?_⟩
299-
· simpa [β, b] using Sigma.ι (b A) ⟨⟨G, hG⟩, f⟩ ≫= huv
300-
· rw [← cancel_epi (Sigma.desc (Sigma.snd (β := β X)))]
301-
ext ⟨⟨_, hG⟩, _⟩
302-
simpa using hh _ hG _
345+
[∀ (X : C), HasCoproduct (P.coproductFromFamily X)] :
346+
IsSeparating P ↔ ∀ X : C, Epi (P.coproductFrom X) :=
347+
fun hP X ↦ hP.epi_coproductFrom X,
348+
fun hP ↦ IsSeparating.mk_of_exists_epi (fun X ↦ ⟨_, P.coproductFromFamily X,
349+
fun i ↦ i.left.2, _, colimit.isColimit _, _, hP X⟩)⟩
350+
351+
section
352+
353+
/-- Given `P : ObjectProperty C` and `X : C`, this is the map which
354+
sends `i : StructuredArrow P.ι X` to `i.right.obj : C`. The product
355+
of this family is the target of the morphism `P.productTo X`. -/
356+
abbrev productToFamily (X : C) (i : StructuredArrow X P.ι) : C := i.right.obj
357+
358+
variable (X : C)
359+
360+
variable [HasProduct (P.productToFamily X)]
361+
362+
/-- Given `P : ObjectProperty C` and `X : C`, this is the product of
363+
all the morphisms `X ⟶ Y` such that `P Y` holds. -/
364+
noncomputable abbrev productTo : X ⟶ ∏ᶜ (P.productToFamily X) :=
365+
Pi.lift (fun i ↦ i.hom)
366+
367+
variable {X} in
368+
/-- The projection morphisms from `∏ᶜ (P.productToFamily X)`. -/
369+
noncomputable abbrev πProductTo {Y : C} (f : X ⟶ Y) (hY : P Y) :
370+
∏ᶜ (P.productToFamily X) ⟶ Y := by
371+
exact Pi.π (P.productToFamily X) (StructuredArrow.mk (Y := ⟨Y, hY⟩) (by exact f))
372+
373+
end
374+
375+
variable {P} in
376+
lemma IsCoseparating.mono_productTo (hP : P.IsCoseparating)
377+
(X : C) [HasProduct (P.productToFamily X)] :
378+
Mono (P.productTo X) where
379+
right_cancellation u v huv :=
380+
hP _ _ (fun G hG h ↦ by simpa using huv =≫ P.πProductTo h hG)
303381

304382
theorem isCoseparating_iff_mono
305-
[∀ A : C, HasProduct fun f : Σ G : Subtype P, A ⟶ G.1 ↦ f.1.1] :
306-
IsCoseparating P ↔
307-
∀ A : C, Mono (Pi.lift (Sigma.snd (β := fun (G : Subtype P) ↦ A ⟶ G.1))) := by
308-
let β (A : C) (G : Subtype P) := A ⟶ G.1
309-
let b (A : C) (x : Σ G, β A G) := x.1.1
310-
refine ⟨fun h A ↦ ⟨fun u v huv ↦ h _ _ fun G hG f ↦ ?_⟩, fun h X Y f g hh ↦ ?_⟩
311-
· simpa [β, b] using huv =≫ Pi.π (b A) ⟨⟨G, hG⟩, f⟩
312-
· rw [← cancel_mono (Pi.lift (Sigma.snd (β := β Y)))]
313-
ext ⟨⟨_, hG⟩, _⟩
314-
simpa using hh _ hG _
383+
[∀ (X : C), HasProduct (P.productToFamily X)] :
384+
IsCoseparating P ↔ ∀ X : C, Mono (P.productTo X) :=
385+
fun hP X ↦ hP.mono_productTo X,
386+
fun hP ↦ IsCoseparating.mk_of_exists_mono (fun X ↦ ⟨_, P.productToFamily X,
387+
fun i ↦ i.right.2, _, limit.isLimit _, _, hP X⟩)⟩
315388

316389
end ObjectProperty
317390

@@ -324,16 +397,17 @@ theorem hasInitial_of_isCoseparating [LocallySmall.{w} C] [WellPowered.{w} C]
324397
[HasLimitsOfSize.{w, w} C] {P : ObjectProperty C} [ObjectProperty.Small.{w} P]
325398
(hP : P.IsCoseparating) : HasInitial C := by
326399
have := hasFiniteLimits_of_hasLimitsOfSize C
327-
haveI : HasProductsOfShape (Subtype P) C := hasProductsOfShape_of_small C (Subtype P)
328-
haveI := fun A => hasProductsOfShape_of_small.{w} C (Σ G : Subtype P, A ⟶ (G : C))
400+
haveI := hasProductsOfShape_of_small C (Subtype P)
401+
haveI := fun A => hasProductsOfShape_of_small.{w} C (StructuredArrow A P.ι)
329402
letI := completeLatticeOfCompleteSemilatticeInf (Subobject (piObj (Subtype.val : Subtype P → C)))
330403
suffices ∀ A : C, Unique (((⊥ : Subobject (piObj (Subtype.val : Subtype P → C))) : C) ⟶ A) by
331404
exact hasInitial_of_unique ((⊥ : Subobject (piObj (Subtype.val : Subtype P → C))) : C)
405+
have := hP.mono_productTo
332406
refine fun A => ⟨⟨?_⟩, fun f => ?_⟩
333-
· let s := Pi.lift fun f : Σ G : Subtype P, A ⟶ (G : C) => Pi.π (Subtype.val : Subtype P → C) f.1
334-
let t := Pi.lift (@Sigma.snd (Subtype P) fun G => A ⟶ (G : C))
335-
haveI : Mono t := P.isCoseparating_iff_mono.1 hP A
336-
exact Subobject.ofLEMk _ (pullback.fst _ _ : pullback s t ⟶ _) bot_le ≫ pullback.snd _ _
407+
· let s : ∏ᶜ (Subtype.val (p := P)) ⟶ ∏ᶜ P.productToFamily A :=
408+
Pi.lift (fun f ↦ Pi.π Subtype.val ⟨f.right.obj, f.right.property⟩)
409+
exact Subobject.ofLEMk _
410+
(pullback.fst _ _ : pullback s (P.productTo A) ⟶ _) bot_le ≫ pullback.snd _ _
337411
· suffices ∀ (g : Subobject.underlying.obj ⊥ ⟶ A), f = g by
338412
apply this
339413
intro g
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/-
2+
Copyright (c) 2025 Joël Riou. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Joël Riou
5+
-/
6+
import Mathlib.CategoryTheory.ExtremalEpi
7+
import Mathlib.CategoryTheory.Generator.Basic
8+
9+
/-!
10+
# Strong generators
11+
12+
If `P : ObjectProperty C`, we say that `P` is a strong generator if it is a
13+
generator (in the sense that `IsSeparating P` holds) such that for any
14+
proper subobject `A ⊂ X`, there exists a morphism `G ⟶ X` which does not factor
15+
through `A` from an object satisfying `P`.
16+
17+
The main result is the lemma `isStrongGenerator_iff_exists_extremalEpi` which
18+
says that if `P` is `w`-small, `C` is locally `w`-small and
19+
has coproducts of size `w`, then `P` is a strong generator iff any
20+
object of `C` is the target of an extremal epimorphism from a coproduct of
21+
objects satisfying `P`.
22+
23+
## References
24+
* [Adámek, J. and Rosický, J., *Locally presentable and accessible categories*][Adamek_Rosicky_1994]
25+
26+
-/
27+
28+
universe w v u
29+
30+
namespace CategoryTheory
31+
32+
open Limits
33+
34+
35+
namespace ObjectProperty
36+
37+
variable {C : Type u} [Category.{v} C] (P : ObjectProperty C)
38+
39+
/-- A property `P : ObjectProperty C` is a strong generator
40+
if it is separating and for any proper subobject `A ⊂ X`, there exists
41+
a morphism `G ⟶ X` which does not factor through `A` from an object
42+
such that `P G` holds. -/
43+
def IsStrongGenerator : Prop :=
44+
P.IsSeparating ∧ ∀ ⦃X : C⦄ (A : Subobject X),
45+
(∀ (G : C) (_ : P G) (f : G ⟶ X), Subobject.Factors A f) → A = ⊤
46+
47+
variable {P}
48+
49+
lemma isStrongGenerator_iff :
50+
P.IsStrongGenerator ↔ P.IsSeparating ∧
51+
∀ ⦃X Y : C⦄ (i : X ⟶ Y) [Mono i],
52+
(∀ (G : C) (_ : P G), Function.Surjective (fun (f : G ⟶ X) ↦ f ≫ i)) → IsIso i := by
53+
refine ⟨fun ⟨hS₁, hS₂⟩ ↦ ⟨hS₁, fun X Y i _ h ↦ ?_⟩,
54+
fun ⟨hS₁, hS₂⟩ ↦ ⟨hS₁, fun X A hA ↦ ?_⟩⟩
55+
· rw [Subobject.isIso_iff_mk_eq_top]
56+
refine hS₂ _ (fun G hG g ↦ ?_)
57+
rw [Subobject.mk_factors_iff]
58+
exact h G hG g
59+
· rw [← Subobject.isIso_arrow_iff_eq_top]
60+
exact hS₂ A.arrow (fun G hG g ↦ ⟨_, Subobject.factorThru_arrow _ _ (hA G hG g)⟩)
61+
62+
namespace IsStrongGenerator
63+
64+
section
65+
66+
variable (hP : P.IsStrongGenerator)
67+
68+
include hP
69+
70+
lemma isSeparating : P.IsSeparating := hP.1
71+
72+
lemma subobject_eq_top {X : C} {A : Subobject X}
73+
(hA : ∀ (G : C) (_ : P G) (f : G ⟶ X), Subobject.Factors A f) :
74+
A = ⊤ :=
75+
hP.2 _ hA
76+
77+
lemma isIso_of_mono ⦃X Y : C⦄ (i : X ⟶ Y) [Mono i]
78+
(hi : ∀ (G : C) (_ : P G), Function.Surjective (fun (f : G ⟶ X) ↦ f ≫ i)) : IsIso i :=
79+
(isStrongGenerator_iff.1 hP).2 i hi
80+
81+
lemma exists_of_subobject_ne_top {X : C} {A : Subobject X} (hA : A ≠ ⊤) :
82+
∃ (G : C) (_ : P G) (f : G ⟶ X), ¬ Subobject.Factors A f := by
83+
by_contra!
84+
exact hA (hP.subobject_eq_top this)
85+
86+
lemma exists_of_mono_not_isIso {X Y : C} (i : X ⟶ Y) [Mono i] (hi : ¬ IsIso i) :
87+
∃ (G : C) (_ : P G) (g : G ⟶ Y), ∀ (f : G ⟶ X), f ≫ i ≠ g := by
88+
by_contra!
89+
exact hi (hP.isIso_of_mono i this)
90+
91+
end
92+
93+
end IsStrongGenerator
94+
95+
namespace IsStrongGenerator
96+
97+
lemma mk_of_exists_extremalEpi
98+
(hS : ∀ (X : C), ∃ (ι : Type w) (s : ι → C) (_ : ∀ i, P (s i)) (c : Cofan s) (_ : IsColimit c)
99+
(p : c.pt ⟶ X), ExtremalEpi p) :
100+
P.IsStrongGenerator := by
101+
rw [isStrongGenerator_iff]
102+
refine ⟨IsSeparating.mk_of_exists_epi.{w} (fun X ↦ ?_), fun X Y i _ hi ↦ ?_⟩
103+
· obtain ⟨ι, s, hs, c, hc, p, _⟩ := hS X
104+
exact ⟨ι, s, hs, c, hc, p, inferInstance⟩
105+
· obtain ⟨ι, s, hs, c, hc, p, _⟩ := hS Y
106+
replace hi (j : ι) := hi (s j) (hs j) (c.inj j ≫ p)
107+
choose φ hφ using hi
108+
exact ExtremalEpi.isIso p (Cofan.IsColimit.desc hc φ) _
109+
(Cofan.IsColimit.hom_ext hc _ _ (by simp [hφ]))
110+
111+
lemma extremalEpi_coproductFrom
112+
(hP : IsStrongGenerator P) (X : C) [HasCoproduct (P.coproductFromFamily X)] :
113+
ExtremalEpi (P.coproductFrom X) where
114+
toEpi := hP.isSeparating.epi_coproductFrom X
115+
isIso p i fac _ := hP.isIso_of_mono _ (fun G hG f ↦ ⟨P.ιCoproductFrom f hG ≫ p, by simp [fac]⟩)
116+
117+
end IsStrongGenerator
118+
119+
lemma isStrongGenerator_iff_exists_extremalEpi
120+
[HasCoproducts.{w} C] [LocallySmall.{w} C] [ObjectProperty.Small.{w} P] :
121+
P.IsStrongGenerator ↔
122+
∀ (X : C), ∃ (ι : Type w) (s : ι → C) (_ : ∀ i, P (s i)) (c : Cofan s) (_ : IsColimit c)
123+
(p : c.pt ⟶ X), ExtremalEpi p := by
124+
refine ⟨fun hP X ↦ ?_, fun hP ↦ .mk_of_exists_extremalEpi hP⟩
125+
have := hasCoproductsOfShape_of_small.{w} C (CostructuredArrow P.ι X)
126+
have := (coproductIsCoproduct (P.coproductFromFamily X)).whiskerEquivalence
127+
(Discrete.equivalence (equivShrink.{w} _)).symm
128+
refine ⟨_, fun j ↦ ((equivShrink.{w} (CostructuredArrow P.ι X)).symm j).left.1,
129+
fun j ↦ ((equivShrink.{w} _).symm j).1.2, _,
130+
(coproductIsCoproduct (P.coproductFromFamily X)).whiskerEquivalence
131+
(Discrete.equivalence (equivShrink.{w} _)).symm, _, hP.extremalEpi_coproductFrom X⟩
132+
133+
end ObjectProperty
134+
135+
end CategoryTheory

0 commit comments

Comments
 (0)