Skip to content

Commit 13f0f7a

Browse files
committed
feat: Functor.mapDerivedCategory is a triangulated functor (#14153)
In this PR, it is shown that an exact functor between abelian categories induces a triangulated functor between the corresponding derived categories.
1 parent a365570 commit 13f0f7a

File tree

4 files changed

+209
-12
lines changed

4 files changed

+209
-12
lines changed

Mathlib/Algebra/Homology/DerivedCategory/ExactFunctor.lean

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,9 @@ import Mathlib.Algebra.Homology.DerivedCategory.Basic
99
# An exact functor induces a functor on derived categories
1010
1111
In this file, we show that if `F : C₁ ⥤ C₂` is an exact functor between
12-
abelian categories, then there is an induced functor
12+
abelian categories, then there is an induced triangulated functor
1313
`F.mapDerivedCategory : DerivedCategory C₁ ⥤ DerivedCategory C₂`.
1414
15-
## TODO
16-
* show that `F.mapDerivedCategory` is a triangulated functor
17-
1815
-/
1916

2017
universe w₁ w₂ v₁ v₂ u₁ u₂
@@ -58,4 +55,19 @@ noncomputable instance :
5855
(F.mapHomotopyCategory _ ⋙ DerivedCategory.Qh) F.mapDerivedCategory :=
5956
⟨F.mapDerivedCategoryFactorsh⟩
6057

58+
noncomputable instance : F.mapDerivedCategory.CommShift ℤ :=
59+
Functor.commShiftOfLocalization DerivedCategory.Qh
60+
(HomotopyCategory.quasiIso C₁ (ComplexShape.up ℤ)) ℤ
61+
(F.mapHomotopyCategory _ ⋙ DerivedCategory.Qh)
62+
F.mapDerivedCategory
63+
64+
instance : NatTrans.CommShift F.mapDerivedCategoryFactorsh.hom ℤ :=
65+
inferInstanceAs (NatTrans.CommShift (Localization.Lifting.iso
66+
DerivedCategory.Qh (HomotopyCategory.quasiIso C₁ (ComplexShape.up ℤ))
67+
(F.mapHomotopyCategory _ ⋙ DerivedCategory.Qh)
68+
F.mapDerivedCategory).hom ℤ)
69+
70+
instance : F.mapDerivedCategory.IsTriangulated :=
71+
Functor.isTriangulated_of_precomp_iso F.mapDerivedCategoryFactorsh
72+
6173
end CategoryTheory.Functor

Mathlib/CategoryTheory/Localization/Predicate.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ instance id : Lifting L W L (𝟭 D) :=
387387
@[simps]
388388
instance compLeft (F : D ⥤ E) : Localization.Lifting L W (L ⋙ F) F := ⟨Iso.refl _⟩
389389

390+
@[simp]
391+
lemma compLeft_iso (F : D ⥤ E) : Localization.Lifting.iso L W (L ⋙ F) F = Iso.refl _ := rfl
392+
390393
/-- Given a localization functor `L : C ⥤ D` for `W : MorphismProperty C`,
391394
if `F₁' : D ⥤ E` lifts a functor `F₁ : C ⥤ D`, then a functor `F₂'` which
392395
is isomorphic to `F₁'` also lifts a functor `F₂` that is isomorphic to `F₁`. -/

Mathlib/CategoryTheory/Shift/Localization.lean

Lines changed: 126 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,12 @@ a shift by `A`, and the localization functor is compatible with the shift.
1818
1919
--/
2020

21-
universe v₁ v₂ u₁ u₂ w
21+
universe v₁ v₂ v₃ u₁ u₂ u₃ w
2222

2323
namespace CategoryTheory
2424

2525
variable {C : Type u₁} {D : Type u₂} [Category.{v₁} C] [Category.{v₂} D]
26+
{E : Type u₃} [Category.{v₃} E]
2627
(L : C ⥤ D) (W : MorphismProperty C) [L.IsLocalization W]
2728
(A : Type w) [AddMonoid A] [HasShift C A]
2829

@@ -110,4 +111,128 @@ noncomputable instance MorphismProperty.commShift_Q' :
110111

111112
attribute [irreducible] HasShift.localization' MorphismProperty.commShift_Q'
112113

114+
section
115+
116+
open Localization
117+
118+
variable (F : C ⥤ E) (F' : D ⥤ E) [Lifting L W F F']
119+
[HasShift D A] [HasShift E A] [L.CommShift A] [F.CommShift A]
120+
121+
namespace Functor
122+
123+
namespace commShiftOfLocalization
124+
125+
variable {A}
126+
127+
/-- Auxiliary definition for `Functor.commShiftOfLocalization`. -/
128+
noncomputable def iso (a : A) :
129+
shiftFunctor D a ⋙ F' ≅ F' ⋙ shiftFunctor E a :=
130+
Localization.liftNatIso L W (L ⋙ shiftFunctor D a ⋙ F')
131+
(L ⋙ F' ⋙ shiftFunctor E a) _ _
132+
((Functor.associator _ _ _).symm ≪≫
133+
isoWhiskerRight (L.commShiftIso a).symm F' ≪≫
134+
Functor.associator _ _ _ ≪≫
135+
isoWhiskerLeft _ (Lifting.iso L W F F') ≪≫
136+
F.commShiftIso a ≪≫
137+
isoWhiskerRight (Lifting.iso L W F F').symm _ ≪≫ Functor.associator _ _ _)
138+
139+
@[simp, reassoc]
140+
lemma iso_hom_app (a : A) (X : C) :
141+
(commShiftOfLocalization.iso L W F F' a).hom.app (L.obj X) =
142+
F'.map ((L.commShiftIso a).inv.app X) ≫
143+
(Lifting.iso L W F F').hom.app (X⟦a⟧) ≫
144+
(F.commShiftIso a).hom.app X ≫
145+
(shiftFunctor E a).map ((Lifting.iso L W F F').inv.app X) := by
146+
simp [commShiftOfLocalization.iso]
147+
148+
@[simp, reassoc]
149+
lemma iso_inv_app (a : A) (X : C) :
150+
(commShiftOfLocalization.iso L W F F' a).inv.app (L.obj X) =
151+
(shiftFunctor E a).map ((Lifting.iso L W F F').hom.app X) ≫
152+
(F.commShiftIso a).inv.app X ≫
153+
(Lifting.iso L W F F').inv.app (X⟦a⟧) ≫
154+
F'.map ((L.commShiftIso a).hom.app X) := by
155+
simp [commShiftOfLocalization.iso]
156+
157+
end commShiftOfLocalization
158+
159+
/-- In the context of localization of categories, if a functor
160+
is induced by a functor which commutes with the shift, then
161+
this functor commutes with the shift. -/
162+
noncomputable def commShiftOfLocalization : F'.CommShift A where
163+
iso := commShiftOfLocalization.iso L W F F'
164+
zero := by
165+
ext1
166+
apply natTrans_ext L W
167+
intro X
168+
dsimp
169+
simp only [commShiftOfLocalization.iso_hom_app, comp_obj, commShiftIso_zero,
170+
CommShift.isoZero_inv_app, map_comp, CommShift.isoZero_hom_app, Category.assoc,
171+
← NatTrans.naturality_assoc, ← NatTrans.naturality]
172+
dsimp
173+
simp only [← Functor.map_comp_assoc, ← Functor.map_comp,
174+
Iso.inv_hom_id_app, id_obj, map_id, Category.id_comp, Iso.hom_inv_id_app_assoc]
175+
add a b := by
176+
ext1
177+
apply natTrans_ext L W
178+
intro X
179+
dsimp
180+
simp only [commShiftOfLocalization.iso_hom_app, comp_obj, commShiftIso_add,
181+
CommShift.isoAdd_inv_app, map_comp, CommShift.isoAdd_hom_app, Category.assoc]
182+
congr 1
183+
rw [← cancel_epi (F'.map ((shiftFunctor D b).map ((L.commShiftIso a).hom.app X))),
184+
← F'.map_comp_assoc, ← map_comp, Iso.hom_inv_id_app, map_id, map_id, Category.id_comp]
185+
conv_lhs =>
186+
erw [← NatTrans.naturality_assoc]
187+
dsimp
188+
rw [← Functor.map_comp_assoc, ← map_comp_assoc, Category.assoc,
189+
← map_comp, Iso.inv_hom_id_app]
190+
dsimp
191+
rw [map_id, Category.comp_id, ← NatTrans.naturality]
192+
dsimp
193+
conv_rhs =>
194+
erw [← NatTrans.naturality_assoc]
195+
dsimp
196+
rw [← Functor.map_comp_assoc, ← map_comp, Iso.hom_inv_id_app]
197+
dsimp
198+
rw [map_id, map_id, Category.id_comp, commShiftOfLocalization.iso_hom_app,
199+
Category.assoc, Category.assoc, Category.assoc, ← map_comp_assoc,
200+
Iso.inv_hom_id_app, map_id, Category.id_comp]
201+
202+
variable {A}
203+
204+
lemma commShiftOfLocalization_iso_hom_app (a : A) (X : C) :
205+
letI := Functor.commShiftOfLocalization L W A F F'
206+
(F'.commShiftIso a).hom.app (L.obj X) =
207+
F'.map ((L.commShiftIso a).inv.app X) ≫ (Lifting.iso L W F F').hom.app (X⟦a⟧) ≫
208+
(F.commShiftIso a).hom.app X ≫
209+
(shiftFunctor E a).map ((Lifting.iso L W F F').inv.app X) := by
210+
apply commShiftOfLocalization.iso_hom_app
211+
212+
lemma commShiftOfLocalization_iso_inv_app (a : A) (X : C) :
213+
letI := Functor.commShiftOfLocalization L W A F F'
214+
(F'.commShiftIso a).inv.app (L.obj X) =
215+
(shiftFunctor E a).map ((Lifting.iso L W F F').hom.app X) ≫
216+
(F.commShiftIso a).inv.app X ≫ (Lifting.iso L W F F').inv.app (X⟦a⟧) ≫
217+
F'.map ((L.commShiftIso a).hom.app X) := by
218+
apply commShiftOfLocalization.iso_inv_app
219+
220+
end Functor
221+
222+
instance NatTrans.commShift_iso_hom_of_localization :
223+
letI := Functor.commShiftOfLocalization L W A F F'
224+
NatTrans.CommShift (Lifting.iso L W F F').hom A := by
225+
letI := Functor.commShiftOfLocalization L W A F F'
226+
constructor
227+
intro a
228+
ext X
229+
simp only [comp_app, whiskerRight_app, whiskerLeft_app,
230+
Functor.commShiftIso_comp_hom_app,
231+
Functor.commShiftOfLocalization_iso_hom_app,
232+
Category.assoc, ← Functor.map_comp, ← Functor.map_comp_assoc,
233+
Iso.hom_inv_id_app, Functor.map_id, Iso.inv_hom_id_app,
234+
Category.comp_id, Category.id_comp, Functor.comp_obj]
235+
236+
end
237+
113238
end CategoryTheory

Mathlib/CategoryTheory/Triangulated/Functor.lean

Lines changed: 64 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,13 @@ noncomputable def mapTriangleInvRotateIso [F.Additive] :
113113
(fun T => Triangle.isoMk _ _ ((F.commShiftIso (-1 : ℤ)).symm.app _) (Iso.refl _) (Iso.refl _)
114114
(by aesop_cat) (by aesop_cat) (by aesop_cat)) (by aesop_cat)
115115

116+
117+
variable (C) in
118+
/-- The canonical isomorphism `(𝟭 C).mapTriangle ≅ 𝟭 (Triangle C)`. -/
119+
@[simps!]
120+
def mapTriangleIdIso : (𝟭 C).mapTriangle ≅ 𝟭 _ :=
121+
NatIso.ofComponents (fun T ↦ Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) (Iso.refl _))
122+
116123
/-- The canonical isomorphism `(F ⋙ G).mapTriangle ≅ F.mapTriangle ⋙ G.mapTriangle`. -/
117124
@[simps!]
118125
def mapTriangleCompIso : (F ⋙ G).mapTriangle ≅ F.mapTriangle ⋙ G.mapTriangle :=
@@ -132,9 +139,11 @@ def mapTriangleIso {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) [F₁.CommShift ℤ
132139

133140
end Additive
134141

135-
variable [HasZeroObject C] [HasZeroObject D] [Preadditive C] [Preadditive D]
142+
variable [HasZeroObject C] [HasZeroObject D] [HasZeroObject E]
143+
[Preadditive C] [Preadditive D] [Preadditive E]
136144
[∀ (n : ℤ), (shiftFunctor C n).Additive] [∀ (n : ℤ), (shiftFunctor D n).Additive]
137-
[Pretriangulated C] [Pretriangulated D]
145+
[∀ (n : ℤ), (shiftFunctor E n).Additive]
146+
[Pretriangulated C] [Pretriangulated D] [Pretriangulated E]
138147

139148
/-- A functor which commutes with the shift by `ℤ` is triangulated if
140149
it sends distinguished triangles to distinguished triangles. -/
@@ -149,9 +158,7 @@ namespace IsTriangulated
149158

150159
open ZeroObject
151160

152-
variable [F.IsTriangulated]
153-
154-
instance (priority := 100) : PreservesZeroMorphisms F where
161+
instance (priority := 100) [F.IsTriangulated] : PreservesZeroMorphisms F where
155162
map_zero X Y := by
156163
have h₁ : (0 : X ⟶ Y) = 0 ≫ 𝟙 00 := by simp
157164
have h₂ : 𝟙 (F.obj 0) = 0 := by
@@ -162,7 +169,8 @@ instance (priority := 100) : PreservesZeroMorphisms F where
162169
infer_instance
163170
rw [h₁, F.map_comp, F.map_comp, F.map_id, h₂, zero_comp, comp_zero]
164171

165-
noncomputable instance : PreservesLimitsOfShape (Discrete WalkingPair) F := by
172+
noncomputable instance [F.IsTriangulated] :
173+
PreservesLimitsOfShape (Discrete WalkingPair) F := by
166174
suffices ∀ (X₁ X₃ : C), IsIso (prodComparison F X₁ X₃) by
167175
have := fun (X₁ X₃ : C) ↦ PreservesLimitPair.ofIsoProdComparison F X₁ X₃
168176
exact ⟨fun {K} ↦ preservesLimitOfIsoDiagram F (diagramIsoPair K).symm⟩
@@ -187,10 +195,59 @@ noncomputable instance : PreservesLimitsOfShape (Discrete WalkingPair) F := by
187195
(binaryProductTriangle_distinguished _ _)
188196
(by dsimp; infer_instance) (by dsimp; infer_instance)
189197

190-
instance (priority := 100) : F.Additive := F.additive_of_preserves_binary_products
198+
instance (priority := 100) [F.IsTriangulated] : F.Additive :=
199+
F.additive_of_preserves_binary_products
200+
201+
instance : (𝟭 C).IsTriangulated where
202+
map_distinguished T hT :=
203+
isomorphic_distinguished _ hT _ ((mapTriangleIdIso C).app T)
204+
205+
instance [F.IsTriangulated] [G.IsTriangulated] : (F ⋙ G).IsTriangulated where
206+
map_distinguished T hT :=
207+
isomorphic_distinguished _ (G.map_distinguished _ (F.map_distinguished T hT)) _
208+
((mapTriangleCompIso F G).app T)
191209

192210
end IsTriangulated
193211

212+
lemma isTriangulated_of_iso {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) [F₁.CommShift ℤ] [F₂.CommShift ℤ]
213+
[NatTrans.CommShift e.hom ℤ] [F₁.IsTriangulated] : F₂.IsTriangulated where
214+
map_distinguished T hT :=
215+
isomorphic_distinguished _ (F₁.map_distinguished T hT) _ ((mapTriangleIso e).app T).symm
216+
217+
lemma isTriangulated_iff_of_iso {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) [F₁.CommShift ℤ] [F₂.CommShift ℤ]
218+
[NatTrans.CommShift e.hom ℤ] : F₁.IsTriangulated ↔ F₂.IsTriangulated := by
219+
constructor
220+
· intro
221+
exact isTriangulated_of_iso e
222+
· intro
223+
have : NatTrans.CommShift e.symm.hom ℤ := inferInstanceAs (NatTrans.CommShift e.inv ℤ)
224+
exact isTriangulated_of_iso e.symm
225+
226+
lemma mem_mapTriangle_essImage_of_distinguished
227+
[F.IsTriangulated] [F.mapArrow.EssSurj] (T : Triangle D) (hT : T ∈ distTriang D) :
228+
∃ (T' : Triangle C) (_ : T' ∈ distTriang C), Nonempty (F.mapTriangle.obj T' ≅ T) := by
229+
obtain ⟨X, Y, f, e₁, e₂, w⟩ : ∃ (X Y : C) (f : X ⟶ Y) (e₁ : F.obj X ≅ T.obj₁)
230+
(e₂ : F.obj Y ≅ T.obj₂), F.map f ≫ e₂.hom = e₁.hom ≫ T.mor₁ := by
231+
let e := F.mapArrow.objObjPreimageIso (Arrow.mk T.mor₁)
232+
exact ⟨_, _, _, Arrow.leftFunc.mapIso e, Arrow.rightFunc.mapIso e, e.hom.w.symm⟩
233+
obtain ⟨W, g, h, H⟩ := distinguished_cocone_triangle f
234+
exact ⟨_, H, ⟨isoTriangleOfIso₁₂ _ _ (F.map_distinguished _ H) hT e₁ e₂ w⟩⟩
235+
236+
lemma isTriangulated_of_precomp
237+
[(F ⋙ G).IsTriangulated] [F.IsTriangulated] [F.mapArrow.EssSurj] :
238+
G.IsTriangulated where
239+
map_distinguished T hT := by
240+
obtain ⟨T', hT', ⟨e⟩⟩ := F.mem_mapTriangle_essImage_of_distinguished T hT
241+
exact isomorphic_distinguished _ ((F ⋙ G).map_distinguished T' hT') _
242+
(G.mapTriangle.mapIso e.symm ≪≫ (mapTriangleCompIso F G).symm.app _)
243+
244+
variable {F G} in
245+
lemma isTriangulated_of_precomp_iso {H : C ⥤ E} (e : F ⋙ G ≅ H) [H.CommShift ℤ]
246+
[H.IsTriangulated] [F.IsTriangulated] [F.mapArrow.EssSurj] [NatTrans.CommShift e.hom ℤ] :
247+
G.IsTriangulated := by
248+
have := (isTriangulated_iff_of_iso e).2 inferInstance
249+
exact isTriangulated_of_precomp F G
250+
194251
end Functor
195252

196253
variable {C D : Type*} [Category C] [Category D] [HasShift C ℤ] [HasShift D ℤ]

0 commit comments

Comments
 (0)