Skip to content

Commit 3ec033a

Browse files
author
blake-farman
committed
Refactored to use Subobject API.
1 parent d0ce4d8 commit 3ec033a

File tree

1 file changed

+132
-93
lines changed
  • Mathlib/CategoryTheory/Abelian/TorsionTheory

1 file changed

+132
-93
lines changed

Mathlib/CategoryTheory/Abelian/TorsionTheory/Basic.lean

Lines changed: 132 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ public import Mathlib.CategoryTheory.ObjectProperty.Extensions
1111
public import Mathlib.CategoryTheory.ObjectProperty.ColimitsOfShape
1212
public import Mathlib.CategoryTheory.Subobject.WellPowered
1313
public 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

4546
variable {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
10849
lemma 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) :
12970
lemma 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`,
134175
the cokernel of the maximal `P`-subobject's arrow is `P.rightOrthogonal`. -/
135176
lemma 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

172211
lemma 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,
183222
and coproducts, then `P = P.rightOrthogonal.leftOrthogonal`. -/

0 commit comments

Comments
 (0)