@@ -11,6 +11,7 @@ public import Mathlib.CategoryTheory.ObjectProperty.Extensions
1111public import Mathlib.CategoryTheory.ObjectProperty.ColimitsOfShape
1212public import Mathlib.CategoryTheory.Subobject.WellPowered
1313public import Mathlib.CategoryTheory.Subobject.Lattice
14+ public import Mathlib.CategoryTheory.Subobject.Limits
1415
1516/-!
1617# Torsion Theory
@@ -44,67 +45,7 @@ open CategoryTheory.Limits
4445
4546variable {C : Type u} [Category.{v} C] [Abelian C]
4647
47- /-- In an abelian category, given a kernel `k` of `q` and a mono `m : B ⟶ Q`,
48- the short complex `K ⟶ pullback q m ⟶ B` (where the left leg is `pullback.lift k 0`
49- and the right leg is `pullback.snd`) is short exact.
50-
51- This captures the general fact that pulling back an extension along a monomorphism
52- yields an extension. -/
53- lemma shortExact_pullbackSnd_of_isLimit_kernelFork
54- {K X Q B : C} {k : K ⟶ X} {q : X ⟶ Q} {m : B ⟶ Q} [Mono m] [Epi q]
55- (w : k ≫ q = 0 ) (hk : IsLimit (KernelFork.ofι k w)) [HasPullback q m] :
56- (ShortComplex.mk (pullback.lift k 0 (by simp [w]))
57- (pullback.snd q m) (pullback.lift_snd k 0 (by simp [w]))).ShortExact := by
58- have w' : k ≫ q = 0 ≫ m := by simp [w]
59- have hg_fst : pullback.lift k 0 (by simp [w]) ≫ pullback.fst q m = k :=
60- pullback.lift_fst k 0 w'
61- haveI : Mono (pullback.lift k 0 w') :=
62- (mono_comp_iff_of_mono _ (pullback.fst q m)).mp
63- (by simpa [hg_fst] using mono_of_isLimit_fork hk)
64- exact {
65- exact := by
66- refine ShortComplex.exact_of_f_is_kernel _ ?_
67- refine KernelFork.IsLimit.ofι' _ (pullback.lift_snd k 0 w') ?_
68- intro A a ha
69- have : (a ≫ pullback.fst q m) ≫ q = 0 := by
70- simpa [Category.assoc' m (pullback.snd q m) a, ha, zero_comp] using
71- congrArg (a ≫ ·) pullback.condition
72- exact ⟨hk.lift (KernelFork.ofι (a ≫ pullback.fst q m) this), by
73- apply (cancel_mono (pullback.fst q m)).mp
74- simpa [Category.assoc, hg_fst] using
75- hk.fac (KernelFork.ofι _ this) WalkingParallelPair.zero⟩
76- mono_f := by infer_instance
77- epi_g := by infer_instance
78- }
79-
80- /-- If `C` is locally small, well-powered, and has coproducts, then every object `X : C` has a
81- subobject with property `P` that is maximal amongst all such subobjects. -/
82- noncomputable
83- abbrev sSup (P : ObjectProperty C) (X : C)
84- [LocallySmall.{w} C] [WellPowered.{w} C] [HasCoproducts.{w} C] :
85- Subobject X :=
86- CategoryTheory.Subobject.sSup {A : Subobject X | P (A : C)}
87-
88- lemma le_sSup_of_prop (P : ObjectProperty C)
89- [P.IsClosedUnderIsomorphisms]
90- [LocallySmall.{w} C] [WellPowered.{w} C] [HasCoproducts.{w} C]
91- {X' X : C} (i : X' ⟶ X) (hi : P (Abelian.image i)) :
92- Subobject.mk (Abelian.image.ι i) ≤ sSup P X :=
93- Subobject.le_sSup _ _
94- (P.prop_of_iso (Subobject.underlyingIso (Abelian.image.ι i)).symm hi)
95-
96- lemma sSup_prop (P : ObjectProperty C)
97- [P.IsClosedUnderQuotients] [∀ J : Type w, P.IsClosedUnderColimitsOfShape (Discrete J)]
98- [LocallySmall.{w} C] [WellPowered.{w} C] [HasCoproducts.{w} C]
99- (X : C) : P (sSup P X) :=
100- P.prop_of_iso (Subobject.underlyingIso
101- (Limits.image.ι (Subobject.smallCoproductDesc _))).symm
102- (P.prop_of_epi (factorThruImage _)
103- ((ObjectProperty.prop_colimit _ _ (fun ⟨j⟩ ↦ by
104- dsimp
105- obtain ⟨S, hS, hj⟩ := j.2
106- simpa [← hj] using hS))))
107-
48+ section GaloisConnection
10849lemma gc_rightOrthogonal_leftOrthogonal :
10950 GaloisConnection (OrderDual.toDual (α := ObjectProperty C) ∘ ObjectProperty.rightOrthogonal)
11051 (ObjectProperty.leftOrthogonal ∘ OrderDual.ofDual) :=
@@ -129,55 +70,153 @@ lemma le_rightOrthogonal_leftOrthogonal (P : ObjectProperty C) :
12970lemma le_leftOrthogonal_rightOrthogonal (P : ObjectProperty C) :
13071 P ≤ P.leftOrthogonal.rightOrthogonal := by
13172 simpa [Function.comp] using gc_rightOrthogonal_leftOrthogonal.l_u_le (OrderDual.toDual P)
73+ end GaloisConnection
74+
75+ section PullbackCokernel
76+ variable {X : C} {A : Subobject X} (B : Subobject (cokernel A.arrow))
77+
78+ /-- For `A : Subobject X`, the pullback of `B : Subobject (cokernel A.arrow)` is a subobject of `X`
79+ that contains `A`. -/
80+ lemma le_pullback_cokernel_π :
81+ A ≤ (Subobject.pullback (cokernel.π A.arrow)).obj B := by
82+ let g : (A : C) ⟶ ((Subobject.pullback (cokernel.π A.arrow)).obj B : C) :=
83+ (Subobject.isPullback (cokernel.π A.arrow) B).lift 0 A.arrow (by simp)
84+ have w : g ≫ ((Subobject.pullback (cokernel.π A.arrow)).obj B).arrow = A.arrow :=
85+ (Subobject.isPullback (cokernel.π A.arrow) B).lift_snd 0 A.arrow (by simp)
86+ haveI : Mono g :=
87+ (mono_comp_iff_of_mono _ ((Subobject.pullback (cokernel.π A.arrow)).obj B).arrow).mp
88+ (by rw [w]; infer_instance)
89+ exact Subobject.le_of_comm g w
90+
91+ /-- Given a subobject `A` of `X` and a subobject `B` of the cokernel of `A.arrow`, the canonical
92+ inclusion of `A` into the pullback `A' = (Subobject.pullback (cokernel.π A.arrow)).obj B`
93+ is a kernel fork for `Subobject.pullbackπ (cokernel.π A.arrow) B`. -/
94+ noncomputable
95+ def kernelForkPullbackπCokernelπ :
96+ KernelFork (Subobject.pullbackπ (cokernel.π A.arrow) B) := by
97+ let A' := (Subobject.pullback (cokernel.π A.arrow)).obj B
98+ let g : (A : C) ⟶ (A' : C) := (Subobject.ofLE A _ (le_pullback_cokernel_π B))
99+ let p := cokernel.π A.arrow
100+ refine KernelFork.ofι g ?_
101+ apply (cancel_mono B.arrow).mp
102+ calc
103+ _ = g ≫ ((Subobject.pullback p).obj B).arrow ≫ p := by
104+ rw [Category.assoc, (Subobject.isPullback p B).toCommSq.w]
105+ _ = A.arrow ≫ p := by
106+ rw [← Category.assoc, Subobject.ofLE_arrow (le_pullback_cokernel_π B)]
107+ _ = 0 ≫ B.arrow := by
108+ rw [zero_comp, cokernel.condition A.arrow]
109+
110+ /-- `kernelFork_pullbackπ_cokernel_π A B` is a limit cone. -/
111+ noncomputable
112+ def isLimit_kernelFork_pullbackπ_cokernel_π : IsLimit (kernelForkPullbackπCokernelπ B) := by
113+ let A' := (Subobject.pullback (cokernel.π A.arrow)).obj B
114+ let i : (A : C) ⟶ (A' : C) := (Subobject.ofLE A _ (le_pullback_cokernel_π B))
115+ let hPB := (Subobject.isPullback (cokernel.π A.arrow) B)
116+ have hA := Abelian.monoIsKernelOfCokernel
117+ (CokernelCofork.ofπ (cokernel.π A.arrow) (cokernel.condition A.arrow))
118+ (cokernelIsCokernel A.arrow)
119+ apply KernelFork.IsLimit.ofι' i (kernelForkPullbackπCokernelπ B).condition
120+ intro Z f hf
121+ let s : KernelFork (cokernel.π A.arrow) := KernelFork.ofι (f ≫ A'.arrow)
122+ (by rw [Category.assoc, ← hPB.toCommSq.w, ← Category.assoc, hf, zero_comp])
123+ refine ⟨hA.lift s, ?_⟩
124+ apply (cancel_mono A'.arrow).mp
125+ rw [Category.assoc, Subobject.ofLE_arrow (le_pullback_cokernel_π B)]
126+ exact hA.fac s WalkingParallelPair.zero
127+
128+ /-- Given a subobject `A` of `X` and a subobject `B` of `cokernel A.arrow`, the short complex
129+ `A ⟶ (Subobject.pullback (cokernel.π A.arrow)).obj B ⟶ B` with first map induced by
130+ `A.arrow ≫ cokernel.π A.arrow = 0 ≫ B.arrow` and second map `Subobject.pullbackπ`. -/
131+ noncomputable
132+ def shortComplexPullbackπCokernelπ : ShortComplex C :=
133+ ShortComplex.mk
134+ (Subobject.ofLE A _ (le_pullback_cokernel_π B))
135+ (Subobject.pullbackπ (cokernel.π A.arrow) B)
136+ (kernelForkPullbackπCokernelπ B).condition
137+
138+ lemma shortExact_shortComplexPullbackπCokernelπ :
139+ ShortComplex.ShortExact (shortComplexPullbackπCokernelπ B) := by
140+ refine {
141+ exact := by
142+ refine ShortComplex.exact_of_f_is_kernel _ ?_
143+ simpa [shortComplexPullbackπCokernelπ, kernelForkPullbackπCokernelπ] using
144+ isLimit_kernelFork_pullbackπ_cokernel_π B
145+ mono_f := by change Mono (Subobject.ofLE A _ (le_pullback_cokernel_π B)); infer_instance
146+ epi_g := by
147+ simpa [(Subobject.isPullback (cokernel.π A.arrow) B).isoPullback_hom_fst] using
148+ epi_comp
149+ (Subobject.isPullback (cokernel.π A.arrow) B).isoPullback.hom
150+ (pullback.fst B.arrow (cokernel.π A.arrow))
151+ }
152+ end PullbackCokernel
153+
154+ lemma le_sSup_of_prop (P : ObjectProperty C)
155+ [P.IsClosedUnderIsomorphisms]
156+ [LocallySmall.{w} C] [WellPowered.{w} C] [HasCoproducts.{w} C]
157+ {X' X : C} (i : X' ⟶ X) (hi : P (Abelian.image i)) :
158+ Subobject.mk (Abelian.image.ι i) ≤ Subobject.sSup {A : Subobject X | P (A : C)} :=
159+ Subobject.le_sSup _ _
160+ (P.prop_of_iso (Subobject.underlyingIso (Abelian.image.ι i)).symm hi)
161+
162+ lemma sSup_prop (P : ObjectProperty C)
163+ [P.IsClosedUnderQuotients] [∀ J : Type w, P.IsClosedUnderColimitsOfShape (Discrete J)]
164+ [LocallySmall.{w} C] [WellPowered.{w} C] [HasCoproducts.{w} C]
165+ (X : C) : P (CategoryTheory.Subobject.sSup {A : Subobject X | P (A : C)}) :=
166+ P.prop_of_iso (Subobject.underlyingIso
167+ (Limits.image.ι (Subobject.smallCoproductDesc _))).symm
168+ (P.prop_of_epi (factorThruImage _)
169+ ((ObjectProperty.prop_colimit _ _ (fun ⟨j⟩ ↦ by
170+ dsimp
171+ obtain ⟨S, hS, hj⟩ := j.2
172+ simpa [← hj] using hS))))
132173
133174/-- If `P` is closed under quotients, extensions, and coproducts, then for any `X`,
134175the cokernel of the maximal `P`-subobject's arrow is `P.rightOrthogonal`. -/
135176lemma rightOrthogonal_cokernel_sSup (P : ObjectProperty C)
136177 [P.IsClosedUnderQuotients] [P.IsClosedUnderExtensions]
137178 [∀ J : Type w, P.IsClosedUnderColimitsOfShape (Discrete J)]
138179 [LocallySmall.{w} C] [WellPowered.{w} C] [HasCoproducts.{w} C]
139- (X : C) : P.rightOrthogonal (cokernel (sSup P X).arrow) := by
140- let Y : Subobject X := sSup P X
180+ (X : C) :
181+ P.rightOrthogonal (cokernel (Subobject.sSup {A : Subobject X | P (A : C)}).arrow) := by
182+ let A := CategoryTheory.Subobject.sSup {A : Subobject X | P (A : C)}
141183 rw [ObjectProperty.rightOrthogonal_iff]
142184 intro Z f hPZ
143- let A := pullback (cokernel.π Y.arrow) (Abelian.image.ι f)
144- let i := pullback.fst (cokernel.π Y.arrow) (Abelian.image.ι f)
145- let p := pullback.snd (cokernel.π Y.arrow) (Abelian.image.ι f)
146- have hSES : (ShortComplex.mk
147- (pullback.lift Y.arrow 0 (by simp) : (Y : C) ⟶ A) p
148- (pullback.lift_snd Y.arrow 0 (by simp))).ShortExact :=
149- let s : ShortComplex C := ShortComplex.cokernelSequence Y.arrow
150- have hs: s.ShortExact := {
151- exact := ShortComplex.cokernelSequence_exact _
152- mono_f := by dsimp [s]; infer_instance
153- epi_g := inferInstance}
154- shortExact_pullbackSnd_of_isLimit_kernelFork (cokernel.condition Y.arrow)
155- hs.fIsKernel
156- have hPimi : P (Abelian.image i) :=
157- P.prop_of_epi (Abelian.factorThruImage i) --hPA
158- ((ObjectProperty.prop_X₂_of_shortExact P hSES (sSup_prop P X)
159- (P.prop_of_epi (Abelian.factorThruImage f) hPZ)))
160- have himg_le_Y : Subobject.mk (Abelian.image.ι i) ≤ Y :=
161- le_sSup_of_prop P i hPimi
162- let g' : Abelian.image i ⟶ (Y : C) := Subobject.ofMkLE (Abelian.image.ι i) Y himg_le_Y
163- have hg' : g' ≫ Y.arrow = image.ι i := Subobject.ofMkLE_arrow himg_le_Y
164- have hi_cokernel : i ≫ cokernel.π Y.arrow = 0 := by
165- simp [← Abelian.image.fac i, ← hg']
166- have hp : p = 0 := by
167- rw [← cancel_mono (Abelian.image.ι f), zero_comp, ← pullback.condition, hi_cokernel]
168- have himf_zero : Abelian.image.ι f = 0 :=
169- IsZero.eq_zero_of_src (IsZero.of_epi_eq_zero p hp) (Abelian.image.ι f)
170- simp [← Abelian.image.fac f, himf_zero]
185+ let B := Subobject.mk (Abelian.image.ι f)
186+ let A':= ((Subobject.pullback
187+ (cokernel.π (Subobject.sSup {A : Subobject X | P (A : C)}).arrow))).obj B
188+ haveI : Epi (Subobject.pullbackπ (cokernel.π A.arrow) B) := by
189+ simpa [(Subobject.isPullback (cokernel.π A.arrow) B).isoPullback_hom_fst] using
190+ epi_comp (Subobject.isPullback (cokernel.π A.arrow) B).isoPullback.hom
191+ (pullback.fst B.arrow (cokernel.π A.arrow))
192+ have hSES := shortExact_shortComplexPullbackπCokernelπ B
193+ let f' : (A' : C) ⟶ A :=
194+ Subobject.ofLE _ _
195+ (Subobject.le_sSup {A | P (Subobject.underlying.obj A)} A'
196+ (P.prop_X₂_of_shortExact hSES (sSup_prop P X)
197+ (P.prop_of_iso
198+ (Subobject.underlyingIso (Abelian.image.ι f)).symm
199+ (P.prop_of_epi (Abelian.factorThruImage f) hPZ))))
200+ have hf' : f' ≫ A.arrow = A'.arrow := Subobject.ofLE_arrow _
201+ have hzero : A'.arrow ≫ cokernel.π (A.arrow) = 0 := by
202+ simp [← hf']
203+ have hpullbackπ : (Subobject.pullbackπ (cokernel.π A.arrow) B) = 0 := by
204+ apply (cancel_mono B.arrow).mp
205+ rw [(Subobject.isPullback (cokernel.π A.arrow) B).toCommSq.w, hzero, zero_comp]
206+ have himf: IsZero (Abelian.image f) :=
207+ IsZero.of_iso (IsZero.of_epi_eq_zero (Subobject.pullbackπ (cokernel.π A.arrow) B) hpullbackπ)
208+ (id (Subobject.underlyingIso (Abelian.image.ι f)).symm)
209+ simp [← Abelian.image.fac f, IsZero.eq_zero_of_src himf]
171210
172211lemma rightOrthogonal_leftOrthogonal_le (P : ObjectProperty C)
173212 [P.IsClosedUnderQuotients] [P.IsClosedUnderExtensions]
174213 [∀ J : Type w, P.IsClosedUnderColimitsOfShape (Discrete J)]
175214 [LocallySmall.{w} C] [WellPowered.{w} C] [HasCoproducts.{w} C] :
176215 P.rightOrthogonal.leftOrthogonal ≤ P :=
177216 fun X hX ↦
178- haveI : Epi (sSup P X ).arrow :=
217+ haveI : Epi (Subobject. sSup {A : Subobject X | P (A : C)} ).arrow :=
179218 Preadditive.epi_of_cokernel_zero (hX (cokernel.π _) (rightOrthogonal_cokernel_sSup P X))
180- P.prop_of_epi (sSup P X ).arrow (sSup_prop P X)
219+ P.prop_of_epi (Subobject. sSup {A : Subobject X | P (A : C)} ).arrow (sSup_prop P X)
181220
182221/-- If an object property `P` in an abelian category is closed under quotients, extensions,
183222and coproducts, then `P = P.rightOrthogonal.leftOrthogonal`. -/
0 commit comments