|
| 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 |
0 commit comments