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

Commit 1037a3a

Browse files
committed
feat(algebra/homology, category_theory/abelian, algebra/category/Module): exactness (#3784)
We define what it means for two maps `f` and `g` to be exact and show that for R-modules, this is the case if and only if `range f = ker g`.
1 parent 2c930a3 commit 1037a3a

File tree

8 files changed

+234
-47
lines changed

8 files changed

+234
-47
lines changed

src/algebra/category/Module/abelian.lean

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ Authors: Markus Himmel
55
-/
66
import algebra.category.Module.kernels
77
import algebra.category.Module.limits
8-
import category_theory.abelian.basic
8+
import category_theory.abelian.exact
99

1010
/-!
1111
# The category of left R-modules is abelian.
12+
13+
Additionally, two linear maps are exact in the categorical sense iff `range f = ker g`.
1214
-/
1315

1416
open category_theory
@@ -72,4 +74,16 @@ instance : abelian (Module R) :=
7274
normal_mono := λ X Y, normal_mono,
7375
normal_epi := λ X Y, normal_epi }
7476

77+
variables {O : Module R} (g : N ⟶ O)
78+
79+
open linear_map
80+
local attribute [instance] preadditive.has_equalizers_of_has_kernels
81+
82+
theorem exact_iff : exact f g ↔ f.range = g.ker :=
83+
begin
84+
rw abelian.exact_iff' f g (kernel_is_limit _) (cokernel_is_colimit _),
85+
exact ⟨λ h, le_antisymm (range_le_ker_iff.2 h.1) (ker_le_range_iff.2 h.2),
86+
λ h, ⟨range_le_ker_iff.1 $ le_of_eq h, ker_le_range_iff.1 $ le_of_eq h.symm⟩⟩
87+
end
88+
7589
end Module

src/algebra/homology/exact.lean

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/-
2+
Copyright (c) 2020 Markus Himmel. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Markus Himmel
5+
-/
6+
import algebra.homology.image_to_kernel_map
7+
8+
/-!
9+
# Exact sequences
10+
11+
In a category with zero morphisms, images, and equalizers we say that `f : A ⟶ B` and `g : B ⟶ C`
12+
are exact if `f ≫ g = 0` and the natural map `image f ⟶ kernel g` is an epimorphism.
13+
14+
# Main results
15+
* Suppose that cokernels exist and that `f` and `g` are exact. If `s` is any kernel fork over `g`
16+
and `t` is any cokernel cofork over `f`, then `fork.ι s ≫ cofork.π t = 0`.
17+
18+
See also `category_theory/abelian/exact.lean` for results that only hold in abelian categories.
19+
20+
# Future work
21+
* Short exact sequences, split exact sequences, the splitting lemma (maybe only for abelian
22+
categories?)
23+
* Two adjacent maps in a chain complex are exact iff the homology vanishes
24+
* Composing with isomorphisms retains exactness, and similar constructions
25+
26+
-/
27+
28+
universes v u
29+
30+
open category_theory
31+
open category_theory.limits
32+
33+
variables {V : Type u} [category.{v} V] [has_zero_morphisms V]
34+
variables [has_kernels V] [has_equalizers V] [has_images V]
35+
36+
namespace category_theory
37+
38+
/-- Two morphisms `f : A ⟶ B`, `g : B ⟶ C` are called exact if `f ≫ g = 0` and the natural map
39+
`image f ⟶ kernel g` is an epimorphism. -/
40+
class exact {A B C : V} (f : A ⟶ B) (g : B ⟶ C) : Prop :=
41+
(w : f ≫ g = 0)
42+
(epi : epi (image_to_kernel_map f g w))
43+
44+
attribute [instance] exact.epi
45+
46+
section
47+
variables [has_cokernels V] {A B C : V} (f : A ⟶ B) (g : B ⟶ C)
48+
49+
@[simp, reassoc] lemma kernel_comp_cokernel [exact f g] : kernel.ι g ≫ cokernel.π f = 0 :=
50+
zero_of_epi_comp (image_to_kernel_map f g exact.w) $ zero_of_epi_comp (factor_thru_image f) $
51+
by simp
52+
53+
lemma comp_eq_zero_of_exact [exact f g] {X Y : V} {ι : X ⟶ B} (hι : ι ≫ g = 0) {π : B ⟶ Y}
54+
(hπ : f ≫ π = 0) : ι ≫ π = 0 :=
55+
by rw [←kernel.lift_ι _ _ hι, ←cokernel.π_desc _ _ hπ, category.assoc, kernel_comp_cokernel_assoc,
56+
has_zero_morphisms.zero_comp, has_zero_morphisms.comp_zero]
57+
58+
@[simp, reassoc] lemma fork_ι_comp_cofork_π [exact f g] (s : kernel_fork g)
59+
(t : cokernel_cofork f) : fork.ι s ≫ cofork.π t = 0 :=
60+
comp_eq_zero_of_exact f g (kernel_fork.condition s) (cokernel_cofork.condition t)
61+
62+
end
63+
end category_theory

src/algebra/homology/homology.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ category_theory.image_to_kernel_map (C.d i) (C.d (i+b)) (by simp)
103103
@[simp, reassoc]
104104
lemma image_to_kernel_map_condition (C : homological_complex V b) (i : β) :
105105
image_to_kernel_map C i ≫ kernel.ι (C.d (i + b)) = image.ι (C.d i) :=
106-
by simp [image_to_kernel_map, category_theory.image_to_kernel_map]
106+
by simp [image_to_kernel_map]
107107

108108
@[reassoc]
109109
lemma image_to_kernel_map_comp_kernel_map [has_image_maps V]

src/algebra/homology/image_to_kernel_map.lean

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -34,33 +34,24 @@ At this point we assume that we have all images, and all equalizers.
3434
We need to assume all equalizers, not just kernels, so that
3535
`factor_thru_image` is an epimorphism.
3636
-/
37-
variables [has_images V] [has_equalizers V]
37+
variables [has_images V] [has_equalizers V] [has_kernels V]
3838
variables {A B C : V} (f : A ⟶ B) (g : B ⟶ C)
3939

4040
/--
4141
The morphism from `image f` to `kernel g` when `f ≫ g = 0`.
4242
-/
43-
def image_to_kernel_map (w : f ≫ g = 0) :
43+
abbreviation image_to_kernel_map (w : f ≫ g = 0) :
4444
image f ⟶ kernel g :=
4545
kernel.lift g (image.ι f) $ (cancel_epi (factor_thru_image f)).1 $ by simp [w]
4646

47-
instance image_to_kernel_map_mono {w : f ≫ g = 0} : mono (image_to_kernel_map f g w) :=
48-
begin
49-
dsimp [image_to_kernel_map],
50-
apply_instance,
51-
end
52-
5347
@[simp]
5448
lemma image_to_kernel_map_zero_left [has_zero_object V] {w} :
5549
image_to_kernel_map (0 : A ⟶ B) g w = 0 :=
56-
by simp [image_to_kernel_map]
50+
by { delta image_to_kernel_map, simp }
5751

5852
lemma image_to_kernel_map_zero_right {w} :
5953
image_to_kernel_map f (0 : B ⟶ C) w = image.ι f ≫ inv (kernel.ι (0 : B ⟶ C)) :=
60-
begin
61-
ext,
62-
simp [image_to_kernel_map],
63-
end
54+
by { ext, simp }
6455

6556
local attribute [instance] has_zero_object.has_zero
6657

src/category_theory/abelian/basic.lean

Lines changed: 45 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,12 @@ working with has natively.
5252
5353
## Implementation notes
5454
55-
The typeclass `abelian` does not extend `non_preadditive_abelian`,
56-
to avoid having to deal with comparing the two `has_zero_morphisms` instances
57-
(one from `preadditive` in `abelian`, and the other a field of `non_preadditive_abelian`).
58-
As a consequence, at the beginning of this file we trivially build
59-
a `non_preadditive_abelian` instance from an `abelian` instance,
60-
and use this to restate a number of theorems,
55+
The typeclass `abelian` does not extend `non_preadditive_abelian`,
56+
to avoid having to deal with comparing the two `has_zero_morphisms` instances
57+
(one from `preadditive` in `abelian`, and the other a field of `non_preadditive_abelian`).
58+
As a consequence, at the beginning of this file we trivially build
59+
a `non_preadditive_abelian` instance from an `abelian` instance,
60+
and use this to restate a number of theorems,
6161
in each case just reusing the proof from `non_preadditive_abelian.lean`.
6262
6363
We don't show this yet, but abelian categories are finitely complete and finitely cocomplete.
@@ -128,7 +128,8 @@ section to_non_preadditive_abelian
128128

129129
local attribute [instance] has_finite_biproducts
130130

131-
@[priority 100] instance non_preadditive_abelian : non_preadditive_abelian C := { ..‹abelian C› }
131+
/-- Every abelian category is, in particular, `non_preadditive_abelian`. -/
132+
def non_preadditive_abelian : non_preadditive_abelian C := { ..‹abelian C› }
132133

133134
end to_non_preadditive_abelian
134135

@@ -152,83 +153,92 @@ is_iso_of_mono_of_strong_epi _
152153
end mono_epi_iso
153154

154155
section factor
156+
local attribute [instance] non_preadditive_abelian
155157

156158
variables {P Q : C} (f : P ⟶ Q)
157159

160+
namespace images
161+
158162
/-- The kernel of the cokernel of `f` is called the image of `f`. -/
159163
protected abbreviation image : C := kernel (cokernel.π f)
160164

161165
/-- The inclusion of the image into the codomain. -/
162-
protected abbreviation image.ι : abelian.image f ⟶ Q :=
166+
protected abbreviation image.ι : images.image f ⟶ Q :=
163167
kernel.ι (cokernel.π f)
164168

165169
/-- There is a canonical epimorphism `p : P ⟶ image f` for every `f`. -/
166-
protected abbreviation factor_thru_image : P ⟶ abelian.image f :=
170+
protected abbreviation factor_thru_image : P ⟶ images.image f :=
167171
kernel.lift (cokernel.π f) f $ cokernel.condition f
168172

169173
/-- `f` factors through its image via the canonical morphism `p`. -/
170174
@[simp, reassoc] protected lemma image.fac :
171-
abelian.factor_thru_image f ≫ image.ι f = f :=
175+
images.factor_thru_image f ≫ image.ι f = f :=
172176
kernel.lift_ι _ _ _
173177

174178
/-- The map `p : P ⟶ image f` is an epimorphism -/
175-
instance : epi (abelian.factor_thru_image f) :=
179+
instance : epi (images.factor_thru_image f) :=
176180
show epi (non_preadditive_abelian.factor_thru_image f), by apply_instance
177181

178-
instance mono_factor_thru_image [mono f] : mono (abelian.factor_thru_image f) :=
182+
instance mono_factor_thru_image [mono f] : mono (images.factor_thru_image f) :=
179183
mono_of_mono_fac $ image.fac f
180184

181-
instance is_iso_factor_thru_image [mono f] : is_iso (abelian.factor_thru_image f) :=
185+
instance is_iso_factor_thru_image [mono f] : is_iso (images.factor_thru_image f) :=
182186
is_iso_of_mono_of_epi _
183187

184188
/-- Factoring through the image is a strong epi-mono factorisation. -/
185189
@[simps] def image_strong_epi_mono_factorisation : strong_epi_mono_factorisation f :=
186-
{ I := abelian.image f,
190+
{ I := images.image f,
187191
m := image.ι f,
188192
m_mono := by apply_instance,
189-
e := abelian.factor_thru_image f,
193+
e := images.factor_thru_image f,
190194
e_strong_epi := strong_epi_of_epi _ }
191195

196+
end images
197+
198+
namespace coimages
199+
192200
/-- The cokernel of the kernel of `f` is called the coimage of `f`. -/
193201
protected abbreviation coimage : C := cokernel (kernel.ι f)
194202

195203
/-- The projection onto the coimage. -/
196-
protected abbreviation coimage.π : P ⟶ abelian.coimage f :=
204+
protected abbreviation coimage.π : P ⟶ coimages.coimage f :=
197205
cokernel.π (kernel.ι f)
198206

199207
/-- There is a canonical monomorphism `i : coimage f ⟶ Q`. -/
200-
protected abbreviation factor_thru_coimage : abelian.coimage f ⟶ Q :=
208+
protected abbreviation factor_thru_coimage : coimages.coimage f ⟶ Q :=
201209
cokernel.desc (kernel.ι f) f $ kernel.condition f
202210

203211
/-- `f` factors through its coimage via the canonical morphism `p`. -/
204-
protected lemma coimage.fac : coimage.π f ≫ abelian.factor_thru_coimage f = f :=
212+
protected lemma coimage.fac : coimage.π f ≫ coimages.factor_thru_coimage f = f :=
205213
cokernel.π_desc _ _ _
206214

207215
/-- The canonical morphism `i : coimage f ⟶ Q` is a monomorphism -/
208-
instance : mono (abelian.factor_thru_coimage f) :=
216+
instance : mono (coimages.factor_thru_coimage f) :=
209217
show mono (non_preadditive_abelian.factor_thru_coimage f), by apply_instance
210218

211-
instance epi_factor_thru_coimage [epi f] : epi (abelian.factor_thru_coimage f) :=
219+
instance epi_factor_thru_coimage [epi f] : epi (coimages.factor_thru_coimage f) :=
212220
epi_of_epi_fac $ coimage.fac f
213221

214-
instance is_iso_factor_thru_coimage [epi f] : is_iso (abelian.factor_thru_coimage f) :=
222+
instance is_iso_factor_thru_coimage [epi f] : is_iso (coimages.factor_thru_coimage f) :=
215223
is_iso_of_mono_of_epi _
216224

217225
/-- Factoring through the coimage is a strong epi-mono factorisation. -/
218226
@[simps] def coimage_strong_epi_mono_factorisation : strong_epi_mono_factorisation f :=
219-
{ I := abelian.coimage f,
220-
m := abelian.factor_thru_coimage f,
227+
{ I := coimages.coimage f,
228+
m := coimages.factor_thru_coimage f,
221229
m_mono := by apply_instance,
222230
e := coimage.π f,
223231
e_strong_epi := strong_epi_of_epi _ }
224232

233+
end coimages
234+
225235
end factor
226236

227237
section has_strong_epi_mono_factorisations
228238

229239
/-- An abelian category has strong epi-mono factorisations. -/
230240
@[priority 100] instance : has_strong_epi_mono_factorisations C :=
231-
⟨λ X Y f, image_strong_epi_mono_factorisation f⟩
241+
⟨λ X Y f, images.image_strong_epi_mono_factorisation f⟩
232242

233243
/- In particular, this means that it has well-behaved images. -/
234244
example : has_images C := by apply_instance
@@ -239,22 +249,26 @@ end has_strong_epi_mono_factorisations
239249
section images
240250
variables {X Y : C} (f : X ⟶ Y)
241251

242-
lemma image_eq_image : limits.image f = abelian.image f := rfl
252+
lemma image_eq_image : limits.image f = images.image f := rfl
243253

244254
/-- There is a canonical isomorphism between the coimage and the image of a morphism. -/
245-
abbreviation coimage_iso_image : abelian.coimage f ≅ abelian.image f :=
246-
is_image.iso_ext (coimage_strong_epi_mono_factorisation f).to_mono_is_image
247-
(image_strong_epi_mono_factorisation f).to_mono_is_image
255+
abbreviation coimage_iso_image : coimages.coimage f ≅ images.image f :=
256+
is_image.iso_ext (coimages.coimage_strong_epi_mono_factorisation f).to_mono_is_image
257+
(images.image_strong_epi_mono_factorisation f).to_mono_is_image
248258

249-
lemma full_image_factorisation : coimage.π f ≫ (coimage_iso_image f).hom ≫ image.ι f = f :=
250-
by rw [limits.is_image.iso_ext_hom, ←image_strong_epi_mono_factorisation_to_mono_factorisation_m,
251-
is_image.lift_fac, coimage_strong_epi_mono_factorisation_to_mono_factorisation_m, coimage.fac]
259+
lemma full_image_factorisation : coimages.coimage.π f ≫ (coimage_iso_image f).hom ≫
260+
images.image.ι f = f :=
261+
by rw [limits.is_image.iso_ext_hom,
262+
←images.image_strong_epi_mono_factorisation_to_mono_factorisation_m, is_image.lift_fac,
263+
coimages.coimage_strong_epi_mono_factorisation_to_mono_factorisation_m, coimages.coimage.fac]
252264

253265
end images
254266

255267
section cokernel_of_kernel
256268
variables {X Y : C} {f : X ⟶ Y}
257269

270+
local attribute [instance] non_preadditive_abelian
271+
258272
/-- In an abelian category, an epi is the cokernel of its kernel. More precisely:
259273
If `f` is an epimorphism and `s` is some limit kernel cone on `f`, then `f` is a cokernel
260274
of `fork.ι s`. -/
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/-
2+
Copyright (c) 2020 Markus Himmel. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Markus Himmel
5+
-/
6+
import category_theory.abelian.basic
7+
import algebra.homology.exact
8+
9+
/-!
10+
# Exact sequences in abelian categories
11+
12+
We prove that in an abelian category, `(f, g)` is exact if and only if `f ≫ g = 0` and
13+
`kernel.ι g ≫ cokernel.π f = 0`.
14+
15+
-/
16+
17+
universes v u
18+
19+
open category_theory
20+
open category_theory.limits
21+
open category_theory.preadditive
22+
23+
variables {C : Type u} [category.{v} C] [abelian C]
24+
25+
namespace category_theory.abelian
26+
variables {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ Z)
27+
28+
local attribute [instance] has_equalizers_of_has_kernels
29+
30+
theorem exact_iff : exact f g ↔ f ≫ g = 0 ∧ kernel.ι g ≫ cokernel.π f = 0 :=
31+
begin
32+
split,
33+
{ introI h,
34+
exact ⟨h.1, kernel_comp_cokernel f g⟩ },
35+
{ refine λ h, ⟨h.1, _⟩,
36+
suffices hl :
37+
is_limit (kernel_fork.of_ι (image.ι f) ((epi_iff_cancel_zero (factor_thru_image f)).1
38+
(by apply_instance) _ (image.ι f ≫ g) (by simp [h.1]))),
39+
{ have : image_to_kernel_map f g h.1 =
40+
(is_limit.cone_point_unique_up_to_iso hl (limit.is_limit _)).hom,
41+
{ ext, simp },
42+
rw this,
43+
apply_instance },
44+
refine is_limit.of_ι _ _ _ _ _,
45+
{ refine λ W u hu, kernel.lift (cokernel.π f) u _,
46+
rw [←kernel.lift_ι g u hu, category.assoc, h.2, has_zero_morphisms.comp_zero] },
47+
{ exact λ _ _ _, kernel.lift_ι _ _ _ },
48+
{ tidy } }
49+
end
50+
51+
theorem exact_iff' {cg : kernel_fork g} (hg : is_limit cg)
52+
{cf : cokernel_cofork f} (hf : is_colimit cf) : exact f g ↔ f ≫ g = 0 ∧ cg.ι ≫ cf.π = 0 :=
53+
begin
54+
split,
55+
{ introI h,
56+
exact ⟨h.1, fork_ι_comp_cofork_π f g cg cf⟩ },
57+
{ rw exact_iff,
58+
refine λ h, ⟨h.1, _⟩,
59+
apply zero_of_epi_comp (is_limit.cone_point_unique_up_to_iso hg (limit.is_limit _)).hom,
60+
apply zero_of_comp_mono (is_colimit.cocone_point_unique_up_to_iso (colimit.is_colimit _) hf).hom,
61+
simp [h.2] }
62+
end
63+
64+
end category_theory.abelian

0 commit comments

Comments
 (0)