From 0bd158187dd0744055ecb8fcbcebcc85e67f41be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 20 Nov 2025 09:20:14 +0100 Subject: [PATCH 01/60] feat(CategoryTheory): orthogonal of a property of objects --- Mathlib.lean | 2 + .../ObjectProperty/Orthogonal.lean | 71 +++++++++++++++++++ .../Triangulated/Orthogonal.lean | 66 +++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 Mathlib/CategoryTheory/ObjectProperty/Orthogonal.lean create mode 100644 Mathlib/CategoryTheory/Triangulated/Orthogonal.lean diff --git a/Mathlib.lean b/Mathlib.lean index 740188104f3884..b53ca0cb30e4c8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2800,6 +2800,7 @@ public import Mathlib.CategoryTheory.ObjectProperty.LimitsClosure public import Mathlib.CategoryTheory.ObjectProperty.LimitsOfShape public import Mathlib.CategoryTheory.ObjectProperty.Local public import Mathlib.CategoryTheory.ObjectProperty.Opposite +public import Mathlib.CategoryTheory.ObjectProperty.Orthogonal public import Mathlib.CategoryTheory.ObjectProperty.Retract public import Mathlib.CategoryTheory.ObjectProperty.Shift public import Mathlib.CategoryTheory.ObjectProperty.Small @@ -2999,6 +3000,7 @@ public import Mathlib.CategoryTheory.Triangulated.Opposite.Basic public import Mathlib.CategoryTheory.Triangulated.Opposite.Functor public import Mathlib.CategoryTheory.Triangulated.Opposite.Pretriangulated public import Mathlib.CategoryTheory.Triangulated.Opposite.Triangle +public import Mathlib.CategoryTheory.Triangulated.Orthogonal public import Mathlib.CategoryTheory.Triangulated.Pretriangulated public import Mathlib.CategoryTheory.Triangulated.Rotate public import Mathlib.CategoryTheory.Triangulated.Subcategory diff --git a/Mathlib/CategoryTheory/ObjectProperty/Orthogonal.lean b/Mathlib/CategoryTheory/ObjectProperty/Orthogonal.lean new file mode 100644 index 00000000000000..0d332471d7b1f5 --- /dev/null +++ b/Mathlib/CategoryTheory/ObjectProperty/Orthogonal.lean @@ -0,0 +1,71 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero + +/-! +# Orthogonal of a property of objects + +Let `P` be a property of objects in a category with zero morphisms. +We define `P.rightOrthogonal` as the property of objects `Y` such that +any map `f : X ⟶ Y` vanishes when `P X` holds. Similarly, we define +`P.leftOrthogonal` as the property of objects `X` such that +any map `f : X ⟶ Y` vanishes when `P Y` holds. + +-/ + +@[expose] public section + +universe v u + +namespace CategoryTheory + +open Limits ZeroObject + +variable {C : Type u} [Category.{v} C] [HasZeroMorphisms C] + +namespace ObjectProperty + +variable (P : ObjectProperty C) + +/-- In a category with zero morphisms, the right orthogonal of a property of objects `P` +is the property of objects `Y` such that any map `X ⟶ Y` vanishes when `P X` holds. -/ +@[stacks 0FXB] +def rightOrthogonal : ObjectProperty C := + fun Y ↦ ∀ ⦃X : C⦄ (f : X ⟶ Y), P X → f = 0 + +lemma rightOrthogonal_iff (Y : C) : + P.rightOrthogonal Y ↔ ∀ ⦃X : C⦄ (f : X ⟶ Y), P X → f = 0 := Iff.rfl + +/-- In a category with zero morphisms, the left orthogonal of a property of objects `P` +is the property of objects `X` such that any map `X ⟶ Y` vanishes when `P Y` holds. -/ +@[stacks 0FXB] +def leftOrthogonal : ObjectProperty C := + fun X ↦ ∀ ⦃Y : C⦄ (f : X ⟶ Y), P Y → f = 0 + +lemma leftOrthogonal_iff (X : C) : + P.leftOrthogonal X ↔ ∀ ⦃Y : C⦄ (f : X ⟶ Y), P Y → f = 0 := Iff.rfl + +instance : P.rightOrthogonal.IsClosedUnderIsomorphisms where + of_iso e h X f hX := by + rw [← cancel_mono e.inv, zero_comp] + exact h _ hX + +instance : P.leftOrthogonal.IsClosedUnderIsomorphisms where + of_iso e h Y f hY := by + rw [← cancel_epi e.hom, comp_zero] + exact h _ hY + +instance [HasZeroObject C] : P.rightOrthogonal.ContainsZero where + exists_zero := ⟨0, isZero_zero _, fun _ _ _ ↦ by ext⟩ + +instance [HasZeroObject C] : P.leftOrthogonal.ContainsZero where + exists_zero := ⟨0, isZero_zero _, fun _ _ _ ↦ by ext⟩ + +end ObjectProperty + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean new file mode 100644 index 00000000000000..16e247f411faa2 --- /dev/null +++ b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean @@ -0,0 +1,66 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.CategoryTheory.ObjectProperty.Orthogonal +public import Mathlib.CategoryTheory.Triangulated.Subcategory + +/-! +# Orthogonal of triangulated subcategories + +Let `P` be a triangulated subcategory of a pretriangulated category `C`. We show +that `P.rightOrthogonal` (which consists of objects `Y` with no nonzero +map `X ⟶ Y` with `X` satisfying `P`) is a triangulated. The dual result +for `P.leftOrthogonal` is also obtained. + +-/ + +universe v u + +namespace CategoryTheory + +open Limits + +namespace ObjectProperty + +variable {C : Type u} [Category.{v} C] (P : ObjectProperty C) + +section + +variable {M : Type*} [AddGroup M] [HasShift C M] [HasZeroMorphisms C] + +instance [P.IsStableUnderShift M] : P.rightOrthogonal.IsStableUnderShift M where + isStableUnderShiftBy n := ⟨fun Y hY X f hX ↦ by + obtain ⟨g, rfl⟩ := ((shiftEquiv C n).symm.toAdjunction.homEquiv _ _).surjective f + simp [hY g (P.le_shift (-n) _ hX), Adjunction.homEquiv_unit]⟩ + +instance [P.IsStableUnderShift M] : P.leftOrthogonal.IsStableUnderShift M where + isStableUnderShiftBy n := ⟨fun X hX Y f hY ↦ by + obtain ⟨g, rfl⟩ := ((shiftEquiv C n).toAdjunction.homEquiv _ _).symm.surjective f + simp [hX g (P.le_shift (-n) _ hY), Adjunction.homEquiv_counit]⟩ + +end + +variable [HasZeroObject C] [HasShift C ℤ] [Preadditive C] + [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] + +instance [P.IsTriangulatedClosed₂] : P.rightOrthogonal.IsTriangulatedClosed₂ := + .mk' (fun T hT h₁ h₃ X f hX ↦ by + obtain ⟨g, rfl⟩ := Pretriangulated.Triangle.coyoneda_exact₂ T hT f (h₃ _ hX) + simp [h₁ g hX]) + +instance [P.IsTriangulatedClosed₂] : P.leftOrthogonal.IsTriangulatedClosed₂ := + .mk' (fun T hT h₁ h₃ Y f hY ↦ by + obtain ⟨g, rfl⟩ := Pretriangulated.Triangle.yoneda_exact₂ T hT f (h₁ _ hY) + simp [h₃ g hY]) + +instance [P.IsTriangulated] : P.rightOrthogonal.IsTriangulated where + +instance [P.IsTriangulated] : P.leftOrthogonal.IsTriangulated where + +end ObjectProperty + +end CategoryTheory From 1807e21dbbb158b44ed83a0a66f993cfd303bb79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 20 Nov 2025 09:46:18 +0100 Subject: [PATCH 02/60] chore(CategoryTheory): rename LeftBousfield.W as ObjectProperty.isLocal --- .../Abelian/SerreClass/Bousfield.lean | 10 +- .../Localization/Bousfield.lean | 113 ++++++++++-------- .../BousfieldTransfiniteComposition.lean | 12 +- .../CategoryTheory/ObjectProperty/Local.lean | 4 +- .../Presentable/OrthogonalReflection.lean | 11 +- Mathlib/CategoryTheory/Sites/Equivalence.lean | 8 +- .../CategoryTheory/Sites/Localization.lean | 25 ++-- .../Sites/PreservesSheafification.lean | 2 +- 8 files changed, 107 insertions(+), 78 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean b/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean index e6cacb328d8f4e..8da08533e9d274 100644 --- a/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean +++ b/Mathlib/CategoryTheory/Abelian/SerreClass/Bousfield.lean @@ -47,12 +47,16 @@ lemma isoModSerre_kernel_eq_inverseImage_isomorphisms : variable {G} -lemma isoModSerre_kernel_eq_leftBousfield_W_of_rightAdjoint +lemma isoModSerre_kernel_eq_isLocal_of_rightAdjoint {F : C ⥤ D} (adj : G ⊣ F) [F.Full] [F.Faithful] : - G.kernel.isoModSerre = LeftBousfield.W (· ∈ Set.range F.obj) := by - rw [LeftBousfield.W_eq_inverseImage_isomorphisms adj, + G.kernel.isoModSerre = ObjectProperty.isLocal (· ∈ Set.range F.obj) := by + rw [ObjectProperty.isLocal_eq_inverseImage_isomorphisms adj, isoModSerre_kernel_eq_inverseImage_isomorphisms] +@[deprecated (since := "2025-11-20")] +alias isoModSerre_kernel_eq_leftBousfield_W_of_rightAdjoint := + isoModSerre_kernel_eq_isLocal_of_rightAdjoint + lemma isLocalization_isoModSerre_kernel_of_leftAdjoint {F : C ⥤ D} (adj : G ⊣ F) [F.Full] [F.Faithful] : G.IsLocalization G.kernel.isoModSerre := by diff --git a/Mathlib/CategoryTheory/Localization/Bousfield.lean b/Mathlib/CategoryTheory/Localization/Bousfield.lean index 8d3de95c616ce1..c28f42c70da992 100644 --- a/Mathlib/CategoryTheory/Localization/Bousfield.lean +++ b/Mathlib/CategoryTheory/Localization/Bousfield.lean @@ -13,16 +13,15 @@ public import Mathlib.CategoryTheory.Localization.Adjunction # Bousfield localization Given a predicate `P : ObjectProperty C` on the objects of a category `C`, -we define `Localization.LeftBousfield.W P : MorphismProperty C` -as the class of morphisms `f : X ⟶ Y` such that for any `Z : C` -such that `P Z`, the precomposition with `f` induces a bijection -`(Y ⟶ Z) ≃ (X ⟶ Z)`. +we define `W.isLocal : MorphismProperty C` as the class of morphisms `f : X ⟶ Y` +such that for any `Z : C` such that `P Z`, the precomposition with `f` +induces a bijection `(Y ⟶ Z) ≃ (X ⟶ Z)`. (This construction is part of left Bousfield localization in the context of model categories.) When `G ⊣ F` is an adjunction with `F : C ⥤ D` fully faithful, then -`G : D ⥤ C` is a localization functor for the class `W (· ∈ Set.range F.obj)`, +`G : D ⥤ C` is a localization functor for the class `isLocal (· ∈ Set.range F.obj)`, which then identifies to the inverse image by `G` of the class of isomorphisms in `C`. @@ -40,9 +39,7 @@ open Category variable {C D : Type*} [Category C] [Category D] -namespace Localization - -namespace LeftBousfield +namespace ObjectProperty section @@ -51,18 +48,18 @@ variable (P : ObjectProperty C) /-- Given `P : ObjectProperty C`, this is the class of morphisms `f : X ⟶ Y` such that for all `Z : C` such that `P Z`, the precomposition with `f` induces a bijection `(Y ⟶ Z) ≃ (X ⟶ Z)`. -/ -def W : MorphismProperty C := fun _ _ f => +def isLocal : MorphismProperty C := fun _ _ f => ∀ Z, P Z → Function.Bijective (fun (g : _ ⟶ Z) => f ≫ g) variable {P} in -/-- The bijection `(Y ⟶ Z) ≃ (X ⟶ Z)` induced by `f : X ⟶ Y` when `LeftBousfield.W P f` +/-- The bijection `(Y ⟶ Z) ≃ (X ⟶ Z)` induced by `f : X ⟶ Y` when `P.isLocal f` and `P Z`. -/ @[simps! apply] -noncomputable def W.homEquiv {X Y : C} {f : X ⟶ Y} (hf : W P f) (Z : C) (hZ : P Z) : +noncomputable def isLocal.homEquiv {X Y : C} {f : X ⟶ Y} (hf : P.isLocal f) (Z : C) (hZ : P Z) : (Y ⟶ Z) ≃ (X ⟶ Z) := Equiv.ofBijective _ (hf Z hZ) -lemma W_isoClosure : W P.isoClosure = W P := by +lemma isoClosure_isLocal : P.isoClosure.isLocal = P.isLocal := by ext X Y f constructor · intro hf Z hZ @@ -77,12 +74,12 @@ lemma W_isoClosure : W P.isoClosure = W P := by obtain ⟨a, h⟩ := (hf _ hZ').2 (g ≫ e.hom) exact ⟨a ≫ e.inv, by simp only [reassoc_of% h, e.hom_inv_id, comp_id]⟩ -instance : (W P).IsMultiplicative where +instance : P.isLocal.IsMultiplicative where id_mem X Z _ := by simpa [id_comp] using Function.bijective_id comp_mem f g hf hg Z hZ := by simpa using Function.Bijective.comp (hf Z hZ) (hg Z hZ) -instance : (W P).HasTwoOutOfThreeProperty where +instance : P.isLocal.HasTwoOutOfThreeProperty where of_postcomp f g hg hfg Z hZ := by rw [← Function.Bijective.of_comp_iff _ (hg Z hZ)] simpa using hfg Z hZ @@ -90,34 +87,34 @@ instance : (W P).HasTwoOutOfThreeProperty where rw [← Function.Bijective.of_comp_iff' (hf Z hZ)] simpa using hfg Z hZ -lemma W_of_isIso {X Y : C} (f : X ⟶ Y) [IsIso f] : W P f := fun Z _ => by +lemma isLocal_of_isIso {X Y : C} (f : X ⟶ Y) [IsIso f] : P.isLocal f := fun Z _ => by constructor · intro g₁ g₂ _ simpa only [← cancel_epi f] · intro g exact ⟨inv f ≫ g, by simp⟩ -lemma W_iff_isIso {X Y : C} (f : X ⟶ Y) (hX : P X) (hY : P Y) : - W P f ↔ IsIso f := by +lemma isLocal_iff_isIso {X Y : C} (f : X ⟶ Y) (hX : P X) (hY : P Y) : + P.isLocal f ↔ IsIso f := by constructor · intro hf obtain ⟨g, hg⟩ := (hf _ hX).2 (𝟙 X) exact ⟨g, hg, (hf _ hY).1 (by simp only [reassoc_of% hg, comp_id])⟩ - · apply W_of_isIso + · apply isLocal_of_isIso -instance : (W P).RespectsIso where - precomp f (_ : IsIso f) g hg := (W P).comp_mem f g (W_of_isIso _ f) hg - postcomp f (_ : IsIso f) g hg := (W P).comp_mem g f hg (W_of_isIso _ f) +instance : P.isLocal.RespectsIso where + precomp f (_ : IsIso f) g hg := P.isLocal.comp_mem f g (isLocal_of_isIso _ f) hg + postcomp f (_ : IsIso f) g hg := P.isLocal.comp_mem g f hg (isLocal_of_isIso _ f) -lemma le_W_iff (P : ObjectProperty C) (W : MorphismProperty C) : - W ≤ LeftBousfield.W P ↔ P ≤ W.isLocal := +lemma le_isLocal_iff (P : ObjectProperty C) (W : MorphismProperty C) : + W ≤ P.isLocal ↔ P ≤ W.isLocal := ⟨fun h _ hZ _ _ _ hf ↦ h _ hf _ hZ, fun h _ _ _ hf _ hZ ↦ h _ hZ _ hf⟩ -lemma galoisConnection : - GaloisConnection (OrderDual.toDual ∘ W (C := C)) +lemma galoisConnection_isLocal : + GaloisConnection (OrderDual.toDual ∘ isLocal (C := C)) (MorphismProperty.isLocal ∘ OrderDual.ofDual) := - le_W_iff + le_isLocal_iff end @@ -126,19 +123,19 @@ section variable {F : C ⥤ D} {G : D ⥤ C} (adj : G ⊣ F) [F.Full] [F.Faithful] include adj -lemma W_adj_unit_app (X : D) : W (· ∈ Set.range F.obj) (adj.unit.app X) := by +lemma isLocal_adj_unit_app (X : D) : isLocal (· ∈ Set.range F.obj) (adj.unit.app X) := by rintro _ ⟨Y, rfl⟩ convert ((Functor.FullyFaithful.ofFullyFaithful F).homEquiv.symm.trans (adj.homEquiv X Y)).bijective using 1 dsimp [Adjunction.homEquiv] aesop -lemma W_iff_isIso_map {X Y : D} (f : X ⟶ Y) : - W (· ∈ Set.range F.obj) f ↔ IsIso (G.map f) := by - rw [← (W (· ∈ Set.range F.obj)).postcomp_iff _ _ (W_adj_unit_app adj Y)] +lemma isLocal_iff_isIso_map {X Y : D} (f : X ⟶ Y) : + isLocal (· ∈ Set.range F.obj) f ↔ IsIso (G.map f) := by + rw [← (isLocal (· ∈ Set.range F.obj)).postcomp_iff _ _ (isLocal_adj_unit_app adj Y)] erw [adj.unit.naturality f] - rw [(W (· ∈ Set.range F.obj)).precomp_iff _ _ (W_adj_unit_app adj X), - W_iff_isIso _ _ ⟨_, rfl⟩ ⟨_, rfl⟩] + rw [(isLocal (· ∈ Set.range F.obj)).precomp_iff _ _ (isLocal_adj_unit_app adj X), + isLocal_iff_isIso _ _ ⟨_, rfl⟩ ⟨_, rfl⟩] constructor · intro h dsimp at h @@ -147,30 +144,52 @@ lemma W_iff_isIso_map {X Y : D} (f : X ⟶ Y) : rw [Functor.comp_map] infer_instance -lemma W_eq_inverseImage_isomorphisms : - W (· ∈ Set.range F.obj) = (MorphismProperty.isomorphisms _).inverseImage G := by +lemma isLocal_eq_inverseImage_isomorphisms : + isLocal (· ∈ Set.range F.obj) = (MorphismProperty.isomorphisms _).inverseImage G := by ext P₁ P₂ f - rw [W_iff_isIso_map adj] + rw [isLocal_iff_isIso_map adj] rfl -lemma isLocalization : G.IsLocalization (W (· ∈ Set.range F.obj)) := by - rw [W_eq_inverseImage_isomorphisms adj] +lemma isLocalization_isLocal : G.IsLocalization (isLocal (· ∈ Set.range F.obj)) := by + rw [isLocal_eq_inverseImage_isomorphisms adj] exact adj.isLocalization end -end LeftBousfield - -end Localization +end ObjectProperty open Localization -lemma ObjectProperty.le_isLocal_W (P : ObjectProperty C) : - P ≤ (LeftBousfield.W P).isLocal := by - rw [← LeftBousfield.le_W_iff] - -lemma MorphismProperty.le_leftBousfieldW_isLocal (W : MorphismProperty C) : - W ≤ LeftBousfield.W W.isLocal := by - rw [LeftBousfield.le_W_iff] +lemma ObjectProperty.le_isLocal_isLocal (P : ObjectProperty C) : + P ≤ P.isLocal.isLocal := by + rw [← le_isLocal_iff] + +lemma MorphismProperty.le_isLocal_isLocal (W : MorphismProperty C) : + W ≤ W.isLocal.isLocal := by + rw [ObjectProperty.le_isLocal_iff] + +@[deprecated (since := "2025-11-20")] alias ObjectProperty.le_isLocal_W := + ObjectProperty.le_isLocal_isLocal +@[deprecated (since := "2025-11-20")] alias MorphismProperty.le_leftBousfieldW_isLocal := + MorphismProperty.le_isLocal_isLocal + +namespace Localization.LeftBousfield + +open ObjectProperty + +@[deprecated (since := "2025-11-20")] alias W := isLocal +@[deprecated (since := "2025-11-20")] alias W.homEquiv := isLocal.homEquiv +@[deprecated (since := "2025-11-20")] alias W_isoClosure := isoClosure_isLocal +@[deprecated (since := "2025-11-20")] alias W_of_isIso := isLocal_of_isIso +@[deprecated (since := "2025-11-20")] alias W_iff_isIso := isLocal_iff_isIso +@[deprecated (since := "2025-11-20")] alias le_W_iff := le_isLocal_iff +@[deprecated (since := "2025-11-20")] alias galoisConnection := galoisConnection_isLocal +@[deprecated (since := "2025-11-20")] alias W_adj_unit_app := isLocal_adj_unit_app +@[deprecated (since := "2025-11-20")] alias W_iff_isIso_map := isLocal_iff_isIso_map +@[deprecated (since := "2025-11-20")] alias W_eq_inverseImage_isomorphisms := + isLocal_eq_inverseImage_isomorphisms +@[deprecated (since := "2025-11-20")] alias isLocalization := isLocalization_isLocal + +end Localization.LeftBousfield end CategoryTheory diff --git a/Mathlib/CategoryTheory/Localization/BousfieldTransfiniteComposition.lean b/Mathlib/CategoryTheory/Localization/BousfieldTransfiniteComposition.lean index b06bcf29207d01..29172c930fcdf1 100644 --- a/Mathlib/CategoryTheory/Localization/BousfieldTransfiniteComposition.lean +++ b/Mathlib/CategoryTheory/Localization/BousfieldTransfiniteComposition.lean @@ -10,9 +10,9 @@ public import Mathlib.CategoryTheory.MorphismProperty.TransfiniteComposition public import Mathlib.CategoryTheory.SmallObject.WellOrderInductionData /-! -# LeftBousfield.W is stable under transfinite compositions +# ObjectProperty.isLocal is stable under transfinite compositions -If `P : ObjectProperty C`, then `Localization.LeftBousfield.W P : MorphismProperty C` +If `P : ObjectProperty C`, then `P.isLocal : MorphismProperty C` is stable under transfinite compositions. -/ @@ -27,12 +27,12 @@ open Limits Opposite variable {C : Type u} [Category.{v} C] -namespace Localization.LeftBousfield +namespace ObjectProperty variable (P : ObjectProperty C) instance (J : Type w) [LinearOrder J] [SuccOrder J] [OrderBot J] [WellFoundedLT J] : - (W P).IsStableUnderTransfiniteCompositionOfShape J where + P.isLocal.IsStableUnderTransfiniteCompositionOfShape J where le := fun X Y f ⟨hf⟩ Z hZ ↦ by refine ⟨fun g₁ g₂ h ↦ hf.isColimit.hom_ext (fun j ↦ ?_), fun g ↦ ?_⟩ · dsimp at h ⊢ @@ -65,8 +65,8 @@ instance (J : Type w) [LinearOrder J] [SuccOrder J] [OrderBot J] [WellFoundedLT simp only [← hf.fac, Category.assoc, hf.isColimit.fac c ⊥, c, σ, d.sectionsMk_val_op_bot, Iso.inv_hom_id_assoc]⟩ -instance : MorphismProperty.IsStableUnderTransfiniteComposition.{w} (W P) where +instance : MorphismProperty.IsStableUnderTransfiniteComposition.{w} P.isLocal where -end Localization.LeftBousfield +end ObjectProperty end CategoryTheory diff --git a/Mathlib/CategoryTheory/ObjectProperty/Local.lean b/Mathlib/CategoryTheory/ObjectProperty/Local.lean index 8380475dbe6882..2096ec7cd8231c 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Local.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Local.lean @@ -16,7 +16,7 @@ which is the property of objects `Z` such that for any `f : X ⟶ Y` satisfying the precomposition with `f` gives a bijection `(Y ⟶ Z) ≃ (X ⟶ Z)`. (In the file `CategoryTheory.Localization.Bousfield`, it is shown that this is part of a Galois connection, with "dual" construction -`Localization.LeftBousfield.W : ObjectProperty C → MorphismProperty C`.) +`ObjectProperty.isLocal : ObjectProperty C → MorphismProperty C`.) -/ @@ -36,7 +36,7 @@ variable (W : MorphismProperty C) the objects `Z` such that for any `f : X ⟶ Y` such that `W f` holds, the precomposition with `f` gives a bijection `(Y ⟶ Z) ≃ (X ⟶ Z)`. (See the file `CategoryTheory.Localization.Bousfield` for the "dual" construction -`Localization.LeftBousfield.W : ObjectProperty C → MorphismProperty C`.) -/ +`ObjectProperty.isLocal : ObjectProperty C → MorphismProperty C`.) -/ def isLocal : ObjectProperty C := fun Z ↦ ∀ ⦃X Y : C⦄ (f : X ⟶ Y), W f → Function.Bijective (fun (g : _ ⟶ Z) ↦ f ≫ g) diff --git a/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean b/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean index 179da90ea95393..d6eec60d294eab 100644 --- a/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean +++ b/Mathlib/CategoryTheory/Presentable/OrthogonalReflection.lean @@ -14,7 +14,7 @@ public import Mathlib.CategoryTheory.SmallObject.Iteration.Basic Given `W : MorphismProperty C` (which should be small) and assuming the existence of certain colimits in `C`, we construct a morphism `toSucc W Z : Z ⟶ succ W Z` for -any `Z : C`. This morphism belongs to `LeftBousfield.W W.isLocal` and +any `Z : C`. This morphism belongs to `W.isLocal.isLocal` and is an isomorphism iff `Z` belongs to `W.isLocal` (see the lemma `isIso_toSucc_iff`). The morphism `toSucc W Z : Z ⟶ succ W Z` is defined as a composition of two morphisms that are roughly described as follows: @@ -199,8 +199,8 @@ lemma toSucc_surjectivity {X Y : C} (f : X ⟶ Y) (hf : W f) (g : X ⟶ Z) : ⟨D₁.ιRight f hf g ≫ pushout.inl _ _ ≫ fromStep W Z, by simp [← D₁.ιLeft_comp_t_assoc, pushout.condition_assoc]⟩ -lemma leftBousfieldW_isLocal_toSucc : - LeftBousfield.W W.isLocal (toSucc W Z) := by +lemma isLocal_isLocal_toSucc : + W.isLocal.isLocal (toSucc W Z) := by refine fun T hT ↦ ⟨fun φ₁ φ₂ h ↦ ?_, fun g ↦ ?_⟩ · ext ⟨⟩ simp only [Category.assoc] at h @@ -213,6 +213,9 @@ lemma leftBousfieldW_isLocal_toSucc : exact ⟨Multicoequalizer.desc _ _ (fun ⟨⟩ ↦ pushout.desc (Sigma.desc f) g) (fun d ↦ (hT d.1.1.hom d.1.2).1 (by simp [reassoc_of% d.2.2])), by simp⟩ +@[deprecated (since := "2025-11-20")] alias leftBousfieldW_isLocal_toSucc := + isLocal_isLocal_toSucc + lemma isIso_toSucc_iff : IsIso (toSucc W Z) ↔ W.isLocal Z := by refine ⟨fun _ X Y f hf ↦ ?_, fun hZ ↦ ?_⟩ @@ -224,7 +227,7 @@ lemma isIso_toSucc_iff : simp only [Category.assoc] at hZ exact ⟨D₁.ιRight f hf g ≫ pushout.inl _ _ ≫ fromStep W Z ≫ inv (toSucc W Z), by simp [← D₁.ιLeft_comp_t_assoc, pushout.condition_assoc, hZ]⟩ - · obtain ⟨f, hf⟩ := (leftBousfieldW_isLocal_toSucc W Z _ hZ).2 (𝟙 _) + · obtain ⟨f, hf⟩ := (isLocal_isLocal_toSucc W Z _ hZ).2 (𝟙 _) dsimp at hf refine ⟨f, hf, ?_⟩ ext ⟨⟩ diff --git a/Mathlib/CategoryTheory/Sites/Equivalence.lean b/Mathlib/CategoryTheory/Sites/Equivalence.lean index 0b89c56cd0c473..0b615af328fe22 100644 --- a/Mathlib/CategoryTheory/Sites/Equivalence.lean +++ b/Mathlib/CategoryTheory/Sites/Equivalence.lean @@ -227,10 +227,10 @@ lemma W_inverseImage_whiskeringLeft : K.W.inverseImage ((whiskeringLeft Dᵒᵖ Cᵒᵖ A).obj G.op) = J.W := by ext P Q f have h₁ : K.W (A := A) = - Localization.LeftBousfield.W (· ∈ Set.range (sheafToPresheaf J A ⋙ + ObjectProperty.isLocal (· ∈ Set.range (sheafToPresheaf J A ⋙ ((whiskeringLeft Dᵒᵖ Cᵒᵖ A).obj G.op)).obj) := by - rw [W_eq_W_range_sheafToPresheaf_obj, ← LeftBousfield.W_isoClosure] - conv_rhs => rw [← LeftBousfield.W_isoClosure] + rw [W_eq_isLocal_range_sheafToPresheaf_obj, ← ObjectProperty.isoClosure_isLocal] + conv_rhs => rw [← ObjectProperty.isoClosure_isLocal] apply congr_arg ext P constructor @@ -247,7 +247,7 @@ lemma W_inverseImage_whiskeringLeft : exact Function.Bijective.of_comp_iff' (Functor.whiskerLeft_obj_map_bijective_of_isCoverDense J G P R.val R.cond) (fun g ↦ f ≫ g) - rw [h₁, J.W_eq_W_range_sheafToPresheaf_obj, MorphismProperty.inverseImage_iff] + rw [h₁, J.W_eq_isLocal_range_sheafToPresheaf_obj, MorphismProperty.inverseImage_iff] constructor · rintro h _ ⟨R, rfl⟩ exact (h₂ R).1 (h _ ⟨R, rfl⟩) diff --git a/Mathlib/CategoryTheory/Sites/Localization.lean b/Mathlib/CategoryTheory/Sites/Localization.lean index bee36d7c7d8883..f1b13117d377a3 100644 --- a/Mathlib/CategoryTheory/Sites/Localization.lean +++ b/Mathlib/CategoryTheory/Sites/Localization.lean @@ -29,11 +29,11 @@ namespace GrothendieckTopology /-- The class of morphisms of presheaves which become isomorphisms after sheafification. (See `GrothendieckTopology.W_iff`.) -/ -abbrev W : MorphismProperty (Cᵒᵖ ⥤ A) := LeftBousfield.W (Presheaf.IsSheaf J) +abbrev W : MorphismProperty (Cᵒᵖ ⥤ A) := ObjectProperty.isLocal (Presheaf.IsSheaf J) variable (A) in -lemma W_eq_W_range_sheafToPresheaf_obj : - J.W = LeftBousfield.W (· ∈ Set.range (sheafToPresheaf J A).obj) := by +lemma W_eq_isLocal_range_sheafToPresheaf_obj : + J.W = ObjectProperty.isLocal (· ∈ Set.range (sheafToPresheaf J A).obj) := by apply congr_arg ext P constructor @@ -42,10 +42,13 @@ lemma W_eq_W_range_sheafToPresheaf_obj : · rintro ⟨F, rfl⟩ exact F.cond +@[deprecated (since := "2025-11-20")] alias W_eq_W_range_sheafToPresheaf_obj := + W_eq_isLocal_range_sheafToPresheaf_obj + lemma W_sheafToPresheaf_map_iff_isIso {F₁ F₂ : Sheaf J A} (φ : F₁ ⟶ F₂) : J.W ((sheafToPresheaf J A).map φ) ↔ IsIso φ := by - rw [W_eq_W_range_sheafToPresheaf_obj, LeftBousfield.W_iff_isIso _ _ ⟨_, rfl⟩ ⟨_, rfl⟩, - isIso_iff_of_reflects_iso] + rw [W_eq_isLocal_range_sheafToPresheaf_obj, + ObjectProperty.isLocal_iff_isIso _ _ ⟨_, rfl⟩ ⟨_, rfl⟩, isIso_iff_of_reflects_iso] @[deprecated (since := "2025-07-27")] alias W_sheafToPreheaf_map_iff_isIso := W_sheafToPresheaf_map_iff_isIso @@ -55,19 +58,19 @@ section Adjunction variable {G : (Cᵒᵖ ⥤ A) ⥤ Sheaf J A} lemma W_adj_unit_app (adj : G ⊣ sheafToPresheaf J A) (P : Cᵒᵖ ⥤ A) : J.W (adj.unit.app P) := by - rw [W_eq_W_range_sheafToPresheaf_obj] - exact LeftBousfield.W_adj_unit_app adj P + rw [W_eq_isLocal_range_sheafToPresheaf_obj] + exact ObjectProperty.isLocal_adj_unit_app adj P lemma W_iff_isIso_map_of_adjunction (adj : G ⊣ sheafToPresheaf J A) {P₁ P₂ : Cᵒᵖ ⥤ A} (f : P₁ ⟶ P₂) : J.W f ↔ IsIso (G.map f) := by - rw [W_eq_W_range_sheafToPresheaf_obj] - exact LeftBousfield.W_iff_isIso_map adj f + rw [W_eq_isLocal_range_sheafToPresheaf_obj] + exact ObjectProperty.isLocal_iff_isIso_map adj f lemma W_eq_inverseImage_isomorphisms_of_adjunction (adj : G ⊣ sheafToPresheaf J A) : J.W = (MorphismProperty.isomorphisms _).inverseImage G := by - rw [W_eq_W_range_sheafToPresheaf_obj, - LeftBousfield.W_eq_inverseImage_isomorphisms adj] + rw [W_eq_isLocal_range_sheafToPresheaf_obj, + ObjectProperty.isLocal_eq_inverseImage_isomorphisms adj] end Adjunction diff --git a/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean b/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean index 9f6ffbcfa1b941..04fecdc1859042 100644 --- a/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean +++ b/Mathlib/CategoryTheory/Sites/PreservesSheafification.lean @@ -147,7 +147,7 @@ lemma GrothendieckTopology.preservesSheafification_iff_of_adjunctions erw [adj₁.unit.naturality f] dsimp only [Functor.comp_map] rw [whiskerRight_comp, (W _).precomp_iff _ _ (h P₁)] - apply Localization.LeftBousfield.W_of_isIso + apply ObjectProperty.isLocal_of_isIso section HasSheafCompose From fb7ad36c341afb95d1fd5765009505b6c31aafa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 20 Nov 2025 10:39:32 +0100 Subject: [PATCH 03/60] feat(CategoryTheory/Triangulated): right orthogonal and localization --- .../Triangulated/Orthogonal.lean | 46 ++++++++++++++++--- 1 file changed, 40 insertions(+), 6 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean index 16e247f411faa2..dc3f4f0c08d8a6 100644 --- a/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean +++ b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean @@ -6,6 +6,7 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.ObjectProperty.Orthogonal +public import Mathlib.CategoryTheory.Localization.Bousfield public import Mathlib.CategoryTheory.Triangulated.Subcategory /-! @@ -18,15 +19,16 @@ for `P.leftOrthogonal` is also obtained. -/ -universe v u +universe v v' u u' namespace CategoryTheory -open Limits +open Limits ZeroObject Pretriangulated namespace ObjectProperty -variable {C : Type u} [Category.{v} C] (P : ObjectProperty C) +variable {C : Type u} [Category.{v} C] {D : Type u'} [Category.{v'} D] + (P : ObjectProperty C) section @@ -57,9 +59,41 @@ instance [P.IsTriangulatedClosed₂] : P.leftOrthogonal.IsTriangulatedClosed₂ obtain ⟨g, rfl⟩ := Pretriangulated.Triangle.yoneda_exact₂ T hT f (h₁ _ hY) simp [h₃ g hY]) -instance [P.IsTriangulated] : P.rightOrthogonal.IsTriangulated where - -instance [P.IsTriangulated] : P.leftOrthogonal.IsTriangulated where +variable [P.IsTriangulated] + +instance : P.rightOrthogonal.IsTriangulated where + +instance : P.leftOrthogonal.IsTriangulated where + +lemma isLocal_trW : P.trW.isLocal = P.rightOrthogonal := by + ext Y + refine ⟨fun hY X f hX ↦ ?_, fun hY X₁ X₂ f ⟨X₃, g, h, hT, hX₃⟩ ↦ ⟨?_, fun α ↦ ?_⟩⟩ + · exact (hY _ (trW.mk P (contractible_distinguished₁ X) hX)).injective (by simp) + · suffices ∀ (α : X₂ ⟶ Y), f ≫ α = 0 → α = 0 from fun α₁ α₂ hα ↦ by + simpa [sub_eq_zero] using this (α₁ - α₂) (by simpa [sub_eq_zero] using hα) + intro α hα + obtain ⟨β, rfl⟩ := Triangle.yoneda_exact₂ _ hT α hα + simp [hY β hX₃] + · obtain ⟨β, rfl⟩ := Triangle.yoneda_exact₂ _ (inv_rot_of_distTriang _ hT) + α (hY _ (P.le_shift _ _ hX₃)) + exact ⟨β, rfl⟩ + +variable {P} in +lemma rightOrthogonal.map_bijective_of_isTriangulated + {Y : C} (hY : P.rightOrthogonal Y) + [IsTriangulated C] (L : C ⥤ D) [L.IsLocalization P.trW] (X : C) : + Function.Bijective (L.map : (X ⟶ Y) → _) := by + rw [← isLocal_trW] at hY + refine ⟨fun f₁ f₂ hf ↦ ?_, fun g ↦ ?_⟩ + · rw [MorphismProperty.map_eq_iff_precomp L P.trW] at hf + obtain ⟨Z, s, hs, eq⟩ := hf + exact (hY _ hs).1 eq + · obtain ⟨φ, hφ⟩ := Localization.exists_rightFraction L P.trW g + have := Localization.inverts L P.trW φ.s φ.hs + obtain ⟨α, hα⟩ := (hY _ φ.hs).2 φ.f + refine ⟨α, ?_⟩ + rw [hφ, ← cancel_epi (L.map φ.s), MorphismProperty.RightFraction.map_s_comp_map, + ← hα, Functor.map_comp] end ObjectProperty From e8c89bec4b740fc468aabcb9405f6b1076d6bc1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 13:42:49 +0100 Subject: [PATCH 04/60] added docstring --- Mathlib/CategoryTheory/Localization/Bousfield.lean | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Localization/Bousfield.lean b/Mathlib/CategoryTheory/Localization/Bousfield.lean index c28f42c70da992..c2d2d53e0583d7 100644 --- a/Mathlib/CategoryTheory/Localization/Bousfield.lean +++ b/Mathlib/CategoryTheory/Localization/Bousfield.lean @@ -17,7 +17,7 @@ we define `W.isLocal : MorphismProperty C` as the class of morphisms `f : X ⟶ such that for any `Z : C` such that `P Z`, the precomposition with `f` induces a bijection `(Y ⟶ Z) ≃ (X ⟶ Z)`. -(This construction is part of left Bousfield localization +(This construction is part of the left Bousfield localization in the context of model categories.) When `G ⊣ F` is an adjunction with `F : C ⥤ D` fully faithful, then @@ -41,6 +41,8 @@ variable {C D : Type*} [Category C] [Category D] namespace ObjectProperty +/-! ### Left Bousfield localization -/ + section variable (P : ObjectProperty C) From 6f361c966c75d699fd86576836ec4150cedbe7bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 13:46:19 +0100 Subject: [PATCH 05/60] add reference to Bousfield localization for `ObjectProperty.isLocal` --- Mathlib/CategoryTheory/Localization/Bousfield.lean | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Localization/Bousfield.lean b/Mathlib/CategoryTheory/Localization/Bousfield.lean index c2d2d53e0583d7..a0820544d699f8 100644 --- a/Mathlib/CategoryTheory/Localization/Bousfield.lean +++ b/Mathlib/CategoryTheory/Localization/Bousfield.lean @@ -49,7 +49,8 @@ variable (P : ObjectProperty C) /-- Given `P : ObjectProperty C`, this is the class of morphisms `f : X ⟶ Y` such that for all `Z : C` such that `P Z`, the precomposition with `f` induces -a bijection `(Y ⟶ Z) ≃ (X ⟶ Z)`. -/ +a bijection `(Y ⟶ Z) ≃ (X ⟶ Z)`. (One of the applications of this notion +is the left Bousfield localization of model categories.) -/ def isLocal : MorphismProperty C := fun _ _ f => ∀ Z, P Z → Function.Bijective (fun (g : _ ⟶ Z) => f ≫ g) From 86fb3b021f0d083e43cf5c052125b813ef4bb4eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 15:48:32 +0100 Subject: [PATCH 06/60] feat(Algebra/Homology): K-injective cochain complexes --- Mathlib.lean | 1 + .../Homology/HomotopyCategory/HomComplex.lean | 25 ++++ .../HomotopyCategory/HomComplexInduction.lean | 84 +++++++++++++ .../Homology/HomotopyCategory/KInjective.lean | 110 ++++++++++++++++++ docs/references.bib | 16 +++ 5 files changed, 236 insertions(+) create mode 100644 Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean create mode 100644 Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean diff --git a/Mathlib.lean b/Mathlib.lean index 4180a07483c728..5229994a000bb6 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -581,6 +581,7 @@ public import Mathlib.Algebra.Homology.HomotopyCategory.DegreewiseSplit public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexShift public import Mathlib.Algebra.Homology.HomotopyCategory.HomologicalFunctor +public import Mathlib.Algebra.Homology.HomotopyCategory.KInjective public import Mathlib.Algebra.Homology.HomotopyCategory.MappingCone public import Mathlib.Algebra.Homology.HomotopyCategory.Pretriangulated public import Mathlib.Algebra.Homology.HomotopyCategory.Shift diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index 8d6e33e82967f7..df26bc73fec379 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -775,6 +775,31 @@ lemma equivHomotopy_apply_of_eq {φ₁ φ₂ : F ⟶ G} (h : φ₁ = φ₂) : lemma ofHom_injective {f₁ f₂ : F ⟶ G} (h : ofHom f₁ = ofHom f₂) : f₁ = f₂ := (Cocycle.equivHom F G).injective (by ext1; exact h) +/-- The cochain in `Cochain K L n` that is given by a single +morphism `K.X p ⟶ L.X q` and is zero otherwise. (As we do not check +that `p + n = q`, this will be the zero cochain when `p + n ≠ q`.) -/ +def single {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) : + Cochain K L n := + Cochain.mk (fun p' q' _ => + if h : p = p' ∧ q = q' + then (K.XIsoOfEq h.1).inv ≫ f ≫ (L.XIsoOfEq h.2).hom + else 0) + +@[simp] +lemma single_v {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) (hpq : p + n = q) : + (single f n).v p q hpq = f := by + dsimp [single] + rw [if_pos, id_comp, comp_id] + tauto + +lemma single_v_eq_zero {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) (p' q' : ℤ) (hpq' : p' + n = q') + (hp' : p' ≠ p) : + (single f n).v p' q' hpq' = 0 := by + dsimp [single] + rw [dif_neg] + intro h + exact hp' (by linarith) + end Cochain section diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean new file mode 100644 index 00000000000000..545584c446947f --- /dev/null +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean @@ -0,0 +1,84 @@ +/- +Copyright (c) 2023 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex + +/-! +# Construction of cochains by induction + +Let `K` and `L` be cochain complexes in a preadditive category `C`. +We provide an API to construct a cochain in `Cochain K L d` in the following +situation. Assume that `X n : Set (Cochain K L d)` is a sequence of subsets +of `Cochain K L d`, and `φ n : X n → X (n + 1)` is a sequence of maps such +that for a certain `p₀ : ℕ` and any `x : X n`, `φ n x` and `x` coincide +up to the degree `p₀ + n`, then we construct a cochain +`InductionUp.limitSequence` in `Cochain K L d` which coincide with the +`n`th-iteration of `φ` evaluated on `x₀` up to the degree `p₀ + n` for any `n : ℕ`. + +-/ + +@[expose] public section + +universe v u + +open CategoryTheory + +namespace CochainComplex.HomComplex.Cochain + +variable {C : Type u} [Category.{v} C] [Preadditive C] + {K L : CochainComplex C ℤ} + +/-- Given `p₀ : ℤ`, this is condition on two cochains `α` and `β` in `Cochain K L N` +saying that `α.v p q _ = β.v p q _` when `p ≤ p₀`. -/ +def EqUpTo {n : ℤ} (α β : Cochain K L n) (p₀ : ℤ) : Prop := + ∀ (p q : ℤ) (hpq : p + n = q), p ≤ p₀ → α.v p q hpq = β.v p q hpq + +namespace InductionUp + +variable {d : ℤ} {X : ℕ → Set (Cochain K L d)} (φ : ∀ (n : ℕ), X n → X (n + 1)) + {p₀ : ℤ} (hφ : ∀ (n : ℕ) (x : X n), (φ n x).val.EqUpTo x.val (p₀ + n)) (x₀ : X 0) + +/-- Assuming we have a sequence of subsets `X n : Set (Cochain K L d)` for all `n : ℕ`, +a sequence of maps `φ n : X n → X (n + 1)` for `n : ℕ`, and an element `x₀ : X 0`, +this is the dependent sequence in `∀ (n : ℕ), X n` obtained by evaluation iterations of `φ` +on `x₀`. -/ +def sequence : ∀ n, X n + | 0 => x₀ + | n + 1 => φ n (sequence n) + +include hφ in +lemma sequence_eqUpTo (n₁ n₂ : ℕ) (h : n₁ ≤ n₂) : + (sequence φ x₀ n₁).val.EqUpTo (sequence φ x₀ n₂).val (p₀ + n₁) := by + obtain ⟨k, rfl⟩ : ∃ (k : ℕ), n₂ = n₁ + k := Nat.exists_eq_add_of_le h + clear h + revert n₁ + induction k with + | zero => intro _ _ _ _ _; simp + | succ k hk => + intro n₁ p q hpq hp + rw [hk n₁ p q hpq hp, ← hφ (n₁ + k) (sequence φ x₀ (n₁ + k)) p q hpq (by cutsat)] + rfl + +/-- Assuming we have a sequence of subsets `X n : Set (Cochain K L d)` for all `n : ℕ`, +a sequence of maps `φ n : X n → X (n + 1)` for `n : ℕ`, and an element `x₀ : X 0`, +this is a cochain in `Cochain K L d` which, under the assumption that for any `x : X n` +the cochain `φ n x` coincides with `x` up to the degree `p₀ + n`, can be understood +as the "limit" of the sequence of cochain obtained by evaluating iterations of `φ` +on `x₀`. -/ +@[nolint unusedArguments] +def limitSequence (_ : ∀ (n : ℕ) (x : X n), (φ n x).val.EqUpTo x.val (p₀ + n)) (x₀ : X 0) : + Cochain K L d := + Cochain.mk (fun p q hpq => (sequence φ x₀ (p - p₀).toNat).1.v p q hpq) + +lemma limitSequence_eqUpTo (n : ℕ) : + (limitSequence φ hφ x₀).EqUpTo (sequence φ x₀ n).1 (p₀ + n) := by + intro p q hpq hp + exact sequence_eqUpTo φ hφ _ _ _ (by cutsat) _ _ _ (by cutsat) + +end InductionUp + +end CochainComplex.HomComplex.Cochain diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean new file mode 100644 index 00000000000000..d89551ff5686b3 --- /dev/null +++ b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean @@ -0,0 +1,110 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.Embedding.CochainComplex +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexInduction +public import Mathlib.Algebra.Homology.Homotopy + +/-! +# K-injective cochain complexes + +We define the notion of K-injective cochain complex in an abelian category, +and show that bounded below complexes of injective objects are K-injective. + +## TODO (@joelriou) +* Show that a cochain complex is K-injective iff its image in the homotopy +category belongs to the right orthogonal of the triangulated subcategory +of acyclic complexes +* Deduce that we can compute morphisms to a K-injective complex in the +derived category as homotopy classes of morphisms +* Provide an API for computing `Ext`-groups using an injective resolution + +## References +* [N. Spaltenstein, *Resolutions of unbounded complexes*][spaltenstein1998] + +-/ + +@[expose] public section + +namespace CochainComplex + +open CategoryTheory Limits HomComplex Preadditive + +variable {C : Type*} [Category C] [Abelian C] + +/-- A cochain complex `L` is K-injective if any morphism `K ⟶ L` +with `K` acyclic is homotopic to zero. -/ +class IsKInjective (L : CochainComplex C ℤ) : Prop where + nonempty_homotopy_zero {K : CochainComplex C ℤ} (f : K ⟶ L) : + K.Acyclic → Nonempty (Homotopy f 0) + +lemma isKInjective_of_injective_aux {K L : CochainComplex C ℤ} + (f : K ⟶ L) (α : Cochain K L (-1)) (n m : ℤ) (hnm : n + 1 = m) + (hK : K.ExactAt m) [Injective (L.X m)] + (hα : (δ (-1) 0 α).EqUpTo (Cochain.ofHom f) n) : + ∃ (h : K.X (n + 2) ⟶ L.X (n + 1)), + (δ (-1) 0 (α + Cochain.single h (-1))).EqUpTo (Cochain.ofHom f) m := by + subst hnm + let u := f.f (n + 1) - α.v (n + 1) n (by cutsat) ≫ L.d n (n + 1) - + K.d (n + 1) (n + 2) ≫ α.v (n + 2) (n + 1) (by cutsat) + have hu : K.d n (n+1) ≫ u = 0 := by + have eq := hα n n (add_zero n) (by rfl) + simp only [δ_v (-1) 0 (neg_add_cancel 1) α n n (add_zero _) (n - 1) (n + 1) + (by cutsat) (by cutsat), Int.negOnePow_zero, one_smul, Cochain.ofHom_v] at eq + simp only [u, comp_sub, HomologicalComplex.d_comp_d_assoc, zero_comp, + ← f.comm, ← eq, add_comp, Category.assoc, L.d_comp_d, comp_zero, zero_add, sub_self] + rw [K.exactAt_iff' n (n + 1) (n + 2) (by simp) (by simp; cutsat)] at hK + obtain ⟨β, hβ⟩ : ∃ (β : K.X (n + 2) ⟶ L.X (n + 1)), K.d (n + 1) (n + 2) ≫ β = u := + ⟨hK.descToInjective _ hu, hK.comp_descToInjective _ _⟩ + refine ⟨β, ?_⟩ + intro p q hpq hp + obtain rfl : p = q := by cutsat + obtain hp | rfl := hp.lt_or_eq + · rw [δ_add, Cochain.add_v, hα p p (by cutsat) (by cutsat), add_eq_left, + δ_v (-1) 0 (neg_add_cancel 1) _ p p hpq (p - 1) (p + 1) rfl rfl, + Cochain.single_v_eq_zero _ _ _ _ _ (by cutsat), + Cochain.single_v_eq_zero _ _ _ _ _ (by cutsat)] + simp + · rw [δ_v (-1) 0 (neg_add_cancel 1) _ (n + 1) (n + 1) (by cutsat) n (n + 2) + (by cutsat) (by cutsat), Cochain.add_v, + Cochain.single_v_eq_zero _ _ _ _ _ (by cutsat)] + simp [hβ, u] + +open Cochain.InductionUp in +lemma isKInjective_of_injective (L : CochainComplex C ℤ) (d : ℤ) + [L.IsStrictlyGE d] [∀ (n : ℤ), Injective (L.X n)] : + L.IsKInjective where + nonempty_homotopy_zero {K} f hK := by + /- The strategy of the proof is express the `0`-cocycle in `Cochain K L 0` + corresponding to `f` as the coboundary of a `-1`-cochain. An approximate + solution for some `n : ℕ` is an element in the subset `X n` consisting + of the `-1`-cochains such that `δ (-1) 0 α` coincide with `Cochain.ofHom f` + up to the degree `n + d - 1`. The assumption on `L` implies that + the zero `-1`-cochain belongs to `X 0`, and we use the lemma + `isKInjective_of_injective_aux` in order to get better approximations, + and we pass to the limit. -/ + let X (n : ℕ) : Set (Cochain K L (-1)) := + setOf (fun α => (δ (-1) 0 α).EqUpTo (Cochain.ofHom f) (n + d - 1)) + let x₀ : X 0 := ⟨0, fun p q hpq hp ↦ + IsZero.eq_of_tgt (L.isZero_of_isStrictlyGE d _ (by cutsat)) _ _⟩ + let φ (n : ℕ) (α : X n) : X (n + 1) := + ⟨_, (isKInjective_of_injective_aux f α.1 (n + d - 1) ((n + 1 : ℕ) + d - 1) + (by cutsat) (hK _) α.2).choose_spec⟩ + have hφ (k : ℕ) (x : X k) : (φ k x).1.EqUpTo x.1 (d + k) := fun p q hpq hp => by + dsimp [φ] + rw [add_eq_left, Cochain.single_v_eq_zero _ _ _ _ _ (by cutsat)] + refine ⟨(Cochain.equivHomotopy f 0).symm ⟨limitSequence φ hφ x₀, ?_⟩⟩ + rw [Cochain.ofHom_zero, add_zero] + ext n + let k₀ := (n - d + 1).toNat + rw [← (sequence φ x₀ k₀).2 n n (add_zero n) (by cutsat), + δ_v (-1) 0 (neg_add_cancel 1) _ n n (by cutsat) (n - 1) (n + 1) rfl (by cutsat), + δ_v (-1) 0 (neg_add_cancel 1) _ n n (by cutsat) (n - 1) (n + 1) rfl (by cutsat), + limitSequence_eqUpTo φ hφ x₀ k₀ n (n - 1) (by cutsat) (by cutsat), + limitSequence_eqUpTo φ hφ x₀ k₀ (n + 1) n (by cutsat) (by cutsat)] + +end CochainComplex diff --git a/docs/references.bib b/docs/references.bib index e2e0ee5d660192..e3543b31851811 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -4479,6 +4479,22 @@ @Book{ soare1987 doi = {10.1007/978-3-662-02460-7} } +@Article{ spaltenstein1988, + author = {Spaltenstein, N.}, + title = {Resolutions of unbounded complexes}, + journal = {Compositio Math.}, + fjournal = {Compositio Mathematica}, + volume = {65}, + year = {1988}, + number = {2}, + pages = {121--154}, + issn = {0010-437X,1570-5846}, + mrclass = {18E25 (32C35)}, + mrnumber = {932640}, + mrreviewer = {Michael\ M.\ Kapranov}, + url = {http://www.numdam.org/item?id=CM_1988__65_2_121_0} +} + @Book{ spiegel_odonnel1997, author = {Spiegel, Eugene and O'Donnell, Christopher J.}, title = {Incidence algebras}, From 777ad2797d9e7887a12417041c025f3a2e68ea18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 15:48:57 +0100 Subject: [PATCH 07/60] added TODO --- Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean index d89551ff5686b3..7aa13ccca98e0f 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean @@ -22,6 +22,7 @@ of acyclic complexes * Deduce that we can compute morphisms to a K-injective complex in the derived category as homotopy classes of morphisms * Provide an API for computing `Ext`-groups using an injective resolution +* Dualize everything ## References * [N. Spaltenstein, *Resolutions of unbounded complexes*][spaltenstein1998] From c4849ddc73de87e0d208dedfddf75947be74c68f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 15:50:00 +0100 Subject: [PATCH 08/60] fix --- Mathlib.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib.lean b/Mathlib.lean index 5229994a000bb6..a3cf2c9e9a9b9c 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -579,6 +579,7 @@ public import Mathlib.Algebra.Homology.Homotopy public import Mathlib.Algebra.Homology.HomotopyCategory public import Mathlib.Algebra.Homology.HomotopyCategory.DegreewiseSplit public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexInduction public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexShift public import Mathlib.Algebra.Homology.HomotopyCategory.HomologicalFunctor public import Mathlib.Algebra.Homology.HomotopyCategory.KInjective From 207532e93338561cc72c51e03097b09e49891f83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 15:52:38 +0100 Subject: [PATCH 09/60] better syntax --- .../Homology/HomotopyCategory/HomComplexInduction.lean | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean index 545584c446947f..62623fe20a8c73 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean @@ -53,13 +53,12 @@ def sequence : ∀ n, X n include hφ in lemma sequence_eqUpTo (n₁ n₂ : ℕ) (h : n₁ ≤ n₂) : (sequence φ x₀ n₁).val.EqUpTo (sequence φ x₀ n₂).val (p₀ + n₁) := by - obtain ⟨k, rfl⟩ : ∃ (k : ℕ), n₂ = n₁ + k := Nat.exists_eq_add_of_le h + obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le h clear h - revert n₁ - induction k with - | zero => intro _ _ _ _ _; simp + induction k generalizing n₁ with + | zero => intro _ _ _ _ ; simp | succ k hk => - intro n₁ p q hpq hp + intro p q hpq hp rw [hk n₁ p q hpq hp, ← hφ (n₁ + k) (sequence φ x₀ (n₁ + k)) p q hpq (by cutsat)] rfl From 2b63d6cbd13f20cfe32b46006b7492545f0b08ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 15:57:30 +0100 Subject: [PATCH 10/60] better docstring --- .../Homology/HomotopyCategory/HomComplexInduction.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean index 62623fe20a8c73..a4acf9b3338e3e 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean @@ -64,10 +64,10 @@ lemma sequence_eqUpTo (n₁ n₂ : ℕ) (h : n₁ ≤ n₂) : /-- Assuming we have a sequence of subsets `X n : Set (Cochain K L d)` for all `n : ℕ`, a sequence of maps `φ n : X n → X (n + 1)` for `n : ℕ`, and an element `x₀ : X 0`, -this is a cochain in `Cochain K L d` which, under the assumption that for any `x : X n` -the cochain `φ n x` coincides with `x` up to the degree `p₀ + n`, can be understood -as the "limit" of the sequence of cochain obtained by evaluating iterations of `φ` -on `x₀`. -/ +and under the assumption that for any `x : X n` the cochain `φ n x` coincides +with `x` up to the degree `p₀ + n`, this is a cochain in `Cochain K L d` which +can be understood as the "limit" of the sequence of cochains obtained by +evaluating iterations of `φ` on `x₀`. -/ @[nolint unusedArguments] def limitSequence (_ : ∀ (n : ℕ) (x : X n), (φ n x).val.EqUpTo x.val (p₀ + n)) (x₀ : X 0) : Cochain K L d := From d9b561f63a7619b2c2b61057e2f778e91f78dd40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 17:09:21 +0100 Subject: [PATCH 11/60] fix --- .../Algebra/Homology/HomotopyCategory/HomComplexInduction.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean index a4acf9b3338e3e..1608b5d78c72ff 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexInduction.lean @@ -56,7 +56,7 @@ lemma sequence_eqUpTo (n₁ n₂ : ℕ) (h : n₁ ≤ n₂) : obtain ⟨k, rfl⟩ := Nat.exists_eq_add_of_le h clear h induction k generalizing n₁ with - | zero => intro _ _ _ _ ; simp + | zero => intro _ _ _ _; simp | succ k hk => intro p q hpq hp rw [hk n₁ p q hpq hp, ← hφ (n₁ + k) (sequence φ x₀ (n₁ + k)) p q hpq (by cutsat)] From e8c86e3c51056229dab43cef4b5cb6fd58136af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 21 Nov 2025 18:29:41 +0100 Subject: [PATCH 12/60] fix --- docs/references.bib | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/references.bib b/docs/references.bib index e3543b31851811..7fca53f4c69abd 100644 --- a/docs/references.bib +++ b/docs/references.bib @@ -4492,7 +4492,7 @@ @Article{ spaltenstein1988 mrclass = {18E25 (32C35)}, mrnumber = {932640}, mrreviewer = {Michael\ M.\ Kapranov}, - url = {http://www.numdam.org/item?id=CM_1988__65_2_121_0} + url = {http://www.numdam.org/item?id=CM_1988__65_2_121_0} } @Book{ spiegel_odonnel1997, From 382e0f7ebbae17ff85202d42b4ab954bd7f8d066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Fri, 21 Nov 2025 20:12:35 +0100 Subject: [PATCH 13/60] Apply suggestion from @joelriou --- Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index df26bc73fec379..1fd9e4ea5354fb 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -798,7 +798,7 @@ lemma single_v_eq_zero {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) (p' q' : ℤ) dsimp [single] rw [dif_neg] intro h - exact hp' (by linarith) + exact hp' (by cutsat) end Cochain From b59c9df5e63a26f6bb7174e61c594f079bc54024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 22 Nov 2025 11:33:18 +0100 Subject: [PATCH 14/60] morphisms to a K-injective complex in the derived category --- Mathlib.lean | 2 + .../Homology/DerivedCategory/Basic.lean | 45 +----------- .../Homology/DerivedCategory/KInjective.lean | 35 +++++++++ .../Homology/HomotopyCategory/Acyclic.lean | 72 +++++++++++++++++++ .../Homology/HomotopyCategory/KInjective.lean | 62 ++++++++++++++-- .../Triangulated/Orthogonal.lean | 2 + 6 files changed, 170 insertions(+), 48 deletions(-) create mode 100644 Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean create mode 100644 Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean diff --git a/Mathlib.lean b/Mathlib.lean index 048344719316de..65243c34365548 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -541,6 +541,7 @@ public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Linear public import Mathlib.Algebra.Homology.DerivedCategory.Fractions public import Mathlib.Algebra.Homology.DerivedCategory.FullyFaithful public import Mathlib.Algebra.Homology.DerivedCategory.HomologySequence +public import Mathlib.Algebra.Homology.DerivedCategory.KInjective public import Mathlib.Algebra.Homology.DerivedCategory.Linear public import Mathlib.Algebra.Homology.DerivedCategory.ShortExact public import Mathlib.Algebra.Homology.DerivedCategory.SingleTriangle @@ -577,6 +578,7 @@ public import Mathlib.Algebra.Homology.HomologySequence public import Mathlib.Algebra.Homology.HomologySequenceLemmas public import Mathlib.Algebra.Homology.Homotopy public import Mathlib.Algebra.Homology.HomotopyCategory +public import Mathlib.Algebra.Homology.HomotopyCategory.Acyclic public import Mathlib.Algebra.Homology.HomotopyCategory.DegreewiseSplit public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexInduction diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean index 3c306bb0329708..c88ea3b2873730 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean @@ -5,11 +5,9 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.HomotopyCategory.HomologicalFunctor -public import Mathlib.Algebra.Homology.HomotopyCategory.ShiftSequence +public import Mathlib.Algebra.Homology.HomotopyCategory.Acyclic public import Mathlib.Algebra.Homology.HomotopyCategory.SingleFunctors public import Mathlib.Algebra.Homology.HomotopyCategory.Triangulated -public import Mathlib.Algebra.Homology.Localization /-! # The derived category of an abelian category @@ -23,8 +21,8 @@ localization functor `DerivedCategory.Q : CochainComplex C ℤ ⥤ DerivedCatego It was already shown in the file `Algebra.Homology.Localization` that the induced functor `DerivedCategory.Qh : HomotopyCategory C (ComplexShape.up ℤ) ⥤ DerivedCategory C` is a localization functor with respect to the class of morphisms -`HomotopyCategory.quasiIso C (ComplexShape.up ℤ)`. In the lemma -`HomotopyCategory.quasiIso_eq_subcategoryAcyclic_W` we obtain that this class of morphisms +`HomotopyCategory.quasiIso C (ComplexShape.up ℤ)`. In the file +`HomotopyCategory.Acyclic`, it was shown that this class of quasiisomorphisms consists of morphisms whose cone belongs to the triangulated subcategory `HomotopyCategory.subcategoryAcyclic C` of acyclic complexes. Then, the triangulated structure on `DerivedCategory C` is deduced from the triangulated structure @@ -69,43 +67,6 @@ open CategoryTheory Limits Pretriangulated variable (C : Type u) [Category.{v} C] [Abelian C] -namespace HomotopyCategory - -/-- The triangulated subcategory of `HomotopyCategory C (ComplexShape.up ℤ)` consisting -of acyclic complexes. -/ -def subcategoryAcyclic : ObjectProperty (HomotopyCategory C (ComplexShape.up ℤ)) := - (homologyFunctor C (ComplexShape.up ℤ) 0).homologicalKernel - -instance : (subcategoryAcyclic C).IsTriangulated := by - dsimp [subcategoryAcyclic] - infer_instance - -instance : (subcategoryAcyclic C).IsClosedUnderIsomorphisms := by - dsimp [subcategoryAcyclic] - infer_instance - -variable {C} - -lemma mem_subcategoryAcyclic_iff (X : HomotopyCategory C (ComplexShape.up ℤ)) : - subcategoryAcyclic C X ↔ ∀ (n : ℤ), IsZero ((homologyFunctor _ _ n).obj X) := - Functor.mem_homologicalKernel_iff _ X - -lemma quotient_obj_mem_subcategoryAcyclic_iff_exactAt (K : CochainComplex C ℤ) : - subcategoryAcyclic C ((quotient _ _).obj K) ↔ ∀ (n : ℤ), K.ExactAt n := by - rw [mem_subcategoryAcyclic_iff] - refine forall_congr' (fun n => ?_) - simp only [HomologicalComplex.exactAt_iff_isZero_homology] - exact ((homologyFunctorFactors C (ComplexShape.up ℤ) n).app K).isZero_iff - -variable (C) - -lemma quasiIso_eq_subcategoryAcyclic_W : - quasiIso C (ComplexShape.up ℤ) = (subcategoryAcyclic C).trW := by - ext K L f - exact ((homologyFunctor C (ComplexShape.up ℤ) 0).mem_homologicalKernel_trW_iff f).symm - -end HomotopyCategory - /-- The assumption that a localized category for `(HomologicalComplex.quasiIso C (ComplexShape.up ℤ))` has been chosen, and that the morphisms in this chosen category are in `Type w`. -/ diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean new file mode 100644 index 00000000000000..5c06768f3f9240 --- /dev/null +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -0,0 +1,35 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.DerivedCategory.Basic +public import Mathlib.Algebra.Homology.HomotopyCategory.KInjective + +/-! +# Morphisms to K-injective complexes in the derived category + +In this file, we show that if `L : CochainComplex C ℤ` is K-injective, +then for any `K : HomotopyCategory C (.up ℤ)`, the functor `DerivedCategory.Qh` +induces a bijection from the type of morphisms `K ⟶ (HomotopyCategory.quotient _ _).obj L)` +(i.e. homotopy classes of morphisms of cochain complexes) to the type of +morphisms in the derived category. + +-/ + +@[expose] public section + +universe w v u + +open CategoryTheory Limits Pretriangulated + +variable {C : Type u} [Category.{v} C] [Abelian C] + +lemma CochainComplex.IsKInjective.Qh_map_bijective [HasDerivedCategory C] + (K : HomotopyCategory C (ComplexShape.up ℤ)) + (L : CochainComplex C ℤ) [L.IsKInjective] : + Function.Bijective (DerivedCategory.Qh.map : + (K ⟶ (HomotopyCategory.quotient _ _).obj L) → _ ) := + (CochainComplex.IsKInjective.rightOrthogonal L).map_bijective_of_isTriangulated _ _ diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean b/Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean new file mode 100644 index 00000000000000..a5211a56142e52 --- /dev/null +++ b/Mathlib/Algebra/Homology/HomotopyCategory/Acyclic.lean @@ -0,0 +1,72 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.HomotopyCategory.HomologicalFunctor +public import Mathlib.Algebra.Homology.HomotopyCategory.ShiftSequence +public import Mathlib.Algebra.Homology.Localization + +/-! +# The triangulated subcategory of acyclic complex in the homotopy category + +In this file, we define the triangulated subcategory +`HomotopyCategory.subcategoryAcyclic C` of the homotopy category of +cochain complexes in an abelian category `C`. +In the lemma `HomotopyCategory.quasiIso_eq_subcategoryAcyclic_W` we obtain +that the class of quasiisomorphisms `HomotopyCategory.quasiIso C (ComplexShape.up ℤ)` +consists of morphisms whose cone belongs to the triangulated subcategory +`HomotopyCategory.subcategoryAcyclic C` of acyclic complexes. + +-/ + +@[expose] public section + +universe v u + +open CategoryTheory Limits Pretriangulated + +variable (C : Type u) [Category.{v} C] [Abelian C] + +namespace HomotopyCategory + +/-- The triangulated subcategory of `HomotopyCategory C (ComplexShape.up ℤ)` consisting +of acyclic complexes. -/ +def subcategoryAcyclic : ObjectProperty (HomotopyCategory C (ComplexShape.up ℤ)) := + (homologyFunctor C (ComplexShape.up ℤ) 0).homologicalKernel + +instance : (subcategoryAcyclic C).IsTriangulated := by + dsimp [subcategoryAcyclic] + infer_instance + +instance : (subcategoryAcyclic C).IsClosedUnderIsomorphisms := by + dsimp [subcategoryAcyclic] + infer_instance + +variable {C} + +lemma mem_subcategoryAcyclic_iff (X : HomotopyCategory C (ComplexShape.up ℤ)) : + subcategoryAcyclic C X ↔ ∀ (n : ℤ), IsZero ((homologyFunctor _ _ n).obj X) := + Functor.mem_homologicalKernel_iff _ X + +lemma quotient_obj_mem_subcategoryAcyclic_iff_exactAt (K : CochainComplex C ℤ) : + subcategoryAcyclic C ((quotient _ _).obj K) ↔ ∀ (n : ℤ), K.ExactAt n := by + rw [mem_subcategoryAcyclic_iff] + refine forall_congr' (fun n => ?_) + simp only [HomologicalComplex.exactAt_iff_isZero_homology] + exact ((homologyFunctorFactors C (ComplexShape.up ℤ) n).app K).isZero_iff + +lemma quotient_obj_mem_subcategoryAcyclic_iff_acyclic (K : CochainComplex C ℤ) : + subcategoryAcyclic C ((quotient _ _).obj K) ↔ K.Acyclic := + quotient_obj_mem_subcategoryAcyclic_iff_exactAt _ + +variable (C) + +lemma quasiIso_eq_subcategoryAcyclic_W : + quasiIso C (ComplexShape.up ℤ) = (subcategoryAcyclic C).trW := by + ext K L f + exact ((homologyFunctor C (ComplexShape.up ℤ) 0).mem_homologicalKernel_trW_iff f).symm + +end HomotopyCategory diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean index 7aa13ccca98e0f..e7e463e179443b 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/KInjective.lean @@ -6,8 +6,9 @@ Authors: Joël Riou module public import Mathlib.Algebra.Homology.Embedding.CochainComplex +public import Mathlib.Algebra.Homology.HomotopyCategory.Acyclic public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexInduction -public import Mathlib.Algebra.Homology.Homotopy +public import Mathlib.CategoryTheory.Triangulated.Orthogonal /-! # K-injective cochain complexes @@ -16,11 +17,6 @@ We define the notion of K-injective cochain complex in an abelian category, and show that bounded below complexes of injective objects are K-injective. ## TODO (@joelriou) -* Show that a cochain complex is K-injective iff its image in the homotopy -category belongs to the right orthogonal of the triangulated subcategory -of acyclic complexes -* Deduce that we can compute morphisms to a K-injective complex in the -derived category as homotopy classes of morphisms * Provide an API for computing `Ext`-groups using an injective resolution * Dualize everything @@ -43,6 +39,60 @@ class IsKInjective (L : CochainComplex C ℤ) : Prop where nonempty_homotopy_zero {K : CochainComplex C ℤ} (f : K ⟶ L) : K.Acyclic → Nonempty (Homotopy f 0) +/-- A choice of homotopy to zero for a morphism from an acyclic +cochain complex to a K-injective cochain complex. -/ +noncomputable irreducible_def IsKInjective.homotopyZero {K L : CochainComplex C ℤ} (f : K ⟶ L) + (hK : K.Acyclic) [L.IsKInjective] : + Homotopy f 0 := + (IsKInjective.nonempty_homotopy_zero f hK).some + +lemma _root_.HomotopyEquiv.isKInjective {L₁ L₂ : CochainComplex C ℤ} + (e : HomotopyEquiv L₁ L₂) + [L₁.IsKInjective] : L₂.IsKInjective where + nonempty_homotopy_zero {K} f hK := + ⟨Homotopy.trans (Homotopy.trans (.ofEq (by simp)) + ((e.homotopyInvHomId.symm.compLeft f).trans (.ofEq (by simp)))) + (((IsKInjective.homotopyZero (f ≫ e.inv) hK).compRight e.hom).trans (.ofEq (by simp)))⟩ + +lemma isKInjective_of_iso {L₁ L₂ : CochainComplex C ℤ} (e : L₁ ≅ L₂) + [L₁.IsKInjective] : + L₂.IsKInjective := + (HomotopyEquiv.ofIso e).isKInjective + +lemma isKInjective_iff_of_iso {L₁ L₂ : CochainComplex C ℤ} (e : L₁ ≅ L₂) : + L₁.IsKInjective ↔ L₂.IsKInjective := + ⟨fun _ ↦ isKInjective_of_iso e, fun _ ↦ isKInjective_of_iso e.symm⟩ + +lemma isKInjective_iff_rightOrthogonal (L : CochainComplex C ℤ) : + L.IsKInjective ↔ + (HomotopyCategory.subcategoryAcyclic C).rightOrthogonal + ((HomotopyCategory.quotient _ _).obj L) := by + refine ⟨fun _ K f hK ↦ ?_, + fun hL ↦ ⟨fun {K} f hK ↦ ⟨HomotopyCategory.homotopyOfEq _ _ ?_⟩⟩⟩ + · obtain ⟨K, rfl⟩ := HomotopyCategory.quotient_obj_surjective K + obtain ⟨f, rfl⟩ := (HomotopyCategory.quotient _ _).map_surjective f + rw [HomotopyCategory.quotient_obj_mem_subcategoryAcyclic_iff_acyclic] at hK + rw [HomotopyCategory.eq_of_homotopy f 0 (IsKInjective.homotopyZero f hK), Functor.map_zero] + · rw [← HomotopyCategory.quotient_obj_mem_subcategoryAcyclic_iff_acyclic] at hK + rw [hL ((HomotopyCategory.quotient _ _).map f) hK, Functor.map_zero] + +lemma IsKInjective.rightOrthogonal (L : CochainComplex C ℤ) [L.IsKInjective] : + (HomotopyCategory.subcategoryAcyclic C).rightOrthogonal + ((HomotopyCategory.quotient _ _).obj L) := by + rwa [← isKInjective_iff_rightOrthogonal] + +instance (L : CochainComplex C ℤ) [hL : L.IsKInjective] (n : ℤ) : + (L⟦n⟧).IsKInjective := by + rw [isKInjective_iff_rightOrthogonal] at hL ⊢ + exact ObjectProperty.prop_of_iso _ + (((HomotopyCategory.quotient C (.up ℤ)).commShiftIso n).symm.app L) + ((HomotopyCategory.subcategoryAcyclic C).rightOrthogonal.le_shift n _ hL) + +lemma isKInjective_shift_iff (L : CochainComplex C ℤ) (n : ℤ) : + (L⟦n⟧).IsKInjective ↔ L.IsKInjective := + ⟨fun _ ↦ isKInjective_of_iso (show L⟦n⟧⟦-n⟧ ≅ L from (shiftEquiv _ n).unitIso.symm.app L), + fun _ ↦ inferInstance⟩ + lemma isKInjective_of_injective_aux {K L : CochainComplex C ℤ} (f : K ⟶ L) (α : Cochain K L (-1)) (n m : ℤ) (hnm : n + 1 = m) (hK : K.ExactAt m) [Injective (L.X m)] diff --git a/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean index dc3f4f0c08d8a6..47273334c8a3c8 100644 --- a/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean +++ b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean @@ -19,6 +19,8 @@ for `P.leftOrthogonal` is also obtained. -/ +@[expose] public section + universe v v' u u' namespace CategoryTheory From 37cf3151d5cb91e16690c0b2bff131d10f8b9659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 22 Nov 2025 12:43:11 +0100 Subject: [PATCH 15/60] fix --- Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean | 2 +- Mathlib/CategoryTheory/Triangulated/Orthogonal.lean | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean index 5c06768f3f9240..1bf68129bb960c 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -23,7 +23,7 @@ morphisms in the derived category. universe w v u -open CategoryTheory Limits Pretriangulated +open CategoryTheory variable {C : Type u} [Category.{v} C] [Abelian C] diff --git a/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean index 47273334c8a3c8..32140bcf2e489e 100644 --- a/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean +++ b/Mathlib/CategoryTheory/Triangulated/Orthogonal.lean @@ -51,12 +51,12 @@ end variable [HasZeroObject C] [HasShift C ℤ] [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] -instance [P.IsTriangulatedClosed₂] : P.rightOrthogonal.IsTriangulatedClosed₂ := +instance : P.rightOrthogonal.IsTriangulatedClosed₂ := .mk' (fun T hT h₁ h₃ X f hX ↦ by obtain ⟨g, rfl⟩ := Pretriangulated.Triangle.coyoneda_exact₂ T hT f (h₃ _ hX) simp [h₁ g hX]) -instance [P.IsTriangulatedClosed₂] : P.leftOrthogonal.IsTriangulatedClosed₂ := +instance : P.leftOrthogonal.IsTriangulatedClosed₂ := .mk' (fun T hT h₁ h₃ Y f hY ↦ by obtain ⟨g, rfl⟩ := Pretriangulated.Triangle.yoneda_exact₂ T hT f (h₁ _ hY) simp [h₃ g hY]) From 5065e6b7c3be55c9696f203d07852ced98b805a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 23 Nov 2025 16:39:53 +0100 Subject: [PATCH 16/60] the cochain complex indexed by integers associated to an injective resolution --- Mathlib.lean | 1 + .../Homology/Embedding/CochainComplex.lean | 4 + .../Algebra/Homology/Embedding/Extend.lean | 54 ++++++++++++ .../Homology/Embedding/ExtendHomology.lean | 4 + .../Abelian/Injective/Extend.lean | 87 +++++++++++++++++++ 5 files changed, 150 insertions(+) create mode 100644 Mathlib/CategoryTheory/Abelian/Injective/Extend.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8e256fc8ff6e3a..4a0dd3caab2cd9 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2161,6 +2161,7 @@ public import Mathlib.CategoryTheory.Abelian.Images public import Mathlib.CategoryTheory.Abelian.Indization public import Mathlib.CategoryTheory.Abelian.Injective.Basic public import Mathlib.CategoryTheory.Abelian.Injective.Dimension +public import Mathlib.CategoryTheory.Abelian.Injective.Extend public import Mathlib.CategoryTheory.Abelian.Injective.Resolution public import Mathlib.CategoryTheory.Abelian.LeftDerived public import Mathlib.CategoryTheory.Abelian.Monomorphisms diff --git a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean index e8943228c5af77..fe1ddc29e1345b 100644 --- a/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean +++ b/Mathlib/Algebra/Homology/Embedding/CochainComplex.lean @@ -212,6 +212,10 @@ section variable [HasZeroObject C] +instance (X : CochainComplex C ℕ) : + CochainComplex.IsStrictlyGE (X.extend embeddingUpNat) 0 where + isZero _ _ := isZero_extend_X _ _ _ (by aesop) + /-- A cochain complex that is both strictly `≤ n` and `≥ n` is isomorphic to a complex `(single _ _ n).obj M` for some object `M`. -/ lemma exists_iso_single (n : ℤ) [K.IsStrictlyGE n] [K.IsStrictlyLE n] : diff --git a/Mathlib/Algebra/Homology/Embedding/Extend.lean b/Mathlib/Algebra/Homology/Embedding/Extend.lean index ccfdfb973abc67..72d9043decc4cb 100644 --- a/Mathlib/Algebra/Homology/Embedding/Extend.lean +++ b/Mathlib/Algebra/Homology/Embedding/Extend.lean @@ -267,6 +267,60 @@ lemma extendMap_add [Preadditive C] {K L : HomologicalComplex C c} (φ φ' : K simp [extendMap_f _ e hi] · apply (K.isZero_extend_X e i' (fun i hi => hi' ⟨i, hi⟩)).eq_of_src +section + +variable [HasZeroMorphisms C] [DecidableEq ι] + (e : c.Embedding c') (X : C) + +@[simp] +lemma extend_single_d (i : ι) (j' k' : ι') : + (((single C c i).obj X).extend e).d j' k' = 0 := by + by_cases hj : ∃ j, e.f j = j' + · obtain ⟨j, rfl⟩ := hj + by_cases hk : ∃ k, e.f k = k' + · obtain ⟨k, rfl⟩ := hk + simp [extend_d_eq _ _ rfl rfl] + · exact IsZero.eq_of_tgt (isZero_extend_X _ _ _ (by tauto)) _ _ + · exact IsZero.eq_of_src (isZero_extend_X _ _ _ (by tauto)) _ _ + +variable [DecidableEq ι'] (i : ι) (i' : ι') + +/-- The extension of a single complex is a single complex. -/ +noncomputable def extendSingleIso (h : e.f i = i') : + ((single C c i).obj X).extend e ≅ (single C c' i').obj X where + hom := + mkHomToSingle + ((((single C c i).obj X).extendXIso e h).hom ≫ (singleObjXSelf c i X).hom) (by simp) + inv := + mkHomFromSingle + ((singleObjXSelf c i X).inv ≫ (((single C c i).obj X).extendXIso e h).inv) (by simp) + hom_inv_id := by + ext j' + by_cases hj : ∃ j, e.f j = j' + · obtain ⟨j, hj⟩ := hj + by_cases hij : j = i + · obtain rfl : i' = j' := by rw [← hj, hij, h] + simp + · exact ((isZero_single_obj_X _ _ _ _ hij).of_iso + (((single C c i).obj X).extendXIso e hj)).eq_of_src _ _ + · exact IsZero.eq_of_src (isZero_extend_X _ _ _ (by tauto)) _ _ + +@[reassoc] +lemma extendSingleIso_hom_f (h : e.f i = i') : + (extendSingleIso e X i i' h).hom.f i' = + (((single C c i).obj X).extendXIso e h).hom ≫ (singleObjXSelf c i X).hom ≫ + (singleObjXSelf c' i' X).inv := by + simp [extendSingleIso] + +@[reassoc] +lemma extendSingleIso_inv_f (h : e.f i = i') : + (extendSingleIso e X i i' h).inv.f i' = + (singleObjXSelf c' i' X).hom ≫ (singleObjXSelf c i X).inv ≫ + (((single C c i).obj X).extendXIso e h).inv := by + simp [extendSingleIso] + +end + end HomologicalComplex namespace ComplexShape.Embedding diff --git a/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean b/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean index 5e9f24ec8dc01c..d7e1dc3134d97b 100644 --- a/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean +++ b/Mathlib/Algebra/Homology/Embedding/ExtendHomology.lean @@ -429,4 +429,8 @@ lemma quasiIso_extendMap_iff [∀ j, K.HasHomology j] [∀ j, L.HasHomology j] : all_goals exact extend_exactAt _ _ _ (by simpa using hj') +instance [∀ j, K.HasHomology j] [∀ j, L.HasHomology j] [QuasiIso φ] : + QuasiIso (extendMap φ e) := by + rwa [quasiIso_extendMap_iff] + end HomologicalComplex diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean new file mode 100644 index 00000000000000..01bb1c8a13341e --- /dev/null +++ b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean @@ -0,0 +1,87 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.Embedding.CochainComplex +public import Mathlib.CategoryTheory.Preadditive.Injective.Resolution + +/-! +# Injective resolutions as cochain complexes indexed by the integers + +Given an injective resolution `R` on an object `X` in an abelian category, +we define `R.cochainComplex : CochainComplex C ℤ`, which is the extension +of `R.cocomplex : CochainComplex C ℕ`, and the quasi-isomorphism +`R.ι' : (CochainComplex.singleFunctor C 0).obj X ⟶ R.cochainComplex`. + +-/ + +@[expose] public section + +universe v u + +namespace CategoryTheory + +open Limits + +variable {C : Type u} [Category.{v} C] + +namespace InjectiveResolution + +section + +variable [HasZeroObject C] [Preadditive C] {X : C} + (R : InjectiveResolution X) + +/-- If `R : InjectiveResolution X`, this is the cochain complex indexed by `ℤ` +obtained by extending by zero the `R.cocomplex`. -/ +noncomputable def cochainComplex : CochainComplex C ℤ := + R.cocomplex.extend ComplexShape.embeddingUpNat + +/-- If `R : InjectiveResolution X`, then `R.cochainComplex.X n` (with `n : ℕ`) +is isomorphic to `R.cocomplex.X k` (with `k : ℕ`) when `k = n`. -/ +noncomputable def cochainComplexXIso (n : ℤ) (k : ℕ) (h : k = n) : + R.cochainComplex.X n ≅ R.cocomplex.X k := + HomologicalComplex.extendXIso _ _ h + +@[reassoc] +lemma cochainComplex_d (n₁ n₂ : ℤ) (k₁ k₂ : ℕ) (h₁ : k₁ = n₁) (h₂ : k₂ = n₂) : + R.cochainComplex.d n₁ n₂ = (cochainComplexXIso _ _ _ h₁).hom ≫ + R.cocomplex.d k₁ k₂ ≫ (cochainComplexXIso _ _ _ h₂).inv := + HomologicalComplex.extend_d_eq _ _ h₁ h₂ + +instance : R.cochainComplex.IsStrictlyGE 0 := by + dsimp [cochainComplex] + infer_instance + +instance (n : ℤ) : Injective (R.cochainComplex.X n) := by + by_cases hn : 0 ≤ n + · obtain ⟨k, rfl⟩ := Int.eq_ofNat_of_zero_le hn + exact Injective.of_iso (R.cochainComplexXIso _ _ rfl).symm inferInstance + · exact IsZero.injective (CochainComplex.isZero_of_isStrictlyGE _ 0 _ (by cutsat)) + +/-- The quasi-isomorphism `(CochainComplex.singleFunctor C 0).obj X ⟶ R.cochainComplex` +in `CochainComplex C ℤ` when `R` is an injective resolution of `X`. -/ +noncomputable def ι' : (CochainComplex.singleFunctor C 0).obj X ⟶ R.cochainComplex := + (HomologicalComplex.extendSingleIso _ _ _ _ (by simp)).inv ≫ + (ComplexShape.embeddingUpNat.extendFunctor C).map R.ι + +lemma ι'_f_zero : + R.ι'.f 0 = (HomologicalComplex.singleObjXSelf (.up ℤ) 0 X).hom ≫ R.ι.f 0 ≫ + (R.cochainComplexXIso _ _ (by simp)).inv := by + dsimp [ι'] + rw [HomologicalComplex.extendMap_f _ _ (i := 0) (by simp), + HomologicalComplex.extendSingleIso_inv_f] + cat_disch + +end + +variable [Abelian C] {X : C} (R : InjectiveResolution X) + +instance : QuasiIso R.ι' := by dsimp [ι']; infer_instance + +end InjectiveResolution + +end CategoryTheory From 79a9e1284bec63841c46aee95712867470fb87b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 23 Nov 2025 16:40:47 +0100 Subject: [PATCH 17/60] typo --- Mathlib/CategoryTheory/Abelian/Injective/Extend.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean index 01bb1c8a13341e..bac76d56a9ab2d 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean @@ -11,7 +11,7 @@ public import Mathlib.CategoryTheory.Preadditive.Injective.Resolution /-! # Injective resolutions as cochain complexes indexed by the integers -Given an injective resolution `R` on an object `X` in an abelian category, +Given an injective resolution `R` of an object `X` in an abelian category `C`, we define `R.cochainComplex : CochainComplex C ℤ`, which is the extension of `R.cocomplex : CochainComplex C ℕ`, and the quasi-isomorphism `R.ι' : (CochainComplex.singleFunctor C 0).obj X ⟶ R.cochainComplex`. From 2455b116196cd36a6c8cee41c85124d67e7b57d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 11:45:27 +0100 Subject: [PATCH 18/60] feat(Algebra/Homology): cohomology of HomComplex --- Mathlib.lean | 1 + .../Homology/HomotopyCategory/HomComplex.lean | 22 +++ .../HomComplexCohomology.lean | 161 ++++++++++++++++++ 3 files changed, 184 insertions(+) create mode 100644 Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1c867654297929..e297f32e511b13 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -581,6 +581,7 @@ public import Mathlib.Algebra.Homology.Homotopy public import Mathlib.Algebra.Homology.HomotopyCategory public import Mathlib.Algebra.Homology.HomotopyCategory.DegreewiseSplit public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexShift public import Mathlib.Algebra.Homology.HomotopyCategory.HomologicalFunctor public import Mathlib.Algebra.Homology.HomotopyCategory.MappingCone diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index 8d6e33e82967f7..c093fa596ffca0 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -704,6 +704,28 @@ def diff : Cocycle K K 1 := simp only [Cochain.zero_v, δ_v 1 2 rfl _ p q hpq _ _ rfl rfl, Cochain.diff_v, HomologicalComplex.d_comp_d, smul_zero, add_zero]) +variable (L n) in +/-- The inclusion `Cocycle K L n →+ Cochain K L n`. -/ +@[simps] +def toCochainAddMonoidHom : Cocycle K L n →+ Cochain K L n where + toFun x := x + map_zero' := by simp + map_add' := by simp + +variable (L n) in +/-- `Cocycle K L n` is the kernel of the differential on `HomComplex K L`. -/ +def isKernel (hm : n + 1 = m) : + IsLimit ((KernelFork.ofι (f := (HomComplex K L).d n m) + (AddCommGrpCat.ofHom (toCochainAddMonoidHom K L n))) (by cat_disch)) := + Fork.IsLimit.mk _ + (fun s ↦ AddCommGrpCat.ofHom + { toFun x := ⟨s.ι x, by + rw [mem_iff _ _ hm] + exact ConcreteCategory.congr_hom s.condition x⟩ + map_zero' := by cat_disch + map_add' := by cat_disch }) + (by cat_disch) (fun s l hl ↦ by ext : 3; simp [← hl]) + end Cocycle variable {F G} diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean new file mode 100644 index 00000000000000..4a3950db8d1627 --- /dev/null +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -0,0 +1,161 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.ShortComplex.Ab +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex +public import Mathlib.Algebra.Homology.HomotopyCategory.Shift + +/-! +# Cohomology of the hom complex + +Given `ℤ`-index cochain complexes `K` and `L`, and `n : ℤ`, we introduce +a type `HomComplex.CohomologyClass K L n` which is the quotient +of `HomComplex.Cocycle K L n` which identifies cohomologous cocycles. +The reason for not applying the homology API to this complex is that +`Cochain K L` can be considered both as a complex of abelian groups +or as a complex of `R`-modules when the category is `R`-linear. + + +-/ + +@[expose] public section + +assert_not_exists TwoSidedIdeal + +open CategoryTheory Category Limits Preadditive + +universe v u + +variable {C : Type u} [Category.{v} C] [Preadditive C] {R : Type*} [Ring R] [Linear R C] + +namespace CochainComplex + +variable (K L : CochainComplex C ℤ) (n m p : ℤ) + +namespace HomComplex + +/-- The subgroup of `Cocycle K L n` consisting of coboundaries. -/ +def coboundaries : AddSubgroup (Cocycle K L n) where + carrier := setOf (fun α ↦ ∃ (m : ℤ) (hm : m + 1 = n) (β : Cochain K L m), δ m n β = α) + zero_mem' := ⟨n - 1, by simp, 0, by simp⟩ + add_mem' := by + rintro α₁ α₂ ⟨m, hm, β₁, hβ₁⟩ ⟨m', hm', β₂, hβ₂⟩ + obtain rfl : m = m' := by cutsat + exact ⟨m, hm, β₁ + β₂, by aesop⟩ + neg_mem' := by + rintro α ⟨m, hm, β, hβ⟩ + exact ⟨m, hm, -β, by aesop⟩ + +/-- The type of cohomology classes of degree `n` in the complex of morphisms +from `K` to `L`. -/ +def CohomologyClass : Type v := Cocycle K L n ⧸ coboundaries K L n + +instance : AddCommGroup (CohomologyClass K L n) := + inferInstanceAs (AddCommGroup (Cocycle K L n ⧸ coboundaries K L n)) + +namespace CohomologyClass + +variable {K L n} + +/-- The cohomology class of a cocycle. -/ +def mk (x : Cocycle K L n) : CohomologyClass K L n := + Quotient.mk _ x + +lemma mk_surjective : Function.Surjective (mk : Cocycle K L n → _) := + Quotient.mk_surjective + +variable (K L n) in +@[simp] +lemma mk_zero : + mk (0 : Cocycle K L n) = 0 := rfl + +@[simp] +lemma mk_add (x y : Cocycle K L n) : + mk (x + y) = mk x + mk y := rfl + +@[simp] +lemma mk_sub (x y : Cocycle K L n) : + mk (x - y) = mk x - mk y := rfl + +@[simp] +lemma mk_neg (x : Cocycle K L n) : + mk (-x) = - mk x := rfl + +lemma mk_eq_zero_iff (x : Cocycle K L n) : + mk x = 0 ↔ x ∈ coboundaries K L n := + QuotientAddGroup.eq_zero_iff x + +variable (K L n) in +/-- The projection map `Cocycle K L n →+ CohomologyClass K L n`. -/ +@[simps] +def mkAddMonoidHom : Cocycle K L n →+ CohomologyClass K L n where + toFun := mk + map_zero' := by simp + map_add' := by simp + +section + +variable {G : Type*} [AddCommGroup G] + (f : Cocycle K L n →+ G) (hf : coboundaries K L n ≤ f.ker) + +/-- Constructor for additive morphisms from `CohomologyClass K L n`. -/ +def descAddMonoidHom : + CohomologyClass K L n →+ G := + QuotientAddGroup.lift _ f hf + +@[simp] +lemma descAddMonoidHom_cohomologyClass (x : Cocycle K L n) : + descAddMonoidHom f hf (mk x) = f x := rfl + +end + +end CohomologyClass + +/-- `CohomologyClass K L m` identifies to the cohomology of the complex `HomComplex K L` +in degree `m`. -/ +@[simps] +def leftHomologyData' (hm : n + 1 = m) (hp : m + 1 = p) : + ((HomComplex K L).sc' n m p).LeftHomologyData where + K := .of (Cocycle K L m) + H := .of (CohomologyClass K L m) + i := AddCommGrpCat.ofHom (Cocycle.toCochainAddMonoidHom K L m) + π := AddCommGrpCat.ofHom (CohomologyClass.mkAddMonoidHom K L m) + wi := by cat_disch + hi := Cocycle.isKernel K L _ _ hp + wπ := by + ext x + dsimp + rw [CohomologyClass.mk_eq_zero_iff] + exact ⟨n, hm, x, rfl⟩ + hπ := + Cofork.IsColimit.mk _ + (fun s ↦ AddCommGrpCat.ofHom (CohomologyClass.descAddMonoidHom s.π.hom + (by + rintro ⟨_, _⟩ ⟨q, hq, y, rfl⟩ + obtain rfl : n = q := by cutsat + simpa only [zero_comp] using ConcreteCategory.congr_hom s.condition y))) + (fun s ↦ rfl) + (fun s l hl ↦ by + ext x + obtain ⟨y, rfl⟩ := x.mk_surjective + simpa using ConcreteCategory.congr_hom hl y) + +/-- `CohomologyClass K L m` identifies to the cohomology of the complex `HomComplex K L` +in degree `m`. -/ +@[simps!] +noncomputable def leftHomologyData : + ((HomComplex K L).sc n).LeftHomologyData := + leftHomologyData' K L _ n _ (by simp) (by simp) + +/-- The homology of `HomComplex K L` in degree `n` identifies to `CohomologyClass K L n`. -/ +noncomputable def homologyAddEquiv : + (HomComplex K L).homology n ≃+ CohomologyClass K L n := + (leftHomologyData K L n).homologyIso.addCommGroupIsoToAddEquiv + +end HomComplex + +end CochainComplex From fb9a8924a4fe38c064af9f655c24988c23bc800f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 11:46:55 +0100 Subject: [PATCH 19/60] typo --- .../Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index 4a3950db8d1627..b3dcea24b9cb53 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -12,7 +12,7 @@ public import Mathlib.Algebra.Homology.HomotopyCategory.Shift /-! # Cohomology of the hom complex -Given `ℤ`-index cochain complexes `K` and `L`, and `n : ℤ`, we introduce +Given `ℤ`-indexed cochain complexes `K` and `L`, and `n : ℤ`, we introduce a type `HomComplex.CohomologyClass K L n` which is the quotient of `HomComplex.Cocycle K L n` which identifies cohomologous cocycles. The reason for not applying the homology API to this complex is that From ecd0ef4cadd7fc05277271d5aaa1824aae9166e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 12:36:38 +0100 Subject: [PATCH 20/60] morphisms in the homotopy category --- .../Algebra/Homology/HomotopyCategory.lean | 5 ++ .../HomComplexCohomology.lean | 51 ++++++++++++++++++- .../HomotopyCategory/HomComplexShift.lean | 15 ++++++ 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory.lean b/Mathlib/Algebra/Homology/HomotopyCategory.lean index a5dd78f34cc955..d56b3e192f8494 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory.lean @@ -119,6 +119,11 @@ def homotopyOfEq {C D : HomologicalComplex V c} (f g : C ⟶ D) (w : (quotient V c).map f = (quotient V c).map g) : Homotopy f g := ((Quotient.functor_map_eq_iff _ _ _).mp w).some +lemma quotient_map_eq_zero_iff {C D : HomologicalComplex V c} (f : C ⟶ D) : + (quotient V c).map f = 0 ↔ Nonempty (Homotopy f 0) := + ⟨fun h ↦ ⟨homotopyOfEq _ _ (by simpa using h)⟩, + fun ⟨h⟩ ↦ by simpa using eq_of_homotopy _ _ h⟩ + /-- An arbitrarily chosen representation of the image of a chain map in the homotopy category is homotopic to the original chain map. -/ diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index b3dcea24b9cb53..5fecaed4d392bb 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -6,8 +6,7 @@ Authors: Joël Riou module public import Mathlib.Algebra.Homology.ShortComplex.Ab -public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex -public import Mathlib.Algebra.Homology.HomotopyCategory.Shift +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexShift /-! # Cohomology of the hom complex @@ -19,6 +18,8 @@ The reason for not applying the homology API to this complex is that `Cochain K L` can be considered both as a complex of abelian groups or as a complex of `R`-modules when the category is `R`-linear. +We also show that `HomComplex.CohomologyClass K L n` identifies to +the type of morphisms between `K` and `L⟦n⟧` in the homotopy category. -/ @@ -113,6 +114,52 @@ lemma descAddMonoidHom_cohomologyClass (x : Cocycle K L n) : end +/-- The additive map which sends a cohomology class to the corresponding morphism +in the homotopy category. -/ +def toHom : + CohomologyClass K L n →+ + ((HomotopyCategory.quotient C _).obj K ⟶ (HomotopyCategory.quotient C _).obj (L⟦n⟧)) := + descAddMonoidHom ((Functor.mapAddHom _).comp Cocycle.equivHomShift.symm.toAddMonoidHom) (by + rintro ⟨x, _⟩ ⟨m, hm, β, rfl⟩ + simp only [AddMonoidHom.mem_ker, AddMonoidHom.coe_comp, AddMonoidHom.coe_coe, + AddEquiv.toAddMonoidHom_eq_coe, Function.comp_apply, Cocycle.equivHomShift_symm_apply, + Functor.mapAddHom_apply, HomotopyCategory.quotient_map_eq_zero_iff] + exact ⟨(Cochain.equivHomotopy _ _).symm ⟨n.negOnePow • β.rightShift _ _ (by cutsat), + by simp [Cochain.δ_rightShift _ _ _ _ _ _ (zero_add n), smul_smul]⟩⟩) + +lemma toHom_mk (x : Cocycle K L n) : + toHom (mk x) = (HomotopyCategory.quotient C _).map (Cocycle.equivHomShift.symm x) := rfl + +lemma toHom_mk_eq_zero_iff (x : Cocycle K L n) : + toHom (mk x) = 0 ↔ x ∈ coboundaries K L n := by + refine ⟨fun h ↦ ?_, fun h ↦ ?_⟩ + · simp only [coboundaries, exists_prop, AddSubgroup.mem_mk, AddSubmonoid.mem_mk, + AddSubsemigroup.mem_mk, Set.mem_setOf_eq] + rw [toHom_mk, HomotopyCategory.quotient_map_eq_zero_iff] at h + obtain ⟨γ, h⟩ := Cochain.equivHomotopy _ _ h.some + simp only [Cochain.ofHom_zero, add_zero, Cocycle.equivHomShift_symm_apply, + Cocycle.cochain_ofHom_homOf_eq_coe, Cocycle.rightShift_coe] at h + exact ⟨n - 1, by simp, n.negOnePow • γ.rightUnshift _ (by cutsat), + by simp [Cochain.δ_rightUnshift _ _ _ _ _ (zero_add n), smul_smul, ← h]⟩ + · rw [← mk_eq_zero_iff] at h + rw [h, map_zero] + +lemma toHom_bijective : Function.Bijective (toHom : CohomologyClass K L n → _) := by + refine ⟨fun x y h ↦ ?_, fun f ↦ ?_⟩ + · obtain ⟨x, rfl⟩ := x.mk_surjective + obtain ⟨y, rfl⟩ := y.mk_surjective + rw [← sub_eq_zero, ← mk_sub, mk_eq_zero_iff, ← toHom_mk_eq_zero_iff, + mk_sub, map_sub, h, sub_self] + · obtain ⟨f, rfl⟩ := Functor.map_surjective _ f + exact ⟨mk (Cocycle.equivHomShift f), by simp [toHom_mk]⟩ + +/-- Cohomology classes identifies to morphisms in the homotopy category. -/ +@[simps! apply] +noncomputable def homAddEquiv : + CohomologyClass K L n ≃+ + ((HomotopyCategory.quotient C _).obj K ⟶ (HomotopyCategory.quotient C _).obj (L⟦n⟧)) := + AddEquiv.ofBijective toHom toHom_bijective + end CohomologyClass /-- `CohomologyClass K L m` identifies to the cohomology of the complex `HomComplex K L` diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean index 8d24794ae8c9ef..680c49ba89a23d 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean @@ -539,6 +539,21 @@ def shift (γ : Cocycle K L n) (a : ℤ) : Cocycle.mk (γ.1.shift a) _ rfl (by simp only [Cochain.δ_shift, δ_eq_zero, Cochain.shift_zero, smul_zero]) +/-- The additive equivalence `Cocycle K L n ≃+ Cocycle K L⟦a⟧ n'` when `n' + a = n`. -/ +@[simps] +def rightShiftAddEquiv (n a n' : ℤ) (hn' : n' + a = n) : + Cocycle K L n ≃+ Cocycle K (L⟦a⟧) n' where + toFun γ := γ.rightShift a n' hn' + invFun γ := γ.rightUnshift n hn' + left_inv γ := by cat_disch + right_inv γ := by cat_disch + map_add' γ γ' := by cat_disch + +/-- The additive equivalence `K ⟶ L⟦n⟧ ≃+ Cocycle K L n`. -/ +@[simps! -isSimp apply symm_apply] +def equivHomShift : (K ⟶ L⟦n⟧) ≃+ Cocycle K L n := + (equivHom _ _).trans (rightShiftAddEquiv _ _ _ (zero_add n)).symm + end Cocycle end CochainComplex.HomComplex From 84cdbb1ff67db05a0349397e0fab47db1be5e219 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 13:17:31 +0100 Subject: [PATCH 21/60] wip --- Mathlib.lean | 1 + .../HomotopyCategory/HomComplexSingle.lean | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean diff --git a/Mathlib.lean b/Mathlib.lean index 8595094dda4780..68ed3b5101e8ea 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -582,6 +582,7 @@ public import Mathlib.Algebra.Homology.HomotopyCategory public import Mathlib.Algebra.Homology.HomotopyCategory.DegreewiseSplit public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexShift +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexSingle public import Mathlib.Algebra.Homology.HomotopyCategory.HomologicalFunctor public import Mathlib.Algebra.Homology.HomotopyCategory.MappingCone public import Mathlib.Algebra.Homology.HomotopyCategory.Pretriangulated diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean new file mode 100644 index 00000000000000..cb61413018c6f8 --- /dev/null +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -0,0 +1,40 @@ +/- +Copyright (c) 2023 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex + +/-! +# Cochains from single complexes + + +-/ + +@[expose] public section + +assert_not_exists TwoSidedIdeal + +open CategoryTheory Category Limits Preadditive + +universe v u + +variable {C : Type u} [Category.{v} C] [Preadditive C] + +namespace CochainComplex + +namespace HomComplex + +variable {X : C} {K : CochainComplex C ℤ} (n : ℤ) + +namespace Cochain + +def fromSingleMk + +end Cochain + +end HomComplex + +end CochainComplex From 0c72eacd551cb12dc0db9cb2ba3ad50d01759703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 14:07:38 +0100 Subject: [PATCH 22/60] feat(Algebra/Homology): cochains and cocycles from/to single complexes --- .../Homology/HomotopyCategory/HomComplex.lean | 49 ++++++++++ .../HomotopyCategory/HomComplexSingle.lean | 97 ++++++++++++++++++- .../HomotopyCategory/SingleFunctors.lean | 5 + 3 files changed, 147 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index 1fd9e4ea5354fb..74827af5b801e8 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -800,6 +800,55 @@ lemma single_v_eq_zero {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) (p' q' : ℤ) intro h exact hp' (by cutsat) +/-- Variant of `single_v_eq_zero` where the assumption is `q' ≠ q` rather than `p' ≠ p`. -/ +lemma single_v_eq_zero' {p q : ℤ} (f : K.X p ⟶ L.X q) (n : ℤ) (p' q' : ℤ) (hpq' : p' + n = q') + (hq' : q' ≠ q) : + (single f n).v p' q' hpq' = 0 := by + dsimp [single] + rw [dif_neg] + intro h + exact hq' (by cutsat) + +variable (K L) in +@[simp] +lemma single_zero (p q n : ℤ) : + (single (p := p) (q := q) 0 n : Cochain K L n) = 0 := by + ext p' q' hpq' + by_cases hp : p' = p + · subst hp + by_cases hq : q' = q + · subst hq + simp + · simp [single_v_eq_zero' _ _ _ _ _ hq] + · simp [single_v_eq_zero _ _ _ _ _ hp] + +lemma δ_single {p q : ℤ} (f : K.X p ⟶ L.X q) (n m : ℤ) (hm : n + 1 = m) + (p' q' : ℤ) (hp' : p' + 1 = p) (hq' : q + 1 = q') : + δ n m (single f n) = single (f ≫ L.d q q') m + m.negOnePow • single (K.d p' p ≫ f) m := by + ext p'' q'' hpq'' + rw [δ_v n m hm (single f n) p'' q'' (by cutsat) (q'' - 1) (p'' + 1) rfl (by cutsat), + add_v, units_smul_v] + congr 1 + · by_cases h : p'' = p + · subst h + by_cases h : q = q'' - 1 + · subst h + obtain rfl : q' = q'' := by cutsat + simp only [single_v] + · rw [single_v_eq_zero', single_v_eq_zero', zero_comp] + all_goals cutsat + · rw [single_v_eq_zero _ _ _ _ _ h, single_v_eq_zero _ _ _ _ _ h, zero_comp] + · subst hm + by_cases h : q'' = q + · subst h + by_cases h : p'' = p' + · subst h + obtain rfl : p = p'' + 1 := by cutsat + simp + · rw [single_v_eq_zero _ _ _ _ _ h, single_v_eq_zero, comp_zero, smul_zero] + cutsat + · simp only [single_v_eq_zero' _ _ _ _ _ h, comp_zero, smul_zero] + end Cochain section diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean index cb61413018c6f8..c0d024cdd0ec3c 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -6,10 +6,14 @@ Authors: Joël Riou module public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex +public import Mathlib.Algebra.Homology.HomotopyCategory.SingleFunctors /-! -# Cochains from single complexes +# Cochains from or to single complexes +We introduce constructors `Cochain.fromSingleMk` and `Cocycle.fromSingleMk` +for cochains and cocycles from a single complex. We also introduce similar +definitions for cochains and cocyles to a single complex. -/ @@ -21,20 +25,105 @@ open CategoryTheory Category Limits Preadditive universe v u -variable {C : Type u} [Category.{v} C] [Preadditive C] +variable {C : Type u} [Category.{v} C] [Preadditive C] [HasZeroObject C] namespace CochainComplex namespace HomComplex -variable {X : C} {K : CochainComplex C ℤ} (n : ℤ) +variable {X : C} {K : CochainComplex C ℤ} namespace Cochain -def fromSingleMk +/-- Constructor for cochains from a single complex. -/ +@[nolint unusedArguments] +noncomputable def fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (_ : p + n = q) : + Cochain ((singleFunctor C p).obj X) K n := + Cochain.single ((HomologicalComplex.singleObjXSelf (.up ℤ) p X).hom ≫ f) n + +variable (X K) in +@[simp] +lemma fromSingleMk_zero (p q n : ℤ) (h : p + n = q) : + fromSingleMk (X := X) (K := K) 0 h = 0 := by + simp [fromSingleMk] + +@[simp] +lemma fromSingleMk_v {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : + (fromSingleMk f h).v p q h = + (HomologicalComplex.singleObjXSelf (.up ℤ) p X).hom ≫ f := by + simp [fromSingleMk] + +lemma fromSingleMk_v_eq_zero {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (p' q' : ℤ) (hpq' : p' + n = q') (hp' : p' ≠ p) : + (fromSingleMk f h).v p' q' hpq' = 0 := + single_v_eq_zero _ _ _ _ _ hp' + +lemma δ_fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (n' q' : ℤ) (h' : p + n' = q') : + δ n n' (fromSingleMk f h) = fromSingleMk (f ≫ K.d q q') h' := by + by_cases hq : q + 1 = q' + · dsimp only [fromSingleMk] + rw [δ_single _ n n' (by cutsat) (p - 1) q' (by cutsat) hq] + simp + · simp [δ_shape n n' (by cutsat), HomologicalComplex.shape K q q' (by simp; cutsat), + fromSingleMk] + +/-- Constructor for cochains to a single complex. -/ +@[nolint unusedArguments] +noncomputable def toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (_ : p + n = q) : + Cochain K ((singleFunctor C q).obj X) n := + Cochain.single (f ≫ (HomologicalComplex.singleObjXSelf (.up ℤ) q X).inv) n + +variable (X K) in +@[simp] +lemma toSingleMk_zero (p q n : ℤ) (h : p + n = q) : + toSingleMk (X := X) (K := K) 0 h = 0 := by + simp [toSingleMk] + +@[simp] +lemma toSingleMk_v {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) : + (toSingleMk f h).v p q h = + f ≫ (HomologicalComplex.singleObjXSelf (.up ℤ) q X).inv := by + simp [toSingleMk] + +lemma toSingleMk_v_eq_zero {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) + (p' q' : ℤ) (hpq' : p' + n = q') (hp' : p' ≠ p) : + (toSingleMk f h).v p' q' hpq' = 0 := + single_v_eq_zero _ _ _ _ _ hp' + +lemma δ_toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) + (n' p' : ℤ) (h' : p' + n' = q) : + δ n n' (toSingleMk f h) = n'.negOnePow • toSingleMk (K.d p' p ≫ f) h' := by + by_cases hp : p' + 1 = p + · dsimp only [toSingleMk] + rw [δ_single _ n n' (by cutsat) p' (q + 1) (by cutsat) rfl] + simp + · simp [δ_shape n n' (by cutsat), HomologicalComplex.shape K p' p (by simp; cutsat)] end Cochain +namespace Cocycle + +/-- Constructor for cocycles from a single complex. -/ +@[simps!] +noncomputable def fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (q' : ℤ) (hq' : q + 1 = q') (hf : f ≫ K.d q q' = 0) : + Cocycle ((singleFunctor C p).obj X) K n := + Cocycle.mk (Cochain.fromSingleMk f h) _ rfl (by + rw [Cochain.δ_fromSingleMk _ _ _ q' (by cutsat), hf] + simp) + +/-- Constructor for cocycles to a single complex. -/ +@[simps!] +noncomputable def toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) + (p' : ℤ) (hp' : p' + 1 = p) (hf : K.d p' p ≫ f = 0) : + Cocycle K ((singleFunctor C q).obj X) n := + Cocycle.mk (Cochain.toSingleMk f h) _ rfl (by + rw [Cochain.δ_toSingleMk _ _ _ p' (by cutsat), hf] + simp) + +end Cocycle + end HomComplex end CochainComplex diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean b/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean index c154e4096270ed..91eb28ecdf880f 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/SingleFunctors.lean @@ -79,6 +79,11 @@ consisting of `X` in degree `n : ℤ` and zero otherwise. but `singleFunctor C n` is the preferred term when interactions with shifts are relevant.) -/ noncomputable abbrev singleFunctor (n : ℤ) := (singleFunctors C).functor n +variable {C} in +@[simp] +lemma singleFunctor_obj_d (X : C) (n p q : ℤ) : + ((singleFunctor C n).obj X).d p q = 0 := rfl + instance (n : ℤ) : (singleFunctor C n).Full := inferInstanceAs (single _ _ _).Full From ecae259f36e396a10a4b3479f0ace697e99aadee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 16:47:51 +0100 Subject: [PATCH 23/60] feat(CategoryTheory): constructor for Ext-groups using an injective resolution --- Mathlib.lean | 2 +- .../Ext/InjectiveResolution.lean | 0 .../CategoryTheory/Abelian/Injective/Ext.lean | 71 +++++++++++++++++ .../Localization/SmallShiftedHom.lean | 79 +++++++++++++++++++ 4 files changed, 151 insertions(+), 1 deletion(-) delete mode 100644 Mathlib/Algebra/Homology/DerivedCategory/Ext/InjectiveResolution.lean create mode 100644 Mathlib/CategoryTheory/Abelian/Injective/Ext.lean diff --git a/Mathlib.lean b/Mathlib.lean index 0c3217200346f5..dc87a1cff50d29 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -538,7 +538,6 @@ public import Mathlib.Algebra.Homology.DerivedCategory.Ext.EnoughInjectives public import Mathlib.Algebra.Homology.DerivedCategory.Ext.EnoughProjectives public import Mathlib.Algebra.Homology.DerivedCategory.Ext.ExactSequences public import Mathlib.Algebra.Homology.DerivedCategory.Ext.ExtClass -public import Mathlib.Algebra.Homology.DerivedCategory.Ext.InjectiveResolution public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Linear public import Mathlib.Algebra.Homology.DerivedCategory.Fractions public import Mathlib.Algebra.Homology.DerivedCategory.FullyFaithful @@ -2175,6 +2174,7 @@ public import Mathlib.CategoryTheory.Abelian.Images public import Mathlib.CategoryTheory.Abelian.Indization public import Mathlib.CategoryTheory.Abelian.Injective.Basic public import Mathlib.CategoryTheory.Abelian.Injective.Dimension +public import Mathlib.CategoryTheory.Abelian.Injective.Ext public import Mathlib.CategoryTheory.Abelian.Injective.Extend public import Mathlib.CategoryTheory.Abelian.Injective.Resolution public import Mathlib.CategoryTheory.Abelian.LeftDerived diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/InjectiveResolution.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/InjectiveResolution.lean deleted file mode 100644 index e69de29bb2d1d6..00000000000000 diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean new file mode 100644 index 00000000000000..cc0924106cbc0e --- /dev/null +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -0,0 +1,71 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Basic +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexSingle +public import Mathlib.Algebra.Homology.HomotopyCategory.KInjective +public import Mathlib.CategoryTheory.Abelian.Injective.Extend + +/-! +# Computing `Ext` using an injective resolution + +-/ + +@[expose] public section + +universe w v u + +open CategoryTheory CochainComplex HomComplex Abelian Localization + +def CochainComplex.HomComplex.equivOfIsKInjective + {C : Type u} [Category.{v} C] [Abelian C] + {K L : CochainComplex C ℤ} [L.IsKInjective] {n : ℤ} + [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] : + CohomologyClass K L n ≃ + SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ) ) K L n := sorry + +namespace CategoryTheory + +variable {C : Type u} [Category.{v} C] [Abelian C] [HasExt.{w} C] + +namespace InjectiveResolution + +variable {X Y : C} (R : InjectiveResolution Y) {n : ℕ} + +instance : R.cochainComplex.IsKInjective := isKInjective_of_injective _ 0 + +-- should be generalized as a lemma +instance (K L : CochainComplex C ℤ) [K.IsGE 0] [K.IsLE 0] [L.IsGE 0] [L.IsLE 0] : + HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso _ _) ℤ K L := sorry + +instance : R.cochainComplex.IsGE 0 := sorry + +instance : R.cochainComplex.IsLE 0 := sorry + +noncomputable def extEquivCohomologyClass : + Ext X Y n ≃ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := by + have hι' : HomologicalComplex.quasiIso C (ComplexShape.up ℤ) R.ι' := by + simp only [HomologicalComplex.mem_quasiIso_iff] + infer_instance + exact (SmallShiftedHom.postcompEquiv.{w} R.ι' + (by rw [HomologicalComplex.mem_quasiIso_iff]; infer_instance)).trans + CochainComplex.HomComplex.equivOfIsKInjective.{w}.symm + +/-- Given an injective resolution `R` of an object `Y` of an abelian category, +this is a constructor for elements in `Ext X Y n` which takes as an input +a "cocycle" `f : X ⟶ R.cocomplex.X n`. -/ +noncomputable def extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) + (hf : f ≫ R.cocomplex.d n m = 0) : + Ext X Y n := + R.extEquivCohomologyClass.symm + (.mk (Cocycle.fromSingleMk (f ≫ (R.cochainComplexXIso n n rfl).inv) (zero_add _) + m (by cutsat) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) + +end InjectiveResolution + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean b/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean index 7a12d7324cb1ce..6a54f3a4944e78 100644 --- a/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean +++ b/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean @@ -162,6 +162,14 @@ noncomputable def mk₀ [HasSmallLocalizedShiftedHom.{w} W M X Y] SmallShiftedHom.{w} W X Y m₀ := SmallShiftedHom.mk _ (ShiftedHom.mk₀ _ hm₀ f) +/-- The formal inverse in `SmallShiftedHom.{w} W Y X m₀` of a morphism `f : Y ⟶ X` +such that `W f`. -/ +noncomputable def mk₀Inv [HasSmallLocalizedShiftedHom.{w} W M Y X] [W.RespectsIso] + (m₀ : M) (hm₀ : m₀ = 0) (f : X ⟶ Y) (hf : W f) : + SmallShiftedHom.{w} W Y X m₀ := + SmallHom.mkInv ((shiftFunctorZero' C m₀ hm₀).hom.app X ≫ f) + (MorphismProperty.RespectsIso.precomp _ _ _ hf) + end section @@ -236,6 +244,17 @@ lemma equiv_mk₀ [HasSmallLocalizedShiftedHom.{w} W M X Y] simp only [comp_id, L.commShiftIso_zero, Functor.CommShift.isoZero_hom_app, assoc, ← Functor.map_comp_assoc, Iso.inv_hom_id_app, Functor.id_obj, Functor.map_id, id_comp] +@[simp] +lemma equiv_mk₀Inv [HasSmallLocalizedShiftedHom.{w} W M Y X] [W.RespectsIso] + (m₀ : M) (hm₀ : m₀ = 0) (f : X ⟶ Y) (hf : W f) : + equiv W L (mk₀Inv m₀ hm₀ f hf) = + ShiftedHom.mk₀ m₀ hm₀ ((isoOfHom L W f hf).inv) := by + have hf' : W ((shiftFunctorZero' C m₀ hm₀).hom.app X ≫ f) := + MorphismProperty.RespectsIso.precomp _ _ _ hf + refine (SmallHom.equiv_mkInv L _ hf' =≫ _).trans ?_ + rw [← cancel_epi (isoOfHom L W _ hf').hom, Iso.hom_inv_id_assoc] + simp [ShiftedHom.mk₀, Functor.commShiftIso_zero' _ _ m₀ hm₀] + end section @@ -257,6 +276,66 @@ lemma comp_assoc {X Y Z T : C} {a₁ a₂ a₃ a₁₂ a₂₃ a : M} end +variable {W} in +@[simp] +lemma mk₀_comp_mk₀Inv {X Y : C} [HasSmallLocalizedShiftedHom.{w} W M X Y] + [HasSmallLocalizedShiftedHom.{w} W M Y Y] + [HasSmallLocalizedShiftedHom.{w} W M Y X] [W.IsCompatibleWithShift M] [W.RespectsIso] + (m₀ : M) (hm₀ : m₀ = 0) (f : Y ⟶ X) (hf : W f) : + (mk₀ W m₀ hm₀ f).comp (mk₀Inv m₀ hm₀ f hf) (by subst hm₀; simp) = + mk₀ W m₀ hm₀ (𝟙 Y) := + (equiv W W.Q).injective (by simp [equiv_comp]) + +variable {W} in +@[simp] +lemma mk₀Inv_comp_mk₀ {X Y : C} [HasSmallLocalizedShiftedHom.{w} W M X Y] + [HasSmallLocalizedShiftedHom.{w} W M X X] + [HasSmallLocalizedShiftedHom.{w} W M Y X] [W.IsCompatibleWithShift M] [W.RespectsIso] + (m₀ : M) (hm₀ : m₀ = 0) (f : Y ⟶ X) (hf : W f) : + (mk₀Inv m₀ hm₀ f hf).comp (mk₀ W m₀ hm₀ f) (by subst hm₀; simp) = + mk₀ W m₀ hm₀ (𝟙 X) := + (equiv W W.Q).injective (by simp [equiv_comp]) + +variable {W} in +@[simp] +lemma comp_mk₀_id {X Y : C} [HasSmallLocalizedShiftedHom.{w} W M X Y] + [HasSmallLocalizedShiftedHom.{w} W M Y Y] + [W.IsCompatibleWithShift M] {m : M} + (α : SmallShiftedHom.{w} W X Y m) (m₀ : M) (hm₀ : m₀ = 0) : + α.comp (mk₀ W m₀ hm₀ (𝟙 Y)) (by aesop) = α := + (equiv W W.Q).injective (by simp [equiv_comp]) + +@[simp] +lemma mk₀_id_comp {X Y : C} [HasSmallLocalizedShiftedHom.{w} W M X Y] + [HasSmallLocalizedShiftedHom.{w} W M X X] + [HasSmallLocalizedShiftedHom.{w} W M Y Y] + [W.IsCompatibleWithShift M] {m : M} + (α : SmallShiftedHom.{w} W X Y m) (m₀ : M) (hm₀ : m₀ = 0) : + (mk₀ W m₀ hm₀ (𝟙 X)).comp α (by aesop) = α := + (equiv W W.Q).injective (by simp [equiv_comp]) + +variable {W} in +@[simps! -isSimp] +noncomputable def postcompEquiv {X Y Z : C} + [W.RespectsIso] [W.IsCompatibleWithShift M] [HasSmallLocalizedShiftedHom.{w} W M X Y] + [HasSmallLocalizedShiftedHom.{w} W M Y Z] + [HasSmallLocalizedShiftedHom.{w} W M X Z] + [HasSmallLocalizedShiftedHom.{w} W M Z Y] + [HasSmallLocalizedShiftedHom.{w} W M Y Y] + [HasSmallLocalizedShiftedHom.{w} W M Z Z] + (f : Y ⟶ Z) (hf : W f) {a : M} : + SmallShiftedHom.{w} W X Y a ≃ SmallShiftedHom.{w} W X Z a where + toFun α := α.comp (mk₀ _ _ rfl f) (zero_add _) + invFun β := β.comp (mk₀Inv _ rfl _ hf) (zero_add _) + left_inv α := by + dsimp + rw [comp_assoc _ _ _ _ _ (zero_add 0) (by simp)] + simp + right_inv β := by + dsimp + rw [comp_assoc _ _ _ _ _ (zero_add 0) (by simp)] + simp + section ChangeOfUniverse variable {W} From 106d01e9f9cd58272410fe5b965bedc22c12fba8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 17:39:03 +0100 Subject: [PATCH 24/60] wip --- Mathlib/Algebra/Homology/Embedding/IsSupported.lean | 11 ++++++++++- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 4 ---- Mathlib/CategoryTheory/Abelian/Injective/Extend.lean | 8 ++++++++ 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Homology/Embedding/IsSupported.lean b/Mathlib/Algebra/Homology/Embedding/IsSupported.lean index 9d0188d4e528c2..03549c8176113c 100644 --- a/Mathlib/Algebra/Homology/Embedding/IsSupported.lean +++ b/Mathlib/Algebra/Homology/Embedding/IsSupported.lean @@ -36,7 +36,7 @@ namespace HomologicalComplex section variable {C : Type*} [Category C] [HasZeroMorphisms C] - (K L : HomologicalComplex C c') (e' : K ≅ L) (e : c.Embedding c') + (K L : HomologicalComplex C c') (e' : K ≅ L) (φ : K ⟶ L) (e : c.Embedding c') /-- If `K : HomologicalComplex C c'`, then `K.IsStrictlySupported e` holds for an embedding `e : c.Embedding c'` of complex shapes if `K.X i'` is zero @@ -68,6 +68,7 @@ instance [K.IsStrictlySupported e] : K.op.IsStrictlySupported e.op := by /-- If `K : HomologicalComplex C c'`, then `K.IsStrictlySupported e` holds for an embedding `e : c.Embedding c'` of complex shapes if `K` is exact at `i'` whenever `i'` is not of the form `e.f i` for some `i`. -/ +@[mk_iff] class IsSupported : Prop where exactAt (i' : ι') (hi' : ∀ i, e.f i ≠ i') : K.ExactAt i' @@ -81,6 +82,14 @@ lemma isSupported_of_iso [K.IsSupported e] : L.IsSupported e where exactAt i' hi' := (K.exactAt_of_isSupported e i' hi').of_iso e' +variable {K L} in +lemma isSupported_iff_of_quasiIso [∀ i, K.HasHomology i] [∀ i, L.HasHomology i] + [QuasiIso φ] : + K.IsSupported e ↔ L.IsSupported e := by + simp only [isSupported_iff] + exact forall_congr' (fun i' ↦ forall_congr' + (fun hi' ↦ exactAt_iff_of_quasiIsoAt φ _)) + instance [K.IsStrictlySupported e] : K.IsSupported e where exactAt i' hi' := by rw [exactAt_iff] diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index cc0924106cbc0e..f6cf1635962cd5 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -43,10 +43,6 @@ instance : R.cochainComplex.IsKInjective := isKInjective_of_injective _ 0 instance (K L : CochainComplex C ℤ) [K.IsGE 0] [K.IsLE 0] [L.IsGE 0] [L.IsLE 0] : HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso _ _) ℤ K L := sorry -instance : R.cochainComplex.IsGE 0 := sorry - -instance : R.cochainComplex.IsLE 0 := sorry - noncomputable def extEquivCohomologyClass : Ext X Y n ≃ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := by have hι' : HomologicalComplex.quasiIso C (ComplexShape.up ℤ) R.ι' := by diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean index bac76d56a9ab2d..d4e5fdefb6ea12 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean @@ -40,6 +40,10 @@ obtained by extending by zero the `R.cocomplex`. -/ noncomputable def cochainComplex : CochainComplex C ℤ := R.cocomplex.extend ComplexShape.embeddingUpNat +instance : R.cochainComplex.IsStrictlyGE 0 := by + dsimp [cochainComplex] + infer_instance + /-- If `R : InjectiveResolution X`, then `R.cochainComplex.X n` (with `n : ℕ`) is isomorphic to `R.cocomplex.X k` (with `k : ℕ`) when `k = n`. -/ noncomputable def cochainComplexXIso (n : ℤ) (k : ℕ) (h : k = n) : @@ -82,6 +86,10 @@ variable [Abelian C] {X : C} (R : InjectiveResolution X) instance : QuasiIso R.ι' := by dsimp [ι']; infer_instance +instance : R.cochainComplex.IsLE 0 := by + simp only [← HomologicalComplex.isSupported_iff_of_quasiIso R.ι'] + infer_instance + end InjectiveResolution end CategoryTheory From 6ab1c63a772dd09a536bdf5bead7891516ffd8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 20:04:00 +0100 Subject: [PATCH 25/60] fix --- .../Homology/DerivedCategory/Basic.lean | 4 + .../Homology/DerivedCategory/Ext/Basic.lean | 38 ++++++++++ .../Homology/DerivedCategory/TStructure.lean | 7 ++ .../HomComplexCohomology.lean | 3 +- .../CategoryTheory/Abelian/Injective/Ext.lean | 74 ++++++++++++++++--- 5 files changed, 115 insertions(+), 11 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean index c88ea3b2873730..96ee4a8342499e 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Basic.lean @@ -255,4 +255,8 @@ lemma isIso_Q_map_iff_quasiIso {K L : CochainComplex C ℤ} (φ : K ⟶ L) : IsIso (Q.map φ) ↔ QuasiIso φ := by apply HomologicalComplexUpToQuasiIso.isIso_Q_map_iff_mem_quasiIso +lemma Q_map_eq_of_homotopy {K L : CochainComplex C ℤ} {f g : K ⟶ L} (h : Homotopy f g) : + DerivedCategory.Q.map f = DerivedCategory.Q.map g := + HomologicalComplexUpToQuasiIso.Q_map_eq_of_homotopy h + end DerivedCategory diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean index a19f6b17d45f5d..5ae570c57f249d 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean @@ -6,6 +6,7 @@ Authors: Joël Riou module public import Mathlib.Algebra.Homology.DerivedCategory.FullyFaithful +public import Mathlib.Algebra.Homology.DerivedCategory.TStructure public import Mathlib.CategoryTheory.Localization.SmallShiftedHom /-! @@ -93,6 +94,43 @@ lemma HasExt.standard : HasExt.{max u v} C := by letI := HasDerivedCategory.standard exact hasExt_of_hasDerivedCategory _ +instance [HasExt.{w} C] (X Y : C) (a b : ℤ) [HasDerivedCategory.{w'} C] : + Small.{w} ((singleFunctor C a).obj X ⟶ (singleFunctor C b).obj Y) := by + have (a b : ℤ) : + Small.{w} (((singleFunctor C 0).obj X)⟦a⟧ ⟶ ((singleFunctor C 0).obj Y)⟦b⟧) := + (hasSmallLocalizedShiftedHom_iff.{w} + (W := (HomologicalComplex.quasiIso C (ComplexShape.up ℤ))) (M := ℤ) + (X := (CochainComplex.singleFunctor C 0).obj X) + (Y := (CochainComplex.singleFunctor C 0).obj Y) Q).1 inferInstance a b + exact small_of_injective + (β := (((singleFunctor C 0).obj X)⟦-a⟧ ⟶ ((singleFunctor C 0).obj Y)⟦-b⟧)) + (f := fun φ ↦ + ((singleFunctors C).shiftIso (-a) a 0 (by simp)).hom.app X ≫ φ ≫ + ((singleFunctors C).shiftIso (-b) b 0 (by simp)).inv.app Y) + (fun φ₁ φ₂ h ↦ by simpa using h) + +variable {C} in +lemma HasExt.hasSmallLocalizedShiftedHom_of_isLE_of_isGE + [HasExt.{w} C] (K L : CochainComplex C ℤ) + (a b : ℤ) [K.IsGE a] [K.IsLE a] [L.IsGE b] [L.IsLE b] : + HasSmallLocalizedShiftedHom.{w} + (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ K L := by + letI := HasDerivedCategory.standard + obtain ⟨X, ⟨eX⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj K) a + obtain ⟨Y, ⟨eY⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj L) b + simp only [hasSmallLocalizedShiftedHom_iff _ _ Q] + exact fun p q ↦ small_of_injective (f := fun φ ↦ + ((singleFunctors C).shiftIso p (a - p) a (by simp)).inv.app X ≫ + eX.inv⟦p⟧' ≫ φ ≫ eY.hom⟦q⟧' ≫ + ((singleFunctors C).shiftIso q (b - q) b (by simp)).hom.app Y) + (fun φ₁ φ₂ h ↦ by simpa [cancel_epi, cancel_mono] using h) + +instance [HasExt.{w} C] (K L : CochainComplex C ℤ) + [K.IsGE 0] [K.IsLE 0] [L.IsGE 0] [L.IsLE 0] : + HasSmallLocalizedShiftedHom.{w} + (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ K L := + HasExt.hasSmallLocalizedShiftedHom_of_isLE_of_isGE _ _ 0 0 + variable {C} variable [HasExt.{w} C] diff --git a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean index c1719f649c77a3..9eb056fe69832c 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/TStructure.lean @@ -182,4 +182,11 @@ lemma exists_iso_Q_obj_of_isGE_of_isLE (X : DerivedCategory C) (a b : ℤ) [X.Is exact TStructure.t.isGE_of_iso e a exact ⟨K.truncGE a, inferInstance, inferInstance, ⟨e ≪≫ asIso (Q.map (K.πTruncGE a))⟩⟩ +lemma exists_iso_singleFunctor_obj_of_isGE_of_isLE + (X : DerivedCategory C) (n : ℤ) [X.IsGE n] [X.IsLE n] : + ∃ (Y : C), Nonempty (X ≅ (singleFunctor C n).obj Y) := by + obtain ⟨K, _, _, ⟨e⟩⟩ := exists_iso_Q_obj_of_isGE_of_isLE X n n + obtain ⟨Y, ⟨e'⟩⟩ := CochainComplex.exists_iso_single K n + exact ⟨Y, ⟨e ≪≫ Q.mapIso e'⟩⟩ + end DerivedCategory diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index 5fecaed4d392bb..2d7478dd89d8d9 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -144,6 +144,7 @@ lemma toHom_mk_eq_zero_iff (x : Cocycle K L n) : · rw [← mk_eq_zero_iff] at h rw [h, map_zero] +variable (K L n) in lemma toHom_bijective : Function.Bijective (toHom : CohomologyClass K L n → _) := by refine ⟨fun x y h ↦ ?_, fun f ↦ ?_⟩ · obtain ⟨x, rfl⟩ := x.mk_surjective @@ -158,7 +159,7 @@ lemma toHom_bijective : Function.Bijective (toHom : CohomologyClass K L n → _) noncomputable def homAddEquiv : CohomologyClass K L n ≃+ ((HomotopyCategory.quotient C _).obj K ⟶ (HomotopyCategory.quotient C _).obj (L⟦n⟧)) := - AddEquiv.ofBijective toHom toHom_bijective + AddEquiv.ofBijective toHom (toHom_bijective _ _ _) end CohomologyClass diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index f6cf1635962cd5..68f12a3bd94c78 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -6,6 +6,7 @@ Authors: Joël Riou module public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Basic +public import Mathlib.Algebra.Homology.DerivedCategory.KInjective public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexSingle public import Mathlib.Algebra.Homology.HomotopyCategory.KInjective @@ -22,12 +23,66 @@ universe w v u open CategoryTheory CochainComplex HomComplex Abelian Localization -def CochainComplex.HomComplex.equivOfIsKInjective - {C : Type u} [Category.{v} C] [Abelian C] - {K L : CochainComplex C ℤ} [L.IsKInjective] {n : ℤ} - [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] : +-- to be moved... +namespace CochainComplex.HomComplex + +variable {C : Type u} [Category.{v} C] [Abelian C] + {K L : CochainComplex C ℤ} {n : ℤ} + [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] + +namespace CohomologyClass + +/-- Given `x : CohomologyClass K L n`, this is the element in the type +`SmallShiftedHom` relatively to quasi-isomorphisms that is associated +to the `x`. -/ +noncomputable def toSmallShiftedHom (x : CohomologyClass K L n) : + SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := + Quotient.lift (fun y ↦ SmallShiftedHom.mk _ (Cocycle.equivHomShift.symm y)) (by + letI := HasDerivedCategory.standard C + intro y₁ y₂ h + refine (SmallShiftedHom.equiv _ DerivedCategory.Q).injective ?_ + simp only [SmallShiftedHom.equiv_mk, ShiftedHom.map] + rw [cancel_mono, DerivedCategory.Q_map_eq_of_homotopy] + apply HomotopyCategory.homotopyOfEq + rw [← toHom_mk, ← toHom_mk] + congr 1 + exact Quotient.sound h) x + +lemma toSmallShiftedHom_mk (x : Cocycle K L n) : + (mk x).toSmallShiftedHom = + SmallShiftedHom.mk _ (Cocycle.equivHomShift.symm x) := rfl + +@[simp] +lemma equiv_toSmallShiftedHom_mk [HasDerivedCategory C] (x : Cocycle K L n) : + SmallShiftedHom.equiv _ DerivedCategory.Q (mk x).toSmallShiftedHom = + ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q := by + simp [toSmallShiftedHom_mk] + +open DerivedCategory in +lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : + Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by + letI := HasDerivedCategory.standard C + rw [← Function.Bijective.of_comp_iff' + (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, + ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) + ((Q.commShiftIso n).symm.app L ≪≫ (quotientCompQhIso C).symm.app (L⟦n⟧))).bijective] + convert (CochainComplex.IsKInjective.Qh_map_bijective _ _).comp (toHom_bijective K L n) + ext x + obtain ⟨x, rfl⟩ := x.mk_surjective + simp [toHom_mk, ShiftedHom.map] + +/-- When `L` is a K-injective cochain complex, cohomology classes +in `CohomologyClass K L n` identify to elements in a type `SmallShiftedHom` relatively +to quasi-isomorphisms. -/ +@[simps! -isSimp] +noncomputable def equivOfIsKInjective [L.IsKInjective] : CohomologyClass K L n ≃ - SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ) ) K L n := sorry + SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := + Equiv.ofBijective _ bijective_toSmallShiftedHom_of_isKInjective + +end CohomologyClass + +end CochainComplex.HomComplex namespace CategoryTheory @@ -39,10 +94,9 @@ variable {X Y : C} (R : InjectiveResolution Y) {n : ℕ} instance : R.cochainComplex.IsKInjective := isKInjective_of_injective _ 0 --- should be generalized as a lemma -instance (K L : CochainComplex C ℤ) [K.IsGE 0] [K.IsLE 0] [L.IsGE 0] [L.IsLE 0] : - HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso _ _) ℤ K L := sorry - +/-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identify +to the type of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` +to `R.cochainComplex`. -/ noncomputable def extEquivCohomologyClass : Ext X Y n ≃ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := by have hι' : HomologicalComplex.quasiIso C (ComplexShape.up ℤ) R.ι' := by @@ -50,7 +104,7 @@ noncomputable def extEquivCohomologyClass : infer_instance exact (SmallShiftedHom.postcompEquiv.{w} R.ι' (by rw [HomologicalComplex.mem_quasiIso_iff]; infer_instance)).trans - CochainComplex.HomComplex.equivOfIsKInjective.{w}.symm + CochainComplex.HomComplex.CohomologyClass.equivOfIsKInjective.{w}.symm /-- Given an injective resolution `R` of an object `Y` of an abelian category, this is a constructor for elements in `Ext X Y n` which takes as an input From 47c840d02621f502a978c0ad1414d06e85939f09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 20:19:31 +0100 Subject: [PATCH 26/60] better syntax --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 68f12a3bd94c78..c654a1ae3b8f98 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -98,11 +98,8 @@ instance : R.cochainComplex.IsKInjective := isKInjective_of_injective _ 0 to the type of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` to `R.cochainComplex`. -/ noncomputable def extEquivCohomologyClass : - Ext X Y n ≃ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := by - have hι' : HomologicalComplex.quasiIso C (ComplexShape.up ℤ) R.ι' := by - simp only [HomologicalComplex.mem_quasiIso_iff] - infer_instance - exact (SmallShiftedHom.postcompEquiv.{w} R.ι' + Ext X Y n ≃ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := + (SmallShiftedHom.postcompEquiv.{w} R.ι' (by rw [HomologicalComplex.mem_quasiIso_iff]; infer_instance)).trans CochainComplex.HomComplex.CohomologyClass.equivOfIsKInjective.{w}.symm From d1bd720e3733b722f762077d5c372ba63eb8db01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 25 Nov 2025 23:08:37 +0100 Subject: [PATCH 27/60] wip --- .../Homology/HomotopyCategory/HomComplex.lean | 2 +- .../HomotopyCategory/HomComplexSingle.lean | 27 +++++++++++++++ .../CategoryTheory/Abelian/Injective/Ext.lean | 10 ++++++ .../Localization/SmallShiftedHom.lean | 33 +++++++++++++++++-- 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index 49e1c4e33609ae..4b2a8d89920eab 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -599,7 +599,7 @@ instance : Coe (Cocycle F G n) (Cochain F G n) where coe x := x.1 @[ext] -lemma ext (z₁ z₂ : Cocycle F G n) (h : (z₁ : Cochain F G n) = z₂) : z₁ = z₂ := +lemma ext {z₁ z₂ : Cocycle F G n} (h : (z₁ : Cochain F G n) = z₂) : z₁ = z₂ := Subtype.ext h instance : SMul R (Cocycle F G n) where diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean index c0d024cdd0ec3c..09ecb31f5a2467 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -68,6 +68,24 @@ lemma δ_fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) · simp [δ_shape n n' (by cutsat), HomologicalComplex.shape K q q' (by simp; cutsat), fromSingleMk] +/-- Cochains of degree `n` from `(singleFunctor C p).obj X` to `K` identify +to `X ⟶ K.X q` when `p + n = q`. -/ +noncomputable def fromSingleEquiv {p q n : ℤ} (h : p + n = q) : + Cochain ((singleFunctor C p).obj X) K n ≃ (X ⟶ K.X q) where + toFun α := (HomologicalComplex.singleObjXSelf (.up ℤ) p X).inv ≫ α.v p q h + invFun f := fromSingleMk f h + left_inv α := by + ext p' q' hpq' + by_cases hp : p' = p + · aesop + · exact (HomologicalComplex.isZero_single_obj_X _ _ _ _ hp).eq_of_src _ _ + right_inv f := by simp + +lemma fromSingleMk_surjective {p n : ℤ} (α : Cochain ((singleFunctor C p).obj X) K n) + (q : ℤ) (h : p + n = q) : + ∃ (f : X ⟶ K.X q), fromSingleMk f h = α := + (fromSingleEquiv h).symm.surjective α + /-- Constructor for cochains to a single complex. -/ @[nolint unusedArguments] noncomputable def toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (_ : p + n = q) : @@ -113,6 +131,15 @@ noncomputable def fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + rw [Cochain.δ_fromSingleMk _ _ _ q' (by cutsat), hf] simp) +lemma fromSingleMk_surjective {p n : ℤ} (α : Cocycle ((singleFunctor C p).obj X) K n) + (q : ℤ) (h : p + n = q) (q' : ℤ) (hq' : q + 1 = q') : + ∃ (f : X ⟶ K.X q) (hf : f ≫ K.d q q' = 0), fromSingleMk f h q' hq' hf = α := by + obtain ⟨f, hf⟩ := Cochain.fromSingleMk_surjective α.1 q h + have hα := α.δ_eq_zero (n + 1) + rw [← hf, Cochain.δ_fromSingleMk _ _ _ q' (by cutsat)] at hα + replace hα := Cochain.congr_v hα p q' (by cutsat) + exact ⟨f, by simpa using hα, by ext : 1; assumption⟩ + /-- Constructor for cocycles to a single complex. -/ @[simps!] noncomputable def toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index c654a1ae3b8f98..70ea87f8337060 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -113,6 +113,16 @@ noncomputable def extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n (.mk (Cocycle.fromSingleMk (f ≫ (R.cochainComplexXIso n n rfl).inv) (zero_add _) m (by cutsat) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) +lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : + ∃ (f : X ⟶ R.cocomplex.X n) (hf : f ≫ R.cocomplex.d n m = 0), + R.extMk f m hm hf = α := by + obtain ⟨x, rfl⟩ := R.extEquivCohomologyClass.symm.surjective α + obtain ⟨x, rfl⟩ := x.mk_surjective + obtain ⟨f, hf, rfl⟩ := Cocycle.fromSingleMk_surjective x n (by simp) m (by cutsat) + exact ⟨f ≫ (R.cochainComplexXIso n n rfl).hom, + by simpa [R.cochainComplex_d _ _ _ _ rfl rfl, + ← cancel_mono (R.cochainComplexXIso m m rfl).inv] using hf, by simp [extMk]⟩ + end InjectiveResolution end CategoryTheory diff --git a/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean b/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean index 6a54f3a4944e78..bd61aea5257923 100644 --- a/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean +++ b/Mathlib/CategoryTheory/Localization/SmallShiftedHom.lean @@ -315,9 +315,12 @@ lemma mk₀_id_comp {X Y : C} [HasSmallLocalizedShiftedHom.{w} W M X Y] (equiv W W.Q).injective (by simp [equiv_comp]) variable {W} in -@[simps! -isSimp] +/-- The postcomposition on the types `SmallShiftedHom W` with a morphism +which satisfies `W` is a bijection. -/ +@[simps!] noncomputable def postcompEquiv {X Y Z : C} - [W.RespectsIso] [W.IsCompatibleWithShift M] [HasSmallLocalizedShiftedHom.{w} W M X Y] + [W.RespectsIso] [W.IsCompatibleWithShift M] + [HasSmallLocalizedShiftedHom.{w} W M X Y] [HasSmallLocalizedShiftedHom.{w} W M Y Z] [HasSmallLocalizedShiftedHom.{w} W M X Z] [HasSmallLocalizedShiftedHom.{w} W M Z Y] @@ -336,6 +339,32 @@ noncomputable def postcompEquiv {X Y Z : C} rw [comp_assoc _ _ _ _ _ (zero_add 0) (by simp)] simp +variable {W} in +/-- The precomposition on the types `SmallShiftedHom W` with a morphism +which satisfies `W` is a bijection. -/ +@[simps!] +noncomputable def precompEquiv {X Y Z : C} + [W.RespectsIso] [W.IsCompatibleWithShift M] + [HasSmallLocalizedShiftedHom.{w} W M X X] + [HasSmallLocalizedShiftedHom.{w} W M Y Y] + [HasSmallLocalizedShiftedHom.{w} W M X Y] + [HasSmallLocalizedShiftedHom.{w} W M Y X] + [HasSmallLocalizedShiftedHom.{w} W M Y Z] + [HasSmallLocalizedShiftedHom.{w} W M X Z] + [HasSmallLocalizedShiftedHom.{w} W M Z Z] + (f : X ⟶ Y) (hf : W f) {a : M} : + SmallShiftedHom.{w} W Y Z a ≃ SmallShiftedHom.{w} W X Z a where + toFun α := (mk₀ _ _ rfl f).comp α (add_zero _) + invFun β := (mk₀Inv _ rfl _ hf).comp β (add_zero _) + left_inv α := by + dsimp + rw [← comp_assoc _ _ _ _ (add_zero 0) _ (by simp)] + simp + right_inv β := by + dsimp + rw [← comp_assoc _ _ _ _ (add_zero 0) _ (by simp)] + simp + section ChangeOfUniverse variable {W} From 1d605c4564cd614d37ea046432f828c17d588fa4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Wed, 26 Nov 2025 09:04:00 +0100 Subject: [PATCH 28/60] wip --- .../HomComplexCohomology.lean | 12 ++ .../HomotopyCategory/HomComplexSingle.lean | 71 ++++++++- .../CategoryTheory/Abelian/Injective/Ext.lean | 137 ++++++++++++++++++ 3 files changed, 212 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index 2d7478dd89d8d9..a9e279ee5bee6b 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -51,6 +51,18 @@ def coboundaries : AddSubgroup (Cocycle K L n) where rintro α ⟨m, hm, β, hβ⟩ exact ⟨m, hm, -β, by aesop⟩ +variable {K L n} in +lemma mem_coboundaries_iff (α : Cocycle K L n) (m : ℤ) (hm : m + 1 = n) : + α ∈ coboundaries K L n ↔ ∃ (β : Cochain K L m), δ m n β = α := by + simp only [coboundaries, exists_prop, AddSubgroup.mem_mk, AddSubmonoid.mem_mk, + AddSubsemigroup.mem_mk, Set.mem_setOf_eq] + constructor + · rintro ⟨m', hm', β, hβ⟩ + obtain rfl : m = m' := by cutsat + exact ⟨β, hβ⟩ + · rintro ⟨β, hβ⟩ + exact ⟨m, hm, β, hβ⟩ + /-- The type of cohomology classes of degree `n` in the complex of morphisms from `K` to `L`. -/ def CohomologyClass : Type v := Cocycle K L n ⧸ coboundaries K L n diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean index 09ecb31f5a2467..8455b7d680c6e7 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -5,7 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplex +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology public import Mathlib.Algebra.Homology.HomotopyCategory.SingleFunctors /-! @@ -41,12 +41,6 @@ noncomputable def fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (_ : p + Cochain ((singleFunctor C p).obj X) K n := Cochain.single ((HomologicalComplex.singleObjXSelf (.up ℤ) p X).hom ≫ f) n -variable (X K) in -@[simp] -lemma fromSingleMk_zero (p q n : ℤ) (h : p + n = q) : - fromSingleMk (X := X) (K := K) 0 h = 0 := by - simp [fromSingleMk] - @[simp] lemma fromSingleMk_v {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : (fromSingleMk f h).v p q h = @@ -71,7 +65,7 @@ lemma δ_fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) /-- Cochains of degree `n` from `(singleFunctor C p).obj X` to `K` identify to `X ⟶ K.X q` when `p + n = q`. -/ noncomputable def fromSingleEquiv {p q n : ℤ} (h : p + n = q) : - Cochain ((singleFunctor C p).obj X) K n ≃ (X ⟶ K.X q) where + Cochain ((singleFunctor C p).obj X) K n ≃+ (X ⟶ K.X q) where toFun α := (HomologicalComplex.singleObjXSelf (.up ℤ) p X).inv ≫ α.v p q h invFun f := fromSingleMk f h left_inv α := by @@ -80,6 +74,28 @@ noncomputable def fromSingleEquiv {p q n : ℤ} (h : p + n = q) : · aesop · exact (HomologicalComplex.isZero_single_obj_X _ _ _ _ hp).eq_of_src _ _ right_inv f := by simp + map_add' := by simp + +variable (X K) in +@[simp] +lemma fromSingleMk_zero (p q n : ℤ) (h : p + n = q) : + fromSingleMk (X := X) (K := K) 0 h = 0 := + (fromSingleEquiv h (X := X)).symm.map_zero + +@[simp] +lemma fromSingleMk_add {p q : ℤ} (f g : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : + fromSingleMk (f + g) h = fromSingleMk f h + fromSingleMk g h := + (fromSingleEquiv h).symm.map_add _ _ + +@[simp] +lemma fromSingleMk_sub {p q : ℤ} (f g : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : + fromSingleMk (f - g) h = fromSingleMk f h - fromSingleMk g h := + (fromSingleEquiv h).symm.map_sub _ _ + +@[simp] +lemma fromSingleMk_neg {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : + fromSingleMk (-f) h = -fromSingleMk f h := + (fromSingleEquiv h).symm.map_neg _ lemma fromSingleMk_surjective {p n : ℤ} (α : Cochain ((singleFunctor C p).obj X) K n) (q : ℤ) (h : p + n = q) : @@ -140,6 +156,45 @@ lemma fromSingleMk_surjective {p n : ℤ} (α : Cocycle ((singleFunctor C p).obj replace hα := Cochain.congr_v hα p q' (by cutsat) exact ⟨f, by simpa using hα, by ext : 1; assumption⟩ +lemma fromSingleMk_add {p q : ℤ} (f g : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (q' : ℤ) (hq' : q + 1 = q') (hf : f ≫ K.d q q' = 0) (hg : g ≫ K.d q q' = 0) : + fromSingleMk (f + g) h q' hq' (by simp [hf, hg]) = + fromSingleMk f h q' hq' hf + fromSingleMk g h q' hq' hg := by + cat_disch + +lemma fromSingleMk_sub {p q : ℤ} (f g : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (q' : ℤ) (hq' : q + 1 = q') (hf : f ≫ K.d q q' = 0) (hg : g ≫ K.d q q' = 0) : + fromSingleMk (f - g) h q' hq' (by simp [hf, hg]) = + fromSingleMk f h q' hq' hf - fromSingleMk g h q' hq' hg := by + cat_disch + +lemma fromSingleMk_neg {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (q' : ℤ) (hq' : q + 1 = q') (hf : f ≫ K.d q q' = 0) : + fromSingleMk (-f) h q' hq' (by simp [hf]) = - fromSingleMk f h q' hq' hf := by + cat_disch + +variable (X K) in +@[simp] +lemma fromSingleMk_zero {p q : ℤ} {n : ℤ} (h : p + n = q) + (q' : ℤ) (hq' : q + 1 = q') : + fromSingleMk (0 : X ⟶ K.X q) h q' hq' (by simp) = 0 := by + cat_disch + +lemma fromSingleMk_mem_coboundaries_iff {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (q' : ℤ) (hq' : q + 1 = q') (hf : f ≫ K.d q q' = 0) + (q'' : ℤ) (hq'' : q'' + 1 = q) : + fromSingleMk f h q' hq' hf ∈ coboundaries _ _ _ ↔ + ∃ (g : X ⟶ K.X q''), g ≫ K.d q'' q = f := by + rw [mem_coboundaries_iff _ (n -1) (by simp)] + constructor + · rintro ⟨α, hα⟩ + obtain ⟨g, hg⟩ := Cochain.fromSingleMk_surjective α q'' (by cutsat) + refine ⟨g, ?_⟩ + rw [← hg, fromSingleMk_coe, Cochain.δ_fromSingleMk _ _ _ _ h] at hα + exact (Cochain.fromSingleEquiv h).symm.injective hα + · rintro ⟨g, rfl⟩ + exact ⟨Cochain.fromSingleMk g (by cutsat), Cochain.δ_fromSingleMk _ _ _ _ h⟩ + /-- Constructor for cocycles to a single complex. -/ @[simps!] noncomputable def toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 70ea87f8337060..704401c441b1bf 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -103,6 +103,86 @@ noncomputable def extEquivCohomologyClass : (by rw [HomologicalComplex.mem_quasiIso_iff]; infer_instance)).trans CochainComplex.HomComplex.CohomologyClass.equivOfIsKInjective.{w}.symm +lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] + (x : Cocycle ((singleFunctor C 0).obj X) R.cochainComplex n) : + (R.extEquivCohomologyClass.symm (.mk x)).hom = + DerivedCategory.Q.map (Cocycle.equivHomShift.symm x) ≫ + inv (DerivedCategory.Q.map (R.ι'⟦(n : ℤ)⟧')) ≫ + (DerivedCategory.Q.commShiftIso (n : ℤ)).hom.app _ := by + simp [extEquivCohomologyClass, CohomologyClass.equivOfIsKInjective_apply, + Ext.hom, Ext.homEquiv] + erw [SmallShiftedHom.postcompEquiv_symm_apply, SmallShiftedHom.equiv_comp] + simp [ShiftedHom.map, ShiftedHom.comp, ShiftedHom.mk₀, shiftFunctorAdd'_zero_add_inv_app, + shiftFunctorZero'] + rw [← Functor.map_comp, Iso.inv_hom_id_app] + dsimp + rw [Functor.map_id, Category.comp_id] + congr 1 + simp [← Functor.map_comp] + +@[simp] +lemma extEquivCohomologyClass_symm_add + (x y : CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n) : + R.extEquivCohomologyClass.symm (x + y) = + R.extEquivCohomologyClass.symm x + R.extEquivCohomologyClass.symm y := by + have := HasDerivedCategory.standard C + obtain ⟨x, rfl⟩ := x.mk_surjective + obtain ⟨y, rfl⟩ := y.mk_surjective + ext + simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom] + +/-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identify +to the type of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` +to `R.cochainComplex`. -/ +noncomputable def extAddEquivCohomologyClass : + Ext X Y n ≃+ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := + AddEquiv.symm + { toEquiv := (R.extEquivCohomologyClass (X := X) (Y := Y) (n := n)).symm + map_add' := by simp } + +@[simp] +lemma extEquivCohomologyClass_symm_sub + (x y : CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n) : + R.extEquivCohomologyClass.symm (x - y) = + R.extEquivCohomologyClass.symm x - R.extEquivCohomologyClass.symm y := + R.extAddEquivCohomologyClass.symm.map_sub _ _ + +@[simp] +lemma extEquivCohomologyClass_symm_neg + (x : CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n) : + R.extEquivCohomologyClass.symm (-x) = + -R.extEquivCohomologyClass.symm x := + R.extAddEquivCohomologyClass.symm.map_neg _ + +@[simp] +lemma extEquivCohomologyClass_symm_zero : + (R.extEquivCohomologyClass (X := X) (n := n)).symm 0 = 0 := + R.extAddEquivCohomologyClass.symm.map_zero + +@[simp] +lemma extEquivCohomologyClass_add (x y : Ext X Y n) : + R.extEquivCohomologyClass (x + y) = + R.extEquivCohomologyClass x + R.extEquivCohomologyClass y := + R.extAddEquivCohomologyClass.map_add _ _ + +@[simp] +lemma extEquivCohomologyClass_sub (x y : Ext X Y n) : + R.extEquivCohomologyClass (x - y) = + R.extEquivCohomologyClass x - R.extEquivCohomologyClass y := + R.extAddEquivCohomologyClass.map_sub _ _ + +@[simp] +lemma extEquivCohomologyClass_neg (x : Ext X Y n) : + R.extEquivCohomologyClass (-x) = + -R.extEquivCohomologyClass x := + R.extAddEquivCohomologyClass.map_neg _ + +variable (X n) in +@[simp] +lemma extEquivCohomologyClass_zero : + R.extEquivCohomologyClass (0 : Ext X Y n) = 0 := + R.extAddEquivCohomologyClass.map_zero + /-- Given an injective resolution `R` of an object `Y` of an abelian category, this is a constructor for elements in `Ext X Y n` which takes as an input a "cocycle" `f : X ⟶ R.cocomplex.X n`. -/ @@ -113,6 +193,63 @@ noncomputable def extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n (.mk (Cocycle.fromSingleMk (f ≫ (R.cochainComplexXIso n n rfl).inv) (zero_add _) m (by cutsat) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) +@[simp] +lemma extEquivCohomologyClass_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) + (hf : f ≫ R.cocomplex.d n m = 0) : + R.extEquivCohomologyClass (R.extMk f m hm hf) = + (.mk (Cocycle.fromSingleMk (f ≫ (R.cochainComplexXIso n n rfl).inv) (zero_add _) + m (by cutsat) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) := by + simp [extMk] + +noncomputable def add_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) + (hf : f ≫ R.cocomplex.d n m = 0) (hg : g ≫ R.cocomplex.d n m = 0) : + R.extMk f m hm hf + R.extMk g m hm hg = + R.extMk (f + g) m hm (by simp [hf, hg]) := by + simp only [extMk, Preadditive.add_comp] + rw [Cocycle.fromSingleMk_add _ _ _ _ _ + (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]) + (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hg])] + simp + +noncomputable def sub_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) + (hf : f ≫ R.cocomplex.d n m = 0) (hg : g ≫ R.cocomplex.d n m = 0) : + R.extMk f m hm hf - R.extMk g m hm hg = + R.extMk (f - g) m hm (by simp [hf, hg]) := by + dsimp [extMk] + simp only [Preadditive.sub_comp] + rw [Cocycle.fromSingleMk_sub _ _ _ _ _ + (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]) + (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hg])] + simp + +noncomputable def neg_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) + (hf : f ≫ R.cocomplex.d n m = 0) : + -R.extMk f m hm hf = R.extMk (-f) m hm (by simp [hf]) := by + dsimp [extMk] + simp only [Preadditive.neg_comp] + rw [Cocycle.fromSingleMk_neg _ _ _ _ + (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf])] + simp + +@[simp] +noncomputable def extMk_zero {n : ℕ} (m : ℕ) (hm : n + 1 = m) : + R.extMk (0 : X ⟶ R.cocomplex.X n) m hm (by simp) = 0 := by + simp [extMk] + +lemma extMk_eq_zero_iff (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) + (hf : f ≫ R.cocomplex.d n m = 0) + (p : ℕ) (hp : p + 1 = n) : + R.extMk f m hm hf = 0 ↔ + ∃ (g : X ⟶ R.cocomplex.X p), g ≫ R.cocomplex.d p n = f := by + simp only [← R.extEquivCohomologyClass.apply_eq_iff_eq, + extEquivCohomologyClass_extMk, extEquivCohomologyClass_zero, + CohomologyClass.mk_eq_zero_iff] + rw [Cocycle.fromSingleMk_mem_coboundaries_iff _ _ _ _ _ p (by cutsat), + R.cochainComplex_d _ _ _ _ rfl rfl] + exact ⟨fun ⟨g, hg⟩ ↦ ⟨g ≫ (R.cochainComplexXIso p p rfl).hom, + by simp only [← cancel_mono (R.cochainComplexXIso n n rfl).inv, Category.assoc, hg]⟩, + fun ⟨g, hg⟩ ↦ ⟨g ≫ (R.cochainComplexXIso p p rfl).inv, by simp [← hg]⟩⟩ + lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : ∃ (f : X ⟶ R.cocomplex.X n) (hf : f ≫ R.cocomplex.d n m = 0), R.extMk f m hm hf = α := by From 0c47772a0705cbee85613c484ba6a40cbfe9636a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 27 Nov 2025 10:41:14 +0100 Subject: [PATCH 29/60] rephrasing --- .../HomotopyCategory/HomComplexCohomology.lean | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index b3dcea24b9cb53..d79d846fb912c0 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -15,10 +15,12 @@ public import Mathlib.Algebra.Homology.HomotopyCategory.Shift Given `ℤ`-indexed cochain complexes `K` and `L`, and `n : ℤ`, we introduce a type `HomComplex.CohomologyClass K L n` which is the quotient of `HomComplex.Cocycle K L n` which identifies cohomologous cocycles. -The reason for not applying the homology API to this complex is that -`Cochain K L` can be considered both as a complex of abelian groups -or as a complex of `R`-modules when the category is `R`-linear. - +We construct this type of cohomology classes instead of using +the homology API because `Cochain K L` can be considered both +as a complex of abelian groups or as a complex of `R`-modules +when the category is `R`-linear. This also complements the API +around `HomComplex` which is centered on terms in types +`Cochain` or `Cocycle` which are suitable for computations. -/ From 6da92ab550b855203a2882ef4c77b8f9307b340d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Thu, 27 Nov 2025 14:44:11 +0100 Subject: [PATCH 30/60] Apply suggestion from @joelriou --- .../Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean index c03e34cc448eea..2f62a8741cc1eb 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexCohomology.lean @@ -155,7 +155,7 @@ lemma toHom_bijective : Function.Bijective (toHom : CohomologyClass K L n → _) · obtain ⟨f, rfl⟩ := Functor.map_surjective _ f exact ⟨mk (Cocycle.equivHomShift f), by simp [toHom_mk]⟩ -/-- Cohomology classes identifies to morphisms in the homotopy category. -/ +/-- Cohomology classes identify to morphisms in the homotopy category. -/ @[simps! apply] noncomputable def homAddEquiv : CohomologyClass K L n ≃+ From 491c379303e2cad93f30f55b3d4503eb7311c375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 29 Nov 2025 11:21:09 +0100 Subject: [PATCH 31/60] equivHomShift' --- .../HomotopyCategory/HomComplexShift.lean | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean index 680c49ba89a23d..6ff5295e7cb139 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean @@ -551,9 +551,26 @@ def rightShiftAddEquiv (n a n' : ℤ) (hn' : n' + a = n) : /-- The additive equivalence `K ⟶ L⟦n⟧ ≃+ Cocycle K L n`. -/ @[simps! -isSimp apply symm_apply] -def equivHomShift : (K ⟶ L⟦n⟧) ≃+ Cocycle K L n := +def equivHomShift : + (K ⟶ L⟦n⟧) ≃+ Cocycle K L n := (equivHom _ _).trans (rightShiftAddEquiv _ _ _ (zero_add n)).symm +/-- The additive equivalence `Cocycle K L n ≃+ Cocycle K⟦a⟧ L n'` when `n + a = n'`. -/ +@[simps] +def leftShiftAddEquiv (n a n' : ℤ) (hn' : n + a = n') : + Cocycle K L n ≃+ Cocycle (K⟦a⟧) L n' where + toFun γ := γ.leftShift a n' hn' + invFun γ := γ.leftUnshift n hn' + left_inv γ := by cat_disch + right_inv γ := by cat_disch + map_add' γ γ' := by cat_disch + +/-- The additive equivalence `(K⟦n⟧) ⟶ L ≃+ Cocycle K L m` when `m + n = 0`. -/ +@[simps! -isSimp apply symm_apply] +def equivHomShift' (n m : ℤ) (h : m + n = 0) : + ((K⟦n⟧) ⟶ L) ≃+ Cocycle K L m := + (equivHom _ _).trans (leftShiftAddEquiv _ _ _ h).symm + end Cocycle end CochainComplex.HomComplex From 269e1ecee33070aad8fe86b209e106012127d0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 18:27:30 +0100 Subject: [PATCH 32/60] fix --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 704401c441b1bf..18118e9ccf9bd6 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -201,7 +201,7 @@ lemma extEquivCohomologyClass_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : m (by cutsat) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) := by simp [extMk] -noncomputable def add_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) +lemma add_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) (hf : f ≫ R.cocomplex.d n m = 0) (hg : g ≫ R.cocomplex.d n m = 0) : R.extMk f m hm hf + R.extMk g m hm hg = R.extMk (f + g) m hm (by simp [hf, hg]) := by @@ -211,7 +211,7 @@ noncomputable def add_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (h (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hg])] simp -noncomputable def sub_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) +lemma sub_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) (hf : f ≫ R.cocomplex.d n m = 0) (hg : g ≫ R.cocomplex.d n m = 0) : R.extMk f m hm hf - R.extMk g m hm hg = R.extMk (f - g) m hm (by simp [hf, hg]) := by @@ -222,7 +222,7 @@ noncomputable def sub_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (h (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hg])] simp -noncomputable def neg_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) +lemma neg_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) (hf : f ≫ R.cocomplex.d n m = 0) : -R.extMk f m hm hf = R.extMk (-f) m hm (by simp [hf]) := by dsimp [extMk] @@ -232,7 +232,7 @@ noncomputable def neg_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm simp @[simp] -noncomputable def extMk_zero {n : ℕ} (m : ℕ) (hm : n + 1 = m) : +lemma extMk_zero {n : ℕ} (m : ℕ) (hm : n + 1 = m) : R.extMk (0 : X ⟶ R.cocomplex.X n) m hm (by simp) = 0 := by simp [extMk] From 72943d4d74dbb49bc2d2ea583170190d4e0a2dc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 18:29:46 +0100 Subject: [PATCH 33/60] fix --- .../Homology/HomotopyCategory/HomComplexSingle.lean | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean index 8455b7d680c6e7..d0184364ab7223 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -41,6 +41,12 @@ noncomputable def fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (_ : p + Cochain ((singleFunctor C p).obj X) K n := Cochain.single ((HomologicalComplex.singleObjXSelf (.up ℤ) p X).hom ≫ f) n +variable (X K) in +@[simp] +lemma fromSingleMk_zero (p q n : ℤ) (h : p + n = q) : + fromSingleMk (X := X) (K := K) 0 h = 0 := by + simp [fromSingleMk] + @[simp] lemma fromSingleMk_v {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : (fromSingleMk f h).v p q h = @@ -76,12 +82,6 @@ noncomputable def fromSingleEquiv {p q n : ℤ} (h : p + n = q) : right_inv f := by simp map_add' := by simp -variable (X K) in -@[simp] -lemma fromSingleMk_zero (p q n : ℤ) (h : p + n = q) : - fromSingleMk (X := X) (K := K) 0 h = 0 := - (fromSingleEquiv h (X := X)).symm.map_zero - @[simp] lemma fromSingleMk_add {p q : ℤ} (f g : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : fromSingleMk (f + g) h = fromSingleMk f h + fromSingleMk g h := From 03dcbd86e79082439bd1295200a099ce9c392bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 19:36:58 +0100 Subject: [PATCH 34/60] wip --- Mathlib.lean | 1 + .../Homology/DerivedCategory/Ext/Basic.lean | 23 -------- .../DerivedCategory/Ext/TStructure.lean | 54 +++++++++++++++++++ .../CategoryTheory/Abelian/Injective/Ext.lean | 2 +- 4 files changed, 56 insertions(+), 24 deletions(-) create mode 100644 Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7a125653c4eda0..524720e85b4efc 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -545,6 +545,7 @@ public import Mathlib.Algebra.Homology.DerivedCategory.Ext.EnoughProjectives public import Mathlib.Algebra.Homology.DerivedCategory.Ext.ExactSequences public import Mathlib.Algebra.Homology.DerivedCategory.Ext.ExtClass public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Linear +public import Mathlib.Algebra.Homology.DerivedCategory.Ext.TStructure public import Mathlib.Algebra.Homology.DerivedCategory.Fractions public import Mathlib.Algebra.Homology.DerivedCategory.FullyFaithful public import Mathlib.Algebra.Homology.DerivedCategory.HomologySequence diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean index 9831571d0b40df..e944776336a454 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean @@ -6,7 +6,6 @@ Authors: Joël Riou module public import Mathlib.Algebra.Homology.DerivedCategory.FullyFaithful -public import Mathlib.Algebra.Homology.DerivedCategory.TStructure public import Mathlib.CategoryTheory.Localization.SmallShiftedHom /-! @@ -109,28 +108,6 @@ instance [HasExt.{w} C] (X Y : C) (a b : ℤ) [HasDerivedCategory.{w'} C] : ((singleFunctors C).shiftIso (-b) b 0 (by simp)).inv.app Y) (fun φ₁ φ₂ h ↦ by simpa using h) -variable {C} in -lemma HasExt.hasSmallLocalizedShiftedHom_of_isLE_of_isGE - [HasExt.{w} C] (K L : CochainComplex C ℤ) - (a b : ℤ) [K.IsGE a] [K.IsLE a] [L.IsGE b] [L.IsLE b] : - HasSmallLocalizedShiftedHom.{w} - (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ K L := by - letI := HasDerivedCategory.standard - obtain ⟨X, ⟨eX⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj K) a - obtain ⟨Y, ⟨eY⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj L) b - simp only [hasSmallLocalizedShiftedHom_iff _ _ Q] - exact fun p q ↦ small_of_injective (f := fun φ ↦ - ((singleFunctors C).shiftIso p (a - p) a (by simp)).inv.app X ≫ - eX.inv⟦p⟧' ≫ φ ≫ eY.hom⟦q⟧' ≫ - ((singleFunctors C).shiftIso q (b - q) b (by simp)).hom.app Y) - (fun φ₁ φ₂ h ↦ by simpa [cancel_epi, cancel_mono] using h) - -instance [HasExt.{w} C] (K L : CochainComplex C ℤ) - [K.IsGE 0] [K.IsLE 0] [L.IsGE 0] [L.IsLE 0] : - HasSmallLocalizedShiftedHom.{w} - (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ K L := - HasExt.hasSmallLocalizedShiftedHom_of_isLE_of_isGE _ _ 0 0 - variable {C} variable [HasExt.{w} C] diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean new file mode 100644 index 00000000000000..1f5a28c5ac5580 --- /dev/null +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean @@ -0,0 +1,54 @@ +/- +Copyright (c) 2024 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Basic +public import Mathlib.Algebra.Homology.DerivedCategory.TStructure + +/-! +# Morphisms between bounded objects are small + +-/ + +@[expose] public section + +assert_not_exists TwoSidedIdeal + +universe w'' w' w v u + +namespace CategoryTheory + +variable (C : Type u) [Category.{v} C] [Abelian C] + +open Localization Limits ZeroObject DerivedCategory Pretriangulated + +namespace HasExt + +variable {C} in +lemma hasSmallLocalizedShiftedHom_of_isLE_of_isGE + [HasExt.{w} C] (K L : CochainComplex C ℤ) + (a b : ℤ) [K.IsGE a] [K.IsLE a] [L.IsGE b] [L.IsLE b] : + HasSmallLocalizedShiftedHom.{w} + (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ K L := by + letI := HasDerivedCategory.standard + obtain ⟨X, ⟨eX⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj K) a + obtain ⟨Y, ⟨eY⟩⟩ := DerivedCategory.exists_iso_singleFunctor_obj_of_isGE_of_isLE (Q.obj L) b + simp only [hasSmallLocalizedShiftedHom_iff _ _ Q] + exact fun p q ↦ small_of_injective (f := fun φ ↦ + ((singleFunctors C).shiftIso p (a - p) a (by simp)).inv.app X ≫ + eX.inv⟦p⟧' ≫ φ ≫ eY.hom⟦q⟧' ≫ + ((singleFunctors C).shiftIso q (b - q) b (by simp)).hom.app Y) + (fun φ₁ φ₂ h ↦ by simpa [cancel_epi, cancel_mono] using h) + +instance [HasExt.{w} C] (K L : CochainComplex C ℤ) + [K.IsGE 0] [K.IsLE 0] [L.IsGE 0] [L.IsLE 0] : + HasSmallLocalizedShiftedHom.{w} + (HomologicalComplex.quasiIso C (ComplexShape.up ℤ)) ℤ K L := + HasExt.hasSmallLocalizedShiftedHom_of_isLE_of_isGE _ _ 0 0 + +end HasExt + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 18118e9ccf9bd6..11023406d88a57 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -5,7 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Basic +public import Mathlib.Algebra.Homology.DerivedCategory.Ext.TStructure public import Mathlib.Algebra.Homology.DerivedCategory.KInjective public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexSingle From dc97b3b100c5bd9b4fafc690336a46f989c8c580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 19:48:53 +0100 Subject: [PATCH 35/60] wip --- .../Homology/DerivedCategory/Ext/TStructure.lean | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean index 1f5a28c5ac5580..40d9dfd6c1398e 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean @@ -9,7 +9,17 @@ public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Basic public import Mathlib.Algebra.Homology.DerivedCategory.TStructure /-! -# Morphisms between bounded objects are small +# Morphisms between bounded complexes are small + +Let `C` be an abelian category. Assuming `HasExt.{w} C`, we show that +if two cochain complexes `K` and `L` are cohomologically in a single degree, +then the type of morphisms from `K` to `L⟦n⟧` in the derived category if `w`-small +for any `n : ℤ`, which we phrase here by saying that +`HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso _ _) ℤ K L` hold. + +## TODO +* When more definitions are introduced for t-structures (e.g. the heart), +show that the conclusion hold when `K` and `L` are cohomologically bounded. -/ @@ -17,7 +27,7 @@ public import Mathlib.Algebra.Homology.DerivedCategory.TStructure assert_not_exists TwoSidedIdeal -universe w'' w' w v u +universe w v u namespace CategoryTheory From c30dd40320560e7317028207dddd950ca04185e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 19:51:46 +0100 Subject: [PATCH 36/60] fix --- Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean index e944776336a454..e661e5086387ed 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/Basic.lean @@ -102,7 +102,7 @@ instance [HasExt.{w} C] (X Y : C) (a b : ℤ) [HasDerivedCategory.{w'} C] : (X := (CochainComplex.singleFunctor C 0).obj X) (Y := (CochainComplex.singleFunctor C 0).obj Y) Q).1 inferInstance a b exact small_of_injective - (β := (((singleFunctor C 0).obj X)⟦-a⟧ ⟶ ((singleFunctor C 0).obj Y)⟦-b⟧)) + (β := ((singleFunctor C 0).obj X)⟦-a⟧ ⟶ ((singleFunctor C 0).obj Y)⟦-b⟧) (f := fun φ ↦ ((singleFunctors C).shiftIso (-a) a 0 (by simp)).hom.app X ≫ φ ≫ ((singleFunctors C).shiftIso (-b) b 0 (by simp)).inv.app Y) From 06212aa5529a0393bbeb8eb5eb781c14349e46ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 20:00:24 +0100 Subject: [PATCH 37/60] wip --- Mathlib.lean | 1 + .../DerivedCategory/Ext/TStructure.lean | 2 +- .../Homology/DerivedCategory/KInjective.lean | 2 +- .../DerivedCategory/SmallShiftedHom.lean | 61 +++++++++++++++++++ .../CategoryTheory/Abelian/Injective/Ext.lean | 26 -------- 5 files changed, 64 insertions(+), 28 deletions(-) create mode 100644 Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean diff --git a/Mathlib.lean b/Mathlib.lean index 524720e85b4efc..34f4e2176210ae 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -553,6 +553,7 @@ public import Mathlib.Algebra.Homology.DerivedCategory.KInjective public import Mathlib.Algebra.Homology.DerivedCategory.Linear public import Mathlib.Algebra.Homology.DerivedCategory.ShortExact public import Mathlib.Algebra.Homology.DerivedCategory.SingleTriangle +public import Mathlib.Algebra.Homology.DerivedCategory.SmallShiftedHom public import Mathlib.Algebra.Homology.DerivedCategory.TStructure public import Mathlib.Algebra.Homology.DifferentialObject public import Mathlib.Algebra.Homology.Double diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean index 40d9dfd6c1398e..89039b7beb3eb2 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2025 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean index 1bf68129bb960c..a94c59f125e2a1 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -5,7 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.DerivedCategory.Basic +public import Mathlib.Algebra.Homology.DerivedCategory.SmallShiftedHom public import Mathlib.Algebra.Homology.HomotopyCategory.KInjective /-! diff --git a/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean b/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean new file mode 100644 index 00000000000000..598721afd9ae1e --- /dev/null +++ b/Mathlib/Algebra/Homology/DerivedCategory/SmallShiftedHom.lean @@ -0,0 +1,61 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.DerivedCategory.Ext.Basic +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology + +/-! +# Cohomology of `HomComplex` and morphisms in the derived category + +Let `K` and `L` be two cochain complexes in an abelian category `C`. +Given a class `x : HomComplex.CohomologyClass K L n`, we construct an +element in the type +`SmallShiftedHom (HomologicalComplex.quasiIso C (.up ℤ)) K L n`, and +compute its image as a morphism `Q.obj K ⟶ (Q.obj L)⟦n⟧` in the +derived category when `x` is given as the class of a cocycle. + +-/ + +@[expose] public section + +universe w v u + +open CategoryTheory Localization + +namespace CochainComplex.HomComplex.CohomologyClass + +variable {C : Type u} [Category.{v} C] [Abelian C] + {K L : CochainComplex C ℤ} {n : ℤ} + [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] + +/-- Given `x : CohomologyClass K L n`, this is the element in the type +`SmallShiftedHom` relatively to quasi-isomorphisms that is associated +to the `x`. -/ +noncomputable def toSmallShiftedHom (x : CohomologyClass K L n) : + SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := + Quotient.lift (fun y ↦ SmallShiftedHom.mk _ (Cocycle.equivHomShift.symm y)) (by + letI := HasDerivedCategory.standard C + intro y₁ y₂ h + refine (SmallShiftedHom.equiv _ DerivedCategory.Q).injective ?_ + simp only [SmallShiftedHom.equiv_mk, ShiftedHom.map] + rw [cancel_mono, DerivedCategory.Q_map_eq_of_homotopy] + apply HomotopyCategory.homotopyOfEq + rw [← toHom_mk, ← toHom_mk] + congr 1 + exact Quotient.sound h) x + +lemma toSmallShiftedHom_mk (x : Cocycle K L n) : + (mk x).toSmallShiftedHom = + SmallShiftedHom.mk _ (Cocycle.equivHomShift.symm x) := rfl + +@[simp] +lemma equiv_toSmallShiftedHom_mk [HasDerivedCategory C] (x : Cocycle K L n) : + SmallShiftedHom.equiv _ DerivedCategory.Q (mk x).toSmallShiftedHom = + ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q := by + simp [toSmallShiftedHom_mk] + +end CochainComplex.HomComplex.CohomologyClass diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 11023406d88a57..3aeede55b6733d 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -32,32 +32,6 @@ variable {C : Type u} [Category.{v} C] [Abelian C] namespace CohomologyClass -/-- Given `x : CohomologyClass K L n`, this is the element in the type -`SmallShiftedHom` relatively to quasi-isomorphisms that is associated -to the `x`. -/ -noncomputable def toSmallShiftedHom (x : CohomologyClass K L n) : - SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := - Quotient.lift (fun y ↦ SmallShiftedHom.mk _ (Cocycle.equivHomShift.symm y)) (by - letI := HasDerivedCategory.standard C - intro y₁ y₂ h - refine (SmallShiftedHom.equiv _ DerivedCategory.Q).injective ?_ - simp only [SmallShiftedHom.equiv_mk, ShiftedHom.map] - rw [cancel_mono, DerivedCategory.Q_map_eq_of_homotopy] - apply HomotopyCategory.homotopyOfEq - rw [← toHom_mk, ← toHom_mk] - congr 1 - exact Quotient.sound h) x - -lemma toSmallShiftedHom_mk (x : Cocycle K L n) : - (mk x).toSmallShiftedHom = - SmallShiftedHom.mk _ (Cocycle.equivHomShift.symm x) := rfl - -@[simp] -lemma equiv_toSmallShiftedHom_mk [HasDerivedCategory C] (x : Cocycle K L n) : - SmallShiftedHom.equiv _ DerivedCategory.Q (mk x).toSmallShiftedHom = - ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q := by - simp [toSmallShiftedHom_mk] - open DerivedCategory in lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by From ff8530a972dbeea1e9393348923c3464704844c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 20:09:36 +0100 Subject: [PATCH 38/60] added TODO --- .../Homology/DerivedCategory/KInjective.lean | 37 +++++++++++- .../CategoryTheory/Abelian/Injective/Ext.lean | 58 +++++-------------- 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean index a94c59f125e2a1..8aa637d3e67844 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -27,9 +27,44 @@ open CategoryTheory variable {C : Type u} [Category.{v} C] [Abelian C] -lemma CochainComplex.IsKInjective.Qh_map_bijective [HasDerivedCategory C] +open CategoryTheory Localization DerivedCategory + +namespace CochainComplex + +lemma IsKInjective.Qh_map_bijective [HasDerivedCategory C] (K : HomotopyCategory C (ComplexShape.up ℤ)) (L : CochainComplex C ℤ) [L.IsKInjective] : Function.Bijective (DerivedCategory.Qh.map : (K ⟶ (HomotopyCategory.quotient _ _).obj L) → _ ) := (CochainComplex.IsKInjective.rightOrthogonal L).map_bijective_of_isTriangulated _ _ + +namespace HomComplex.CohomologyClass + +variable (K L : CochainComplex C ℤ) (n : ℤ) + [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] + +lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : + Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by + letI := HasDerivedCategory.standard C + rw [← Function.Bijective.of_comp_iff' + (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, + ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) + ((Q.commShiftIso n).symm.app L ≪≫ (quotientCompQhIso C).symm.app (L⟦n⟧))).bijective] + convert (CochainComplex.IsKInjective.Qh_map_bijective _ _).comp (toHom_bijective K L n) + ext x + obtain ⟨x, rfl⟩ := x.mk_surjective + simp [toHom_mk, ShiftedHom.map] + +variable {K L n} in +/-- When `L` is a K-injective cochain complex, cohomology classes +in `CohomologyClass K L n` identify to elements in a type `SmallShiftedHom` relatively +to quasi-isomorphisms. -/ +@[simps! -isSimp] +noncomputable def equivOfIsKInjective [L.IsKInjective] : + CohomologyClass K L n ≃ + SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := + Equiv.ofBijective _ (bijective_toSmallShiftedHom_of_isKInjective _ _ _) + +end HomComplex.CohomologyClass + +end CochainComplex diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 3aeede55b6733d..e83695cca826de 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -15,6 +15,18 @@ public import Mathlib.CategoryTheory.Abelian.Injective.Extend /-! # Computing `Ext` using an injective resolution +Given an injective resolution `R` of an object `Y` in an abelian category `C`, +we provide an API in order to construct elements in `Ext X Y n` in terms +of the complex `R.cocomplex` and to make computation in the `Ext`-group. + +## TODO +* Functoriality in `X` for a given injective resolution `R` +* Functoriality in `Y`: this would involve a morphism `Y ⟶ Y'`, injective +resolutions `R` and `R'` of `Y` and `Y'`, a lift of `Y ⟶ Y'` as a morphism +of cochain complexes `R.cocomplex ⟶ R'.cocomplex`; in this context, +we should be able to compute the postcomposition of an element +`R.extMk f m hm hf : Ext X Y n` by `Y ⟶ Y'`. + -/ @[expose] public section @@ -23,48 +35,10 @@ universe w v u open CategoryTheory CochainComplex HomComplex Abelian Localization --- to be moved... -namespace CochainComplex.HomComplex - -variable {C : Type u} [Category.{v} C] [Abelian C] - {K L : CochainComplex C ℤ} {n : ℤ} - [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] - -namespace CohomologyClass - -open DerivedCategory in -lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : - Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by - letI := HasDerivedCategory.standard C - rw [← Function.Bijective.of_comp_iff' - (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, - ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) - ((Q.commShiftIso n).symm.app L ≪≫ (quotientCompQhIso C).symm.app (L⟦n⟧))).bijective] - convert (CochainComplex.IsKInjective.Qh_map_bijective _ _).comp (toHom_bijective K L n) - ext x - obtain ⟨x, rfl⟩ := x.mk_surjective - simp [toHom_mk, ShiftedHom.map] - -/-- When `L` is a K-injective cochain complex, cohomology classes -in `CohomologyClass K L n` identify to elements in a type `SmallShiftedHom` relatively -to quasi-isomorphisms. -/ -@[simps! -isSimp] -noncomputable def equivOfIsKInjective [L.IsKInjective] : - CohomologyClass K L n ≃ - SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := - Equiv.ofBijective _ bijective_toSmallShiftedHom_of_isKInjective - -end CohomologyClass - -end CochainComplex.HomComplex - -namespace CategoryTheory +namespace CategoryTheory.InjectiveResolution variable {C : Type u} [Category.{v} C] [Abelian C] [HasExt.{w} C] - -namespace InjectiveResolution - -variable {X Y : C} (R : InjectiveResolution Y) {n : ℕ} + {X Y : C} (R : InjectiveResolution Y) {n : ℕ} instance : R.cochainComplex.IsKInjective := isKInjective_of_injective _ 0 @@ -234,6 +208,4 @@ lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : by simpa [R.cochainComplex_d _ _ _ _ rfl rfl, ← cancel_mono (R.cochainComplexXIso m m rfl).inv] using hf, by simp [extMk]⟩ -end InjectiveResolution - -end CategoryTheory +end CategoryTheory.InjectiveResolution From af0c548ee412ed3e342a8b8a66d7f5b837829c67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 20:09:54 +0100 Subject: [PATCH 39/60] typo --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index e83695cca826de..1e447b007971df 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -17,7 +17,7 @@ public import Mathlib.CategoryTheory.Abelian.Injective.Extend Given an injective resolution `R` of an object `Y` in an abelian category `C`, we provide an API in order to construct elements in `Ext X Y n` in terms -of the complex `R.cocomplex` and to make computation in the `Ext`-group. +of the complex `R.cocomplex` and to make computations in the `Ext`-group. ## TODO * Functoriality in `X` for a given injective resolution `R` From bd58ec546d23dbc7a28eb93bbc882052281c333e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 20:10:40 +0100 Subject: [PATCH 40/60] typo --- Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean index 89039b7beb3eb2..08871e21f3462d 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean @@ -13,7 +13,7 @@ public import Mathlib.Algebra.Homology.DerivedCategory.TStructure Let `C` be an abelian category. Assuming `HasExt.{w} C`, we show that if two cochain complexes `K` and `L` are cohomologically in a single degree, -then the type of morphisms from `K` to `L⟦n⟧` in the derived category if `w`-small +then the type of morphisms from `K` to `L⟦n⟧` in the derived category is `w`-small for any `n : ℤ`, which we phrase here by saying that `HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso _ _) ℤ K L` hold. From c9b75c9ee0e834c9c89b570979a6456f3c7ada17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 4 Dec 2025 20:11:02 +0100 Subject: [PATCH 41/60] typo --- Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean index 08871e21f3462d..8d793cf53be2db 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/Ext/TStructure.lean @@ -19,7 +19,7 @@ for any `n : ℤ`, which we phrase here by saying that ## TODO * When more definitions are introduced for t-structures (e.g. the heart), -show that the conclusion hold when `K` and `L` are cohomologically bounded. +show that the conclusion holds when `K` and `L` are cohomologically bounded. -/ From 2eebe2aa223d1262dd30f63eb2a630f70242b659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 12 Dec 2025 20:45:50 +0100 Subject: [PATCH 42/60] whitespace --- Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean index 8aa637d3e67844..02e45c2c0db6ef 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -47,7 +47,7 @@ lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by letI := HasDerivedCategory.standard C rw [← Function.Bijective.of_comp_iff' - (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, + (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) ((Q.commShiftIso n).symm.app L ≪≫ (quotientCompQhIso C).symm.app (L⟦n⟧))).bijective] convert (CochainComplex.IsKInjective.Qh_map_bijective _ _).comp (toHom_bijective K L n) From 2185be829b772364646a370adee928e467e90c3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 12 Dec 2025 20:48:27 +0100 Subject: [PATCH 43/60] s/cutsat/lia/g --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 341c7aaf48a41c..0c2214b96c4086 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -141,14 +141,14 @@ noncomputable def extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n Ext X Y n := R.extEquivCohomologyClass.symm (.mk (Cocycle.fromSingleMk (f ≫ (R.cochainComplexXIso n n rfl).inv) (zero_add _) - m (by cutsat) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) + m (by lia) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) @[simp] lemma extEquivCohomologyClass_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) (hf : f ≫ R.cocomplex.d n m = 0) : R.extEquivCohomologyClass (R.extMk f m hm hf) = (.mk (Cocycle.fromSingleMk (f ≫ (R.cochainComplexXIso n n rfl).inv) (zero_add _) - m (by cutsat) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) := by + m (by lia) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]))) := by simp [extMk] lemma add_extMk {n : ℕ} (f g : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) @@ -194,7 +194,7 @@ lemma extMk_eq_zero_iff (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) simp only [← R.extEquivCohomologyClass.apply_eq_iff_eq, extEquivCohomologyClass_extMk, extEquivCohomologyClass_zero, CohomologyClass.mk_eq_zero_iff] - rw [Cocycle.fromSingleMk_mem_coboundaries_iff _ _ _ _ _ p (by cutsat), + rw [Cocycle.fromSingleMk_mem_coboundaries_iff _ _ _ _ _ p (by lia), R.cochainComplex_d _ _ _ _ rfl rfl] exact ⟨fun ⟨g, hg⟩ ↦ ⟨g ≫ (R.cochainComplexXIso p p rfl).hom, by simp only [← cancel_mono (R.cochainComplexXIso n n rfl).inv, Category.assoc, hg]⟩, @@ -205,7 +205,7 @@ lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : R.extMk f m hm hf = α := by obtain ⟨x, rfl⟩ := R.extEquivCohomologyClass.symm.surjective α obtain ⟨x, rfl⟩ := x.mk_surjective - obtain ⟨f, hf, rfl⟩ := Cocycle.fromSingleMk_surjective x n (by simp) m (by cutsat) + obtain ⟨f, hf, rfl⟩ := Cocycle.fromSingleMk_surjective x n (by simp) m (by lia) exact ⟨f ≫ (R.cochainComplexXIso n n rfl).hom, by simpa [R.cochainComplex_d _ _ _ _ rfl rfl, ← cancel_mono (R.cochainComplexXIso m m rfl).inv] using hf, by simp [extMk]⟩ From 070a4ab775c0ed1522f6c3ecfa8dda3db04bd643 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 12 Dec 2025 22:25:00 +0100 Subject: [PATCH 44/60] feat(Algebra/Homology): equivOfIsKInjective --- .../Homology/DerivedCategory/KInjective.lean | 39 ++++++++++++++++++- .../Homology/DerivedCategory/KProjective.lean | 39 ++++++++++++++++++- .../Homology/Embedding/IsSupported.lean | 11 +++++- .../Abelian/Injective/Extend.lean | 8 ++++ 4 files changed, 92 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean index 1bf68129bb960c..02e45c2c0db6ef 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KInjective.lean @@ -5,7 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.DerivedCategory.Basic +public import Mathlib.Algebra.Homology.DerivedCategory.SmallShiftedHom public import Mathlib.Algebra.Homology.HomotopyCategory.KInjective /-! @@ -27,9 +27,44 @@ open CategoryTheory variable {C : Type u} [Category.{v} C] [Abelian C] -lemma CochainComplex.IsKInjective.Qh_map_bijective [HasDerivedCategory C] +open CategoryTheory Localization DerivedCategory + +namespace CochainComplex + +lemma IsKInjective.Qh_map_bijective [HasDerivedCategory C] (K : HomotopyCategory C (ComplexShape.up ℤ)) (L : CochainComplex C ℤ) [L.IsKInjective] : Function.Bijective (DerivedCategory.Qh.map : (K ⟶ (HomotopyCategory.quotient _ _).obj L) → _ ) := (CochainComplex.IsKInjective.rightOrthogonal L).map_bijective_of_isTriangulated _ _ + +namespace HomComplex.CohomologyClass + +variable (K L : CochainComplex C ℤ) (n : ℤ) + [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] + +lemma bijective_toSmallShiftedHom_of_isKInjective [L.IsKInjective] : + Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by + letI := HasDerivedCategory.standard C + rw [← Function.Bijective.of_comp_iff' + (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, + ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) + ((Q.commShiftIso n).symm.app L ≪≫ (quotientCompQhIso C).symm.app (L⟦n⟧))).bijective] + convert (CochainComplex.IsKInjective.Qh_map_bijective _ _).comp (toHom_bijective K L n) + ext x + obtain ⟨x, rfl⟩ := x.mk_surjective + simp [toHom_mk, ShiftedHom.map] + +variable {K L n} in +/-- When `L` is a K-injective cochain complex, cohomology classes +in `CohomologyClass K L n` identify to elements in a type `SmallShiftedHom` relatively +to quasi-isomorphisms. -/ +@[simps! -isSimp] +noncomputable def equivOfIsKInjective [L.IsKInjective] : + CohomologyClass K L n ≃ + SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := + Equiv.ofBijective _ (bijective_toSmallShiftedHom_of_isKInjective _ _ _) + +end HomComplex.CohomologyClass + +end CochainComplex diff --git a/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean b/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean index 7ec58f1a26801e..ef0a614ef2fd8d 100644 --- a/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean +++ b/Mathlib/Algebra/Homology/DerivedCategory/KProjective.lean @@ -5,7 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.DerivedCategory.Basic +public import Mathlib.Algebra.Homology.DerivedCategory.SmallShiftedHom public import Mathlib.Algebra.Homology.HomotopyCategory.KProjective /-! @@ -27,9 +27,44 @@ open CategoryTheory variable {C : Type u} [Category.{v} C] [Abelian C] -lemma CochainComplex.IsKProjective.Qh_map_bijective [HasDerivedCategory C] +open CategoryTheory Localization DerivedCategory + +namespace CochainComplex + +lemma IsKProjective.Qh_map_bijective [HasDerivedCategory C] (K : CochainComplex C ℤ) (L : HomotopyCategory C (ComplexShape.up ℤ)) [K.IsKProjective] : Function.Bijective (DerivedCategory.Qh.map : ((HomotopyCategory.quotient _ _).obj K ⟶ L) → _ ) := (CochainComplex.IsKProjective.leftOrthogonal K).map_bijective_of_isTriangulated _ _ + +namespace HomComplex.CohomologyClass + +variable (K L : CochainComplex C ℤ) (n : ℤ) + [HasSmallLocalizedShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) ℤ K L] + +lemma bijective_toSmallShiftedHom_of_isKProjective [K.IsKProjective] : + Function.Bijective (toSmallShiftedHom.{w} (K := K) (L := L) (n := n)) := by + letI := HasDerivedCategory.standard C + rw [← Function.Bijective.of_comp_iff' + (SmallShiftedHom.equiv _ DerivedCategory.Q).bijective, + ← Function.Bijective.of_comp_iff' (Iso.homCongr ((quotientCompQhIso C).symm.app K) + ((Q.commShiftIso n).symm.app L ≪≫ (quotientCompQhIso C).symm.app (L⟦n⟧))).bijective] + convert (CochainComplex.IsKProjective.Qh_map_bijective _ _).comp (toHom_bijective K L n) + ext x + obtain ⟨x, rfl⟩ := x.mk_surjective + simp [toHom_mk, ShiftedHom.map] + +variable {K L n} in +/-- When `K` is a K-projective cochain complex, cohomology classes +in `CohomologyClass K L n` identify to elements in a type `SmallShiftedHom` relatively +to quasi-isomorphisms. -/ +@[simps! -isSimp] +noncomputable def equivOfIsKProjective [K.IsKProjective] : + CohomologyClass K L n ≃ + SmallShiftedHom.{w} (HomologicalComplex.quasiIso C (.up ℤ)) K L n := + Equiv.ofBijective _ (bijective_toSmallShiftedHom_of_isKProjective _ _ _) + +end HomComplex.CohomologyClass + +end CochainComplex diff --git a/Mathlib/Algebra/Homology/Embedding/IsSupported.lean b/Mathlib/Algebra/Homology/Embedding/IsSupported.lean index 9d0188d4e528c2..03549c8176113c 100644 --- a/Mathlib/Algebra/Homology/Embedding/IsSupported.lean +++ b/Mathlib/Algebra/Homology/Embedding/IsSupported.lean @@ -36,7 +36,7 @@ namespace HomologicalComplex section variable {C : Type*} [Category C] [HasZeroMorphisms C] - (K L : HomologicalComplex C c') (e' : K ≅ L) (e : c.Embedding c') + (K L : HomologicalComplex C c') (e' : K ≅ L) (φ : K ⟶ L) (e : c.Embedding c') /-- If `K : HomologicalComplex C c'`, then `K.IsStrictlySupported e` holds for an embedding `e : c.Embedding c'` of complex shapes if `K.X i'` is zero @@ -68,6 +68,7 @@ instance [K.IsStrictlySupported e] : K.op.IsStrictlySupported e.op := by /-- If `K : HomologicalComplex C c'`, then `K.IsStrictlySupported e` holds for an embedding `e : c.Embedding c'` of complex shapes if `K` is exact at `i'` whenever `i'` is not of the form `e.f i` for some `i`. -/ +@[mk_iff] class IsSupported : Prop where exactAt (i' : ι') (hi' : ∀ i, e.f i ≠ i') : K.ExactAt i' @@ -81,6 +82,14 @@ lemma isSupported_of_iso [K.IsSupported e] : L.IsSupported e where exactAt i' hi' := (K.exactAt_of_isSupported e i' hi').of_iso e' +variable {K L} in +lemma isSupported_iff_of_quasiIso [∀ i, K.HasHomology i] [∀ i, L.HasHomology i] + [QuasiIso φ] : + K.IsSupported e ↔ L.IsSupported e := by + simp only [isSupported_iff] + exact forall_congr' (fun i' ↦ forall_congr' + (fun hi' ↦ exactAt_iff_of_quasiIsoAt φ _)) + instance [K.IsStrictlySupported e] : K.IsSupported e where exactAt i' hi' := by rw [exactAt_iff] diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean index 91d6a7c120f69b..5d8faab0f288d6 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Extend.lean @@ -40,6 +40,10 @@ obtained by extending by zero the cochain complex `R.cocomplex` indexed by `ℕ` noncomputable def cochainComplex : CochainComplex C ℤ := R.cocomplex.extend ComplexShape.embeddingUpNat +instance : R.cochainComplex.IsStrictlyGE 0 := by + dsimp [cochainComplex] + infer_instance + /-- If `R : InjectiveResolution X`, then `R.cochainComplex.X n` (with `n : ℕ`) is isomorphic to `R.cocomplex.X k` (with `k : ℕ`) when `k = n`. -/ noncomputable def cochainComplexXIso (n : ℤ) (k : ℕ) (h : k = n) : @@ -83,6 +87,10 @@ variable [Abelian C] {X : C} (R : InjectiveResolution X) instance : QuasiIso R.ι' := by dsimp [ι']; infer_instance +instance : R.cochainComplex.IsLE 0 := by + simp only [← HomologicalComplex.isSupported_iff_of_quasiIso R.ι'] + infer_instance + end InjectiveResolution end CategoryTheory From 47b374b9a93e3d3bedbe3e23f729bef37c4423e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 12 Dec 2025 22:29:48 +0100 Subject: [PATCH 45/60] dual instance --- Mathlib/CategoryTheory/Abelian/Projective/Extend.lean | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean b/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean index 98dc644d95f37e..6ed51e71bb14a3 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean @@ -83,6 +83,10 @@ variable [Abelian C] {X : C} (R : ProjectiveResolution X) instance : QuasiIso R.π' := by dsimp [π']; infer_instance +instance : R.cochainComplex.IsLE 0 := by + simp only [HomologicalComplex.isSupported_iff_of_quasiIso R.π'] + infer_instance + end ProjectiveResolution end CategoryTheory From f65be34db556f48ae2bdd6bb3c0fd2e0d21607d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 12 Dec 2025 23:23:50 +0100 Subject: [PATCH 46/60] feat(CategoryTheory): computing Ext-groups using a projective resolution --- Mathlib.lean | 1 + .../Abelian/Projective/Ext.lean | 207 ++++++++++++++++++ .../Abelian/Projective/Extend.lean | 2 +- 3 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 Mathlib/CategoryTheory/Abelian/Projective/Ext.lean diff --git a/Mathlib.lean b/Mathlib.lean index 97ed832c65e790..5bd0b074639152 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2208,6 +2208,7 @@ public import Mathlib.CategoryTheory.Abelian.NonPreadditive public import Mathlib.CategoryTheory.Abelian.Opposite public import Mathlib.CategoryTheory.Abelian.Projective.Basic public import Mathlib.CategoryTheory.Abelian.Projective.Dimension +public import Mathlib.CategoryTheory.Abelian.Projective.Ext public import Mathlib.CategoryTheory.Abelian.Projective.Extend public import Mathlib.CategoryTheory.Abelian.Projective.Resolution public import Mathlib.CategoryTheory.Abelian.Pseudoelements diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean new file mode 100644 index 00000000000000..8cb5a592b5bd1b --- /dev/null +++ b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean @@ -0,0 +1,207 @@ +/- +Copyright (c) 2025 Joël Riou. All rights reserved. +Released under Apache 2.0 license as described in the file LICENSE. +Authors: Joël Riou +-/ +module + +public import Mathlib.Algebra.Homology.DerivedCategory.Ext.TStructure +public import Mathlib.Algebra.Homology.DerivedCategory.KProjective +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexCohomology +public import Mathlib.Algebra.Homology.HomotopyCategory.HomComplexSingle +public import Mathlib.Algebra.Homology.HomotopyCategory.KProjective +public import Mathlib.CategoryTheory.Abelian.Projective.Extend + +/-! +# Computing `Ext` using a projective resolution + +Given a projective resolution `R` of an object `X` in an abelian category `C`, +we provide an API in order to construct elements in `Ext X Y n` in terms +of the complex `R.complex` and to make computations in the `Ext`-group. + +## TODO +* Functoriality in `Y` for a given projective resolution `R` +* Functoriality in `X`: this would involve a morphism `X ⟶ X'`, projective +resolutions `R` and `R'` of `X` and `X'`, a lift of `X ⟶ X'` as a morphism +of cochain complexes `R.complex ⟶ R'.complex`; in this context, +we should be able to compute the precomposition of an element +`R.extMk f m hm hf : Ext X' Y n` by `X ⟶ X'`. + +-/ + +@[expose] public section + +universe w v u + +open CategoryTheory CochainComplex HomComplex Abelian Localization + +namespace CategoryTheory.ProjectiveResolution + +variable {C : Type u} [Category.{v} C] [Abelian C] [HasExt.{w} C] + {X Y : C} (R : ProjectiveResolution X) {n : ℕ} + +instance : R.cochainComplex.IsKProjective := isKProjective_of_projective _ 0 + +/-- If `R` is a pronjective resolution of `X`, then `Ext X Y n` identify +to the type of cohomology classes of degree `n` from `R.cochainComplex` +to `(singleFunctor C 0).obj Y`. -/ +noncomputable def extEquivCohomologyClass : + Ext X Y n ≃ CohomologyClass R.cochainComplex ((singleFunctor C 0).obj Y) n := + (SmallShiftedHom.precompEquiv.{w} R.π' + ((by rw [HomologicalComplex.mem_quasiIso_iff]; infer_instance))).trans + CochainComplex.HomComplex.CohomologyClass.equivOfIsKProjective.{w}.symm + +lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] + (x : Cocycle R.cochainComplex ((singleFunctor C 0).obj Y) n) : + (R.extEquivCohomologyClass.symm (.mk x)).hom = + inv (DerivedCategory.Q.map R.π') ≫ + DerivedCategory.Q.map (Cocycle.equivHomShift.symm x) ≫ + (DerivedCategory.Q.commShiftIso (n : ℤ)).hom.app _ := by + simp only [Ext.hom, Ext.homEquiv, extEquivCohomologyClass, SmallShiftedHom.precompEquiv, + Equiv.symm_trans_apply, Equiv.symm_symm, CohomologyClass.equivOfIsKProjective_apply, + Equiv.coe_fn_symm_mk, Functor.comp_obj] + refine (SmallShiftedHom.equiv_comp _ _ _ _ _).trans ?_ + simp [ShiftedHom.comp, ShiftedHom.mk₀, shiftFunctorZero', ShiftedHom.map, + shiftFunctorAdd'_add_zero_inv_app, isoOfHom] + +@[simp] +lemma extEquivCohomologyClass_symm_add + (x y : CohomologyClass R.cochainComplex ((singleFunctor C 0).obj Y) n) : + R.extEquivCohomologyClass.symm (x + y) = + R.extEquivCohomologyClass.symm x + R.extEquivCohomologyClass.symm y := by + have := HasDerivedCategory.standard C + obtain ⟨x, rfl⟩ := x.mk_surjective + obtain ⟨y, rfl⟩ := y.mk_surjective + ext + simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom] + +/-- If `R` is a projective resolution of `X`, then `Ext X Y n` identify +to the type of cohomology classes of degree `n` from `R.cochainComplex` +to `(singleFunctor C 0).obj X`. -/ +noncomputable def extAddEquivCohomologyClass : + Ext X Y n ≃+ CohomologyClass R.cochainComplex ((singleFunctor C 0).obj Y) n := + AddEquiv.symm + { toEquiv := R.extEquivCohomologyClass.symm + map_add' := by simp } + +@[simp] +lemma extEquivCohomologyClass_symm_sub + (x y : CohomologyClass R.cochainComplex ((singleFunctor C 0).obj Y) n) : + R.extEquivCohomologyClass.symm (x - y) = + R.extEquivCohomologyClass.symm x - R.extEquivCohomologyClass.symm y := + R.extAddEquivCohomologyClass.symm.map_sub _ _ + +@[simp] +lemma extEquivCohomologyClass_symm_neg + (x : CohomologyClass R.cochainComplex ((singleFunctor C 0).obj Y) n) : + R.extEquivCohomologyClass.symm (-x) = + -R.extEquivCohomologyClass.symm x := + R.extAddEquivCohomologyClass.symm.map_neg _ + +@[simp] +lemma extEquivCohomologyClass_symm_zero : + (R.extEquivCohomologyClass (Y := Y) (n := n)).symm 0 = 0 := + R.extAddEquivCohomologyClass.symm.map_zero + +@[simp] +lemma extEquivCohomologyClass_add (x y : Ext X Y n) : + R.extEquivCohomologyClass (x + y) = + R.extEquivCohomologyClass x + R.extEquivCohomologyClass y := + R.extAddEquivCohomologyClass.map_add _ _ + +@[simp] +lemma extEquivCohomologyClass_sub (x y : Ext X Y n) : + R.extEquivCohomologyClass (x - y) = + R.extEquivCohomologyClass x - R.extEquivCohomologyClass y := + R.extAddEquivCohomologyClass.map_sub _ _ + +@[simp] +lemma extEquivCohomologyClass_neg (x : Ext X Y n) : + R.extEquivCohomologyClass (-x) = + -R.extEquivCohomologyClass x := + R.extAddEquivCohomologyClass.map_neg _ + +variable (X n) in +@[simp] +lemma extEquivCohomologyClass_zero : + R.extEquivCohomologyClass (0 : Ext X Y n) = 0 := + R.extAddEquivCohomologyClass.map_zero + +/-- Given a projective resolution `R` of an object `X` of an abelian category, +this is a constructor for elements in `Ext X Y n` which takes as an input +a "cocycle" `f : R.cocomplex.X n ⟶ Y`. -/ +noncomputable def extMk {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) + (hf : R.complex.d m n ≫ f = 0) : + Ext X Y n := + R.extEquivCohomologyClass.symm + (.mk (Cocycle.toSingleMk ((R.cochainComplexXIso (-n) n rfl).hom ≫ f) (by simp) + (-m) (by lia) (by simpa [cochainComplex_d _ _ _ m n rfl rfl]))) + +@[simp] +lemma extEquivCohomologyClass_extMk {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) + (hf : R.complex.d m n ≫ f = 0) : + R.extEquivCohomologyClass (R.extMk f m hm hf) = + (.mk (Cocycle.toSingleMk ((R.cochainComplexXIso (-n) n rfl).hom ≫ f) (by simp) + (-m) (by lia) (by simpa [cochainComplex_d _ _ _ m n rfl rfl]))) := by + simp [extMk] + +lemma add_extMk {n : ℕ} (f g : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) + (hf : R.complex.d m n ≫ f = 0) (hg : R.complex.d m n ≫ g = 0) : + R.extMk f m hm hf + R.extMk g m hm hg = + R.extMk (f + g) m hm (by simp [hf, hg]) := by + simp only [extMk, Preadditive.comp_add] + rw [Cocycle.toSingleMk_add _ _ _ _ _ + (by simpa [cochainComplex_d _ _ _ m n rfl rfl]) + (by simpa [cochainComplex_d _ _ _ m n rfl rfl])] + simp + +lemma sub_extMk {n : ℕ} (f g : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) + (hf : R.complex.d m n ≫ f = 0) (hg : R.complex.d m n ≫ g = 0) : + R.extMk f m hm hf - R.extMk g m hm hg = + R.extMk (f - g) m hm (by simp [hf, hg]) := by + simp only [extMk, Preadditive.comp_sub] + rw [Cocycle.toSingleMk_sub _ _ _ _ _ + (by simpa [cochainComplex_d _ _ _ m n rfl rfl]) + (by simpa [cochainComplex_d _ _ _ m n rfl rfl])] + simp + +lemma neg_extMk {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) + (hf : R.complex.d m n ≫ f = 0) : + -R.extMk f m hm hf = + R.extMk (-f) m hm (by simp [hf]) := by + simp only [extMk, Preadditive.comp_neg] + rw [Cocycle.toSingleMk_neg _ _ _ _ + (by simpa [cochainComplex_d _ _ _ m n rfl rfl])] + simp + +@[simp] +lemma extMk_zero {n : ℕ} (m : ℕ) (hm : n + 1 = m) : + R.extMk (0 : R.complex.X n ⟶ Y) m hm (by simp) = 0 := by + simp [extMk] + +lemma extMk_eq_zero_iff (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) + (hf : R.complex.d m n ≫ f = 0) + (p : ℕ) (hp : p + 1 = n) : + R.extMk f m hm hf = 0 ↔ + ∃ (g : R.complex.X p ⟶ Y), R.complex.d n p ≫ g = f := by + simp only [← R.extEquivCohomologyClass.apply_eq_iff_eq, + extEquivCohomologyClass_extMk, extEquivCohomologyClass_zero, + CohomologyClass.mk_eq_zero_iff] + rw [Cocycle.toSingleMk_mem_coboundaries_iff _ _ _ _ _ (-p) (by lia), + R.cochainComplex_d _ _ _ _ rfl rfl] + refine ⟨fun ⟨g, hg⟩ ↦ ⟨(R.cochainComplexXIso (-p) p rfl).inv ≫ g, ?_⟩, + fun ⟨g, hg⟩ ↦ ⟨(R.cochainComplexXIso (-p) p rfl).hom ≫ g, by simpa⟩⟩ + rw [← cancel_epi (R.cochainComplexXIso (-n) n rfl).hom] + simpa [Category.assoc] using hg + +lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : + ∃ (f : R.complex.X n ⟶ Y) (hf : R.complex.d m n ≫ f = 0), + R.extMk f m hm hf = α := by + obtain ⟨x, rfl⟩ := R.extEquivCohomologyClass.symm.surjective α + obtain ⟨x, rfl⟩ := x.mk_surjective + obtain ⟨f, hf, rfl⟩ := Cocycle.toSingleMk_surjective x (-n) (by simp) (-m) (by lia) + refine ⟨(R.cochainComplexXIso (-n) n rfl).inv ≫ f, ?_, by simp [extMk]⟩ + rw [← cancel_epi (R.cochainComplexXIso (-m) m rfl).hom] + simpa [R.cochainComplex_d _ _ _ _ rfl rfl] using hf + +end CategoryTheory.ProjectiveResolution diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean b/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean index 6ed51e71bb14a3..bb5ef26e165e2f 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Extend.lean @@ -83,7 +83,7 @@ variable [Abelian C] {X : C} (R : ProjectiveResolution X) instance : QuasiIso R.π' := by dsimp [π']; infer_instance -instance : R.cochainComplex.IsLE 0 := by +instance : R.cochainComplex.IsGE 0 := by simp only [HomologicalComplex.isSupported_iff_of_quasiIso R.π'] infer_instance From eafd64a7db6be8fa095ca57fd5d1079ec93d517e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 23 Dec 2025 13:48:11 +0100 Subject: [PATCH 47/60] Update Mathlib/CategoryTheory/Abelian/Injective/Ext.lean Co-authored-by: Dagur Asgeirsson --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 0c2214b96c4086..9946285f21295d 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -42,7 +42,7 @@ variable {C : Type u} [Category.{v} C] [Abelian C] [HasExt.{w} C] instance : R.cochainComplex.IsKInjective := isKInjective_of_injective _ 0 -/-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identify +/-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identifies to the type of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` to `R.cochainComplex`. -/ noncomputable def extEquivCohomologyClass : From 35822243e74c28e53ee52f7586d6738247246926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 23 Dec 2025 13:48:18 +0100 Subject: [PATCH 48/60] Update Mathlib/CategoryTheory/Abelian/Injective/Ext.lean Co-authored-by: Dagur Asgeirsson --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 9946285f21295d..d7ce64a76795d9 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -81,8 +81,8 @@ lemma extEquivCohomologyClass_symm_add ext simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom] -/-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identify -to the type of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` +/-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identifies +to the group of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` to `R.cochainComplex`. -/ noncomputable def extAddEquivCohomologyClass : Ext X Y n ≃+ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := From b3855740fd00aae34d2af970f1334a7a9ac6a6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 23 Dec 2025 14:00:52 +0100 Subject: [PATCH 49/60] used erw --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index d7ce64a76795d9..1f9de1eec5fb44 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -60,7 +60,7 @@ lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] simp only [Ext.hom, Ext.homEquiv, extEquivCohomologyClass, SmallShiftedHom.postcompEquiv, Equiv.symm_trans_apply, Equiv.symm_symm, CohomologyClass.equivOfIsKInjective_apply, Equiv.coe_fn_symm_mk, Functor.comp_obj] - refine (SmallShiftedHom.equiv_comp _ _ _ _ _).trans ?_ + erw [SmallShiftedHom.equiv_comp] simp only [ShiftedHom.comp, CohomologyClass.equiv_toSmallShiftedHom_mk, ShiftedHom.map, SmallShiftedHom.equiv_mk₀Inv, ShiftedHom.mk₀, shiftFunctorZero', eqToIso_refl, Iso.refl_trans, Functor.map_comp, shiftFunctorAdd'_zero_add_inv_app, Functor.id_obj, Category.assoc] From 108dde0055c62686abbe1c44bcc11e243944be47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 23 Dec 2025 14:13:23 +0100 Subject: [PATCH 50/60] used change instead --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 1f9de1eec5fb44..99fe0dc6f4b96f 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -57,16 +57,11 @@ lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] DerivedCategory.Q.map (Cocycle.equivHomShift.symm x) ≫ inv (DerivedCategory.Q.map (R.ι'⟦(n : ℤ)⟧')) ≫ (DerivedCategory.Q.commShiftIso (n : ℤ)).hom.app _ := by - simp only [Ext.hom, Ext.homEquiv, extEquivCohomologyClass, SmallShiftedHom.postcompEquiv, - Equiv.symm_trans_apply, Equiv.symm_symm, CohomologyClass.equivOfIsKInjective_apply, - Equiv.coe_fn_symm_mk, Functor.comp_obj] - erw [SmallShiftedHom.equiv_comp] - simp only [ShiftedHom.comp, CohomologyClass.equiv_toSmallShiftedHom_mk, ShiftedHom.map, - SmallShiftedHom.equiv_mk₀Inv, ShiftedHom.mk₀, shiftFunctorZero', eqToIso_refl, Iso.refl_trans, - Functor.map_comp, shiftFunctorAdd'_zero_add_inv_app, Functor.id_obj, Category.assoc] - rw [← Functor.map_comp, Iso.inv_hom_id_app] - dsimp - rw [Functor.map_id, Category.comp_id] + change (SmallShiftedHom.equiv _ _) ((CohomologyClass.mk x).toSmallShiftedHom.comp _ _) = _ + simp only [SmallShiftedHom.equiv_comp, ShiftedHom.comp, + CohomologyClass.equiv_toSmallShiftedHom_mk, ShiftedHom.map, SmallShiftedHom.equiv_mk₀Inv, + ShiftedHom.mk₀, shiftFunctorZero', eqToIso_refl, Iso.refl_trans, + shiftFunctorAdd'_zero_add_inv_app, Functor.id_obj, Category.assoc, Functor.comp_obj] congr 1 simp [← Functor.map_comp] From d2f501545bd6fb2c7ad76cd094fb661c611b6781 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 23 Dec 2025 14:19:41 +0100 Subject: [PATCH 51/60] better syntax --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 99fe0dc6f4b96f..f35f73292f569a 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -57,7 +57,7 @@ lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] DerivedCategory.Q.map (Cocycle.equivHomShift.symm x) ≫ inv (DerivedCategory.Q.map (R.ι'⟦(n : ℤ)⟧')) ≫ (DerivedCategory.Q.commShiftIso (n : ℤ)).hom.app _ := by - change (SmallShiftedHom.equiv _ _) ((CohomologyClass.mk x).toSmallShiftedHom.comp _ _) = _ + change SmallShiftedHom.equiv _ _ ((CohomologyClass.mk x).toSmallShiftedHom.comp _ _) = _ simp only [SmallShiftedHom.equiv_comp, ShiftedHom.comp, CohomologyClass.equiv_toSmallShiftedHom_mk, ShiftedHom.map, SmallShiftedHom.equiv_mk₀Inv, ShiftedHom.mk₀, shiftFunctorZero', eqToIso_refl, Iso.refl_trans, From 00c86c8fe8374bff346d409781e2651a39c94869 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 27 Dec 2025 18:21:16 +0100 Subject: [PATCH 52/60] added simps attribute --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 1 + 1 file changed, 1 insertion(+) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index f35f73292f569a..97d743e62c7a1e 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -79,6 +79,7 @@ lemma extEquivCohomologyClass_symm_add /-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identifies to the group of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` to `R.cochainComplex`. -/ +@[simps!] noncomputable def extAddEquivCohomologyClass : Ext X Y n ≃+ CohomologyClass ((singleFunctor C 0).obj X) R.cochainComplex n := AddEquiv.symm From 19f66fb376a529b27a752b21bcdf4ae4e530f5fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 28 Dec 2025 12:24:59 +0100 Subject: [PATCH 53/60] fix --- Mathlib/CategoryTheory/Abelian/Projective/Ext.lean | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean index 8cb5a592b5bd1b..43c321d2ab8ba4 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean @@ -42,7 +42,7 @@ variable {C : Type u} [Category.{v} C] [Abelian C] [HasExt.{w} C] instance : R.cochainComplex.IsKProjective := isKProjective_of_projective _ 0 -/-- If `R` is a pronjective resolution of `X`, then `Ext X Y n` identify +/-- If `R` is a projective resolution of `X`, then `Ext X Y n` identifies to the type of cohomology classes of degree `n` from `R.cochainComplex` to `(singleFunctor C 0).obj Y`. -/ noncomputable def extEquivCohomologyClass : @@ -57,12 +57,9 @@ lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] inv (DerivedCategory.Q.map R.π') ≫ DerivedCategory.Q.map (Cocycle.equivHomShift.symm x) ≫ (DerivedCategory.Q.commShiftIso (n : ℤ)).hom.app _ := by - simp only [Ext.hom, Ext.homEquiv, extEquivCohomologyClass, SmallShiftedHom.precompEquiv, - Equiv.symm_trans_apply, Equiv.symm_symm, CohomologyClass.equivOfIsKProjective_apply, - Equiv.coe_fn_symm_mk, Functor.comp_obj] - refine (SmallShiftedHom.equiv_comp _ _ _ _ _).trans ?_ - simp [ShiftedHom.comp, ShiftedHom.mk₀, shiftFunctorZero', ShiftedHom.map, - shiftFunctorAdd'_add_zero_inv_app, isoOfHom] + change SmallShiftedHom.equiv _ _ (.comp _ (CohomologyClass.mk x).toSmallShiftedHom _) = _ + simp [SmallShiftedHom.equiv_comp, ShiftedHom.mk₀, ShiftedHom.comp, + ShiftedHom.map, shiftFunctorAdd'_add_zero_inv_app, shiftFunctorZero'] @[simp] lemma extEquivCohomologyClass_symm_add @@ -75,9 +72,10 @@ lemma extEquivCohomologyClass_symm_add ext simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom] -/-- If `R` is a projective resolution of `X`, then `Ext X Y n` identify +/-- If `R` is a projective resolution of `X`, then `Ext X Y n` identifies to the type of cohomology classes of degree `n` from `R.cochainComplex` to `(singleFunctor C 0).obj X`. -/ +@[simps!] noncomputable def extAddEquivCohomologyClass : Ext X Y n ≃+ CohomologyClass R.cochainComplex ((singleFunctor C 0).obj Y) n := AddEquiv.symm From 8fcc7cd5753a996948392fea5467a220ac1d41e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 28 Dec 2025 12:37:16 +0100 Subject: [PATCH 54/60] better equational lemma --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index 97d743e62c7a1e..b4d6626bad5c84 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -54,16 +54,10 @@ noncomputable def extEquivCohomologyClass : lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] (x : Cocycle ((singleFunctor C 0).obj X) R.cochainComplex n) : (R.extEquivCohomologyClass.symm (.mk x)).hom = - DerivedCategory.Q.map (Cocycle.equivHomShift.symm x) ≫ - inv (DerivedCategory.Q.map (R.ι'⟦(n : ℤ)⟧')) ≫ - (DerivedCategory.Q.commShiftIso (n : ℤ)).hom.app _ := by + (ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q).comp + (.mk₀ _ rfl (inv (DerivedCategory.Q.map (R.ι')))) (zero_add _) := by change SmallShiftedHom.equiv _ _ ((CohomologyClass.mk x).toSmallShiftedHom.comp _ _) = _ - simp only [SmallShiftedHom.equiv_comp, ShiftedHom.comp, - CohomologyClass.equiv_toSmallShiftedHom_mk, ShiftedHom.map, SmallShiftedHom.equiv_mk₀Inv, - ShiftedHom.mk₀, shiftFunctorZero', eqToIso_refl, Iso.refl_trans, - shiftFunctorAdd'_zero_add_inv_app, Functor.id_obj, Category.assoc, Functor.comp_obj] - congr 1 - simp [← Functor.map_comp] + simp [SmallShiftedHom.equiv_comp, isoOfHom] @[simp] lemma extEquivCohomologyClass_symm_add @@ -74,7 +68,7 @@ lemma extEquivCohomologyClass_symm_add obtain ⟨x, rfl⟩ := x.mk_surjective obtain ⟨y, rfl⟩ := y.mk_surjective ext - simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom] + simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom, ShiftedHom.map] /-- If `R` is an injective resolution of `Y`, then `Ext X Y n` identifies to the group of cohomology classes of degree `n` from `(singleFunctor C 0).obj X` From 1c8eb6751b345f52436dad6eeee655af5a12cefb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 28 Dec 2025 12:41:48 +0100 Subject: [PATCH 55/60] better lemma --- Mathlib/CategoryTheory/Abelian/Projective/Ext.lean | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean index 43c321d2ab8ba4..5071dc32d3ee91 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean @@ -54,9 +54,8 @@ noncomputable def extEquivCohomologyClass : lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] (x : Cocycle R.cochainComplex ((singleFunctor C 0).obj Y) n) : (R.extEquivCohomologyClass.symm (.mk x)).hom = - inv (DerivedCategory.Q.map R.π') ≫ - DerivedCategory.Q.map (Cocycle.equivHomShift.symm x) ≫ - (DerivedCategory.Q.commShiftIso (n : ℤ)).hom.app _ := by + (ShiftedHom.mk₀ _ rfl (inv (DerivedCategory.Q.map R.π'))).comp + (ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q) (add_zero _) := by change SmallShiftedHom.equiv _ _ (.comp _ (CohomologyClass.mk x).toSmallShiftedHom _) = _ simp [SmallShiftedHom.equiv_comp, ShiftedHom.mk₀, ShiftedHom.comp, ShiftedHom.map, shiftFunctorAdd'_add_zero_inv_app, shiftFunctorZero'] @@ -70,7 +69,7 @@ lemma extEquivCohomologyClass_symm_add obtain ⟨x, rfl⟩ := x.mk_surjective obtain ⟨y, rfl⟩ := y.mk_surjective ext - simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom] + simp [← CohomologyClass.mk_add, extEquivCohomologyClass_symm_mk_hom, ShiftedHom.map] /-- If `R` is a projective resolution of `X`, then `Ext X Y n` identifies to the type of cohomology classes of degree `n` from `R.cochainComplex` From 27aece17921e82934681279a1da77a0fdc5c37b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 28 Dec 2025 12:42:10 +0100 Subject: [PATCH 56/60] typo --- Mathlib/CategoryTheory/Abelian/Injective/Ext.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index b4d6626bad5c84..e802ed8bf10893 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -55,7 +55,7 @@ lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] (x : Cocycle ((singleFunctor C 0).obj X) R.cochainComplex n) : (R.extEquivCohomologyClass.symm (.mk x)).hom = (ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q).comp - (.mk₀ _ rfl (inv (DerivedCategory.Q.map (R.ι')))) (zero_add _) := by + (.mk₀ _ rfl (inv (DerivedCategory.Q.map R.ι'))) (zero_add _) := by change SmallShiftedHom.equiv _ _ ((CohomologyClass.mk x).toSmallShiftedHom.comp _ _) = _ simp [SmallShiftedHom.equiv_comp, isoOfHom] From 851cf7673570da7388fcbcef0cf650e6f5f2aac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 28 Dec 2025 12:43:19 +0100 Subject: [PATCH 57/60] better proof --- Mathlib/CategoryTheory/Abelian/Projective/Ext.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean index 5071dc32d3ee91..256179cd70d501 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean @@ -57,8 +57,7 @@ lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] (ShiftedHom.mk₀ _ rfl (inv (DerivedCategory.Q.map R.π'))).comp (ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q) (add_zero _) := by change SmallShiftedHom.equiv _ _ (.comp _ (CohomologyClass.mk x).toSmallShiftedHom _) = _ - simp [SmallShiftedHom.equiv_comp, ShiftedHom.mk₀, ShiftedHom.comp, - ShiftedHom.map, shiftFunctorAdd'_add_zero_inv_app, shiftFunctorZero'] + simp [SmallShiftedHom.equiv_comp, isoOfHom] @[simp] lemma extEquivCohomologyClass_symm_add From 3549a58fd43a295ad860e810f7ba05872540f945 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 28 Dec 2025 13:42:59 +0100 Subject: [PATCH 58/60] functoriality --- .../Homology/HomotopyCategory/HomComplex.lean | 10 ++++++++++ .../HomotopyCategory/HomComplexShift.lean | 11 +++++++++++ .../HomotopyCategory/HomComplexSingle.lean | 19 +++++++++++++++++++ .../CategoryTheory/Abelian/Injective/Ext.lean | 15 +++++++++++++++ 4 files changed, 55 insertions(+) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean index 8c6f447f1e8bf0..b42c9b10178816 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplex.lean @@ -759,6 +759,16 @@ lemma δ_ofHom_comp {n : ℤ} (f : F ⟶ G) (z : Cochain G K n) (m : ℤ) : (Cochain.ofHom f).comp (δ n m z) (zero_add m) := by rw [← Cocycle.ofHom_coe, δ_zero_cocycle_comp] +/-- The precomposition of a cocycle with a morphism of cochain complexes. -/ +@[simps!] +def Cocycle.precomp {n : ℤ} (z : Cocycle G K n) (f : F ⟶ G) : Cocycle F K n := + Cocycle.mk ((Cochain.ofHom f).comp z (zero_add n)) _ rfl (by simp) + +/-- The postcomposition of a cocycle with a morphism of cochain complexes. -/ +@[simps!] +def Cocycle.postcomp {n : ℤ} (z : Cocycle F G n) (f : G ⟶ K) : Cocycle F K n := + Cocycle.mk (z.1.comp (Cochain.ofHom f) (add_zero n)) _ rfl (by simp) + namespace Cochain /-- Given two morphisms of complexes `φ₁ φ₂ : F ⟶ G`, the datum of a homotopy between `φ₁` and diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean index 213c75e406f063..10da22e34a3c42 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean @@ -555,6 +555,17 @@ def equivHomShift : (K ⟶ L⟦n⟧) ≃+ Cocycle K L n := (equivHom _ _).trans (rightShiftAddEquiv _ _ _ (zero_add n)).symm +lemma equivHomShift_comp {K' : CochainComplex C ℤ} + (g : K' ⟶ K) (f : K ⟶ L⟦n⟧) : + equivHomShift (g ≫ f) = Cocycle.precomp (equivHomShift f) g := by + ext p q hpq + simp [equivHomShift_apply, Cochain.rightUnshift_v _ _ _ _ _ _ _ (add_zero p)] + +lemma equivHomShift_symm_precomp + (z : Cocycle K L n) {K' : CochainComplex C ℤ} (g : K' ⟶ K) : + equivHomShift.symm (z.precomp g) = g ≫ equivHomShift.symm z := + equivHomShift.injective (by simp [equivHomShift_comp]) + /-- The additive equivalence `Cocycle K L n ≃+ Cocycle K⟦a⟧ L n'` when `n + a = n'`. -/ @[simps] def leftShiftAddEquiv (n a n' : ℤ) (hn' : n + a = n') : diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean index 2961901e8ae538..431448b585d200 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -82,6 +82,11 @@ noncomputable def fromSingleEquiv {p q n : ℤ} (h : p + n = q) : right_inv f := by simp map_add' := by simp +@[simp] +lemma fromSingleEquiv_fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : + fromSingleEquiv h (fromSingleMk f h) = f := by + simp [fromSingleEquiv] + @[simp] lemma fromSingleMk_add {p q : ℤ} (f g : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : fromSingleMk (f + g) h = fromSingleMk f h + fromSingleMk g h := @@ -102,6 +107,13 @@ lemma fromSingleMk_surjective {p n : ℤ} (α : Cochain ((singleFunctor C p).obj ∃ (f : X ⟶ K.X q), fromSingleMk f h = α := (fromSingleEquiv h).symm.surjective α +lemma fromSingleMk_precomp + {X' : C} (g : X' ⟶ X) {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) : + fromSingleMk (g ≫ f) h = + (Cochain.ofHom ((singleFunctor C p).map g)).comp (fromSingleMk f h) (zero_add n) := by + apply (fromSingleEquiv h).injective + simp [fromSingleEquiv, singleFunctor, singleFunctors, HomologicalComplex.single_map_f_self] + /-- Constructor for cochains to a single complex. -/ @[nolint unusedArguments] noncomputable def toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (_ : p + n = q) : @@ -181,6 +193,13 @@ noncomputable def fromSingleMk {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + rw [Cochain.δ_fromSingleMk _ _ _ q' (by lia), hf] simp) +lemma fromSingleMk_precomp {X' : C} (g : X' ⟶ X) {p q : ℤ} (f : X ⟶ K.X q) {n : ℤ} (h : p + n = q) + (q' : ℤ) (hq' : q + 1 = q') (hf : f ≫ K.d q q' = 0) : + fromSingleMk (g ≫ f) h q' hq' (by simp [hf]) = + (fromSingleMk f h q' hq' hf).precomp ((singleFunctor C p).map g) := by + ext : 1 + exact (Cochain.fromSingleEquiv h).injective (by simp [Cochain.fromSingleMk_precomp]) + lemma fromSingleMk_surjective {p n : ℤ} (α : Cocycle ((singleFunctor C p).obj X) K n) (q : ℤ) (h : p + n = q) (q' : ℤ) (hq' : q + 1 = q') : ∃ (f : X ⟶ K.X q) (hf : f ≫ K.d q q' = 0), fromSingleMk f h q' hq' hf = α := by diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index e802ed8bf10893..fa8248caf7e5a9 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -200,4 +200,19 @@ lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : by simpa [R.cochainComplex_d _ _ _ _ rfl rfl, ← cancel_mono (R.cochainComplexXIso m m rfl).inv] using hf, by simp [extMk]⟩ +lemma mk₀_comp_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + 1 = m) + (hf : f ≫ R.cocomplex.d n m = 0) {X' : C} (g : X' ⟶ X) : + (Ext.mk₀ g).comp (R.extMk f m hm hf) (zero_add _) = + R.extMk (g ≫ f) m hm (by simp [hf]) := by + have := HasDerivedCategory.standard C + ext + simp only [extMk, Ext.comp_hom, Int.cast_ofNat_Int, Ext.mk₀_hom, + extEquivCohomologyClass_symm_mk_hom, Category.assoc] + rw [Cocycle.fromSingleMk_precomp g _ (zero_add _) _ (by lia) (by + simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]), + Cocycle.equivHomShift_symm_precomp, ← ShiftedHom.mk₀_comp 0 rfl, + ShiftedHom.map_comp, ShiftedHom.map_mk₀, + ShiftedHom.comp_assoc _ _ _ (add_zero _) (zero_add _) (by simp)] + rfl + end CategoryTheory.InjectiveResolution From 211678c1c8f1db60c592c9ab8b3b712d4a883a12 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 28 Dec 2025 14:01:06 +0100 Subject: [PATCH 59/60] dual statement --- .../HomotopyCategory/HomComplexShift.lean | 10 ++++++++++ .../HomotopyCategory/HomComplexSingle.lean | 19 +++++++++++++++++++ .../CategoryTheory/Abelian/Injective/Ext.lean | 1 - .../Abelian/Projective/Ext.lean | 18 +++++++++++++++++- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean index 10da22e34a3c42..98dd4f969117c5 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexShift.lean @@ -566,6 +566,16 @@ lemma equivHomShift_symm_precomp equivHomShift.symm (z.precomp g) = g ≫ equivHomShift.symm z := equivHomShift.injective (by simp [equivHomShift_comp]) +lemma equivHomShift_comp_shift (f : K ⟶ L⟦n⟧) {L' : CochainComplex C ℤ} (g : L ⟶ L') : + equivHomShift (f ≫ g⟦n⟧') = Cocycle.postcomp (equivHomShift f) g := by + ext p q rfl + simp [equivHomShift_apply, Cochain.rightUnshift_v _ _ _ _ _ _ _ (add_zero p)] + +lemma equivHomShift_symm_postcomp + (z : Cocycle K L n) {L' : CochainComplex C ℤ} (g : L ⟶ L') : + equivHomShift.symm (z.postcomp g) = equivHomShift.symm z ≫ g⟦n⟧' := + equivHomShift.injective (by simp [equivHomShift_comp_shift]) + /-- The additive equivalence `Cocycle K L n ≃+ Cocycle K⟦a⟧ L n'` when `n + a = n'`. -/ @[simps] def leftShiftAddEquiv (n a n' : ℤ) (hn' : n + a = n') : diff --git a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean index 431448b585d200..9f30a2eea13895 100644 --- a/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean +++ b/Mathlib/Algebra/Homology/HomotopyCategory/HomComplexSingle.lean @@ -160,6 +160,11 @@ noncomputable def toSingleEquiv {p q n : ℤ} (h : p + n = q) : right_inv f := by simp map_add' := by simp +@[simp] +lemma toSingleEquiv_toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) : + toSingleEquiv h (toSingleMk f h) = f := by + simp [toSingleEquiv] + @[simp] lemma toSingleMk_add {p q : ℤ} (f g : K.X p ⟶ X) {n : ℤ} (h : p + n = q) : toSingleMk (f + g) h = toSingleMk f h + toSingleMk g h := @@ -180,6 +185,13 @@ lemma toSingleMk_surjective {q n : ℤ} (α : Cochain K ((singleFunctor C q).obj ∃ (f : K.X p ⟶ X), toSingleMk f h = α := (toSingleEquiv h).symm.surjective α +lemma toSingleMk_postcomp + {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) {X' : C} (g : X ⟶ X') : + toSingleMk (f ≫ g) h = + (toSingleMk f h).comp (.ofHom ((singleFunctor C q).map g)) (add_zero n) := by + apply (toSingleEquiv h).injective + simp [toSingleEquiv, singleFunctor, singleFunctors, HomologicalComplex.single_map_f_self] + end Cochain namespace Cocycle @@ -257,6 +269,13 @@ noncomputable def toSingleMk {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n rw [Cochain.δ_toSingleMk _ _ _ p' (by lia), hf] simp) +lemma toSingleMk_postcomp {p q : ℤ} (f : K.X p ⟶ X) {n : ℤ} (h : p + n = q) + (p' : ℤ) (hp' : p' + 1 = p) (hf : K.d p' p ≫ f = 0) {X' : C} (g : X ⟶ X') : + toSingleMk (f ≫ g) h p' hp' (by simp [reassoc_of% hf]) = + (toSingleMk f h p' hp' hf).postcomp ((singleFunctor C q).map g) := by + ext : 1 + exact (Cochain.toSingleEquiv h).injective (by simp [Cochain.toSingleMk_postcomp]) + lemma toSingleMk_surjective {q n : ℤ} (α : Cocycle K ((singleFunctor C q).obj X) n) (p : ℤ) (h : p + n = q) (p' : ℤ) (hp' : p' + 1 = p) : ∃ (f : K.X p ⟶ X) (hf : K.d p' p ≫ f = 0), toSingleMk f h p' hp' hf = α := by diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index fa8248caf7e5a9..d2fb3c608e9c45 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -20,7 +20,6 @@ we provide an API in order to construct elements in `Ext X Y n` in terms of the complex `R.cocomplex` and to make computations in the `Ext`-group. ## TODO -* Functoriality in `X` for a given injective resolution `R` * Functoriality in `Y`: this would involve a morphism `Y ⟶ Y'`, injective resolutions `R` and `R'` of `Y` and `Y'`, a lift of `Y ⟶ Y'` as a morphism of cochain complexes `R.cocomplex ⟶ R'.cocomplex`; in this context, diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean index 256179cd70d501..e04c0dada41ca0 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean @@ -20,7 +20,6 @@ we provide an API in order to construct elements in `Ext X Y n` in terms of the complex `R.complex` and to make computations in the `Ext`-group. ## TODO -* Functoriality in `Y` for a given projective resolution `R` * Functoriality in `X`: this would involve a morphism `X ⟶ X'`, projective resolutions `R` and `R'` of `X` and `X'`, a lift of `X ⟶ X'` as a morphism of cochain complexes `R.complex ⟶ R'.complex`; in this context, @@ -200,4 +199,21 @@ lemma extMk_surjective (α : Ext X Y n) (m : ℕ) (hm : n + 1 = m) : rw [← cancel_epi (R.cochainComplexXIso (-m) m rfl).hom] simpa [R.cochainComplex_d _ _ _ _ rfl rfl] using hf +lemma extMk_comp_mk₀ {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 = m) + (hf : R.complex.d m n ≫ f = 0) {Y' : C} (g : Y ⟶ Y') : + (R.extMk f m hm hf).comp (Ext.mk₀ g) (add_zero _) = + R.extMk (f ≫ g) m hm (by simp [reassoc_of% hf]) := by + have := HasDerivedCategory.standard C + ext + simp only [extMk, Ext.comp_hom, Int.cast_ofNat_Int, Ext.mk₀_hom, + extEquivCohomologyClass_symm_mk_hom] + simp only [← Category.assoc] + rw [Cocycle.toSingleMk_postcomp _ _ _ _ + (by simpa [cochainComplex_d _ _ _ m n rfl rfl]) g, + Cocycle.equivHomShift_symm_postcomp, + ← ShiftedHom.comp_mk₀ _ 0 rfl, + ShiftedHom.map_comp, ShiftedHom.map_mk₀, + ShiftedHom.comp_assoc _ _ _ (add_zero _) (zero_add _) (by simp)] + rfl + end CategoryTheory.ProjectiveResolution From 72ae66c6ebf2137197d1ee29364a5eb8d6f9347b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 3 Jan 2026 14:51:59 +0100 Subject: [PATCH 60/60] suggestion by robin-carlier --- .../CategoryTheory/Abelian/Injective/Ext.lean | 20 ++++++++++++------ .../Abelian/Projective/Ext.lean | 21 ++++++++++++++----- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean index d2fb3c608e9c45..ef434a7b9ea62f 100644 --- a/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Injective/Ext.lean @@ -53,10 +53,17 @@ noncomputable def extEquivCohomologyClass : lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] (x : Cocycle ((singleFunctor C 0).obj X) R.cochainComplex n) : (R.extEquivCohomologyClass.symm (.mk x)).hom = - (ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q).comp - (.mk₀ _ rfl (inv (DerivedCategory.Q.map R.ι'))) (zero_add _) := by + (ShiftedHom.mk₀ _ rfl ((DerivedCategory.singleFunctorIsoCompQ C 0).hom.app X)).comp + ((ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q).comp + (.mk₀ _ rfl (inv (DerivedCategory.Q.map R.ι') ≫ + (DerivedCategory.singleFunctorIsoCompQ C 0).inv.app Y)) (zero_add _)) (add_zero _) := by change SmallShiftedHom.equiv _ _ ((CohomologyClass.mk x).toSmallShiftedHom.comp _ _) = _ - simp [SmallShiftedHom.equiv_comp, isoOfHom] + simp only [SmallShiftedHom.equiv_comp, CohomologyClass.equiv_toSmallShiftedHom_mk, + SmallShiftedHom.equiv_mk₀Inv, isoOfHom, asIso_inv, Functor.comp_obj, + DerivedCategory.singleFunctorIsoCompQ, Iso.refl_hom, NatTrans.id_app, Iso.refl_inv, + ShiftedHom.mk₀_id_comp] + congr + cat_disch @[simp] lemma extEquivCohomologyClass_symm_add @@ -210,8 +217,9 @@ lemma mk₀_comp_extMk {n : ℕ} (f : X ⟶ R.cocomplex.X n) (m : ℕ) (hm : n + rw [Cocycle.fromSingleMk_precomp g _ (zero_add _) _ (by lia) (by simp [cochainComplex_d _ _ _ n m rfl rfl, reassoc_of% hf]), Cocycle.equivHomShift_symm_precomp, ← ShiftedHom.mk₀_comp 0 rfl, - ShiftedHom.map_comp, ShiftedHom.map_mk₀, - ShiftedHom.comp_assoc _ _ _ (add_zero _) (zero_add _) (by simp)] - rfl + ShiftedHom.map_comp, + ShiftedHom.comp_assoc _ _ _ (add_zero _) (zero_add _) (by simp), + ← ShiftedHom.comp_assoc _ _ _ (add_zero _) (add_zero (n : ℤ)) (by simp)] + simp end CategoryTheory.InjectiveResolution diff --git a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean index e04c0dada41ca0..2fcdd31f2986e6 100644 --- a/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean +++ b/Mathlib/CategoryTheory/Abelian/Projective/Ext.lean @@ -53,10 +53,18 @@ noncomputable def extEquivCohomologyClass : lemma extEquivCohomologyClass_symm_mk_hom [HasDerivedCategory C] (x : Cocycle R.cochainComplex ((singleFunctor C 0).obj Y) n) : (R.extEquivCohomologyClass.symm (.mk x)).hom = - (ShiftedHom.mk₀ _ rfl (inv (DerivedCategory.Q.map R.π'))).comp - (ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q) (add_zero _) := by + (ShiftedHom.mk₀ _ rfl ((DerivedCategory.singleFunctorIsoCompQ C 0).hom.app X ≫ + inv (DerivedCategory.Q.map R.π'))).comp + ((ShiftedHom.map (Cocycle.equivHomShift.symm x) DerivedCategory.Q).comp + (.mk₀ _ rfl ((DerivedCategory.singleFunctorIsoCompQ C 0).inv.app Y)) + (zero_add _)) (add_zero _) := by change SmallShiftedHom.equiv _ _ (.comp _ (CohomologyClass.mk x).toSmallShiftedHom _) = _ - simp [SmallShiftedHom.equiv_comp, isoOfHom] + simp only [SmallShiftedHom.equiv_comp, SmallShiftedHom.equiv_mk₀Inv, isoOfHom, asIso_inv, + CohomologyClass.equiv_toSmallShiftedHom_mk, Functor.comp_obj, + DerivedCategory.singleFunctorIsoCompQ, Iso.refl_hom, NatTrans.id_app, Category.id_comp, + Iso.refl_inv] + congr + exact (ShiftedHom.comp_mk₀_id ..).symm @[simp] lemma extEquivCohomologyClass_symm_add @@ -213,7 +221,10 @@ lemma extMk_comp_mk₀ {n : ℕ} (f : R.complex.X n ⟶ Y) (m : ℕ) (hm : n + 1 Cocycle.equivHomShift_symm_postcomp, ← ShiftedHom.comp_mk₀ _ 0 rfl, ShiftedHom.map_comp, ShiftedHom.map_mk₀, - ShiftedHom.comp_assoc _ _ _ (add_zero _) (zero_add _) (by simp)] - rfl + ShiftedHom.comp_assoc _ _ _ (add_zero _) (zero_add _) (by simp), + ShiftedHom.comp_assoc _ _ _ (zero_add _) (zero_add _) (by simp), + ShiftedHom.comp_assoc _ _ _ (zero_add _) (zero_add _) (by simp), + ShiftedHom.mk₀_comp_mk₀, ShiftedHom.mk₀_comp_mk₀, ← NatTrans.naturality] + dsimp end CategoryTheory.ProjectiveResolution