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

Commit a52f471

Browse files
committed
feat(algebra/homology): chain complexes are an additive category (#7478)
Co-authored-by: Scott Morrison <scott.morrison@gmail.com>
1 parent f8dc722 commit a52f471

File tree

2 files changed

+243
-1
lines changed

2 files changed

+243
-1
lines changed

src/algebra/homology/additive.lean

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
/-
2+
Copyright (c) 2021 Scott Morrison. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Scott Morrison
5+
-/
6+
import algebra.homology.homology
7+
import algebra.homology.single
8+
import category_theory.preadditive.additive_functor
9+
10+
/-!
11+
# Homology is an additive functor
12+
13+
When `V` is preadditive, `homological_complex V c` is also preadditive,
14+
and `homology_functor` is additive.
15+
16+
TODO: similarly for `R`-linear.
17+
-/
18+
19+
universes v u
20+
21+
open_locale classical
22+
noncomputable theory
23+
24+
open category_theory category_theory.limits homological_complex
25+
26+
variables {ι : Type*}
27+
variables {V : Type u} [category.{v} V] [preadditive V]
28+
29+
variables {c : complex_shape ι} {C D E : homological_complex V c}
30+
variables (f g : C ⟶ D) (h k : D ⟶ E) (i : ι)
31+
32+
namespace homological_complex
33+
34+
instance : has_zero (C ⟶ D) := ⟨{ f := λ i, 0 }⟩
35+
instance : has_add (C ⟶ D) := ⟨λ f g, { f := λ i, f.f i + g.f i, }⟩
36+
instance : has_neg (C ⟶ D) := ⟨λ f, { f := λ i, -(f.f i), }⟩
37+
instance : has_sub (C ⟶ D) := ⟨λ f g, { f := λ i, f.f i - g.f i, }⟩
38+
39+
@[simp] lemma zero_f_apply (i : ι) : (0 : C ⟶ D).f i = 0 := rfl
40+
@[simp] lemma add_f_apply (f g : C ⟶ D) (i : ι) : (f + g).f i = f.f i + g.f i := rfl
41+
@[simp] lemma neg_f_apply (f : C ⟶ D) (i : ι) : (-f).f i = -(f.f i) := rfl
42+
@[simp] lemma sub_f_apply (f g : C ⟶ D) (i : ι) : (f - g).f i = f.f i - g.f i := rfl
43+
44+
45+
/- TODO(jmc/Scott): the instance below doesn't have the correct defeq for `nsmul` and `gsmul`.
46+
We should generalize `function.injective.add_comm_group` and friends.
47+
For the `R`-linear version, it will be very convenient to have
48+
a good definition of `nsmul` and `gsmul` that matches `smul`. -/
49+
50+
instance : add_comm_group (C ⟶ D) :=
51+
function.injective.add_comm_group hom.f
52+
homological_complex.hom_f_injective (by tidy) (by tidy) (by tidy) (by tidy)
53+
54+
instance : preadditive (homological_complex V c) := {}
55+
56+
end homological_complex
57+
58+
namespace homological_complex
59+
60+
variables [has_zero_object V]
61+
62+
instance cycles_additive [has_equalizers V] : (cycles_functor V c i).additive := {}
63+
64+
variables [has_images V] [has_image_maps V]
65+
66+
instance boundaries_additive : (boundaries_functor V c i).additive := {}
67+
68+
variables [has_equalizers V] [has_cokernels V]
69+
70+
instance homology_additive : (homology_functor V c i).additive :=
71+
{ map_zero' := λ C D, begin
72+
dsimp [homology_functor],
73+
ext,
74+
simp only [limits.cokernel.π_desc, limits.comp_zero, homology.π_map],
75+
convert zero_comp,
76+
ext,
77+
simp,
78+
end,
79+
map_add' := λ C D f g, begin
80+
dsimp [homology_functor],
81+
ext,
82+
simp only [homology.π_map, preadditive.comp_add, ←preadditive.add_comp],
83+
congr,
84+
ext, simp,
85+
end }
86+
87+
88+
end homological_complex
89+
90+
namespace category_theory
91+
92+
variables {W : Type*} [category W] [preadditive W]
93+
94+
/--
95+
An additive functor induces a functor between homological complexes.
96+
This is sometimes called the "prolongation".
97+
-/
98+
@[simps]
99+
def functor.map_homological_complex (F : V ⥤ W) [F.additive] (c : complex_shape ι) :
100+
homological_complex V c ⥤ homological_complex W c :=
101+
{ obj := λ C,
102+
{ X := λ i, F.obj (C.X i),
103+
d := λ i j, F.map (C.d i j),
104+
shape' := λ i j w, by rw [C.shape _ _ w, F.map_zero],
105+
d_comp_d' := λ i j k, by rw [←F.map_comp, C.d_comp_d, F.map_zero], },
106+
map := λ C D f,
107+
{ f := λ i, F.map (f.f i),
108+
comm' := λ i j, by { dsimp, rw [←F.map_comp, ←F.map_comp, f.comm], }, }, }.
109+
110+
instance functor.map_homogical_complex_additive
111+
(F : V ⥤ W) [F.additive] (c : complex_shape ι) : (F.map_homological_complex c).additive := {}
112+
113+
/--
114+
A natural transformation between functors induces a natural transformation
115+
between those functors applied to homological complexes.
116+
-/
117+
@[simps]
118+
def nat_trans.map_homological_complex {F G : V ⥤ W} [F.additive] [G.additive]
119+
(α : F ⟶ G) (c : complex_shape ι) : F.map_homological_complex c ⟶ G.map_homological_complex c :=
120+
{ app := λ C, { f := λ i, α.app _, }, }
121+
122+
@[simp] lemma nat_trans.map_homological_complex_id (c : complex_shape ι) (F : V ⥤ W) [F.additive] :
123+
nat_trans.map_homological_complex (𝟙 F) c = 𝟙 (F.map_homological_complex c) :=
124+
by tidy
125+
126+
@[simp] lemma nat_trans.map_homological_complex_comp (c : complex_shape ι)
127+
{F G H : V ⥤ W} [F.additive] [G.additive] [H.additive]
128+
(α : F ⟶ G) (β : G ⟶ H):
129+
nat_trans.map_homological_complex (α ≫ β) c =
130+
nat_trans.map_homological_complex α c ≫ nat_trans.map_homological_complex β c :=
131+
by tidy
132+
133+
@[simp, reassoc] lemma nat_trans.map_homological_complex_naturality {c : complex_shape ι}
134+
{F G : V ⥤ W} [F.additive] [G.additive] (α : F ⟶ G) {C D : homological_complex V c} (f : C ⟶ D) :
135+
(F.map_homological_complex c).map f ≫ (nat_trans.map_homological_complex α c).app D =
136+
(nat_trans.map_homological_complex α c).app C ≫ (G.map_homological_complex c).map f :=
137+
by tidy
138+
139+
end category_theory
140+
141+
variables [has_zero_object V] {W : Type*} [category W] [preadditive W] [has_zero_object W]
142+
143+
namespace homological_complex
144+
145+
/--
146+
Turning an object into a complex supported at `j` then applying a functor is
147+
the same as applying the functor then forming the complex.
148+
-/
149+
def single_map_homological_complex (F : V ⥤ W) [F.additive] (c : complex_shape ι) (j : ι):
150+
single V c j ⋙ F.map_homological_complex _ ≅ F ⋙ single W c j :=
151+
nat_iso.of_components (λ X,
152+
{ hom := { f := λ i, if h : i = j then
153+
eq_to_hom (by simp [h])
154+
else
155+
0, },
156+
inv := { f := λ i, if h : i = j then
157+
eq_to_hom (by simp [h])
158+
else
159+
0, },
160+
hom_inv_id' := begin
161+
ext i,
162+
dsimp,
163+
split_ifs with h,
164+
{ simp [h] },
165+
{ rw [zero_comp, if_neg h],
166+
exact (zero_of_source_iso_zero _ F.map_zero_object).symm, },
167+
end,
168+
inv_hom_id' := begin
169+
ext i,
170+
dsimp,
171+
split_ifs with h,
172+
{ simp [h] },
173+
{ rw [zero_comp, if_neg h],
174+
simp, },
175+
end, })
176+
(λ X Y f, begin
177+
ext i,
178+
dsimp,
179+
split_ifs with h; simp [h],
180+
end).
181+
182+
variables (F : V ⥤ W) [functor.additive F] (c)
183+
184+
@[simp] lemma single_map_homological_complex_hom_app_self (j : ι) (X : V) :
185+
((single_map_homological_complex F c j).hom.app X).f j = eq_to_hom (by simp) :=
186+
by simp [single_map_homological_complex]
187+
@[simp] lemma single_map_homological_complex_hom_app_ne
188+
{i j : ι} (h : i ≠ j) (X : V) :
189+
((single_map_homological_complex F c j).hom.app X).f i = 0 :=
190+
by simp [single_map_homological_complex, h]
191+
@[simp] lemma single_map_homological_complex_inv_app_self (j : ι) (X : V) :
192+
((single_map_homological_complex F c j).inv.app X).f j = eq_to_hom (by simp) :=
193+
by simp [single_map_homological_complex]
194+
@[simp] lemma single_map_homological_complex_inv_app_ne
195+
{i j : ι} (h : i ≠ j) (X : V):
196+
((single_map_homological_complex F c j).inv.app X).f i = 0 :=
197+
by simp [single_map_homological_complex, h]
198+
199+
end homological_complex
200+
201+
namespace chain_complex
202+
203+
-- TODO: dualize to cochain complexes
204+
205+
/--
206+
Turning an object into a chain complex supported at zero then applying a functor is
207+
the same as applying the functor then forming the complex.
208+
-/
209+
def single₀_map_homological_complex (F : V ⥤ W) [F.additive] :
210+
single₀ V ⋙ F.map_homological_complex _ ≅ F ⋙ single₀ W :=
211+
nat_iso.of_components (λ X,
212+
{ hom := { f := λ i, match i with
213+
| 0 := 𝟙 _
214+
| (i+1) := F.map_zero_object.hom
215+
end, },
216+
inv := { f := λ i, match i with
217+
| 0 := 𝟙 _
218+
| (i+1) := F.map_zero_object.inv
219+
end, },
220+
hom_inv_id' := begin
221+
ext (_|i),
222+
{ unfold_aux, simp, },
223+
{ unfold_aux,
224+
dsimp,
225+
simp only [comp_f, id_f, zero_comp],
226+
exact (zero_of_source_iso_zero _ F.map_zero_object).symm, }
227+
end,
228+
inv_hom_id' := by { ext (_|i); { unfold_aux, dsimp, simp, }, }, })
229+
(λ X Y f, by { ext (_|i); { unfold_aux, dsimp, simp, }, }).
230+
231+
@[simp] lemma single₀_map_homological_complex_hom_app_zero (F : V ⥤ W) [F.additive] (X : V) :
232+
((single₀_map_homological_complex F).hom.app X).f 0 = 𝟙 _ := rfl
233+
@[simp] lemma single₀_map_homological_complex_hom_app_succ
234+
(F : V ⥤ W) [F.additive] (X : V) (n : ℕ) :
235+
((single₀_map_homological_complex F).hom.app X).f (n+1) = 0 := rfl
236+
@[simp] lemma single₀_map_homological_complex_inv_app_zero (F : V ⥤ W) [F.additive] (X : V) :
237+
((single₀_map_homological_complex F).inv.app X).f 0 = 𝟙 _ := rfl
238+
@[simp] lemma single₀_map_homological_complex_inv_app_succ
239+
(F : V ⥤ W) [F.additive] (X : V) (n : ℕ) :
240+
((single₀_map_homological_complex F).inv.app X).f (n+1) = 0 := rfl
241+
242+
end chain_complex

src/algebra/homology/single.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ local attribute [instance] has_zero_object.has_zero
3737
/--
3838
The functor `V ⥤ homological_complex V c` creating a chain complex supported in a single degree.
3939
40-
See also `chain_complex.single_0 : V ⥤ chain_complex V ℕ`,
40+
See also `chain_complex.single₀ : V ⥤ chain_complex V ℕ`,
4141
which has better definitional properties,
4242
if you are working with `ℕ`-indexed complexes.
4343
-/

0 commit comments

Comments
 (0)