From b11f8815827cfa37a45c8896bbd3c78d75c6ce82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 11 Jan 2026 16:35:06 +0100 Subject: [PATCH 01/72] feat(Algebra/Homology): spectral sequences --- Mathlib.lean | 16 + Mathlib/Algebra/Homology/ExactSequence.lean | 13 + .../Algebra/Homology/ExactSequenceFour.lean | 222 +++++ .../Homology/ShortComplex/Abelian.lean | 170 +++- .../Algebra/Homology/ShortComplex/Basic.lean | 8 +- .../Algebra/Homology/ShortComplex/Exact.lean | 46 +- .../Homology/ShortComplex/Homology.lean | 6 + .../Homology/ShortComplex/LeftHomology.lean | 19 + .../Homology/ShortComplex/RightHomology.lean | 20 + .../Homology/SpectralObject/Basic.lean | 235 +++++ .../Homology/SpectralObject/Cycles.lean | 501 ++++++++++ .../SpectralObject/Differentials.lean | 255 +++++ .../SpectralObject/HasSpectralSequence.lean | 462 ++++++++++ .../Homology/SpectralObject/Homology.lean | 244 +++++ .../Algebra/Homology/SpectralObject/Page.lean | 871 ++++++++++++++++++ .../Homology/SpectralSequence/Basic.lean | 137 +++ .../SpectralSequence/ComplexShape.lean | 54 ++ Mathlib/CategoryTheory/Category/Preorder.lean | 14 + .../ComposableArrows/Basic.lean | 87 +- .../CategoryTheory/ComposableArrows/Four.lean | 148 +++ .../ComposableArrows/Three.lean | 120 +++ .../CategoryTheory/ComposableArrows/Two.lean | 48 +- .../Limits/Shapes/Equalizers.lean | 7 +- .../ObjectProperty/ContainsZero.lean | 40 +- .../ObjectProperty/FullSubcategory.lean | 7 + .../CategoryTheory/ObjectProperty/Shift.lean | 10 +- Mathlib/CategoryTheory/Shift/CommShift.lean | 273 +++++- .../CategoryTheory/Triangulated/Basic.lean | 81 +- .../CategoryTheory/Triangulated/Functor.lean | 71 +- .../Triangulated/Pretriangulated.lean | 89 +- .../Triangulated/Subcategory.lean | 344 ++++++- .../Triangulated/TStructure/Basic.lean | 49 +- .../Triangulated/TStructure/ETrunc.lean | 539 +++++++++++ .../Triangulated/TStructure/Induced.lean | 148 +++ .../TStructure/SpectralObject.lean | 177 ++++ .../Triangulated/TStructure/TruncLEGT.lean | 396 ++++++++ .../Triangulated/TStructure/TruncLTGE.lean | 631 ++++++++++++- Mathlib/Data/EInt/Basic.lean | 93 ++ 38 files changed, 6577 insertions(+), 74 deletions(-) create mode 100644 Mathlib/Algebra/Homology/ExactSequenceFour.lean create mode 100644 Mathlib/Algebra/Homology/SpectralObject/Basic.lean create mode 100644 Mathlib/Algebra/Homology/SpectralObject/Cycles.lean create mode 100644 Mathlib/Algebra/Homology/SpectralObject/Differentials.lean create mode 100644 Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean create mode 100644 Mathlib/Algebra/Homology/SpectralObject/Homology.lean create mode 100644 Mathlib/Algebra/Homology/SpectralObject/Page.lean create mode 100644 Mathlib/Algebra/Homology/SpectralSequence/Basic.lean create mode 100644 Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean create mode 100644 Mathlib/CategoryTheory/ComposableArrows/Four.lean create mode 100644 Mathlib/CategoryTheory/ComposableArrows/Three.lean create mode 100644 Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean create mode 100644 Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean create mode 100644 Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean create mode 100644 Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean create mode 100644 Mathlib/Data/EInt/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index aec76ebc1b2eac..ad9530bcac3a23 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -578,6 +578,7 @@ public import Mathlib.Algebra.Homology.Embedding.TruncGEHomology public import Mathlib.Algebra.Homology.Embedding.TruncLE public import Mathlib.Algebra.Homology.Embedding.TruncLEHomology public import Mathlib.Algebra.Homology.ExactSequence +public import Mathlib.Algebra.Homology.ExactSequenceFour public import Mathlib.Algebra.Homology.Factorizations.Basic public import Mathlib.Algebra.Homology.Factorizations.CM5b public import Mathlib.Algebra.Homology.Functor @@ -644,6 +645,14 @@ public import Mathlib.Algebra.Homology.ShortComplex.ShortExact public import Mathlib.Algebra.Homology.ShortComplex.SnakeLemma public import Mathlib.Algebra.Homology.Single public import Mathlib.Algebra.Homology.SingleHomology +public import Mathlib.Algebra.Homology.SpectralObject.Basic +public import Mathlib.Algebra.Homology.SpectralObject.Cycles +public import Mathlib.Algebra.Homology.SpectralObject.Differentials +public import Mathlib.Algebra.Homology.SpectralObject.HasSpectralSequence +public import Mathlib.Algebra.Homology.SpectralObject.Homology +public import Mathlib.Algebra.Homology.SpectralObject.Page +public import Mathlib.Algebra.Homology.SpectralSequence.Basic +public import Mathlib.Algebra.Homology.SpectralSequence.ComplexShape public import Mathlib.Algebra.Homology.Square public import Mathlib.Algebra.Homology.TotalComplex public import Mathlib.Algebra.Homology.TotalComplexShift @@ -2379,7 +2388,9 @@ public import Mathlib.CategoryTheory.Comma.StructuredArrow.Final public import Mathlib.CategoryTheory.Comma.StructuredArrow.Functor public import Mathlib.CategoryTheory.Comma.StructuredArrow.Small public import Mathlib.CategoryTheory.ComposableArrows.Basic +public import Mathlib.CategoryTheory.ComposableArrows.Four public import Mathlib.CategoryTheory.ComposableArrows.One +public import Mathlib.CategoryTheory.ComposableArrows.Three public import Mathlib.CategoryTheory.ComposableArrows.Two public import Mathlib.CategoryTheory.ConcreteCategory.Basic public import Mathlib.CategoryTheory.ConcreteCategory.Bundled @@ -3152,6 +3163,10 @@ public import Mathlib.CategoryTheory.Triangulated.Rotate public import Mathlib.CategoryTheory.Triangulated.SpectralObject public import Mathlib.CategoryTheory.Triangulated.Subcategory public import Mathlib.CategoryTheory.Triangulated.TStructure.Basic +public import Mathlib.CategoryTheory.Triangulated.TStructure.ETrunc +public import Mathlib.CategoryTheory.Triangulated.TStructure.Induced +public import Mathlib.CategoryTheory.Triangulated.TStructure.SpectralObject +public import Mathlib.CategoryTheory.Triangulated.TStructure.TruncLEGT public import Mathlib.CategoryTheory.Triangulated.TStructure.TruncLTGE public import Mathlib.CategoryTheory.Triangulated.TriangleShift public import Mathlib.CategoryTheory.Triangulated.Triangulated @@ -3455,6 +3470,7 @@ public import Mathlib.Data.DFinsupp.Small public import Mathlib.Data.DFinsupp.Submonoid public import Mathlib.Data.DFinsupp.WellFounded public import Mathlib.Data.DList.Instances +public import Mathlib.Data.EInt.Basic public import Mathlib.Data.ENNReal.Action public import Mathlib.Data.ENNReal.Basic public import Mathlib.Data.ENNReal.BigOperators diff --git a/Mathlib/Algebra/Homology/ExactSequence.lean b/Mathlib/Algebra/Homology/ExactSequence.lean index b0081ee5fef5c5..f23298d04ad5d6 100644 --- a/Mathlib/Algebra/Homology/ExactSequence.lean +++ b/Mathlib/Algebra/Homology/ExactSequence.lean @@ -136,6 +136,19 @@ lemma Exact.exact' (hS : S.Exact) (i j k : ℕ) (hij : i + 1 = j := by omega) subst hij hjk exact hS.exact i hk +/-- The (exact) short complex consisting of maps `S.map' i j` and `S.map' j k` when we know +that `S : ComposableArrows C n` is exact. -/ +abbrev Exact.sc' (hS : S.Exact) (i j k : ℕ) (hij : i + 1 = j := by lia) + (hjk : j + 1 = k := by lia) (hk : k ≤ n := by lia) : + ShortComplex C := + S.sc' hS.toIsComplex i j k + +/-- The short complex consisting of maps `S.map' i (i + 1)` and `S.map' (i + 1) (i + 2)` +when we know that `S : ComposableArrows C n` is exact. -/ +abbrev Exact.sc (hS : S.Exact) (i : ℕ) (hi : i + 2 ≤ n := by lia) : + ShortComplex C := + S.sc' hS.toIsComplex i (i + 1) (i + 2) + /-- Functoriality maps for `ComposableArrows.sc'`. -/ @[simps] def sc'Map {S₁ S₂ : ComposableArrows C n} (φ : S₁ ⟶ S₂) (h₁ : S₁.IsComplex) (h₂ : S₂.IsComplex) diff --git a/Mathlib/Algebra/Homology/ExactSequenceFour.lean b/Mathlib/Algebra/Homology/ExactSequenceFour.lean new file mode 100644 index 00000000000000..d8cc3d2c0f89db --- /dev/null +++ b/Mathlib/Algebra/Homology/ExactSequenceFour.lean @@ -0,0 +1,222 @@ +/- +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.ExactSequence + +/-! +# Exact sequences with four terms + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits + +namespace ComposableArrows + +section HasZeroMorphisms + +namespace IsComplex + +variable {C : Type*} [Category C] [HasZeroMorphisms C] {n : ℕ} {S : ComposableArrows C (n + 3)} + (hS : S.IsComplex) (k : ℕ) + +section + +/-- Generalization of `cokerToKer`. -/ +def cokerToKer' (hk : k ≤ n) (cc : CokernelCofork (S.map' k (k + 1))) + (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) : + cc.pt ⟶ kf.pt := + IsColimit.desc hcc (CokernelCofork.ofπ _ + (show S.map' k (k + 1) ≫ IsLimit.lift hkf (KernelFork.ofι _ (hS.zero (k + 1))) = _ from + Fork.IsLimit.hom_ext hkf (by simpa using hS.zero k))) + +@[reassoc (attr := simp)] +lemma cokerToKer'_fac (hk : k ≤ n) (cc : CokernelCofork (S.map' k (k + 1))) + (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) : + cc.π ≫ hS.cokerToKer' k hk cc kf hcc hkf ≫ kf.ι = + S.map' (k + 1) (k + 2) := by + simp [cokerToKer'] + +end + +section + +noncomputable def cokerToKer (hk : k ≤ n := by lia) + [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : + cokernel (S.map' k (k + 1)) ⟶ kernel (S.map' (k + 2) (k + 3)) := + hS.cokerToKer' k hk (CokernelCofork.ofπ _ (cokernel.condition _)) + (KernelFork.ofι _ (kernel.condition _)) (cokernelIsCokernel _) (kernelIsKernel _) + +@[reassoc (attr := simp)] +lemma cokerToKer_fac (hk : k ≤ n := by lia) + [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : + cokernel.π _ ≫ hS.cokerToKer k hk ≫ kernel.ι _ = S.map' (k + 1) (k + 2) := + hS.cokerToKer'_fac k hk _ _ (cokernelIsCokernel _) (kernelIsKernel _) + +end + +section + +noncomputable def opcyclesToCycles (hk : k ≤ n := by lia) + [(S.sc hS k).HasRightHomology] [(S.sc hS (k + 1)).HasLeftHomology] : + (S.sc hS k _).opcycles ⟶ (S.sc hS (k + 1) _).cycles := + hS.cokerToKer' k hk _ _ (S.sc hS k _).opcyclesIsCokernel + (S.sc hS (k + 1) _).cyclesIsKernel + +@[reassoc (attr := simp)] +lemma opcyclesToCycles_fac (hk : k ≤ n := by lia) + [(S.sc hS k).HasRightHomology] [(S.sc hS (k + 1)).HasLeftHomology] : + (S.sc hS k _).pOpcycles ≫ hS.opcyclesToCycles k ≫ (S.sc hS (k + 1) _).iCycles = + S.map' (k + 1) (k + 2) := + hS.cokerToKer'_fac k hk _ _ (S.sc hS k _).opcyclesIsCokernel + (S.sc hS (k + 1) _).cyclesIsKernel + +end + +end IsComplex + +end HasZeroMorphisms + +section Preadditive + +variable {C : Type*} [Category C] [Preadditive C] {n : ℕ} {S : ComposableArrows C (n + 3)} + +namespace IsComplex + +variable (hS : S.IsComplex) (k : ℕ) (hk : k ≤ n) + (cc : CokernelCofork (S.map' k (k + 1))) (kf : KernelFork (S.map' (k + 2) (k + 3))) + (hcc : IsColimit cc) (hkf : IsLimit kf) + +/-- `cokerToKer'` is an epi. -/ +lemma epi_cokerToKer' (hS' : (S.sc hS (k + 1)).Exact) : + Epi (hS.cokerToKer' k hk cc kf hcc hkf) := by + have := hS'.hasZeroObject + have := hS'.hasHomology + have : Epi cc.π := ⟨fun _ _ => Cofork.IsColimit.hom_ext hcc⟩ + let h := hS'.leftHomologyDataOfIsLimitKernelFork kf hkf + have := h.exact_iff_epi_f'.1 hS' + have fac : cc.π ≫ hS.cokerToKer' k hk cc kf hcc hkf = h.f' := by + rw [← cancel_mono h.i, h.f'_i, ShortComplex.Exact.leftHomologyDataOfIsLimitKernelFork_i, + assoc, IsComplex.cokerToKer'_fac] + exact epi_of_epi_fac fac + +/-- `cokerToKer'` is a mono. -/ +lemma mono_cokerToKer' (hS' : (S.sc hS k).Exact) : + Mono (hS.cokerToKer' k hk cc kf hcc hkf) := by + have := hS'.hasZeroObject + have := hS'.hasHomology + have : Mono kf.ι := ⟨fun _ _ => Fork.IsLimit.hom_ext hkf⟩ + let h := hS'.rightHomologyDataOfIsColimitCokernelCofork cc hcc + have := h.exact_iff_mono_g'.1 hS' + have fac : hS.cokerToKer' k hk cc kf hcc hkf ≫ kf.ι = h.g' := by + rw [← cancel_epi h.p, h.p_g', ShortComplex.Exact.rightHomologyDataOfIsColimitCokernelCofork_p, + cokerToKer'_fac] + exact mono_of_mono_fac fac + +end IsComplex + +end Preadditive + +section Balanced + +variable {C : Type*} [Category C] [Preadditive C] [Balanced C] {n : ℕ} + {S : ComposableArrows C (n + 3)} (hS : S.Exact) + +namespace Exact + +section + +variable (k : ℕ) (hk : k ≤ n) + (cc : CokernelCofork (S.map' k (k + 1))) (kf : KernelFork (S.map' (k + 2) (k + 3))) + (hcc : IsColimit cc) (hkf : IsLimit kf) + +/-- Auxiliary definition for `cokerIsoKer'`. -/ +def cokerToKer' : cc.pt ⟶ kf.pt := + hS.toIsComplex.cokerToKer' k hk cc kf hcc hkf + +omit [Balanced C] in +@[reassoc (attr := simp)] +lemma cokerToKer'_fac : cc.π ≫ hS.cokerToKer' k hk cc kf hcc hkf ≫ kf.ι = + S.map' (k + 1) (k + 2) := by + simp [cokerToKer'] + +/-- `cokerToKer'` is an isomorphism. -/ +instance isIso_cokerToKer' : IsIso (hS.cokerToKer' k hk cc kf hcc hkf) := by + have : Mono (hS.cokerToKer' k hk cc kf hcc hkf) := + hS.toIsComplex.mono_cokerToKer' k hk cc kf hcc hkf + (hS.exact k) + have : Epi (hS.cokerToKer' k hk cc kf hcc hkf) := + hS.epi_cokerToKer' k hk cc kf hcc hkf (hS.exact (k + 1)) + apply isIso_of_mono_of_epi + +/-- Auxiliary definition for `cokerIsoKer`. -/ +@[simps! hom] +noncomputable def cokerIsoKer' : cc.pt ≅ kf.pt := + asIso (hS.cokerToKer' k hk cc kf hcc hkf) + +@[reassoc (attr := simp)] +lemma cokerIsoKer'_hom_inv_id : + hS.cokerToKer' k hk cc kf hcc hkf ≫ (hS.cokerIsoKer' k hk cc kf hcc hkf).inv = 𝟙 _ := + (hS.cokerIsoKer' k hk cc kf hcc hkf).hom_inv_id + +@[reassoc (attr := simp)] +lemma cokerIsoKer'_inv_hom_id : + (hS.cokerIsoKer' k hk cc kf hcc hkf).inv ≫ hS.cokerToKer' k hk cc kf hcc hkf = 𝟙 _ := + (hS.cokerIsoKer' k hk cc kf hcc hkf).inv_hom_id + +end + +section + +noncomputable def cokerIsoKer (k : ℕ) (hk : k ≤ n := by lia) + [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : + cokernel (S.map' k (k + 1) _ _) ≅ kernel (S.map' (k + 2) (k + 3) _ _) := + hS.cokerIsoKer' k hk (CokernelCofork.ofπ _ (cokernel.condition _)) + (KernelFork.ofι _ (kernel.condition _)) (cokernelIsCokernel _) (kernelIsKernel _) + +lemma cokerIsoKer_hom (k : ℕ) (hk : k ≤ n := by lia) + [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : + (hS.cokerIsoKer k).hom = hS.toIsComplex.cokerToKer k := rfl + +@[reassoc (attr := simp)] +lemma cokerIsoKer_hom_fac (k : ℕ) (hk : k ≤ n := by lia) + [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : + cokernel.π _ ≫ (hS.cokerIsoKer k).hom ≫ kernel.ι _ = S.map' (k + 1) (k + 2) := by + rw [hS.cokerIsoKer_hom k, hS.toIsComplex.cokerToKer_fac k] + +end + +section + +noncomputable def opcyclesIsoCycles (k : ℕ) (hk : k ≤ n := by lia) + [h₁ : (hS.sc k).HasRightHomology] [h₂ : (hS.sc (k + 1)).HasLeftHomology] : + (hS.sc k _).opcycles ≅ (hS.sc (k + 1) _).cycles := + hS.cokerIsoKer' k hk _ _ (hS.sc k _).opcyclesIsCokernel (hS.sc (k + 1) _).cyclesIsKernel + +lemma opcyclesIsoCycles_hom (k : ℕ) (hk : k ≤ n := by lia) + [h₁ : (hS.sc k).HasRightHomology] [h₂ : (hS.sc (k + 1)).HasLeftHomology] : + (hS.opcyclesIsoCycles k).hom = hS.toIsComplex.opcyclesToCycles k hk := rfl + +@[reassoc (attr := simp)] +lemma opcyclesIsoCycles_hom_fac (k : ℕ) (hk : k ≤ n := by lia) + [h₁ : (hS.sc k).HasRightHomology] [h₂ : (hS.sc (k + 1)).HasLeftHomology] : + (hS.sc k _).pOpcycles ≫ (hS.opcyclesIsoCycles k).hom ≫ (hS.sc (k + 1) _).iCycles = + S.map' (k + 1) (k + 2) := + hS.toIsComplex.opcyclesToCycles_fac k hk + +end + +end Exact + +end Balanced + +end ComposableArrows + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean b/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean index 56759f82a449c4..7baff2279806bd 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean @@ -6,7 +6,10 @@ Authors: Joël Riou module public import Mathlib.Algebra.Homology.ShortComplex.Homology +public import Mathlib.Algebra.Homology.ShortComplex.Limits +public import Mathlib.Algebra.Homology.ShortComplex.Preadditive public import Mathlib.CategoryTheory.Abelian.Basic +public import Batteries.Tactic.Lint /-! # Abelian categories have homology @@ -24,17 +27,23 @@ these left and right homology data are compatible (i.e. provide a `HomologyData`) is obtained by using the coimage-image isomorphism in abelian categories. +We also provide a constructor `HomologyData.ofEpiMonoFactorisation` +which takes as an input an epi-mono factorization `kf.pt ⟶ H ⟶ cc.pt` +of `kf.ι ≫ cc.π` where `kf` is a limit kernel fork of `S.g` and +`cc` is a limit cokernel cofork of `S.f`. + -/ @[expose] public section -universe v u +universe v v' u u' namespace CategoryTheory open Category Limits variable {C : Type u} [Category.{v} C] [Abelian C] (S : ShortComplex C) + {D : Type u'} [Category.{v'} D] [HasZeroMorphisms D] namespace ShortComplex @@ -185,6 +194,165 @@ instance _root_.CategoryTheory.categoryWithHomology_of_abelian : CategoryWithHomology C where hasHomology S := HasHomology.mk' (HomologyData.ofAbelian S) +noncomputable instance : IsNormalMonoCategory (ShortComplex C) := ⟨fun i _ => ⟨by + refine NormalMono.mk _ (cokernel.π i) (cokernel.condition _) + (isLimitOfIsLimitπ _ ?_ ?_ ?_) + all_goals apply Abelian.isLimitMapConeOfKernelForkOfι⟩⟩ + +noncomputable instance : IsNormalEpiCategory (ShortComplex C) := ⟨fun p _ => ⟨by + refine NormalEpi.mk _ (kernel.ι p) (kernel.condition _) + (isColimitOfIsColimitπ _ ?_ ?_ ?_) + all_goals apply Abelian.isColimitMapCoconeOfCokernelCoforkOfπ⟩⟩ + +noncomputable instance : Abelian (ShortComplex C) where + +attribute [local instance] strongEpi_of_epi + +/-- The homology of a short complex `S` in an abelian category identifies to +the image of `S.iCycles ≫ S.pOpcycles : S.cycles ⟶ S.opcycles`. -/ +noncomputable def homologyIsoImageICyclesCompPOpcycles : + S.homology ≅ image (S.iCycles ≫ S.pOpcycles) := + image.isoStrongEpiMono _ _ S.homology_π_ι + +@[reassoc (attr := simp)] +lemma homologyIsoImageICyclesCompPOpcycles_ι : + S.homologyIsoImageICyclesCompPOpcycles.hom ≫ image.ι (S.iCycles ≫ S.pOpcycles) = + S.homologyι := + image.isoStrongEpiMono_hom_comp_ι _ _ _ + +namespace HomologyData + +namespace ofEpiMonoFactorisation + +variable {kf : KernelFork S.g} {cc : CokernelCofork S.f} + (hkf : IsLimit kf) (hcc : IsColimit cc) + {H : C} {π : kf.pt ⟶ H} {ι : H ⟶ cc.pt} + (fac : kf.ι ≫ cc.π = π ≫ ι) + [Epi π] [Mono ι] + +/-- Let `S` be a short complex in an abelian category. Let `kf` be a +limit kernel fork of `S.g` and `cc` a limit cokernel cofork of `S.f`. +Let `kf.pt ⟶ H ⟶ cc.pt` be an epi-mono factorization of `kf.ι ≫ cc.π : kf.pt ⟶ cc.pt`, +then `H` identifies to the image of `S.iCycles ≫ S.pOpcycles : S.cycles ⟶ S.opcycles`. -/ +noncomputable def isoImage : H ≅ image (S.iCycles ≫ S.pOpcycles) := by + have : ((S.isoCyclesOfIsLimit hkf).inv ≫ π) ≫ ι ≫ + (S.isoOpcyclesOfIsColimit hcc).hom = S.iCycles ≫ S.pOpcycles := by + simp [← reassoc_of% fac] + exact image.isoStrongEpiMono _ _ this + +@[reassoc (attr := simp)] +lemma isoImage_ι : + (isoImage S hkf hcc fac).hom ≫ image.ι (S.iCycles ≫ S.pOpcycles) = + ι ≫ (S.isoOpcyclesOfIsColimit hcc).hom := by + apply image.isoStrongEpiMono_hom_comp_ι + simp [← reassoc_of% fac] + +/-- Let `S` be a short complex in an abelian category. Let `kf` be a +limit kernel fork of `S.g` and `cc` a limit cokernel cofork of `S.f`. +Let `kf.pt ⟶ H ⟶ cc.pt` be an epi-mono factorization of `kf.ι ≫ cc.π : kf.pt ⟶ cc.pt`, +then `H` identifies to the homology of `S`. -/ +noncomputable def isoHomology : H ≅ S.homology := + isoImage S hkf hcc fac ≪≫ S.homologyIsoImageICyclesCompPOpcycles.symm + +@[reassoc (attr := simp)] +lemma π_comp_isoHomology_hom : + π ≫ (isoHomology S hkf hcc fac).hom = (S.isoCyclesOfIsLimit hkf).hom ≫ S.homologyπ := by + dsimp [isoHomology] + simp [← cancel_mono (S.homologyIsoImageICyclesCompPOpcycles.hom), + ← cancel_mono (image.ι (S.iCycles ≫ S.pOpcycles)), + ← reassoc_of% fac] + +@[reassoc (attr := simp)] +lemma isoHomology_hom_comp_ι : + (isoHomology S hkf hcc fac).inv ≫ ι = S.homologyι ≫ (S.isoOpcyclesOfIsColimit hcc).inv := by + simp [← cancel_epi S.homologyπ, ← cancel_epi (S.isoCyclesOfIsLimit hkf).hom, + ← π_comp_isoHomology_hom_assoc S hkf hcc fac, ← fac] + +lemma f'_eq : + hkf.lift (KernelFork.ofι S.f S.zero) = + S.toCycles ≫ (S.isoCyclesOfIsLimit hkf).inv := by + have := Fork.IsLimit.mono hkf + simp [← cancel_mono kf.ι] + +lemma g'_eq : hcc.desc (CokernelCofork.ofπ S.g S.zero) = + (S.isoOpcyclesOfIsColimit hcc).hom ≫ S.fromOpcycles := by + have := Cofork.IsColimit.epi hcc + simp [← cancel_epi cc.π] + +@[reassoc (attr := simp)] +lemma homologyπ_isoHomology_inv : + S.homologyπ ≫ (isoHomology S hkf hcc fac).inv = (S.isoCyclesOfIsLimit hkf).inv ≫ π := by + simp only [← cancel_mono (isoHomology S hkf hcc fac).hom, assoc, Iso.inv_hom_id, comp_id, + π_comp_isoHomology_hom, Iso.inv_hom_id_assoc] + +@[reassoc (attr := simp)] +lemma isoHomology_inv_homologyι : + (isoHomology S hkf hcc fac).hom ≫ S.homologyι = + ι ≫ (S.isoOpcyclesOfIsColimit hcc).hom := by + rw [← cancel_mono (S.isoOpcyclesOfIsColimit hcc).inv, assoc, assoc, Iso.hom_inv_id, + comp_id, ← isoHomology_hom_comp_ι S hkf hcc fac, Iso.hom_inv_id_assoc] + +/-- Let `S` be a short complex in an abelian category. Let `kf` be a +limit kernel fork of `S.g` and `cc` a limit cokernel cofork of `S.f`. +Let `kf.pt ⟶ H ⟶ cc.pt` be an epi-mono factorization of `kf.ι ≫ cc.π : kf.pt ⟶ cc.pt`. +This is the left homology data expressing `H` as the homology of `S`. -/ +@[simps] +noncomputable def leftHomologyData : S.LeftHomologyData where + K := kf.pt + H := H + i := kf.ι + π := π + wi := KernelFork.condition kf + hi := IsLimit.ofIsoLimit hkf (Fork.ext (Iso.refl _) (by simp)) + wπ := by + dsimp + rw [← cancel_mono (isoHomology S hkf hcc fac).hom, assoc, assoc, id_comp, + π_comp_isoHomology_hom, zero_comp, f'_eq, + assoc, Iso.inv_hom_id_assoc, toCycles_comp_homologyπ] + hπ := by + refine (IsColimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 S.homologyIsCokernel + · exact parallelPair.ext (Iso.refl _) (S.isoCyclesOfIsLimit hkf) + · exact Cofork.ext (isoHomology S hkf hcc fac) (by simp [Cofork.π]) + +attribute [local simp] g'_eq in +/-- Let `S` be a short complex in an abelian category. Let `kf` be a +limit kernel fork of `S.g` and `cc` a limit cokernel cofork of `S.f`. +Let `kf.pt ⟶ H ⟶ cc.pt` be an epi-mono factorization of `kf.ι ≫ cc.π : kf.pt ⟶ cc.pt`. +This is the right homology data expressing `H` as the homology of `S`. -/ +@[simps] +noncomputable def rightHomologyData : S.RightHomologyData where + Q := cc.pt + H := H + p := cc.π + ι := ι + wp := CokernelCofork.condition cc + hp := IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl _) (by simp)) + wι := by + dsimp + rw [id_comp, g'_eq, ← cancel_epi (isoHomology S hkf hcc fac).inv, comp_zero, + isoHomology_hom_comp_ι_assoc, Iso.inv_hom_id_assoc, homologyι_comp_fromOpcycles] + hι := by + refine (IsLimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 S.homologyIsKernel + · exact parallelPair.ext (S.isoOpcyclesOfIsColimit hcc) (Iso.refl _) + · exact Fork.ext (isoHomology S hkf hcc fac) (by simp [Fork.ι]) + +end ofEpiMonoFactorisation + +/-- Let `S` be a short complex in an abelian category. Let `kf` be a +limit kernel fork of `S.g` and `cc` a limit cokernel cofork of `S.f`. +Let `kf.pt ⟶ H ⟶ cc.pt` be an epi-mono factorization of `kf.ι ≫ cc.π : kf.pt ⟶ cc.pt`. +This is the homology data expressing `H` as the homology of `S`. -/ +@[simps] +noncomputable def ofEpiMonoFactorisation {kf : KernelFork S.g} {cc : CokernelCofork S.f} + (hkf : IsLimit kf) (hcc : IsColimit cc) {H : C} {π : kf.pt ⟶ H} {ι : H ⟶ cc.pt} + (fac : kf.ι ≫ cc.π = π ≫ ι) [Epi π] [Mono ι] : + S.HomologyData where + left := ofEpiMonoFactorisation.leftHomologyData S hkf hcc fac + right := ofEpiMonoFactorisation.rightHomologyData S hkf hcc fac + iso := Iso.refl _ + +end HomologyData + end ShortComplex end CategoryTheory diff --git a/Mathlib/Algebra/Homology/ShortComplex/Basic.lean b/Mathlib/Algebra/Homology/ShortComplex/Basic.lean index 20a2324b2ee0e1..98dc3003d70129 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Basic.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Basic.lean @@ -43,7 +43,7 @@ structure ShortComplex where /-- the second morphism of a `ShortComplex` -/ g : X₂ ⟶ X₃ /-- the composition of the two given morphisms is zero -/ - zero : f ≫ g = 0 + zero : f ≫ g = 0 := by cat_disch namespace ShortComplex @@ -221,6 +221,12 @@ def isoMk (e₁ : S₁.X₁ ≅ S₂.X₁) (e₂ : S₁.X₂ ≅ S₂.X₂) (e lemma isIso_of_isIso (f : S₁ ⟶ S₂) [IsIso f.τ₁] [IsIso f.τ₂] [IsIso f.τ₃] : IsIso f := (isoMk (asIso f.τ₁) (asIso f.τ₂) (asIso f.τ₃)).isIso_hom +lemma isIso_iff (f : S₁ ⟶ S₂) : + IsIso f ↔ IsIso f.τ₁ ∧ IsIso f.τ₂ ∧ IsIso f.τ₃ := by + refine ⟨fun _ ↦ ⟨inferInstance, inferInstance, inferInstance⟩, ?_⟩ + rintro ⟨_, _, _⟩ + apply isIso_of_isIso + /-- The first map of a short complex, as a functor. -/ @[simps] def fFunctor : ShortComplex C ⥤ Arrow C where obj S := .mk S.f diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index beee9f0dc869a9..51011f447ee4a6 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -236,15 +236,15 @@ lemma exact_map_iff_of_faithful [S.HasHomology] (F : C ⥤ D) [F.PreservesZeroMorphisms] [F.PreservesLeftHomologyOf S] [F.PreservesRightHomologyOf S] [F.Faithful] : (S.map F).Exact ↔ S.Exact := by - constructor - · intro h - rw [S.leftHomologyData.exact_iff, IsZero.iff_id_eq_zero] - rw [(S.leftHomologyData.map F).exact_iff, IsZero.iff_id_eq_zero, - LeftHomologyData.map_H] at h - apply F.map_injective - rw [F.map_id, F.map_zero, h] - · intro h - exact h.map F + constructor + · intro h + rw [S.leftHomologyData.exact_iff, IsZero.iff_id_eq_zero] + rw [(S.leftHomologyData.map F).exact_iff, IsZero.iff_id_eq_zero, + LeftHomologyData.map_H] at h + apply F.map_injective + rw [F.map_id, F.map_zero, h] + · intro h + exact h.map F variable {S} @@ -829,6 +829,34 @@ section Abelian variable [Abelian C] +section + +variable {X Y : C} (f : X ⟶ Y) + +@[simps] +noncomputable def kernelSequence : ShortComplex C := + ShortComplex.mk _ _ (kernel.condition f) + +@[simps] +noncomputable def cokernelSequence : ShortComplex C := + ShortComplex.mk _ _ (cokernel.condition f) + +instance : Mono (kernelSequence f).f := by + dsimp + infer_instance + +instance : Epi (cokernelSequence f).g := by + dsimp + infer_instance + +lemma kernelSequence_exact : (kernelSequence f).Exact := + exact_of_f_is_kernel _ (kernelIsKernel f) + +lemma cokernelSequence_exact : (cokernelSequence f).Exact := + exact_of_g_is_cokernel _ (cokernelIsCokernel f) + +end + /-- Given a morphism of short complexes `φ : S₁ ⟶ S₂` in an abelian category, if `S₁.f` and `S₁.g` are zero (e.g. when `S₁` is of the form `0 ⟶ S₁.X₂ ⟶ 0`) and `S₂.f = 0` (e.g when `S₂` is of the form `0 ⟶ S₂.X₂ ⟶ S₂.X₃`), then `φ` is a quasi-isomorphism iff diff --git a/Mathlib/Algebra/Homology/ShortComplex/Homology.lean b/Mathlib/Algebra/Homology/ShortComplex/Homology.lean index da80f1d73236af..d9ce2b088e7557 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Homology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Homology.lean @@ -694,6 +694,12 @@ lemma HomologyData.right_homologyIso_eq_left_homologyIso_trans_iso dsimp rw [← leftRightHomologyComparison'_fac, leftRightHomologyComparison'_eq] +lemma HomologyData.left_homologyIso_eq_right_homologyIso_trans_iso_symm + (h : S.HomologyData) [S.HasHomology] : + h.left.homologyIso = h.right.homologyIso ≪≫ h.iso.symm := by + rw [right_homologyIso_eq_left_homologyIso_trans_iso] + cat_disch + lemma hasHomology_of_isIso_leftRightHomologyComparison' (h₁ : S.LeftHomologyData) (h₂ : S.RightHomologyData) [IsIso (leftRightHomologyComparison' h₁ h₂)] : diff --git a/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean b/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean index ed538341e74c76..a7d3a07f797d52 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/LeftHomology.lean @@ -971,6 +971,25 @@ noncomputable def cyclesIsoKernel [HasKernel S.g] : S.cycles ≅ kernel S.g wher hom := kernel.lift S.g S.iCycles (by simp) inv := S.liftCycles (kernel.ι S.g) (by simp) +section + +variable {kf : KernelFork S.g} (hkf : IsLimit kf) + +/-- The isomorphism from the point of a limit kernel fork of `S.g` to `S.cycles`. -/ +noncomputable def isoCyclesOfIsLimit : + kf.pt ≅ S.cycles := + IsLimit.conePointUniqueUpToIso hkf S.cyclesIsKernel + +@[reassoc (attr := simp)] +lemma isoCyclesOfIsLimit_inv_ι : (S.isoCyclesOfIsLimit hkf).inv ≫ kf.ι = S.iCycles := + IsLimit.conePointUniqueUpToIso_inv_comp _ _ WalkingParallelPair.zero + +@[reassoc (attr := simp)] +lemma isoCyclesOfIsLimit_hom_iCycles : (S.isoCyclesOfIsLimit hkf).hom ≫ S.iCycles = kf.ι := + IsLimit.conePointUniqueUpToIso_hom_comp _ _ WalkingParallelPair.zero + +end + /-- The morphism `A ⟶ S.leftHomology` obtained from a morphism `k : A ⟶ S.X₂` such that `k ≫ S.g = 0.` -/ @[simp] diff --git a/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean b/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean index 17d6e27efeb4f0..55cdca9ddc1f73 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/RightHomology.lean @@ -1253,6 +1253,26 @@ noncomputable def opcyclesIsoCokernel [HasCokernel S.f] : S.opcycles ≅ cokerne hom := S.descOpcycles (cokernel.π S.f) (by simp) inv := cokernel.desc S.f S.pOpcycles (by simp) +section + +variable {cc : CokernelCofork S.f} (hcc : IsColimit cc) + +/-- The isomorphism from the point of a colimit cokernel cofork of `S.f` to `S.opcycles`. -/ +noncomputable def isoOpcyclesOfIsColimit : + cc.pt ≅ S.opcycles := + IsColimit.coconePointUniqueUpToIso hcc S.opcyclesIsCokernel + +@[reassoc (attr := simp)] +lemma π_isoOpcyclesOfIsColimit_hom : cc.π ≫ (S.isoOpcyclesOfIsColimit hcc).hom = S.pOpcycles := + IsColimit.comp_coconePointUniqueUpToIso_hom _ _ WalkingParallelPair.one + +@[reassoc (attr := simp)] +lemma pOpcycles_π_isoOpcyclesOfIsColimit_inv : + S.pOpcycles ≫ (S.isoOpcyclesOfIsColimit hcc).inv = cc.π := + IsColimit.comp_coconePointUniqueUpToIso_inv _ S.opcyclesIsCokernel WalkingParallelPair.one + +end + /-- The morphism `S.rightHomology ⟶ A` obtained from a morphism `k : S.X₂ ⟶ A` such that `S.f ≫ k = 0.` -/ @[simp] diff --git a/Mathlib/Algebra/Homology/SpectralObject/Basic.lean b/Mathlib/Algebra/Homology/SpectralObject/Basic.lean new file mode 100644 index 00000000000000..dc327d0a3c3c5b --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/Basic.lean @@ -0,0 +1,235 @@ +/- +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.ExactSequence +public import Mathlib.CategoryTheory.ComposableArrows.One +public import Mathlib.CategoryTheory.ComposableArrows.Two + +/-! +# Spectral objects in abelian categories + +In this file, we introduce the category `SpectralObject C ι` of spectral +objects in an abelian category `C` indexed by the category `ι`. + +## References +* [Jean-Louis Verdier, *Des catégories dérivées des catégories abéliennes*, II.4][verdier1996] + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits + +namespace Abelian + +variable (C ι : Type*) [Category C] [Category ι] [Abelian C] + +open ComposableArrows + +/-- A spectral object in an abelian category category `C` indexed by a category `` +consists of a functor `H : ComposableArrows ι 1 ⥤ C`, and a +functorial long exact sequence +`⋯ ⟶ (H n₀).obj (mk₁ f) ⟶ (H n₀).obj (mk₁ (f ≫ g)) ⟶ (H n₀).obj (mk₁ g) ⟶ (H n₁).obj (mk₁ f) ⟶ ⋯` +when `n₀ + 1 = n₁` and `f` and `g` are composable morphisms in `ι`. (This will be +shortened as `H^n₀(f) ⟶ H^n₀(f ≫ g) ⟶ H^n₀(g) ⟶ H^n₁(f)` in the documentation.) -/ +structure SpectralObject where + /-- A sequence of functors from `ComposableArrows ι 1` to the abelian category. + The image of `mk₁ f` will be referred to as `H^n(f)` in the documentation. -/ + H (n : ℤ) : ComposableArrows ι 1 ⥤ C + /-- The connecting homomorphism of the spectral object. (Use `δ` instead.) -/ + δ' (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) : + functorArrows ι 1 2 2 ⋙ H n₀ ⟶ functorArrows ι 0 1 2 ⋙ H n₁ + exact₁' (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (D : ComposableArrows ι 2) : + (mk₂ ((δ' n₀ n₁ h).app D) ((H n₁).map ((mapFunctorArrows ι 0 1 0 2 2).app D))).Exact + exact₂' (n : ℤ) (D : ComposableArrows ι 2) : + (mk₂ ((H n).map ((mapFunctorArrows ι 0 1 0 2 2).app D)) + ((H n).map ((mapFunctorArrows ι 0 2 1 2 2).app D))).Exact + exact₃' (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (D : ComposableArrows ι 2) : + (mk₂ ((H n₀).map ((mapFunctorArrows ι 0 2 1 2 2).app D)) ((δ' n₀ n₁ h).app D)).Exact + +namespace SpectralObject + +variable {C ι} (X : SpectralObject C ι) + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) + +/-- The connecting homomorphism of the spectral object. -/ +def δ : (X.H n₀).obj (mk₁ g) ⟶ (X.H n₁).obj (mk₁ f) := + (X.δ' n₀ n₁ hn₁).app (mk₂ f g) + +@[reassoc] +lemma δ_naturality {i' j' k' : ι} (f' : i' ⟶ j') (g' : j' ⟶ k') + (α : mk₁ f ⟶ mk₁ f') (β : mk₁ g ⟶ mk₁ g') (hαβ : α.app 1 = β.app 0 := by cat_disch) : + (X.H n₀).map β ≫ X.δ n₀ n₁ hn₁ f' g' = X.δ n₀ n₁ hn₁ f g ≫ (X.H n₁).map α := by + have h := (X.δ' n₀ n₁ hn₁).naturality + (homMk₂ (α.app 0) (α.app 1) (β.app 1) (naturality' α 0 1) + (by simpa only [hαβ] using naturality' β 0 1) : mk₂ f g ⟶ mk₂ f' g') + dsimp at h + convert h <;> cat_disch + +end + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) + (fg : i ⟶ k) (h : f ≫ g = fg) + +@[reassoc (attr := simp)] +lemma zero₁ : + X.δ n₀ n₁ hn₁ f g ≫ (X.H n₁).map (twoδ₂Toδ₁ f g fg h) = 0 := by + subst h + exact (X.exact₁' n₀ n₁ hn₁ (mk₂ f g)).zero 0 + +@[reassoc (attr := simp)] +lemma zero₂ (fg : i ⟶ k) (h : f ≫ g = fg) : + (X.H n₀).map (twoδ₂Toδ₁ f g fg h) ≫ (X.H n₀).map (twoδ₁Toδ₀ f g fg h) = 0 := by + subst h + exact (X.exact₂' n₀ (mk₂ f g)).zero 0 + +@[reassoc (attr := simp)] +lemma zero₃ : + (X.H n₀).map (twoδ₁Toδ₀ f g fg h) ≫ X.δ n₀ n₁ hn₁ f g = 0 := by + subst h + exact (X.exact₃' n₀ n₁ hn₁ (mk₂ f g)).zero 0 + +/-- The (exact) short complex `H^n₀(g) ⟶ H^n₁(f) ⟶ H^n₁(fg)` of a +spectral object, when `f ≫ g = fg` and `n₀ + 1 = n₁`. -/ +@[simps] +def sc₁ : ShortComplex C := + ShortComplex.mk _ _ (X.zero₁ n₀ n₁ hn₁ f g fg h) + +/-- The (exact) short complex `H^n₀(f) ⟶ H^n₀(fg) ⟶ H^n₀(g)` of a +spectral object, when `f ≫ g = fg`. -/ +@[simps] +def sc₂ : ShortComplex C := + ShortComplex.mk _ _ (X.zero₂ n₀ f g fg h) + +/-- The (exact) short complex `H^n₀(fg) ⟶ H^n₀(g) ⟶ H^n₁(f)` +of a spectral object, when `f ≫ g = fg` and `n₀ + 1 = n₁`. -/ +@[simps] +def sc₃ : ShortComplex C := + ShortComplex.mk _ _ (X.zero₃ n₀ n₁ hn₁ f g fg h) + +lemma exact₁ : (X.sc₁ n₀ n₁ hn₁ f g fg h).Exact := by + subst h + exact (X.exact₁' n₀ n₁ hn₁ (mk₂ f g)).exact 0 + +lemma exact₂ : (X.sc₂ n₀ f g fg h).Exact := by + subst h + exact (X.exact₂' n₀ (mk₂ f g)).exact 0 + +lemma exact₃ : (X.sc₃ n₀ n₁ hn₁ f g fg h).Exact := by + subst h + exact ((X.exact₃' n₀ n₁ hn₁ (mk₂ f g))).exact 0 + +/-- The (exact) sequence +`H^n₀(f) ⟶ H^n₀(fg) ⟶ H^n₀(g) ⟶ H^n₁(f) ⟶ H^n₁(fg) ⟶ H^n₁(g)` +of a spectral object, when `f ≫ g = fg` and `n₀ + 1 = n₁`. -/ +abbrev composableArrows₅ : ComposableArrows C 5 := + mk₅ ((X.H n₀).map (twoδ₂Toδ₁ f g fg h)) ((X.H n₀).map (twoδ₁Toδ₀ f g fg h)) + (X.δ n₀ n₁ hn₁ f g) ((X.H n₁).map (twoδ₂Toδ₁ f g fg h)) + ((X.H n₁).map (twoδ₁Toδ₀ f g fg h)) + +lemma composableArrows₅_exact : + (X.composableArrows₅ n₀ n₁ hn₁ f g fg h).Exact := + exact_of_δ₀ (X.exact₂ n₀ _ _ _ h).exact_toComposableArrows + (exact_of_δ₀ (X.exact₃ n₀ n₁ hn₁ _ _ _ h).exact_toComposableArrows + (exact_of_δ₀ (X.exact₁ n₀ n₁ hn₁ _ _ _ h).exact_toComposableArrows + ((X.exact₂ n₁ _ _ _ h).exact_toComposableArrows))) + +end + +@[reassoc (attr := simp)] +lemma δ_δ (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i j k l : ι} (f : i ⟶ j) (g : j ⟶ k) (h : k ⟶ l) : + X.δ n₀ n₁ hn₁ g h ≫ X.δ n₁ n₂ hn₂ f g = 0 := by + have eq := X.δ_naturality n₁ n₂ hn₂ f g f (g ≫ h) (𝟙 _) (twoδ₂Toδ₁ g h _ rfl) + rw [Functor.map_id, comp_id] at eq + rw [← eq, X.zero₁_assoc n₀ n₁ hn₁ g h _ rfl, zero_comp] + +/-- The type of morphisms between spectral objects in abelian categories. -/ +@[ext] +structure Hom (X' : SpectralObject C ι) where + /-- The natural transformation that is part of a morphism between spectral objects. -/ + hom (n : ℤ) : X.H n ⟶ X'.H n + comm (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) : + X.δ n₀ n₁ hn₁ f g ≫ (hom n₁).app (mk₁ f) = + (hom n₀).app (mk₁ g) ≫ X'.δ n₀ n₁ hn₁ f g := by cat_disch + +attribute [reassoc (attr := simp)] Hom.comm + +@[simps] +instance : Category (SpectralObject C ι) where + Hom := Hom + id X := { hom _ := 𝟙 _ } + comp f g := { hom n := f.hom n ≫ g.hom n } + +attribute [simp] id_hom +attribute [reassoc, simp] comp_hom + +lemma isZero_H_map_mk₁_of_isIso (n : ℤ) {i₀ i₁ : ι} (f : i₀ ⟶ i₁) [IsIso f] : + IsZero ((X.H n).obj (mk₁ f)) := by + let φ := twoδ₂Toδ₁ f (inv f) (𝟙 i₀) (by simp) ≫ twoδ₁Toδ₀ f (inv f) (𝟙 i₀) + have : IsIso φ := by + rw [isIso_iff₁] + constructor <;> dsimp <;> infer_instance + rw [IsZero.iff_id_eq_zero] + rw [← cancel_mono ((X.H n).map φ), Category.id_comp, zero_comp, + ← X.zero₂ n f (inv f) (𝟙 _) (by simp), ← Functor.map_comp] + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) {i₀ i₁ i₂ : ι} + (f : i₀ ⟶ i₁) (g : i₁ ⟶ i₂) (fg : i₀ ⟶ i₂) (hfg : f ≫ g = fg) + (h₁ : IsZero ((X.H n₀).obj (mk₁ f))) (h₂ : IsZero ((X.H n₁).obj (mk₁ f))) + +include h₁ in +lemma mono_H_map_twoδ₁Toδ₀ : Mono ((X.H n₀).map (twoδ₁Toδ₀ f g fg hfg)) := + (X.exact₂ n₀ f g fg hfg).mono_g (h₁.eq_of_src _ _) + +include h₂ hn₁ in +lemma epi_H_map_twoδ₁Toδ₀ : Epi ((X.H n₀).map (twoδ₁Toδ₀ f g fg hfg)) := + (X.exact₃ n₀ n₁ hn₁ f g fg hfg).epi_f (h₂.eq_of_tgt _ _) + +include h₁ h₂ hn₁ in +lemma isIso_H_map_twoδ₁Toδ₀ : IsIso ((X.H n₀).map (twoδ₁Toδ₀ f g fg hfg)) := by + have := X.mono_H_map_twoδ₁Toδ₀ n₀ f g fg hfg h₁ + have := X.epi_H_map_twoδ₁Toδ₀ n₀ n₁ hn₁ f g fg hfg h₂ + apply isIso_of_mono_of_epi + +end + +section + +variable {ι' : Type*} [Preorder ι'] (X' : SpectralObject C ι') + (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) (i₀ i₁ i₂ : ι') (h₀₁ : i₀ ≤ i₁) (h₁₂ : i₁ ≤ i₂) + (h₁ : IsZero ((X'.H n₀).obj (mk₁ (homOfLE h₀₁)))) + (h₂ : IsZero ((X'.H n₁).obj (mk₁ (homOfLE h₀₁)))) + +include h₁ in +lemma mono_H_map_twoδ₁Toδ₀' : Mono ((X'.H n₀).map (twoδ₁Toδ₀' i₀ i₁ i₂ h₀₁ h₁₂)) := + X'.mono_H_map_twoδ₁Toδ₀ _ _ _ _ _ h₁ + +include h₂ hn₁ in +lemma epi_H_map_twoδ₁Toδ₀' : Epi ((X'.H n₀).map (twoδ₁Toδ₀' i₀ i₁ i₂ h₀₁ h₁₂)) := + X'.epi_H_map_twoδ₁Toδ₀ _ _ hn₁ _ _ _ _ h₂ + +include h₁ h₂ hn₁ in +lemma isIso_H_map_twoδ₁Toδ₀' : IsIso ((X'.H n₀).map (twoδ₁Toδ₀' i₀ i₁ i₂ h₀₁ h₁₂)) := + X'.isIso_H_map_twoδ₁Toδ₀ _ _ hn₁ _ _ _ _ h₁ h₂ + +end + +end SpectralObject + +end Abelian + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean new file mode 100644 index 00000000000000..1670bb9091ee3b --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean @@ -0,0 +1,501 @@ +/- +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.SpectralObject.Basic +public import Mathlib.Algebra.Homology.ExactSequenceFour +public import Batteries.Tactic.Lint + +/-! +# Kernel and cokernel of the differentiel of a spectral object + +Let `X` be a spectral object index by the category `ι` +in the abelian category `C`. In this file, we introduce +the kernel `X.cycles` and the cokernel `X.opcycles` of `X.δ`. +These are defined when `f` and `g` are composable morphisms +in `ι` and for any integer `n`. +In the documentation, the kernel `X.cycles n f g` of +`δ : H^n(g) ⟶ H^{n+1}(f)` shall be denoted `Z^n(f, g)`, +and the cokernel `X.opcycles n f g` of `δ : H^{n-1}(g) ⟶ H^n(f)` +shall be denoted `opZ^n(f, g)`. +The definitions `cyclesMap` and `opcyclesMap` give the +functoriality of these definitions with respect +to morphisms in `ComposableArrows ι 2`. + +We record that `Z^n(f, g)` is a kernel by the lemma +`kernelSequenceCycles_exact` and that `opZ^n(f, g)` is +a cokernel by the lemma `cokernelSequenceOpcycles_exact`. +We also provide a constructor `X.liftCycles` for morphisms +to cycles and `X.descOpcycles` for morphisms from opcycles. + +The fact that the morphisms `δ` are part of a long exact sequence allow +to show that `X.cycles` also identify to a cokernel (`cokernelIsoCycles`) +and `X.opcycles` to a kernel (`opcyclesIsoKernel`). +More precisely, the exactness of `H^n(f) ⟶ H^n(f ≫ g) ⟶ Z^n(f, g) ⟶ 0` +is `cokernelSequenceCycles_exact` and the exactness of +`0 ⟶ opZ^n(f, g) ⟶ H^n(f ≫ g) ⟶ H^n(g)` is +`kernelSequenceOpcycles_exact`. In particular, we also +get constructors `descCycles` and `liftOpcycles` for morphisms +from cycles and to opcycles. + +When `f₁`, `f₂` and `f₃` are composable morphisms, we introduce +morphisms `δToCycles : H^n(f₃) ⟶ Z^{n+1}(f₁, f₂)` and . +`δFromOpcycles : opZ^n(f₂, f₃) ⟶ H^{n+1}(f₁)`. + +## References +* [Jean-Louis Verdier, *Des catégories dérivées des catégories abéliennes*, II.4][verdier1996] +-/ + +@[expose] public section + +namespace CategoryTheory + +open Limits ComposableArrows + +namespace Abelian + +variable {C ι : Type*} [Category C] [Category ι] [Abelian C] + +namespace SpectralObject + +variable (X : SpectralObject C ι) + +section + +variable (n : ℤ) {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) + +/-- The kernel of `δ : H^n(g) ⟶ H^{n+1}(f)`. In the documentation, +this may be shortened as `Z^n(f, g)` -/ +noncomputable def cycles : C := kernel (X.δ n (n + 1) rfl f g) + +/-- The cokernel of `δ : H^{n-1}(g) ⟶ H^n(g)`. In the documentation, +this may be shortened as `opZ^n₁(f, g)`. -/ +noncomputable def opcycles : C := cokernel (X.δ (n - 1) n (by lia) f g) + +/-- The inclusion `Z^n(f, g) ⟶ H^n(g)` of the kernel of `δ`. -/ +noncomputable def iCycles : + X.cycles n f g ⟶ (X.H n).obj (mk₁ g) := + kernel.ι _ + +/-- The projection `H^n(f) ⟶ opZ^n(f, g)` to the cokernel of `δ`. -/ +noncomputable def pOpcycles : + (X.H n).obj (mk₁ f) ⟶ X.opcycles n f g := + cokernel.π _ + +instance : Mono (X.iCycles n f g) := by + dsimp [iCycles] + infer_instance + +instance : Epi (X.pOpcycles n f g) := by + dsimp [pOpcycles] + infer_instance + +lemma isZero_opcycles (h : IsZero ((X.H n).obj (mk₁ f))) : + IsZero (X.opcycles n f g) := by + rw [IsZero.iff_id_eq_zero, ← cancel_epi (X.pOpcycles ..)] + apply h.eq_of_src + +lemma isZero_cycles (h : IsZero ((X.H n).obj (mk₁ g))) : + IsZero (X.cycles n f g) := by + rw [IsZero.iff_id_eq_zero, ← cancel_mono (X.iCycles ..)] + apply h.eq_of_tgt + +end + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) + +@[reassoc (attr := simp)] +lemma iCycles_δ : X.iCycles n₀ f g ≫ X.δ n₀ n₁ hn₁ f g = 0 := by + subst hn₁ + simp [iCycles] + +@[reassoc (attr := simp)] +lemma δ_pOpcycles : X.δ n₀ n₁ hn₁ f g ≫ X.pOpcycles n₁ f g = 0 := by + obtain rfl : n₀ = n₁ - 1 := by lia + simp [pOpcycles] + +/-- The short complex which expresses `X.cycles` as the kernel of `X.δ`. -/ +@[simps] +noncomputable def kernelSequenceCycles : ShortComplex C := + ShortComplex.mk _ _ (X.iCycles_δ n₀ n₁ hn₁ f g) + +/-- The short complex which expresses `X.opcycles` as the cokernel of `X.δ`. -/ +@[simps] +noncomputable def cokernelSequenceOpcycles : ShortComplex C := + ShortComplex.mk _ _ (X.δ_pOpcycles n₀ n₁ hn₁ f g) + +instance : Mono (X.kernelSequenceCycles n₀ n₁ hn₁ f g).f := by + dsimp + infer_instance + +instance : Epi (X.cokernelSequenceOpcycles n₀ n₁ hn₁ f g).g := by + dsimp + infer_instance + +lemma kernelSequenceCycles_exact : + (X.kernelSequenceCycles n₀ n₁ hn₁ f g).Exact := by + subst hn₁ + exact ShortComplex.kernelSequence_exact _ + +lemma cokernelSequenceOpcycles_exact : + (X.cokernelSequenceOpcycles n₀ n₁ hn₁ f g).Exact := by + obtain rfl : n₀ = n₁ - 1 := by lia + exact ShortComplex.cokernelSequence_exact _ + +section + +variable {A : C} (x : A ⟶ (X.H n₀).obj (mk₁ g)) (hx : x ≫ X.δ n₀ n₁ hn₁ f g = 0) + +/-- Constructor for morphisms to `X.cycles`. -/ +noncomputable def liftCycles : + A ⟶ X.cycles n₀ f g := + kernel.lift _ x (by subst hn₁; exact hx) + +@[reassoc (attr := simp)] +lemma liftCycles_i : X.liftCycles n₀ n₁ hn₁ f g x hx ≫ X.iCycles n₀ f g = x := by + apply kernel.lift_ι + +end + +section + +variable {A : C} (x : (X.H n₁).obj (mk₁ f) ⟶ A) (hx : X.δ n₀ n₁ hn₁ f g ≫ x = 0) + +/-- Constructor for morphisms from `X.opcycles`. -/ +noncomputable def descOpcycles : + X.opcycles n₁ f g ⟶ A := + cokernel.desc _ x (by + obtain rfl : n₀ = n₁ -1 := by lia + exact hx) + +@[reassoc (attr := simp)] +lemma p_descOpcycles : X.pOpcycles n₁ f g ≫ X.descOpcycles n₀ n₁ hn₁ f g x hx = x := by + apply cokernel.π_desc + +end + +end + +section + +variable (n : ℤ) {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) + {i' j' k' : ι} (f' : i' ⟶ j') (g' : j' ⟶ k') + {i'' j'' k'' : ι} (f'' : i'' ⟶ j'') (g'' : j'' ⟶ k'') + +/-- The functoriality of `X.cycles` with respect to morphisms in +`ComposableArrows ι 2`. -/ +noncomputable def cyclesMap (α : mk₂ f g ⟶ mk₂ f' g') : + X.cycles n f g ⟶ X.cycles n f' g' := + X.liftCycles _ _ rfl _ _ + (X.iCycles n f g ≫ (X.H n).map (homMk₁ (α.app 1) (α.app 2) + (naturality' α 1 2))) (by + rw [Category.assoc, X.δ_naturality n _ rfl f g f' g' + (homMk₁ (α.app 0) (α.app 1) (naturality' α 0 1)) + (homMk₁ (α.app 1) (α.app 2) (naturality' α 1 2)) rfl, + iCycles_δ_assoc, zero_comp]) + +@[reassoc] +lemma cyclesMap_i (α : mk₂ f g ⟶ mk₂ f' g') (β : mk₁ g ⟶ mk₁ g') + (hβ : β = homMk₁ (α.app 1) (α.app 2) (naturality' α 1 2)) : + X.cyclesMap n f g f' g' α ≫ X.iCycles n f' g' = + X.iCycles n f g ≫ (X.H n).map β := by + subst hβ + simp [cyclesMap] + +@[simp] +lemma cyclesMap_id : + X.cyclesMap n f g f g (𝟙 _) = 𝟙 _ := by + rw [← cancel_mono (X.iCycles n f g), + X.cyclesMap_i n f g f g (𝟙 _) (𝟙 _) (by cat_disch), + Functor.map_id, Category.comp_id, Category.id_comp] + +@[reassoc] +lemma cyclesMap_comp (α : mk₂ f g ⟶ mk₂ f' g') (α' : mk₂ f' g' ⟶ mk₂ f'' g'') + (α'' : mk₂ f g ⟶ mk₂ f'' g'') (h : α ≫ α' = α'') : + X.cyclesMap n f g f' g' α ≫ X.cyclesMap n f' g' f'' g'' α' = + X.cyclesMap n f g f'' g'' α'' := by + subst h + rw [← cancel_mono (X.iCycles n f'' g''), Category.assoc, + X.cyclesMap_i n f' g' f'' g'' α' _ rfl, + X.cyclesMap_i_assoc n f g f' g' α _ rfl, + ← Functor.map_comp] + symm + apply X.cyclesMap_i + cat_disch + +/-- The functoriality of `X.opcycles` with respect to morphisms in +`ComposableArrows ι 2`. -/ +noncomputable def opcyclesMap (α : mk₂ f g ⟶ mk₂ f' g') : + X.opcycles n f g ⟶ X.opcycles n f' g' := + X.descOpcycles (n - 1) n (by lia) _ _ + ((X.H n).map (homMk₁ (by exact α.app 0) (by exact α.app 1) + (naturality' α 0 1)) ≫ X.pOpcycles n f' g') (by + rw [← X.δ_naturality_assoc (n - 1) n (by lia) f g f' g' + (homMk₁ (α.app 0) (α.app 1) (naturality' α 0 1)) + (homMk₁ (α.app 1) (α.app 2) (naturality' α 1 2)) rfl, + δ_pOpcycles, comp_zero]) + +@[reassoc] +lemma p_opcyclesMap (α : mk₂ f g ⟶ mk₂ f' g') (β : mk₁ f ⟶ mk₁ f') + (hβ : β = homMk₁ (α.app 0) (α.app 1) (naturality' α 0 1)) : + X.pOpcycles n f g ≫ X.opcyclesMap n f g f' g' α = + (X.H n).map β ≫ X.pOpcycles n f' g' := by + subst hβ + simp [opcyclesMap] + +@[simp] +lemma opcyclesMap_id : + X.opcyclesMap n f g f g (𝟙 _) = 𝟙 _ := by + rw [← cancel_epi (X.pOpcycles n f g), + X.p_opcyclesMap n f g f g (𝟙 _) (𝟙 _) (by cat_disch), + Functor.map_id, Category.comp_id, Category.id_comp] + +lemma opcyclesMap_comp (α : mk₂ f g ⟶ mk₂ f' g') (α' : mk₂ f' g' ⟶ mk₂ f'' g'') + (α'' : mk₂ f g ⟶ mk₂ f'' g'') (h : α ≫ α' = α'') : + X.opcyclesMap n f g f' g' α ≫ X.opcyclesMap n f' g' f'' g'' α' = + X.opcyclesMap n f g f'' g'' α'' := by + subst h + rw [← cancel_epi (X.pOpcycles n f g), + X.p_opcyclesMap_assoc n f g f' g' α _ rfl, + X.p_opcyclesMap n f' g' f'' g'' α' _ rfl, + ← Functor.map_comp_assoc] + symm + apply X.p_opcyclesMap + aesop_cat + +variable (fg : i ⟶ k) (h : f ≫ g = fg) (fg' : i' ⟶ k') (h' : f' ≫ g' = fg') + +/-- `X.cycles` also identifies to a cokernel. More precisely, +`Z^n(f, g)` identifies to the cokernel of `H^n(f) ⟶ H^n(f ≫ g)` -/ +noncomputable def cokernelIsoCycles : + cokernel ((X.H n).map (twoδ₂Toδ₁ f g fg h)) ≅ X.cycles n f g := + (X.composableArrows₅_exact n _ rfl f g fg h).cokerIsoKer 0 + +@[reassoc (attr := simp)] +lemma cokernelIsoCycles_hom_fac : + cokernel.π _ ≫ (X.cokernelIsoCycles n f g fg h).hom ≫ + X.iCycles n f g = (X.H n).map (twoδ₁Toδ₀ f g fg h) := + (X.composableArrows₅_exact n _ rfl f g fg h).cokerIsoKer_hom_fac 0 + +/-- `X.opcycles` also identifies to a kernel. More precisely, +`opZ(f, g)` identifies to the kernel of `H^n(f ≫ g) ⟶ H^n(g)` -/ +noncomputable def opcyclesIsoKernel : + X.opcycles n f g ≅ kernel ((X.H n).map (twoδ₁Toδ₀ f g fg h)) := + (X.composableArrows₅_exact (n - 1) n (by lia) f g fg h).cokerIsoKer 2 + +@[reassoc (attr := simp)] +lemma opcyclesIsoKernel_hom_fac : + X.pOpcycles n f g ≫ (X.opcyclesIsoKernel n f g fg h).hom ≫ + kernel.ι _ = (X.H n).map (twoδ₂Toδ₁ f g fg h) := + (X.composableArrows₅_exact (n - 1) n (by lia) f g fg h).cokerIsoKer_hom_fac 2 + +/-- The map `H^n(fg) ⟶ H^n(g)` factors through `Z^n(f, g)`. -/ +noncomputable def toCycles : (X.H n).obj (mk₁ fg) ⟶ X.cycles n f g := + kernel.lift _ ((X.H n).map (twoδ₁Toδ₀ f g fg h)) (by simp) + +instance : Epi (X.toCycles n f g fg h) := + (ShortComplex.exact_iff_epi_kernel_lift _).1 (X.exact₃ n _ rfl f g fg h) + +@[reassoc (attr := simp)] +lemma toCycles_i : + X.toCycles n f g fg h ≫ X.iCycles n f g = (X.H n).map (twoδ₁Toδ₀ f g fg h) := + kernel.lift_ι .. + +@[reassoc] +lemma toCycles_cyclesMap (α : mk₂ f g ⟶ mk₂ f' g') (β : mk₁ fg ⟶ mk₁ fg') + (hβ₀ : β.app 0 = α.app 0) (hβ₁ : β.app 1 = α.app 2) : + X.toCycles n f g fg h ≫ X.cyclesMap n f g f' g' α = + (X.H n).map β ≫ X.toCycles n f' g' fg' h' := by + rw [← cancel_mono (X.iCycles n f' g'), Category.assoc, Category.assoc, toCycles_i, + X.cyclesMap_i n f g f' g' α (homMk₁ (α.app 1) (α.app 2) (naturality' α 1 2)) rfl, + toCycles_i_assoc, ← Functor.map_comp, ← Functor.map_comp] + congr 1 + ext + · dsimp + rw [hβ₀] + exact naturality' α 0 1 + · dsimp + rw [hβ₁, Category.comp_id, Category.id_comp] + +/-- The map `H^n(f) ⟶ H^n(f ≫ g)` factors through `opZ^n(f, g)`. -/ +noncomputable def fromOpcycles : + X.opcycles n f g ⟶ (X.H n).obj (mk₁ fg) := + cokernel.desc _ ((X.H n).map (twoδ₂Toδ₁ f g fg h)) (by simp) + +instance : Mono (X.fromOpcycles n f g fg h) := + (ShortComplex.exact_iff_mono_cokernel_desc _).1 (X.exact₁ (n - 1) n (by lia) f g fg h) + +@[reassoc (attr := simp)] +lemma p_fromOpcycles : + X.pOpcycles n f g ≫ X.fromOpcycles n f g fg h = + (X.H n).map (twoδ₂Toδ₁ f g fg h) := + cokernel.π_desc .. + +@[reassoc] +lemma opcyclesMap_fromOpcycles (α : mk₂ f g ⟶ mk₂ f' g') (β : mk₁ fg ⟶ mk₁ fg') + (hβ₀ : β.app 0 = α.app 0) (hβ₁ : β.app 1 = α.app 2) : + X.opcyclesMap n f g f' g' α ≫ X.fromOpcycles n f' g' fg' h' = + X.fromOpcycles n f g fg h ≫ (X.H n).map β := by + rw [← cancel_epi (X.pOpcycles n f g), p_fromOpcycles_assoc, + X.p_opcyclesMap_assoc n f g f' g' α (homMk₁ (α.app 0) (α.app 1) + (naturality' α 0 1)) rfl, + p_fromOpcycles, ← Functor.map_comp, ← Functor.map_comp] + congr 1 + ext + · cat_disch + · dsimp + rw [hβ₁] + exact (naturality' α 1 2).symm + +@[reassoc (attr := simp)] +lemma H_map_twoδ₂Toδ₁_toCycles : + (X.H n).map (twoδ₂Toδ₁ f g fg h) ≫ X.toCycles n f g fg h = 0 := by + simp [← cancel_mono (X.iCycles n f g)] + +@[reassoc (attr := simp)] +lemma fromOpcycles_H_map_twoδ₁Toδ₀ : + X.fromOpcycles n f g fg h ≫ (X.H n).map (twoδ₁Toδ₀ f g fg h) = 0 := by + simp [← cancel_epi (X.pOpcycles n f g)] + +/-- The short complex expressing `Z^n(f, g)` as a cokernel of +the map `H^n(f) ⟶ H^n(f ≫ g)`. -/ +@[simps] +noncomputable def cokernelSequenceCycles : ShortComplex C := + ShortComplex.mk _ _ (X.H_map_twoδ₂Toδ₁_toCycles n f g fg h) + +/-- The short complex expressing `opZ^n(f, g)` as a kernel of +the map `H^n(f ≫ g) ⟶ H^n(g)`. -/ +@[simps] +noncomputable def kernelSequenceOpcycles : ShortComplex C := + ShortComplex.mk _ _ (X.fromOpcycles_H_map_twoδ₁Toδ₀ n f g fg h) + +instance : Epi (X.cokernelSequenceCycles n f g fg h).g := by + dsimp + infer_instance + +instance : Mono (X.kernelSequenceOpcycles n f g fg h).f := by + dsimp + infer_instance + +/-- `Z^n(f, g)` identifies to a cokernel of the `H^n(f) ⟶ H^n(f ≫ g)`. -/ +lemma cokernelSequenceCycles_exact : + (X.cokernelSequenceCycles n f g fg h).Exact := by + apply ShortComplex.exact_of_g_is_cokernel + exact IsColimit.ofIsoColimit (cokernelIsCokernel _) + (Cofork.ext (X.cokernelIsoCycles n f g fg h) (by + simp [← cancel_mono (X.iCycles n f g)])) + +/-- `opZ^n(f, g)` identifies to the kernel of `H^n(f ≫ g) ⟶ H^n(g)`. -/ +lemma kernelSequenceOpcycles_exact : + (X.kernelSequenceOpcycles n f g fg h).Exact := by + apply ShortComplex.exact_of_f_is_kernel + exact IsLimit.ofIsoLimit (kernelIsKernel _) + (Iso.symm (Fork.ext (X.opcyclesIsoKernel n f g fg h) (by + simp [← cancel_epi (X.pOpcycles n f g)]))) + +lemma isIso_toCycles (hf : IsZero ((X.H n).obj (mk₁ f))) : + IsIso (X.toCycles n f g fg h) := by + have : Mono (X.toCycles n f g fg h) := + (X.cokernelSequenceCycles_exact n f g fg h).mono_g (hf.eq_of_src _ _) + exact Balanced.isIso_of_mono_of_epi _ + +lemma isIso_fromOpcycles (hg : IsZero ((X.H n).obj (mk₁ g))) : + IsIso (X.fromOpcycles n f g fg h) := by + have : Epi (X.fromOpcycles n f g fg h) := + (X.kernelSequenceOpcycles_exact n f g fg h).epi_f (hg.eq_of_tgt _ _) + exact Balanced.isIso_of_mono_of_epi _ + +section + +variable {A : C} (x : (X.H n).obj (mk₁ fg) ⟶ A) + (hx : (X.H n).map (twoδ₂Toδ₁ f g fg h) ≫ x = 0) + +/-- Constructor for morphisms from `X.cycles`. -/ +noncomputable def descCycles : + X.cycles n f g ⟶ A := + (X.cokernelSequenceCycles_exact n f g fg h).desc x hx + +@[reassoc (attr := simp)] +lemma toCycles_descCycles : + X.toCycles n f g fg h ≫ X.descCycles n f g fg h x hx = x := + (X.cokernelSequenceCycles_exact n f g fg h).g_desc x hx + +end + +section + +variable {A : C} (x : A ⟶ (X.H n).obj (mk₁ fg)) + (hx : x ≫ (X.H n).map (twoδ₁Toδ₀ f g fg h) = 0) + +/-- Constructor for morphisms to `X.opcycles`. -/ +noncomputable def liftOpcycles : + A ⟶ X.opcycles n f g := + (X.kernelSequenceOpcycles_exact n f g fg h).lift x hx + +@[reassoc (attr := simp)] +lemma liftOpcycles_fromOpcycles : + X.liftOpcycles n f g fg h x hx ≫ X.fromOpcycles n f g fg h = x := + (X.kernelSequenceOpcycles_exact n f g fg h).lift_f x hx + +end + +end + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) + {i j k l : ι} (f₁ : i ⟶ j) (f₂ : j ⟶ k) (f₃ : k ⟶ l) + (f₁₂ : i ⟶ k) (h₁₂ : f₁ ≫ f₂ = f₁₂) (f₂₃ : j ⟶ l) (h₂₃ : f₂ ≫ f₃ = f₂₃) + +/-- The morphism `H^{n₀}(f₃) ⟶ Z^{n₁}(f₁, f₂)` induced by `δ` +when `f₁`, `f₂`, `f₃` are composable morphisms and `n₀ + 1 = n₁`. -/ +noncomputable def δToCycles : (X.H n₀).obj (mk₁ f₃) ⟶ X.cycles n₁ f₁ f₂ := + X.liftCycles n₁ _ rfl f₁ f₂ (X.δ n₀ n₁ hn₁ f₂ f₃) (by simp) + +@[reassoc (attr := simp)] +lemma δToCycles_iCycles : + X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃ ≫ X.iCycles n₁ f₁ f₂ = + X.δ n₀ n₁ hn₁ f₂ f₃ := by + simp only [δToCycles, liftCycles_i] + +@[reassoc (attr := simp)] +lemma δ_toCycles : + X.δ n₀ n₁ hn₁ f₁₂ f₃ ≫ X.toCycles n₁ f₁ f₂ f₁₂ h₁₂ = + X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃ := by + rw [← cancel_mono (X.iCycles n₁ f₁ f₂), Category.assoc, + toCycles_i, δToCycles_iCycles, + ← X.δ_naturality n₀ n₁ hn₁ f₁₂ f₃ f₂ f₃ (twoδ₁Toδ₀ f₁ f₂ f₁₂ h₁₂) (𝟙 _) rfl, + Functor.map_id, Category.id_comp] + +/-- The morphism `opZ^{n₀}(f₂, f₃) ⟶ H^{n₁}(f₁)` induced by `δ` +when `f₁`, `f₂`, `f₃` are composable morphisms and `n₀ + 1 = n₁`. -/ +noncomputable def δFromOpcycles : X.opcycles n₀ f₂ f₃ ⟶ (X.H n₁).obj (mk₁ f₁) := + X.descOpcycles (n₀ - 1) n₀ (by lia) f₂ f₃ (X.δ n₀ n₁ hn₁ f₁ f₂) (by simp) + +@[reassoc (attr := simp)] +lemma pOpcycles_δFromOpcycles : + X.pOpcycles n₀ f₂ f₃ ≫ X.δFromOpcycles n₀ n₁ hn₁ f₁ f₂ f₃ = + X.δ n₀ n₁ hn₁ f₁ f₂ := by + simp only [δFromOpcycles, p_descOpcycles] + +@[reassoc (attr := simp)] +lemma fromOpcyles_δ : + X.fromOpcycles n₀ f₂ f₃ f₂₃ h₂₃ ≫ X.δ n₀ n₁ hn₁ f₁ f₂₃ = + X.δFromOpcycles n₀ n₁ hn₁ f₁ f₂ f₃ := by + rw [← cancel_epi (X.pOpcycles n₀ f₂ f₃), + p_fromOpcycles_assoc, pOpcycles_δFromOpcycles, + X.δ_naturality n₀ n₁ hn₁ f₁ f₂ f₁ f₂₃ (𝟙 _) (twoδ₂Toδ₁ f₂ f₃ f₂₃ h₂₃) rfl, + Functor.map_id, Category.comp_id] + +end + +end SpectralObject + +end Abelian + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralObject/Differentials.lean b/Mathlib/Algebra/Homology/SpectralObject/Differentials.lean new file mode 100644 index 00000000000000..ccd0f9b960d826 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/Differentials.lean @@ -0,0 +1,255 @@ +/- +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.SpectralObject.Page +public import Mathlib.CategoryTheory.ComposableArrows.Three + +/-! +# Differentials of a spectral object + +Let `X` be a spectral object in an abelian category `C` indexed by a category `ι`. +In this file, we construct the differentials `d : E^{n}(f₃, f₄, f₅) ⟶ E^{n+1}(f₁, f₂, f₃)` +that are attached to families of five composable morphisms `f₁`, `f₂`, `f₃`, `f₄`, `f₅` +in `ι`. We show that `d ≫ d = 0`. The homology of these differentials is computed in the +file `Mathlib/Algebra/Homology/SpectralObject/Homology.lean`. + +## References +* [Jean-Louis Verdier, *Des catégories dérivées des catégories abéliennes*, II.4][verdier1996] + +-/ + +@[expose] public section + +namespace CategoryTheory + +variable {C ι : Type*} [Category C] [Category ι] [Abelian C] + +open Category ComposableArrows Limits Preadditive + +namespace Abelian + +namespace SpectralObject + +variable (X : SpectralObject C ι) + +section + +variable (n₀ n₁ n₂ n₃ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) + {i₀ i₁ i₂ i₃ i₄ i₅ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) (f₁₂ : i₀ ⟶ i₂) (h₁₂ : f₁ ≫ f₂ = f₁₂) + (f₂₃ : i₁ ⟶ i₃) (h₂₃ : f₂ ≫ f₃ = f₂₃) + (f₃₄ : i₂ ⟶ i₄) (h₃₄ : f₃ ≫ f₄ = f₃₄) + (f₄₅ : i₃ ⟶ i₅) (h₄₅ : f₄ ≫ f₅ = f₄₅) + +/-- The differential `E^{n}(f₃, f₄, f₅) ⟶ E^{n+1}(f₁, f₂, f₃)` that is +attached to a family of five composable morphisms `f₁`, `f₂`, `f₃`, `f₄`, `f₅`. -/ +noncomputable def d : X.E n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅ ⟶ X.E n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ := + X.descE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅ _ rfl (X.δ n₁ n₂ hn₂ (f₁ ≫ f₂) (f₃ ≫ f₄) ≫ + X.toCycles n₂ f₁ f₂ _ rfl ≫ X.πE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃) (by + rw [X.δ_naturality_assoc n₁ n₂ hn₂ (f₁ ≫ f₂) f₃ (f₁ ≫ f₂) (f₃ ≫ f₄) + (𝟙 _) (twoδ₂Toδ₁ f₃ f₄ _ rfl) rfl, Functor.map_id, id_comp, + δ_toCycles_assoc, δToCycles_πE]) (by rw [δ_δ_assoc, zero_comp]) + +@[reassoc] +lemma toCycles_πE_d : + X.toCycles n₁ f₃ f₄ f₃₄ h₃₄ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅ ≫ + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ = + X.δ n₁ n₂ hn₂ f₁₂ f₃₄ ≫ X.toCycles n₂ f₁ f₂ f₁₂ h₁₂ ≫ + X.πE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ := by + subst h₁₂ h₃₄ + simp only [d, δ_toCycles_assoc, toCycles_πE_descE] + +include h₃₄ in +@[reassoc] +lemma d_ιE_fromOpcycles : + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ X.ιE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ ≫ + X.fromOpcycles n₂ f₂ f₃ f₂₃ h₂₃ = + X.ιE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅ ≫ X.fromOpcycles n₁ f₄ f₅ f₄₅ h₄₅ ≫ + X.δ n₁ n₂ hn₂ f₂₃ f₄₅ := by + rw [← cancel_epi (X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅), + ← cancel_epi (X.toCycles n₁ f₃ f₄ f₃₄ h₃₄), + X.toCycles_πE_d_assoc n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ _ rfl] + rw [πE_ιE_assoc, p_fromOpcycles, toCycles_i_assoc, fromOpcyles_δ, + πE_ιE_assoc, pOpcycles_δFromOpcycles, toCycles_i_assoc, ← Functor.map_comp] + symm + apply δ_naturality + simp + +end + +section + +variable (n₀ n₁ n₂ n₃ n₄ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) (hn₄ : n₃ + 1 = n₄) + {i₀ i₁ i₂ i₃ i₄ i₅ i₆ i₇ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) (f₆ : i₅ ⟶ i₆) (f₇ : i₆ ⟶ i₇) + +@[reassoc (attr := simp)] +lemma d_d : + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₃ f₄ f₅ f₆ f₇ ≫ + X.d n₁ n₂ n₃ n₄ hn₂ hn₃ hn₄ f₁ f₂ f₃ f₄ f₅ = 0 := by + rw [← cancel_epi (X.πE n₀ n₁ n₂ hn₁ hn₂ f₅ f₆ f₇), + ← cancel_epi (X.toCycles n₁ f₅ f₆ _ rfl), comp_zero, comp_zero, + X.toCycles_πE_d_assoc n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₃ f₄ f₅ f₆ f₇ _ rfl _ rfl, + X.toCycles_πE_d n₁ n₂ n₃ n₄ hn₂ hn₃ hn₄ f₁ f₂ f₃ f₄ f₅ _ rfl _ rfl, + δ_δ_assoc, zero_comp] + +end + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) + {i j k l : ι} (f₁ : i ⟶ j) (f₂ : j ⟶ k) (f₃ : k ⟶ l) + (f₁₂ : i ⟶ k) (h₁₂ : f₁ ≫ f₂ = f₁₂) (f₂₃ : j ⟶ l) (h₂₃ : f₂ ≫ f₃ = f₂₃) + +/-- When `f₁`, `f₂` and `f₃` are composable morphisms, this is the canonical +morphism `Z^n(f₂, f₃) ⟶ opZ^{n+1}(f₁, f₂)` that is induced both +by `δ : H^n(f₂ ≫ f₃) ⟶ H^{n+1}(f₁)` (see `toCycles_Ψ`) and +by `δ : H^n(f₃) ⟶ H^{n+1}(f₁ ≫ f₂)` (see `Ψ_fromOpcycles`). +See the lemma `πE_d_ιE` for the relation between this definition +and the differentials `d`. -/ +noncomputable def Ψ : X.cycles n₀ f₂ f₃ ⟶ X.opcycles n₁ f₁ f₂ := + X.descCycles n₀ f₂ f₃ _ rfl + (X.δ n₀ n₁ hn₁ f₁ (f₂ ≫ f₃) ≫ X.pOpcycles n₁ f₁ f₂) (by + rw [X.δ_naturality_assoc n₀ n₁ hn₁ f₁ f₂ f₁ (f₂ ≫ f₃) (𝟙 _) (twoδ₂Toδ₁ f₂ f₃ _ rfl) rfl, + Functor.map_id, id_comp, δ_pOpcycles]) + +@[reassoc (attr := simp)] +lemma toCycles_Ψ : + X.toCycles n₀ f₂ f₃ f₂₃ h₂₃ ≫ X.Ψ n₀ n₁ hn₁ f₁ f₂ f₃ = + X.δ n₀ n₁ hn₁ f₁ f₂₃ ≫ X.pOpcycles n₁ f₁ f₂ := by + subst h₂₃ + simp only [Ψ, toCycles_descCycles] + +@[reassoc (attr := simp)] +lemma Ψ_fromOpcycles : + X.Ψ n₀ n₁ hn₁ f₁ f₂ f₃ ≫ X.fromOpcycles n₁ f₁ f₂ f₁₂ h₁₂ = + X.iCycles n₀ f₂ f₃ ≫ X.δ n₀ n₁ hn₁ f₁₂ f₃ := by + rw [← cancel_epi (X.toCycles n₀ f₂ f₃ _ rfl), + toCycles_Ψ_assoc, p_fromOpcycles, toCycles_i_assoc] + exact (X.δ_naturality _ _ _ _ _ _ _ _ _ rfl).symm + +include h₂₃ in +lemma cyclesMap_Ψ : + X.cyclesMap n₀ _ _ _ _ (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂) ≫ + X.Ψ n₀ n₁ hn₁ f₁ f₂ f₃ = 0 := by + rw [← cancel_epi (X.toCycles n₀ f₁₂ f₃ (f₁ ≫ f₂ ≫ f₃) + (by rw [reassoc_of% h₁₂])), comp_zero, + X.toCycles_cyclesMap_assoc n₀ f₁₂ f₃ f₂ f₃ (f₁ ≫ f₂ ≫ f₃) + (by rw [reassoc_of% h₁₂]) f₂₃ h₂₃ (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂) + (twoδ₁Toδ₀ f₁ f₂₃ (f₁ ≫ f₂ ≫ f₃) (by rw [h₂₃])) rfl rfl, + toCycles_Ψ, zero₃_assoc, zero_comp] + +include h₁₂ in +lemma Ψ_opcyclesMap : + X.Ψ n₀ n₁ hn₁ f₁ f₂ f₃ ≫ + X.opcyclesMap n₁ _ _ _ _ (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃) = 0 := by + rw [← cancel_mono (X.fromOpcycles n₁ f₁ f₂₃ (f₁ ≫ f₂ ≫ f₃) (by rw [h₂₃])), + zero_comp, assoc, X.opcyclesMap_fromOpcycles n₁ f₁ f₂ f₁ f₂₃ f₁₂ h₁₂ + (f₁ ≫ f₂ ≫ f₃) (by rw [h₂₃]) (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃) + (twoδ₂Toδ₁ f₁₂ f₃ (f₁ ≫ f₂ ≫ f₃) (by rw [reassoc_of% h₁₂])) rfl rfl, + Ψ_fromOpcycles_assoc, zero₁, comp_zero] + +/-- When `f₁`, `f₂` and `f₃` are composable morphisms, this is the exact sequence +`Z^n(f₁ ≫ f₂, f₃) ⟶ Z^n(f₂, f₃) ⟶ opZ^{n+1}(f₁, f₂) ⟶ opZ^{n+1}(f₁, f₂ ≫ f₃)`. -/ +noncomputable def sequenceΨ : ComposableArrows C 3 := + mk₃ (X.cyclesMap n₀ _ _ _ _ (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂)) + (X.Ψ n₀ n₁ hn₁ f₁ f₂ f₃) + (X.opcyclesMap n₁ _ _ _ _ (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃)) + +lemma cyclesMap_Ψ_exact : + (ShortComplex.mk _ _ (X.cyclesMap_Ψ n₀ n₁ hn₁ f₁ f₂ f₃ f₁₂ h₁₂ f₂₃ h₂₃)).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A z hz + refine ⟨A, 𝟙 _, inferInstance, + X.liftCycles n₀ n₁ hn₁ f₁₂ f₃ (z ≫ X.iCycles n₀ f₂ f₃) ?_, ?_⟩ + · dsimp + rw [assoc, ← X.Ψ_fromOpcycles n₀ n₁ hn₁ f₁ f₂ f₃ f₁₂ h₁₂ , reassoc_of% hz, zero_comp] + · dsimp + rw [← cancel_mono (X.iCycles n₀ f₂ f₃), id_comp, assoc, + X.cyclesMap_i n₀ _ _ _ _ (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂) (𝟙 _) (by cat_disch), + Functor.map_id, comp_id, liftCycles_i] + +lemma Ψ_opcyclesMap_exact : + (ShortComplex.mk _ _ (X.Ψ_opcyclesMap n₀ n₁ hn₁ f₁ f₂ f₃ f₁₂ h₁₂ f₂₃ h₂₃)).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A z₀ hz₀ + dsimp at z₀ hz₀ + obtain ⟨A₁, π₁, _, z₁, hz₁⟩ := + surjective_up_to_refinements_of_epi (X.pOpcycles n₁ f₁ f₂) z₀ + obtain ⟨A₂, π₂, _, z₂, hz₂⟩ := + (X.cokernelSequenceOpcycles_exact n₀ n₁ hn₁ f₁ f₂₃).exact_up_to_refinements z₁ (by + dsimp + have H := X.p_opcyclesMap n₁ f₁ f₂ f₁ f₂₃ + (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃) (𝟙 _) (by cat_disch) + rw [Functor.map_id, id_comp] at H + rw [← H, ← reassoc_of% hz₁, hz₀, comp_zero]) + dsimp at z₂ hz₂ + refine ⟨A₂, π₂ ≫ π₁, inferInstance, z₂ ≫ X.toCycles n₀ f₂ f₃ f₂₃ h₂₃, ?_⟩ + dsimp + rw [← cancel_mono (X.fromOpcycles n₁ f₁ f₂ f₁₂ h₁₂), assoc, assoc, + assoc, assoc, toCycles_Ψ_assoc, p_fromOpcycles, ← reassoc_of% hz₂, + reassoc_of% hz₁, p_fromOpcycles] + +lemma sequenceΨ_exact : + (X.sequenceΨ n₀ n₁ hn₁ f₁ f₂ f₃ f₁₂ h₁₂ f₂₃ h₂₃).Exact := + exact_of_δ₀ + (X.cyclesMap_Ψ_exact n₀ n₁ hn₁ f₁ f₂ f₃ f₁₂ h₁₂ f₂₃ h₂₃).exact_toComposableArrows + (X.Ψ_opcyclesMap_exact n₀ n₁ hn₁ f₁ f₂ f₃ f₁₂ h₁₂ f₂₃ h₂₃).exact_toComposableArrows + +end + + +section + +variable (n₀ n₁ n₂ n₃ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) + {i₀ i₁ i₂ i₃ i₄ i₅ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) + +@[reassoc (attr := simp)] +lemma πE_d_ιE : + X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅ ≫ X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ + X.ιE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ = X.Ψ n₁ n₂ hn₂ f₂ f₃ f₄ := by + rw [← cancel_epi (X.toCycles n₁ f₃ f₄ _ rfl), toCycles_Ψ, + X.toCycles_πE_d_assoc n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ _ rfl, + πE_ιE, toCycles_i_assoc, ← X.δ_naturality_assoc n₁ n₂ hn₂ (f₁ ≫ f₂) (f₃ ≫ f₄) f₂ (f₃ ≫ f₄) + (twoδ₁Toδ₀ f₁ f₂ _ rfl) (𝟙 _) rfl, Functor.map_id, id_comp] + +end + +section + +variable (n₀ n₁ n₂ n₃ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) + {i₀ i₁ i₂ : ι} + (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) + +@[reassoc (attr := simp)] +lemma πE_EIsoH_hom : + X.πE n₀ n₁ n₂ hn₁ hn₂ (𝟙 i₀) f₁ (𝟙 i₁) ≫ (X.EIsoH n₀ n₁ n₂ hn₁ hn₂ f₁).hom = + (X.cyclesIsoH n₁ n₂ hn₂ f₁).hom := by + obtain rfl : n₀ = n₁ - 1 := by lia + simp [πE, cyclesIsoH, EIsoH] + +@[reassoc] +lemma d_EIsoH_hom : + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ (𝟙 i₀) f₁ (𝟙 i₁) f₂ (𝟙 i₂) ≫ + (X.EIsoH n₁ n₂ n₃ hn₂ hn₃ f₁).hom = + (X.EIsoH n₀ n₁ n₂ hn₁ hn₂ f₂).hom ≫ X.δ n₁ n₂ hn₂ f₁ f₂ := by + rw [← cancel_epi (X.πE n₀ n₁ n₂ hn₁ hn₂ (𝟙 i₁) f₂ (𝟙 i₂)), + ← cancel_epi (X.toCycles n₁ (𝟙 i₁) f₂ f₂ (by simp)), + X.toCycles_πE_d_assoc n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ (𝟙 i₀) f₁ (𝟙 i₁) f₂ (𝟙 i₂) f₁ (by simp), + πE_EIsoH_hom, πE_EIsoH_hom_assoc, cyclesIsoH_inv_hom_id, comp_id, + cyclesIsoH_inv_hom_id_assoc] + +end + +end SpectralObject + +end Abelian + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean new file mode 100644 index 00000000000000..389269ffaa6d56 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -0,0 +1,462 @@ +/- +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.SpectralObject.Basic +public import Mathlib.Algebra.Homology.SpectralSequence.ComplexShape +public import Mathlib.Data.EInt.Basic +public import Batteries.Tactic.Lint + +/-! +# Shapes of spectral sequences obtained from a spectral object + +This file prepares for the construction of the spectral sequence +of a spectral object in an abelian category which shall be conducted +in the file `Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean`. + +In this file, we introduce a structure `SpectralSequenceMkData` which +contains a recipe for the construction of the pages of the spectral sequence. +For example, from a spectral object `X` indexed by `EInt` the definition +`mkDataE₂Cohomological` will allow to construct an `E₂` cohomological +spectral sequence such that the object on position `(p, q)` on the `r`th +page is `E^{p + q}(q - r + 2 ≤ q ≤ q + 1 ≤ q + r - 1)`. +The data (and properties) in the structure `SpectralSequenceMkData` allow +to define the pages and the differentials directly from the `SpectralObject` +API from the files +`Mathlib/Algebra/Homology/SpectralObject/Page.lean` and +`Mathlib/Algebra/Homology/SpectralObject/Differentials.lean`. +However, the computation of the homology of the differentials in +`Mathlib/Algebra/Homology/SpectralObject/Homology.lean` may not directly +apply: we introduce a typeclass `HasSpectralSequence` which puts +additional conditions on the spectral object so that the homology of a +page identifies to the next page. These conditions are automatically +satisfied for `mkDataE₂Cohomological`, but this design allows +to obtain a spectral sequence with objects of the pages indexed +by `ℕ × ℕ` instead of `ℤ × ℤ` when suitable conditions are satisfied by +a spectral object indexed by `EInt` (see `mkDataE₂CohomologicalNat` +and the typeclass `IsFirstQuadrant`). + +-/ + +/-! +# The spectral sequence of a spectral object + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits ComposableArrows + +namespace Abelian + +namespace SpectralObject + +variable {C ι κ : Type*} [Category C] [Abelian C] [Preorder ι] + {c : ℤ → ComplexShape κ} {r₀ : ℤ} + +variable (ι c r₀) in +/-- This data is a recipe in order to produce a spectral sequence starting on +page `r₀` (where the `r`th page is of shape `c r`) from a spectral object +indexed by `ι`. The object on page `r` at the position `pq : κ` shall be +`E^(deg pq)(i₀ ≤ i₁ ≤ i₂ ≤ i₃)`, where `i₀ ≤ i₁ ≤ i₂ ≤ i₃` are elements in the +index type `ι` of the spectral object and `deg pq : ℤ` is a cohomological degree. +The indices `i₀` and `i₃` depend on `r` and `pq`, but `i₁`, `i₂` only depend on `pq`. +Various conditions are added in order to construct the differentials on the pages +and show that the homology of a page identifies to the next page; in certain +cases, additional conditions may be required on the spectral object, +see the typeclass `HasSpectralSequence`. -/ +structure SpectralSequenceMkData where + /-- The cohomological degree of objects in the pages -/ + deg : κ → ℤ + /-- The zeroth index -/ + i₀ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : ι + /-- The first index -/ + i₁ (pq : κ) : ι + /-- The second index -/ + i₂ (pq : κ) : ι + /-- The third index -/ + i₃ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : ι + le₀₁ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : i₀ r hr pq ≤ i₁ pq + le₁₂ (pq : κ) : i₁ pq ≤ i₂ pq + le₂₃ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : i₂ pq ≤ i₃ r hr pq + hc (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : deg pq + 1 = deg pq' + hc₀₂ (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : i₀ r hr pq = i₂ pq' + hc₁₃ (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : i₁ pq = i₃ r hr pq' + antitone_i₀ (r r' : ℤ) (hr : r₀ ≤ r) (hrr' : r ≤ r') (pq : κ) : + i₀ r' (by lia) pq ≤ i₀ r hr pq + monotone_i₃ (r r' : ℤ) (hr : r₀ ≤ r) (hrr' : r ≤ r') (pq : κ) : + i₃ r hr pq ≤ i₃ r' (by lia) pq + i₀_prev' (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : + i₀ (r + 1) (by lia) pq = i₁ pq' + i₃_next' (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : + i₃ (r + 1) (by lia) pq' = i₂ pq + +namespace SpectralSequenceMkData + +variable (data : SpectralSequenceMkData ι c r₀) + +lemma i₀_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) : + data.i₀ r' (by lia) pq ≤ data.i₀ r hr pq := by + apply data.antitone_i₀ + lia + +lemma i₃_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) : + data.i₃ r hr pq ≤ data.i₃ r' (by lia) pq := by + apply data.monotone_i₃ + lia + +lemma i₀_prev (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq pq' : κ) + (hpq : (c r).Rel pq pq') : + data.i₀ r' (by lia) pq = data.i₁ pq' := by + subst hrr' + exact data.i₀_prev' r hr pq pq' hpq + +lemma i₃_next (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq pq' : κ) + (hpq : (c r).Rel pq pq') : + data.i₃ r' (by lia) pq' = data.i₂ pq := by + subst hrr' + exact data.i₃_next' r hr pq pq' hpq + +end SpectralSequenceMkData + +/-- The data which allows to construct an `E₂`-cohomological spectral sequence +indexed by `ℤ × ℤ` from a spectral object indexed by `EInt`. -/ +@[simps!] +def mkDataE₂Cohomological : + SpectralSequenceMkData EInt (fun r ↦ ComplexShape.up' (⟨r, 1 - r⟩ : ℤ × ℤ)) 2 where + deg pq := pq.1 + pq.2 + i₀ r hr pq := EInt.mk (pq.2 - r + 2) + i₁ pq := EInt.mk pq.2 + i₂ pq := EInt.mk (pq.2 + 1) + i₃ r hr pq := EInt.mk (pq.2 + r - 1) + le₀₁ r hr pq := by simp; lia + le₁₂ pq := by simp + le₂₃ r hr pq := by simp; lia + hc := by rintro r _ pq _ rfl; dsimp; lia + hc₀₂ := by rintro r hr pq _ rfl; simp; lia + hc₁₃ := by rintro r hr pq _ rfl; simp; lia + antitone_i₀ r r' hr hrr' pq := by simp; lia + monotone_i₃ r r' hr hrr' pq := by simp; lia + i₀_prev' := by rintro r hr pq _ rfl; dsimp; lia + i₃_next' := by rintro r hr pq _ rfl; dsimp; lia + +/-- The data which allows to construct an `E₂`-cohomological spectral sequence +indexed by `ℕ × ℕ` from a spectral object indexed by `EInt`. (Note: additional +assumptions on the spectral object are required.) -/ +@[simps!] +def mkDataE₂CohomologicalNat : + SpectralSequenceMkData EInt + (fun r ↦ ComplexShape.spectralSequenceNat ⟨r, 1 - r⟩) 2 where + deg pq := pq.1 + pq.2 + i₀ r hr pq := EInt.mk (pq.2 - r + 2) + i₁ pq := EInt.mk pq.2 + i₂ pq := EInt.mk (pq.2 + 1) + i₃ r hr pq := EInt.mk (pq.2 + r - 1) + le₀₁ r hr pq := by simp; lia + le₁₂ pq := by simp + le₂₃ r hr pq := by simp; lia + hc r _ pq pq' hpq := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq; lia + hc₀₂ r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + hc₁₃ r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + antitone_i₀ r r' hrr' hr pq := by simp; lia + monotone_i₃ r r' hrr' hr pq := by simp; lia + i₀_prev' r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + i₃_next' r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + +-- to be moved +lemma _root_.Fin.clamp_le_clamp {a b : ℕ} (h : a ≤ b) (m : ℕ) : + Fin.clamp a m ≤ Fin.clamp b m := by + rw [Fin.le_iff_val_le_val] + exact min_le_min_right m h + +/-- The data which allows to construct an `E₂`-cohomological spectral sequence +indexed by `ℤ × Fin l` from a spectral object indexed by `Fin (l + 1)`. -/ +@[simps deg i₀ i₁ i₂ i₃] +def mkDataE₂CohomologicalFin (l : ℕ) : + SpectralSequenceMkData (Fin (l + 1)) + (fun r ↦ ComplexShape.spectralSequenceFin l ⟨r, 1 - r⟩) 2 where + deg pq := pq.1 + pq.2.1 + i₀ r hr pq := ⟨(pq.2.1 - (r - 2)).toNat, by grind⟩ + i₁ pq := pq.2.castSucc + i₂ pq := pq.2.succ + i₃ r hr pq := Fin.clamp (pq.2.1 + (r - 1)).toNat _ + le₀₁ r hr := by rintro ⟨p, q, hq⟩; simp; lia + le₁₂ pq := by simp [Fin.le_iff_val_le_val] + le₂₃ r hr pq := by + simp only [Fin.le_iff_val_le_val, Fin.val_succ, le_min_iff, Fin.clamp] + grind + hc _ _ _ _ := fun ⟨h₁, h₂⟩ ↦ by lia + hc₀₂ r hr := by + rintro ⟨a₁, ⟨a₂, _⟩⟩ ⟨b₁, ⟨b₂, _⟩⟩ ⟨h₁, h₂⟩ + ext + grind + hc₁₃ r hr := by + rintro ⟨a₁, ⟨a₂, _⟩⟩ ⟨b₁, ⟨b₂, _⟩⟩ ⟨h₁, h₂⟩ + rw [Fin.ext_iff] + dsimp at h₁ h₂ ⊢ + grind + antitone_i₀ r r' hr hrr' := by + rintro ⟨a, ⟨a', _⟩⟩ + dsimp + rw [Fin.mk_le_mk] + lia + monotone_i₃ r r' hr hrr' := by + rintro ⟨a, ⟨a', _⟩⟩ + dsimp + rw [Fin.mk_le_mk] + apply Fin.clamp_le_clamp + lia + i₀_prev' r hr := by + rintro ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ + ext + dsimp at h₁ h₂ ⊢ + lia + i₃_next' r hr := by + rintro ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ + ext + dsimp at h₁ h₂ ⊢ + grind + +/-- The data which allows to construct an `E₂`-homological spectral sequence +indexed by `ℕ × ℕ` from a spectral object indexed by `EInt`. (Note: additional +assumptions on the spectral object are required.) -/ +@[simps!] +def mkDataE₂HomologicalNat : + SpectralSequenceMkData EInt + (fun r ↦ ComplexShape.spectralSequenceNat ⟨-r, r - 1⟩) 2 where + deg pq := - pq.1 - pq.2 + i₀ r hr pq := EInt.mk (-pq.2 - r + 2) + i₁ pq := EInt.mk (-pq.2) + i₂ pq := EInt.mk (-pq.2 + 1) + i₃ r hr pq := EInt.mk (-pq.2 + r - 1) + le₀₁ r hr pq := by simp; lia + le₁₂ pq := by simp + le₂₃ r hr pq := by simp; lia + hc r _ pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + hc₀₂ r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + hc₁₃ r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + antitone_i₀ r r' hrr' hr pq := by simp; lia + monotone_i₃ r r' hrr' hr pq := by simp; lia + i₀_prev' r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + i₃_next' r hr pq pq' hpq := by + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + lia + +variable (X : SpectralObject C ι) (data : SpectralSequenceMkData ι c r₀) + +/-- Given `X : SpectralObject C ι` and `data : SpectralSequenceMkData ι c r₀`, this is +the property which allows to construct a spectral sequence by using the recipe given +by `data`. The conditions given allow to show that the homology of a page identifies +to the next page. -/ +class HasSpectralSequence : Prop where + isZero_H_obj_mk₁_i₀_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) + (n : ℤ) (hn : n = data.deg pq + 1) : + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₀_le r r' hrr' hr pq)))) + isZero_H_obj_mk₁_i₃_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) + (n : ℤ) (hn : n = data.deg pq - 1) : + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₃_le r r' hrr' hr pq)))) + +variable [X.HasSpectralSequence data] + +lemma isZero_H_obj_mk₁_i₀_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) + (n : ℤ) (hn : n = data.deg pq + 1) : + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₀_le r r' hrr' hr pq)))) := + HasSpectralSequence.isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq n hn + +/-- isZero_H_obj_mk₁_i₀_le' -/ +lemma isZero_H_obj_mk₁_i₀_le' (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) + (n : ℤ) (hn : n = data.deg pq + 1) (i₀' i₀ : ι) + (hi₀' : i₀' = data.i₀ r' (by lia) pq) + (hi₀ : i₀ = data.i₀ r hr pq) : + IsZero ((X.H n).obj (mk₁ (homOfLE (show i₀' ≤ i₀ by + simpa only [hi₀', hi₀] using data.i₀_le r r' hrr' hr pq)))) := by + subst hi₀' hi₀ + exact HasSpectralSequence.isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq n hn + +lemma isZero_H_obj_mk₁_i₃_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) + (n : ℤ) (hn : n = data.deg pq - 1) : + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₃_le r r' hrr' hr pq)))) := + HasSpectralSequence.isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq n hn + +/-- isZero_H_obj_mk₁_i₃_le' -/ +lemma isZero_H_obj_mk₁_i₃_le' (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) + (n : ℤ) (hn : n = data.deg pq - 1) (i₃ i₃' : ι) + (hi₃ : i₃ = data.i₃ r hr pq) + (hi₃' : i₃' = data.i₃ r' (by lia) pq) : + IsZero ((X.H n).obj (mk₁ (homOfLE (show i₃ ≤ i₃' by + simpa only [hi₃, hi₃'] using data.i₃_le r r' hrr' hr pq)))) := by + subst hi₃ hi₃' + exact HasSpectralSequence.isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq n hn + +instance (E : SpectralObject C EInt) : E.HasSpectralSequence mkDataE₂Cohomological where + isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq := by + exfalso + exact hpq _ rfl + isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq := by + exfalso + exact hpq (pq - (r, 1-r)) (by simp) + +lemma _root_.Fin.clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : + Fin.clamp n m = Fin.last _ := by + ext + simpa + +instance {l : ℕ} (E : SpectralObject C (Fin (l + 1))) : + E.HasSpectralSequence (mkDataE₂CohomologicalFin l) where + isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq n hn := by + have : (mkDataE₂CohomologicalFin l).i₀ r' (by lia) pq = + (mkDataE₂CohomologicalFin l).i₀ r hr pq := by + subst hrr' + obtain ⟨k, rfl⟩ := Int.le.dest hr + obtain ⟨p, q, hq⟩ := pq + ext + have h : q ≤ k := by + by_contra! + simp only [ComplexShape.spectralSequenceFin_rel_iff, not_and, Prod.forall] at hpq + obtain ⟨t, rfl⟩ := Nat.le.dest (Nat.add_one_le_of_lt this) + exact hpq _ ⟨t, by lia⟩ rfl (by simp; lia) + simp_all + lia + have := isIso_homOfLE this + apply E.isZero_H_map_mk₁_of_isIso + isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq n hn := by + have : (mkDataE₂CohomologicalFin l).i₃ r hr pq = + (mkDataE₂CohomologicalFin l).i₃ r' (by lia) pq := by + subst hrr' + obtain ⟨p, q, hq⟩ := pq + have h : l < q + r := by + by_contra! + obtain ⟨t, ht⟩ := Int.le.dest this + simp only [ComplexShape.spectralSequenceFin_rel_iff, not_and, Prod.forall] at hpq + exact hpq (p - r) ⟨l - 1 - t, by lia⟩ (by lia) (by lia) + dsimp + rw [add_sub_cancel_right, Fin.clamp_eq_last _ _ (by lia), + Fin.clamp_eq_last _ _ (by lia)] + have := isIso_homOfLE this + apply E.isZero_H_map_mk₁_of_isIso + +section + +variable (Y : SpectralObject C EInt) + +/-- The conditions on a spectral object indexed by `EInt` which allow +to obtain a (convergent) first quadrant `E₂` cohomological spectral sequence. -/ +class IsFirstQuadrant : Prop where + isZero₁ (i j : EInt) (hij : i ≤ j) (hj : j ≤ EInt.mk 0) (n : ℤ) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) + isZero₂ (i j : EInt) (hij : i ≤ j) (n : ℤ) (hi : EInt.mk n < i) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) + +variable [Y.IsFirstQuadrant] + +lemma isZero₁_of_isFirstQuadrant (i j : EInt) (hij : i ≤ j) (hj : j ≤ EInt.mk 0) (n : ℤ) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := + IsFirstQuadrant.isZero₁ i j hij hj n + +lemma isZero₂_of_isFirstQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hi : EInt.mk n < i) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := + IsFirstQuadrant.isZero₂ i j hij n hi + +instance : Y.HasSpectralSequence mkDataE₂CohomologicalNat where + isZero_H_obj_mk₁_i₀_le := by + rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + apply isZero₁_of_isFirstQuadrant + dsimp + simp only [EInt.coe_le_coe_iff] + by_contra! + obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p + r by lia) + obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q + 1 - r by lia) + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + exact hpq ⟨p', q'⟩ (by constructor <;> lia) + isZero_H_obj_mk₁_i₃_le := by + rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + apply isZero₂_of_isFirstQuadrant + dsimp + simp only [EInt.coe_lt_coe_iff, Int.sub_lt_sub_right_iff] + by_contra! + obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p - r by lia) + obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q - 1 + r by lia) + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + exact hpq ⟨p', q'⟩ (by constructor <;> lia) + +end + +section + +variable (Y : SpectralObject C EInt) + +/-- The conditions on a spectral object indexed by `EInt` which allow +to obtain a (convergent) third quadrant `E₂` cohomological spectral sequence, +or a (convergent) first quadrant `E₂` *homological* spectral sequence -/ +class IsThirdQuadrant where + isZero₁ (i j : EInt) (hij : i ≤ j) (hi : EInt.mk 0 < i) (n : ℤ) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) + isZero₂ (i j : EInt) (hij : i ≤ j) (n : ℤ) (hj : j ≤ EInt.mk n) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) + +variable [Y.IsThirdQuadrant] + +lemma isZero₁_of_isThirdQuadrant (i j : EInt) (hij : i ≤ j) (hi : EInt.mk 0 < i) (n : ℤ) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := + IsThirdQuadrant.isZero₁ i j hij hi n + +lemma isZero₂_of_isThirdQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hj : j ≤ EInt.mk n) : + IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := + IsThirdQuadrant.isZero₂ i j hij n hj + +instance : Y.HasSpectralSequence mkDataE₂HomologicalNat where + isZero_H_obj_mk₁_i₀_le := by + rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + apply isZero₂_of_isThirdQuadrant + dsimp + simp only [EInt.coe_le_coe_iff] + by_contra! + obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p - r by lia) + obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q + r - 1 by lia) + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + exact hpq ⟨p', q'⟩ (by constructor <;> lia) + isZero_H_obj_mk₁_i₃_le := by + rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + apply isZero₁_of_isThirdQuadrant + dsimp + simp only [EInt.coe_lt_coe_iff] + by_contra! + obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p + r by lia) + obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q + 1 - r by lia) + simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq + exact hpq ⟨p', q'⟩ (by constructor <;> lia) + +end + +end SpectralObject + +end Abelian + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralObject/Homology.lean b/Mathlib/Algebra/Homology/SpectralObject/Homology.lean new file mode 100644 index 00000000000000..ae3f763e084422 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/Homology.lean @@ -0,0 +1,244 @@ +/- +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.SpectralObject.Differentials +public import Mathlib.CategoryTheory.ComposableArrows.Four + +/-! +# The homology of the differentials of a spectral object + +Let `X` be a spectral object indexed by a category `ι` in an abelian +category `C`. Assume we have seven composable arrows +`f₁`, `f₂`, `f₃`, `f₄`, `f₅`, `f₆`, `f₇` in `ι`. In this file, +we compute the homology of the differentials, i.e. the homology of the short complex +`E^{n - 1}(f₅, f₆, f₇) ⟶ E^n(f₃, f₄, f₅) ⟶ E^{n + 1}(f₁, f₂, f₃)`. +The main definition for this is `dHomologyData` which is an homology data +for this short complex where: +* the cycles are `E^n(f₂ ≫ f₃, f₄, f₅)`; +* the opcycles are `E^n(f₃, f₄, f₅ ≫ f₆)`; +* the homology is `E^n(f₂ ≫ f₃, f₄, f₅ ≫ f₆)`. + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits ComposableArrows Preadditive + +namespace Abelian + +variable {C ι : Type*} [Category C] [Abelian C] [Category ι] + +namespace SpectralObject + +variable (X : SpectralObject C ι) + +section + +variable (n₀ n₁ n₂ n₃ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i₀' i₀ i₁ i₂ i₃ i₃' : ι} (f₁ : i₀ ⟶ i₁) + (f₁' : i₀' ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) (f₃' : i₂ ⟶ i₃') + +lemma epi_EMap (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁ f₂ f₃') + (hα₀ : α.app 0 = 𝟙 _) (hα₁ : α.app 1 = 𝟙 _) (hα₂ : α.app 2 = 𝟙 _) : + Epi (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁ f₂ f₃' α) := by + have := X.πE_EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ α (𝟙 _) (by cat_disch) + rw [cyclesMap_id, id_comp] at this + exact epi_of_epi_fac this + +lemma mono_EMap (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁' f₂ f₃) + (hα₁ : α.app 1 = 𝟙 _) (hα₂ : α.app 2 = 𝟙 _) (hα₃ : α.app 3 = 𝟙 _) : + Mono (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂ f₃ α) := by + have := X.EMap_ιE n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ α (𝟙 _) (by cat_disch) + rw [opcyclesMap_id, comp_id] at this + exact mono_of_mono_fac this + +end + +section + +variable (n₀ n₁ n₂ n₃ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) + {i₀ i₁ i₂ i₃ i₄ i₅ i₆ i₇ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) + (f₂₃ : i₁ ⟶ i₃) (h₂₃ : f₂ ≫ f₃ = f₂₃) + (f₃₄ : i₂ ⟶ i₄) (h₃₄ : f₃ ≫ f₄ = f₃₄) + +@[reassoc (attr := simp)] +lemma d_EMap_fourδ₄Toδ₃ : + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ + X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄) = 0 := by + rw [← cancel_epi (X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅), + ← cancel_epi (X.toCycles n₁ f₃ f₄ f₃₄ h₃₄), comp_zero, comp_zero, + X.toCycles_πE_d_assoc n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ _ rfl f₃₄ h₃₄, + X.πE_EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ + (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄) (𝟙 _) (by ext <;> simp; rfl), + cyclesMap_id, Category.id_comp, δ_toCycles_assoc, δToCycles_πE] + +instance : + Epi (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := + X.epi_EMap _ _ _ _ _ _ _ _ _ _ rfl rfl rfl + +lemma isIso_EMap_fourδ₄Toδ₃ (h : ((X.H n₁).map (twoδ₁Toδ₀ f₃ f₄ f₃₄ h₃₄) = 0)) : + IsIso (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := by + apply ShortComplex.isIso_homologyMap_of_epi_of_isIso_of_mono' + · exact (X.exact₂ _ f₃ f₄ f₃₄ h₃₄).epi_f h + · dsimp + convert inferInstanceAs (IsIso ((X.H n₂).map (𝟙 _))) + cat_disch + · dsimp + convert inferInstanceAs (Mono ((X.H n₃).map (𝟙 (mk₁ f₁)))) + cat_disch + +lemma isIso_EMap_fourδ₄Toδ₃_of_isZero (h : IsZero ((X.H n₁).obj (mk₁ f₄))) : + IsIso (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := by + apply X.isIso_EMap_fourδ₄Toδ₃ + apply h.eq_of_tgt + +@[reassoc (attr := simp)] +lemma EMap_fourδ₁Toδ₀_d : + X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) ≫ + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ = 0 := by + rw [← cancel_mono (X.ιE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃), + ← cancel_mono (X.fromOpcycles n₂ f₂ f₃ f₂₃ h₂₃), zero_comp, zero_comp, assoc, + assoc, X.d_ιE_fromOpcycles n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₂₃ h₂₃ _ rfl _ rfl] + rw [X.EMap_ιE_assoc n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ + (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) (𝟙 _) (by ext <;> simp <;> rfl), + opcyclesMap_id, fromOpcyles_δ, id_comp, ιE_δFromOpcycles] + +instance : + Mono (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := + X.mono_EMap _ _ _ _ _ _ _ _ _ _ rfl rfl rfl + +lemma isIso_EMap_fourδ₁Toδ₀ (h : ((X.H n₂).map (twoδ₂Toδ₁ f₂ f₃ f₂₃ h₂₃) = 0)) : + IsIso (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := by + apply ShortComplex.isIso_homologyMap_of_epi_of_isIso_of_mono' + · dsimp + convert inferInstanceAs (Epi ((X.H n₀).map (𝟙 _))) + cat_disch + · dsimp + convert inferInstanceAs (IsIso ((X.H n₁).map (𝟙 _))) + cat_disch + · exact (X.exact₂ n₂ f₂ f₃ f₂₃ h₂₃).mono_g h + +lemma isIso_EMap_fourδ₁Toδ₀_of_isZero (h : IsZero ((X.H n₂).obj (mk₁ f₂))) : + IsIso (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := by + apply X.isIso_EMap_fourδ₁Toδ₀ + apply h.eq_of_src + + +/-- The (exact) sequence expressing `E^n(f₁, f₂, f₃ ≫ f₄)` as the cokernel +of the differential `E^{n-1}(f₃, f₄, f₅) ⟶ E^n(f₁, f₂, f₃)` -/ +@[simps!] +noncomputable def dCokernelSequence : ShortComplex C := + ShortComplex.mk _ _ (X.d_EMap_fourδ₄Toδ₃ n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₃₄ h₃₄) + +instance : Epi (X.dCokernelSequence n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₃₄ h₃₄).g := by + dsimp + infer_instance + +lemma dCokernelSequence_exact : + (X.dCokernelSequence n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₃₄ h₃₄).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A x₂ hx₂ + dsimp at x₂ hx₂ ⊢ + have hx₂' := hx₂ =≫ X.ιE _ _ _ _ _ _ _ _ + simp only [assoc, zero_comp] at hx₂' + rw [X.EMap_ιE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄) + (threeδ₃Toδ₂ f₂ f₃ f₄ f₃₄ h₃₄) (by cat_disch)] at hx₂' + obtain ⟨A₁, π₁, _, x₁, hx₁⟩ := + ((X.sequenceΨ_exact n₁ n₂ hn₂ f₂ f₃ f₄ _ rfl + f₃₄ h₃₄).exact 1).exact_up_to_refinements (x₂ ≫ X.ιE _ _ _ _ _ _ _ _) (by + dsimp [sequenceΨ, Precomp.map] + rw [assoc, hx₂']) + dsimp [sequenceΨ, Precomp.map] at x₁ hx₁ + refine ⟨A₁, π₁, inferInstance, x₁ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅, ?_⟩ + rw [← cancel_mono (X.ιE _ _ _ _ _ _ _ _), assoc, assoc, assoc, hx₁, πE_d_ιE] + +/-- The (exact) sequence expressing `E^n(f₂ ≫ f₃, f₄, f₅)` as the kernel +of the differential `E^n(f₃, f₄, f₅) ⟶ E^{n+1}(f₁, f₂, f₃)` -/ +@[simps!] +noncomputable def dKernelSequence : ShortComplex C := + ShortComplex.mk _ _ (X.EMap_fourδ₁Toδ₀_d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₂₃ h₂₃) + +instance : Mono (X.dKernelSequence n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₂₃ h₂₃).f := by + dsimp + infer_instance + +lemma dKernelSequence_exact : + (X.dKernelSequence n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₂₃ h₂₃).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A x₂ hx₂ + dsimp at x₂ hx₂ ⊢ + obtain ⟨A₁, π₁, _, y₂, hy₂⟩ := + surjective_up_to_refinements_of_epi (X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅) x₂ + have hy₂' := hy₂ =≫ (X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ X.ιE _ _ _ _ _ _ _ _) + simp only [assoc, reassoc_of% hx₂, zero_comp, comp_zero, πE_d_ιE] at hy₂' + obtain ⟨A₂, π₂, _, y₁, hy₁⟩ := + ((X.sequenceΨ_exact n₁ n₂ hn₂ f₂ f₃ f₄ + f₂₃ h₂₃ _ rfl).exact 0).exact_up_to_refinements y₂ hy₂'.symm + dsimp [sequenceΨ] at y₁ hy₁ + refine ⟨A₂, π₂ ≫ π₁, inferInstance, y₁ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅, ?_⟩ + rw [assoc, assoc, hy₂, reassoc_of% hy₁, + X.πE_EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) + (threeδ₁Toδ₀ f₂ f₃ f₄ f₂₃ h₂₃) (by ext <;> simp; rfl)] + +end + +variable (n₀ n₁ n₂ n₃ n₄ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) (hn₄ : n₃ + 1 = n₄) + {i₀ i₁ i₂ i₃ i₄ i₅ i₆ i₇ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) (f₆ : i₅ ⟶ i₆) (f₇ : i₆ ⟶ i₇) + (f₂₃ : i₁ ⟶ i₃) (h₂₃ : f₂ ≫ f₃ = f₂₃) + (f₅₆ : i₄ ⟶ i₆) (h₅₆ : f₅ ≫ f₆ = f₅₆) + +/-- The short complex `E^{n₁}(f₅, f₆, f₇) ⟶ E^{n₀}(f₃, f₄, f₅) ⟶ E^{n₂}(f₁, f₂, f₃)` +given by the differentials of a spectral object. -/ +@[simps!] +noncomputable def dShortComplex : ShortComplex C := + ShortComplex.mk _ _ (X.d_d n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ f₁ f₂ f₃ f₄ f₅ f₆ f₇) + +@[reassoc] +lemma EMap_fourδ₁Toδ₀_EMap_fourδ₄Toδ₃ : + X.EMap n₁ n₂ n₃ hn₂ hn₃ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) ≫ + X.EMap n₁ n₂ n₃ hn₂ hn₃ f₃ f₄ f₅ f₃ f₄ f₅₆ (fourδ₄Toδ₃ f₃ f₄ f₅ f₆ f₅₆ h₅₆) = + X.EMap n₁ n₂ n₃ hn₂ hn₃ f₂₃ f₄ f₅ f₂₃ f₄ f₅₆ (fourδ₄Toδ₃ f₂₃ f₄ f₅ f₆ f₅₆ h₅₆) ≫ + X.EMap n₁ n₂ n₃ hn₂ hn₃ f₂₃ f₄ f₅₆ f₃ f₄ f₅₆ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅₆ f₂₃ h₂₃) := by + simp only [← EMap_comp] + congr 1 + ext <;> simp + +/-- The homology data of the short complex +`E^{n-1}(f₅, f₆, f₇) ⟶ E^{n}(f₃, f₄, f₅) ⟶ E^{n+1}(f₁, f₂, f₃)` for which +* the cycles are `E^n(f₂ ≫ f₃, f₄, f₅)`; +* the opcycles are `E^n(f₃, f₄, f₅ ≫ f₆)`; +* the homology is `E^n(f₂ ≫ f₃, f₄, f₅ ≫ f₆)`. -/ +@[simps!] +noncomputable def dHomologyData : + (X.dShortComplex n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ f₁ f₂ f₃ f₄ f₅ f₆ f₇).HomologyData := + ShortComplex.HomologyData.ofEpiMonoFactorisation + (X.dShortComplex n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ f₁ f₂ f₃ f₄ f₅ f₆ f₇) + (X.dKernelSequence_exact n₁ n₂ n₃ n₄ hn₂ hn₃ hn₄ f₁ f₂ f₃ f₄ f₅ f₂₃ h₂₃).fIsKernel + (X.dCokernelSequence_exact n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₃ f₄ f₅ f₆ f₇ f₅₆ h₅₆).gIsCokernel + (X.EMap_fourδ₁Toδ₀_EMap_fourδ₄Toδ₃ n₁ n₂ n₃ hn₂ hn₃ f₂ f₃ f₄ f₅ f₆ f₂₃ h₂₃ f₅₆ h₅₆) + +/-- The homology of the short complex +`E^{n₁}(f₅, f₆, f₇) ⟶ E^{n₀}(f₃, f₄, f₅) ⟶ E^{n₂}(f₁, f₂, f₃)` identifies to +`E^n(f₂ ≫ f₃, f₄, f₅ ≫ f₆)`. -/ +noncomputable def dHomologyIso : + (X.dShortComplex n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ f₁ f₂ f₃ f₄ f₅ f₆ f₇).homology ≅ + X.E n₁ n₂ n₃ hn₂ hn₃ f₂₃ f₄ f₅₆ := + (X.dHomologyData n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ + f₁ f₂ f₃ f₄ f₅ f₆ f₇ f₂₃ h₂₃ f₅₆ h₅₆).left.homologyIso + +end SpectralObject + +end Abelian + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralObject/Page.lean b/Mathlib/Algebra/Homology/SpectralObject/Page.lean new file mode 100644 index 00000000000000..50d7fe424a68a2 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/Page.lean @@ -0,0 +1,871 @@ +/- +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.SpectralObject.Cycles +public import Mathlib.Algebra.Homology.ShortComplex.ShortExact +public import Mathlib.CategoryTheory.Abelian.Refinements +public import Mathlib.CategoryTheory.ComposableArrows.Three +public import Batteries.Tactic.Lint + +/-! +# Spectral objects in abelian categories + +Let `X` be a spectral object index by the category `ι` +in the abelian category `C`. The purpose of this file +is to introduce the homology `X.E` of the short complex `X.shortComplexE` +`(X.H n₀).obj (mk₁ f₃) ⟶ (X.H n₁).obj (mk₁ f₂) ⟶ (X.H n₂).obj (mk₁ f₁)` +when `f₁`, `f₂` and `f₃` are composable morphisms in `ι` and the +equalities `n₀ + 1 = n₁` and `n₁ + 1 = n₂` hold (both maps in the +short complex are given by `X.δ`). All the relevant objects in the +spectral sequence attached to spectral objects can be defined +in terms of this homology `X.E`: the objects in all pages, including +the page at infinity. + +## References +* [Jean-Louis Verdier, *Des catégories dérivées des catégories abéliennes*, II.4][verdier1996] + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Limits ComposableArrows + +namespace Abelian + +variable {C ι : Type*} [Category C] [Category ι] [Abelian C] + +namespace SpectralObject + +variable (X : SpectralObject C ι) + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i j k l : ι} (f₁ : i ⟶ j) (f₂ : j ⟶ k) (f₃ : k ⟶ l) + +/-- The short complex consisting of the composition of +two morphisms `X.δ`, given three composable morphisms `f₁`, `f₂` +and `f₃` in `ι`, and three consecutive integers. -/ +@[simps] +def shortComplexE : ShortComplex C where + X₁ := (X.H n₀).obj (mk₁ f₃) + X₂ := (X.H n₁).obj (mk₁ f₂) + X₃ := (X.H n₂).obj (mk₁ f₁) + f := X.δ n₀ n₁ hn₁ f₂ f₃ + g := X.δ n₁ n₂ hn₂ f₁ f₂ + +/-- The homology of the short complex `shortComplexE` consisting of +two morphisms `X.δ`. In the documentation, we shorten it as `E^n₁(f₁, f₂, f₃)` -/ +noncomputable def E : C := (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).homology + +lemma isZero_E_of_isZero_H (h : IsZero ((X.H n₁).obj (mk₁ f₂))) : + IsZero (X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃) := + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).exact_iff_isZero_homology.1 + (ShortComplex.exact_of_isZero_X₂ _ h) + +end + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i j k l : ι} + {i j k l : ι} (f₁ : i ⟶ j) (f₂ : j ⟶ k) (f₃ : k ⟶ l) + {i' j' k' l' : ι} (f₁' : i' ⟶ j') (f₂' : j' ⟶ k') (f₃' : k' ⟶ l') + {i'' j'' k'' l'' : ι} (f₁'' : i'' ⟶ j'') (f₂'' : j'' ⟶ k'') (f₃'' : k'' ⟶ l'') + (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁' f₂' f₃') + (β : mk₃ f₁' f₂' f₃' ⟶ mk₃ f₁'' f₂'' f₃'') + (γ : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁'' f₂'' f₃'') + +/-- The functoriality of `shortComplexE` with respect to morphisms +in `ComposableArrows ι 3`. -/ +@[simps] +def shortComplexEMap : + X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ⟶ + X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃' where + τ₁ := (X.H n₀).map (homMk₁ (α.app 2) (α.app 3) (naturality' α 2 3)) + τ₂ := (X.H n₁).map (homMk₁ (α.app 1) (α.app 2) (naturality' α 1 2)) + τ₃ := (X.H n₂).map (homMk₁ (α.app 0) (α.app 1) (naturality' α 0 1)) + comm₁₂ := δ_naturality .. + comm₂₃ := δ_naturality .. + +@[simp] +lemma shortComplexEMap_id : + X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁ f₂ f₃ (𝟙 _) = 𝟙 _ := by + ext + all_goals dsimp; convert (X.H _).map_id _; cat_disch + +@[reassoc, simp] +lemma shortComplexEMap_comp : + X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁'' f₂'' f₃'' (α ≫ β) = + X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α ≫ + X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃' f₁'' f₂'' f₃'' β := by + ext + all_goals dsimp; rw [← Functor.map_comp]; congr 1; cat_disch + +/-- The functoriality of `E` with respect to morphisms +in `ComposableArrows ι 3`. -/ +noncomputable def EMap : + X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ⟶ X.E n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃' := + ShortComplex.homologyMap (X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α) + +@[simp] +lemma EMap_id : + X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁ f₂ f₃ (𝟙 _) = 𝟙 _ := by + dsimp only [EMap] + rw [shortComplexEMap_id, ShortComplex.homologyMap_id] + rfl + +@[reassoc, simp] +lemma EMap_comp : + X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁'' f₂'' f₃'' (α ≫ β) = + X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α ≫ + X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃' f₁'' f₂'' f₃'' β := by + dsimp only [EMap] + rw [shortComplexEMap_comp, ShortComplex.homologyMap_comp] + +lemma isIso_EMap + (h₀ : IsIso ((X.H n₀).map ((functorArrows ι 2 3 3).map α))) + (h₁ : IsIso ((X.H n₁).map ((functorArrows ι 1 2 3).map α))) + (h₂ : IsIso ((X.H n₂).map ((functorArrows ι 0 1 3).map α))) : + IsIso (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α) := by + have : IsIso (shortComplexEMap X n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α) := by + apply (config := { allowSynthFailures := true}) + ShortComplex.isIso_of_isIso <;> assumption + dsimp [EMap] + infer_instance + +end + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) + {i j k : ι} (f : i ⟶ j) (g : j ⟶ k) + +lemma δ_eq_zero_of_isIso₁ (hf : IsIso f) : + X.δ n₀ n₁ hn₁ f g = 0 := by + simpa only [Preadditive.IsIso.comp_left_eq_zero] using X.zero₃ n₀ n₁ hn₁ f g _ rfl + +lemma δ_eq_zero_of_isIso₂ (hg : IsIso g) : + X.δ n₀ n₁ hn₁ f g = 0 := by + simpa only [Preadditive.IsIso.comp_right_eq_zero] using X.zero₁ n₀ n₁ hn₁ f g _ rfl + +end + +lemma isZero_H_obj_of_isIso (n : ℤ) {i j : ι} (f : i ⟶ j) (hf : IsIso f) : + IsZero ((X.H n).obj (mk₁ f)) := by + let e : mk₁ (𝟙 i) ≅ mk₁ f := isoMk₁ (Iso.refl _) (asIso f) (by simp) + refine IsZero.of_iso ?_ ((X.H n).mapIso e.symm) + have h := X.zero₂ n (𝟙 i) (𝟙 i) (𝟙 i) (by simp) + rw [← Functor.map_comp] at h + rw [IsZero.iff_id_eq_zero, ← Functor.map_id, ← h] + congr 1 + cat_disch + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i j k l : ι} (f₁ : i ⟶ j) (f₂ : j ⟶ k) (f₃ : k ⟶ l) + (f₁₂ : i ⟶ k) (h₁₂ : f₁ ≫ f₂ = f₁₂) (f₂₃ : j ⟶ l) (h₂₃ : f₂ ≫ f₃ = f₂₃) + +/-- `E^n₁(f₁, f₂, f₃)` identifies to the cokernel +of `δToCycles : H^{n₀}(f₃) ⟶ Z^{n₁}(f₁, f₂)`. -/ +@[simps] +noncomputable def leftHomologyDataShortComplexE : + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).LeftHomologyData := by + let hi := (X.kernelSequenceCycles_exact _ _ hn₂ f₁ f₂).fIsKernel + have : hi.lift (KernelFork.ofι _ (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).zero) = + X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃ := + Fork.IsLimit.hom_ext hi (by simpa using hi.fac _ .zero) + refine { + K := X.cycles n₁ f₁ f₂ + H := cokernel (X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃) + i := X.iCycles n₁ f₁ f₂ + π := cokernel.π _ + wi := by simp + hi := hi + wπ := by rw [this]; simp + hπ := by + refine (IsColimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 + (cokernelIsCokernel (X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃)) + · exact parallelPair.ext (Iso.refl _) (Iso.refl _) (by simpa) (by simp) + · exact Cofork.ext (Iso.refl _)} + +@[simp] +lemma leftHomologyDataShortComplexE_f' : + (X.leftHomologyDataShortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).f' = + X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃ := by + let hi := (X.kernelSequenceCycles_exact _ _ hn₂ f₁ f₂).fIsKernel + exact Fork.IsLimit.hom_ext hi (by simpa using hi.fac _ .zero) + +/-- The cycles of the short complex `shortComplexE` at `E^{n₁}(f₁, f₂, f₃)` +identifies to `Z^{n₁}(f₁, f₂)`. -/ +noncomputable def cyclesIso : + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).cycles ≅ X.cycles n₁ f₁ f₂ := + (X.leftHomologyDataShortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).cyclesIso + +@[reassoc (attr := simp)] +lemma cyclesIso_inv_i : + (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).inv ≫ + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).iCycles = X.iCycles n₁ f₁ f₂ := + ShortComplex.LeftHomologyData.cyclesIso_inv_comp_iCycles _ + +@[reassoc (attr := simp)] +lemma cyclesIso_hom_i : + (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).hom ≫ X.iCycles n₁ f₁ f₂ = + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).iCycles := + ShortComplex.LeftHomologyData.cyclesIso_hom_comp_i _ + +/-- The epimorphism `Z^{n₁}(f₁, f₂) ⟶ E^{n₁}(f₁, f₂, f₃)`. -/ +noncomputable def πE : X.cycles n₁ f₁ f₂ ⟶ X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ := + (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).inv ≫ + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).homologyπ + deriving Epi + +@[reassoc (attr := simp)] +lemma δToCycles_cyclesIso_inv : + X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃ ≫ (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).inv = + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).toCycles := by + rw [← cancel_mono (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).iCycles, Category.assoc, + cyclesIso_inv_i, δToCycles_iCycles, ShortComplex.toCycles_i, shortComplexE_f] + +@[reassoc (attr := simp)] +lemma δToCycles_πE : + X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ = 0 := by + simp only [πE, δToCycles_cyclesIso_inv_assoc, ShortComplex.toCycles_comp_homologyπ] + +/-- The (exact) sequence `H^{n-1}(f₃) ⟶ Z^n(f₁, f₂) ⟶ E^n(f₁, f₂, f₃) ⟶ 0`. -/ +@[simps] +noncomputable def cokernelSequenceCyclesE : ShortComplex C := + ShortComplex.mk _ _ (X.δToCycles_πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃) + +/-- The short complex `H^{n-1}(f₃) ⟶ Z^n(f₁, f₂) ⟶ E^n(f₁, f₂, f₃)` identifies +to the cokernel sequence of the definition of the homology of the short +complex `shortComplexE` as a cokernel of `ShortComplex.toCycles`. -/ +@[simps!] +noncomputable def cokernelSequenceCyclesEIso : + X.cokernelSequenceCyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≅ ShortComplex.mk _ _ + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).toCycles_comp_homologyπ := + ShortComplex.isoMk (Iso.refl _) (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).symm + (Iso.refl _) (by simp) (by simp [πE]) + +lemma cokernelSequenceCyclesE_exact : + (X.cokernelSequenceCyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).Exact := + ShortComplex.exact_of_iso (X.cokernelSequenceCyclesEIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).symm + (ShortComplex.exact_of_g_is_cokernel _ (ShortComplex.homologyIsCokernel _)) + +instance : Epi (X.cokernelSequenceCyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).g := by + dsimp; infer_instance + +/-- `E^n₁(f₁, f₂, f₃)` identifies to the kernel +of `δFromOpcycles : opZ^{n₁}(f₂, f₃) ⟶ H^{n₂}(f₁)`. -/ +@[simps] +noncomputable def rightHomologyDataShortComplexE : + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).RightHomologyData := by + let hp := (X.cokernelSequenceOpcycles_exact _ _ hn₁ f₂ f₃).gIsCokernel + have : hp.desc (CokernelCofork.ofπ _ (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).zero) = + X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃ := + Cofork.IsColimit.hom_ext hp (by simpa using hp.fac _ .one) + refine { + Q := X.opcycles n₁ f₂ f₃ + H := kernel (X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃) + p := X.pOpcycles n₁ f₂ f₃ + ι := kernel.ι _ + wp := by simp + hp := hp + wι := by rw [this]; simp + hι := by + refine (IsLimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 + (kernelIsKernel (X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃)) + · exact parallelPair.ext (Iso.refl _) (Iso.refl _) (by simpa) (by simp) + · exact Fork.ext (Iso.refl _) } + +@[simp] +lemma rightHomologyDataShortComplexE_g' : + (X.rightHomologyDataShortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).g' = + X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃ := by + let hp := (X.cokernelSequenceOpcycles_exact _ _ hn₁ f₂ f₃).gIsCokernel + exact Cofork.IsColimit.hom_ext hp (by simpa using hp.fac _ .one) + +/-- The opcycles of the short complex `shortComplexE` at `E^{n₁}(f₁, f₂, f₃)` +identifies to `opZ^{n₁}(f₂, f₃)`. -/ +noncomputable def opcyclesIso : + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).opcycles ≅ X.opcycles n₁ f₂ f₃ := + (X.rightHomologyDataShortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).opcyclesIso + +@[reassoc (attr := simp)] +lemma p_opcyclesIso_hom : + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).pOpcycles ≫ + (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).hom = + X.pOpcycles n₁ f₂ f₃ := + ShortComplex.RightHomologyData.pOpcycles_comp_opcyclesIso_hom _ + +@[reassoc (attr := simp)] +lemma p_opcyclesIso_inv : + X.pOpcycles n₁ f₂ f₃ ≫ (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).inv = + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).pOpcycles := + (X.rightHomologyDataShortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).p_comp_opcyclesIso_inv + +/-- The monomorphism `E^{n₁}(f₁, f₂, f₃) ⟶ opZ^{n₁}(f₂, f₃) ⟶ `. -/ +noncomputable def ιE : X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ⟶ X.opcycles n₁ f₂ f₃ := + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).homologyι ≫ + (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).hom + deriving Mono + +@[reassoc (attr := simp)] +lemma opcyclesIso_hom_δFromOpcycles : + (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).hom ≫ X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃ = + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).fromOpcycles := by + rw [← cancel_epi (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).pOpcycles, + p_opcyclesIso_hom_assoc, ShortComplex.p_fromOpcycles, shortComplexE_g, + pOpcycles_δFromOpcycles] + +@[reassoc (attr := simp)] +lemma ιE_δFromOpcycles : + X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃ = 0 := by + simp only [ιE, Category.assoc, opcyclesIso_hom_δFromOpcycles, + ShortComplex.homologyι_comp_fromOpcycles] + +@[reassoc (attr := simp)] +lemma πE_ιE : + X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ = + X.iCycles n₁ f₁ f₂ ≫ X.pOpcycles n₁ f₂ f₃ := by + simp [πE, ιE] + +/-- The (exact) sequence `0 ⟶ E^n(f₁, f₂, f₃) ⟶ opZ^n(f₂, f₃) ⟶ H^{n+1}(f₁)`. -/ +@[simps] +noncomputable def kernelSequenceOpcyclesE : ShortComplex C := + ShortComplex.mk _ _ (X.ιE_δFromOpcycles n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃) + +/-- The short complex `E^n(f₁, f₂, f₃) ⟶ opZ^n(f₂, f₃) ⟶ H^{n+1}(f₁)` identifies +to the kernel sequence of the definition of the homology of the short +complex `shortComplexE` as a kernel of `ShortComplex.fromOpcycles`. -/ +@[simps!] +noncomputable def kernelSequenceOpcyclesEIso : + X.kernelSequenceOpcyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≅ + ShortComplex.mk _ _ + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).homologyι_comp_fromOpcycles := + Iso.symm (ShortComplex.isoMk (Iso.refl _) (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃) + (Iso.refl _) (by simp [ιE]) (by simp)) + +lemma kernelSequenceOpcyclesE_exact : + (X.kernelSequenceOpcyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).Exact := + ShortComplex.exact_of_iso (X.kernelSequenceOpcyclesEIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).symm + (ShortComplex.exact_of_f_is_kernel _ (ShortComplex.homologyIsKernel _)) + +instance : Mono (X.kernelSequenceOpcyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).f := by + dsimp; infer_instance + +/-- The (exact) sequence `H^n(f₁) ⊞ H^{n-1}(f₃) ⟶ H^n(f₁ ≫ f₂) ⟶ E^n(f₁, f₂, f₃) ⟶ 0`. -/ +@[simps] +noncomputable def cokernelSequenceE : ShortComplex C where + X₁ := (X.H n₁).obj (mk₁ f₁) ⊞ (X.H n₀).obj (mk₁ f₃) + X₂ := (X.H n₁).obj (mk₁ f₁₂) + X₃ := X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ + f := biprod.desc ((X.H n₁).map (twoδ₂Toδ₁ f₁ f₂ f₁₂ h₁₂)) (X.δ n₀ n₁ hn₁ f₁₂ f₃) + g := X.toCycles n₁ f₁ f₂ f₁₂ h₁₂ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ + zero := by ext <;> simp + +instance : Epi (X.cokernelSequenceE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂).g := by + dsimp; infer_instance + +lemma cokernelSequenceE_exact : + (X.cokernelSequenceE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A x₂ hx₂ + dsimp at x₂ hx₂ + obtain ⟨A₁, π₁, _, y₁, hy₁⟩ := + (X.cokernelSequenceCyclesE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).exact_up_to_refinements + (x₂ ≫ X.toCycles n₁ f₁ f₂ f₁₂ h₁₂) (by simpa using hx₂) + dsimp at y₁ hy₁ + let z := π₁ ≫ x₂ - y₁ ≫ X.δ n₀ n₁ hn₁ f₁₂ f₃ + obtain ⟨A₂, π₂, _, x₁, hx₁⟩ := (X.exact₂ n₁ f₁ f₂ f₁₂ h₁₂).exact_up_to_refinements z (by + have : z ≫ X.toCycles n₁ f₁ f₂ f₁₂ h₁₂ = 0 := by simp [z, hy₁] + simpa only [zero_comp, Category.assoc, toCycles_i] using this =≫ X.iCycles n₁ f₁ f₂) + dsimp at x₁ hx₁ + exact ⟨A₂, π₂ ≫ π₁, epi_comp _ _, biprod.lift x₁ (π₂ ≫ y₁), by simp [z, ← hx₁]⟩ + +section + +variable {A : C} (x : (X.H n₁).obj (mk₁ f₁₂) ⟶ A) + (h : (X.H n₁).map (twoδ₂Toδ₁ f₁ f₂ f₁₂ h₁₂) ≫ x = 0) + (h' : X.δ n₀ n₁ hn₁ f₁₂ f₃ ≫ x = 0) + +/-- Constructor for morphisms for `E^{n₁}(f₁, f₂, f₃)`. -/ +noncomputable def descE : + X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ⟶ A := + (X.cokernelSequenceE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂).desc x (by cat_disch) + +@[reassoc (attr := simp)] +lemma toCycles_πE_descE : + X.toCycles n₁ f₁ f₂ f₁₂ h₁₂ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ + X.descE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ x h h' = x := by + dsimp only [descE] + rw [← Category.assoc] + apply (X.cokernelSequenceE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂).g_desc + +end + +/-- The (exact) sequence `0 ⟶ E^n(f₁, f₂, f₃) ⟶ H^n(f₂ ≫ f₃) ⟶ H^n(f₃) ⊞ H^{n+1}(f₁)`. -/ +@[simps] +noncomputable def kernelSequenceE : ShortComplex C where + X₁ := X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ + X₂ := (X.H n₁).obj (mk₁ f₂₃) + X₃ := (X.H n₁).obj (mk₁ f₃) ⊞ (X.H n₂).obj (mk₁ f₁) + f := X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.fromOpcycles n₁ f₂ f₃ f₂₃ h₂₃ + g := biprod.lift ((X.H n₁).map (twoδ₁Toδ₀ f₂ f₃ f₂₃ h₂₃)) (X.δ n₁ n₂ hn₂ f₁ f₂₃) + zero := by ext <;> simp + +instance : Mono (X.kernelSequenceE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃).f := by + dsimp; infer_instance + +lemma kernelSequenceE_exact : + (X.kernelSequenceE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A x₂ hx₂ + dsimp at x₂ hx₂ + obtain ⟨A₁, π₁, _, x₁, hx₁⟩ := + (X.kernelSequenceOpcyclesE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).exact_up_to_refinements + (X.liftOpcycles n₁ f₂ f₃ f₂₃ h₂₃ x₂ (by simpa using hx₂ =≫ biprod.fst)) (by + dsimp + rw [← X.fromOpcyles_δ n₁ n₂ hn₂ f₁ f₂ f₃ f₂₃ h₂₃, + X.liftOpcycles_fromOpcycles_assoc ] + simpa using hx₂ =≫ biprod.snd) + dsimp at x₁ hx₁ + refine ⟨A₁, π₁, inferInstance, x₁, ?_⟩ + dsimp + rw [← reassoc_of% hx₁, liftOpcycles_fromOpcycles] + +section + +variable {A : C} (x : A ⟶ (X.H n₁).obj (mk₁ f₂₃)) + (h : x ≫ (X.H n₁).map (twoδ₁Toδ₀ f₂ f₃ f₂₃ h₂₃) = 0) + (h' : x ≫ X.δ n₁ n₂ hn₂ f₁ f₂₃ = 0) + +/-- Constructor for morphisms to `E^{n₁}(f₁, f₂, f₃)`. -/ +noncomputable def liftE : + A ⟶ X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ := + (X.kernelSequenceE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃).lift x (by cat_disch) + +@[reassoc (attr := simp)] +lemma liftE_ιE_fromOpcycles : + X.liftE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃ x h h' ≫ X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ + X.fromOpcycles n₁ f₂ f₃ f₂₃ h₂₃ = x := by + apply (X.kernelSequenceE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃).lift_f + +end + +end + +section + +variable (n₀ n₁ n₂ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i₀ i₁ i₂ i₃ : ι} + (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + {i₀' i₁' i₂' i₃' : ι} + (f₁' : i₀' ⟶ i₁') (f₂' : i₁' ⟶ i₂') (f₃' : i₂' ⟶ i₃') + (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁' f₂' f₃') + +@[reassoc] +lemma cyclesIso_inv_cyclesMap + (β : mk₂ f₁ f₂ ⟶ mk₂ f₁' f₂') + (hβ : β = homMk₂ (α.app 0) (α.app 1) (α.app 2) (naturality' α 0 1 (by lia) (by lia)) + (naturality' α 1 2 (by lia) (by lia))) : + (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).inv ≫ + ShortComplex.cyclesMap (X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α) = + X.cyclesMap n₁ f₁ f₂ f₁' f₂' β ≫ + (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃').inv := by + subst hβ + rw [← cancel_mono (ShortComplex.iCycles _), Category.assoc, Category.assoc, + ShortComplex.cyclesMap_i, cyclesIso_inv_i_assoc, cyclesIso_inv_i, + shortComplexEMap_τ₂, cyclesMap_i] + dsimp + +@[reassoc] +lemma opcyclesMap_opcyclesIso_hom + (γ : mk₂ f₂ f₃ ⟶ mk₂ f₂' f₃') + (hγ : γ = homMk₂ (α.app 1) (α.app 2) (α.app 3) (naturality' α 1 2) (naturality' α 2 3)) : + ShortComplex.opcyclesMap (X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α) ≫ + (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃').hom = + (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).hom ≫ X.opcyclesMap n₁ f₂ f₃ f₂' f₃' γ := by + subst hγ + rw [← cancel_epi (ShortComplex.pOpcycles _), ShortComplex.p_opcyclesMap_assoc, + p_opcyclesIso_hom, p_opcyclesIso_hom_assoc, shortComplexEMap_τ₂, p_opcyclesMap] + dsimp + +@[reassoc] +lemma πE_EMap (β : mk₂ f₁ f₂ ⟶ mk₂ f₁' f₂') + (hβ : β = homMk₂ (α.app 0) (α.app 1) (α.app 2) (naturality' α 0 1 (by lia) (by lia)) + (naturality' α 1 2 (by lia) (by lia))) : + X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α = + X.cyclesMap n₁ f₁ f₂ f₁' f₂' β ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃' := by + dsimp [πE, EMap] + simp only [Category.assoc, ShortComplex.homologyπ_naturality, + X.cyclesIso_inv_cyclesMap_assoc n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α β hβ] + +@[reassoc] +lemma EMap_ιE + (γ : mk₂ f₂ f₃ ⟶ mk₂ f₂' f₃') + (hγ : γ = homMk₂ (α.app 1) (α.app 2) (α.app 3) (naturality' α 1 2) (naturality' α 2 3)) : + X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α ≫ X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃' = + X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.opcyclesMap n₁ f₂ f₃ f₂' f₃' γ := by + dsimp [ιE, EMap] + simp only [ShortComplex.homologyι_naturality_assoc, Category.assoc, + X.opcyclesMap_opcyclesIso_hom n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂' f₃' α γ hγ] + +end + +section + +variable (n₀ n₁ n₂ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i₀ i₁ i₂ i₃ : ι} + (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₁₂ : i₀ ⟶ i₂) (f₂₃ : i₁ ⟶ i₃) + (h₁₂ : f₁ ≫ f₂ = f₁₂) (h₂₃ : f₂ ≫ f₃ = f₂₃) + +/-- The map `opZ^n(f₁ ≫ f₂, f₃) ⟶ E^n(f₁, f₂, f₃)`. -/ +noncomputable def opcyclesToE : X.opcycles n₁ f₁₂ f₃ ⟶ X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ := + X.descOpcycles n₀ _ hn₁ _ _ + (X.toCycles n₁ f₁ f₂ f₁₂ h₁₂ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃) (by simp) + +@[reassoc (attr := simp)] +lemma p_opcyclesToE : + X.pOpcycles n₁ f₁₂ f₃ ≫ X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ = + X.toCycles n₁ f₁ f₂ f₁₂ h₁₂ ≫ X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ := by + simp [opcyclesToE] + +@[reassoc (attr := simp)] +lemma opcyclesToE_ιE : + X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ ≫ X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ = + X.opcyclesMap n₁ f₁₂ f₃ f₂ f₃ (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂) := by + rw [← cancel_epi (X.pOpcycles n₁ f₁₂ f₃), p_opcyclesToE_assoc, + πE_ιE, toCycles_i_assoc] + exact (X.p_opcyclesMap _ _ _ _ _ _ _ (by rfl)).symm + +instance : Epi (X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂) := + epi_of_epi_fac (X.p_opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂) + +/-- The (exact) sequence `H^n(f₁) ⟶ opZ^n(f₁ ≫ f₂, f₃) ⟶ E^n(f₁, f₂, f₃) ⟶ 0`. -/ +@[simps!] +noncomputable def cokernelSequenceOpcyclesE : ShortComplex C where + X₁ := (X.H n₁).obj (mk₁ f₁) + X₂ := X.opcycles n₁ f₁₂ f₃ + X₃ := X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ + f := (X.H n₁).map (twoδ₂Toδ₁ f₁ f₂ f₁₂ h₁₂) ≫ X.pOpcycles n₁ f₁₂ f₃ + g := X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ + +instance : Epi (X.cokernelSequenceOpcyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂).g := by + dsimp; infer_instance + +lemma cokernelSequenceOpcyclesE_exact : + (X.cokernelSequenceOpcyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A x₂ hx₂ + dsimp at x₂ hx₂ + obtain ⟨A₁, π₁, _, y₂, hy₂⟩ := + surjective_up_to_refinements_of_epi (X.pOpcycles n₁ f₁₂ f₃) x₂ + obtain ⟨A₂, π₂, _, y₁, hy₁⟩ := + (X.cokernelSequenceE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂).exact_up_to_refinements y₂ + (by simpa only [Category.assoc, p_opcyclesToE, hx₂, comp_zero] + using hy₂.symm =≫ X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂) + dsimp at y₁ hy₁ + obtain ⟨a, b, rfl⟩ : ∃ a b, y₁ = a ≫ biprod.inl + b ≫ biprod.inr := + ⟨y₁ ≫ biprod.fst, y₁ ≫ biprod.snd, by ext <;> simp⟩ + simp only [Preadditive.add_comp, Category.assoc, biprod.inl_desc, biprod.inr_desc] at hy₁ + refine ⟨A₂, π₂ ≫ π₁, inferInstance, a, ?_⟩ + dsimp + simp only [Category.assoc, hy₂, reassoc_of% hy₁, Preadditive.add_comp, δ_pOpcycles, + comp_zero, add_zero] + +-- TODO: dual statement? + +/-- The map `E^n(f₁, f₂, f₃) ⟶ Z^n(f₁, f₂ ≫ f₃)`. -/ +noncomputable def EToCycles : X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ⟶ X.cycles n₁ f₁ f₂₃ := + X.liftCycles n₁ n₂ hn₂ _ _ + (X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.fromOpcycles n₁ f₂ f₃ f₂₃ h₂₃) (by simp) + +@[reassoc (attr := simp)] +lemma EToCycles_i : + X.EToCycles n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃ ≫ X.iCycles n₁ f₁ f₂₃ = + X.ιE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.fromOpcycles n₁ f₂ f₃ f₂₃ h₂₃ := by + simp [EToCycles] + +@[reassoc (attr := simp)] +lemma πE_EToCycles : + X.πE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ ≫ X.EToCycles n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃ = + X.cyclesMap n₁ f₁ f₂ f₁ f₂₃ (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃) := by + rw [← cancel_mono (X.iCycles n₁ f₁ f₂₃), Category.assoc, EToCycles_i, + πE_ιE_assoc, p_fromOpcycles] + exact (X.cyclesMap_i _ _ _ _ _ _ _ (by rfl)).symm + +instance : Mono (X.EToCycles n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃) := + mono_of_mono_fac (X.EToCycles_i n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃) + +/-- The (exact) sequence `0 ⟶ E^n(f₁, f₂, f₃) ⟶ Z^n(f₁, f₂ ≫ f₃) ⟶ H^n(f₃)`. -/ +@[simps!] +noncomputable def kernelSequenceCyclesE : ShortComplex C where + X₁ := X.E n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ + X₂ := X.cycles n₁ f₁ f₂₃ + X₃ := (X.H n₁).obj (mk₁ f₃) + f := X.EToCycles n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃ + g := X.iCycles n₁ f₁ f₂₃ ≫ (X.H n₁).map (twoδ₁Toδ₀ f₂ f₃ f₂₃ h₂₃) + +instance : Mono (X.kernelSequenceCyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃).f := by + dsimp; infer_instance + +lemma kernelSequenceCyclesE_exact : + (X.kernelSequenceCyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃).Exact := by + rw [ShortComplex.exact_iff_exact_up_to_refinements] + intro A x₂ hx₂ + dsimp at x₂ hx₂ + obtain ⟨A₁, π₁, _, x₁, hx₁⟩ := + (X.kernelSequenceE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₂₃ h₂₃).exact_up_to_refinements + (x₂ ≫ X.iCycles n₁ f₁ f₂₃) (by cat_disch) + exact ⟨A₁, π₁, inferInstance, x₁, by simpa [← cancel_mono (X.iCycles ..)]⟩ + +end + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i j : ι} (f : i ⟶ j) {i' j' : ι} (f' : i' ⟶ j') + +/-- An homology data for `X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j)`, +expressing `H^n₁(f)` as the homology of this short complex, +see `EIsoH`. -/ +@[simps!] +noncomputable def homologyDataEIdId : + (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j)).HomologyData := + (ShortComplex.HomologyData.ofZeros (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j)) + (X.δ_eq_zero_of_isIso₂ n₀ n₁ hn₁ f (𝟙 j) inferInstance) + (X.δ_eq_zero_of_isIso₁ n₁ n₂ hn₂ (𝟙 i) f inferInstance)) + +/-- For any morphism `f : i ⟶ j`, this is the isomorphism from +`E^n₁(𝟙 i, f, 𝟙 j)` to `H^n₁(f)`. -/ +noncomputable def EIsoH : + X.E n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j) ≅ (X.H n₁).obj (mk₁ f) := + (X.homologyDataEIdId ..).left.homologyIso + +lemma EIsoH_hom_naturality + (α : mk₁ f ⟶ mk₁ f') (β : mk₃ (𝟙 _) f (𝟙 _) ⟶ mk₃ (𝟙 _) f' (𝟙 _)) + (hβ : β = homMk₃ (α.app 0) (α.app 0) (α.app 1) (α.app 1) + (by simp) (naturality' α 0 1) (by simp [Precomp.obj, Precomp.map])) : + X.EMap n₀ n₁ n₂ hn₁ hn₂ (𝟙 _) f (𝟙 _) (𝟙 _) f' (𝟙 _) β ≫ + (X.EIsoH n₀ n₁ n₂ hn₁ hn₂ f').hom = + (X.EIsoH n₀ n₁ n₂ hn₁ hn₂ f).hom ≫ (X.H n₁).map α := by + obtain rfl : α = homMk₁ (β.app 1) (β.app 2) (naturality' β 1 2) := by + subst hβ + exact hom_ext₁ rfl rfl + exact (ShortComplex.LeftHomologyMapData.ofZeros + (X.shortComplexEMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ β) _ _ _ _).homologyMap_comm + +end + +section + +variable (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) + {i₀ i₁ : ι} (f : i₀ ⟶ i₁) + +/-- The isomorphism `Z^n(𝟙 _, f) ≅ H^n(f)`. -/ +noncomputable def cyclesIsoH : + X.cycles n₀ (𝟙 i₀) f ≅ (X.H n₀).obj (mk₁ f) := + (X.cyclesIso (n₀ - 1) n₀ n₁ (by lia) hn₁ (𝟙 i₀) f (𝟙 i₁)).symm ≪≫ + (X.homologyDataEIdId ..).left.cyclesIso + +@[simp] +lemma cyclesIsoH_inv : + (X.cyclesIsoH n₀ n₁ hn₁ f).inv = X.toCycles n₀ (𝟙 _) f f (by simp) := by + rw [← cancel_mono (X.iCycles n₀ (𝟙 _) f ), toCycles_i] + dsimp [cyclesIsoH] + rw [Category.assoc, cyclesIso_hom_i, + ShortComplex.LeftHomologyData.cyclesIso_inv_comp_iCycles, + homologyDataEIdId_left_i, ← Functor.map_id] + congr 1 + cat_disch + +@[reassoc (attr := simp)] +lemma cyclesIsoH_hom_inv_id : + (X.cyclesIsoH n₀ n₁ hn₁ f).hom ≫ + X.toCycles n₀ (𝟙 _) f f (by simp) = 𝟙 _ := by + simpa using (X.cyclesIsoH n₀ n₁ hn₁ f).hom_inv_id + +@[reassoc (attr := simp)] +lemma cyclesIsoH_inv_hom_id : + X.toCycles n₀ (𝟙 _) f f (by simp) ≫ + (X.cyclesIsoH n₀ n₁ hn₁ f).hom = 𝟙 _ := by + simpa using (X.cyclesIsoH n₀ n₁ hn₁ f).inv_hom_id + +/-- The isomorphism `opZ^n(f, 𝟙 _) ≅ H^n(f)`. -/ +noncomputable def opcyclesIsoH : + X.opcycles n₁ f (𝟙 i₁) ≅ (X.H n₁).obj (mk₁ f) := + (X.opcyclesIso n₀ n₁ (n₁ + 1) hn₁ (by lia) (𝟙 i₀) f (𝟙 i₁)).symm ≪≫ + (X.homologyDataEIdId ..).right.opcyclesIso + +@[simp] +lemma opcyclesIsoH_hom : + (X.opcyclesIsoH n₀ n₁ hn₁ f).hom = X.fromOpcycles n₁ f (𝟙 _) f (by simp) := by + rw [← cancel_epi (X.pOpcycles n₁ f (𝟙 _)), p_fromOpcycles] + dsimp [opcyclesIsoH] + rw [p_opcyclesIso_inv_assoc, ShortComplex.RightHomologyData.pOpcycles_comp_opcyclesIso_hom, + homologyDataEIdId_right_p, ← Functor.map_id] + congr 1 + cat_disch + +@[reassoc (attr := simp)] +lemma opcyclesIsoH_hom_inv_id : + X.fromOpcycles n₁ f (𝟙 _) f (by simp) ≫ + (X.opcyclesIsoH n₀ n₁ hn₁ f).inv = 𝟙 _ := by + simpa using (X.opcyclesIsoH n₀ n₁ hn₁ f).hom_inv_id + +@[reassoc (attr := simp)] +lemma opcyclesIsoH_inv_hom_id : + (X.opcyclesIsoH n₀ n₁ hn₁ f).inv ≫ + X.fromOpcycles n₁ f (𝟙 _) f (by simp) = 𝟙 _ := by + simpa using (X.opcyclesIsoH n₀ n₁ hn₁ f).inv_hom_id + +end + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) {i j : ι} (f : i ⟶ j) + +@[reassoc (attr := simp)] +lemma cyclesIsoH_hom_EIsoH_inv : + (X.cyclesIsoH n₁ n₂ hn₂ f).hom ≫ (X.EIsoH n₀ n₁ n₂ hn₁ hn₂ f).inv = + X.πE n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j) := by + let h := (X.homologyDataEIdId n₀ n₁ n₂ hn₁ hn₂ f).left + have : h.cyclesIso.inv = + X.toCycles n₁ (𝟙 i) f f (by simp) ≫ + (X.cyclesIso n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j)).inv := by + rw [← cancel_mono (X.cyclesIso ..).hom, + Category.assoc, Iso.inv_hom_id, Category.comp_id, + ← cancel_mono (X.iCycles ..), Category.assoc, cyclesIso_hom_i, + h.cyclesIso_inv_comp_iCycles, toCycles_i] + dsimp [h] + rw [← Functor.map_id] + congr 1 + cat_disch + obtain rfl : n₀ = n₁ - 1 := by lia + rw [← cancel_epi (X.cyclesIsoH n₁ n₂ hn₂ f).inv, + cyclesIsoH_inv, cyclesIsoH_inv_hom_id_assoc] + dsimp [EIsoH] + rw [← cancel_epi h.π, h.π_comp_homologyIso_inv] + simp [πE, h, this] + +@[reassoc (attr := simp)] +lemma EIsoH_hom_opcyclesIsoH_inv : + (X.EIsoH n₀ n₁ n₂ hn₁ hn₂ f).hom ≫ (X.opcyclesIsoH n₀ n₁ hn₁ f).inv = + X.ιE n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j) := by + let h := (X.homologyDataEIdId n₀ n₁ n₂ hn₁ hn₂ f) + have : h.right.opcyclesIso.hom = + (X.opcyclesIso n₀ n₁ n₂ hn₁ hn₂ (𝟙 i) f (𝟙 j)).hom ≫ + X.fromOpcycles n₁ f (𝟙 j) f (by simp) := by + rw [← cancel_epi (X.opcyclesIso ..).inv, Iso.inv_hom_id_assoc, + ← cancel_epi (X.pOpcycles ..), p_opcyclesIso_inv_assoc, + h.right.pOpcycles_comp_opcyclesIso_hom, p_fromOpcycles] + dsimp [h] + rw [← Functor.map_id] + congr 1 + cat_disch + obtain rfl : n₂ = n₁ + 1 := by lia + rw [← cancel_mono (X.opcyclesIsoH n₀ n₁ hn₁ f).hom, Category.assoc, + opcyclesIsoH_hom, opcyclesIsoH_inv_hom_id] + dsimp [EIsoH, ιE] + rw [Category.assoc, ← this, + h.left_homologyIso_eq_right_homologyIso_trans_iso_symm, + ← ShortComplex.RightHomologyData.homologyIso_hom_comp_ι] + simp [h] + +end + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i₀ i₁ i₂ i₃ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₁₂ : i₀ ⟶ i₂) (f₂₃ : i₁ ⟶ i₃) + (h₁₂ : f₁ ≫ f₂ = f₁₂) (h₂₃ : f₂ ≫ f₃ = f₂₃) + +@[reassoc (attr := simp)] +lemma opcyclesMap_threeδ₂Toδ₁_opcyclesToE : + X.opcyclesMap n₁ _ _ _ _ (threeδ₂Toδ₁ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃) ≫ + X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ = 0 := by + rw [← cancel_epi (X.pOpcycles ..), comp_zero, + p_opcyclesMap_assoc _ _ _ _ _ _ _ (twoδ₂Toδ₁ f₁ f₂ f₁₂ h₁₂) rfl _, + p_opcyclesToE, H_map_twoδ₂Toδ₁_toCycles_assoc, zero_comp] + +/-- The short exact sequence +`0 ⟶ opZ^(f₁, f₂ ≫ f₃) ⟶ opZ^n(f₁ ≫ f₂, f₃) ⟶ H^n(f₁, f₂, f₃) ⟶ 0`. -/ +@[simps] +noncomputable def shortComplexOpcyclesThreeδ₂Toδ₁ : ShortComplex C := + ShortComplex.mk _ _ + (X.opcyclesMap_threeδ₂Toδ₁_opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃) + +instance : + Mono (X.shortComplexOpcyclesThreeδ₂Toδ₁ n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃).f := by + dsimp + rw [Preadditive.mono_iff_cancel_zero] + intro A x hx + replace hx := hx =≫ X.fromOpcycles n₁ f₁₂ f₃ _ rfl + rw [zero_comp, Category.assoc, + X.opcyclesMap_fromOpcycles n₁ f₁ f₂₃ f₁₂ f₃ (f₁₂ ≫ f₃) (by cat_disch) _ rfl _ (𝟙 _) + (by simp) (by cat_disch), Functor.map_id, Category.comp_id] at hx + rw [← cancel_mono (X.fromOpcycles n₁ f₁ f₂₃ (f₁₂ ≫ f₃) (by cat_disch)), hx, zero_comp] + +instance : + Epi (X.shortComplexOpcyclesThreeδ₂Toδ₁ n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃).g := by + dsimp; infer_instance + +lemma shortComplexOpcyclesThreeδ₂Toδ₁_exact : + (X.shortComplexOpcyclesThreeδ₂Toδ₁ n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃).Exact := by + let φ : X.cokernelSequenceOpcyclesE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ ⟶ + (X.shortComplexOpcyclesThreeδ₂Toδ₁ n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃) := + { τ₁ := X.pOpcycles n₁ f₁ f₂₃ + τ₂ := 𝟙 _ + τ₃ := 𝟙 _ + comm₁₂ := by + dsimp + rw [Category.comp_id, X.p_opcyclesMap _ _ _ _ _ _ (twoδ₂Toδ₁ f₁ f₂ f₁₂) rfl] } + rw [← ShortComplex.exact_iff_of_epi_of_isIso_of_mono φ] + exact X.cokernelSequenceOpcyclesE_exact n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ + +lemma shortComplexOpcyclesThreeδ₂Toδ₁_shortExact : + (X.shortComplexOpcyclesThreeδ₂Toδ₁ n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃).ShortExact where + exact := X.shortComplexOpcyclesThreeδ₂Toδ₁_exact .. + +end + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i₀ i₁ i₂ i₃ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₁₂ : i₀ ⟶ i₂) (h₁₂ : f₁ ≫ f₂ = f₁₂) + {i₀' i₁' i₂' i₃' : ι} (f₁' : i₀' ⟶ i₁') (f₂' : i₁' ⟶ i₂') (f₃' : i₂' ⟶ i₃') + (f₁₂' : i₀' ⟶ i₂') (h₁₂' : f₁' ≫ f₂' = f₁₂') + +@[reassoc] +lemma opcyclesToE_EMap (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁' f₂' f₃') (β : mk₂ f₁₂ f₃ ⟶ mk₂ f₁₂' f₃') + (h₀ : β.app 0 = α.app 0) (h₁ : β.app 1 = α.app 2) : + X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁₂ h₁₂ ≫ X.EMap _ _ _ _ _ _ _ _ _ _ _ α = + X.opcyclesMap _ _ _ _ _ β ≫ X.opcyclesToE n₀ n₁ n₂ hn₁ hn₂ f₁' f₂' f₃' f₁₂' h₁₂' := by + rw [← cancel_mono (X.ιE ..), Category.assoc, Category.assoc, opcyclesToE_ιE, + ← cancel_epi (X.pOpcycles ..), p_opcyclesToE_assoc, + X.πE_EMap_assoc _ _ _ _ _ _ _ _ _ _ _ _ + (homMk₂ (α.app 0) (α.app 1) (α.app 2) (naturality' α 0 1) (naturality' α 1 2)) rfl, + πE_ιE, X.cyclesMap_i_assoc _ _ _ _ _ _ _ rfl, toCycles_i_assoc, + X.p_opcyclesMap_assoc _ _ _ _ _ _ _ rfl, X.p_opcyclesMap _ _ _ _ _ _ _ rfl, + ← Functor.map_comp_assoc, ← Functor.map_comp_assoc] + congr 2 + ext + · simpa [h₀] using naturality' α 0 1 + · simp [h₁] + +end SpectralObject + +end Abelian + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralSequence/Basic.lean b/Mathlib/Algebra/Homology/SpectralSequence/Basic.lean new file mode 100644 index 00000000000000..c77d056ab17174 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralSequence/Basic.lean @@ -0,0 +1,137 @@ +/- +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.HomologicalComplex +public import Mathlib.Algebra.Homology.ShortComplex.Abelian +public import Mathlib.Algebra.Homology.SpectralSequence.ComplexShape + +/-! +# Spectral sequences + +In this file, we define the category `SpectralSequence C c r₀` of spectral sequences +in an abelian category `C` with `Eᵣ`-pages defined from `r₀ : ℤ` having differentials +given by complex shapes `c : ℤ → ComplexShape ι`, where `ι` is the index type +for the objects on each page (e.g. `ι := ℤ × ℤ` or `ι := ℕ × ℕ`). +A spectral sequence is defined as the data of a sequence of homological complexes +(the pages) and a sequence of isomorphism between the homology of a page and the +next page. + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits + +variable (C : Type*) [Category C] [Abelian C] + {κ : Type*} (c : ℤ → ComplexShape κ) (r₀ : ℤ) + +/-- Given an abelian category `C`, a sequence of complex shapes `c : ℤ → ComplexShape ι` +and a starting page `r₀ : ℤ`, a spectral sequence involves pages which are homological +complexes and isomorphisms saying that the homology of a page identifies to the next page. -/ +structure SpectralSequence where + /-- the `r`th page of a spectral sequence is an homological complex -/ + page (r : ℤ) (hr : r₀ ≤ r := by lia) : HomologicalComplex C (c r) + /-- the isomorphism between the homology of the `r`-th page at an object `pq : ι` + and the corresponding object on the next page -/ + iso (r r' : ℤ) (pq : κ) (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + (page r).homology pq ≅ (page r').X pq + +namespace SpectralSequence + +variable {C c r₀} + +/-- A morphism of spectral sequence is a sequence of morphisms between the +pages which commutes with the isomorphisms in homology. -/ +@[ext] +structure Hom (E E' : SpectralSequence C c r₀) where + /-- the morphism of homological complexes between the `r`th pages -/ + hom (r : ℤ) (hr : r₀ ≤ r := by lia) : E.page r ⟶ E'.page r + comm (r r' : ℤ) (pq : κ) (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + HomologicalComplex.homologyMap (hom r) pq ≫ (E'.iso r r' pq).hom = + (E.iso r r' pq).hom ≫ (hom r').f pq := by cat_disch + +/-- If `E` is a spectral sequence, and `r = r'`, this is the +isomorphism `(E.page r).X pq ≅ (E.page r').X pq`. -/ +def pageXIsoOfEq (E : SpectralSequence C c r₀) (pq : κ) (r r' : ℤ) (h : r = r' := by lia) + (hr : r₀ ≤ r := by lia) : + (E.page r).X pq ≅ (E.page r').X pq := + eqToIso (by subst h; rfl) + +attribute [reassoc (attr := simp)] Hom.comm + +@[simps! id_hom comp_hom] +instance : Category (SpectralSequence C c r₀) where + Hom := Hom + id _ := { hom _ _ := 𝟙 _} + comp f g := + { hom r hr := f.hom r ≫ g.hom r + comm r r' hrr' pq hr := by + dsimp + simp [HomologicalComplex.homologyMap_comp, assoc, g.comm r r', f.comm_assoc r r'] } + +@[ext] +lemma hom_ext {E E' : SpectralSequence C c r₀} {f f' : E ⟶ E'} + (h : ∀ (r : ℤ) (hr : r₀ ≤ r), f.hom r = f'.hom r) : + f = f' := + Hom.ext (by grind) + +attribute [simp] id_hom +attribute [reassoc, simp] comp_hom + +variable (C c r₀) + +/-- The functor `SpectralSequence C c r₀ ⥤ HomologicalComplex C (c r)` which +sends a spectral sequence to its `r`th page. -/ +@[simps] +def pageFunctor (r : ℤ) (hr : r₀ ≤ r := by lia) : + SpectralSequence C c r₀ ⥤ HomologicalComplex C (c r) where + obj E := E.page r + map f := f.hom r + +/-- The natural isomorphism between the homology of a spectral sequence on the +object `pq : ι` of the `r`th page and the corresponding object on the next page. -/ +@[simps!] +noncomputable def pageHomologyNatIso + (r r' : ℤ) (pq : κ) (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + pageFunctor C c r₀ r ⋙ HomologicalComplex.homologyFunctor _ _ pq ≅ + pageFunctor C c r₀ r' ⋙ HomologicalComplex.eval _ _ pq := + NatIso.ofComponents (fun E ↦ E.iso r r' pq) + +end SpectralSequence + +/-- A cohomological spectral sequence has differentials given by the +vector `(r, 1 - r)` on the `r`th page. -/ +abbrev CohomologicalSpectralSequence := + SpectralSequence C (fun r ↦ ComplexShape.up' (⟨r, 1 - r⟩ : ℤ × ℤ)) + +/-- A `E₂`-cohomological spectral sequence has differentials given by the +vector `(r, 1 - r)` on the `r`th page for `2 ≤ r`. -/ +abbrev E₂CohomologicalSpectralSequence := CohomologicalSpectralSequence C 2 + +/-- A first quadrant cohomological spectral sequence has differentials +given by the vector `(r, 1 - r)` on the `r`th page. -/ +abbrev CohomologicalSpectralSequenceNat := + SpectralSequence C (fun r ↦ ComplexShape.spectralSequenceNat ⟨r, 1 - r⟩) + +/-- A first quadrant `E₂`-cohomological spectral sequence has differentials +given by the vector `(r, 1 - r)` on the `r`th page for `2 ≤ r`. -/ +abbrev E₂CohomologicalSpectralSequenceNat := + CohomologicalSpectralSequenceNat C 2 + +/-- A cohomological spectral sequence lying on finitely many rows +has differentials given by the vector `(r, 1 - r)` on the `r`th page. -/ +abbrev CohomologicalSpectralSequenceFin (l : ℕ) := + SpectralSequence C (fun r ↦ ComplexShape.spectralSequenceFin l ⟨r, 1 - r⟩) + +/-- A `E₂`-cohomological spectral sequence lying on finitely many rows +has differentials given by the vector `(r, 1 - r)` on the `r`th page for `2 ≤ r`. -/ +abbrev E₂CohomologicalSpectralSequenceFin (l : ℕ) := + CohomologicalSpectralSequenceFin C 2 l + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean b/Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean new file mode 100644 index 00000000000000..fdf82adb1039a1 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean @@ -0,0 +1,54 @@ +/- +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.ComplexShape + +/-! +# Complex shapes for pages of spectral sequences + +In this file, we define complex shapes which correspond +to pages of spectral sequences: +* `ComplexShape.spectralSequenceNat`: for any `u : ℤ × ℤ`, this +is the complex shape on `ℕ × ℕ` corresponding to differentials +of `ComplexShape.up' u : ComplexShape (ℤ × ℤ)` with source +and target in `ℕ × ℕ`. (With `u := (r, 1 - r)`, this will +apply to the `r`th-page of first quadrant `E₂` cohomological +spectral sequence). +* `ComplexShape.spectralSequenceFin`: for any `u : ℤ × ℤ` and `l : ℕ`, +this is a similar definition as `ComplexShape.spectralSequenceNat` +but for `ℤ × Fin l` (identified as a subset of `ℤ × ℤ`). (This could +be used for spectral sequences associated to a *finite* filtration.) + +-/ + +@[expose] public section + +namespace ComplexShape + +/-- For `u : ℤ × ℤ`, this is the complex shape on `ℕ × ℕ`, which +connects `a` to `b` when the equality `a + u = b` holds in `ℤ × ℤ`. -/ +def spectralSequenceNat (u : ℤ × ℤ) : ComplexShape (ℕ × ℕ) where + Rel a b := a.1 + u.1 = b.1 ∧ a.2 + u.2 = b.2 + next_eq _ _ := by ext <;> lia + prev_eq _ _ := by ext <;> lia + +@[simp] +lemma spectralSequenceNat_rel_iff (u : ℤ × ℤ) (a b : ℕ × ℕ) : + (spectralSequenceNat u).Rel a b ↔ a.1 + u.1 = b.1 ∧ a.2 + u.2 = b.2 := Iff.rfl + +/-- For `l : ℕ` and `u : ℤ × ℤ`, this is the complex shape on `ℤ × Fin l`, which +connects `a` to `b` when the equality `a + u = b` holds in `ℤ × Fin l`. -/ +def spectralSequenceFin (l : ℕ) (u : ℤ × ℤ) : ComplexShape (ℤ × Fin l) where + Rel a b := a.1 + u.1 = b.1 ∧ a.2.1 + u.2 = b.2.1 + next_eq _ _ := by ext <;> lia + prev_eq _ _ := by ext <;> lia + +@[simp] +lemma spectralSequenceFin_rel_iff {l : ℕ} (u : ℤ × ℤ) (a b : ℤ × Fin l) : + (spectralSequenceFin l u).Rel a b ↔ a.1 + u.1 = b.1 ∧ a.2 + u.2 = b.2 := Iff.rfl + +end ComplexShape diff --git a/Mathlib/CategoryTheory/Category/Preorder.lean b/Mathlib/CategoryTheory/Category/Preorder.lean index 502cd253384312..4b61bb5cecc445 100644 --- a/Mathlib/CategoryTheory/Category/Preorder.lean +++ b/Mathlib/CategoryTheory/Category/Preorder.lean @@ -68,6 +68,10 @@ def homOfLE {x y : X} (h : x ≤ y) : x ⟶ y := @[inherit_doc homOfLE] abbrev _root_.LE.le.hom := @homOfLE +/-- Express an inequality `x ≤ y` as a morphism in the corresponding preorder category. +(In this version, the variables `x` and `y` are explicit.) -/ +abbrev homOfLE' (x y : X) (h : x ≤ y) : x ⟶ y := homOfLE h + @[simp] theorem homOfLE_refl {x : X} (h : x ≤ x) : h.hom = 𝟙 x := rfl @@ -92,6 +96,16 @@ lemma homOfLE_isIso_of_eq {x y : X} (h : x ≤ y) (heq : x = y) : IsIso (homOfLE h) := ⟨homOfLE (le_of_eq heq.symm), by simp⟩ +lemma isIso_homOfLE {x y : X} (h : x = y) : + IsIso (homOfLE (by rw [h]): x ⟶ y) := by + subst h + change IsIso (𝟙 _) + infer_instance + +lemma isIso_homOfLE' (x y : X) (h : x = y) : + IsIso (homOfLE' x y (by rw [h])) := + isIso_homOfLE h + @[simp, reassoc] lemma homOfLE_comp_eqToHom {a b c : X} (hab : a ≤ b) (hbc : b = c) : homOfLE hab ≫ eqToHom hbc = homOfLE (hab.trans (le_of_eq hbc)) := diff --git a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean index dfd780e1bfe77e..db8be175cf7008 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean @@ -231,6 +231,11 @@ def isoMk₀ {F G : ComposableArrows C 0} (e : F.obj' 0 ≅ G.obj' 0) : F ≅ G hom := homMk₀ e.hom inv := homMk₀ e.inv +lemma isIso_iff₀ {F G : ComposableArrows C 0} (f : F ⟶ G) : + IsIso f ↔ IsIso (f.app 0) := by + rw [NatTrans.isIso_iff_isIso_app] + exact ⟨fun h ↦ h 0, fun _ i ↦ by fin_cases i; assumption⟩ + lemma ext₀ {F G : ComposableArrows C 0} (h : F.obj' 0 = G.obj 0) : F = G := ext (fun i => match i with | ⟨0, _⟩ => h) (fun i hi => by simp at hi) @@ -273,6 +278,11 @@ def isoMk₁ {F G : ComposableArrows C 1} lemma map'_eq_hom₁ (F : ComposableArrows C 1) : F.map' 0 1 = F.hom := rfl +lemma isIso_iff₁ {F G : ComposableArrows C 1} (f : F ⟶ G) : + IsIso f ↔ IsIso (f.app 0) ∧ IsIso (f.app 1) := by + rw [NatTrans.isIso_iff_isIso_app] + exact ⟨fun h ↦ ⟨h 0, h 1⟩, fun _ i ↦ by fin_cases i <;> tauto⟩ + lemma ext₁ {F G : ComposableArrows C 1} (left : F.left = G.left) (right : F.right = G.right) (w : F.hom = eqToHom left ≫ G.hom ≫ eqToHom right.symm) : F = G := @@ -398,23 +408,23 @@ def precomp {X : C} (f : X ⟶ F.left) : ComposableArrows C (n + 1) where map_comp g g' := Precomp.map_comp F f (leOfHom g) (leOfHom g') /-- Constructor for `ComposableArrows C 2`. -/ -@[simp] +@[reducible] def mk₂ {X₀ X₁ X₂ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) : ComposableArrows C 2 := (mk₁ g).precomp f /-- Constructor for `ComposableArrows C 3`. -/ -@[simp] +@[reducible] def mk₃ {X₀ X₁ X₂ X₃ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) : ComposableArrows C 3 := (mk₂ g h).precomp f /-- Constructor for `ComposableArrows C 4`. -/ -@[simp] +@[reducible] def mk₄ {X₀ X₁ X₂ X₃ X₄ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) : ComposableArrows C 4 := (mk₃ g h i).precomp f /-- Constructor for `ComposableArrows C 5`. -/ -@[simp] +@[reducible] def mk₅ {X₀ X₁ X₂ X₃ X₄ X₅ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) (j : X₄ ⟶ X₅) : ComposableArrows C 5 := @@ -512,7 +522,7 @@ def homMkSucc (α : F.obj' 0 ⟶ G.obj' 0) (β : F.δ₀ ⟶ G.δ₀) · exact naturality' β i (i + 1)) variable (α : F.obj' 0 ⟶ G.obj' 0) (β : F.δ₀ ⟶ G.δ₀) - (w : F.map' 0 1 ≫ app' β 0 = α ≫ G.map' 0 1) + (w : F.map' 0 1 ≫ app' β 0 = α ≫ G.map' 0 1 := by cat_disch) @[simp] lemma homMkSucc_app_zero : (homMkSucc α β w).app 0 = α := rfl @@ -575,8 +585,8 @@ section variable {f g : ComposableArrows C 2} (app₀ : f.obj' 0 ⟶ g.obj' 0) (app₁ : f.obj' 1 ⟶ g.obj' 1) (app₂ : f.obj' 2 ⟶ g.obj' 2) - (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1) - (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2) + (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1 := by cat_disch) + (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2 := by cat_disch) /-- Constructor for morphisms in `ComposableArrows C 2`. -/ def homMk₂ : f ⟶ g := homMkSucc app₀ (homMk₁ app₁ app₂ w₁) w₀ @@ -588,7 +598,10 @@ lemma homMk₂_app_zero : (homMk₂ app₀ app₁ app₂ w₀ w₁).app 0 = app lemma homMk₂_app_one : (homMk₂ app₀ app₁ app₂ w₀ w₁).app 1 = app₁ := rfl @[simp] -lemma homMk₂_app_two : (homMk₂ app₀ app₁ app₂ w₀ w₁).app ⟨2, by valid⟩ = app₂ := rfl +lemma homMk₂_app_two : (homMk₂ app₀ app₁ app₂ w₀ w₁).app 2 = app₂ := rfl + +@[simp] +lemma homMk₂_app_two' : (homMk₂ app₀ app₁ app₂ w₀ w₁).app ⟨2, by valid⟩ = app₂ := rfl end @@ -611,6 +624,11 @@ def isoMk₂ {f g : ComposableArrows C 2} (by rw [← cancel_epi app₁.hom, ← reassoc_of% w₁, app₂.hom_inv_id, comp_id, app₁.hom_inv_id_assoc]) +lemma isIso_iff₂ {F G : ComposableArrows C 2} (f : F ⟶ G) : + IsIso f ↔ IsIso (f.app 0) ∧ IsIso (f.app 1) ∧ IsIso (f.app 2) := by + rw [NatTrans.isIso_iff_isIso_app] + exact ⟨fun h ↦ ⟨h 0, h 1, h 2⟩, fun _ i ↦ by fin_cases i <;> tauto⟩ + lemma ext₂ {f g : ComposableArrows C 2} (h₀ : f.obj' 0 = g.obj' 0) (h₁ : f.obj' 1 = g.obj' 1) (h₂ : f.obj' 2 = g.obj' 2) (w₀ : f.map' 0 1 = eqToHom h₀ ≫ g.map' 0 1 ≫ eqToHom h₁.symm) @@ -639,9 +657,9 @@ variable {f g : ComposableArrows C 3} (app₀ : f.obj' 0 ⟶ g.obj' 0) (app₁ : f.obj' 1 ⟶ g.obj' 1) (app₂ : f.obj' 2 ⟶ g.obj' 2) (app₃ : f.obj' 3 ⟶ g.obj' 3) - (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1) - (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2) - (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3) + (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1 := by cat_disch) + (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2 := by cat_disch) + (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3 := by cat_disch) /-- Constructor for morphisms in `ComposableArrows C 3`. -/ def homMk₃ : f ⟶ g := homMkSucc app₀ (homMk₂ app₁ app₂ app₃ w₁ w₂) w₀ @@ -705,10 +723,10 @@ variable {f g : ComposableArrows C 4} (app₀ : f.obj' 0 ⟶ g.obj' 0) (app₁ : f.obj' 1 ⟶ g.obj' 1) (app₂ : f.obj' 2 ⟶ g.obj' 2) (app₃ : f.obj' 3 ⟶ g.obj' 3) (app₄ : f.obj' 4 ⟶ g.obj' 4) - (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1) - (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2) - (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3) - (w₃ : f.map' 3 4 ≫ app₄ = app₃ ≫ g.map' 3 4) + (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1 := by cat_disch) + (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2 := by cat_disch) + (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3 := by cat_disch) + (w₃ : f.map' 3 4 ≫ app₄ = app₃ ≫ g.map' 3 4 := by cat_disch) /-- Constructor for morphisms in `ComposableArrows C 4`. -/ def homMk₄ : f ⟶ g := homMkSucc app₀ (homMk₃ app₁ app₂ app₃ app₄ w₁ w₂ w₃) w₀ @@ -785,11 +803,11 @@ variable {f g : ComposableArrows C 5} (app₀ : f.obj' 0 ⟶ g.obj' 0) (app₁ : f.obj' 1 ⟶ g.obj' 1) (app₂ : f.obj' 2 ⟶ g.obj' 2) (app₃ : f.obj' 3 ⟶ g.obj' 3) (app₄ : f.obj' 4 ⟶ g.obj' 4) (app₅ : f.obj' 5 ⟶ g.obj' 5) - (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1) - (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2) - (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3) - (w₃ : f.map' 3 4 ≫ app₄ = app₃ ≫ g.map' 3 4) - (w₄ : f.map' 4 5 ≫ app₅ = app₄ ≫ g.map' 4 5) + (w₀ : f.map' 0 1 ≫ app₁ = app₀ ≫ g.map' 0 1 := by cat_disch) + (w₁ : f.map' 1 2 ≫ app₂ = app₁ ≫ g.map' 1 2 := by cat_disch) + (w₂ : f.map' 2 3 ≫ app₃ = app₂ ≫ g.map' 2 3 := by cat_disch) + (w₃ : f.map' 3 4 ≫ app₄ = app₃ ≫ g.map' 3 4 := by cat_disch) + (w₄ : f.map' 4 5 ≫ app₅ = app₄ ≫ g.map' 4 5 := by cat_disch) /-- Constructor for morphisms in `ComposableArrows C 5`. -/ def homMk₅ : f ⟶ g := homMkSucc app₀ (homMk₄ app₁ app₂ app₃ app₄ app₅ w₁ w₂ w₃ w₄) w₀ @@ -943,6 +961,35 @@ def Functor.mapComposableArrowsObjMk₂Iso {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ (G.mapComposableArrows 2).obj (.mk₂ f g) ≅ .mk₂ (G.map f) (G.map g) := isoMk₂ (Iso.refl _) (Iso.refl _) (Iso.refl _) +@[simps] +def composableArrows₀Equivalence : ComposableArrows C 0 ≌ C where + functor := + { obj := fun f => f.obj' 0 + map := fun f => ComposableArrows.app' f 0 } + inverse := + { obj := fun X => ComposableArrows.mk₀ X + map := fun f => ComposableArrows.homMk₀ f } + unitIso := NatIso.ofComponents (fun X => ComposableArrows.isoMk₀ (Iso.refl _)) + (by aesop_cat) + counitIso := Iso.refl _ + +set_option maxHeartbeats 600000 in +-- this is a slow proof +@[simps] +def composableArrows₁Equivalence : ComposableArrows C 1 ≌ Arrow C where + functor := + { obj := fun F => Arrow.mk (F.map' 0 1) + map := fun {F G} f => + { left := ComposableArrows.app' f 0 + right := ComposableArrows.app' f 1 + w := (f.naturality _).symm } } + inverse := + { obj := fun f => ComposableArrows.mk₁ f.hom + map := fun {f g} φ => ComposableArrows.homMk₁ φ.left φ.right φ.w.symm } + unitIso := NatIso.ofComponents + (fun f => ComposableArrows.isoMk₁ (Iso.refl _) (Iso.refl _) (by aesop_cat)) + (by aesop_cat) + counitIso := Iso.refl _ suppress_compilation in /-- The functor `ComposableArrows C n ⥤ ComposableArrows D n` induced by `G : C ⥤ D` diff --git a/Mathlib/CategoryTheory/ComposableArrows/Four.lean b/Mathlib/CategoryTheory/ComposableArrows/Four.lean new file mode 100644 index 00000000000000..f7dd4c26bd9f2c --- /dev/null +++ b/Mathlib/CategoryTheory/ComposableArrows/Four.lean @@ -0,0 +1,148 @@ +/- +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.ComposableArrows.Basic + +/-! +# API for compositions of four arrows + +-/ + +@[expose] public section + +namespace CategoryTheory + +namespace ComposableArrows + +section + +variable {C : Type*} [Category* C] + {i₀ i₁ i₂ i₃ i₄ : C} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) (f₄ : i₃ ⟶ i₄) + (f₁₂ : i₀ ⟶ i₂) (f₂₃ : i₁ ⟶ i₃) (f₃₄ : i₂ ⟶ i₄) + +/-- The morphism `mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁ f₂ f₃₄` when `f₃ ≫ f₃ = f₃₄`. -/ +def fourδ₄Toδ₃ (h₃₄ : f₃ ≫ f₄ = f₃₄ := by cat_disch) : + mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁ f₂ f₃₄ := + homMk₃ (𝟙 _) (𝟙 _) (𝟙 _) f₄ + +/-- The morphism `mk₃ f₁ f₂ f₃₄ ⟶ mk₃ f₁ f₂₃ f₄` when `f₂ ≫ f₂ = f₂₃` and `f₃ ≫ f₃ = f₃₄`. -/ +def fourδ₃Toδ₂ (h₂₃ : f₂ ≫ f₃ = f₂₃ := by cat_disch) (h₃₄ : f₃ ≫ f₄ = f₃₄ := by cat_disch) : + mk₃ f₁ f₂ f₃₄ ⟶ mk₃ f₁ f₂₃ f₄ := + homMk₃ (𝟙 _) (𝟙 _) f₃ (𝟙 _) + +/-- The morphism `mk₃ f₁ f₂₃ f₄ ⟶ mk₃ f₁₂ f₃ f₄` when `f₁ ≫ f₂ = f₁₂` and `f₂ ≫ f₂ = f₂₃`. -/ +def fourδ₂Toδ₁ (h₁₂ : f₁ ≫ f₂ = f₁₂ := by cat_disch) (h₂₃ : f₂ ≫ f₃ = f₂₃ := by cat_disch) : + mk₃ f₁ f₂₃ f₄ ⟶ mk₃ f₁₂ f₃ f₄ := + homMk₃ (𝟙 _) f₂ (𝟙 _) (𝟙 _) + +/-- The morphism `mk₃ f₁₂ f₃ f₄ ⟶ mk₃ f₂ f₃ f₄` when `f₁ ≫ f₂ = f₁₂`. -/ +def fourδ₁Toδ₀ (h₁₂ : f₁ ≫ f₂ = f₁₂ := by cat_disch) : + mk₃ f₁₂ f₃ f₄ ⟶ mk₃ f₂ f₃ f₄ := + homMk₃ f₁ (𝟙 _) (𝟙 _) (𝟙 _) + +variable (h₁₂ : f₁ ≫ f₂ = f₁₂) (h₂₃ : f₂ ≫ f₃ = f₂₃) (h₃₄ : f₃ ≫ f₄ = f₃₄) + +@[simp] +lemma fourδ₄Toδ₃_app_zero : + (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄).app 0 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₄Toδ₃_app_one : + (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄).app 1 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₄Toδ₃_app_two : + (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄).app 2 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₄Toδ₃_app_three : + (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄).app 3 = f₄ := rfl + +@[simp] +lemma fourδ₃Toδ₂_app_zero : + (fourδ₃Toδ₂ f₁ f₂ f₃ f₄ f₂₃ f₃₄ h₂₃ h₃₄).app 0 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₃Toδ₂_app_one : + (fourδ₃Toδ₂ f₁ f₂ f₃ f₄ f₂₃ f₃₄ h₂₃ h₃₄).app 1 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₃Toδ₂_app_two : + (fourδ₃Toδ₂ f₁ f₂ f₃ f₄ f₂₃ f₃₄ h₂₃ h₃₄).app 2 = f₃ := rfl + +@[simp] +lemma fourδ₃Toδ₂_app_three : + (fourδ₃Toδ₂ f₁ f₂ f₃ f₄ f₂₃ f₃₄ h₂₃ h₃₄).app 3 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₂Toδ₁_app_zero : + (fourδ₂Toδ₁ f₁ f₂ f₃ f₄ f₁₂ f₂₃ h₁₂ h₂₃).app 0 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₂Toδ₁_app_one : + (fourδ₂Toδ₁ f₁ f₂ f₃ f₄ f₁₂ f₂₃ h₁₂ h₂₃).app 1 = f₂ := rfl + +@[simp] +lemma fourδ₂Toδ₁_app_two : + (fourδ₂Toδ₁ f₁ f₂ f₃ f₄ f₁₂ f₂₃ h₁₂ h₂₃).app 2 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₂Toδ₁_app_three : + (fourδ₂Toδ₁ f₁ f₂ f₃ f₄ f₁₂ f₂₃ h₁₂ h₂₃).app 3 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₁Toδ₀_app_zero : + (fourδ₁Toδ₀ f₁ f₂ f₃ f₄ f₁₂ h₁₂).app 0 = f₁ := rfl + +@[simp] +lemma fourδ₁Toδ₀_app_one : + (fourδ₁Toδ₀ f₁ f₂ f₃ f₄ f₁₂ h₁₂).app 1 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₁Toδ₀_app_two : + (fourδ₁Toδ₀ f₁ f₂ f₃ f₄ f₁₂ h₁₂).app 2 = 𝟙 _ := rfl + +@[simp] +lemma fourδ₁Toδ₀_app_three : + (fourδ₁Toδ₀ f₁ f₂ f₃ f₄ f₁₂ h₁₂).app 3 = 𝟙 _ := rfl + +end + +section + +variable {ι : Type*} [Preorder ι] (i₀ i₁ i₂ i₃ i₄ : ι) + (hi₀₁ : i₀ ≤ i₁) (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) (hi₃₄ : i₃ ≤ i₄) + +/-- Variant of `fourδ₄Toδ₃` for preorders. -/ +abbrev fourδ₄Toδ₃' : + mk₃ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE hi₂₃) ⟶ + mk₃ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE (hi₂₃.trans hi₃₄)) := + fourδ₄Toδ₃ _ _ _ (homOfLE hi₃₄) _ rfl + +/-- Variant of `fourδ₃Toδ₂` for preorders. -/ +abbrev fourδ₃Toδ₂' : + mk₃ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE (hi₂₃.trans hi₃₄)) ⟶ + mk₃ (homOfLE hi₀₁) (homOfLE (hi₁₂.trans hi₂₃)) (homOfLE hi₃₄) := + fourδ₃Toδ₂ _ (homOfLE hi₁₂) (homOfLE hi₂₃) _ _ _ rfl rfl + +/-- Variant of `fourδ₂Toδ₁` for preorders. -/ +abbrev fourδ₂Toδ₁' : + mk₃ (homOfLE hi₀₁) (homOfLE (hi₁₂.trans hi₂₃)) (homOfLE hi₃₄) ⟶ + mk₃ (homOfLE (hi₀₁.trans hi₁₂)) (homOfLE hi₂₃) (homOfLE hi₃₄) := + fourδ₂Toδ₁ _ (homOfLE hi₁₂) _ _ _ _ rfl rfl + +/-- Variant of `fourδ₁Toδ₀` for preorders. -/ +abbrev fourδ₁Toδ₀' : + mk₃ (homOfLE (hi₀₁.trans hi₁₂)) (homOfLE hi₂₃) (homOfLE hi₃₄) ⟶ + mk₃ (homOfLE hi₁₂) (homOfLE hi₂₃) (homOfLE hi₃₄) := + fourδ₁Toδ₀ (homOfLE hi₀₁) _ _ _ _ rfl + +end + +end ComposableArrows + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/ComposableArrows/Three.lean b/Mathlib/CategoryTheory/ComposableArrows/Three.lean new file mode 100644 index 00000000000000..48a202eff0a715 --- /dev/null +++ b/Mathlib/CategoryTheory/ComposableArrows/Three.lean @@ -0,0 +1,120 @@ +/- +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.ComposableArrows.Basic + +/-! +# API for compositions of three arrows + +Given morphisms `f₁ : i ⟶ j`, `f₂ : j ⟶ k`, `f₃ : k ⟶ l`, and their +compositions `f₁₂ : i ⟶ k` and `f₂₃ : j ⟶ l`, we define +maps `ComposableArrowsthreeδ₃Toδ₂ : mk₂ f₁ f₂ ⟶ mk₂ f₁ f₂₃` +`threeδ₂Toδ₁ : mk₂ f₁ f₂₃ ⟶ mk₂ f₁₂ f₃`, and `threeδ₁Toδ₀ : mk₂ f₁₂ f₃ ⟶ mk₂ f₂ f₃`. +The names are justified by the fact that `ComposableArrow.mk₃ f₁ f₂ f₃` +can be thought of as a `3`-simplex in the simplicial set `nerve C`, +and its faces (numbered from `0` to `3`) are respectively +`mk₂ f₂ f₃`, `mk₂ f₁₂ f₃`, `mk₂ f₁ f₂₃`, `mk₂ f₁ f₂`. + +-/ + +@[expose] public section + +universe v u + +namespace CategoryTheory + +namespace ComposableArrows + +section + +variable {C : Type u} [Category.{v} C] + {i j k l : C} (f₁ : i ⟶ j) (f₂ : j ⟶ k) (f₃ : k ⟶ l) + (f₁₂ : i ⟶ k) (f₂₃ : j ⟶ l) + +/-- The morphism `mk₂ f₁ f₂ ⟶ mk₂ f₁ f₂₃` when `f₂ ≫ f₃ = f₂₃`. -/ +def threeδ₃Toδ₂ (h₂₃ : f₂ ≫ f₃ = f₂₃ := by cat_disch) : + mk₂ f₁ f₂ ⟶ mk₂ f₁ f₂₃ := + homMk₂ (𝟙 _) (𝟙 _) f₃ + +/-- The morphism `mk₂ f₁ f₂₃ ⟶ mk₂ f₁₂ f₃` when `f₁ ≫ f₂ = f₁₂` and `f₂ ≫ f₃ = f₂₃`. -/ +def threeδ₂Toδ₁ (h₁₂ : f₁ ≫ f₂ = f₁₂ := by cat_disch) (h₂₃ : f₂ ≫ f₃ = f₂₃ := by cat_disch) : + mk₂ f₁ f₂₃ ⟶ mk₂ f₁₂ f₃ := + homMk₂ (𝟙 _) f₂ (𝟙 _) + +/-- The morphism `mk₂ f₁₂ f₃ ⟶ mk₂ f₂ f₃` when `f₁ ≫ f₂ = f₁₂`. -/ +def threeδ₁Toδ₀ (h₁₂ : f₁ ≫ f₂ = f₁₂ := by cat_disch) : + mk₂ f₁₂ f₃ ⟶ mk₂ f₂ f₃ := + homMk₂ f₁ (𝟙 _) (𝟙 _) + +variable (h₁₂ : f₁ ≫ f₂ = f₁₂) (h₂₃ : f₂ ≫ f₃ = f₂₃) + +@[simp] +lemma threeδ₃Toδ₂_app_zero : + (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃).app 0 = 𝟙 _ := rfl + +@[simp] +lemma threeδ₃Toδ₂_app_one : + (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃).app 1 = 𝟙 _ := rfl + +@[simp] +lemma threeδ₃Toδ₂_app_two : + (threeδ₃Toδ₂ f₁ f₂ f₃ f₂₃ h₂₃).app 2 = f₃ := rfl + +@[simp] +lemma threeδ₂Toδ₁_app_zero : + (threeδ₂Toδ₁ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃).app 0 = 𝟙 _ := rfl + +@[simp] +lemma threeδ₂Toδ₁_app_one : + (threeδ₂Toδ₁ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃).app 1 = f₂ := rfl + +@[simp] +lemma threeδ₂Toδ₁_app_two : + (threeδ₂Toδ₁ f₁ f₂ f₃ f₁₂ f₂₃ h₁₂ h₂₃).app 2 = 𝟙 _ := rfl + +@[simp] +lemma threeδ₁Toδ₀_app_zero : + (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂).app 0 = f₁ := rfl + +@[simp] +lemma threeδ₁Toδ₀_app_one : + (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂).app 1 = (𝟙 _) := rfl + +@[simp] +lemma threeδ₁Toδ₀_app_two : + (threeδ₁Toδ₀ f₁ f₂ f₃ f₁₂ h₁₂).app 2 = (𝟙 _) := rfl + +end + +section + +variable {ι : Type*} [Preorder ι] + (i₀ i₁ i₂ i₃ : ι) (hi₀₁ : i₀ ≤ i₁) (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) + +/-- Variant of `threeδ₃Toδ₂` for preorders. -/ +abbrev threeδ₃Toδ₂' : + mk₂ (homOfLE hi₀₁) (homOfLE hi₁₂) ⟶ + mk₂ (homOfLE hi₀₁) (homOfLE (hi₁₂.trans hi₂₃)) := + threeδ₃Toδ₂ _ _ (homOfLE hi₂₃) _ rfl + +/-- Variant of `threeδ₂Toδ₁` for preorders. -/ +abbrev threeδ₂Toδ₁' : + mk₂ (homOfLE hi₀₁) (homOfLE (hi₁₂.trans hi₂₃)) ⟶ + mk₂ (homOfLE (hi₀₁.trans hi₁₂)) (homOfLE hi₂₃) := + threeδ₂Toδ₁ _ (homOfLE hi₁₂) _ _ _ rfl rfl + +/-- Variant of `threeδ₁Toδ₀` for preorders. -/ +abbrev threeδ₁Toδ₀' : + mk₂ (homOfLE (hi₀₁.trans hi₁₂)) (homOfLE hi₂₃) ⟶ + mk₂ (homOfLE hi₁₂) (homOfLE hi₂₃) := + threeδ₁Toδ₀ (homOfLE hi₀₁) _ _ _ rfl + +end + +end ComposableArrows + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/ComposableArrows/Two.lean b/Mathlib/CategoryTheory/ComposableArrows/Two.lean index c097dcc1688805..698a59be84e46d 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Two.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Two.lean @@ -22,20 +22,27 @@ and its faces (numbered from `0` to `2`) are respectively `mk₁ g`, @[expose] public section -universe v u - namespace CategoryTheory namespace ComposableArrows -variable {C : Type u} [Category.{v} C] - {i j k : C} (f : i ⟶ j) (g : j ⟶ k) (fg : i ⟶ k) (h : f ≫ g = fg) +section + +variable {C : Type*} [Category* C] + {i j k : C} (f : i ⟶ j) (g : j ⟶ k) (fg : i ⟶ k) /-- The morphism `mk₁ f ⟶ mk₁ fg` when `f ≫ g = fg` for some morphism `g`. -/ -def twoδ₂Toδ₁ : +def twoδ₂Toδ₁ (h : f ≫ g = fg := by cat_disch) : mk₁ f ⟶ mk₁ fg := homMk₁ (𝟙 _) g +/-- The morphism `mk₁ fg ⟶ mk₁ g` when `f ≫ g = fg` for some morphism `f`. -/ +def twoδ₁Toδ₀ (h : f ≫ g = fg := by cat_disch) : + mk₁ fg ⟶ mk₁ g := + homMk₁ f (𝟙 _) + +variable (h : f ≫ g = fg) + @[simp] lemma twoδ₂Toδ₁_app_zero : (twoδ₂Toδ₁ f g fg h).app 0 = 𝟙 _ := rfl @@ -44,11 +51,6 @@ lemma twoδ₂Toδ₁_app_zero : lemma twoδ₂Toδ₁_app_one : (twoδ₂Toδ₁ f g fg h).app 1 = g := rfl -/-- The morphism `mk₁ fg ⟶ mk₁ g` when `f ≫ g = fg` for some morphism `f`. -/ -def twoδ₁Toδ₀ : - mk₁ fg ⟶ mk₁ g := - homMk₁ f (𝟙 _) - @[simp] lemma twoδ₁Toδ₀_app_zero : (twoδ₁Toδ₀ f g fg h).app 0 = f := rfl @@ -57,6 +59,32 @@ lemma twoδ₁Toδ₀_app_zero : lemma twoδ₁Toδ₀_app_one : (twoδ₁Toδ₀ f g fg h).app 1 = 𝟙 _ := rfl +instance [IsIso g] : IsIso (twoδ₂Toδ₁ f g fg h) := by + rw [isIso_iff₁] + constructor <;> dsimp <;> infer_instance + +instance [IsIso f] : IsIso (twoδ₁Toδ₀ f g fg h) := by + rw [isIso_iff₁] + constructor <;> dsimp <;> infer_instance + +end + +section + +variable {ι : Type*} [Preorder ι] (i₀ i₁ i₂ : ι) (hi₀₁ : i₀ ≤ i₁) (hi₁₂ : i₁ ≤ i₂) + +/-- Variant of `twoδ₁Toδ₀` for preorders. -/ +abbrev twoδ₁Toδ₀' : + mk₁ (homOfLE (hi₀₁.trans hi₁₂)) ⟶ mk₁ (homOfLE hi₁₂) := + twoδ₁Toδ₀ (homOfLE hi₀₁) _ _ rfl + +/-- Variant of `twoδ₂Toδ₁` for preorders. -/ +abbrev twoδ₂Toδ₁' : + mk₁ (homOfLE hi₀₁) ⟶ mk₁ (homOfLE (hi₀₁.trans hi₁₂)) := + twoδ₂Toδ₁ _ (homOfLE hi₁₂) _ rfl + +end + end ComposableArrows end CategoryTheory diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean index 185610d7147608..e4709b2fb7425b 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Equalizers.lean @@ -297,9 +297,10 @@ theorem parallelPairHom_app_one {X' Y' : C} (f g : X ⟶ Y) (f' g' : X' ⟶ Y') /-- Construct a natural isomorphism between functors out of the walking parallel pair from its components. -/ @[simps!] -def parallelPair.ext {F G : WalkingParallelPair ⥤ C} (zero : F.obj zero ≅ G.obj zero) - (one : F.obj one ≅ G.obj one) (left : F.map left ≫ one.hom = zero.hom ≫ G.map left) - (right : F.map right ≫ one.hom = zero.hom ≫ G.map right) : F ≅ G := +def parallelPair.ext {F G : WalkingParallelPair ⥤ C} + (zero : F.obj zero ≅ G.obj zero) (one : F.obj one ≅ G.obj one) + (left : F.map left ≫ one.hom = zero.hom ≫ G.map left := by cat_disch) + (right : F.map right ≫ one.hom = zero.hom ≫ G.map right := by cat_disch) : F ≅ G := NatIso.ofComponents (by rintro ⟨j⟩ diff --git a/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean b/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean index beb03fb547ef4e..260d07c05075dc 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean @@ -6,6 +6,8 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.ObjectProperty.ClosedUnderIsomorphisms +public import Mathlib.CategoryTheory.ObjectProperty.Opposite +public import Mathlib.CategoryTheory.ObjectProperty.FullSubcategory public import Mathlib.CategoryTheory.Limits.Preserves.Shapes.Zero /-! @@ -24,13 +26,26 @@ universe v v' u u' namespace CategoryTheory -open Limits ZeroObject +open Limits ZeroObject Opposite variable {C : Type u} [Category.{v} C] {D : Type u'} [Category.{v'} D] +-- to be moved +lemma IsZero.of_full_of_faithful_of_isZero + (F : C ⥤ D) [F.Full] [F.Faithful] (X : C) (hX : IsZero (F.obj X)) : + IsZero X := by + have h : F.FullyFaithful := .ofFullyFaithful _ + constructor + · intro Y + have := (hX.unique_to (F.obj Y)).some + exact ⟨h.homEquiv.unique⟩ + · intro Y + have := (hX.unique_from (F.obj Y)).some + exact ⟨h.homEquiv.unique⟩ + namespace ObjectProperty -variable (P : ObjectProperty C) +variable (P Q : ObjectProperty C) /-- Given `P : ObjectProperty C`, we say that `P.ContainsZero` if there exists a zero object for which `P` holds. When `P` is closed under isomorphisms, @@ -76,6 +91,27 @@ instance [P.ContainsZero] : P.isoClosure.ContainsZero where obtain ⟨Z, hZ, hP⟩ := P.exists_prop_of_containsZero exact ⟨Z, hZ, P.le_isoClosure _ hP⟩ +instance [P.ContainsZero] [P.IsClosedUnderIsomorphisms] [Q.ContainsZero] : + (P ⊓ Q).ContainsZero where + exists_zero := by + obtain ⟨Z, hZ, hQ⟩ := Q.exists_prop_of_containsZero + exact ⟨Z, hZ, P.prop_of_isZero hZ, hQ⟩ + +instance [P.ContainsZero] : P.op.ContainsZero where + exists_zero := by + obtain ⟨Z, hZ, mem⟩ := P.exists_prop_of_containsZero + exact ⟨op Z, hZ.op, mem⟩ + +instance (P : ObjectProperty Cᵒᵖ) [P.ContainsZero] : P.unop.ContainsZero where + exists_zero := by + obtain ⟨Z, hZ, mem⟩ := P.exists_prop_of_containsZero + exact ⟨Z.unop, hZ.unop, mem⟩ + +instance [P.ContainsZero] : HasZeroObject P.FullSubcategory where + zero := by + obtain ⟨X, h₁, h₂⟩ := P.exists_prop_of_containsZero + exact ⟨_, IsZero.of_full_of_faithful_of_isZero P.ι ⟨X, h₂⟩ h₁⟩ + end ObjectProperty /-- Given a functor `F : C ⥤ D`, this is the property of objects of `C` diff --git a/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean b/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean index d1a6dc375eaa3c..97e5587d898e3b 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/FullSubcategory.lean @@ -63,6 +63,8 @@ theorem ι_obj {X} : P.ι.obj X = X.obj := theorem ι_map {X Y} {f : X ⟶ Y} : P.ι.map f = f.hom := rfl +lemma prop_ι_obj (X) : P (P.ι.obj X) := X.2 + @[simp] lemma FullSubcategory.id_hom (X : P.FullSubcategory) : InducedCategory.Hom.hom (𝟙 X) = 𝟙 X.obj := rfl @@ -80,6 +82,11 @@ variable {P} in def homMk {X Y : P.FullSubcategory} (f : X.obj ⟶ Y.obj) : X ⟶ Y where hom := f +variable {P} in +lemma homMk_surjective {X Y : P.FullSubcategory} (f : X ⟶ Y) : + ∃ (g : X.obj ⟶ Y.obj), homMk g = f := + ⟨f.hom, rfl⟩ + /-- The inclusion of a full subcategory is fully faithful. -/ abbrev fullyFaithfulι : P.ι.FullyFaithful where diff --git a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean index d7b764233eef14..4f17274b324272 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean @@ -24,7 +24,7 @@ open CategoryTheory Category namespace CategoryTheory -variable {C : Type*} [Category* C] (P : ObjectProperty C) +variable {C : Type*} [Category C] (P Q : ObjectProperty C) {A : Type*} [AddMonoid A] [HasShift C A] namespace ObjectProperty @@ -67,6 +67,11 @@ instance (a : A) [P.IsStableUnderShiftBy a] : rintro X ⟨Y, hY, ⟨e⟩⟩ exact ⟨Y⟦a⟧, P.le_shift a _ hY, ⟨(shiftFunctor C a).mapIso e⟩⟩ +instance (a : A) [P.IsStableUnderShiftBy a] + [Q.IsStableUnderShiftBy a] : (P ⊓ Q).IsStableUnderShiftBy a where + le_shift _ hX := + ⟨P.le_shift a _ hX.1, Q.le_shift a _ hX.2⟩ + variable (A) in /-- `P : ObjectProperty C` is stable under the shift by `A` if `P X` implies `P X⟦a⟧` for any `a : A`. -/ @@ -78,6 +83,9 @@ attribute [instance] IsStableUnderShift.isStableUnderShiftBy instance [P.IsStableUnderShift A] : P.isoClosure.IsStableUnderShift A where +instance [P.IsStableUnderShift A] + [Q.IsStableUnderShift A] : (P ⊓ Q).IsStableUnderShift A where + lemma prop_shift_iff_of_isStableUnderShift {G : Type*} [AddGroup G] [HasShift C G] [P.IsStableUnderShift G] [P.IsClosedUnderIsomorphisms] (X : C) (g : G) : P (X⟦g⟧) ↔ P X := by diff --git a/Mathlib/CategoryTheory/Shift/CommShift.lean b/Mathlib/CategoryTheory/Shift/CommShift.lean index 4bae01e0a615a1..d49ee051a85794 100644 --- a/Mathlib/CategoryTheory/Shift/CommShift.lean +++ b/Mathlib/CategoryTheory/Shift/CommShift.lean @@ -31,8 +31,31 @@ shift functors.) namespace CategoryTheory +-- to be moved +@[reassoc] +lemma NatTrans.naturality_1 {C D : Type*} [Category C] [Category D] + {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (e : X ≅ Y) : + F.map e.inv ≫ α.app X ≫ G.map e.hom = α.app Y := by + simp + +-- to be moved +@[reassoc] +lemma NatTrans.naturality_2 {C D : Type*} [Category C] [Category D] + {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (e : X ≅ Y) : + F.map e.hom ≫ α.app Y ≫ G.map e.inv = α.app X := by + simp + open Category +instance {C D E : Type*} [Category C] [Category D] [Category E] (G : D ⥤ E) + [G.Full] [G.Faithful] : ((Functor.whiskeringRight C D E).obj G).Full where + map_surjective τ := ⟨ + { app := fun X => G.preimage (τ.app X) + naturality := fun X Y f => by + apply G.map_injective + simpa only [Functor.whiskeringRight_obj_obj, Functor.map_comp, Functor.map_preimage] + using τ.naturality f }, by aesop_cat⟩ + namespace Functor variable {C D E : Type*} [Category* C] [Category* D] [Category* E] @@ -102,6 +125,42 @@ lemma isoAdd_inv_app {a b : A} F.map ((shiftFunctorAdd C a b).inv.app X) := by simp only [isoAdd, isoAdd'_inv_app, shiftFunctorAdd'_eq_shiftFunctorAdd] +lemma isoAdd'_isoZero {a : A} + (e : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) : + isoAdd' (add_zero a) e (isoZero F A) = e := by + ext X + simp [shiftFunctorAdd'_add_zero_hom_app, ← Functor.map_comp_assoc, + shiftFunctorAdd'_add_zero_inv_app] + +lemma isoZero_isoAdd'_ {a : A} + (e : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) : + isoAdd' (zero_add a) (isoZero F A) e = e := by + ext X + have := e.hom.naturality ((shiftFunctorZero C A).inv.app X) + dsimp at this + simp [shiftFunctorAdd'_zero_add_hom_app, + shiftFunctorAdd'_zero_add_inv_app, ← map_comp, + reassoc_of% this] + +lemma isoAdd'_assoc {a b c ab bc abc : A} + (ea : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a) + (eb : shiftFunctor C b ⋙ F ≅ F ⋙ shiftFunctor D b) + (ec : shiftFunctor C c ⋙ F ≅ F ⋙ shiftFunctor D c) + (hab : a + b = ab) (hbc : b + c = bc) (h : a + b + c = abc) : + isoAdd' (show ab + c = abc by rwa [← hab]) (isoAdd' hab ea eb) ec = + isoAdd' (by rwa [← hbc, ← add_assoc]) ea (isoAdd' hbc eb ec) := by + ext X + have := NatTrans.naturality_2 ec.hom + ((shiftFunctorAdd' C a b ab hab).app X) + dsimp at this ⊢ + simp only [isoAdd'_hom_app, Category.assoc] + rw [← NatTrans.naturality_assoc, ← this, Category.assoc, ← F.map_comp_assoc, + shiftFunctorAdd'_assoc_hom_app a b c ab bc abc hab hbc h, + Functor.map_comp_assoc, Category.assoc] + nth_rw 2 [← Functor.map_comp_assoc] + nth_rw 2 [← Functor.map_comp_assoc] + simp [shiftFunctorAdd'_assoc_inv_app a b c ab bc abc hab hbc h] + end CommShift /-- A functor `F` commutes with the shift by a monoid `A` if it is equipped with @@ -181,6 +240,20 @@ instance comp [F.CommShift A] [G.CommShift A] : (F ⋙ G).CommShift A where simp only [comp_id, id_comp, assoc, ← Functor.map_comp_assoc, Iso.inv_hom_id_app, comp_obj] simp only [map_comp, assoc, commShiftIso_hom_naturality_assoc] +variable {F G} + +@[simp] +lemma commShiftIso_id_hom_app (a : A) (X : C) : + ((𝟭 C).commShiftIso a).hom.app X = 𝟙 _ := by + dsimp [commShiftIso] + rw [id_comp] + +@[simp] +lemma commShiftIso_id_inv_app (a : A) (X : C) : + ((𝟭 C).commShiftIso a).inv.app X = 𝟙 _ := by + dsimp [commShiftIso] + rw [id_comp] + end CommShift alias commShiftIso_id_hom_app := CommShift.id_commShiftIso_hom_app @@ -245,6 +318,62 @@ variable {C D E J : Type*} [Category* C] [Category* D] [Category* E] [Category* [F₁.CommShift A] [F₂.CommShift A] [F₃.CommShift A] [G.CommShift A] [G'.CommShift A] [H.CommShift A] +variable {A} in +structure CommShiftCore (a : A) : Prop where + shift_comm : (F₁.commShiftIso a).hom ≫ Functor.whiskerRight τ _ = + Functor.whiskerLeft _ τ ≫ (F₂.commShiftIso a).hom + +namespace CommShiftCore + +section + +variable {A} {a : A} (hτ : CommShiftCore τ a) + +include hτ + +@[reassoc] +lemma shift_app_comm (X : C) : + (F₁.commShiftIso a).hom.app X ≫ (τ.app X)⟦a⟧' = + τ.app (X⟦a⟧) ≫ (F₂.commShiftIso a).hom.app X := + congr_app hτ.shift_comm X + +@[reassoc] +lemma shift_app (X : C) : + (τ.app X)⟦a⟧' = (F₁.commShiftIso a).inv.app X ≫ + τ.app (X⟦a⟧) ≫ (F₂.commShiftIso a).hom.app X := by + rw [← hτ.shift_app_comm, Iso.inv_hom_id_app_assoc] + +@[reassoc] +lemma app_shift (X : C) : + τ.app (X⟦a⟧) = (F₁.commShiftIso a).hom.app X ≫ (τ.app X)⟦a⟧' ≫ + (F₂.commShiftIso a).inv.app X := by + simp [hτ.shift_app_comm_assoc τ X] + +end + +variable {τ} + +lemma zero : CommShiftCore τ (0 : A) where + shift_comm := by + ext X + simp [Functor.commShiftIso_zero, ← NatTrans.naturality] + +variable {A} + +lemma add {a b : A} (ha : CommShiftCore τ a) (hb : CommShiftCore τ b) : + CommShiftCore τ (a + b) where + shift_comm := by + ext X + have := (shiftFunctorAdd D a b).inv.naturality (τ.app X) + dsimp at this ⊢ + simp only [Functor.commShiftIso_add, Functor.CommShift.isoAdd_hom_app, + ← NatTrans.naturality_2 τ ((shiftFunctorAdd C a b).app X), + Functor.comp_obj, hb.app_shift_assoc, ha.app_shift, assoc, + (shiftFunctor D b).map_comp_assoc] + simp [← Functor.map_comp_assoc, this] + +end CommShiftCore + /-- If `τ : F₁ ⟶ F₂` is a natural transformation between two functors which commute with a shift by an additive monoid `A`, this typeclass asserts a compatibility of `τ` with these shifts. -/ @@ -254,7 +383,14 @@ class CommShift : Prop where section -variable {A} [NatTrans.CommShift τ A] +variable {A} + +variable {τ} in +lemma CommShift.of_core (h : ∀ (a : A), CommShiftCore τ a) : + CommShift τ A where + shift_comm a := (h a).shift_comm + +variable [NatTrans.CommShift τ A] @[reassoc] lemma shift_comm (a : A) : @@ -364,6 +500,141 @@ lemma ofIso_compatibility : end CommShift +end Functor + +namespace Functor + +section hasShiftOfFullyFaithful + +variable {C D : Type _} [Category C] [Category D] + {A : Type _} [AddMonoid A] [HasShift D A] + {F : C ⥤ D} (hF : F.FullyFaithful) + (s : A → C ⥤ C) (i : ∀ i, s i ⋙ F ≅ F ⋙ shiftFunctor D i) + +namespace CommShift + +def of_hasShiftOfFullyFaithful : + letI := hF.hasShift s i; F.CommShift A := by + letI := hF.hasShift s i + exact + { commShiftIso := i + commShiftIso_zero := by + ext X + simp only [comp_obj, isoZero_hom_app, ShiftMkCore.shiftFunctorZero_eq, + FullyFaithful.hasShift.map_zero_hom_app, id_obj, Category.assoc, + Iso.hom_inv_id_app, Category.comp_id] + commShiftIso_add := fun a b => by + ext X + simp only [comp_obj, isoAdd_hom_app, ShiftMkCore.shiftFunctorAdd_eq, + FullyFaithful.hasShift.map_add_hom_app, Category.assoc, ShiftMkCore.shiftFunctor_eq, + Iso.inv_hom_id_app_assoc, ← (shiftFunctor D b).map_comp_assoc, Iso.inv_hom_id_app, + Functor.map_id, Category.id_comp, Iso.hom_inv_id_app, Category.comp_id] } + +end CommShift + +lemma shiftFunctorIso_of_hasShiftOfFullyFaithful (a : A) : + letI := hF.hasShift s i; + letI := CommShift.of_hasShiftOfFullyFaithful hF s i; + F.commShiftIso a = i a := by + rfl + +end hasShiftOfFullyFaithful + +lemma map_shiftFunctorComm {C D : Type _} [Category C] [Category D] {A : Type _} [AddCommMonoid A] + [HasShift C A] [HasShift D A] (F : C ⥤ D) [F.CommShift A] (X : C) (a b : A) : + F.map ((shiftFunctorComm C a b).hom.app X) = (F.commShiftIso b).hom.app (X⟦a⟧) ≫ + ((F.commShiftIso a).hom.app X)⟦b⟧' ≫ (shiftFunctorComm D a b).hom.app (F.obj X) ≫ + ((F.commShiftIso b).inv.app X)⟦a⟧' ≫ (F.commShiftIso a).inv.app (X⟦b⟧) := by + have eq := NatTrans.congr_app (congr_arg Iso.hom (F.commShiftIso_add a b)) X + simp only [comp_obj, CommShift.isoAdd_hom_app, + ← cancel_epi (F.map ((shiftFunctorAdd C a b).inv.app X)), + ← F.map_comp_assoc, Iso.inv_hom_id_app, F.map_id, Category.id_comp] at eq + simp only [shiftFunctorComm_eq D a b _ rfl] + dsimp + simp only [shiftFunctorAdd'_eq_shiftFunctorAdd, Category.assoc, + ← reassoc_of% eq, + shiftFunctorComm_eq C a b _ rfl] + dsimp + rw [Functor.map_comp] + congr 1 + simp only [NatTrans.congr_app (congr_arg Iso.hom (F.commShiftIso_add' (add_comm b a))) X, + CommShift.isoAdd'_hom_app, Category.assoc, Iso.inv_hom_id_app_assoc, + ← Functor.map_comp_assoc, Iso.hom_inv_id_app] + dsimp + simp only [Functor.map_id, Category.id_comp, Iso.hom_inv_id_app, comp_obj, Category.comp_id] + +namespace CommShift + +variable {C D E : Type*} [Category C] [Category D] [Category E] + {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} (e : F ⋙ G ≅ H) + [Full G] [Faithful G] + (A : Type*) [AddMonoid A] [HasShift C A] [HasShift D A] [HasShift E A] + [G.CommShift A] [H.CommShift A] + +namespace OfComp + +variable {A} + +noncomputable def iso (a : A) : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a := + ((whiskeringRight C D E).obj G).preimageIso (Functor.associator _ _ _ ≪≫ + isoWhiskerLeft _ e ≪≫ + H.commShiftIso a ≪≫ isoWhiskerRight e.symm _ ≪≫ Functor.associator _ _ _ ≪≫ + isoWhiskerLeft F (G.commShiftIso a).symm ≪≫ (Functor.associator _ _ _).symm) + +@[simp] +lemma map_iso_hom_app (a : A) (X : C) : + G.map ((iso e a).hom.app X) = e.hom.app (X⟦a⟧) ≫ + (H.commShiftIso a).hom.app X ≫ (e.inv.app X)⟦a⟧' ≫ + (G.commShiftIso a).inv.app (F.obj X) := by + have h : ((whiskeringRight C D E).obj G).map (iso e a).hom = _ := + Functor.map_preimage _ _ + simpa using congr_app h X + +@[simp] +lemma map_iso_inv_app (a : A) (X : C) : + G.map ((iso e a).inv.app X) = + (G.commShiftIso a).hom.app (F.obj X) ≫ (e.hom.app X)⟦a⟧' ≫ + (H.commShiftIso a).inv.app X ≫ e.inv.app (X⟦a⟧) := by + have h : ((whiskeringRight C D E).obj G).map (iso e a).inv = _ := + Functor.map_preimage _ _ + simpa using congr_app h X + +attribute [irreducible] iso + +end OfComp + +noncomputable def ofComp : F.CommShift A where + commShiftIso := OfComp.iso e + commShiftIso_zero := by + ext X + apply G.map_injective + simp [G.commShiftIso_zero, H.commShiftIso_zero] + commShiftIso_add a b := by + ext X + apply G.map_injective + simp only [comp_obj, OfComp.map_iso_hom_app, H.commShiftIso_add, isoAdd_hom_app, + G.commShiftIso_add, isoAdd_inv_app, NatTrans.naturality_assoc, comp_map, assoc, + Iso.inv_hom_id_app_assoc, map_comp] + erw [← NatTrans.naturality_assoc, ← NatTrans.naturality_assoc] + dsimp + simp only [← Functor.map_comp_assoc] + congr 4 + simp + +lemma ofComp_compatibility : + letI := ofComp e + NatTrans.CommShift e.hom A := by + letI := ofComp e + refine ⟨fun a => ?_⟩ + ext X + have : commShiftIso F a = OfComp.iso e a := rfl + simp only [comp_obj, NatTrans.comp_app, commShiftIso_comp_hom_app, this, + OfComp.map_iso_hom_app, assoc, Iso.inv_hom_id_app, comp_id, whiskerRight_app, + whiskerLeft_app, ← Functor.map_comp, Functor.map_id] + +end CommShift + + end Functor /-- diff --git a/Mathlib/CategoryTheory/Triangulated/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Basic.lean index 7dbbba3f876c7f..bacfb60791f8a7 100644 --- a/Mathlib/CategoryTheory/Triangulated/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Basic.lean @@ -331,14 +331,10 @@ def binaryBiproductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryBipro Triangle C := Triangle.mk biprod.inl (Limits.biprod.snd : X₁ ⊞ X₂ ⟶ _) 0 -/-- The obvious triangle `X₁ ⟶ X₁ ⨯ X₂ ⟶ X₂ ⟶ X₁⟦1⟧`. -/ @[simps!] -def binaryProductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryProduct X₁ X₂] : - Triangle C := +def binaryProductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryProduct X₁ X₂] : Triangle C := Triangle.mk ((Limits.prod.lift (𝟙 X₁) 0)) (Limits.prod.snd : X₁ ⨯ X₂ ⟶ _) 0 -/-- The canonical isomorphism of triangles -`binaryProductTriangle X₁ X₂ ≅ binaryBiproductTriangle X₁ X₂`. -/ @[simps!] def binaryProductTriangleIsoBinaryBiproductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryBiproduct X₁ X₂] : @@ -394,7 +390,10 @@ def productTriangle.isLimitFan : IsLimit (productTriangle.fan T) := intro s m hm ext1 all_goals - exact Pi.hom_ext _ _ (fun j => (by simp [← hm]))) + · dsimp + ext1 j + dsimp + simp [← hm]) lemma productTriangle.zero₃₁ [HasZeroMorphisms C] (h : ∀ j, (T j).mor₃ ≫ (T j).mor₁⟦(1 : ℤ)⟧' = 0) : @@ -470,6 +469,8 @@ end section +open Functor + variable {J : Type*} [Category* J] /-- Constructor for functors to the category of triangles. -/ @@ -483,6 +484,74 @@ def functorMk {obj₁ obj₂ obj₃ : J ⥤ C} hom₂ := obj₂.map φ hom₃ := obj₃.map φ } +@[simps] +def functorHomMk (A B : J ⥤ Triangle C) (hom₁ : A ⋙ π₁ ⟶ B ⋙ π₁) + (hom₂ : A ⋙ π₂ ⟶ B ⋙ π₂) (hom₃ : A ⋙ π₃ ⟶ B ⋙ π₃) + (comm₁ : whiskerLeft A π₁Toπ₂ ≫ hom₂ = hom₁ ≫ whiskerLeft B π₁Toπ₂ := by cat_disch) + (comm₂ : whiskerLeft A π₂Toπ₃ ≫ hom₃ = hom₂ ≫ whiskerLeft B π₂Toπ₃ := by cat_disch) + (comm₃ : whiskerLeft A π₃Toπ₁ ≫ whiskerRight hom₁ (shiftFunctor C (1 : ℤ)) = + hom₃ ≫ whiskerLeft B π₃Toπ₁ := by cat_disch) : A ⟶ B where + app j := + { hom₁ := hom₁.app j + hom₂ := hom₂.app j + hom₃ := hom₃.app j + comm₁ := NatTrans.congr_app comm₁ j + comm₂ := NatTrans.congr_app comm₂ j + comm₃ := NatTrans.congr_app comm₃ j } + naturality _ _ φ := by + ext + · exact hom₁.naturality φ + · exact hom₂.naturality φ + · exact hom₃.naturality φ + +/-- Constructor for morphisms between functors constructed by `functorHomMk`. -/ +@[simps!] +def functorHomMk' + {obj₁ obj₂ obj₃ : J ⥤ C} + {mor₁ : obj₁ ⟶ obj₂} {mor₂ : obj₂ ⟶ obj₃} {mor₃ : obj₃ ⟶ obj₁ ⋙ shiftFunctor C (1 : ℤ)} + {obj₁' obj₂' obj₃' : J ⥤ C} + {mor₁' : obj₁' ⟶ obj₂'} {mor₂' : obj₂' ⟶ obj₃'} + {mor₃' : obj₃' ⟶ obj₁' ⋙ shiftFunctor C (1 : ℤ)} + (hom₁ : obj₁ ⟶ obj₁') (hom₂ : obj₂ ⟶ obj₂') (hom₃ : obj₃ ⟶ obj₃') + (comm₁ : mor₁ ≫ hom₂ = hom₁ ≫ mor₁') + (comm₂ : mor₂ ≫ hom₃ = hom₂ ≫ mor₂') + (comm₃ : mor₃ ≫ whiskerRight hom₁ (shiftFunctor C (1 : ℤ)) = hom₃ ≫ mor₃') : + functorMk mor₁ mor₂ mor₃ ⟶ functorMk mor₁' mor₂' mor₃' := + functorHomMk _ _ hom₁ hom₂ hom₃ comm₁ comm₂ comm₃ + +@[simps] +def functorIsoMk (A B : J ⥤ Triangle C) (iso₁ : A ⋙ π₁ ≅ B ⋙ π₁) + (iso₂ : A ⋙ π₂ ≅ B ⋙ π₂) (iso₃ : A ⋙ π₃ ≅ B ⋙ π₃) + (comm₁ : whiskerLeft A π₁Toπ₂ ≫ iso₂.hom = iso₁.hom ≫ whiskerLeft B π₁Toπ₂) + (comm₂ : whiskerLeft A π₂Toπ₃ ≫ iso₃.hom = iso₂.hom ≫ whiskerLeft B π₂Toπ₃) + (comm₃ : whiskerLeft A π₃Toπ₁ ≫ whiskerRight iso₁.hom (shiftFunctor C (1 : ℤ)) = + iso₃.hom ≫ whiskerLeft B π₃Toπ₁) : A ≅ B where + hom := functorHomMk _ _ iso₁.hom iso₂.hom iso₃.hom comm₁ comm₂ comm₃ + inv := functorHomMk _ _ iso₁.inv iso₂.inv iso₃.inv + (by simp only [← cancel_epi iso₁.hom, ← reassoc_of% comm₁, + Iso.hom_inv_id, comp_id, Iso.hom_inv_id_assoc]) + (by simp only [← cancel_epi iso₂.hom, ← reassoc_of% comm₂, + Iso.hom_inv_id, comp_id, Iso.hom_inv_id_assoc]) + (by + simp only [← cancel_epi iso₃.hom, ← reassoc_of% comm₃, Iso.hom_inv_id_assoc, + ← whiskerRight_comp, Iso.hom_inv_id, whiskerRight_id'] + apply comp_id) + +/-- Constructor for isomorphisms between functors constructed by `functorHomMk`. -/ +@[simps!] +def functorIsoMk' + {obj₁ obj₂ obj₃ : J ⥤ C} + {mor₁ : obj₁ ⟶ obj₂} {mor₂ : obj₂ ⟶ obj₃} {mor₃ : obj₃ ⟶ obj₁ ⋙ shiftFunctor C (1 : ℤ)} + {obj₁' obj₂' obj₃' : J ⥤ C} + {mor₁' : obj₁' ⟶ obj₂'} {mor₂' : obj₂' ⟶ obj₃'} + {mor₃' : obj₃' ⟶ obj₁' ⋙ shiftFunctor C (1 : ℤ)} + (iso₁ : obj₁ ≅ obj₁') (iso₂ : obj₂ ≅ obj₂') (iso₃ : obj₃ ≅ obj₃') + (comm₁ : mor₁ ≫ iso₂.hom = iso₁.hom ≫ mor₁') + (comm₂ : mor₂ ≫ iso₃.hom = iso₂.hom ≫ mor₂') + (comm₃ : mor₃ ≫ whiskerRight iso₁.hom (shiftFunctor C (1 : ℤ)) = iso₃.hom ≫ mor₃') : + functorMk mor₁ mor₂ mor₃ ≅ functorMk mor₁' mor₂' mor₃' := + functorIsoMk _ _ iso₁ iso₂ iso₃ comm₁ comm₂ comm₃ + end end Triangle diff --git a/Mathlib/CategoryTheory/Triangulated/Functor.lean b/Mathlib/CategoryTheory/Triangulated/Functor.lean index 9c54d1c09dbd48..c55e02b12b883b 100644 --- a/Mathlib/CategoryTheory/Triangulated/Functor.lean +++ b/Mathlib/CategoryTheory/Triangulated/Functor.lean @@ -52,6 +52,11 @@ def mapTriangle : Triangle C ⥤ Triangle D where simp only [Category.assoc, ← NatTrans.naturality, ← F.map_comp_assoc, f.comm₃] } +attribute [local simp] map_zsmul comp_zsmul zsmul_comp + commShiftIso_zero commShiftIso_add + shiftFunctorAdd'_eq_shiftFunctorAdd + commShiftIso_comp_hom_app + instance [Faithful F] : Faithful F.mapTriangle where map_injective {X Y} f g h := by ext <;> apply F.map_injective @@ -228,6 +233,16 @@ instance [F.IsTriangulated] [G.IsTriangulated] : (F ⋙ G).IsTriangulated where end IsTriangulated +lemma map_distinguished_iff [F.IsTriangulated] [Full F] [Faithful F] (T : Triangle C) : + (F.mapTriangle.obj T ∈ distTriang D) ↔ T ∈ distTriang C := by + constructor + · intro hT + obtain ⟨Z, g, h, mem⟩ := distinguished_cocone_triangle T.mor₁ + refine isomorphic_distinguished _ mem _ (F.mapTriangle.preimageIso ?_) + exact isoTriangleOfIso₁₂ _ _ hT (F.map_distinguished _ mem) (Iso.refl _) (Iso.refl _) + (by simp) + · exact F.map_distinguished T + lemma isTriangulated_of_iso {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) [F₁.CommShift ℤ] [F₂.CommShift ℤ] [NatTrans.CommShift e.hom ℤ] [F₁.IsTriangulated] : F₂.IsTriangulated where map_distinguished T hT := @@ -242,6 +257,21 @@ lemma isTriangulated_iff_of_iso {F₁ F₂ : C ⥤ D} (e : F₁ ≅ F₂) [F₁. have : NatTrans.CommShift e.symm.hom ℤ := inferInstanceAs (NatTrans.CommShift e.inv ℤ) exact isTriangulated_of_iso e.symm +lemma isTriangulated_iff_comp_right {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} (e : F ⋙ G ≅ H) + [F.CommShift ℤ] [G.CommShift ℤ] [H.CommShift ℤ] [NatTrans.CommShift e.hom ℤ] + [G.IsTriangulated] [Full G] [Faithful G] : + F.IsTriangulated ↔ H.IsTriangulated := by + rw [← isTriangulated_iff_of_iso e] + constructor + · intro + infer_instance + · intro + constructor + intro T hT + rw [← G.map_distinguished_iff] + exact isomorphic_distinguished _ ((F ⋙ G).map_distinguished T hT) _ + ((mapTriangleCompIso F G).symm.app T) + lemma mem_mapTriangle_essImage_of_distinguished [F.IsTriangulated] [F.mapArrow.EssSurj] (T : Triangle D) (hT : T ∈ distTriang D) : ∃ (T' : Triangle C) (_ : T' ∈ distTriang C), Nonempty (F.mapTriangle.obj T' ≅ T) := by @@ -320,9 +350,46 @@ lemma isTriangulated_of_essSurj_mapComposableArrows_two obtain ⟨_, _, _, h₁₂'⟩ := distinguished_cocone_triangle f obtain ⟨_, _, _, h₂₃'⟩ := distinguished_cocone_triangle g obtain ⟨_, _, _, h₁₃'⟩ := distinguished_cocone_triangle (f ≫ g) - exact ⟨Octahedron.ofIso (e₁ := (e.app 0).symm) (e₂ := (e.app 1).symm) (e₃ := (e.app 2).symm) + constructor + exact Octahedron.ofIso + (e₁ := (e.app 0).symm) (e₂ := (e.app 1).symm) (e₃ := (e.app 2).symm) (comm₁₂ := ComposableArrows.naturality' e.inv 0 1) (comm₂₃ := ComposableArrows.naturality' e.inv 1 2) - (H := (someOctahedron rfl h₁₂' h₂₃' h₁₃').map F) ..⟩ + (H := (someOctahedron rfl h₁₂' h₂₃' h₁₃').map F) .. + +section + +variable {C D : Type _} [Category C] [Category D] + [HasShift C ℤ] [HasShift D ℤ] [HasZeroObject C] [HasZeroObject D] + [Preadditive C] [Preadditive D] + [∀ (n : ℤ), (shiftFunctor C n).Additive] [∀ (n : ℤ), (shiftFunctor D n).Additive] + [Pretriangulated C] [Pretriangulated D] + (F : C ⥤ D) [F.CommShift ℤ] + +lemma IsTriangulated.of_fully_faithful_triangulated_functor + [F.IsTriangulated] [F.Full] [F.Faithful] [IsTriangulated D] : + IsTriangulated C where + octahedron_axiom {X₁ X₂ X₃ Z₁₂ Z₂₃ Z₁₃ u₁₂ u₂₃ u₁₃} comm + {v₁₂ w₁₂} h₁₂ {v₂₃ w₂₃} h₂₃ {v₁₃ w₁₃} h₁₃ := by + have comm' : F.map u₁₂ ≫ F.map u₂₃ = F.map u₁₃ := by rw [← comm, F.map_comp] + have H := Triangulated.someOctahedron comm' (F.map_distinguished _ h₁₂) + (F.map_distinguished _ h₂₃) (F.map_distinguished _ h₁₃) + exact + ⟨{ + m₁ := F.preimage H.m₁ + m₃ := F.preimage H.m₃ + comm₁ := F.map_injective (by simpa using H.comm₁) + comm₂ := F.map_injective (by + rw [← cancel_mono ((F.commShiftIso (1 : ℤ)).hom.app X₁)] + simpa using H.comm₂) + comm₃ := F.map_injective (by simpa using H.comm₃) + comm₄ := F.map_injective (by + rw [← cancel_mono ((F.commShiftIso (1 : ℤ)).hom.app X₂)] + simpa using H.comm₄) + mem := by + rw [← F.map_distinguished_iff] + simpa using H.mem }⟩ + +end end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean index 1ecbfef8e09231..71bbdbe22e89e0 100644 --- a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean +++ b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean @@ -35,6 +35,43 @@ universe v v₀ v₁ v₂ u u₀ u₁ u₂ namespace CategoryTheory +namespace Limits + +-- should be moved to a better place +namespace BinaryBiproductData + +variable {C : Type _} [Category C] + {X₁ X₂ : C} [HasZeroMorphisms C] [HasBinaryBiproduct X₁ X₂] (d : BinaryBiproductData X₁ X₂) + +def isoBiprod {C : Type _} [Category C] + {X₁ X₂ : C} [HasZeroMorphisms C] [HasBinaryBiproduct X₁ X₂] (d : BinaryBiproductData X₁ X₂) : + X₁ ⊞ X₂ ≅ d.bicone.pt := + IsLimit.conePointUniqueUpToIso (BinaryBiproduct.isLimit X₁ X₂) d.isBilimit.isLimit + +@[reassoc (attr := simp)] +lemma isoBiprod_inv_fst : d.isoBiprod.inv ≫ biprod.fst = d.bicone.fst := + IsLimit.conePointUniqueUpToIso_inv_comp _ d.isBilimit.isLimit ⟨WalkingPair.left⟩ + +@[reassoc (attr := simp)] +lemma isoBiprod_inv_snd : d.isoBiprod.inv ≫ biprod.snd = d.bicone.snd := + IsLimit.conePointUniqueUpToIso_inv_comp _ d.isBilimit.isLimit ⟨WalkingPair.right⟩ + +@[reassoc (attr := simp)] +lemma isoBiprod_hom_fst : d.isoBiprod.hom ≫ d.bicone.fst = biprod.fst := by + rw [← isoBiprod_inv_fst, Iso.hom_inv_id_assoc] + +@[reassoc (attr := simp)] +lemma isoBiprod_hom_snd : d.isoBiprod.hom ≫ d.bicone.snd = biprod.snd := by + rw [← isoBiprod_inv_snd, Iso.hom_inv_id_assoc] + +end BinaryBiproductData + +end Limits + +end CategoryTheory + +namespace CategoryTheory + open Category Pretriangulated ZeroObject /- @@ -403,13 +440,36 @@ lemma shift_distinguished (n : ℤ) : | zero => exact H_neg_one | succ n hn => exact H_add hn H_neg_one rfl -omit hT in +section + +omit hT + lemma shift_distinguished_iff (n : ℤ) : (CategoryTheory.shiftFunctor (Triangle C) n).obj T ∈ (distTriang C) ↔ T ∈ distTriang C := ⟨fun hT ↦ isomorphic_distinguished _ (shift_distinguished _ hT (-n)) _ ((shiftEquiv (Triangle C) n).unitIso.app T), fun hT ↦ shift_distinguished T hT n⟩ +lemma distinguished_iff_of_isZero₃ (T : Triangle C) (h : IsZero T.obj₃) : + T ∈ distTriang _ ↔ IsIso T.mor₁ := + ⟨fun hT ↦ by rwa [← isZero₃_iff_isIso₁ _ hT], + fun _ ↦ isomorphic_distinguished _ (contractible_distinguished T.obj₁) _ + (isoMk _ _ (Iso.refl _) (asIso T.mor₁).symm h.isoZero (by simp) + ((isZero_zero C).eq_of_tgt _ _) (h.eq_of_src _ _))⟩ + +lemma distinguished_iff_of_isZero₁ (T : Triangle C) (h : IsZero T.obj₁) : + T ∈ distTriang _ ↔ IsIso T.mor₂ := by + rw [rotate_distinguished_triangle, + distinguished_iff_of_isZero₃ _ (Functor.map_isZero (CategoryTheory.shiftFunctor C 1) h)] + simp + +lemma distinguished_iff_of_isZero₂ (T : Triangle C) (h : IsZero T.obj₂) : + T ∈ distTriang _ ↔ IsIso T.mor₃ := by + rw [rotate_distinguished_triangle, distinguished_iff_of_isZero₁ _ h] + simp + +end + end Triangle instance : SplitEpiCategory C where @@ -521,6 +581,7 @@ instance : HasBinaryBiproducts C := ⟨fun X₁ X₃ => by instance : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal instance : HasFiniteCoproducts C := hasFiniteCoproducts_of_has_binary_and_initial instance : HasFiniteBiproducts C := HasFiniteBiproducts.of_hasFiniteProducts +instance : HasBinaryProducts C := inferInstance lemma exists_iso_binaryBiproduct_of_distTriang (T : Triangle C) (hT : T ∈ distTriang C) (zero : T.mor₃ = 0) : @@ -661,6 +722,32 @@ def isoTriangleOfIso₁₂ (T₁ T₂ : Triangle C) (hT₁ : T₁ ∈ distTriang dsimp at eq ⊢ conv_lhs => rw [← eq, TriangleMorphism.comm₃]) +@[simps! hom_hom₁ hom_hom₃ inv_hom₁ inv_hom₃] +def isoTriangleOfIso₁₃ (T₁ T₂ : Triangle C) (hT₁ : T₁ ∈ distTriang C) + (hT₂ : T₂ ∈ distTriang C) (e₁ : T₁.obj₁ ≅ T₂.obj₁) (e₃ : T₁.obj₃ ≅ T₂.obj₃) + (comm : T₁.mor₃ ≫ (shiftFunctor C 1).map e₁.hom = e₃.hom ≫ T₂.mor₃) : + T₁ ≅ T₂ := by + have h := exists_iso_of_arrow_iso _ _ (inv_rot_of_distTriang _ hT₁) + (inv_rot_of_distTriang _ hT₂) + (Arrow.isoMk ((shiftFunctor C (-1)).mapIso e₃) e₁ (by + dsimp + simp only [comp_neg, neg_comp, assoc, neg_inj, ← Functor.map_comp_assoc, ← comm] + simp only [Functor.map_comp, assoc] + erw [← NatTrans.naturality] + rfl)) + let e := h.choose + refine Triangle.isoMk _ _ e₁ (Triangle.π₃.mapIso e) e₃ ?_ ?_ comm + · refine e.hom.comm₂.trans ?_ + congr 1 + exact h.choose_spec.2 + · rw [← cancel_mono ((shiftFunctorCompIsoId C (-1) 1 (neg_add_cancel 1)).inv.app T₂.obj₃)] + rw [assoc, assoc] + refine Eq.trans ?_ e.hom.comm₃ + rw [h.choose_spec.1] + dsimp + erw [assoc, ← NatTrans.naturality] + rfl + end Pretriangulated end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index e85fdf21a18769..bdf53c556539ad 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -8,8 +8,10 @@ module public import Mathlib.CategoryTheory.Localization.CalculusOfFractions public import Mathlib.CategoryTheory.Localization.Triangulated public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero +public import Mathlib.CategoryTheory.ObjectProperty.LimitsOfShape public import Mathlib.CategoryTheory.ObjectProperty.Shift public import Mathlib.CategoryTheory.Shift.Localization +public import Mathlib.CategoryTheory.MorphismProperty.Limits /-! # Triangulated subcategories @@ -48,7 +50,53 @@ namespace CategoryTheory open Category Limits Preadditive ZeroObject Pretriangulated Triangulated -variable {C : Type*} [Category* C] [HasZeroObject C] [HasShift C ℤ] +namespace Limits + +variable {C J₁ J₂ : Type _} [Category C] + (X : J₂ → C) (e : J₁ ≃ J₂) [HasProduct X] + +noncomputable def fanOfEquiv : Fan (X ∘ e) := Fan.mk (∏ᶜ X) (fun _ => Pi.π _ _) + +@[simp] +lemma fanOfEquiv_proj (j : J₁) : (fanOfEquiv X e).proj j = Pi.π _ (e j) := rfl + +@[reassoc] +lemma Fan.congr_proj {J : Type _} {F : J → C} (s : Fan F) + {j₁ j₂ : J} (h : j₁ = j₂) : s.proj j₁ ≫ eqToHom (by rw [h]) = s.proj j₂ := by + subst h + simp + +@[reassoc] +lemma Pi.congr_π {J : Type _} (F : J → C) [HasProduct F] {j₁ j₂ : J} (h : j₁ = j₂) : + Pi.π F j₁ ≫ eqToHom (by rw [h]) = Pi.π F j₂ := by + subst h + simp + +noncomputable def isLimitFanOfEquiv : IsLimit (fanOfEquiv X e) := + mkFanLimit _ (fun s => Pi.lift (fun j₂ => s.proj (e.symm j₂) ≫ eqToHom (by simp) )) + (fun s j => by simp [Fan.congr_proj _ (e.symm_apply_apply j)]) + (fun s m hm => Limits.Pi.hom_ext (f := X) _ _ (fun j ↦ by simp [← hm])) + +lemma hasProductOfEquiv : HasProduct (X ∘ e) := + ⟨⟨_, isLimitFanOfEquiv X e⟩⟩ + +noncomputable def productIsoOfEquiv [HasProduct (X ∘ e)] : ∏ᶜ (X ∘ e) ≅ ∏ᶜ X := + IsLimit.conePointUniqueUpToIso (limit.isLimit _) (isLimitFanOfEquiv X e) + +noncomputable def productOptionIso {C J : Type _} [Category C] + (X : Option J → C) [HasProduct X] [HasProduct (fun j => X (some j))] + [HasBinaryProduct (∏ᶜ (fun j => X (some j))) (X none)] : + (∏ᶜ X) ≅ (∏ᶜ (fun j => X (some j))) ⨯ (X none) where + hom := prod.lift (Pi.lift (fun j => Pi.π _ (some j))) (Pi.π _ none) + inv := Pi.lift (fun b => match b with + | some j => prod.fst ≫ Pi.π _ j + | none => prod.snd) + +end Limits + +open Pretriangulated + +variable {C : Type*} [Category C] [HasZeroObject C] [HasShift C ℤ] [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] namespace ObjectProperty @@ -250,6 +298,13 @@ lemma trW_iff_of_distinguished · intro h exact ⟨_, _, _, hT, h⟩ +/-- Variant of `mem_W_iff_of_distinguished`. -/ +lemma trW_iff_of_distinguished' [P.IsStableUnderShift ℤ] + [P.IsClosedUnderIsomorphisms] (T : Triangle C) (hT : T ∈ distTriang C) : + P.trW T.mor₂ ↔ P T.obj₁ := by + simpa [P.prop_shift_iff_of_isStableUnderShift] + using P.trW_iff_of_distinguished _ (rot_of_distTriang _ hT) + instance [IsTriangulated C] [P.IsTriangulated] : P.trW.HasLeftCalculusOfFractions where exists_leftFraction X Y φ := by obtain ⟨Z, f, g, H, mem⟩ := φ.hs @@ -296,6 +351,293 @@ instance [IsTriangulated C] [P.IsTriangulated] : P.trW.IsCompatibleWithTriangula exact ⟨φ.hom₃, P.trW.comp_mem _ _ (trW.mk P H.mem mem₄') (trW.mk' P H'.mem mem₅'), by simpa [φ] using φ.comm₂, by simpa [φ] using φ.comm₃⟩⟩ +lemma binary_product_stable_of_isTriangulated [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] + (X₁ X₂ : C) (hX₁ : P X₁) (hX₂ : P X₂) : + P (X₁ ⨯ X₂) := + P.ext_of_isTriangulatedClosed₂ _ (binaryProductTriangle_distinguished X₁ X₂) hX₁ hX₂ + +lemma pi_finite_stable [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] + {J : Type} [Finite J] (X : J → C) (hX : ∀ j, P (X j)) : + P (∏ᶜ X) := by + revert hX X + let Q : Type → Prop := fun J => + ∀ [hJ : Finite J] (X : J → C) (_ : ∀ j, P (X j)), P (∏ᶜ X) + suffices Q J by convert this + apply @Finite.induction_empty_option + · intro J₁ J₂ e hJ₁ _ X hX + have : Finite J₁ := Finite.of_equiv _ e.symm + exact prop_of_iso _ (productIsoOfEquiv X e) (hJ₁ (fun j₁ => X (e j₁)) (fun j₁ => hX _)) + · intro _ X _ + refine prop_of_iso _ (IsZero.isoZero ?_).symm P.prop_zero + rw [IsZero.iff_id_eq_zero] + ext ⟨⟩ + · intro J _ hJ _ X hX + exact prop_of_iso _ (productOptionIso X).symm + (P.binary_product_stable_of_isTriangulated _ _ + (hJ (fun j => X (some j)) (fun j => hX _)) (hX none)) + +instance [P.IsTriangulated] : P.trW.IsStableUnderFiniteProducts := by + rw [← trW_isoClosure] + exact ⟨fun J _ => by + refine MorphismProperty.IsStableUnderProductsOfShape.mk _ _ ?_ + intro _ _ X₁ X₂ f hf + exact trW.mk _ (productTriangle_distinguished _ + (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose)) + (pi_finite_stable _ _ (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose_spec))⟩ + +lemma closedUnderLimitsOfShape_discrete_of_isTriangulated + [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] (J : Type) [Finite J] : + P.IsClosedUnderLimitsOfShape (Discrete J) where + limitsOfShape_le := by + rintro X ⟨p⟩ + let G (j : J) : C := p.diag.obj ⟨j⟩ + have e : Discrete.functor G ≅ p.diag := Discrete.natIso (fun _ ↦ Iso.refl _) + have := IsLimit.conePointUniqueUpToIso (limit.isLimit _) + ((IsLimit.postcomposeInvEquiv e _).2 p.isLimit) + exact P.prop_of_iso this (P.pi_finite_stable G (fun j ↦ p.prop_diag_obj _)) + +section + +instance (P' : ObjectProperty C) [P.IsTriangulatedClosed₂] [P.IsClosedUnderIsomorphisms] + [P'.IsTriangulatedClosed₂] : + (P ⊓ P').IsTriangulatedClosed₂ where + ext₂' T hT h₁ h₃ := by + obtain ⟨X₂, h₂, ⟨e⟩⟩ := P'.ext_of_isTriangulatedClosed₂' T hT h₁.2 h₃.2 + exact ⟨X₂, ⟨P.prop_of_iso e (P.ext_of_isTriangulatedClosed₂ T hT h₁.1 h₃.1), h₂⟩, ⟨e⟩⟩ + +instance (P' : ObjectProperty C) [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] + [P'.IsTriangulated] : + (P ⊓ P').IsTriangulated where + +end + +section + +variable [IsTriangulated C] [P.IsTriangulated] + +noncomputable example : Pretriangulated (P.trW.Localization) := inferInstance +example : IsTriangulated (P.trW.Localization) := inferInstance +example : P.trW.Q.IsTriangulated := inferInstance + +end + +example : Preadditive P.FullSubcategory := inferInstance +example : P.ι.Additive := inferInstance + +section + +variable [P.IsTriangulated] + +noncomputable instance hasShift : + HasShift P.FullSubcategory ℤ := + P.fullyFaithfulι.hasShift (fun n ↦ ObjectProperty.lift _ (P.ι ⋙ shiftFunctor C n) + (fun X ↦ P.le_shift n _ X.2)) (fun _ => P.liftCompιIso _ _) + +instance commShiftι : P.ι.CommShift ℤ := + Functor.CommShift.of_hasShiftOfFullyFaithful _ _ _ + +-- these definitions are made irreducible to prevent (at least temporarily) any abuse of defeq +attribute [irreducible] hasShift commShiftι + +instance (n : ℤ) : (shiftFunctor P.FullSubcategory n).Additive := by + have := Functor.additive_of_iso (P.ι.commShiftIso n).symm + apply Functor.additive_of_comp_faithful _ P.ι + +instance : HasZeroObject P.FullSubcategory where + zero := by + obtain ⟨Z, hZ, mem⟩ := P.exists_prop_of_containsZero + refine ⟨⟨Z, mem⟩, ?_⟩ + rw [IsZero.iff_id_eq_zero] + apply ObjectProperty.hom_ext + apply hZ.eq_of_src + +attribute [local simp] ObjectProperty.fullyFaithfulι fullyFaithfulInducedFunctor + +noncomputable instance : Pretriangulated P.FullSubcategory where + distinguishedTriangles := fun T => P.ι.mapTriangle.obj T ∈ distTriang C + isomorphic_distinguished := fun T₁ hT₁ T₂ e => + isomorphic_distinguished _ hT₁ _ (P.ι.mapTriangle.mapIso e) + contractible_distinguished X := by + refine isomorphic_distinguished _ (contractible_distinguished (P.ι.obj X)) _ ?_ + exact Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) P.ι.mapZeroObject + (by aesop_cat) (by aesop_cat) (by aesop_cat) + distinguished_cocone_triangle {X Y} f := by + obtain ⟨Z', g', h', mem⟩ := distinguished_cocone_triangle (P.ι.map f) + obtain ⟨Z'', hZ'', ⟨e⟩⟩ := P.ext_of_isTriangulatedClosed₃' _ mem X.2 Y.2 + let Z : P.FullSubcategory := ⟨Z'', hZ''⟩ + refine ⟨Z, P.fullyFaithfulι.preimage (g' ≫ e.hom), + P.fullyFaithfulι.preimage (e.inv ≫ h' ≫ (P.ι.commShiftIso (1 : ℤ)).inv.app X), + isomorphic_distinguished _ mem _ ?_⟩ + exact Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) e.symm + (by aesop_cat) (by simp) (by simp) + rotate_distinguished_triangle T := + (rotate_distinguished_triangle (P.ι.mapTriangle.obj T)).trans + (distinguished_iff_of_iso (P.ι.mapTriangleRotateIso.app T)) + complete_distinguished_triangle_morphism T₁ T₂ hT₁ hT₂ a b comm := by + obtain ⟨c, ⟨hc₁, hc₂⟩⟩ := complete_distinguished_triangle_morphism (P.ι.mapTriangle.obj T₁) + (P.ι.mapTriangle.obj T₂) hT₁ hT₂ (P.ι.map a) (P.ι.map b) + (by simpa using P.ι.congr_map comm) + have ⟨c', hc'⟩ : ∃ (c' : T₁.obj₃ ⟶ T₂.obj₃), c = P.ι.map c' := + ⟨P.fullyFaithfulι.preimage c, by simp⟩ + dsimp at hc₁ hc₂ + rw [hc'] at hc₁ + rw [hc', assoc] at hc₂ + dsimp at hc₂ + erw [← Functor.commShiftIso_hom_naturality] at hc₂ + refine ⟨c', ⟨P.ι.map_injective ?_, P.ι.map_injective ?_⟩⟩ + · simpa using hc₁ + · rw [← cancel_mono ((Functor.commShiftIso P.ι (1 : ℤ)).hom.app T₂.obj₁), + P.ι.map_comp, P.ι.map_comp, assoc, assoc] + erw [hc₂] + rfl + +instance : P.ι.IsTriangulated := ⟨fun _ hT => hT⟩ + +instance [IsTriangulated C] : IsTriangulated P.FullSubcategory := + IsTriangulated.of_fully_faithful_triangulated_functor P.ι + +section + +variable {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] + [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] + +instance : (F.essImage).IsTriangulated where + isStableUnderShiftBy n := + { le_shift := by + rintro Y ⟨X, ⟨e⟩⟩ + exact ⟨X⟦n⟧, ⟨(F.commShiftIso n).app _ ≪≫ (shiftFunctor D n).mapIso e⟩⟩ } + exists_zero := ⟨0, isZero_zero D, ⟨0, ⟨F.mapZeroObject⟩⟩⟩ + toIsTriangulatedClosed₂ := .mk' (by + rintro T hT ⟨X₁, ⟨e₁⟩⟩ ⟨X₃, ⟨e₃⟩⟩ + have ⟨h, hh⟩ := F.map_surjective (e₃.hom ≫ T.mor₃ ≫ e₁.inv⟦1⟧' ≫ + (F.commShiftIso (1 : ℤ)).inv.app X₁) + obtain ⟨X₂, f, g, H⟩ := distinguished_cocone_triangle₂ h + exact ⟨X₂, ⟨Triangle.π₂.mapIso + (isoTriangleOfIso₁₃ _ _ (F.map_distinguished _ H) hT e₁ e₃ (by + dsimp + simp only [hh, assoc, Iso.inv_hom_id_app, Functor.comp_obj, + comp_id, ← Functor.map_comp, + Iso.inv_hom_id, Functor.map_id]))⟩⟩) + + + +end + +section + +variable {D : Type*} [Category D] (F : D ⥤ C) (hF : ∀ (X : D), P (F.obj X)) + +-- some of these are general API, not specific to triangulated subcategories + +instance [F.Faithful] : (P.lift F hF).Faithful := + Functor.Faithful.of_comp_iso (P.liftCompιIso F hF) + +instance [F.Full] : (P.lift F hF).Full := + Functor.Full.of_comp_faithful_iso (P.liftCompιIso F hF) + +-- should be generalized +instance [Preadditive D] [F.Additive] : (P.lift F hF).Additive where + map_add {X Y f g} := by + apply P.ι.map_injective + apply F.map_add + +noncomputable instance [HasShift D ℤ] [F.CommShift ℤ] : (P.lift F hF).CommShift ℤ := + Functor.CommShift.ofComp (P.liftCompιIso F hF) ℤ + +noncomputable instance [HasShift D ℤ] [F.CommShift ℤ] : + NatTrans.CommShift (P.liftCompιIso F hF).hom ℤ := + Functor.CommShift.ofComp_compatibility _ _ + +instance isTriangulated_lift [HasShift D ℤ] [Preadditive D] [F.CommShift ℤ] [HasZeroObject D] + [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] [F.IsTriangulated] : + (P.lift F hF).IsTriangulated := by + rw [Functor.isTriangulated_iff_comp_right (P.liftCompιIso F hF)] + infer_instance + +end + +section + +variable {D : Type*} [Category D] [Preadditive D] [HasZeroObject D] [HasShift D ℤ] + [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + (F : D ⥤ C) [F.CommShift ℤ] [F.IsTriangulated] + [P.IsClosedUnderIsomorphisms] + +instance : (P.inverseImage F).IsTriangulated where + isStableUnderShiftBy n := + { le_shift _ hY := P.prop_of_iso ((F.commShiftIso n).symm.app _) (P.le_shift n _ hY) } + toIsTriangulatedClosed₂ := .mk' (fun T hT h₁ h₃ ↦ + P.ext_of_isTriangulatedClosed₂ _ (F.map_distinguished T hT) h₁ h₃) + +omit [P.IsTriangulated] in +lemma inverseImage_trW_iff {X Y : D} (s : X ⟶ Y) : + (P.inverseImage F).trW s ↔ P.trW (F.map s) := by + obtain ⟨Z, g, h, hT⟩ := distinguished_cocone_triangle s + have eq₁ := (P.inverseImage F).trW_iff_of_distinguished _ hT + have eq₂ := P.trW_iff_of_distinguished _ (F.map_distinguished _ hT) + dsimp at eq₁ eq₂ + rw [eq₁, prop_inverseImage_iff, eq₂] + +omit [P.IsTriangulated] in +lemma inverseImage_W_isInverted {E : Type*} [Category E] + (L : C ⥤ E) [L.IsLocalization P.trW] : + (P.inverseImage F).trW.IsInvertedBy (F ⋙ L) := + fun X Y f hf => Localization.inverts L P.trW (F.map f) + (by simpa only [inverseImage_trW_iff] using hf) + +end + +section + +variable {D : Type*} [Category D] [Preadditive D] [HasZeroObject D] [HasShift D ℤ] + [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + {F G : C ⥤ D} [F.CommShift ℤ] [G.CommShift ℤ] [F.IsTriangulated] + [G.IsTriangulated] (τ : F ⟶ G) [NatTrans.CommShift τ ℤ] + +def ofNatTrans : ObjectProperty C := fun X ↦ IsIso (τ.app X) + +instance : (ofNatTrans τ).IsClosedUnderIsomorphisms where + of_iso e h := by + dsimp [ofNatTrans] at h ⊢ + rwa [← NatTrans.isIso_app_iff_of_iso τ e] + +instance : (ofNatTrans τ).IsTriangulated where + exists_zero := ⟨0, isZero_zero C, + ⟨0, (F.map_isZero (isZero_zero C)).eq_of_src _ _, + (G.map_isZero (isZero_zero C)).eq_of_src _ _⟩⟩ + isStableUnderShiftBy n := + { le_shift X (hX : IsIso _) := by + simp only [prop_shift_iff, ofNatTrans, NatTrans.app_shift] + infer_instance } + toIsTriangulatedClosed₂ := .mk' (fun T hT _ _ ↦ by + exact Pretriangulated.isIso₂_of_isIso₁₃ + ((Pretriangulated.Triangle.homMk _ _ (τ.app _) (τ.app _) (τ.app _) + (by simp) (by simp) (by simp [NatTrans.shift_app_comm]))) + (F.map_distinguished _ hT) (G.map_distinguished _ hT) (by assumption) (by assumption)) + +end + +section + +variable {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] + [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] + +instance : (P.map F).IsTriangulated := by + convert inferInstanceAs (P.ι ⋙ F).essImage.IsTriangulated + ext Y + constructor + · rintro ⟨X, hX, ⟨e⟩⟩ + exact ⟨⟨X, hX⟩, ⟨e⟩⟩ + · rintro ⟨X, ⟨e⟩⟩ + exact ⟨X.1, X.2, ⟨e⟩⟩ + + +end + +end + end ObjectProperty namespace Triangulated diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean index 6edcdf971c8db3..f6acd4278c5cc7 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean @@ -5,8 +5,9 @@ Authors: Joël Riou -/ module +public import Mathlib.CategoryTheory.ObjectProperty.CompleteLattice public import Mathlib.CategoryTheory.ObjectProperty.Shift -public import Mathlib.CategoryTheory.Triangulated.Pretriangulated +public import Mathlib.CategoryTheory.Triangulated.Subcategory /-! # t-structures on triangulated categories @@ -28,12 +29,7 @@ use depending on the context. ## TODO -* define functors `t.truncLE n : C ⥤ C`, `t.truncGE n : C ⥤ C` and the - associated distinguished triangles -* promote these truncations to a (functorial) spectral object * define the heart of `t` and show it is an abelian category -* define triangulated subcategories `t.plus`, `t.minus`, `t.bounded` and show - that there are induced t-structures on these full subcategories ## References * [Beilinson, Bernstein, Deligne, Gabber, *Faisceaux pervers*][bbd-1982] @@ -48,11 +44,11 @@ namespace CategoryTheory open Limits -namespace Triangulated - -variable (C : Type _) [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] +variable (C : Type*) [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] +namespace Triangulated + open Pretriangulated /-- `TStructure C` is the type of t-structures on the (pre)triangulated category `C`. -/ @@ -237,6 +233,41 @@ lemma isZero (X : C) (n₀ n₁ : ℤ) (h : n₀ < n₁ := by lia) rw [IsZero.iff_id_eq_zero] exact t.zero _ n₀ n₁ h +/-- The full subcategory consisting of `t`-bounded above objects. -/ +def minus : ObjectProperty C := fun X ↦ ∃ (n : ℤ), t.IsLE X n + +/-- The full subcategory consisting of `t`-bounded below objects. -/ +def plus : ObjectProperty C := fun X ↦ ∃ (n : ℤ), t.IsGE X n + +/-- The full subcategory consisting of `t`-bounded objects. -/ +def bounded : ObjectProperty C := t.plus ⊓ t.minus + +instance : t.minus.IsClosedUnderIsomorphisms where + of_iso e := by rintro ⟨n, _⟩; exact ⟨_, t.isLE_of_iso e n⟩ + +instance : t.minus.IsStableUnderShift ℤ where + isStableUnderShiftBy n := + { le_shift := by + rintro X ⟨i, _⟩ + exact ⟨i - n, t.isLE_shift _ i _ _ (by omega)⟩ } + +instance : t.plus.IsClosedUnderIsomorphisms where + of_iso e := by rintro ⟨n, _⟩; exact ⟨_, t.isGE_of_iso e n⟩ + +instance : t.plus.IsStableUnderShift ℤ where + isStableUnderShiftBy n := + { le_shift := by + rintro X ⟨i, _⟩ + exact ⟨i - n, t.isGE_shift _ i _ _ (by omega)⟩ } + +instance : t.bounded.IsClosedUnderIsomorphisms := by + dsimp [bounded] + infer_instance + +instance : t.bounded.IsStableUnderShift ℤ := by + dsimp [bounded] + infer_instance + end TStructure end Triangulated diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean new file mode 100644 index 00000000000000..5e0da4f7daf1a3 --- /dev/null +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -0,0 +1,539 @@ +/- +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.CategoryTheory.Triangulated.TStructure.TruncLEGT +public import Mathlib.Data.EInt.Basic + +/-! +# Truncations for a t-structure + +Let `t` be a t-structure on a triangulated category `C`. +In this file, we extend the definition of the truncation functors +`truncLT` and `truncGE` for indices in `ℤ` to `EInt`, +as `t.eTruncLT : EInt ⥤ C ⥤ C` and `t.eTruncGE : EInt ⥤ C ⥤ C`. + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits Pretriangulated ZeroObject Preadditive + +variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] + [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] + +namespace Triangulated + +namespace TStructure + +variable (t : TStructure C) + +/-- The functor `EInt ⥤ C ⥤ C` which sends `⊥` to the zero functor, +`n : ℤ` to `t.truncLT n` and `⊤` to `𝟭 C`. -/ +noncomputable def eTruncLT : EInt ⥤ C ⥤ C where + obj n := by + induction n with + | bot => exact 0 + | coe a => exact t.truncLT a + | top => exact 𝟭 C + map {x y} f := by + induction x with + | bot => + induction y with + | bot => exact 𝟙 _ + | coe b => exact 0 + | top => exact 0 + | coe a => + induction y with + | bot => exact 0 + | coe b => exact t.natTransTruncLTOfLE a b (by simpa using leOfHom f) + | top => exact t.truncLTι a + | top => + induction y with + | bot => exact 0 + | coe b => exact 0 + | top => exact 𝟙 _ + map_id n := by induction n <;> simp + map_comp {x y z} f g := by + have f' := leOfHom f + have g' := leOfHom g + induction x <;> induction y <;> induction z <;> cat_disch + +@[simp] +lemma eTruncLT_obj_top : t.eTruncLT.obj ⊤ = 𝟭 _ := rfl + +@[simp] +lemma eTruncLT_obj_bot : t.eTruncLT.obj ⊥ = 0 := rfl + +@[simp] +lemma eTruncLT_obj_mk (n : ℤ) : t.eTruncLT.obj (EInt.mk n) = t.truncLT n := rfl + +@[simp] +lemma eTruncLT_map_eq_truncLTι (n : ℤ) : + t.eTruncLT.map (homOfLE (show EInt.mk n ≤ ⊤ by simp)) = t.truncLTι n := rfl + +instance (i : EInt) : (t.eTruncLT.obj i).Additive := by + induction i <;> constructor <;> cat_disch + +/-- The functor `EInt ⥤ C ⥤ C` which sends `⊥` to `𝟭 C`, +`n : ℤ` to `t.truncGE n` and `⊤` to the zero functor. -/ +noncomputable def eTruncGE : EInt ⥤ C ⥤ C where + obj n := by + induction n with + | bot => exact 𝟭 C + | coe a => exact t.truncGE a + | top => exact 0 + map {x y} f := by + induction x with + | bot => + induction y with + | bot => exact 𝟙 _ + | coe b => exact t.truncGEπ b + | top => exact 0 + | coe a => + induction y with + | bot => exact 0 + | coe b => exact t.natTransTruncGEOfLE a b (by simpa using leOfHom f) + | top => exact 0 + | top => + induction y with + | bot => exact 0 + | coe b => exact 0 + | top => exact 𝟙 _ + map_id n := by induction n <;> simp + map_comp {x y z} f g := by + have f' := leOfHom f + have g' := leOfHom g + induction x <;> induction y <;> induction z <;> cat_disch + +@[simp] +lemma eTruncGE_obj_bot : + t.eTruncGE.obj ⊥ = 𝟭 _ := rfl + +@[simp] +lemma eTruncGE_obj_top : + t.eTruncGE.obj ⊤ = 0 := rfl + +@[simp] +lemma eTruncGE_obj_mk (n : ℤ) : t.eTruncGE.obj (EInt.mk n) = t.truncGE n := rfl + +instance (i : EInt) : (t.eTruncGE.obj i).Additive := by + induction i <;> constructor <;> cat_disch + +/-- The connecting homomorphism from `t.eTruncGE` to the +shift by `1` of `t.eTruncLT`. -/ +noncomputable def eTruncGEδLT : + t.eTruncGE ⟶ t.eTruncLT ⋙ ((Functor.whiskeringRight C C C).obj (shiftFunctor C (1 : ℤ))) where + app a := by + induction a with + | bot => exact 0 + | coe a => exact t.truncGEδLT a + | top => exact 0 + naturality {a b} hab := by + replace hab := leOfHom hab + induction a; rotate_right + · apply (isZero_zero _).eq_of_src + all_goals + induction b <;> simp at hab <;> + dsimp [eTruncGE, eTruncLT] <;> + simp [t.truncGEδLT_comp_whiskerRight_natTransTruncLTOfLE] + +@[simp] +lemma eTruncGEδLT_mk (n : ℤ) : + t.eTruncGEδLT.app (EInt.mk n) = t.truncGEδLT n := rfl + +/-- The natural transformation `t.eTruncLT.obj i ⟶ 𝟭 C` for all `i : EInt`. -/ +noncomputable abbrev eTruncLTι (i : EInt) : t.eTruncLT.obj i ⟶ 𝟭 _ := + t.eTruncLT.map (homOfLE (le_top)) + +@[simp] lemma eTruncLT_ι_bot : t.eTruncLTι ⊥ = 0 := rfl +@[simp] lemma eTruncLT_ι_coe (n : ℤ) : t.eTruncLTι n = t.truncLTι n := rfl +@[simp] lemma eTruncLT_ι_top : t.eTruncLTι ⊤ = 𝟙 _ := rfl + +@[reassoc] +lemma eTruncLTι_naturality (i : EInt) {X Y : C} (f : X ⟶ Y) : + (t.eTruncLT.obj i).map f ≫ (t.eTruncLTι i).app Y = (t.eTruncLTι i).app X ≫ f := + (t.eTruncLTι i).naturality f + +instance : IsIso (t.eTruncLTι ⊤) := by + dsimp [eTruncLTι] + infer_instance + +@[reassoc (attr := simp)] +lemma eTruncLT_map_app_eTruncLTι_app {i j : EInt} (f : i ⟶ j) (X : C) : + (t.eTruncLT.map f).app X ≫ (t.eTruncLTι j).app X = (t.eTruncLTι i).app X := by + simp only [← NatTrans.comp_app, ← Functor.map_comp] + rfl + +@[reassoc] +lemma eTruncLT_obj_map_eTruncLTι_app (i : EInt) (X : C) : + (t.eTruncLT.obj i).map ((t.eTruncLTι i).app X) = + (t.eTruncLTι i).app ((t.eTruncLT.obj i).obj X) := by + induction i with + | bot => simp + | coe n => simp [truncLT_map_truncLTι_app] + | top => simp + +/-- The natural transformation `𝟭 C ⟶ t.eTruncGE.obj i` for all `i : EInt`. -/ +noncomputable abbrev eTruncGEπ (i : EInt) : 𝟭 C ⟶ t.eTruncGE.obj i := + t.eTruncGE.map (homOfLE (bot_le)) + +@[simp] lemma eTruncGEπ_bot : t.eTruncGEπ ⊥ = 𝟙 _ := rfl +@[simp] lemma eTruncGEπ_coe (n : ℤ) : t.eTruncGEπ n = t.truncGEπ n := rfl +@[simp] lemma eTruncGEπ_top : t.eTruncGEπ ⊤ = 0 := rfl + +@[reassoc (attr := simp)] +lemma eTruncGEπ_naturality (i : EInt) {X Y : C} (f : X ⟶ Y) : + (t.eTruncGEπ i).app X ≫ (t.eTruncGE.obj i).map f = f ≫ (t.eTruncGEπ i).app Y := + ((t.eTruncGEπ i).naturality f).symm + +instance : IsIso (t.eTruncGEπ ⊥) := by + dsimp [eTruncGEπ] + infer_instance + +@[reassoc (attr := simp)] +lemma eTruncGEπ_app_eTruncGE_map_app {i j : EInt} (f : i ⟶ j) (X : C) : + (t.eTruncGEπ i).app X ≫ (t.eTruncGE.map f).app X = (t.eTruncGEπ j).app X := by + simp only [← NatTrans.comp_app, ← Functor.map_comp] + rfl + +@[reassoc] +lemma eTruncGE_obj_map_eTruncGEπ_app (i : EInt) (X : C) : + (t.eTruncGE.obj i).map ((t.eTruncGEπ i).app X) = + (t.eTruncGEπ i).app ((t.eTruncGE.obj i).obj X) := by + induction i with + | bot => simp + | coe n => simp [truncGE_map_truncGEπ_app] + | top => simp + +/-- The (distinguished) triangles given by the natural transformations +`t.eTruncLT.obj i ⟶ 𝟭 C ⟶ t.eTruncGE.obj i ⟶ ...` for all `i : EInt`. -/ +@[simps!] +noncomputable def eTriangleLTGE : EInt ⥤ C ⥤ Triangle C where + obj i := Triangle.functorMk (t.eTruncLTι i) (t.eTruncGEπ i) (t.eTruncGEδLT.app i) + map f := Triangle.functorHomMk _ _ (t.eTruncLT.map f) (𝟙 _) (t.eTruncGE.map f) + +lemma eTriangleLTGE_distinguished (i : EInt) (X : C) : + (t.eTriangleLTGE.obj i).obj X ∈ distTriang _ := by + induction i with + | bot => + rw [Triangle.distinguished_iff_of_isZero₁ _ (Functor.zero_obj X)] + dsimp + infer_instance + | coe n => exact t.triangleLTGE_distinguished n X + | top => + rw [Triangle.distinguished_iff_of_isZero₃ _ (Functor.zero_obj X)] + dsimp + infer_instance + +instance (X : C) (n : ℤ) [t.IsLE X n] (i : EInt) : + t.IsLE ((t.eTruncLT.obj i).obj X) n := by + induction i with + | bot => exact isLE_of_isZero _ (by simp) _ + | coe _ => dsimp; infer_instance + | top => dsimp; infer_instance + +instance (X : C) (n : ℤ) [t.IsGE X n] (i : EInt) : + t.IsGE ((t.eTruncGE.obj i).obj X) n := by + induction i with + | bot => dsimp; infer_instance + | coe _ => dsimp; infer_instance + | top => exact isGE_of_isZero _ (by simp) _ + +lemma isGE_eTruncGE_obj_obj (n : ℤ) (i : EInt) (h : EInt.mk n ≤ i) (X : C) : + t.IsGE ((t.eTruncGE.obj i).obj X) n := by + induction i with + | bot => simp at h + | coe i => + dsimp + exact t.isGE_of_GE _ _ _ (by simpa using h) + | top => exact t.isGE_of_isZero (Functor.zero_obj _) _ + +lemma isLE_eTruncLT_obj_obj (n : ℤ) (i : EInt) (h : i ≤ EInt.mk (n + 1)) (X : C) : + t.IsLE (((t.eTruncLT.obj i)).obj X) n := by + induction i with + | bot => exact t.isLE_of_isZero (by simp) _ + | coe i => + simp only [EInt.coe_le_coe_iff] at h + dsimp + exact t.isLE_of_LE _ (i - 1) n (by lia) + | top => simp at h + +lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j ≤ EInt.mk n) : + IsZero ((t.eTruncLT.obj j).obj X) := by + induction j with + | bot => simp + | coe j => + have := t.isGE_of_GE X j n (by simpa using hj) + exact t.isZero_truncLT_obj_of_isGE _ _ + | top => simp at hj + +lemma isZero_eTruncGE_obj_obj (X : C) (n : ℤ) [t.IsLE X n] (j : EInt) (hj : EInt.mk n < j) : + IsZero ((t.eTruncGE.obj j).obj X) := by + induction j with + | bot => simp at hj + | coe j => + simp only [EInt.coe_lt_coe_iff] at hj + have := t.isLE_of_LE X n (j - 1) (by lia) + exact t.isZero_truncGE_obj_of_isLE (j - 1) j (by lia) _ + | top => simp + +section + +variable [IsTriangulated C] + +lemma isIso_eTruncGE_obj_map_truncGEπ_app (a b : EInt) (h : a ≤ b) (X : C) : + IsIso ((t.eTruncGE.obj b).map ((t.eTruncGEπ a).app X)) := by + induction b with + | bot => + obtain rfl : a = ⊥ := by simpa using h + infer_instance + | coe b => + induction a with + | bot => dsimp; infer_instance + | coe a => exact t.isIso_truncGE_map_truncGEπ_app b a (by simpa using h) X + | top => simp at h + | top => exact ⟨0, IsZero.eq_of_src (by simp) _ _, IsZero.eq_of_src (by simp) _ _⟩ + +lemma isIso_eTruncLT_obj_map_truncLTπ_app (a b : EInt) (h : a ≤ b) (X : C) : + IsIso ((t.eTruncLT.obj a).map ((t.eTruncLTι b).app X)) := by + induction a with + | bot => exact ⟨0, IsZero.eq_of_src (by simp) _ _, IsZero.eq_of_src (by simp) _ _⟩ + | coe a => + induction b with + | bot => simp at h + | coe b => + exact t.isIso_truncLT_map_truncLTι_app a b (by simpa using h) X + | top => dsimp; infer_instance + | top => + obtain rfl : b = ⊤ := by simpa using h + infer_instance + +instance (a : EInt) (X : C) : IsIso ((t.eTruncLT.obj a).map ((t.eTruncLTι a).app X)) := + isIso_eTruncLT_obj_map_truncLTπ_app t a a (by rfl) X + +instance (a : EInt) (X : C) : IsIso ((t.eTruncLTι a).app ((t.eTruncLT.obj a).obj X)) := by + rw [← eTruncLT_obj_map_eTruncLTι_app] + infer_instance + +instance (X : C) (n : ℤ) [t.IsGE X n] (i : EInt) : + t.IsGE ((t.eTruncLT.obj i).obj X) n := by + induction i with + | bot => exact isGE_of_isZero _ (by simp) _ + | coe _ => dsimp; infer_instance + | top => dsimp; infer_instance + +instance (X : C) (n : ℤ) [t.IsLE X n] (i : EInt) : + t.IsLE ((t.eTruncGE.obj i).obj X) n := by + induction i with + | bot => dsimp; infer_instance + | coe _ => dsimp; infer_instance + | top => exact isLE_of_isZero _ (by simp) _ + +/-- The natural transformation `t.eTruncGE.obj b ⟶ t.eTruncGE.obj a ⋙ t.eTruncGE.obj b` +for all `a` and `b` in `EInt`. -/ +@[simps!] +noncomputable def eTruncGEToGEGE (a b : EInt) : + t.eTruncGE.obj b ⟶ t.eTruncGE.obj a ⋙ t.eTruncGE.obj b := + (Functor.leftUnitor _).inv ≫ Functor.whiskerRight (t.eTruncGEπ a) _ + +lemma isIso_eTruncGEIsoGEGE (a b : EInt) (hab : a ≤ b) : + IsIso (t.eTruncGEToGEGE a b) := by + rw [NatTrans.isIso_iff_isIso_app] + intro X + simp only [Functor.comp_obj, eTruncGEToGEGE_app] + exact t.isIso_eTruncGE_obj_map_truncGEπ_app _ _ hab _ + +section + +variable (a b : EInt) (hab : a ≤ b) + +/-- The natural isomorphism `t.eTruncGE.obj b ≅ t.eTruncGE.obj a ⋙ t.eTruncGE.obj b` +when `a` and `b` in `EInt` satisfy `a ≤ b`. -/ +@[simps! hom] +noncomputable def eTruncGEIsoGEGE : + t.eTruncGE.obj b ≅ t.eTruncGE.obj a ⋙ t.eTruncGE.obj b := + haveI := t.isIso_eTruncGEIsoGEGE a b hab + asIso (t.eTruncGEToGEGE a b) + +@[reassoc (attr := simp)] +lemma eTruncGEIsoGEGE_hom_inv_id_app (X : C) : + (t.eTruncGE.obj b).map ((t.eTruncGEπ a).app X) ≫ (t.eTruncGEIsoGEGE a b hab).inv.app X = + 𝟙 _ := by + simpa using (t.eTruncGEIsoGEGE a b hab).hom_inv_id_app X + +@[reassoc (attr := simp)] +lemma eTruncGEIsoGEGE_inv_hom_id_app (X : C) : + (t.eTruncGEIsoGEGE a b hab).inv.app X ≫ (t.eTruncGE.obj b).map ((t.eTruncGEπ a).app X) = + 𝟙 _ := by + simpa using (t.eTruncGEIsoGEGE a b hab).inv_hom_id_app X + +end + +/-- The natural transformation `t.eTruncLT.obj a ⋙ t.eTruncLT.obj b ⟶ t.eTruncLT.obj b` +for all `a` and `b` in `EInt`. -/ +@[simps!] +noncomputable def eTruncLTLTToLT (a b : EInt) : + t.eTruncLT.obj a ⋙ t.eTruncLT.obj b ⟶ t.eTruncLT.obj b := + Functor.whiskerRight (t.eTruncLTι a) _ ≫ (Functor.leftUnitor _).hom + +lemma isIso_eTruncLTLTIsoLT (a b : EInt) (hab : b ≤ a) : + IsIso (t.eTruncLTLTToLT a b) := by + rw [NatTrans.isIso_iff_isIso_app] + intro X + simp only [Functor.comp_obj, eTruncLTLTToLT_app] + exact t.isIso_eTruncLT_obj_map_truncLTπ_app _ _ hab _ + +section + +variable (a b : EInt) (hab : b ≤ a) + +/-- The natural isomorphism `t.eTruncLT.obj a ⋙ t.eTruncLT.obj b ⟶ t.eTruncLT.obj b` +when `a` and `b` in `EInt` satisfy `b ≤ a`. -/ +@[simps! hom] +noncomputable def eTruncLTLTIsoLT : + t.eTruncLT.obj a ⋙ t.eTruncLT.obj b ≅ t.eTruncLT.obj b := + haveI := t.isIso_eTruncLTLTIsoLT a b hab + asIso (t.eTruncLTLTToLT a b) + +@[reassoc] +lemma eTruncLTLTIsoLT_hom_inv_id_app (X : C) : + (t.eTruncLT.obj b).map ((t.eTruncLTι a).app X) ≫ + (t.eTruncLTLTIsoLT a b hab).inv.app X = 𝟙 _ := by + simpa using (t.eTruncLTLTIsoLT a b hab).hom_inv_id_app X + +@[reassoc (attr := simp)] +lemma eTruncLTLTIsoLT_inv_hom_id_app (X : C) : + (t.eTruncLTLTIsoLT a b hab).inv.app X ≫ + (t.eTruncLT.obj b).map ((t.eTruncLTι a).app X) = 𝟙 _ := by + simpa using (t.eTruncLTLTIsoLT a b hab).inv_hom_id_app X + +@[reassoc (attr := simp)] +lemma eTruncLTLTIsoLT_inv_hom_id_app_eTruncLT_obj (X : C) : + (t.eTruncLTLTIsoLT a b hab).inv.app ((t.eTruncLT.obj a).obj X) ≫ + (t.eTruncLT.obj b).map ((t.eTruncLT.obj a).map ((t.eTruncLTι a).app X)) = 𝟙 _ := by + simp [eTruncLT_obj_map_eTruncLTι_app] + +end + + +section + +variable (a b : EInt) + +/-- The natural transformation from +`t.eTruncLT.obj b ⋙ t.eTruncGE.obj a ⋙ t.eTruncLT.obj b` to +`t.eTruncGE.obj a ⋙ t.eTruncLT.obj b`. (This is an isomorphism.) -/ +@[simps!] +noncomputable def eTruncLTGELTSelfToLTGE : + t.eTruncLT.obj b ⋙ t.eTruncGE.obj a ⋙ t.eTruncLT.obj b ⟶ + t.eTruncGE.obj a ⋙ t.eTruncLT.obj b := + Functor.whiskerRight (t.eTruncLTι b) _ ≫ (Functor.leftUnitor _).hom + +/-- The natural transformation from +`t.eTruncLT.obj b ⋙ t.eTruncGE.obj a ⋙ t.eTruncLT.obj b` to +`t.eTruncLT.obj b ⋙ t.eTruncGE.obj a`. (This is an isomorphism.) -/ +@[simps!] +noncomputable def eTruncLTGELTSelfToGELT : + t.eTruncLT.obj b ⋙ t.eTruncGE.obj a ⋙ t.eTruncLT.obj b ⟶ + t.eTruncLT.obj b ⋙ t.eTruncGE.obj a := + (Functor.associator _ _ _).inv ≫ Functor.whiskerLeft _ (t.eTruncLTι b) ≫ + (Functor.rightUnitor _).hom + +instance : IsIso (t.eTruncLTGELTSelfToLTGE a b) := by + rw [NatTrans.isIso_iff_isIso_app] + intro X + induction b with + | bot => simp [isIsoZero_iff_source_target_isZero] + | coe b => + induction a with + | bot => simpa using inferInstanceAs (IsIso ((t.truncLT b).map ((t.truncLTι b).app X))) + | coe a => + simp only [eTruncLT_obj_mk, eTruncGE_obj_mk, Functor.comp_obj, eTruncLTGELTSelfToLTGE_app, + eTruncLT_map_eq_truncLTι] + infer_instance + | top => + simp only [eTruncLT_obj_mk, eTruncGE_obj_top, Functor.comp_obj, eTruncLTGELTSelfToLTGE_app, + eTruncLT_map_eq_truncLTι, zero_map, Functor.map_zero, isIsoZero_iff_source_target_isZero] + constructor + all_goals exact Functor.map_isZero _ (Functor.zero_obj _) + | top => simpa using inferInstanceAs (IsIso (𝟙 _)) + +variable (b : EInt) (X : C) + +instance : IsIso (t.eTruncLTGELTSelfToGELT a b) := by + rw [NatTrans.isIso_iff_isIso_app] + intro X + induction a with + | bot => simpa using inferInstanceAs (IsIso ((t.eTruncLTι b).app ((t.eTruncLT.obj b).obj X))) + | coe a => + induction b with + | bot => simpa [isIsoZero_iff_source_target_isZero] using + (t.eTruncGE.obj a).map_isZero (Functor.zero_obj _) + | coe b => + simp only [eTruncLT_obj_mk, eTruncGE_obj_mk, Functor.comp_obj, eTruncLTGELTSelfToGELT_app, + eTruncLT_map_eq_truncLTι] + infer_instance + | top => simpa using inferInstanceAs (IsIso (𝟙 _)) + | top => + exact ⟨0, ((t.eTruncLT.obj b).map_isZero (by simp)).eq_of_src _ _, + IsZero.eq_of_src (by simp) _ _⟩ + +end + +/-- The commutation natural isomorphism +`t.eTruncGE.obj a ⋙ t.eTruncLT.obj b ≅ t.eTruncLT.obj b ⋙ t.eTruncGE.obj a` +for all `a` and `b` in `EInt`. -/ +noncomputable def eTruncLTGEIsoLEGT (a b : EInt) : + t.eTruncGE.obj a ⋙ t.eTruncLT.obj b ≅ t.eTruncLT.obj b ⋙ t.eTruncGE.obj a := + (asIso (t.eTruncLTGELTSelfToLTGE a b)).symm ≪≫ asIso (t.eTruncLTGELTSelfToGELT a b) + +@[reassoc (attr := simp)] +lemma eTruncLTGEIsoLEGT_hom_naturality (a b : EInt) {X Y : C} (f : X ⟶ Y) : + (t.eTruncLT.obj b).map ((t.eTruncGE.obj a).map f) ≫ (t.eTruncLTGEIsoLEGT a b).hom.app Y = + (t.eTruncLTGEIsoLEGT a b).hom.app X ≫ (t.eTruncGE.obj a).map ((t.eTruncLT.obj b).map f) := + (t.eTruncLTGEIsoLEGT a b).hom.naturality f + +@[reassoc] +lemma eTruncLTGEIsoLEGT_hom_app_fac (a b : EInt) (X : C) : + (t.eTruncLT.obj b).map ((t.eTruncGE.obj a).map ((t.eTruncLTι b).app X)) ≫ + (t.eTruncLTGEIsoLEGT a b).hom.app X = + (t.eTruncLTι b).app ((t.eTruncGE.obj a).obj ((t.eTruncLT.obj b).obj X)):= by + simp [eTruncLTGEIsoLEGT] + +@[reassoc (attr := simp)] +lemma eTruncLTGEIsoLEGT_hom_app_fac' (a b : EInt) (X : C) : + (t.eTruncLTGEIsoLEGT a b).hom.app X ≫ (t.eTruncGE.obj a).map ((t.eTruncLTι b).app X) = + (t.eTruncLTι b).app ((t.eTruncGE.obj a).obj X) := by + simp [eTruncLTGEIsoLEGT] + +open ComposableArrows in +@[reassoc] +lemma eTruncLTGEIsoLEGT_naturality_app (a b : EInt) (hab : a ≤ b) + (a' b' : EInt) (hab' : a' ≤ b') (φ : mk₁ (homOfLE hab) ⟶ mk₁ (homOfLE hab')) (X : C) : + (t.eTruncLT.map (φ.app 1)).app ((t.eTruncGE.obj a).obj X) ≫ + (t.eTruncLT.obj b').map ((t.eTruncGE.map (φ.app 0)).app X) ≫ + (t.eTruncLTGEIsoLEGT a' b').hom.app X = + (t.eTruncLTGEIsoLEGT a b).hom.app X ≫ (t.eTruncGE.map (φ.app 0)).app _ ≫ + (t.eTruncGE.obj a').map ((t.eTruncLT.map (φ.app 1)).app X) := by + rw [← cancel_epi ((t.eTruncLTGELTSelfToLTGE a b).app X)] + dsimp + rw [eTruncLTGELTSelfToLTGE_app, eTruncLTGEIsoLEGT_hom_app_fac_assoc, + NatTrans.naturality_assoc, ← Functor.map_comp_assoc, NatTrans.naturality, + Functor.map_comp_assoc, ← t.eTruncLT_map_app_eTruncLTι_app (φ.app 1) X, + Functor.map_comp, Functor.map_comp, Category.assoc, + t.eTruncLTGEIsoLEGT_hom_app_fac] + simp + +end + +end TStructure + +end Triangulated + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean new file mode 100644 index 00000000000000..ec8f11d310a847 --- /dev/null +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean @@ -0,0 +1,148 @@ +/- +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.Shift +public import Mathlib.CategoryTheory.Triangulated.Subcategory +public import Mathlib.CategoryTheory.Triangulated.TStructure.TruncLEGT + +/-! +# Induced t-structures + +Let `t` be a t-structure on a pretriangulated cateogry `C`. +If `P` is a triangulated subcategory of `C`, we introduce a typeclass +`P.HasInducedTStructure t` which essentially says that up to isomorphisms +`P` is stable by the application of the truncation functors. + +In particular, we show that the triangulated subcategory `t.plus` +of `t`-bounded above objects can be endowed with a t-structure `t.onPlus`, +and the same applis to `t.minus` and `t.bounded`. + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Limits Pretriangulated Triangulated + +variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] + [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] + (P : ObjectProperty C) (t : TStructure C) + +namespace ObjectProperty + +/-- The property that a full subcategory of a pretriangulated category +equipped with a t-structure can be endowed with an induced t-structure. -/ +class HasInducedTStructure [P.IsTriangulated] : Prop where + exists_triangle_zero_one (A : C) (hA : P A) : + ∃ (X Y : C) (_ : t.IsLE X 0) (_ : t.IsGE Y 1) + (f : X ⟶ A) (g : A ⟶ Y) (h : Y ⟶ X⟦(1 : ℤ)⟧) (_ : Triangle.mk f g h ∈ distTriang C), + P.isoClosure X ∧ P.isoClosure Y + +variable [P.IsTriangulated] [h : P.HasInducedTStructure t] + +/-- The t-structure induced on a full subcategory. -/ +noncomputable def tStructure : TStructure P.FullSubcategory where + le n X := t.le n X.obj + ge n X := t.ge n X.obj + le_isClosedUnderIsomorphisms n := ⟨fun {X Y} e hX ↦ (t.le n).prop_of_iso (P.ι.mapIso e) hX⟩ + ge_isClosedUnderIsomorphisms n := ⟨fun {X Y} e hX ↦ (t.ge n).prop_of_iso (P.ι.mapIso e) hX⟩ + le_shift n a n' h X hX := (t.le n').prop_of_iso ((P.ι.commShiftIso a).symm.app X) + (t.le_shift n a n' h X.obj hX) + ge_shift n a n' h X hX := (t.ge n').prop_of_iso ((P.ι.commShiftIso a).symm.app X) + (t.ge_shift n a n' h X.obj hX) + zero' {X Y} f hX hY := P.ι.map_injective (by + rw [Functor.map_zero] + exact t.zero' (P.ι.map f) hX hY) + le_zero_le X hX := t.le_zero_le _ hX + ge_one_le X hX := t.ge_one_le _ hX + exists_triangle_zero_one A := by + obtain ⟨X, Y, hX, hY, f, g, h, hT, ⟨X', hX', ⟨e⟩⟩, ⟨Y', hY', ⟨e'⟩⟩⟩ := + h.exists_triangle_zero_one A.1 A.2 + exact ⟨⟨X', hX'⟩, ⟨Y', hY'⟩, (t.le 0).prop_of_iso e hX.le, + (t.ge 1).prop_of_iso e' hY.ge, + P.fullyFaithfulι.preimage (e.inv ≫ f), + P.fullyFaithfulι.preimage (g ≫ e'.hom), + P.fullyFaithfulι.preimage (e'.inv ≫ h ≫ e.hom⟦(1 : ℤ)⟧' ≫ + (P.ι.commShiftIso (1 : ℤ)).inv.app ⟨X', hX'⟩), + isomorphic_distinguished _ hT _ (Triangle.isoMk _ _ e.symm (Iso.refl _) e'.symm)⟩ + +lemma tStructure_isLE_iff (X : P.FullSubcategory) (n : ℤ) : + (P.tStructure t).IsLE X n ↔ t.IsLE X.obj n := + ⟨fun h => ⟨h.1⟩, fun h => ⟨h.1⟩⟩ + +lemma tStructure_isGE_iff (X : P.FullSubcategory) (n : ℤ) : + (P.tStructure t).IsGE X n ↔ t.IsGE X.obj n := + ⟨fun h => ⟨h.1⟩, fun h => ⟨h.1⟩⟩ + +/-- Constructor for `HasInducedTStructure`. -/ +lemma HasInducedTStructure.mk' {P : ObjectProperty C} [P.IsTriangulated] {t : TStructure C} + (h : ∀ (X : C) (_ : P X) (n : ℤ), P ((t.truncLE n).obj X) ∧ P ((t.truncGE n).obj X)) : + P.HasInducedTStructure t where + exists_triangle_zero_one X hX := + ⟨_, _, inferInstance, inferInstance, _, _, _, + t.triangleLEGE_distinguished 0 1 (by lia) X, + P.le_isoClosure _ ((h X hX _).1), P.le_isoClosure _ ((h X hX _).2)⟩ + +lemma mem_of_hasInductedTStructure (P : ObjectProperty C) [P.IsTriangulated] (t : TStructure C) + [P.IsClosedUnderIsomorphisms] [P.HasInducedTStructure t] + (T : Triangle C) (hT : T ∈ distTriang C) + (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (h₁ : t.IsLE T.obj₁ n₀) (h₂ : P T.obj₂) + (h₃ : t.IsGE T.obj₃ n₁) : + P T.obj₁ ∧ P T.obj₃ := by + obtain ⟨e, _⟩ := t.triangle_iso_exists hT + (P.ι.map_distinguished _ ((P.tStructure t).triangleLEGE_distinguished n₀ n₁ h ⟨_, h₂⟩)) + (Iso.refl _) n₀ n₁ inferInstance inferInstance + (by dsimp; rw [← P.tStructure_isLE_iff]; infer_instance) + (by dsimp; rw [← P.tStructure_isGE_iff]; infer_instance) + exact ⟨(P.prop_iff_of_iso (Triangle.π₁.mapIso e)).2 (P.prop_ι_obj _), + (P.prop_iff_of_iso (Triangle.π₃.mapIso e)).2 (P.prop_ι_obj _)⟩ + +instance (P P' : ObjectProperty C) [P.IsTriangulated] [P'.IsTriangulated] (t : TStructure C) + [P.HasInducedTStructure t] [P'.HasInducedTStructure t] + [P.IsClosedUnderIsomorphisms] [P'.IsClosedUnderIsomorphisms] : + (P ⊓ P').HasInducedTStructure t := + .mk' (by + rintro X ⟨hX, hX'⟩ n + exact + ⟨⟨(P.mem_of_hasInductedTStructure t _ (t.triangleLEGE_distinguished n _ rfl X) n _ rfl + (by dsimp; infer_instance) hX (by dsimp; infer_instance)).1, + (P'.mem_of_hasInductedTStructure t _ (t.triangleLEGE_distinguished n _ rfl X) n _ rfl + (by dsimp; infer_instance) hX' (by dsimp; infer_instance)).1⟩, + ⟨(P.mem_of_hasInductedTStructure t _ (t.triangleLEGE_distinguished (n - 1) n (by lia) X) + (n - 1) n (by lia) (by dsimp; infer_instance) hX (by dsimp; infer_instance)).2, + (P'.mem_of_hasInductedTStructure t _ (t.triangleLEGE_distinguished (n - 1) n (by lia) X) + (n - 1) n (by lia) (by dsimp; infer_instance) hX' (by dsimp; infer_instance)).2⟩⟩) + +end ObjectProperty + +namespace Triangulated.TStructure + +variable [IsTriangulated C] + +instance : t.plus.HasInducedTStructure t := + .mk' (by rintro X ⟨a, _⟩ n; exact ⟨⟨a, inferInstance⟩, ⟨a, inferInstance⟩⟩) + +instance : t.minus.HasInducedTStructure t := + .mk' (by rintro X ⟨a, _⟩ n; exact ⟨⟨a, inferInstance⟩, ⟨a, inferInstance⟩⟩) + +instance : t.bounded.HasInducedTStructure t := by + dsimp [bounded] + infer_instance + +/-- The t-structure induced on the full subcategory of `t`-bounded above objects. -/ +noncomputable abbrev onPlus : TStructure t.plus.FullSubcategory := t.plus.tStructure t + +/-- The t-structure induced on the full subcategory of `t`-bounded below objects. -/ +noncomputable abbrev onMinus : TStructure t.minus.FullSubcategory := t.minus.tStructure t + +/-- The t-structure induced on the full subcategory of `t`-bounded objects. -/ +noncomputable abbrev onBounded : TStructure t.bounded.FullSubcategory := t.bounded.tStructure t + +end Triangulated.TStructure + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean new file mode 100644 index 00000000000000..c041877fba77be --- /dev/null +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean @@ -0,0 +1,177 @@ +/- +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.Triangulated.SpectralObject +public import Mathlib.CategoryTheory.Triangulated.TStructure.ETrunc + +/-! +# Spectral objects attached t-structures + +Let `C` be a triangulated category equipped with a t-structure `t`. +We define a functor `t.ω₁ : ComposableArrows EInt 1 ⥤ C ⥤ C` which sends +a map `a ⟶ b` in `EInt` (i.e. `a ≤ b`) to the functor +`t.eTruncLT.obj b ⋙ t.eTruncGE.obj a`. (Roughly speaking, we "keep" the +`t`-homology only in degree `n` such that `a ≤ n < b`.) +When we have two composable morphisms `f : a ⟶ b` and `g : b ⟶ c` in `EInt`, +we define a connecting homomorphism +`ω₁δ : t.ω₁.obj (mk₁ g) ⟶ t.ω₁.obj (mk₁ f) ⋙ shiftFunctor C (1 : ℤ)`, and +this gives distinguished triangles that are functorial both in `X : C` +and `a ⟶ b ⟶ c` in `ComposableArrows EInt 2`. + +In other words, for each `X : C`, we define a spectral +object `t.spectralObject X : SpectralObject C EInt` in the +triangulated category `C`, and this extends to a functor +`t.spectralObjectFunctor : C ⥤ SpectralObject C EInt`. + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Limits Pretriangulated ZeroObject Preadditive ComposableArrows + +variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] + [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] + +namespace Triangulated + +namespace TStructure + +variable (t : TStructure C) [IsTriangulated C] + +/-- Given a t-structure `t` on a triangulated category `C`, this is the functor +`ComposableArrows EInt 1 ⥤ C ⥤ C` which sends an arrows `a ⟶ b` in `EInt` +to the functor `t.eTruncLT.obj b ⋙ t.eTruncGE.obj a`. -/ +@[simps] +noncomputable def ω₁ : ComposableArrows EInt 1 ⥤ C ⥤ C where + obj D := t.eTruncLT.obj (D.obj 1) ⋙ t.eTruncGE.obj (D.obj 0) + map φ := t.eTruncLT.map (φ.app 1) ◫ t.eTruncGE.map (φ.app 0) + +section + +variable (a b c : EInt) (hab : a ≤ b) (hbc : b ≤ c) + +open Functor in +/-- The connecting homomorphism (as a natural transformation) for the spectral +objects attached to the objects of a triangulated equipped with a t-structure. -/ +@[simps!] +noncomputable def ω₁δ : + t.ω₁.obj (mk₁ (homOfLE hbc)) ⟶ t.ω₁.obj (mk₁ (homOfLE hab)) ⋙ shiftFunctor C (1 : ℤ) := + whiskerLeft _ (t.eTruncGEToGEGE a b) ≫ (associator _ _ _).inv ≫ + (t.ω₁.obj (mk₁ (homOfLE (hab.trans hbc)))).whiskerLeft (t.eTruncGEδLT.app b) ≫ + (associator _ _ _).inv ≫ + whiskerRight + ((associator _ _ _).hom ≫ whiskerLeft _ (t.eTruncLTGEIsoLEGT a b).hom ≫ + (associator _ _ _).inv ≫ whiskerRight (t.eTruncLTLTToLT c b) _) _ + +@[reassoc] +lemma ω₁δ_naturality (a' b' c' : EInt) (hab' : a' ≤ b') (hbc' : b' ≤ c') + (φ : mk₂ (homOfLE hab) (homOfLE hbc) ⟶ mk₂ (homOfLE hab') (homOfLE hbc')) : + t.ω₁.map (homMk₁ (φ.app 1) (φ.app 2)) ≫ t.ω₁δ a' b' c' hab' hbc' = + t.ω₁δ a b c hab hbc ≫ Functor.whiskerRight (t.ω₁.map (homMk₁ (φ.app 0) (φ.app 1))) _ := by + ext X + simp only [ω₁_obj, mk₁_obj, Mk₁.obj, Functor.comp_obj, ω₁_map, homMk₁_app, + NatTrans.comp_app, NatTrans.hcomp_app, ω₁δ_app, + ← Functor.map_comp, Category.assoc, NatTrans.naturality_assoc, Functor.comp_map, + ← Functor.map_comp_assoc, NatTrans.naturality_app_assoc, Functor.whiskeringRight_obj_obj, + Functor.whiskeringRight_obj_map, Functor.whiskerRight_app, NatTrans.naturality] + congr 2 + have h₁ := t.eTruncLTGEIsoLEGT_naturality_app a b hab a' b' hab' (homMk₁ (φ.app 0) (φ.app 1)) + dsimp at h₁ + simp only [Functor.map_comp, Category.assoc] + rw [← reassoc_of% h₁, ← eTruncLTGEIsoLEGT_hom_naturality, ← eTruncLTGEIsoLEGT_hom_naturality, + ← t.eTruncLT_map_app_eTruncLTι_app (φ.app 2) X, NatTrans.naturality_assoc, + ← Functor.map_comp_assoc, ← Functor.map_comp_assoc, + ← Functor.map_comp_assoc, ← Functor.map_comp_assoc] + simp only [homOfLE_leOfHom, Fin.isValue, Category.assoc, eTruncGEπ_naturality, + eTruncLT_map_app_eTruncLTι_app_assoc, Functor.map_comp, eTruncGEπ_app_eTruncGE_map_app, + eTruncLT_map_app_eTruncLTι_app] + +/-- The functorial (distinguished) triangles that are part of the spectral +object attached to objects in a triangulated category equipped with a t-structure. -/ +@[simps!] +noncomputable def triangleω₁δ : C ⥤ Triangle C := + Triangle.functorMk (t.ω₁.map (twoδ₂Toδ₁' a b c hab hbc)) + (t.ω₁.map (twoδ₁Toδ₀' a b c hab hbc)) (t.ω₁δ a b c hab hbc) + +/-- The triangle `(t.triangleω₁δ a b c hab hbc).obj X` is isomorphic to +the (distinguished) triangle obtained by applying the functor `t.eTriangleLTGE.obj b` +to the object `(t.eTruncGE.obj a).obj ((t.eTruncLT.obj c).obj X)`. -/ +noncomputable def triangleω₁δObjIso (X : C) : + (t.triangleω₁δ a b c hab hbc).obj X ≅ + (t.eTriangleLTGE.obj b).obj ((t.ω₁.obj (mk₁ (homOfLE (hab.trans hbc)))).obj X) := by + refine Triangle.isoMk _ _ + ((t.eTruncGE.obj a).mapIso ((t.eTruncLTLTIsoLT c b hbc).symm.app X) ≪≫ + (t.eTruncLTGEIsoLEGT a b).symm.app _) + (Iso.refl _) ((t.eTruncGEIsoGEGE a b hab).app _) ?_ ?_ ?_ + · dsimp + simp only [triangleω₁δ_obj_mor₁, homOfLE_leOfHom, Category.comp_id, Category.assoc] + rw [← cancel_epi ((t.eTruncGE.obj a).map ((t.eTruncLTLTIsoLT c b hbc).hom.app X)), + ← Functor.map_comp_assoc, Iso.hom_inv_id_app, Functor.map_id, Category.id_comp, + ← cancel_epi ((t.eTruncLTGEIsoLEGT a b).hom.app ((t.eTruncLT.obj c).obj X)), + Iso.hom_inv_id_app_assoc, eTruncLTLTIsoLT_hom, eTruncLTLTToLT_app, + ← Functor.map_comp] + -- this should be cleanup and made a separate lemma + have : ((t.eTruncLT.obj b).map ((t.eTruncLTι c).app X) ≫ + (t.eTruncLT.map (homOfLE hbc)).app X) = (t.eTruncLTι _).app _ := by + dsimp [eTruncLTι] + rw [← homOfLE_comp hbc le_top, Functor.map_comp, NatTrans.comp_app, + NatTrans.naturality] + congr 1 + induction c with + | bot => simp + | coe c => simp [truncLT_map_truncLTι_app] + | top => simp + simp [this] + · dsimp + simp only [triangleω₁δ_obj_mor₂, eTruncGEToGEGE_app, Category.id_comp, + ← t.eTruncGEπ_app_eTruncGE_map_app (homOfLE hab), ← NatTrans.naturality, + eTruncGE_obj_map_eTruncGEπ_app] + · simp [← Functor.map_comp_assoc, ← Functor.map_comp] + +lemma triangleω₁δ_distinguished (X : C) : + (t.triangleω₁δ a b c hab hbc).obj X ∈ distTriang _ := + isomorphic_distinguished _ (t.eTriangleLTGE_distinguished b _) _ + (t.triangleω₁δObjIso a b c hab hbc X) + +end + +/-- The spectral object attached to an object `X : C` in a category +equipped with a t-structure. It consists of all truncations of `X`. -/ +@[simps ω₁] +noncomputable def spectralObject (X : C) : SpectralObject C EInt where + ω₁ := t.ω₁ ⋙ (evaluation _ _).obj X + δ'.app D := (t.ω₁δ (D.obj 0) (D.obj 1) (D.obj 2) + (leOfHom (D.map' 0 1)) (leOfHom (D.map' 1 2))).app X + δ'.naturality {D D'} φ := by + obtain ⟨a, b, c, f, g, rfl⟩ := mk₂_surjective D + obtain ⟨a', b', c', f', g', rfl⟩ := mk₂_surjective D' + exact NatTrans.congr_app (t.ω₁δ_naturality a b c (leOfHom f) (leOfHom g) + a' b' c' (leOfHom f') (leOfHom g') φ) X + distinguished' D := by + obtain ⟨a, b, c, f, g, rfl⟩ := mk₂_surjective D + exact t.triangleω₁δ_distinguished a b c (leOfHom f) (leOfHom g) X + +@[simp] +lemma spectralObject_δ (X : C) {a b c : EInt} (f : a ⟶ b) (g : b ⟶ c) : + (t.spectralObject X).δ f g = (t.ω₁δ a b c (leOfHom f) (leOfHom g)).app X := rfl + +/-- The spectral object attached to an object `X : C` in a category +equipped with a t-structure, as a functor `C ⥤ SpectralObject C EInt`. -/ +@[simps] +noncomputable def spectralObjectFunctor : C ⥤ SpectralObject C EInt where + obj := t.spectralObject + map φ := + { hom := Functor.whiskerLeft _ ((evaluation _ _).map φ) + comm f g := ((t.ω₁δ _ _ _ (leOfHom f) (leOfHom g)).naturality φ).symm } + +end TStructure + +end Triangulated + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean new file mode 100644 index 00000000000000..25beaa581aa3a1 --- /dev/null +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean @@ -0,0 +1,396 @@ +/- +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.Triangulated.TStructure.TruncLTGE + +/-! +# Truncations for a t-structure + +Let `t` be a t-structure on a (pre)triangulated category `C`. +In this file, for any `n : ℤ`, we introduce the truncation functors +`t.truncLE n : C ⥤ C` and `t.truncGT n : C ⥤ C`, as variants of the functors +`t.truncLT n : C ⥤ C` and `t.truncGE n : C ⥤ C` introduced in the file +`Mathlib/CategoryTheory/Triangulated/TStucture/TruncLTGE.lean`. + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Limits Pretriangulated + +variable {C : Type*} [Category* C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] + [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] + +namespace Triangulated + +namespace TStructure + +variable (t : TStructure C) + +/-- Given a t-structure `t` on a pretriangulated category `C` and `n : ℤ`, this +is the `≤ n`-truncation functor. See also the natural transformation `truncLEι`. -/ +noncomputable def truncLE (n : ℤ) : C ⥤ C := t.truncLT (n + 1) + +instance (n : ℤ) : (t.truncLE n).Additive := by + dsimp only [truncLE] + infer_instance + +lemma isLE_truncLE_obj (X : C) (a b : ℤ) (hn : a ≤ b := by lia) : + t.IsLE ((t.truncLE a).obj X) b := + t.isLE_truncLT_obj .. + +instance (n : ℤ) (X : C) : t.IsLE ((t.truncLE n).obj X) n := + t.isLE_truncLE_obj .. + +/-- Given a t-structure `t` on a pretriangulated category `C` and `n : ℤ`, this +is the `> n`-truncation functor. See also the natural transformation `truncGTπ`. -/ +noncomputable def truncGT (n : ℤ) : C ⥤ C := t.truncGE (n + 1) + +instance (n : ℤ) : (t.truncGT n).Additive := by + dsimp only [truncGT] + infer_instance + +lemma isGE_truncGT_obj (X : C) (a b : ℤ) (hn : b ≤ a + 1 := by lia) : + t.IsGE ((t.truncGT a).obj X) b := + t.isGE_truncGE_obj .. + +instance (n : ℤ) (X : C) : t.IsGE ((t.truncGT n).obj X) (n + 1) := + t.isGE_truncGT_obj .. + +instance (n : ℤ) (X : C) : t.IsGE ((t.truncGT (n - 1)).obj X) n := + t.isGE_truncGT_obj .. + +/-- The isomorphism `t.truncLE a ≅ t.truncLT b` when `a + 1 = b`. -/ +noncomputable def truncLEIsoTruncLT (a b : ℤ) (h : a + 1 = b) : + t.truncLE a ≅ t.truncLT b := + eqToIso (by rw [← h]; rfl) + +/-- The isomorphism `t.truncGT a ≅ t.truncGE b` when `a + 1 = b`. -/ +noncomputable def truncGTIsoTruncGE (a b : ℤ) (h : a + 1 = b) : + t.truncGT a ≅ t.truncGE b := + eqToIso (by rw [← h]; rfl) + +/-- The natural transformation `t.truncLE n ⟶ 𝟭 C` when `t` is a t-structure +on a category `C` and `n : ℤ`. -/ +noncomputable def truncLEι (n : ℤ) : t.truncLE n ⟶ 𝟭 C := t.truncLTι (n + 1) + +@[reassoc (attr := simp)] +lemma truncLEIsoTruncLT_hom_ι (a b : ℤ) (h : a + 1 = b) : + (t.truncLEIsoTruncLT a b h).hom ≫ t.truncLTι b = t.truncLEι a := by + subst h + dsimp [truncLEIsoTruncLT, truncLEι] + rw [Category.id_comp] + +@[reassoc (attr := simp)] +lemma truncLEIsoTruncLT_hom_ι_app (a b : ℤ) (h : a + 1 = b) (X : C) : + (t.truncLEIsoTruncLT a b h).hom.app X ≫ (t.truncLTι b).app X = (t.truncLEι a).app X := + congr_app (t.truncLEIsoTruncLT_hom_ι a b h) X + +@[reassoc (attr := simp)] +lemma truncLEIsoTruncLT_inv_ι (a b : ℤ) (h : a + 1 = b) : + (t.truncLEIsoTruncLT a b h).inv ≫ t.truncLEι a = t.truncLTι b := by + subst h + dsimp [truncLEIsoTruncLT, truncLEι, truncLE] + rw [Category.id_comp] + +@[reassoc (attr := simp)] +lemma truncLEIsoTruncLT_inv_ι_app (a b : ℤ) (h : a + 1 = b) (X : C) : + (t.truncLEIsoTruncLT a b h).inv.app X ≫ (t.truncLEι a).app X = (t.truncLTι b).app X := + congr_app (t.truncLEIsoTruncLT_inv_ι a b h) X + +/-- The natural transformation `t.truncLE a ⟶ t.truncLE b` when `a ≤ b`. -/ +noncomputable def natTransTruncLEOfLE (a b : ℤ) (h : a ≤ b) : + t.truncLE a ⟶ t.truncLE b := + t.natTransTruncLTOfLE (a+1) (b+1) (by lia) + +@[reassoc (attr := simp)] +lemma natTransTruncLEOfLE_ι_app (n₀ n₁ : ℤ) (h : n₀ ≤ n₁) (X : C) : + (t.natTransTruncLEOfLE n₀ n₁ h).app X ≫ (t.truncLEι n₁).app X = + (t.truncLEι n₀).app X := + t.natTransTruncLTOfLE_ι_app _ _ _ _ + +@[reassoc (attr := simp)] +lemma natTransTruncLEOfLE_ι (a b : ℤ) (h : a ≤ b) : + t.natTransTruncLEOfLE a b h ≫ t.truncLEι b = t.truncLEι a := by cat_disch + +@[simp] +lemma natTransTruncLEOfLE_refl (a : ℤ) : + t.natTransTruncLEOfLE a a (by rfl) = 𝟙 _ := + t.natTransTruncLTOfLE_refl _ + +@[simp] +lemma natTransTruncLEOfLE_trans (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) : + t.natTransTruncLEOfLE a b hab ≫ t.natTransTruncLEOfLE b c hbc = + t.natTransTruncLEOfLE a c (hab.trans hbc) := + t.natTransTruncLTOfLE_trans _ _ _ _ _ + +lemma natTransTruncLEOfLE_refl_app (a : ℤ) (X : C) : + (t.natTransTruncLEOfLE a a (by rfl)).app X = 𝟙 _ := + congr_app (t.natTransTruncLEOfLE_refl a) X + +@[reassoc (attr := simp)] +lemma natTransTruncLEOfLE_trans_app (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) (X : C) : + (t.natTransTruncLEOfLE a b hab).app X ≫ (t.natTransTruncLEOfLE b c hbc).app X = + (t.natTransTruncLEOfLE a c (hab.trans hbc)).app X := + congr_app (t.natTransTruncLEOfLE_trans a b c hab hbc) X + +/-- The natural transformation `𝟭 C ⟶ t.truncGT n` when `t` is a t-structure +on a category `C` and `n : ℤ`. -/ +noncomputable def truncGTπ (n : ℤ) : 𝟭 C ⟶ t.truncGT n := t.truncGEπ (n + 1) + +@[reassoc (attr := simp)] +lemma π_truncGTIsoTruncGE_hom (a b : ℤ) (h : a + 1 = b) : + t.truncGTπ a ≫ (t.truncGTIsoTruncGE a b h).hom = t.truncGEπ b := by + subst h + dsimp [truncGTIsoTruncGE, truncGTπ] + rw [Category.comp_id] + +@[reassoc (attr := simp)] +lemma π_truncGTIsoTruncGE_hom_ι_app (a b : ℤ) (h : a + 1 = b) (X : C) : + (t.truncGTπ a).app X ≫ (t.truncGTIsoTruncGE a b h).hom.app X = (t.truncGEπ b).app X := + congr_app (t.π_truncGTIsoTruncGE_hom a b h) X + +@[reassoc (attr := simp)] +lemma π_truncGTIsoTruncGE_inv (a b : ℤ) (h : a + 1 = b) : + t.truncGEπ b ≫ (t.truncGTIsoTruncGE a b h).inv = t.truncGTπ a := by + subst h + dsimp [truncGTIsoTruncGE, truncGTπ, truncGT] + rw [Category.comp_id] + +@[reassoc (attr := simp)] +lemma π_truncGTIsoTruncGE_inv_ι_app (a b : ℤ) (h : a + 1 = b) (X : C) : + (t.truncGEπ b).app X ≫ (t.truncGTIsoTruncGE a b h).inv.app X = (t.truncGTπ a).app X := + congr_app (t.π_truncGTIsoTruncGE_inv a b h) X + +/-- The connecting homomorphism `(t.truncGE b).obj X ⟶ ((t.truncLE a).obj X)⟦1⟧` +when `a + 1 = b`, as a natural transformation. -/ +noncomputable def truncGEδLE (a b : ℤ) (h : a + 1 = b) : + t.truncGE b ⟶ t.truncLE a ⋙ shiftFunctor C (1 : ℤ) := + t.truncGEδLT b ≫ Functor.whiskerRight (t.truncLEIsoTruncLT a b h).inv (shiftFunctor C (1 : ℤ)) + +/-- The distinguished triangle `(t.truncLE a).obj A ⟶ A ⟶ (t.truncGE b).obj A ⟶ ...` +as a functor `C ⥤ Triangle C` when `t` is a `t`-structure on a pretriangulated +category `C` and `a + 1 = b`. -/ +@[simps!] +noncomputable def triangleLEGE (a b : ℤ) (h : a + 1 = b) : C ⥤ Triangle C := + Triangle.functorMk (t.truncLEι a) (t.truncGEπ b) (t.truncGEδLE a b h) + +/-- The natural isomorphism of triangles `t.triangleLEGE a b h ≅ t.triangleLTGE b` +when `a + 1 = b`. -/ +noncomputable def triangleLEGEIsoTriangleLTGE (a b : ℤ) (h : a + 1 = b) : + t.triangleLEGE a b h ≅ t.triangleLTGE b := by + refine Triangle.functorIsoMk _ _ (t.truncLEIsoTruncLT a b h) (Iso.refl _) (Iso.refl _) ?_ ?_ ?_ + · cat_disch + · cat_disch + · ext + dsimp [truncGEδLE] + simp only [Category.assoc, Category.id_comp, ← Functor.map_comp, + Iso.inv_hom_id_app, Functor.map_id, Category.comp_id] + +lemma triangleLEGE_distinguished (a b : ℤ) (h : a + 1 = b) (X : C) : + (t.triangleLEGE a b h).obj X ∈ distTriang C := + isomorphic_distinguished _ (t.triangleLTGE_distinguished b X) _ + ((t.triangleLEGEIsoTriangleLTGE a b h).app X) + +/-- The connecting homomorphism `(t.truncGT n).obj X ⟶ ((t.truncLE n).obj X)⟦1⟧` +for `n : ℤ`, as a natural transformation. -/ +noncomputable def truncGTδLE (n : ℤ) : + t.truncGT n ⟶ t.truncLE n ⋙ shiftFunctor C (1 : ℤ) := + (t.truncGTIsoTruncGE n (n+1) rfl).hom ≫ t.truncGEδLE n (n + 1) (by lia) + +/-- The distinguished triangle `(t.truncLE n).obj A ⟶ A ⟶ (t.truncGT n).obj A ⟶ ...` +as a functor `C ⥤ Triangle C` when `t` is a t-structure on a pretriangulated +category `C` and `n : ℤ`. -/ +@[simps!] +noncomputable def triangleLEGT (n : ℤ) : C ⥤ Triangle C := + Triangle.functorMk (t.truncLEι n) (t.truncGTπ n) (t.truncGTδLE n) + +/-- The natural isomorphism `t.triangleLEGT a ≅ t.triangleLEGE a b h` +when `a + 1 = b`. -/ +noncomputable def triangleLEGTIsoTriangleLEGE (a b : ℤ) (h : a + 1 = b) : + t.triangleLEGT a ≅ t.triangleLEGE a b h := + Triangle.functorIsoMk _ _ (Iso.refl _) (Iso.refl _) (t.truncGTIsoTruncGE a b h) + (by cat_disch) (by cat_disch) (by + ext + dsimp [truncGTδLE] + subst h + simp only [Functor.map_id, Category.comp_id]) + +lemma triangleLEGT_distinguished (n : ℤ) (X : C) : + (t.triangleLEGT n).obj X ∈ distTriang C := + isomorphic_distinguished _ (t.triangleLEGE_distinguished n (n+1) rfl X) _ + ((t.triangleLEGTIsoTriangleLEGE n (n+1) rfl).app X) + +lemma isLE_iff_isIso_truncLEι_app (n : ℤ) (X : C) : + t.IsLE X n ↔ IsIso ((t.truncLEι n).app X) := + t.isLE_iff_isIso_truncLTι_app n (n + 1) rfl X + +lemma isGE_iff_isIso_truncGTπ_app (n₀ n₁ : ℤ) (hn₁ : n₀ + 1 = n₁) (X : C) : + t.IsGE X n₁ ↔ IsIso ((t.truncGTπ n₀).app X) := by + rw [t.isGE_iff_isIso_truncGEπ_app n₁ X] + exact (MorphismProperty.isomorphisms _).arrow_mk_iso_iff + (Arrow.isoMk (Iso.refl _) ((t.truncGTIsoTruncGE _ _ hn₁).symm.app X)) + +instance (X : C) (n : ℤ) [t.IsLE X n] : IsIso ((t.truncLEι n).app X) := by + rw [← isLE_iff_isIso_truncLEι_app ] + infer_instance + +lemma isLE_iff_isZero_truncGT_obj (n : ℤ) (X : C) : + t.IsLE X n ↔ IsZero ((t.truncGT n).obj X) := by + rw [t.isLE_iff_isIso_truncLEι_app n X] + exact (Triangle.isZero₃_iff_isIso₁ _ (t.triangleLEGT_distinguished n X)).symm + +lemma isGE_iff_isZero_truncLE_obj (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) : + t.IsGE X n₁ ↔ IsZero ((t.truncLE n₀).obj X) := by + rw [t.isGE_iff_isIso_truncGEπ_app n₁ X] + exact (Triangle.isZero₁_iff_isIso₂ _ (t.triangleLEGE_distinguished n₀ n₁ h X)).symm + +lemma isZero_truncLE_obj_of_isGE (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) [t.IsGE X n₁] : + IsZero ((t.truncLE n₀).obj X) := by + rw [← t.isGE_iff_isZero_truncLE_obj _ _ h X] + infer_instance + +lemma to_truncLE_obj_ext {n : ℤ} {Y : C} {X : C} + {f₁ f₂ : Y ⟶ (t.truncLE n).obj X} (h : f₁ ≫ (t.truncLEι n).app X = f₂ ≫ (t.truncLEι n).app X) + [t.IsLE Y n] : + f₁ = f₂ := by + have : t.IsLE Y (n + 1 - 1) := by simpa + rw [← cancel_mono ((t.truncLEIsoTruncLT n (n + 1) rfl).hom.app _)] + exact t.to_truncLT_obj_ext (by simpa) + +section + +variable {X Y : C} (f : X ⟶ Y) (n : ℤ) [t.IsLE X n] + +lemma liftTruncLE_aux : + ∃ (f' : X ⟶ (t.truncLE n).obj Y), f = f' ≫ (t.truncLEι n).app Y := + Triangle.coyoneda_exact₂ _ (t.triangleLEGT_distinguished n Y) f + (t.zero_of_isLE_of_isGE _ n (n + 1) (by lia) inferInstance (by dsimp; infer_instance)) + +/-- Constructor for morphisms to `(t.truncLE n).obj Y`. -/ +noncomputable def liftTruncLE : + X ⟶ (t.truncLE n).obj Y := (t.liftTruncLE_aux f n).choose + +@[reassoc (attr := simp)] +lemma liftTruncLE_ι : + t.liftTruncLE f n ≫ (t.truncLEι n).app Y = f := + (t.liftTruncLE_aux f n).choose_spec.symm + +end + +section + +variable {X Y : C} (f : X ⟶ Y) (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) [t.IsGE Y n₁] + +include h in +lemma descTruncGT_aux : + ∃ (f' : (t.truncGT n₀).obj X ⟶ Y), f = (t.truncGTπ n₀).app X ≫ f' := + Triangle.yoneda_exact₂ _ (t.triangleLEGT_distinguished n₀ X) f + (t.zero_of_isLE_of_isGE _ n₀ n₁ (by lia) (by dsimp; infer_instance) inferInstance) + +/-- Constructor for morphisms from `(t.truncGT n₀).obj Y`. -/ +noncomputable def descTruncGT : + (t.truncGT n₀).obj X ⟶ Y := + (t.descTruncGT_aux f n₀ n₁ h).choose + +@[reassoc (attr := simp)] +lemma π_descTruncGT : + (t.truncGTπ n₀).app X ≫ t.descTruncGT f n₀ n₁ h = f := + (t.descTruncGT_aux f n₀ n₁ h).choose_spec.symm + +end + +lemma isIso_truncLE_map_iff {X Y : C} (f : X ⟶ Y) (a b : ℤ) (h : a + 1 = b) : + IsIso ((t.truncLE a).map f) ↔ + ∃ (Z : C) (g : Y ⟶ Z) (h : Z ⟶ ((t.truncLE a).obj X)⟦1⟧) + (_ : Triangle.mk ((t.truncLEι a).app X ≫ f) g h ∈ distTriang _), t.IsGE Z b := by + subst h + apply isIso_truncLT_map_iff + +lemma isIso_truncGT_map_iff {Y Z : C} (g : Y ⟶ Z) (n : ℤ) : + IsIso ((t.truncGT n).map g) ↔ + ∃ (X : C) (f : X ⟶ Y) (h : ((t.truncGT n).obj Z) ⟶ X⟦(1 : ℤ)⟧) + (_ : Triangle.mk f (g ≫ (t.truncGTπ n).app Z) h ∈ distTriang _), t.IsLE X n := + t.isIso_truncGE_map_iff g n (n + 1) rfl + +instance (X : C) (a b : ℤ) [t.IsLE X b] : t.IsLE ((t.truncLE a).obj X) b := by + dsimp [truncLE] + infer_instance + +instance (X : C) (a b : ℤ) [t.IsGE X a] : t.IsGE ((t.truncGT b).obj X) a := by + dsimp [truncGT] + infer_instance + +/-- The composition `t.truncGE a ⋙ t.truncGE b`. -/ +noncomputable abbrev truncLEGE (a b : ℤ) : C ⥤ C := t.truncGE a ⋙ t.truncLE b + +/-- The composition `t.truncLE b ⋙ t.truncGE a`. -/ +noncomputable abbrev truncGELE (a b : ℤ) : C ⥤ C := t.truncLE b ⋙ t.truncGE a + +instance (X : C) (a b : ℤ) : t.IsGE ((t.truncGELE a b).obj X) a := by + dsimp; infer_instance + +/-- The natural isomorphism `t.truncGELE a b ≅ t.truncGELT a b'` when `b + 1 = b'`. -/ +noncomputable def truncGELEIsoTruncGELT (a b b' : ℤ) (hb' : b + 1 = b') : + t.truncGELE a b ≅ t.truncGELT a b' := + Functor.isoWhiskerRight (t.truncLEIsoTruncLT b b' hb') _ + +section + +variable [IsTriangulated C] + +lemma isIso₁_truncLE_map_of_isGE (T : Triangle C) (hT : T ∈ distTriang C) + (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (h₃ : t.IsGE T.obj₃ n₁) : + IsIso ((t.truncLE n₀).map T.mor₁) := by + subst h + exact t.isIso₁_truncLT_map_of_isGE _ hT _ h₃ + +lemma isIso₂_truncGT_map_of_isLE (T : Triangle C) (hT : T ∈ distTriang C) + (n₀ : ℤ) (h₁ : t.IsLE T.obj₁ n₀) : + IsIso ((t.truncGT n₀).map T.mor₂) := + t.isIso₂_truncGE_map_of_isLE _ hT _ _ rfl h₁ + +instance (X : C) (a b : ℤ) [t.IsGE X a] : + t.IsGE ((t.truncLE b).obj X) a := by + dsimp [truncLE]; infer_instance + +instance (X : C) (a b : ℤ) [t.IsLE X b] : + t.IsLE ((t.truncGT a).obj X) b := by + dsimp [truncGT]; infer_instance + +instance (X : C) (a b : ℤ) [t.IsGE X a] : + t.IsGE ((t.truncLE b).obj X) a := by + dsimp [truncLE]; infer_instance + +instance (X : C) (a b : ℤ) : + t.IsLE ((t.truncGELE a b).obj X) b := by + dsimp; infer_instance + +lemma isIso_truncLE_map_truncLEι_app (a b : ℤ) (h : a ≤ b) (X : C) : + IsIso ((t.truncLE a).map ((t.truncLEι b).app X)) := + t.isIso_truncLT_map_truncLTι_app _ _ (by lia) _ + +lemma isIso_truncGT_map_truncGTπ_app (a b : ℤ) (h : b ≤ a) (X : C) : + IsIso ((t.truncGT a).map ((t.truncGTπ b).app X)) := + isIso_truncGE_map_truncGEπ_app _ _ _ (by lia) _ + +instance (X : C) (n : ℤ) : IsIso ((t.truncLE n).map ((t.truncLEι n).app X)) := + t.isIso_truncLE_map_truncLEι_app _ _ (by lia) _ + +/-- The natural isomorphism `t.truncGELE a b ≅ t.truncLEGE a b`. -/ +noncomputable def truncGELEIsoLEGE (a b : ℤ) : t.truncGELE a b ≅ t.truncLEGE a b := + t.truncGELTIsoLTGE a (b + 1) + +end + +end TStructure + +end Triangulated + +end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean index 44036a78497de9..fd97466755f213 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean @@ -19,13 +19,21 @@ part of a distinguished triangle `(t.truncLT n).obj X ⟶ X ⟶ (t.truncGE n).obj X ⟶ ((t.truncLT n).obj X)⟦1⟧` for any `X : C`, with `(t.truncLT n).obj X < n` and `(t.truncGE n).obj X ≥ n`. +We obtain various properties of these truncation functors. +Variants `truncGT` and `truncLE` are introduced in the file +`Mathlib/CategoryTheory/Triangulated/TStucture/TruncLEGT.lean`. +Extensions to indices in `EInt` instead of `ℤ` are introduced in the file +`Mathlib/CategoryTheory/Triangulated/TStucture/ETrunc.lean`. +The spectral object attached to an object `X : C` is constructed in the file +`Mathlib/CategoryTheory/Triangulated/TStucture/SpectralObject.lean`. + -/ universe v u namespace CategoryTheory -open Limits Pretriangulated +open Limits Pretriangulated ZeroObject variable {C : Type u} [Category.{v} C] [Preadditive C] [HasZeroObject C] [HasShift C ℤ] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] @@ -163,6 +171,43 @@ instance isGE_triangleFunctor_obj_obj₃ : dsimp [triangleFunctor] infer_instance +noncomputable def triangleMapOfLE (a b : ℤ) (h : a ≤ b) : triangle t a A ⟶ triangle t b A := + have H := triangle_map_exists t (triangle_distinguished t a A) + (triangle_distinguished t b A) (𝟙 _) (a-1) b inferInstance inferInstance + { hom₁ := H.choose.hom₁ + hom₂ := 𝟙 _ + hom₃ := H.choose.hom₃ + comm₁ := by rw [← H.choose.comm₁, H.choose_spec] + comm₂ := by rw [H.choose.comm₂, H.choose_spec] + comm₃ := H.choose.comm₃ } + +noncomputable def triangleFunctorNatTransOfLE (a b : ℤ) (h : a ≤ b) : + triangleFunctor t a ⟶ triangleFunctor t b where + app X := triangleMapOfLE t X a b h + naturality {X₁ X₂} φ := + triangle_map_ext t (triangleFunctor_obj_distinguished _ _ _) + (triangleFunctor_obj_distinguished _ _ _) (a - 1) b inferInstance inferInstance + (by simp [triangleMapOfLE]) + +@[simp] +lemma triangleFunctorNatTransOfLE_app_hom₂ (a b : ℤ) (h : a ≤ b) (X : C) : + ((triangleFunctorNatTransOfLE t a b h).app X).hom₂ = 𝟙 X := rfl + +lemma triangleFunctorNatTransOfLE_trans (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) : + triangleFunctorNatTransOfLE t a b hab ≫ triangleFunctorNatTransOfLE t b c hbc = + triangleFunctorNatTransOfLE t a c (hab.trans hbc) := by + apply NatTrans.ext + ext1 X + exact triangle_map_ext t (triangleFunctor_obj_distinguished _ _ _) + (triangleFunctor_obj_distinguished _ _ _) (a - 1) c inferInstance inferInstance (by simp) + +lemma triangleFunctorNatTransOfLE_refl (a : ℤ) : + triangleFunctorNatTransOfLE t a a (by rfl) = 𝟙 _ := by + apply NatTrans.ext + ext1 X + exact triangle_map_ext t (triangleFunctor_obj_distinguished _ _ _) + (triangleFunctor_obj_distinguished _ _ _) (a - 1) a inferInstance inferInstance (by simp) + instance : (triangleFunctor t n).Additive where end TruncAux @@ -201,13 +246,29 @@ on a category `C` and `n : ℤ`. -/ noncomputable def truncGEπ (n : ℤ) : 𝟭 _ ⟶ t.truncGE n := Functor.whiskerLeft (TruncAux.triangleFunctor t n) Triangle.π₂Toπ₃ -instance (X : C) (n : ℤ) : t.IsLE ((t.truncLT n).obj X) (n - 1) := by - dsimp [truncLT] - infer_instance +@[reassoc (attr := simp)] +lemma truncGEπ_naturality (n : ℤ) {X Y : C} (f : X ⟶ Y) : + (t.truncGEπ n).app X ≫ (t.truncGE n).map f = f ≫ (t.truncGEπ n).app Y := + ((t.truncGEπ n).naturality f).symm -instance (X : C) (n : ℤ) : t.IsGE ((t.truncGE n).obj X) n := by - dsimp [truncGE] - infer_instance +lemma isLE_truncLT_obj (X : C) (a b : ℤ) (hn : a ≤ b + 1 := by lia) : + t.IsLE ((t.truncLT a).obj X) b := by + have : t.IsLE ((t.truncLT a).obj X) (a - 1) := by dsimp [truncLT]; infer_instance + exact t.isLE_of_LE _ (a - 1) _ (by lia) + +instance (X : C) (n : ℤ) : t.IsLE ((t.truncLT n).obj X) (n - 1) := + t.isLE_truncLT_obj .. + +instance (X : C) (n : ℤ) : t.IsLE ((t.truncLT (n + 1)).obj X) n := + t.isLE_truncLT_obj .. + +lemma isGE_truncGE_obj (X : C) (a b : ℤ) (hn : b ≤ a := by lia) : + t.IsGE ((t.truncGE a).obj X) b := by + have : t.IsGE ((t.truncGE a).obj X) a := by dsimp [truncGE]; infer_instance + exact t.isGE_of_GE _ _ a (by lia) + +instance (X : C) (n : ℤ) : t.IsGE ((t.truncGE n).obj X) n := + t.isGE_truncGE_obj .. /-- The connecting morphism `t.truncGE n ⟶ t.truncLT n ⋙ shiftFunctor C (1 : ℤ)` when `t` is a t-structure on a pretriangulated category and `n : ℤ`. -/ @@ -234,6 +295,562 @@ instance (X : C) (n : ℤ) : t.IsGE ((t.triangleLTGE n).obj X).obj₃ n := by dsimp infer_instance +@[reassoc (attr := simp)] +lemma truncLTι_comp_truncGEπ_app (n : ℤ) (X : C) : + (t.truncLTι n).app X ≫ (t.truncGEπ n).app X = 0 := + comp_distTriang_mor_zero₁₂ _ (t.triangleLTGE_distinguished n X) + +@[reassoc (attr := simp)] +lemma truncGEπ_comp_truncGEδLT_app (n : ℤ) (X : C) : + (t.truncGEπ n).app X ≫ (t.truncGEδLT n).app X = 0 := + comp_distTriang_mor_zero₂₃ _ (t.triangleLTGE_distinguished n X) + +@[reassoc (attr := simp)] +lemma truncGEδLT_comp_truncLTι_app (n : ℤ) (X : C) : + (t.truncGEδLT n).app X ≫ ((t.truncLTι n).app X)⟦(1 : ℤ)⟧' = 0 := + comp_distTriang_mor_zero₃₁ _ (t.triangleLTGE_distinguished n X) + +@[reassoc (attr := simp)] +lemma truncLTι_comp_truncGEπ (n : ℤ) : + t.truncLTι n ≫ t.truncGEπ n = 0 := by cat_disch + +@[reassoc (attr := simp)] +lemma truncGEπ_comp_truncGEδLT (n : ℤ) : + t.truncGEπ n ≫ t.truncGEδLT n = 0 := by cat_disch + +@[reassoc (attr := simp)] +lemma truncGEδLT_comp_truncLTι (n : ℤ) : + t.truncGEδLT n ≫ Functor.whiskerRight (t.truncLTι n) (shiftFunctor C (1 : ℤ)) = 0 := by + cat_disch + +/-- The natural transformation `t.truncLT a ⟶ t.truncLT b` when `a ≤ b`. -/ +noncomputable def natTransTruncLTOfLE (a b : ℤ) (h : a ≤ b) : + t.truncLT a ⟶ t.truncLT b := + Functor.whiskerRight (TruncAux.triangleFunctorNatTransOfLE t a b h) Triangle.π₁ + +/-- The natural transformation `t.truncGE a ⟶ t.truncGE b` when `a ≤ b`. -/ +noncomputable def natTransTruncGEOfLE (a b : ℤ) (h : a ≤ b) : + t.truncGE a ⟶ t.truncGE b := + Functor.whiskerRight (TruncAux.triangleFunctorNatTransOfLE t a b h) Triangle.π₃ + +@[reassoc (attr := simp)] +lemma natTransTruncLTOfLE_ι_app (a b : ℤ) (h : a ≤ b) (X : C) : + (t.natTransTruncLTOfLE a b h).app X ≫ (t.truncLTι b).app X = (t.truncLTι a).app X := by + simpa using ((TruncAux.triangleFunctorNatTransOfLE t a b h).app X).comm₁.symm + +@[reassoc (attr := simp)] +lemma natTransTruncLTOfLE_ι (a b : ℤ) (h : a ≤ b) : + t.natTransTruncLTOfLE a b h ≫ t.truncLTι b = t.truncLTι a := by cat_disch + +@[reassoc (attr := simp)] +lemma π_natTransTruncGEOfLE_app (a b : ℤ) (h : a ≤ b) (X : C) : + (t.truncGEπ a).app X ≫ (t.natTransTruncGEOfLE a b h).app X = (t.truncGEπ b).app X := by + simpa only [TruncAux.triangleFunctor_obj, TruncAux.triangle_obj₂, + TruncAux.triangleFunctorNatTransOfLE_app_hom₂, Category.id_comp] using + ((TruncAux.triangleFunctorNatTransOfLE t a b h).app X).comm₂ + +@[reassoc] +lemma truncGEδLT_comp_natTransTruncLTOfLE_app (a b : ℤ) (h : a ≤ b) (X : C) : + (t.truncGEδLT a).app X ≫ ((natTransTruncLTOfLE t a b h).app X)⟦(1 :ℤ)⟧' = + (t.natTransTruncGEOfLE a b h).app X ≫ (t.truncGEδLT b).app X := + ((TruncAux.triangleFunctorNatTransOfLE t a b h).app X).comm₃ + +@[reassoc] +lemma truncGEδLT_comp_whiskerRight_natTransTruncLTOfLE (a b : ℤ) (h : a ≤ b) : + t.truncGEδLT a ≫ Functor.whiskerRight (natTransTruncLTOfLE t a b h) (shiftFunctor C (1 : ℤ)) = + t.natTransTruncGEOfLE a b h ≫ t.truncGEδLT b := by + ext X + exact t.truncGEδLT_comp_natTransTruncLTOfLE_app a b h X + +@[reassoc (attr := simp)] +lemma π_natTransTruncGEOfLE (a b : ℤ) (h : a ≤ b) : + t.truncGEπ a ≫ t.natTransTruncGEOfLE a b h = t.truncGEπ b := by cat_disch + +/-- The natural transformation `t.triangleLTGE a ⟶ t.triangleLTGE b` +when `a ≤ b`. -/ +noncomputable def natTransTriangleLTGEOfLE (a b : ℤ) (h : a ≤ b) : + t.triangleLTGE a ⟶ t.triangleLTGE b := by + refine Triangle.functorHomMk' (t.natTransTruncLTOfLE a b h) (𝟙 _) + ((t.natTransTruncGEOfLE a b h)) ?_ ?_ ?_ + · simp + · simp + · exact t.truncGEδLT_comp_whiskerRight_natTransTruncLTOfLE a b h + +@[simp] +lemma natTransTriangleLTGEOfLE_refl (a : ℤ) : + t.natTransTriangleLTGEOfLE a a (by rfl) = 𝟙 _ := + TruncAux.triangleFunctorNatTransOfLE_refl t a + +lemma natTransTriangleLTGEOfLE_trans (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) : + t.natTransTriangleLTGEOfLE a b hab ≫ t.natTransTriangleLTGEOfLE b c hbc = + t.natTransTriangleLTGEOfLE a c (hab.trans hbc) := + TruncAux.triangleFunctorNatTransOfLE_trans t a b c hab hbc + +@[simp] +lemma natTransTruncLTOfLE_refl (a : ℤ) : + t.natTransTruncLTOfLE a a (by rfl) = 𝟙 _ := + congr_arg (fun x ↦ Functor.whiskerRight x (Triangle.π₁)) (t.natTransTriangleLTGEOfLE_refl a) + +@[simp] +lemma natTransTruncLTOfLE_trans (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) : + t.natTransTruncLTOfLE a b hab ≫ t.natTransTruncLTOfLE b c hbc = + t.natTransTruncLTOfLE a c (hab.trans hbc) := + congr_arg (fun x ↦ Functor.whiskerRight x Triangle.π₁) + (t.natTransTriangleLTGEOfLE_trans a b c hab hbc) + +@[simp] +lemma natTransTruncGEOfLE_refl (a : ℤ) : + t.natTransTruncGEOfLE a a (by rfl) = 𝟙 _ := + congr_arg (fun x ↦ Functor.whiskerRight x (Triangle.π₃)) (t.natTransTriangleLTGEOfLE_refl a) + +@[simp] +lemma natTransTruncGEOfLE_trans (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) : + t.natTransTruncGEOfLE a b hab ≫ t.natTransTruncGEOfLE b c hbc = + t.natTransTruncGEOfLE a c (hab.trans hbc) := + congr_arg (fun x ↦ Functor.whiskerRight x Triangle.π₃) + (t.natTransTriangleLTGEOfLE_trans a b c hab hbc) + +lemma natTransTruncLTOfLE_refl_app (a : ℤ) (X : C) : + (t.natTransTruncLTOfLE a a (by rfl)).app X = 𝟙 _ := + congr_app (t.natTransTruncLTOfLE_refl a) X + +lemma natTransTruncLTOfLE_trans_app (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) (X : C) : + (t.natTransTruncLTOfLE a b hab).app X ≫ (t.natTransTruncLTOfLE b c hbc).app X = + (t.natTransTruncLTOfLE a c (hab.trans hbc)).app X := + congr_app (t.natTransTruncLTOfLE_trans a b c hab hbc) X + +lemma natTransTruncGEOfLE_refl_app (a : ℤ) (X : C) : + (t.natTransTruncGEOfLE a a (by rfl)).app X = 𝟙 _ := + congr_app (t.natTransTruncGEOfLE_refl a) X + +lemma natTransTruncGEOfLE_trans_app (a b c : ℤ) (hab : a ≤ b) (hbc : b ≤ c) (X : C) : + (t.natTransTruncGEOfLE a b hab).app X ≫ (t.natTransTruncGEOfLE b c hbc).app X = + (t.natTransTruncGEOfLE a c (hab.trans hbc)).app X := + congr_app (t.natTransTruncGEOfLE_trans a b c hab hbc) X + +lemma isLE_of_isZero {X : C} (hX : IsZero X) (n : ℤ) : t.IsLE X n := + t.isLE_of_iso (((t.truncLT (n + 1)).map_isZero hX).isoZero ≪≫ hX.isoZero.symm) n + +lemma isGE_of_isZero {X : C} (hX : IsZero X) (n : ℤ) : t.IsGE X n := + t.isGE_of_iso (((t.truncGE n).map_isZero hX).isoZero ≪≫ hX.isoZero.symm) n + +instance (n : ℤ) : t.IsLE (0 : C) n := t.isLE_of_isZero (isZero_zero C) n + +instance (n : ℤ) : t.IsGE (0 : C) n := t.isGE_of_isZero (isZero_zero C) n + +lemma isLE_iff_isIso_truncLTι_app (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) : + t.IsLE X n₀ ↔ IsIso (((t.truncLTι n₁)).app X) := by + subst h + refine ⟨fun _ ↦ ?_, + fun _ ↦ t.isLE_of_iso (asIso (((t.truncLTι (n₀ + 1))).app X)) n₀⟩ + obtain ⟨e, he⟩ := t.triangle_iso_exists + (contractible_distinguished X) (t.triangleLTGE_distinguished (n₀ + 1) X) + (Iso.refl X) n₀ (n₀ + 1) + (by dsimp; infer_instance) (by dsimp; infer_instance) + (by dsimp; infer_instance) (by dsimp; infer_instance) + have he' : e.inv.hom₂ = 𝟙 X := by + rw [← cancel_mono e.hom.hom₂, ← comp_hom₂, e.inv_hom_id, he] + simp + have : (t.truncLTι (n₀ + 1)).app X = e.inv.hom₁ := by + simpa [he'] using e.inv.comm₁ + rw [this] + infer_instance + +lemma isGE_iff_isIso_truncGEπ_app (n : ℤ) (X : C) : + t.IsGE X n ↔ IsIso ((t.truncGEπ n).app X) := by + constructor + · intro h + obtain ⟨e, he⟩ := t.triangle_iso_exists + (inv_rot_of_distTriang _ (contractible_distinguished X)) + (t.triangleLTGE_distinguished n X) (Iso.refl X) (n - 1) n + (t.isLE_of_iso (shiftFunctor C (-1 : ℤ)).mapZeroObject.symm _) + (by dsimp; infer_instance) (by dsimp; infer_instance) (by dsimp; infer_instance) + dsimp at he + have : (truncGEπ t n).app X = e.hom.hom₃ := by + have := e.hom.comm₂ + dsimp at this + rw [← cancel_epi e.hom.hom₂, ← this, he] + rw [this] + infer_instance + · intro + exact t.isGE_of_iso (asIso ((truncGEπ t n).app X)).symm n + +instance (X : C) (n : ℤ) [t.IsGE X n] : IsIso ((t.truncGEπ n).app X) := by + rw [← isGE_iff_isIso_truncGEπ_app] + infer_instance + +lemma isGE_iff_isZero_truncLT_obj (n : ℤ) (X : C) : + t.IsGE X n ↔ IsZero ((t.truncLT n).obj X) := by + rw [t.isGE_iff_isIso_truncGEπ_app n X] + exact (Triangle.isZero₁_iff_isIso₂ _ (t.triangleLTGE_distinguished n X)).symm + +lemma isLE_iff_isZero_truncGE_obj (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) : + t.IsLE X n₀ ↔ IsZero ((t.truncGE n₁).obj X) := by + rw [t.isLE_iff_isIso_truncLTι_app n₀ n₁ h X] + exact (Triangle.isZero₃_iff_isIso₁ _ (t.triangleLTGE_distinguished n₁ X)).symm + +lemma isZero_truncLT_obj_of_isGE (n : ℤ) (X : C) [t.IsGE X n] : + IsZero ((t.truncLT n).obj X) := by + rw [← isGE_iff_isZero_truncLT_obj] + infer_instance + +lemma isZero_truncGE_obj_of_isLE (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) [t.IsLE X n₀] : + IsZero ((t.truncGE n₁).obj X) := by + rw [← t.isLE_iff_isZero_truncGE_obj _ _ h X] + infer_instance + +lemma from_truncGE_obj_ext {n : ℤ} {X : C} {Y : C} + {f₁ f₂ : (t.truncGE n).obj X ⟶ Y} (h : (t.truncGEπ n).app X ≫ f₁ = (t.truncGEπ n).app X ≫ f₂) + [t.IsGE Y n] : + f₁ = f₂ := by + suffices ∀ (f : (t.truncGE n).obj X ⟶ Y), (t.truncGEπ n).app X ≫ f = 0 → f = 0 by + rw [← sub_eq_zero, this (f₁ - f₂) (by cat_disch)] + intro f hf + obtain ⟨g, hg⟩ := Triangle.yoneda_exact₃ _ + (t.triangleLTGE_distinguished n X) f hf + have hg' := t.zero_of_isLE_of_isGE g (n-2) n (by lia) + (by exact t.isLE_shift _ (n-1) 1 (n-2) (by lia)) inferInstance + rw [hg, hg', comp_zero] + +lemma to_truncLT_obj_ext {n : ℤ} {Y : C} {X : C} + {f₁ f₂ : Y ⟶ (t.truncLT n).obj X} + (h : f₁ ≫ (t.truncLTι n).app X = f₂ ≫ (t.truncLTι n).app X) + [t.IsLE Y (n - 1)] : + f₁ = f₂ := by + suffices ∀ (f : Y ⟶ (t.truncLT n).obj X) (_ : f ≫ (t.truncLTι n).app X = 0), f = 0 by + rw [← sub_eq_zero, this (f₁ - f₂) (by cat_disch)] + intro f hf + obtain ⟨g, hg⟩ := Triangle.coyoneda_exact₂ _ (inv_rot_of_distTriang _ + (t.triangleLTGE_distinguished n X)) f hf + have hg' := t.zero_of_isLE_of_isGE g (n - 1) (n + 1) (by lia) inferInstance + (by dsimp; apply (t.isGE_shift _ n (-1) (n + 1) (by lia))) + rw [hg, hg', zero_comp] + +@[reassoc] +lemma truncLT_map_truncLTι_app (n : ℤ) (X : C) : + (t.truncLT n).map ((t.truncLTι n).app X) = (t.truncLTι n).app ((t.truncLT n).obj X) := + t.to_truncLT_obj_ext (by simp) + +@[reassoc] +lemma truncGE_map_truncGEπ_app (n : ℤ) (X : C) : + (t.truncGE n).map ((t.truncGEπ n).app X) = (t.truncGEπ n).app ((t.truncGE n).obj X) := + t.from_truncGE_obj_ext (by simp) + +section + +variable {X Y : C} (f : X ⟶ Y) (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) [t.IsLE X n₀] + +include h in +lemma liftTruncLT_aux : + ∃ (f' : X ⟶ (t.truncLT n₁).obj Y), f = f' ≫ (t.truncLTι n₁).app Y := + Triangle.coyoneda_exact₂ _ (t.triangleLTGE_distinguished n₁ Y) f + (t.zero_of_isLE_of_isGE _ n₀ n₁ (by lia) inferInstance (by dsimp; infer_instance)) + +/-- Constructor for morphisms to `(t.truncLT n₁).obj Y`. -/ +noncomputable def liftTruncLT {X Y : C} (f : X ⟶ Y) (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) [t.IsLE X n₀] : + X ⟶ (t.truncLT n₁).obj Y := + (t.liftTruncLT_aux f n₀ n₁ h).choose + +@[reassoc (attr := simp)] +lemma liftTruncLT_ι {X Y : C} (f : X ⟶ Y) (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) [t.IsLE X n₀] : + t.liftTruncLT f n₀ n₁ h ≫ (t.truncLTι n₁).app Y = f := + (t.liftTruncLT_aux f n₀ n₁ h).choose_spec.symm + +end + +section + +variable {X Y : C} (f : X ⟶ Y) (n : ℤ) [t.IsGE Y n] + +lemma descTruncGE_aux : + ∃ (f' : (t.truncGE n).obj X ⟶ Y), f = (t.truncGEπ n).app X ≫ f' := + Triangle.yoneda_exact₂ _ (t.triangleLTGE_distinguished n X) f + (t.zero_of_isLE_of_isGE _ (n-1) n (by lia) (by dsimp; infer_instance) inferInstance) + +/-- Constructor for morphisms from `(t.truncGE n).obj X`. -/ +noncomputable def descTruncGE : + (t.truncGE n).obj X ⟶ Y := + (t.descTruncGE_aux f n).choose + +@[reassoc (attr := simp)] +lemma π_descTruncGE {X Y : C} (f : X ⟶ Y) (n : ℤ) [t.IsGE Y n] : + (t.truncGEπ n).app X ≫ t.descTruncGE f n = f := + (t.descTruncGE_aux f n).choose_spec.symm + +end + +lemma isLE_iff_orthogonal (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) : + t.IsLE X n₀ ↔ ∀ (Y : C) (f : X ⟶ Y) (_ : t.IsGE Y n₁), f = 0 := by + refine ⟨fun _ Y f _ ↦ t.zero f n₀ n₁ (by lia), fun hX ↦ ?_⟩ + rw [t.isLE_iff_isZero_truncGE_obj n₀ n₁ h, IsZero.iff_id_eq_zero] + exact t.from_truncGE_obj_ext (by simpa using hX _ _ inferInstance) + +lemma isGE_iff_orthogonal (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (X : C) : + t.IsGE X n₁ ↔ ∀ (Y : C) (f : Y ⟶ X) (_ : t.IsLE Y n₀), f = 0 := by + refine ⟨fun _ Y f _ ↦ t.zero f n₀ n₁ (by lia), fun hX ↦ ?_⟩ + rw [t.isGE_iff_isZero_truncLT_obj n₁ X, IsZero.iff_id_eq_zero] + exact t.to_truncLT_obj_ext (by simpa using hX _ _ (by rw [← h]; infer_instance)) + +lemma isLE₂ (T : Triangle C) (hT : T ∈ distTriang C) (n : ℤ) (h₁ : t.IsLE T.obj₁ n) + (h₃ : t.IsLE T.obj₃ n) : t.IsLE T.obj₂ n := by + rw [t.isLE_iff_orthogonal n (n+1) rfl] + intro Y f hY + obtain ⟨f', hf'⟩ := Triangle.yoneda_exact₂ _ hT f + (t.zero _ n (n + 1) (by lia) ) + rw [hf', t.zero f' n (n + 1) (by lia), comp_zero] + +lemma isGE₂ (T : Triangle C) (hT : T ∈ distTriang C) (n : ℤ) (h₁ : t.IsGE T.obj₁ n) + (h₃ : t.IsGE T.obj₃ n) : t.IsGE T.obj₂ n := by + rw [t.isGE_iff_orthogonal (n-1) n (by lia)] + intro Y f hY + obtain ⟨f', hf'⟩ := Triangle.coyoneda_exact₂ _ hT f (t.zero _ (n-1) n (by lia)) + rw [hf', t.zero f' (n-1) n (by lia), zero_comp] + +instance : t.minus.IsTriangulated where + exists_zero := ⟨0, isZero_zero C, 0, inferInstance⟩ + toIsTriangulatedClosed₂ := .mk' (fun T hT ↦ by + rintro ⟨i₁, hi₁⟩ ⟨i₃, hi₃⟩ + exact ⟨max i₁ i₃, t.isLE₂ T hT _ (t.isLE_of_LE _ _ _ (le_max_left i₁ i₃)) + (t.isLE_of_LE _ _ _ (le_max_right i₁ i₃))⟩) + +instance : t.plus.IsTriangulated where + exists_zero := ⟨0, isZero_zero C, 0, inferInstance⟩ + toIsTriangulatedClosed₂ := .mk' (fun T hT ↦ by + rintro ⟨i₁, hi₁⟩ ⟨i₃, hi₃⟩ + exact ⟨min i₁ i₃, t.isGE₂ T hT _ (t.isGE_of_GE _ _ _ (min_le_left i₁ i₃)) + (t.isGE_of_GE _ _ _ (min_le_right i₁ i₃))⟩) + +instance : t.bounded.IsTriangulated := by + dsimp [bounded] + infer_instance + +lemma isIso_truncLT_map_iff {X Y : C} (f : X ⟶ Y) (n : ℤ) : + IsIso ((t.truncLT n).map f) ↔ + ∃ (Z : C) (g : Y ⟶ Z) (h : Z ⟶ ((t.truncLT n).obj X)⟦1⟧) + (_ : Triangle.mk ((t.truncLTι n).app X ≫ f) g h ∈ distTriang _), t.IsGE Z n := by + refine ⟨fun hf ↦ ?_, fun ⟨Z, g, h, mem, _⟩ ↦ ?_⟩ + · refine ⟨(t.truncGE n).obj Y, (t.truncGEπ n).app Y, + (t.truncGEδLT n).app Y ≫ (inv ((t.truncLT n).map f))⟦1⟧', + isomorphic_distinguished _ (t.triangleLTGE_distinguished n Y) _ ?_, inferInstance⟩ + exact Triangle.isoMk _ _ (asIso ((t.truncLT n).map f)) (Iso.refl _) (Iso.refl _) + · obtain ⟨e, he⟩ := t.triangle_iso_exists + mem (t.triangleLTGE_distinguished n Y) (Iso.refl _) (n - 1) n + (by dsimp; infer_instance) (by dsimp; infer_instance) + (by dsimp; infer_instance) (by dsimp; infer_instance) + suffices ((t.truncLT n).map f) = e.hom.hom₁ by rw [this]; infer_instance + exact t.to_truncLT_obj_ext (Eq.trans (by cat_disch) e.hom.comm₁) + +lemma isIso_truncGE_map_iff {Y Z : C} (g : Y ⟶ Z) (n₀ n₁ : ℤ) (hn : n₀ + 1 = n₁) : + IsIso ((t.truncGE n₁).map g) ↔ + ∃ (X : C) (f : X ⟶ Y) (h : ((t.truncGE n₁).obj Z) ⟶ X⟦(1 : ℤ)⟧) + (_ : Triangle.mk f (g ≫ (t.truncGEπ n₁).app Z) h ∈ distTriang _), t.IsLE X n₀ := by + refine ⟨fun hf ↦ ?_, fun ⟨X, f, h, mem, _⟩ ↦ ?_⟩ + · refine ⟨_, (t.truncLTι n₁).app Y, inv ((t.truncGE n₁).map g) ≫ (t.truncGEδLT n₁).app Y, + isomorphic_distinguished _ (t.triangleLTGE_distinguished n₁ Y) _ ?_, + by subst hn; infer_instance⟩ + exact Iso.symm (Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) + (asIso ((t.truncGE n₁).map g)) (by simp) (by simp) (by simp)) + · obtain ⟨e, he⟩ := + t.triangle_iso_exists (t.triangleLTGE_distinguished n₁ Y) mem (Iso.refl _) n₀ n₁ + (by dsimp; rw [← hn]; infer_instance) (by dsimp; infer_instance) + (by dsimp; infer_instance) (by dsimp; infer_instance) + suffices ((t.truncGE n₁).map g) = e.hom.hom₃ by rw [this]; infer_instance + exact t.from_truncGE_obj_ext (Eq.trans (by cat_disch) e.hom.comm₂.symm) + +instance (X : C) (a b : ℤ) [t.IsLE X b] : t.IsLE ((t.truncLT a).obj X) b := by + by_cases h : a ≤ b + 1 + · exact t.isLE_truncLT_obj .. + · have := (t.isLE_iff_isIso_truncLTι_app (a - 1) a (by lia) X).1 (t.isLE_of_LE _ b _ (by lia)) + exact t.isLE_of_iso (show X ≅ _ from (asIso ((t.truncLTι a).app X)).symm) _ + +instance (X : C) (a b : ℤ) [t.IsGE X a] : t.IsGE ((t.truncGE b).obj X) a := by + by_cases h : a ≤ b + · exact t.isGE_truncGE_obj .. + · have : t.IsGE X b := t.isGE_of_GE X b a (by lia) + exact t.isGE_of_iso (show X ≅ _ from asIso ((t.truncGEπ b).app X)) _ + +/-- The composition `t.truncLT b ⋙ t.truncGE a`. -/ +noncomputable abbrev truncGELT (a b : ℤ) : C ⥤ C := t.truncLT b ⋙ t.truncGE a + +/-- The composition `t.truncGE b ⋙ t.truncLT a`. -/ +noncomputable abbrev truncLTGE (a b : ℤ) : C ⥤ C := t.truncGE a ⋙ t.truncLT b + +instance (X : C) (a b : ℤ) : t.IsGE ((t.truncGELT a b).obj X) a := by + dsimp; infer_instance + +instance (X : C) (a b : ℤ) : t.IsLE ((t.truncLTGE a b).obj X) (b - 1) := by + dsimp; infer_instance + +section + +variable [IsTriangulated C] + +lemma isIso₁_truncLT_map_of_isGE (T : Triangle C) (hT : T ∈ distTriang C) + (n : ℤ) (h₃ : t.IsGE T.obj₃ n) : + IsIso ((t.truncLT n).map T.mor₁) := by + rw [isIso_truncLT_map_iff] + obtain ⟨Z, g, k, mem⟩ := distinguished_cocone_triangle ((t.truncLTι n).app T.obj₁ ≫ T.mor₁) + refine ⟨_, _, _, mem, ?_⟩ + let H := someOctahedron rfl (t.triangleLTGE_distinguished n T.obj₁) hT mem + exact t.isGE₂ _ H.mem n (by dsimp; infer_instance) (by dsimp; infer_instance) + +lemma isIso₂_truncGE_map_of_isLE (T : Triangle C) (hT : T ∈ distTriang C) + (n₀ n₁ : ℤ) (h : n₀ + 1 = n₁) (h₁ : t.IsLE T.obj₁ n₀) : + IsIso ((t.truncGE n₁).map T.mor₂) := by + rw [isIso_truncGE_map_iff _ _ _ _ h] + obtain ⟨X, f, k, mem⟩ := distinguished_cocone_triangle₁ (T.mor₂ ≫ (t.truncGEπ n₁).app T.obj₃) + refine ⟨_, _, _, mem, ?_⟩ + subst h + have H := someOctahedron rfl (rot_of_distTriang _ hT) + (rot_of_distTriang _ (t.triangleLTGE_distinguished (n₀ + 1) T.obj₃)) + (rot_of_distTriang _ mem) + have : t.IsLE (X⟦(1 : ℤ)⟧) (n₀ - 1) := + t.isLE₂ _ H.mem (n₀ - 1) (t.isLE_shift T.obj₁ n₀ 1 (n₀ - 1) (by lia)) + (t.isLE_shift ((t.truncLT (n₀ + 1)).obj T.obj₃) n₀ 1 (n₀-1) (by lia)) + exact t.isLE_of_shift X n₀ 1 (n₀ - 1) (by lia) + +instance (X : C) (a b : ℤ) [t.IsGE X a] : + t.IsGE ((t.truncLT b).obj X) a := by + rw [t.isGE_iff_isZero_truncLT_obj] + have := t.isIso₁_truncLT_map_of_isGE _ ((t.triangleLTGE_distinguished b X)) a + (by dsimp; infer_instance) + dsimp at this + refine IsZero.of_iso ?_ (asIso ((t.truncLT a).map ((t.truncLTι b).app X))) + rwa [← isGE_iff_isZero_truncLT_obj] + +instance (X : C) (a b : ℤ) [t.IsLE X b] : t.IsLE ((t.truncGE a).obj X) b := by + rw [t.isLE_iff_isZero_truncGE_obj b (b + 1) rfl] + have := t.isIso₂_truncGE_map_of_isLE _ (t.triangleLTGE_distinguished a X) b _ rfl + (by dsimp; infer_instance) + dsimp at this + refine IsZero.of_iso ?_ (asIso ((t.truncGE (b + 1)).map ((t.truncGEπ a).app X))).symm + rwa [← isLE_iff_isZero_truncGE_obj _ _ _ rfl] + +instance (X : C) (a b : ℤ) : + t.IsLE ((t.truncGELT a b).obj X) (b - 1) := by + dsimp; infer_instance + +instance (X : C) (a b : ℤ) : + t.IsGE ((t.truncLTGE a b).obj X) a := by + dsimp; infer_instance + +lemma isIso_truncGE_map_truncGEπ_app (a b : ℤ) (h : b ≤ a) (X : C) : + IsIso ((t.truncGE a).map ((t.truncGEπ b).app X)) := + t.isIso₂_truncGE_map_of_isLE _ (t.triangleLTGE_distinguished b X) + (a - 1) a (by lia) (t.isLE_truncLT_obj _ _ _ (by simpa)) + +lemma isIso_truncLT_map_truncLTι_app (a b : ℤ) (h : a ≤ b) (X : C) : + IsIso ((t.truncLT a).map ((t.truncLTι b).app X)) := + t.isIso₁_truncLT_map_of_isGE _ (t.triangleLTGE_distinguished b X) a + (t.isGE_of_GE ((t.truncGE b).obj X) a b (by lia)) + +instance (X : C) (n : ℤ) : IsIso ((t.truncLT n).map ((t.truncLTι n).app X)) := + isIso_truncLT_map_truncLTι_app t _ _ (by rfl) X + +instance (X : C) (n : ℤ) : IsIso ((t.truncGE n).map ((t.truncGEπ n).app X)) := + t.isIso_truncGE_map_truncGEπ_app _ _ (by rfl) _ + +instance (a b : ℤ) (X : C) : + IsIso ((t.truncLTι b).app ((t.truncGE a).obj ((t.truncLT b).obj X))) := by + rw [← t.isLE_iff_isIso_truncLTι_app (b - 1) b (by lia)] + infer_instance + +/-- The natural transformation `t.truncGELT a b ⟶ t.truncLTGE a b` +(which is an isomorphism, see `truncGELTIsoLTGE`.) -/ +noncomputable def truncGELTToLTGE (a b : ℤ) : + t.truncGELT a b ⟶ t.truncLTGE a b where + app X := t.liftTruncLT (t.descTruncGE + ((t.truncLTι b).app X ≫ (t.truncGEπ a).app X) a) (b - 1) b (by lia) + naturality _ _ _ := + t.to_truncLT_obj_ext (by dsimp; exact t.from_truncGE_obj_ext (by simp)) + +@[reassoc (attr := simp)] +lemma truncGELTToLTGE_app_pentagon (a b : ℤ) (X : C) : + (t.truncGEπ a).app _ ≫ (t.truncGELTToLTGE a b).app X ≫ (t.truncLTι b).app _ = + (t.truncLTι b).app X ≫ (t.truncGEπ a).app X := by + simp [truncGELTToLTGE] + +lemma truncGELTToLTGE_app_pentagon_uniqueness {a b : ℤ} {X : C} + (φ : (t.truncGELT a b).obj X ⟶ (t.truncLTGE a b).obj X) + (hφ : (t.truncGEπ a).app _ ≫ φ ≫ (t.truncLTι b).app _ = + (t.truncLTι b).app X ≫ (t.truncGEπ a).app X) : + (t.truncGELTToLTGE a b).app X = φ := + t.to_truncLT_obj_ext (by dsimp; exact t.from_truncGE_obj_ext (by cat_disch)) + +@[reassoc] +lemma truncLT_map_truncGE_map_truncLTι_app_fac (a b : ℤ) (X : C) : + (t.truncLTι b).app ((t.truncGE a).obj ((t.truncLT b).obj X)) ≫ + (t.truncGELTToLTGE a b).app X = + (t.truncLT b).map ((t.truncGE a).map ((t.truncLTι b).app X)) := by + rw [← cancel_epi (inv ((t.truncLTι b).app ((t.truncGE a).obj ((t.truncLT b).obj X)))), + IsIso.inv_hom_id_assoc] + exact t.truncGELTToLTGE_app_pentagon_uniqueness _ (by simp) + +/-- The connecting homomorphism +`(t.truncGELT a b).obj X ⟶ ((t.truncLT a).obj X)⟦1⟧`, +as a natural transformation. -/ +@[expose, simps!] +noncomputable def truncGELTδLT (a b : ℤ) : + t.truncGELT a b ⟶ t.truncLT a ⋙ shiftFunctor C (1 : ℤ) := + Functor.whiskerLeft (t.truncLT b) (t.truncGEδLT a) ≫ + Functor.whiskerRight (t.truncLTι b) (t.truncLT a ⋙ shiftFunctor C (1 : ℤ)) + +/-- The functorial (distinguished) triangle +`(t.truncLT a).obj X ⟶ (t.truncLT b).obj X ⟶ (t.truncGELT a b).obj X ⟶ ...` +when `a ≤ b`. -/ +@[expose, simps!] +noncomputable def triangleLTLTGELT (a b : ℤ) (h : a ≤ b) : C ⥤ Triangle C := + Triangle.functorMk (t.natTransTruncLTOfLE a b h) + (Functor.whiskerLeft (t.truncLT b) (t.truncGEπ a)) (t.truncGELTδLT a b) + +lemma triangleLTLTGELT_distinguished (a b : ℤ) (h : a ≤ b) (X : C) : + (t.triangleLTLTGELT a b h).obj X ∈ distTriang C := by + have := t.isIso_truncLT_map_truncLTι_app a b h X + refine isomorphic_distinguished _ (t.triangleLTGE_distinguished a ((t.truncLT b).obj X)) _ ?_ + refine Triangle.isoMk _ _ ((asIso ((t.truncLT a).map ((t.truncLTι b).app X))).symm) + (Iso.refl _) (Iso.refl _) ?_ ?_ ?_ + · dsimp + simp only [Category.comp_id, IsIso.eq_inv_comp] + exact t.to_truncLT_obj_ext (by simp) + · simp + · simp + +instance (a b : ℤ) : IsIso (t.truncGELTToLTGE a b) := by + rw [NatTrans.isIso_iff_isIso_app] + intro X + by_cases h : a ≤ b + · let u₁₂ := (t.natTransTruncLTOfLE a b h).app X + let u₂₃ : (t.truncLT b).obj X ⟶ X := (t.truncLTι b).app X + let u₁₃ : _ ⟶ X := (t.truncLTι a).app X + have eq : u₁₂ ≫ u₂₃ = u₁₃ := by simp [u₁₂, u₂₃, u₁₃] + have H := someOctahedron eq (t.triangleLTLTGELT_distinguished a b h X) + (t.triangleLTGE_distinguished b X) (t.triangleLTGE_distinguished a X) + let m₁ : (t.truncGELT a b).obj X ⟶ _ := H.m₁ + have : IsIso ((t.truncLT b).map H.m₁) := + t.isIso₁_truncLT_map_of_isGE _ H.mem b (by dsimp; infer_instance) + have eq' : t.liftTruncLT m₁ (b - 1) b (by lia) = (t.truncGELTToLTGE a b).app X := + t.to_truncLT_obj_ext + (by dsimp; exact t.from_truncGE_obj_ext (by simpa using H.comm₁)) + rw [← eq'] + have fac : (t.truncLTι b).app ((t.truncGE a).obj ((t.truncLT b).obj X)) ≫ + t.liftTruncLT m₁ (b - 1) b (by lia) = (t.truncLT b).map m₁ := + t.to_truncLT_obj_ext (by simp [truncGELT]) + exact IsIso.of_isIso_fac_left fac + · simp at h + refine ⟨0, ?_, ?_⟩ + all_goals exact IsZero.eq_of_src (t.isZero _ (b-1) a (by lia)) _ _ + +instance (a b : ℤ) (X : C) : + IsIso ((t.truncLT b).map ((t.truncGE a).map ((t.truncLTι b).app X))) := by + rw [← t.truncLT_map_truncGE_map_truncLTι_app_fac a b X] + infer_instance + +/-- The natural transformation `t.truncGELT a b ≅ t.truncLTGE a b`. -/ +noncomputable def truncGELTIsoLTGE (a b : ℤ) : t.truncGELT a b ≅ t.truncLTGE a b := + asIso (t.truncGELTToLTGE a b) + +end + end end TStructure diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean new file mode 100644 index 00000000000000..7397e3be68f3c2 --- /dev/null +++ b/Mathlib/Data/EInt/Basic.lean @@ -0,0 +1,93 @@ +/- +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, Kevin Buzzard +-/ +module + +public import Mathlib.Order.WithBot + +/-! +# The extended integers + +This file defines `EInt`, `ℤ` with a top element `⊤` and a bottom element `⊥`, +implemented as `WithBot (WithTop ℤ)`. + +-/ + +@[expose] public section + +/-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ +def EInt := WithBot (WithTop ℤ) + +/-- The canonical inclusion from integers to e-integers. Registered as a coercion. -/ +@[coe] def Int.toEInt : ℤ → EInt := WithBot.some ∘ WithTop.some + +namespace EInt + +instance : LinearOrder EInt := inferInstanceAs (LinearOrder (WithBot (WithTop ℤ))) + +instance : OrderBot EInt := inferInstanceAs (OrderBot (WithBot (WithTop ℤ))) + +instance : OrderTop EInt := inferInstanceAs (OrderTop (WithBot (WithTop ℤ))) + +instance : Coe ℤ EInt := ⟨Int.toEInt⟩ + +theorem coe_strictMono : StrictMono Int.toEInt := + WithBot.coe_strictMono.comp WithTop.coe_strictMono + +theorem coe_injective : Function.Injective Int.toEInt := + coe_strictMono.injective + +lemma coe_monotone : Monotone Int.toEInt := coe_strictMono.monotone + +/-- The constructor `ℤ → EInt`. -/ +abbrev mk (a : ℤ) : EInt := a + +section + +variable {motive : EInt → Sort*} + (bot : motive ⊥) (coe : ∀ a : ℤ, motive a) (top : motive ⊤) + +/-- A recursor for `EInt` in terms of the coercion. -/ +@[elab_as_elim, induction_eliminator, cases_eliminator] +protected def rec : ∀ a : EInt, motive a + | ⊥ => bot + | (a : ℤ) => coe a + | ⊤ => top + +@[simp] lemma rec_bot : EInt.rec (motive := motive) bot coe top ⊥ = bot := rfl +@[simp] lemma rec_coe (a : ℤ) : EInt.rec (motive := motive) bot coe top a = coe a := rfl +@[simp] lemma rec_top : EInt.rec (motive := motive) bot coe top ⊤ = top := rfl + +end + +@[simp] +lemma coe_le_coe_iff (a b : ℤ) : + mk a ≤ mk b ↔ a ≤ b := + coe_strictMono.le_iff_le + +@[simp] +lemma coe_lt_coe_iff (a b : ℤ) : + mk a < mk b ↔ a < b := + coe_strictMono.lt_iff_lt + +@[simp] +lemma coe_eq_bot_iff (a : ℤ) : + EInt.mk a = ⊥ ↔ False := by + simp only [iff_false] + rintro ⟨⟩ + +@[simp] +lemma coe_eq_top_iff (a : ℤ) : + EInt.mk a = ⊤ ↔ False := by + simp only [iff_false] + rintro ⟨⟩ + +@[simp] +lemma top_eq_bot_iff : + (⊤ : EInt) = ⊥ ↔ False := by + simp only [iff_false] + exact ne_of_beq_false rfl + +end EInt From d216f15d814ebc5d185e151bcfead6bdf872ab49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 11 Jan 2026 18:48:48 +0100 Subject: [PATCH 02/72] cleaning up --- .../Algebra/Homology/ExactSequenceFour.lean | 51 +++++++++---------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/Mathlib/Algebra/Homology/ExactSequenceFour.lean b/Mathlib/Algebra/Homology/ExactSequenceFour.lean index d8cc3d2c0f89db..f26a745eba5c34 100644 --- a/Mathlib/Algebra/Homology/ExactSequenceFour.lean +++ b/Mathlib/Algebra/Homology/ExactSequenceFour.lean @@ -10,6 +10,11 @@ public import Mathlib.Algebra.Homology.ExactSequence /-! # Exact sequences with four terms +The main definition in this file is `ComposableArrows.Exact.cokerIsoKer`: +given an exact sequence `S` (involving at least four objects), +this is the isomorphism from the cokernel of `S.map' k (k + 1)` +to the kernel of `S.map' (k + 2) (k + 3)`. + -/ @[expose] public section @@ -29,9 +34,10 @@ variable {C : Type*} [Category C] [HasZeroMorphisms C] {n : ℕ} {S : Composable section -/-- Generalization of `cokerToKer`. -/ +/-- If `S` is a complex, this is the morphism from a cokernel of `S.map' k (k + 1)` +to a kernel of `S.map' (k + 2) (k + 3)`. -/ def cokerToKer' (hk : k ≤ n) (cc : CokernelCofork (S.map' k (k + 1))) - (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) : + (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) : cc.pt ⟶ kf.pt := IsColimit.desc hcc (CokernelCofork.ofπ _ (show S.map' k (k + 1) ≫ IsLimit.lift hkf (KernelFork.ofι _ (hS.zero (k + 1))) = _ from @@ -39,7 +45,7 @@ def cokerToKer' (hk : k ≤ n) (cc : CokernelCofork (S.map' k (k + 1))) @[reassoc (attr := simp)] lemma cokerToKer'_fac (hk : k ≤ n) (cc : CokernelCofork (S.map' k (k + 1))) - (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) : + (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) : cc.π ≫ hS.cokerToKer' k hk cc kf hcc hkf ≫ kf.ι = S.map' (k + 1) (k + 2) := by simp [cokerToKer'] @@ -48,6 +54,8 @@ end section +/-- If `S` is a complex, this is the morphism from the cokernel of `S.map' k (k + 1)` +to the kernel of `S.map' (k + 2) (k + 3)`. -/ noncomputable def cokerToKer (hk : k ≤ n := by lia) [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : cokernel (S.map' k (k + 1)) ⟶ kernel (S.map' (k + 2) (k + 3)) := @@ -64,6 +72,8 @@ end section +/-- If `S` is a complex, this is the morphism from the opcycles of `S` in +degree `k + 1` to the cycles of `S` in degree `k + 2`. -/ noncomputable def opcyclesToCycles (hk : k ≤ n := by lia) [(S.sc hS k).HasRightHomology] [(S.sc hS (k + 1)).HasLeftHomology] : (S.sc hS k _).opcycles ⟶ (S.sc hS (k + 1) _).cycles := @@ -94,7 +104,6 @@ variable (hS : S.IsComplex) (k : ℕ) (hk : k ≤ n) (cc : CokernelCofork (S.map' k (k + 1))) (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) -/-- `cokerToKer'` is an epi. -/ lemma epi_cokerToKer' (hS' : (S.sc hS (k + 1)).Exact) : Epi (hS.cokerToKer' k hk cc kf hcc hkf) := by have := hS'.hasZeroObject @@ -107,7 +116,6 @@ lemma epi_cokerToKer' (hS' : (S.sc hS (k + 1)).Exact) : assoc, IsComplex.cokerToKer'_fac] exact epi_of_epi_fac fac -/-- `cokerToKer'` is a mono. -/ lemma mono_cokerToKer' (hS' : (S.sc hS k).Exact) : Mono (hS.cokerToKer' k hk cc kf hcc hkf) := by have := hS'.hasZeroObject @@ -137,17 +145,11 @@ variable (k : ℕ) (hk : k ≤ n) (cc : CokernelCofork (S.map' k (k + 1))) (kf : KernelFork (S.map' (k + 2) (k + 3))) (hcc : IsColimit cc) (hkf : IsLimit kf) -/-- Auxiliary definition for `cokerIsoKer'`. -/ -def cokerToKer' : cc.pt ⟶ kf.pt := +/-- If `S` is an exact sequence, this is the morphism from a cokernel +of `S.map' k (k + 1)` to a kernel of `S.map' (k + 2) (k + 3)`. -/ +abbrev cokerToKer' : cc.pt ⟶ kf.pt := hS.toIsComplex.cokerToKer' k hk cc kf hcc hkf -omit [Balanced C] in -@[reassoc (attr := simp)] -lemma cokerToKer'_fac : cc.π ≫ hS.cokerToKer' k hk cc kf hcc hkf ≫ kf.ι = - S.map' (k + 1) (k + 2) := by - simp [cokerToKer'] - -/-- `cokerToKer'` is an isomorphism. -/ instance isIso_cokerToKer' : IsIso (hS.cokerToKer' k hk cc kf hcc hkf) := by have : Mono (hS.cokerToKer' k hk cc kf hcc hkf) := hS.toIsComplex.mono_cokerToKer' k hk cc kf hcc hkf @@ -156,7 +158,8 @@ instance isIso_cokerToKer' : IsIso (hS.cokerToKer' k hk cc kf hcc hkf) := by hS.epi_cokerToKer' k hk cc kf hcc hkf (hS.exact (k + 1)) apply isIso_of_mono_of_epi -/-- Auxiliary definition for `cokerIsoKer`. -/ +/-- If `S` is an exact sequence, this is the isomorphism from a cokernel +of `S.map' k (k + 1)` to a kernel of `S.map' (k + 2) (k + 3)`. -/ @[simps! hom] noncomputable def cokerIsoKer' : cc.pt ≅ kf.pt := asIso (hS.cokerToKer' k hk cc kf hcc hkf) @@ -175,35 +178,31 @@ end section +/-- If `S` is an exact sequence, this is the isomorphism from the cokernel +of `S.map' k (k + 1)` to the kernel of `S.map' (k + 2) (k + 3)`. -/ noncomputable def cokerIsoKer (k : ℕ) (hk : k ≤ n := by lia) [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : cokernel (S.map' k (k + 1) _ _) ≅ kernel (S.map' (k + 2) (k + 3) _ _) := hS.cokerIsoKer' k hk (CokernelCofork.ofπ _ (cokernel.condition _)) (KernelFork.ofι _ (kernel.condition _)) (cokernelIsCokernel _) (kernelIsKernel _) -lemma cokerIsoKer_hom (k : ℕ) (hk : k ≤ n := by lia) - [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : - (hS.cokerIsoKer k).hom = hS.toIsComplex.cokerToKer k := rfl - @[reassoc (attr := simp)] lemma cokerIsoKer_hom_fac (k : ℕ) (hk : k ≤ n := by lia) [HasCokernel (S.map' k (k + 1))] [HasKernel (S.map' (k + 2) (k + 3))] : - cokernel.π _ ≫ (hS.cokerIsoKer k).hom ≫ kernel.ι _ = S.map' (k + 1) (k + 2) := by - rw [hS.cokerIsoKer_hom k, hS.toIsComplex.cokerToKer_fac k] + cokernel.π _ ≫ (hS.cokerIsoKer k).hom ≫ kernel.ι _ = S.map' (k + 1) (k + 2) := + hS.toIsComplex.cokerToKer_fac k end section +/-- If `S` is an exact sequence, this is the isomorphism from the opcycles of `S` in +degree `k + 1` to the cycles of `S` in degree `k + 2`. -/ noncomputable def opcyclesIsoCycles (k : ℕ) (hk : k ≤ n := by lia) - [h₁ : (hS.sc k).HasRightHomology] [h₂ : (hS.sc (k + 1)).HasLeftHomology] : + [h₁ : (hS.sc k).HasRightHomology] [h₂ : (hS.sc (k + 1)).HasLeftHomology] : (hS.sc k _).opcycles ≅ (hS.sc (k + 1) _).cycles := hS.cokerIsoKer' k hk _ _ (hS.sc k _).opcyclesIsCokernel (hS.sc (k + 1) _).cyclesIsKernel -lemma opcyclesIsoCycles_hom (k : ℕ) (hk : k ≤ n := by lia) - [h₁ : (hS.sc k).HasRightHomology] [h₂ : (hS.sc (k + 1)).HasLeftHomology] : - (hS.opcyclesIsoCycles k).hom = hS.toIsComplex.opcyclesToCycles k hk := rfl - @[reassoc (attr := simp)] lemma opcyclesIsoCycles_hom_fac (k : ℕ) (hk : k ≤ n := by lia) [h₁ : (hS.sc k).HasRightHomology] [h₂ : (hS.sc (k + 1)).HasLeftHomology] : From 3317a3be70c750ec2a3f8a5f6c5010e7cae3c4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 11 Jan 2026 18:56:40 +0100 Subject: [PATCH 03/72] cleaning up --- .../Algebra/Homology/ShortComplex/Exact.lean | 4 ++- .../ComposableArrows/Basic.lean | 30 ------------------- 2 files changed, 3 insertions(+), 31 deletions(-) diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index 51011f447ee4a6..3c2978ff386558 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -833,10 +833,12 @@ section variable {X Y : C} (f : X ⟶ Y) +/-- The exact short complex `kernel f ⟶ X ⟶ Y` for any morphism `f : X ⟶ Y`. -/ @[simps] noncomputable def kernelSequence : ShortComplex C := ShortComplex.mk _ _ (kernel.condition f) +/-- The exact short complex `X ⟶ Y ⟶ cokernel f` for any morphism `f : X ⟶ Y`. -/ @[simps] noncomputable def cokernelSequence : ShortComplex C := ShortComplex.mk _ _ (cokernel.condition f) @@ -992,5 +994,5 @@ noncomputable def ofExactOfRetraction (S : ShortComplex C) (hS : S.Exact) (r : S end Splitting end ShortComplex - +#lint end CategoryTheory diff --git a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean index db8be175cf7008..ccf6b34316a1c4 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean @@ -961,36 +961,6 @@ def Functor.mapComposableArrowsObjMk₂Iso {X Y Z : C} (f : X ⟶ Y) (g : Y ⟶ (G.mapComposableArrows 2).obj (.mk₂ f g) ≅ .mk₂ (G.map f) (G.map g) := isoMk₂ (Iso.refl _) (Iso.refl _) (Iso.refl _) -@[simps] -def composableArrows₀Equivalence : ComposableArrows C 0 ≌ C where - functor := - { obj := fun f => f.obj' 0 - map := fun f => ComposableArrows.app' f 0 } - inverse := - { obj := fun X => ComposableArrows.mk₀ X - map := fun f => ComposableArrows.homMk₀ f } - unitIso := NatIso.ofComponents (fun X => ComposableArrows.isoMk₀ (Iso.refl _)) - (by aesop_cat) - counitIso := Iso.refl _ - -set_option maxHeartbeats 600000 in --- this is a slow proof -@[simps] -def composableArrows₁Equivalence : ComposableArrows C 1 ≌ Arrow C where - functor := - { obj := fun F => Arrow.mk (F.map' 0 1) - map := fun {F G} f => - { left := ComposableArrows.app' f 0 - right := ComposableArrows.app' f 1 - w := (f.naturality _).symm } } - inverse := - { obj := fun f => ComposableArrows.mk₁ f.hom - map := fun {f g} φ => ComposableArrows.homMk₁ φ.left φ.right φ.w.symm } - unitIso := NatIso.ofComponents - (fun f => ComposableArrows.isoMk₁ (Iso.refl _) (Iso.refl _) (by aesop_cat)) - (by aesop_cat) - counitIso := Iso.refl _ - suppress_compilation in /-- The functor `ComposableArrows C n ⥤ ComposableArrows D n` induced by `G : C ⥤ D` commutes with `opEquivalence`. -/ From 07cdf386ebb494203a9bba60c7e5e2dce1c08e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 11 Jan 2026 19:04:33 +0100 Subject: [PATCH 04/72] fix --- .../Algebra/Homology/ShortComplex/Exact.lean | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index 3c2978ff386558..88a29f84d85a49 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -236,15 +236,15 @@ lemma exact_map_iff_of_faithful [S.HasHomology] (F : C ⥤ D) [F.PreservesZeroMorphisms] [F.PreservesLeftHomologyOf S] [F.PreservesRightHomologyOf S] [F.Faithful] : (S.map F).Exact ↔ S.Exact := by - constructor - · intro h - rw [S.leftHomologyData.exact_iff, IsZero.iff_id_eq_zero] - rw [(S.leftHomologyData.map F).exact_iff, IsZero.iff_id_eq_zero, - LeftHomologyData.map_H] at h - apply F.map_injective - rw [F.map_id, F.map_zero, h] - · intro h - exact h.map F + constructor + · intro h + rw [S.leftHomologyData.exact_iff, IsZero.iff_id_eq_zero] + rw [(S.leftHomologyData.map F).exact_iff, IsZero.iff_id_eq_zero, + LeftHomologyData.map_H] at h + apply F.map_injective + rw [F.map_id, F.map_zero, h] + · intro h + exact h.map F variable {S} From 4e378d036d8e5f5d8f6aee6402c130bf8e77307f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 11 Jan 2026 19:04:55 +0100 Subject: [PATCH 05/72] fix --- Mathlib/Algebra/Homology/ShortComplex/Exact.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index 88a29f84d85a49..38285d78155ea9 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -994,5 +994,5 @@ noncomputable def ofExactOfRetraction (S : ShortComplex C) (hS : S.Exact) (r : S end Splitting end ShortComplex -#lint + end CategoryTheory From eca7e8737a171d5728f04ad79b89eaab53d6374b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 07:56:20 +0100 Subject: [PATCH 06/72] cleaning up --- Mathlib/CategoryTheory/ComposableArrows/Basic.lean | 8 ++++---- Mathlib/CategoryTheory/ComposableArrows/Four.lean | 12 ++++++++++++ Mathlib/CategoryTheory/ComposableArrows/Three.lean | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean index ccf6b34316a1c4..9fdd0f4f1ef76c 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean @@ -408,23 +408,23 @@ def precomp {X : C} (f : X ⟶ F.left) : ComposableArrows C (n + 1) where map_comp g g' := Precomp.map_comp F f (leOfHom g) (leOfHom g') /-- Constructor for `ComposableArrows C 2`. -/ -@[reducible] +@[simp] def mk₂ {X₀ X₁ X₂ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) : ComposableArrows C 2 := (mk₁ g).precomp f /-- Constructor for `ComposableArrows C 3`. -/ -@[reducible] +@[simp] def mk₃ {X₀ X₁ X₂ X₃ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) : ComposableArrows C 3 := (mk₂ g h).precomp f /-- Constructor for `ComposableArrows C 4`. -/ -@[reducible] +@[simp] def mk₄ {X₀ X₁ X₂ X₃ X₄ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) : ComposableArrows C 4 := (mk₃ g h i).precomp f /-- Constructor for `ComposableArrows C 5`. -/ -@[reducible] +@[simp] def mk₅ {X₀ X₁ X₂ X₃ X₄ X₅ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) (j : X₄ ⟶ X₅) : ComposableArrows C 5 := diff --git a/Mathlib/CategoryTheory/ComposableArrows/Four.lean b/Mathlib/CategoryTheory/ComposableArrows/Four.lean index f7dd4c26bd9f2c..99e0a7d2666f0e 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Four.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Four.lean @@ -10,6 +10,18 @@ public import Mathlib.CategoryTheory.ComposableArrows.Basic /-! # API for compositions of four arrows +Given morphisms `f₁ : i₀ ⟶ i₁`, `f₂ : i₁ ⟶ i₂`, `f₃ : i₂ ⟶ i₃`, `f₄ : i₃ ⟶ i₄`, +and their compositions `f₁₂ : i₀ ⟶ i₂`, `f₂₃ : i₁ ⟶ i₃` and `f₃₄ : i₂ ⟶ i₄`, +we define maps `ComposableArrows.fourδ₄Toδ₃ : mk₃ f₁ f₂ f₃ ⟶ mk₂ f₁ f₂ f₃₄`, +`fourδ₃Toδ₂ : mk₃ f₁ f₂ f₃₄ ⟶ mk₂ f₁ f₂₃ f₄`, +`fourδ₂Toδ₁ : mk₃ f₁ f₂₃ f₄ ⟶ mk₂ f₁₂ f₃ f₄`, and +`fourδ₁Toδ₀ : mk₃ f₁₂ f₃ f₄ ⟶ mk₂ f₂ f₃ f₄`. +The names are justified by the fact that `ComposableArrow.mk₄ f₁ f₂ f₃ f₄` +can be thought of as a `4`-simplex in the simplicial set `nerve C`, +and its faces (numbered from `0` to `4`) are respectively +`mk₂ f₂ f₃ f₄`, `mk₂ f₁₂ f₃ f₄`, `mk₂ f₁ f₂₃ f₄`, `mk₂ f₁ f₂ f₃₄` and +`mk₂ f₁ f₂ f₃`. + -/ @[expose] public section diff --git a/Mathlib/CategoryTheory/ComposableArrows/Three.lean b/Mathlib/CategoryTheory/ComposableArrows/Three.lean index 48a202eff0a715..c130d5051a1f24 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Three.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Three.lean @@ -12,7 +12,7 @@ public import Mathlib.CategoryTheory.ComposableArrows.Basic Given morphisms `f₁ : i ⟶ j`, `f₂ : j ⟶ k`, `f₃ : k ⟶ l`, and their compositions `f₁₂ : i ⟶ k` and `f₂₃ : j ⟶ l`, we define -maps `ComposableArrowsthreeδ₃Toδ₂ : mk₂ f₁ f₂ ⟶ mk₂ f₁ f₂₃` +maps `ComposableArrows.threeδ₃Toδ₂ : mk₂ f₁ f₂ ⟶ mk₂ f₁ f₂₃`, `threeδ₂Toδ₁ : mk₂ f₁ f₂₃ ⟶ mk₂ f₁₂ f₃`, and `threeδ₁Toδ₀ : mk₂ f₁₂ f₃ ⟶ mk₂ f₂ f₃`. The names are justified by the fact that `ComposableArrow.mk₃ f₁ f₂ f₃` can be thought of as a `3`-simplex in the simplicial set `nerve C`, From 6f0b12eb504d3988bb76a6f920e72ffbfac67071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 08:35:20 +0100 Subject: [PATCH 07/72] cleaning up --- .../Limits/Shapes/ZeroObjects.lean | 8 ++ Mathlib/CategoryTheory/NatIso.lean | 11 ++ .../ObjectProperty/ContainsZero.lean | 13 --- Mathlib/CategoryTheory/Shift/CommShift.lean | 105 ++++++------------ .../CategoryTheory/Triangulated/Basic.lean | 11 +- .../CategoryTheory/Triangulated/Functor.lean | 5 - .../Triangulated/Subcategory.lean | 2 +- 7 files changed, 60 insertions(+), 95 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/ZeroObjects.lean b/Mathlib/CategoryTheory/Limits/Shapes/ZeroObjects.lean index 81e00ed16f3287..cc930a1388abfb 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/ZeroObjects.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/ZeroObjects.lean @@ -215,6 +215,14 @@ theorem IsZero.obj [HasZeroObject D] {F : C ⥤ D} (hF : IsZero F) (X : C) : IsZ let e : F ≅ G := hF.iso hG exact (isZero_zero _).of_iso (e.app X) +lemma IsZero.of_full_of_faithful_of_isZero + (F : C ⥤ D) [F.Full] [F.Faithful] (X : C) (hX : IsZero (F.obj X)) : + IsZero X := by + have h : F.FullyFaithful := .ofFullyFaithful _ + have (Y : C) := (hX.unique_to (F.obj Y)).some + have (Y : C) := (hX.unique_from (F.obj Y)).some + exact ⟨fun Y ↦ ⟨h.homEquiv.unique⟩, fun Y ↦ ⟨h.homEquiv.unique⟩⟩ + namespace HasZeroObject variable [HasZeroObject C] diff --git a/Mathlib/CategoryTheory/NatIso.lean b/Mathlib/CategoryTheory/NatIso.lean index 4d40fb07c91167..4cb3212c8d0995 100644 --- a/Mathlib/CategoryTheory/NatIso.lean +++ b/Mathlib/CategoryTheory/NatIso.lean @@ -248,4 +248,15 @@ def isoCopyObj : F ≅ F.copyObj obj e := end Functor +@[reassoc] +lemma NatTrans.naturality_1 {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (e : X ≅ Y) : + F.map e.inv ≫ α.app X ≫ G.map e.hom = α.app Y := by + simp + +@[reassoc] +lemma NatTrans.naturality_2 {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (e : X ≅ Y) : + F.map e.hom ≫ α.app Y ≫ G.map e.inv = α.app X := by + simp + + end CategoryTheory diff --git a/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean b/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean index 260d07c05075dc..d0f3b03b95b6c6 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/ContainsZero.lean @@ -30,19 +30,6 @@ open Limits ZeroObject Opposite variable {C : Type u} [Category.{v} C] {D : Type u'} [Category.{v'} D] --- to be moved -lemma IsZero.of_full_of_faithful_of_isZero - (F : C ⥤ D) [F.Full] [F.Faithful] (X : C) (hX : IsZero (F.obj X)) : - IsZero X := by - have h : F.FullyFaithful := .ofFullyFaithful _ - constructor - · intro Y - have := (hX.unique_to (F.obj Y)).some - exact ⟨h.homEquiv.unique⟩ - · intro Y - have := (hX.unique_from (F.obj Y)).some - exact ⟨h.homEquiv.unique⟩ - namespace ObjectProperty variable (P Q : ObjectProperty C) diff --git a/Mathlib/CategoryTheory/Shift/CommShift.lean b/Mathlib/CategoryTheory/Shift/CommShift.lean index d49ee051a85794..c6c9733641514c 100644 --- a/Mathlib/CategoryTheory/Shift/CommShift.lean +++ b/Mathlib/CategoryTheory/Shift/CommShift.lean @@ -6,6 +6,7 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.Shift.Basic +public import Mathlib.CategoryTheory.NatIso /-! # Functors which commute with shifts @@ -31,31 +32,8 @@ shift functors.) namespace CategoryTheory --- to be moved -@[reassoc] -lemma NatTrans.naturality_1 {C D : Type*} [Category C] [Category D] - {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (e : X ≅ Y) : - F.map e.inv ≫ α.app X ≫ G.map e.hom = α.app Y := by - simp - --- to be moved -@[reassoc] -lemma NatTrans.naturality_2 {C D : Type*} [Category C] [Category D] - {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (e : X ≅ Y) : - F.map e.hom ≫ α.app Y ≫ G.map e.inv = α.app X := by - simp - open Category -instance {C D E : Type*} [Category C] [Category D] [Category E] (G : D ⥤ E) - [G.Full] [G.Faithful] : ((Functor.whiskeringRight C D E).obj G).Full where - map_surjective τ := ⟨ - { app := fun X => G.preimage (τ.app X) - naturality := fun X Y f => by - apply G.map_injective - simpa only [Functor.whiskeringRight_obj_obj, Functor.map_comp, Functor.map_preimage] - using τ.naturality f }, by aesop_cat⟩ - namespace Functor variable {C D E : Type*} [Category* C] [Category* D] [Category* E] @@ -240,20 +218,6 @@ instance comp [F.CommShift A] [G.CommShift A] : (F ⋙ G).CommShift A where simp only [comp_id, id_comp, assoc, ← Functor.map_comp_assoc, Iso.inv_hom_id_app, comp_obj] simp only [map_comp, assoc, commShiftIso_hom_naturality_assoc] -variable {F G} - -@[simp] -lemma commShiftIso_id_hom_app (a : A) (X : C) : - ((𝟭 C).commShiftIso a).hom.app X = 𝟙 _ := by - dsimp [commShiftIso] - rw [id_comp] - -@[simp] -lemma commShiftIso_id_inv_app (a : A) (X : C) : - ((𝟭 C).commShiftIso a).inv.app X = 𝟙 _ := by - dsimp [commShiftIso] - rw [id_comp] - end CommShift alias commShiftIso_id_hom_app := CommShift.id_commShiftIso_hom_app @@ -319,6 +283,10 @@ variable {C D E J : Type*} [Category* C] [Category* D] [Category* E] [Category* [G.CommShift A] [G'.CommShift A] [H.CommShift A] variable {A} in +/-- Auxiliary structure for `NatTrans.CommShift` when we need to +show a compatibility of a natural transformation `τ : F₁ ⟶ F₂` with +respect to the shift by a specific element `a`. See also +`NatTrans.CommShift.of_core` -/ structure CommShiftCore (a : A) : Prop where shift_comm : (F₁.commShiftIso a).hom ≫ Functor.whiskerRight τ _ = Functor.whiskerLeft _ τ ≫ (F₂.commShiftIso a).hom @@ -504,69 +472,64 @@ end Functor namespace Functor +variable {C D E : Type*} [Category* C] [Category* D] [Category* E] {A : Type*} + section hasShiftOfFullyFaithful -variable {C D : Type _} [Category C] [Category D] - {A : Type _} [AddMonoid A] [HasShift D A] +variable [AddMonoid A] [HasShift D A] {F : C ⥤ D} (hF : F.FullyFaithful) (s : A → C ⥤ C) (i : ∀ i, s i ⋙ F ≅ F ⋙ shiftFunctor D i) namespace CommShift -def of_hasShiftOfFullyFaithful : +/-- If `F : C ⥤ D` is a fully faithful functor which is used +to construct a shift by `A` on `C` from a shift on `D`, +then the functor `F` itself commutes with the shift by `A`. -/ +def ofHasShiftOfFullyFaithful : letI := hF.hasShift s i; F.CommShift A := by letI := hF.hasShift s i exact { commShiftIso := i commShiftIso_zero := by ext X - simp only [comp_obj, isoZero_hom_app, ShiftMkCore.shiftFunctorZero_eq, - FullyFaithful.hasShift.map_zero_hom_app, id_obj, Category.assoc, - Iso.hom_inv_id_app, Category.comp_id] + simp [ShiftMkCore.shiftFunctorZero_eq] commShiftIso_add := fun a b => by ext X - simp only [comp_obj, isoAdd_hom_app, ShiftMkCore.shiftFunctorAdd_eq, - FullyFaithful.hasShift.map_add_hom_app, Category.assoc, ShiftMkCore.shiftFunctor_eq, - Iso.inv_hom_id_app_assoc, ← (shiftFunctor D b).map_comp_assoc, Iso.inv_hom_id_app, - Functor.map_id, Category.id_comp, Iso.hom_inv_id_app, Category.comp_id] } + simp [ShiftMkCore.shiftFunctorAdd_eq, ShiftMkCore.shiftFunctor_eq, + ← Functor.map_comp_assoc] } end CommShift -lemma shiftFunctorIso_of_hasShiftOfFullyFaithful (a : A) : +lemma shiftFunctorIso_ofHasShiftOfFullyFaithful (a : A) : letI := hF.hasShift s i; - letI := CommShift.of_hasShiftOfFullyFaithful hF s i; + letI := CommShift.ofHasShiftOfFullyFaithful hF s i; F.commShiftIso a = i a := by rfl end hasShiftOfFullyFaithful -lemma map_shiftFunctorComm {C D : Type _} [Category C] [Category D] {A : Type _} [AddCommMonoid A] - [HasShift C A] [HasShift D A] (F : C ⥤ D) [F.CommShift A] (X : C) (a b : A) : +lemma map_shiftFunctorComm + [AddCommMonoid A] [HasShift C A] [HasShift D A] + (F : C ⥤ D) [F.CommShift A] (X : C) (a b : A) : F.map ((shiftFunctorComm C a b).hom.app X) = (F.commShiftIso b).hom.app (X⟦a⟧) ≫ ((F.commShiftIso a).hom.app X)⟦b⟧' ≫ (shiftFunctorComm D a b).hom.app (F.obj X) ≫ ((F.commShiftIso b).inv.app X)⟦a⟧' ≫ (F.commShiftIso a).inv.app (X⟦b⟧) := by - have eq := NatTrans.congr_app (congr_arg Iso.hom (F.commShiftIso_add a b)) X + have := NatTrans.congr_app (congr_arg Iso.hom (F.commShiftIso_add a b)) X simp only [comp_obj, CommShift.isoAdd_hom_app, ← cancel_epi (F.map ((shiftFunctorAdd C a b).inv.app X)), - ← F.map_comp_assoc, Iso.inv_hom_id_app, F.map_id, Category.id_comp] at eq + ← F.map_comp_assoc, Iso.inv_hom_id_app, F.map_id, Category.id_comp] at this simp only [shiftFunctorComm_eq D a b _ rfl] dsimp simp only [shiftFunctorAdd'_eq_shiftFunctorAdd, Category.assoc, - ← reassoc_of% eq, - shiftFunctorComm_eq C a b _ rfl] + ← reassoc_of% this, shiftFunctorComm_eq C a b _ rfl] dsimp rw [Functor.map_comp] - congr 1 - simp only [NatTrans.congr_app (congr_arg Iso.hom (F.commShiftIso_add' (add_comm b a))) X, - CommShift.isoAdd'_hom_app, Category.assoc, Iso.inv_hom_id_app_assoc, - ← Functor.map_comp_assoc, Iso.hom_inv_id_app] - dsimp - simp only [Functor.map_id, Category.id_comp, Iso.hom_inv_id_app, comp_obj, Category.comp_id] + simp [NatTrans.congr_app (congr_arg Iso.hom (F.commShiftIso_add' (add_comm b a))) X, + ← Functor.map_comp_assoc] namespace CommShift -variable {C D E : Type*} [Category C] [Category D] [Category E] - {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} (e : F ⋙ G ≅ H) +variable {F : C ⥤ D} {G : D ⥤ E} {H : C ⥤ E} (e : F ⋙ G ≅ H) [Full G] [Faithful G] (A : Type*) [AddMonoid A] [HasShift C A] [HasShift D A] [HasShift E A] [G.CommShift A] [H.CommShift A] @@ -575,6 +538,7 @@ namespace OfComp variable {A} +/-- Auxiliary definition for `Functor.CommShift.ofComp`. -/ noncomputable def iso (a : A) : shiftFunctor C a ⋙ F ≅ F ⋙ shiftFunctor D a := ((whiskeringRight C D E).obj G).preimageIso (Functor.associator _ _ _ ≪≫ isoWhiskerLeft _ e ≪≫ @@ -603,6 +567,8 @@ attribute [irreducible] iso end OfComp +/-- Given an isomorphism `e : F ⋙ G ≅ H` where `G` is fully faithful, +the functor `F` commutes with shifts by `A` if `G` and `H` do. -/ noncomputable def ofComp : F.CommShift A where commShiftIso := OfComp.iso e commShiftIso_zero := by @@ -615,9 +581,8 @@ noncomputable def ofComp : F.CommShift A where simp only [comp_obj, OfComp.map_iso_hom_app, H.commShiftIso_add, isoAdd_hom_app, G.commShiftIso_add, isoAdd_inv_app, NatTrans.naturality_assoc, comp_map, assoc, Iso.inv_hom_id_app_assoc, map_comp] - erw [← NatTrans.naturality_assoc, ← NatTrans.naturality_assoc] - dsimp - simp only [← Functor.map_comp_assoc] + simp only [← NatTrans.naturality_assoc, ← commShiftIso_inv_naturality_assoc, + ← Functor.map_comp_assoc] congr 4 simp @@ -625,12 +590,10 @@ lemma ofComp_compatibility : letI := ofComp e NatTrans.CommShift e.hom A := by letI := ofComp e - refine ⟨fun a => ?_⟩ + refine ⟨fun a ↦ ?_⟩ ext X - have : commShiftIso F a = OfComp.iso e a := rfl - simp only [comp_obj, NatTrans.comp_app, commShiftIso_comp_hom_app, this, - OfComp.map_iso_hom_app, assoc, Iso.inv_hom_id_app, comp_id, whiskerRight_app, - whiskerLeft_app, ← Functor.map_comp, Functor.map_id] + simp [commShiftIso_comp_hom_app, show F.commShiftIso a = OfComp.iso e a from rfl, + ← Functor.map_comp] end CommShift diff --git a/Mathlib/CategoryTheory/Triangulated/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Basic.lean index bacfb60791f8a7..1e0baf28d54f67 100644 --- a/Mathlib/CategoryTheory/Triangulated/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Basic.lean @@ -331,10 +331,14 @@ def binaryBiproductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryBipro Triangle C := Triangle.mk biprod.inl (Limits.biprod.snd : X₁ ⊞ X₂ ⟶ _) 0 +/-- The obvious triangle `X₁ ⟶ X₁ ⨯ X₂ ⟶ X₂ ⟶ X₁⟦1⟧`. -/ @[simps!] -def binaryProductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryProduct X₁ X₂] : Triangle C := +def binaryProductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryProduct X₁ X₂] : + Triangle C := Triangle.mk ((Limits.prod.lift (𝟙 X₁) 0)) (Limits.prod.snd : X₁ ⨯ X₂ ⟶ _) 0 +/-- The canonical isomorphism of triangles +`binaryProductTriangle X₁ X₂ ≅ binaryBiproductTriangle X₁ X₂`. -/ @[simps!] def binaryProductTriangleIsoBinaryBiproductTriangle (X₁ X₂ : C) [HasZeroMorphisms C] [HasBinaryBiproduct X₁ X₂] : @@ -390,10 +394,7 @@ def productTriangle.isLimitFan : IsLimit (productTriangle.fan T) := intro s m hm ext1 all_goals - · dsimp - ext1 j - dsimp - simp [← hm]) + exact Pi.hom_ext _ _ (fun j => (by simp [← hm]))) lemma productTriangle.zero₃₁ [HasZeroMorphisms C] (h : ∀ j, (T j).mor₃ ≫ (T j).mor₁⟦(1 : ℤ)⟧' = 0) : diff --git a/Mathlib/CategoryTheory/Triangulated/Functor.lean b/Mathlib/CategoryTheory/Triangulated/Functor.lean index c55e02b12b883b..fd7c6fa36e1da0 100644 --- a/Mathlib/CategoryTheory/Triangulated/Functor.lean +++ b/Mathlib/CategoryTheory/Triangulated/Functor.lean @@ -52,11 +52,6 @@ def mapTriangle : Triangle C ⥤ Triangle D where simp only [Category.assoc, ← NatTrans.naturality, ← F.map_comp_assoc, f.comm₃] } -attribute [local simp] map_zsmul comp_zsmul zsmul_comp - commShiftIso_zero commShiftIso_add - shiftFunctorAdd'_eq_shiftFunctorAdd - commShiftIso_comp_hom_app - instance [Faithful F] : Faithful F.mapTriangle where map_injective {X Y} f g h := by ext <;> apply F.map_injective diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index bdf53c556539ad..694ca1355ad342 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -434,7 +434,7 @@ noncomputable instance hasShift : (fun X ↦ P.le_shift n _ X.2)) (fun _ => P.liftCompιIso _ _) instance commShiftι : P.ι.CommShift ℤ := - Functor.CommShift.of_hasShiftOfFullyFaithful _ _ _ + Functor.CommShift.ofHasShiftOfFullyFaithful _ _ _ -- these definitions are made irreducible to prevent (at least temporarily) any abuse of defeq attribute [irreducible] hasShift commShiftι From 707e3c99526e06a1d0121425d71f591f650744c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 08:35:55 +0100 Subject: [PATCH 08/72] whitespace --- Mathlib/CategoryTheory/NatIso.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/CategoryTheory/NatIso.lean b/Mathlib/CategoryTheory/NatIso.lean index 4cb3212c8d0995..22d21c585efe2e 100644 --- a/Mathlib/CategoryTheory/NatIso.lean +++ b/Mathlib/CategoryTheory/NatIso.lean @@ -258,5 +258,4 @@ lemma NatTrans.naturality_2 {F G : C ⥤ D} (α : F ⟶ G) {X Y : C} (e : X ≅ F.map e.hom ≫ α.app Y ≫ G.map e.inv = α.app X := by simp - end CategoryTheory From dfb8b225e8d2b245e5938443bfc7c229d45ea341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 08:38:49 +0100 Subject: [PATCH 09/72] cleaning up --- Mathlib/CategoryTheory/Triangulated/Functor.lean | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Functor.lean b/Mathlib/CategoryTheory/Triangulated/Functor.lean index fd7c6fa36e1da0..3c30aa0328083a 100644 --- a/Mathlib/CategoryTheory/Triangulated/Functor.lean +++ b/Mathlib/CategoryTheory/Triangulated/Functor.lean @@ -345,12 +345,10 @@ lemma isTriangulated_of_essSurj_mapComposableArrows_two obtain ⟨_, _, _, h₁₂'⟩ := distinguished_cocone_triangle f obtain ⟨_, _, _, h₂₃'⟩ := distinguished_cocone_triangle g obtain ⟨_, _, _, h₁₃'⟩ := distinguished_cocone_triangle (f ≫ g) - constructor - exact Octahedron.ofIso - (e₁ := (e.app 0).symm) (e₂ := (e.app 1).symm) (e₃ := (e.app 2).symm) + exact ⟨Octahedron.ofIso (e₁ := (e.app 0).symm) (e₂ := (e.app 1).symm) (e₃ := (e.app 2).symm) (comm₁₂ := ComposableArrows.naturality' e.inv 0 1) (comm₂₃ := ComposableArrows.naturality' e.inv 1 2) - (H := (someOctahedron rfl h₁₂' h₂₃' h₁₃').map F) .. + (H := (someOctahedron rfl h₁₂' h₂₃' h₁₃').map F) ..⟩ section From 4f294280c59911ebf2cf03caefa53174514ef405 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 08:40:11 +0100 Subject: [PATCH 10/72] cleaning up --- .../CategoryTheory/Triangulated/Functor.lean | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Functor.lean b/Mathlib/CategoryTheory/Triangulated/Functor.lean index 3c30aa0328083a..b5fa8b35314e22 100644 --- a/Mathlib/CategoryTheory/Triangulated/Functor.lean +++ b/Mathlib/CategoryTheory/Triangulated/Functor.lean @@ -350,26 +350,17 @@ lemma isTriangulated_of_essSurj_mapComposableArrows_two (comm₂₃ := ComposableArrows.naturality' e.inv 1 2) (H := (someOctahedron rfl h₁₂' h₂₃' h₁₃').map F) ..⟩ -section - -variable {C D : Type _} [Category C] [Category D] - [HasShift C ℤ] [HasShift D ℤ] [HasZeroObject C] [HasZeroObject D] - [Preadditive C] [Preadditive D] - [∀ (n : ℤ), (shiftFunctor C n).Additive] [∀ (n : ℤ), (shiftFunctor D n).Additive] - [Pretriangulated C] [Pretriangulated D] - (F : C ⥤ D) [F.CommShift ℤ] - lemma IsTriangulated.of_fully_faithful_triangulated_functor + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] [IsTriangulated D] : IsTriangulated C where octahedron_axiom {X₁ X₂ X₃ Z₁₂ Z₂₃ Z₁₃ u₁₂ u₂₃ u₁₃} comm {v₁₂ w₁₂} h₁₂ {v₂₃ w₂₃} h₂₃ {v₁₃ w₁₃} h₁₃ := by have comm' : F.map u₁₂ ≫ F.map u₂₃ = F.map u₁₃ := by rw [← comm, F.map_comp] - have H := Triangulated.someOctahedron comm' (F.map_distinguished _ h₁₂) + let H := Triangulated.someOctahedron comm' (F.map_distinguished _ h₁₂) (F.map_distinguished _ h₂₃) (F.map_distinguished _ h₁₃) exact - ⟨{ - m₁ := F.preimage H.m₁ + ⟨{m₁ := F.preimage H.m₁ m₃ := F.preimage H.m₃ comm₁ := F.map_injective (by simpa using H.comm₁) comm₂ := F.map_injective (by @@ -383,6 +374,4 @@ lemma IsTriangulated.of_fully_faithful_triangulated_functor rw [← F.map_distinguished_iff] simpa using H.mem }⟩ -end - end CategoryTheory From cf9df8d3a4500fa4ffa17db7eb2bc3700fc3a3fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 08:40:45 +0100 Subject: [PATCH 11/72] cleaning up --- Mathlib/CategoryTheory/Triangulated/Functor.lean | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Functor.lean b/Mathlib/CategoryTheory/Triangulated/Functor.lean index b5fa8b35314e22..d9a503e3b43088 100644 --- a/Mathlib/CategoryTheory/Triangulated/Functor.lean +++ b/Mathlib/CategoryTheory/Triangulated/Functor.lean @@ -364,14 +364,10 @@ lemma IsTriangulated.of_fully_faithful_triangulated_functor m₃ := F.preimage H.m₃ comm₁ := F.map_injective (by simpa using H.comm₁) comm₂ := F.map_injective (by - rw [← cancel_mono ((F.commShiftIso (1 : ℤ)).hom.app X₁)] - simpa using H.comm₂) + simpa [← cancel_mono ((F.commShiftIso (1 : ℤ)).hom.app X₁)] using H.comm₂) comm₃ := F.map_injective (by simpa using H.comm₃) comm₄ := F.map_injective (by - rw [← cancel_mono ((F.commShiftIso (1 : ℤ)).hom.app X₂)] - simpa using H.comm₄) - mem := by - rw [← F.map_distinguished_iff] - simpa using H.mem }⟩ + simpa [← cancel_mono ((F.commShiftIso (1 : ℤ)).hom.app X₂)] using H.comm₄) + mem := by simpa [← F.map_distinguished_iff] using H.mem }⟩ end CategoryTheory From 76cbc40135e6c97ef23ae5bb7dd17fa79955fbb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 08:45:07 +0100 Subject: [PATCH 12/72] cleaning up --- .../Triangulated/Pretriangulated.lean | 37 ------------------- 1 file changed, 37 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean index 71bbdbe22e89e0..66b200acded704 100644 --- a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean +++ b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean @@ -35,43 +35,6 @@ universe v v₀ v₁ v₂ u u₀ u₁ u₂ namespace CategoryTheory -namespace Limits - --- should be moved to a better place -namespace BinaryBiproductData - -variable {C : Type _} [Category C] - {X₁ X₂ : C} [HasZeroMorphisms C] [HasBinaryBiproduct X₁ X₂] (d : BinaryBiproductData X₁ X₂) - -def isoBiprod {C : Type _} [Category C] - {X₁ X₂ : C} [HasZeroMorphisms C] [HasBinaryBiproduct X₁ X₂] (d : BinaryBiproductData X₁ X₂) : - X₁ ⊞ X₂ ≅ d.bicone.pt := - IsLimit.conePointUniqueUpToIso (BinaryBiproduct.isLimit X₁ X₂) d.isBilimit.isLimit - -@[reassoc (attr := simp)] -lemma isoBiprod_inv_fst : d.isoBiprod.inv ≫ biprod.fst = d.bicone.fst := - IsLimit.conePointUniqueUpToIso_inv_comp _ d.isBilimit.isLimit ⟨WalkingPair.left⟩ - -@[reassoc (attr := simp)] -lemma isoBiprod_inv_snd : d.isoBiprod.inv ≫ biprod.snd = d.bicone.snd := - IsLimit.conePointUniqueUpToIso_inv_comp _ d.isBilimit.isLimit ⟨WalkingPair.right⟩ - -@[reassoc (attr := simp)] -lemma isoBiprod_hom_fst : d.isoBiprod.hom ≫ d.bicone.fst = biprod.fst := by - rw [← isoBiprod_inv_fst, Iso.hom_inv_id_assoc] - -@[reassoc (attr := simp)] -lemma isoBiprod_hom_snd : d.isoBiprod.hom ≫ d.bicone.snd = biprod.snd := by - rw [← isoBiprod_inv_snd, Iso.hom_inv_id_assoc] - -end BinaryBiproductData - -end Limits - -end CategoryTheory - -namespace CategoryTheory - open Category Pretriangulated ZeroObject /- From 127074ecda6091697d52e8d5e00078a918a536ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 09:15:05 +0100 Subject: [PATCH 13/72] cleaning up --- Mathlib/CategoryTheory/ComposableArrows/Basic.lean | 8 ++++---- Mathlib/CategoryTheory/Triangulated/Basic.lean | 10 ++++++++-- .../CategoryTheory/Triangulated/Pretriangulated.lean | 2 ++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean index 9fdd0f4f1ef76c..ccf6b34316a1c4 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean @@ -408,23 +408,23 @@ def precomp {X : C} (f : X ⟶ F.left) : ComposableArrows C (n + 1) where map_comp g g' := Precomp.map_comp F f (leOfHom g) (leOfHom g') /-- Constructor for `ComposableArrows C 2`. -/ -@[simp] +@[reducible] def mk₂ {X₀ X₁ X₂ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) : ComposableArrows C 2 := (mk₁ g).precomp f /-- Constructor for `ComposableArrows C 3`. -/ -@[simp] +@[reducible] def mk₃ {X₀ X₁ X₂ X₃ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) : ComposableArrows C 3 := (mk₂ g h).precomp f /-- Constructor for `ComposableArrows C 4`. -/ -@[simp] +@[reducible] def mk₄ {X₀ X₁ X₂ X₃ X₄ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) : ComposableArrows C 4 := (mk₃ g h i).precomp f /-- Constructor for `ComposableArrows C 5`. -/ -@[simp] +@[reducible] def mk₅ {X₀ X₁ X₂ X₃ X₄ X₅ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) (j : X₄ ⟶ X₅) : ComposableArrows C 5 := diff --git a/Mathlib/CategoryTheory/Triangulated/Basic.lean b/Mathlib/CategoryTheory/Triangulated/Basic.lean index 1e0baf28d54f67..1f017d01a04321 100644 --- a/Mathlib/CategoryTheory/Triangulated/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/Basic.lean @@ -485,6 +485,8 @@ def functorMk {obj₁ obj₂ obj₃ : J ⥤ C} hom₂ := obj₂.map φ hom₃ := obj₃.map φ } +/-- Constructor for natural transformations between functors to the +category of triangles. -/ @[simps] def functorHomMk (A B : J ⥤ Triangle C) (hom₁ : A ⋙ π₁ ⟶ B ⋙ π₁) (hom₂ : A ⋙ π₂ ⟶ B ⋙ π₂) (hom₃ : A ⋙ π₃ ⟶ B ⋙ π₃) @@ -505,7 +507,8 @@ def functorHomMk (A B : J ⥤ Triangle C) (hom₁ : A ⋙ π₁ ⟶ B ⋙ π₁) · exact hom₂.naturality φ · exact hom₃.naturality φ -/-- Constructor for morphisms between functors constructed by `functorHomMk`. -/ +/-- Constructor for natural transformations between functors constructed +with `functorMk`. -/ @[simps!] def functorHomMk' {obj₁ obj₂ obj₃ : J ⥤ C} @@ -520,6 +523,8 @@ def functorHomMk' functorMk mor₁ mor₂ mor₃ ⟶ functorMk mor₁' mor₂' mor₃' := functorHomMk _ _ hom₁ hom₂ hom₃ comm₁ comm₂ comm₃ +/-- Constructor for natural isomorphisms between functors to the +category of triangles. -/ @[simps] def functorIsoMk (A B : J ⥤ Triangle C) (iso₁ : A ⋙ π₁ ≅ B ⋙ π₁) (iso₂ : A ⋙ π₂ ≅ B ⋙ π₂) (iso₃ : A ⋙ π₃ ≅ B ⋙ π₃) @@ -538,7 +543,8 @@ def functorIsoMk (A B : J ⥤ Triangle C) (iso₁ : A ⋙ π₁ ≅ B ⋙ π₁) ← whiskerRight_comp, Iso.hom_inv_id, whiskerRight_id'] apply comp_id) -/-- Constructor for isomorphisms between functors constructed by `functorHomMk`. -/ +/-- Constructor for natural isomorphisms between functors constructed +with `functorMk`. -/ @[simps!] def functorIsoMk' {obj₁ obj₂ obj₃ : J ⥤ C} diff --git a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean index 66b200acded704..9a9fd49ad78ebd 100644 --- a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean +++ b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean @@ -685,6 +685,8 @@ def isoTriangleOfIso₁₂ (T₁ T₂ : Triangle C) (hT₁ : T₁ ∈ distTriang dsimp at eq ⊢ conv_lhs => rw [← eq, TriangleMorphism.comm₃]) +/-- A choice of isomorphism `T₁ ≅ T₂` between two distinguished triangles +when we are given two isomorphisms `e₁ : T₁.obj₁ ≅ T₂.obj₁` and `e₃ : T₁.obj₃ ≅ T₂.obj₃`. -/ @[simps! hom_hom₁ hom_hom₃ inv_hom₁ inv_hom₃] def isoTriangleOfIso₁₃ (T₁ T₂ : Triangle C) (hT₁ : T₁ ∈ distTriang C) (hT₂ : T₂ ∈ distTriang C) (e₁ : T₁.obj₁ ≅ T₂.obj₁) (e₃ : T₁.obj₃ ≅ T₂.obj₃) From 374820eecc9a1cc5937cdfee008ed1f50e492225 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 14:19:51 +0100 Subject: [PATCH 14/72] fix --- .../Limits/Shapes/Products.lean | 8 ++- .../Triangulated/Subcategory.lean | 67 +++++-------------- 2 files changed, 20 insertions(+), 55 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean index f618d3b2da6002..6d5119c9817947 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Products.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Products.lean @@ -118,14 +118,16 @@ def mkFanLimit {f : β → C} (t : Fan f) (lift : ∀ s : Fan f, s.pt ⟶ t.pt) { lift } /-- Constructor for morphisms to the point of a limit fan. -/ -def Fan.IsLimit.desc {F : β → C} {c : Fan F} (hc : IsLimit c) {A : C} +def Fan.IsLimit.lift {F : β → C} {c : Fan F} (hc : IsLimit c) {A : C} (f : ∀ i, A ⟶ F i) : A ⟶ c.pt := hc.lift (Fan.mk A f) +@[deprecated (since := "2026-01-12")] alias Fan.IsLimit.desc := Fan.IsLimit.lift + @[reassoc (attr := simp)] lemma Fan.IsLimit.fac {F : β → C} {c : Fan F} (hc : IsLimit c) {A : C} (f : ∀ i, A ⟶ F i) (i : β) : - Fan.IsLimit.desc hc f ≫ c.proj i = f i := + Fan.IsLimit.lift hc f ≫ c.proj i = f i := hc.fac (Fan.mk A f) ⟨i⟩ @[reassoc (attr := simp)] @@ -887,7 +889,7 @@ def Fan.IsLimit.prod (c : ∀ i : ι, Fan (fun j : ι' ↦ X i j)) (hc : ∀ i : (c' : Fan (fun i : ι ↦ (c i).pt)) (hc' : IsLimit c') : (IsLimit <| Fan.mk c'.pt fun p : ι × ι' ↦ c'.proj _ ≫ (c p.1).proj p.2) := by refine mkFanLimit _ (fun t ↦ ?_) ?_ fun t m hm ↦ ?_ - · exact Fan.IsLimit.desc hc' fun i ↦ Fan.IsLimit.desc (hc i) fun j ↦ t.proj (i, j) + · exact Fan.IsLimit.lift hc' fun i ↦ Fan.IsLimit.lift (hc i) fun j ↦ t.proj (i, j) · simp · refine Fan.IsLimit.hom_ext hc' _ _ fun i ↦ ?_ exact Fan.IsLimit.hom_ext (hc i) _ _ fun j ↦ (by simpa using hm (i, j)) diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index 694ca1355ad342..14effa48d6054e 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -50,52 +50,6 @@ namespace CategoryTheory open Category Limits Preadditive ZeroObject Pretriangulated Triangulated -namespace Limits - -variable {C J₁ J₂ : Type _} [Category C] - (X : J₂ → C) (e : J₁ ≃ J₂) [HasProduct X] - -noncomputable def fanOfEquiv : Fan (X ∘ e) := Fan.mk (∏ᶜ X) (fun _ => Pi.π _ _) - -@[simp] -lemma fanOfEquiv_proj (j : J₁) : (fanOfEquiv X e).proj j = Pi.π _ (e j) := rfl - -@[reassoc] -lemma Fan.congr_proj {J : Type _} {F : J → C} (s : Fan F) - {j₁ j₂ : J} (h : j₁ = j₂) : s.proj j₁ ≫ eqToHom (by rw [h]) = s.proj j₂ := by - subst h - simp - -@[reassoc] -lemma Pi.congr_π {J : Type _} (F : J → C) [HasProduct F] {j₁ j₂ : J} (h : j₁ = j₂) : - Pi.π F j₁ ≫ eqToHom (by rw [h]) = Pi.π F j₂ := by - subst h - simp - -noncomputable def isLimitFanOfEquiv : IsLimit (fanOfEquiv X e) := - mkFanLimit _ (fun s => Pi.lift (fun j₂ => s.proj (e.symm j₂) ≫ eqToHom (by simp) )) - (fun s j => by simp [Fan.congr_proj _ (e.symm_apply_apply j)]) - (fun s m hm => Limits.Pi.hom_ext (f := X) _ _ (fun j ↦ by simp [← hm])) - -lemma hasProductOfEquiv : HasProduct (X ∘ e) := - ⟨⟨_, isLimitFanOfEquiv X e⟩⟩ - -noncomputable def productIsoOfEquiv [HasProduct (X ∘ e)] : ∏ᶜ (X ∘ e) ≅ ∏ᶜ X := - IsLimit.conePointUniqueUpToIso (limit.isLimit _) (isLimitFanOfEquiv X e) - -noncomputable def productOptionIso {C J : Type _} [Category C] - (X : Option J → C) [HasProduct X] [HasProduct (fun j => X (some j))] - [HasBinaryProduct (∏ᶜ (fun j => X (some j))) (X none)] : - (∏ᶜ X) ≅ (∏ᶜ (fun j => X (some j))) ⨯ (X none) where - hom := prod.lift (Pi.lift (fun j => Pi.π _ (some j))) (Pi.π _ none) - inv := Pi.lift (fun b => match b with - | some j => prod.fst ≫ Pi.π _ j - | none => prod.snd) - -end Limits - -open Pretriangulated - variable {C : Type*} [Category C] [HasZeroObject C] [HasShift C ℤ] [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] @@ -363,16 +317,25 @@ lemma pi_finite_stable [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] let Q : Type → Prop := fun J => ∀ [hJ : Finite J] (X : J → C) (_ : ∀ j, P (X j)), P (∏ᶜ X) suffices Q J by convert this - apply @Finite.induction_empty_option - · intro J₁ J₂ e hJ₁ _ X hX + induction J using Finite.induction_empty_option with + | @of_equiv J₁ J₂ e hJ₁ => + intro _ X hX have : Finite J₁ := Finite.of_equiv _ e.symm - exact prop_of_iso _ (productIsoOfEquiv X e) (hJ₁ (fun j₁ => X (e j₁)) (fun j₁ => hX _)) - · intro _ X _ + exact prop_of_iso _ (Pi.whiskerEquiv e (fun _ ↦ Iso.refl _)) + (hJ₁ (fun j₁ ↦ X (e j₁)) (fun j₁ ↦ hX _)) + | h_empty => + intro _ X _ refine prop_of_iso _ (IsZero.isoZero ?_).symm P.prop_zero rw [IsZero.iff_id_eq_zero] ext ⟨⟩ - · intro J _ hJ _ X hX - exact prop_of_iso _ (productOptionIso X).symm + | @h_option J _ hJ => + intro _ X hX + let iso : ∏ᶜ X ≅ (∏ᶜ fun b ↦ X (some b)) ⨯ X none := + { hom := prod.lift (Pi.lift (fun b ↦ Pi.π _ (some b))) (Pi.π _ none) + inv := Pi.lift (fun b ↦ match b with + | some j => prod.fst ≫ Pi.π _ j + | none => prod.snd) } + exact prop_of_iso _ iso.symm (P.binary_product_stable_of_isTriangulated _ _ (hJ (fun j => X (some j)) (fun j => hX _)) (hX none)) From 46d122e5b004f50d2cac8ee2440bd802cf77b9e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 14:41:59 +0100 Subject: [PATCH 15/72] feat(Data): the extended integers --- Mathlib.lean | 1 + Mathlib/Data/EInt/Basic.lean | 93 ++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 Mathlib/Data/EInt/Basic.lean diff --git a/Mathlib.lean b/Mathlib.lean index ebcfd3f8eca3b7..7bb992cde53ca8 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3457,6 +3457,7 @@ public import Mathlib.Data.DFinsupp.Small public import Mathlib.Data.DFinsupp.Submonoid public import Mathlib.Data.DFinsupp.WellFounded public import Mathlib.Data.DList.Instances +public import Mathlib.Data.EInt.Basic public import Mathlib.Data.ENNReal.Action public import Mathlib.Data.ENNReal.Basic public import Mathlib.Data.ENNReal.BigOperators diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean new file mode 100644 index 00000000000000..7397e3be68f3c2 --- /dev/null +++ b/Mathlib/Data/EInt/Basic.lean @@ -0,0 +1,93 @@ +/- +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, Kevin Buzzard +-/ +module + +public import Mathlib.Order.WithBot + +/-! +# The extended integers + +This file defines `EInt`, `ℤ` with a top element `⊤` and a bottom element `⊥`, +implemented as `WithBot (WithTop ℤ)`. + +-/ + +@[expose] public section + +/-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ +def EInt := WithBot (WithTop ℤ) + +/-- The canonical inclusion from integers to e-integers. Registered as a coercion. -/ +@[coe] def Int.toEInt : ℤ → EInt := WithBot.some ∘ WithTop.some + +namespace EInt + +instance : LinearOrder EInt := inferInstanceAs (LinearOrder (WithBot (WithTop ℤ))) + +instance : OrderBot EInt := inferInstanceAs (OrderBot (WithBot (WithTop ℤ))) + +instance : OrderTop EInt := inferInstanceAs (OrderTop (WithBot (WithTop ℤ))) + +instance : Coe ℤ EInt := ⟨Int.toEInt⟩ + +theorem coe_strictMono : StrictMono Int.toEInt := + WithBot.coe_strictMono.comp WithTop.coe_strictMono + +theorem coe_injective : Function.Injective Int.toEInt := + coe_strictMono.injective + +lemma coe_monotone : Monotone Int.toEInt := coe_strictMono.monotone + +/-- The constructor `ℤ → EInt`. -/ +abbrev mk (a : ℤ) : EInt := a + +section + +variable {motive : EInt → Sort*} + (bot : motive ⊥) (coe : ∀ a : ℤ, motive a) (top : motive ⊤) + +/-- A recursor for `EInt` in terms of the coercion. -/ +@[elab_as_elim, induction_eliminator, cases_eliminator] +protected def rec : ∀ a : EInt, motive a + | ⊥ => bot + | (a : ℤ) => coe a + | ⊤ => top + +@[simp] lemma rec_bot : EInt.rec (motive := motive) bot coe top ⊥ = bot := rfl +@[simp] lemma rec_coe (a : ℤ) : EInt.rec (motive := motive) bot coe top a = coe a := rfl +@[simp] lemma rec_top : EInt.rec (motive := motive) bot coe top ⊤ = top := rfl + +end + +@[simp] +lemma coe_le_coe_iff (a b : ℤ) : + mk a ≤ mk b ↔ a ≤ b := + coe_strictMono.le_iff_le + +@[simp] +lemma coe_lt_coe_iff (a b : ℤ) : + mk a < mk b ↔ a < b := + coe_strictMono.lt_iff_lt + +@[simp] +lemma coe_eq_bot_iff (a : ℤ) : + EInt.mk a = ⊥ ↔ False := by + simp only [iff_false] + rintro ⟨⟩ + +@[simp] +lemma coe_eq_top_iff (a : ℤ) : + EInt.mk a = ⊤ ↔ False := by + simp only [iff_false] + rintro ⟨⟩ + +@[simp] +lemma top_eq_bot_iff : + (⊤ : EInt) = ⊥ ↔ False := by + simp only [iff_false] + exact ne_of_beq_false rfl + +end EInt From 215b7a3f651aabf458150b11af22ed553f8a8646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 15:19:41 +0100 Subject: [PATCH 16/72] fix --- Mathlib/CategoryTheory/ObjectProperty/Shift.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean index 4f17274b324272..f9e3c8f85d64ab 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean @@ -24,7 +24,7 @@ open CategoryTheory Category namespace CategoryTheory -variable {C : Type*} [Category C] (P Q : ObjectProperty C) +variable {C : Type*} [Category* C] (P Q : ObjectProperty C) {A : Type*} [AddMonoid A] [HasShift C A] namespace ObjectProperty From e8e22e849feabb63a5bda37a740466f34dc7cd9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 16:26:02 +0100 Subject: [PATCH 17/72] fix --- Mathlib/CategoryTheory/Category/Preorder.lean | 8 -------- 1 file changed, 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Category/Preorder.lean b/Mathlib/CategoryTheory/Category/Preorder.lean index 4b61bb5cecc445..a7dbf2343bd573 100644 --- a/Mathlib/CategoryTheory/Category/Preorder.lean +++ b/Mathlib/CategoryTheory/Category/Preorder.lean @@ -68,10 +68,6 @@ def homOfLE {x y : X} (h : x ≤ y) : x ⟶ y := @[inherit_doc homOfLE] abbrev _root_.LE.le.hom := @homOfLE -/-- Express an inequality `x ≤ y` as a morphism in the corresponding preorder category. -(In this version, the variables `x` and `y` are explicit.) -/ -abbrev homOfLE' (x y : X) (h : x ≤ y) : x ⟶ y := homOfLE h - @[simp] theorem homOfLE_refl {x : X} (h : x ≤ x) : h.hom = 𝟙 x := rfl @@ -102,10 +98,6 @@ lemma isIso_homOfLE {x y : X} (h : x = y) : change IsIso (𝟙 _) infer_instance -lemma isIso_homOfLE' (x y : X) (h : x = y) : - IsIso (homOfLE' x y (by rw [h])) := - isIso_homOfLE h - @[simp, reassoc] lemma homOfLE_comp_eqToHom {a b c : X} (hab : a ≤ b) (hbc : b = c) : homOfLE hab ≫ eqToHom hbc = homOfLE (hab.trans (le_of_eq hbc)) := From eb9c0e038c06b428b0dfc20dfcaa21ae83ed9614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 20:18:49 +0100 Subject: [PATCH 18/72] cleaning up --- .../Triangulated/Subcategory.lean | 116 ++++-------------- 1 file changed, 26 insertions(+), 90 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index 14effa48d6054e..d633893d692229 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -50,7 +50,7 @@ namespace CategoryTheory open Category Limits Preadditive ZeroObject Pretriangulated Triangulated -variable {C : Type*} [Category C] [HasZeroObject C] [HasShift C ℤ] +variable {C : Type*} [Category* C] [HasZeroObject C] [HasShift C ℤ] [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] namespace ObjectProperty @@ -252,7 +252,6 @@ lemma trW_iff_of_distinguished · intro h exact ⟨_, _, _, hT, h⟩ -/-- Variant of `mem_W_iff_of_distinguished`. -/ lemma trW_iff_of_distinguished' [P.IsStableUnderShift ℤ] [P.IsClosedUnderIsomorphisms] (T : Triangle C) (hT : T ∈ distTriang C) : P.trW T.mor₂ ↔ P T.obj₁ := by @@ -305,18 +304,17 @@ instance [IsTriangulated C] [P.IsTriangulated] : P.trW.IsCompatibleWithTriangula exact ⟨φ.hom₃, P.trW.comp_mem _ _ (trW.mk P H.mem mem₄') (trW.mk' P H'.mem mem₅'), by simpa [φ] using φ.comm₂, by simpa [φ] using φ.comm₃⟩⟩ -lemma binary_product_stable_of_isTriangulated [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] +lemma prop_prod_of_isTriangulated [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] (X₁ X₂ : C) (hX₁ : P X₁) (hX₂ : P X₂) : P (X₁ ⨯ X₂) := P.ext_of_isTriangulatedClosed₂ _ (binaryProductTriangle_distinguished X₁ X₂) hX₁ hX₂ -lemma pi_finite_stable [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] +lemma prop_pi_of_isTriangulated [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] {J : Type} [Finite J] (X : J → C) (hX : ∀ j, P (X j)) : P (∏ᶜ X) := by revert hX X - let Q : Type → Prop := fun J => - ∀ [hJ : Finite J] (X : J → C) (_ : ∀ j, P (X j)), P (∏ᶜ X) - suffices Q J by convert this + let Q (J : Type) : Prop := ∀ [hJ : Finite J] (X : J → C) (_ : ∀ j, P (X j)), P (∏ᶜ X) + suffices Q J by exact this induction J using Finite.induction_empty_option with | @of_equiv J₁ J₂ e hJ₁ => intro _ X hX @@ -336,7 +334,7 @@ lemma pi_finite_stable [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] | some j => prod.fst ≫ Pi.π _ j | none => prod.snd) } exact prop_of_iso _ iso.symm - (P.binary_product_stable_of_isTriangulated _ _ + (P.prop_prod_of_isTriangulated _ _ (hJ (fun j => X (some j)) (fun j => hX _)) (hX none)) instance [P.IsTriangulated] : P.trW.IsStableUnderFiniteProducts := by @@ -346,7 +344,8 @@ instance [P.IsTriangulated] : P.trW.IsStableUnderFiniteProducts := by intro _ _ X₁ X₂ f hf exact trW.mk _ (productTriangle_distinguished _ (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose)) - (pi_finite_stable _ _ (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose_spec))⟩ + (prop_pi_of_isTriangulated _ _ + (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose_spec))⟩ lemma closedUnderLimitsOfShape_discrete_of_isTriangulated [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] (J : Type) [Finite J] : @@ -357,7 +356,7 @@ lemma closedUnderLimitsOfShape_discrete_of_isTriangulated have e : Discrete.functor G ≅ p.diag := Discrete.natIso (fun _ ↦ Iso.refl _) have := IsLimit.conePointUniqueUpToIso (limit.isLimit _) ((IsLimit.postcomposeInvEquiv e _).2 p.isLimit) - exact P.prop_of_iso this (P.pi_finite_stable G (fun j ↦ p.prop_diag_obj _)) + exact P.prop_of_iso this (P.prop_pi_of_isTriangulated G (fun j ↦ p.prop_diag_obj _)) section @@ -376,19 +375,6 @@ end section -variable [IsTriangulated C] [P.IsTriangulated] - -noncomputable example : Pretriangulated (P.trW.Localization) := inferInstance -example : IsTriangulated (P.trW.Localization) := inferInstance -example : P.trW.Q.IsTriangulated := inferInstance - -end - -example : Preadditive P.FullSubcategory := inferInstance -example : P.ι.Additive := inferInstance - -section - variable [P.IsTriangulated] noncomputable instance hasShift : @@ -414,8 +400,6 @@ instance : HasZeroObject P.FullSubcategory where apply ObjectProperty.hom_ext apply hZ.eq_of_src -attribute [local simp] ObjectProperty.fullyFaithfulι fullyFaithfulInducedFunctor - noncomputable instance : Pretriangulated P.FullSubcategory where distinguishedTriangles := fun T => P.ι.mapTriangle.obj T ∈ distTriang C isomorphic_distinguished := fun T₁ hT₁ T₂ e => @@ -423,7 +407,6 @@ noncomputable instance : Pretriangulated P.FullSubcategory where contractible_distinguished X := by refine isomorphic_distinguished _ (contractible_distinguished (P.ι.obj X)) _ ?_ exact Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) P.ι.mapZeroObject - (by aesop_cat) (by aesop_cat) (by aesop_cat) distinguished_cocone_triangle {X Y} f := by obtain ⟨Z', g', h', mem⟩ := distinguished_cocone_triangle (P.ι.map f) obtain ⟨Z'', hZ'', ⟨e⟩⟩ := P.ext_of_isTriangulatedClosed₃' _ mem X.2 Y.2 @@ -432,7 +415,6 @@ noncomputable instance : Pretriangulated P.FullSubcategory where P.fullyFaithfulι.preimage (e.inv ≫ h' ≫ (P.ι.commShiftIso (1 : ℤ)).inv.app X), isomorphic_distinguished _ mem _ ?_⟩ exact Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) e.symm - (by aesop_cat) (by simp) (by simp) rotate_distinguished_triangle T := (rotate_distinguished_triangle (P.ι.mapTriangle.obj T)).trans (distinguished_iff_of_iso (P.ι.mapTriangleRotateIso.app T)) @@ -440,19 +422,11 @@ noncomputable instance : Pretriangulated P.FullSubcategory where obtain ⟨c, ⟨hc₁, hc₂⟩⟩ := complete_distinguished_triangle_morphism (P.ι.mapTriangle.obj T₁) (P.ι.mapTriangle.obj T₂) hT₁ hT₂ (P.ι.map a) (P.ι.map b) (by simpa using P.ι.congr_map comm) - have ⟨c', hc'⟩ : ∃ (c' : T₁.obj₃ ⟶ T₂.obj₃), c = P.ι.map c' := - ⟨P.fullyFaithfulι.preimage c, by simp⟩ - dsimp at hc₁ hc₂ - rw [hc'] at hc₁ - rw [hc', assoc] at hc₂ - dsimp at hc₂ - erw [← Functor.commShiftIso_hom_naturality] at hc₂ - refine ⟨c', ⟨P.ι.map_injective ?_, P.ι.map_injective ?_⟩⟩ - · simpa using hc₁ - · rw [← cancel_mono ((Functor.commShiftIso P.ι (1 : ℤ)).hom.app T₂.obj₁), - P.ι.map_comp, P.ι.map_comp, assoc, assoc] - erw [hc₂] - rfl + have := P.ι.commShiftIso_hom_naturality a (1 : ℤ) + refine ⟨P.fullyFaithfulι.preimage c, ⟨by cat_disch, ?_⟩⟩ + ext + rw [← cancel_mono ((Functor.commShiftIso P.ι (1 : ℤ)).hom.app T₂.obj₁)] + cat_disch instance : P.ι.IsTriangulated := ⟨fun _ hT => hT⟩ @@ -462,8 +436,8 @@ instance [IsTriangulated C] : IsTriangulated P.FullSubcategory := section variable {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] - [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] + [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] instance : (F.essImage).IsTriangulated where isStableUnderShiftBy n := @@ -477,19 +451,14 @@ instance : (F.essImage).IsTriangulated where (F.commShiftIso (1 : ℤ)).inv.app X₁) obtain ⟨X₂, f, g, H⟩ := distinguished_cocone_triangle₂ h exact ⟨X₂, ⟨Triangle.π₂.mapIso - (isoTriangleOfIso₁₃ _ _ (F.map_distinguished _ H) hT e₁ e₃ (by - dsimp - simp only [hh, assoc, Iso.inv_hom_id_app, Functor.comp_obj, - comp_id, ← Functor.map_comp, - Iso.inv_hom_id, Functor.map_id]))⟩⟩) - - + (isoTriangleOfIso₁₃ _ _ (F.map_distinguished _ H) hT e₁ e₃ + (by simp [hh, ← Functor.map_comp]))⟩⟩) end section -variable {D : Type*} [Category D] (F : D ⥤ C) (hF : ∀ (X : D), P (F.obj X)) +variable {D : Type*} [Category* D] (F : D ⥤ C) (hF : ∀ (X : D), P (F.obj X)) -- some of these are general API, not specific to triangulated subcategories @@ -501,16 +470,14 @@ instance [F.Full] : (P.lift F hF).Full := -- should be generalized instance [Preadditive D] [F.Additive] : (P.lift F hF).Additive where - map_add {X Y f g} := by - apply P.ι.map_injective - apply F.map_add -noncomputable instance [HasShift D ℤ] [F.CommShift ℤ] : (P.lift F hF).CommShift ℤ := +noncomputable instance [HasShift D ℤ] [F.CommShift ℤ] : + (P.lift F hF).CommShift ℤ := Functor.CommShift.ofComp (P.liftCompιIso F hF) ℤ noncomputable instance [HasShift D ℤ] [F.CommShift ℤ] : - NatTrans.CommShift (P.liftCompιIso F hF).hom ℤ := - Functor.CommShift.ofComp_compatibility _ _ + NatTrans.CommShift (P.liftCompιIso F hF).hom ℤ := + Functor.CommShift.ofComp_compatibility _ _ instance isTriangulated_lift [HasShift D ℤ] [Preadditive D] [F.CommShift ℤ] [HasZeroObject D] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] [F.IsTriangulated] : @@ -543,7 +510,7 @@ lemma inverseImage_trW_iff {X Y : D} (s : X ⟶ Y) : rw [eq₁, prop_inverseImage_iff, eq₂] omit [P.IsTriangulated] in -lemma inverseImage_W_isInverted {E : Type*} [Category E] +lemma inverseImage_trW_isInverted {E : Type*} [Category E] (L : C ⥤ E) [L.IsLocalization P.trW] : (P.inverseImage F).trW.IsInvertedBy (F ⋙ L) := fun X Y f hf => Localization.inverts L P.trW (F.map f) @@ -553,39 +520,9 @@ end section -variable {D : Type*} [Category D] [Preadditive D] [HasZeroObject D] [HasShift D ℤ] - [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - {F G : C ⥤ D} [F.CommShift ℤ] [G.CommShift ℤ] [F.IsTriangulated] - [G.IsTriangulated] (τ : F ⟶ G) [NatTrans.CommShift τ ℤ] - -def ofNatTrans : ObjectProperty C := fun X ↦ IsIso (τ.app X) - -instance : (ofNatTrans τ).IsClosedUnderIsomorphisms where - of_iso e h := by - dsimp [ofNatTrans] at h ⊢ - rwa [← NatTrans.isIso_app_iff_of_iso τ e] - -instance : (ofNatTrans τ).IsTriangulated where - exists_zero := ⟨0, isZero_zero C, - ⟨0, (F.map_isZero (isZero_zero C)).eq_of_src _ _, - (G.map_isZero (isZero_zero C)).eq_of_src _ _⟩⟩ - isStableUnderShiftBy n := - { le_shift X (hX : IsIso _) := by - simp only [prop_shift_iff, ofNatTrans, NatTrans.app_shift] - infer_instance } - toIsTriangulatedClosed₂ := .mk' (fun T hT _ _ ↦ by - exact Pretriangulated.isIso₂_of_isIso₁₃ - ((Pretriangulated.Triangle.homMk _ _ (τ.app _) (τ.app _) (τ.app _) - (by simp) (by simp) (by simp [NatTrans.shift_app_comm]))) - (F.map_distinguished _ hT) (G.map_distinguished _ hT) (by assumption) (by assumption)) - -end - -section - variable {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] - [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] + [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] instance : (P.map F).IsTriangulated := by convert inferInstanceAs (P.ι ⋙ F).essImage.IsTriangulated @@ -596,7 +533,6 @@ instance : (P.map F).IsTriangulated := by · rintro ⟨X, ⟨e⟩⟩ exact ⟨X.1, X.2, ⟨e⟩⟩ - end end From 774332862965a66ad4a7b6785268d01935ae8268 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 20:27:00 +0100 Subject: [PATCH 19/72] added missing file --- Mathlib.lean | 1 + .../SpectralObject/SpectralSequence.lean | 820 ++++++++++++++++++ 2 files changed, 821 insertions(+) create mode 100644 Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean diff --git a/Mathlib.lean b/Mathlib.lean index ad9530bcac3a23..41e1b305b346e6 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -651,6 +651,7 @@ public import Mathlib.Algebra.Homology.SpectralObject.Differentials public import Mathlib.Algebra.Homology.SpectralObject.HasSpectralSequence public import Mathlib.Algebra.Homology.SpectralObject.Homology public import Mathlib.Algebra.Homology.SpectralObject.Page +public import Mathlib.Algebra.Homology.SpectralObject.SpectralSequence public import Mathlib.Algebra.Homology.SpectralSequence.Basic public import Mathlib.Algebra.Homology.SpectralSequence.ComplexShape public import Mathlib.Algebra.Homology.Square diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean new file mode 100644 index 00000000000000..b2eb93172be9cd --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -0,0 +1,820 @@ +/- +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.SpectralObject.Homology +public import Mathlib.Algebra.Homology.SpectralObject.HasSpectralSequence +public import Mathlib.Algebra.Homology.SpectralSequence.Basic +public import Mathlib.Data.EInt.Basic +public import Batteries.Tactic.Lint + +/-! +# The spectral sequence of a spectral object + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits ComposableArrows + +namespace Abelian + +namespace SpectralObject + +variable {C ι κ : Type*} [Category C] [Abelian C] [Preorder ι] + (X : SpectralObject C ι) + {c : ℤ → ComplexShape κ} {r₀ : ℤ} + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + (i₀ i₁ i₂ i₃ i₄ i₅ : ι) (hi₀₁ : i₀ ≤ i₁) + (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) (hi₃₄ : i₃ ≤ i₄) (hi₄₅ : i₄ ≤ i₅) + +/-- EMapFourδ₁Toδ₀' -/ +noncomputable abbrev EMapFourδ₁Toδ₀' := + X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₁Toδ₀' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +/-- mono_EMapFourδ₁Toδ₀' -/ +instance mono_EMapFourδ₁Toδ₀' : + Mono (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + dsimp [EMapFourδ₁Toδ₀'] + infer_instance + +/-- EMapFourδ₄Toδ₃' -/ +noncomputable abbrev EMapFourδ₄Toδ₃' := + X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₄Toδ₃' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +/-- epi_EMapFourδ₄Toδ₃' -/ +instance epi_EMapFourδ₄Toδ₃' : + Epi (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + dsimp [EMapFourδ₄Toδ₃'] + infer_instance + +@[reassoc] +lemma EMapFourδ₁Toδ₀'_comp : + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₃ i₄ i₅ hi₀₁ (hi₁₂.trans hi₂₃) hi₃₄ hi₄₅ ≫ + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₁ i₂ i₃ i₄ i₅ hi₁₂ hi₂₃ hi₃₄ hi₄₅ = + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₂ i₃ i₄ i₅ (hi₀₁.trans hi₁₂) hi₂₃ hi₃₄ hi₄₅ := by + rw [← EMap_comp] + rfl + +@[reassoc] +lemma EMapFourδ₄Toδ₃'_comp : + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₄ i₅ hi₀₁ hi₁₂ (hi₂₃.trans hi₃₄) hi₄₅ = + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₅ hi₀₁ hi₁₂ hi₂₃ (hi₃₄.trans hi₄₅) := by + dsimp [EMapFourδ₄Toδ₃'] + rw [← EMap_comp] + rfl + +/-- EMapFourδ₁Toδ₀'_EMapFourδ₃Toδ₃' -/ +@[reassoc] +lemma EMapFourδ₁Toδ₀'_EMapFourδ₃Toδ₃' : + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₁ i₂ i₃ i₄ i₅ hi₁₂ hi₂₃ hi₃₄ hi₄₅ = + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₂ i₃ i₄ i₅ _ _ _ hi₄₅ ≫ + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₅ hi₀₁ _ _ _ := by + dsimp [EMapFourδ₁Toδ₀', EMapFourδ₄Toδ₃'] + rw [← EMap_comp, ← EMap_comp] + rfl + +section + +variable (h : IsZero ((H X n₂).obj (mk₁ (homOfLE hi₀₁)))) + +include h in +lemma isIso_EMapFourδ₁Toδ₀' : + IsIso (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + apply X.isIso_EMap_fourδ₁Toδ₀_of_isZero + exact h + +/-- isoEMapFourδ₁Toδ₀' -/ +@[simps! hom] +noncomputable def isoEMapFourδ₁Toδ₀' : + X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE (hi₀₁.trans hi₁₂)) (homOfLE hi₂₃) (homOfLE hi₃₄) ≅ + X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₁₂) (homOfLE hi₂₃) (homOfLE hi₃₄) := + have := X.isIso_EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h + asIso (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₁Toδ₀'_hom_inv_id : + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv = 𝟙 _ := + (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).hom_inv_id + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₁Toδ₀'_inv_hom_id : + (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv ≫ + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ = 𝟙 _ := + (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv_hom_id + +end + +section + +variable (h : IsZero ((H X n₀).obj (mk₁ (homOfLE hi₃₄)))) + +include h in +lemma isIso_EMapFourδ₄Toδ₃' : + IsIso (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + apply X.isIso_EMap_fourδ₄Toδ₃_of_isZero + exact h + +/-- isoEMapFourδ₄Toδ₃' -/ +@[simps! hom] +noncomputable def isoEMapFourδ₄Toδ₃' : + X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE hi₂₃) ≅ + X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE (hi₂₃.trans hi₃₄)) := + have := X.isIso_EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h + asIso (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₄Toδ₄'_hom_inv_id : + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv = 𝟙 _ := + (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).hom_inv_id + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₄Toδ₄'_inv_hom_id : + (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv ≫ + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ = 𝟙 _ := + (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv_hom_id + +end + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + (i₀ i₁ i₂ i₃ i₄ i₅ : ι) (hi₀₁ : i₀ ≤ i₁) + (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) (hi₃₄ : i₃ ≤ i₄) (hi₄₅ : i₄ ≤ i₅) + +/-- EMapFourδ₂Toδ₁' -/ +noncomputable abbrev EMapFourδ₂Toδ₁' := + X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₂Toδ₁' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +/-- isIso_EMapFourδ₂Toδ₁' -/ +lemma isIso_EMapFourδ₂Toδ₁' + (h₁ : IsIso ((X.H n₁).map (twoδ₁Toδ₀' i₁ i₂ i₃ hi₁₂ hi₂₃))) + (h₂ : IsIso ((X.H n₂).map (twoδ₂Toδ₁' i₀ i₁ i₂ hi₀₁ hi₁₂))) : + IsIso (X.EMapFourδ₂Toδ₁' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + apply X.isIso_EMap + · dsimp + erw [Functor.map_id] + infer_instance + · exact h₁ + · exact h₂ + +end + +end + +variable (data : SpectralSequenceMkData ι c r₀) + +namespace SpectralSequence + +noncomputable def pageX (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : C := + X.E (data.deg pq - 1) (data.deg pq) (data.deg pq + 1) (by simp) rfl + (homOfLE (data.le₀₁ r hr pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r hr pq)) + +noncomputable def pageXIso (r : ℤ) (hr : r₀ ≤ r) (pq : κ) (n₀ n₁ n₂ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) + (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = data.i₀ r hr pq) (h₁ : i₁ = data.i₁ pq) + (h₂ : i₂ = data.i₂ pq) (h₃ : i₃ = data.i₃ r hr pq) : + pageX X data r hr pq ≅ X.E n₀ n₁ n₂ hn₁ hn₂ + (homOfLE (by subst h₀ h₁; exact data.le₀₁ r hr pq) : i₀ ⟶ i₁) + (homOfLE (by subst h₁ h₂; exact data.le₁₂ pq) : i₁ ⟶ i₂) + (homOfLE (by subst h₂ h₃; exact data.le₂₃ r hr pq) : i₂ ⟶ i₃) := + eqToIso (by + obtain rfl : n₀ = n₁ - 1 := by lia + subst h hn₂ h₀ h₁ h₂ h₃ + rfl) + +open Classical in +noncomputable def paged (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) : + pageX X data r hr pq ⟶ pageX X data r hr pq' := + if hpq : (c r).Rel pq pq' + then + X.d (data.deg pq - 1) (data.deg pq) (data.deg pq + 1) (data.deg pq + 2) _ rfl + (by lia) (homOfLE (data.le₀₁ r hr pq')) + (homOfLE (by simpa only [data.hc₀₂ r hr pq pq' hpq] using data.le₁₂ pq')) + (homOfLE (data.le₀₁ r hr pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r hr pq)) ≫ + (pageXIso _ _ _ _ _ _ _ _ _ _ (data.hc r hr pq pq' hpq) _ _ _ _ rfl rfl + (data.hc₀₂ r hr pq pq' hpq) (data.hc₁₃ r hr pq pq' hpq)).inv + else 0 + +lemma paged_eq (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') + (n₀ n₁ n₂ n₃ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) + {i₀ i₁ i₂ i₃ i₄ i₅ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) (hn₁' : n₁ = data.deg pq) + (h₀ : i₀ = data.i₀ r hr pq') (h₁ : i₁ = data.i₁ pq') (h₂ : i₂ = data.i₀ r hr pq) + (h₃ : i₃ = data.i₁ pq) (h₄ : i₄ = data.i₂ pq) (h₅ : i₅ = data.i₃ r hr pq) : + paged X data r hr pq pq' = + (pageXIso _ _ _ _ _ _ _ _ _ _ hn₁' _ _ _ _ h₂ h₃ h₄ h₅).hom ≫ + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ + (pageXIso _ _ _ _ _ _ _ _ _ _ + (by simpa only [← hn₂, hn₁'] using data.hc r hr pq pq' hpq) _ _ _ _ h₀ h₁ + (by rw [h₂, data.hc₀₂ r hr pq pq' hpq]) + (by rw [h₃, data.hc₁₃ r hr pq pq' hpq])).inv := by + subst hn₁' h₀ h₁ h₂ h₃ h₄ h₅ + obtain rfl : n₀ = data.deg pq - 1 := by lia + obtain rfl : n₂ = data.deg pq + 1 := by lia + obtain rfl : n₃ = data.deg pq + 2 := by lia + dsimp [paged, pageXIso] + rw [dif_pos hpq, id_comp] + rfl + +@[reassoc (attr := simp)] +lemma paged_paged (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) : + paged X data r hr pq pq' ≫ paged X data r hr pq' pq'' = 0 := by + by_cases hpq : (c r).Rel pq pq' + · by_cases hpq' : (c r).Rel pq' pq'' + · let f₁ := homOfLE (data.le₀₁ r hr pq'') + let f₂ := homOfLE (data.le₁₂ pq'') + let f₃ := homOfLE (data.le₂₃ r hr pq'') + let f₄ : data.i₃ r hr pq'' ⟶ data.i₀ r hr pq := homOfLE (by + simpa only [← data.hc₁₃ r hr pq' pq'' hpq', + data.hc₀₂ r hr pq pq' hpq] using data.le₁₂ pq') + let f₅ := homOfLE (data.le₀₁ r hr pq) + let f₆ := homOfLE (data.le₁₂ pq) + let f₇ := homOfLE (data.le₂₃ r hr pq) + rw [paged_eq X data r hr pq pq' hpq (data.deg pq - 1) (data.deg pq) _ _ (by simp) + rfl rfl f₃ f₄ f₅ f₆ f₇ rfl (data.hc₀₂ r hr pq' pq'' hpq').symm + (data.hc₁₃ r hr pq' pq'' hpq').symm rfl rfl rfl rfl, + paged_eq X data r hr pq' pq'' hpq' (data.deg pq) _ _ _ rfl rfl rfl f₁ f₂ f₃ f₄ f₅ + (data.hc r hr pq pq' hpq) rfl rfl (data.hc₀₂ r hr pq' pq'' hpq').symm + (data.hc₁₃ r hr pq' pq'' hpq').symm (data.hc₀₂ r hr pq pq' hpq) + (data.hc₁₃ r hr pq pq' hpq), assoc, assoc, Iso.inv_hom_id_assoc, + d_d_assoc, zero_comp, comp_zero] + · dsimp only [paged] + rw [dif_neg hpq', comp_zero] + · dsimp only [paged] + rw [dif_neg hpq, zero_comp] + +@[simps] +noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : + HomologicalComplex C (c r) where + X pq := pageX X data r hr pq + d := paged X data r hr + shape pq pq' hpq := dif_neg hpq + +section + +noncomputable def shortComplexIso (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) + (hpq : (c r).Rel pq pq') (hpq' : (c r).Rel pq' pq'') + (n₀ n₁ n₂ n₃ n₄ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) (hn₄ : n₃ + 1 = n₄) + (hn₂' : n₂ = data.deg pq') : + (page X data r hr).sc' pq pq' pq'' ≅ + X.dShortComplex n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ (homOfLE (data.le₀₁ r hr pq'')) + (homOfLE (data.le₁₂ pq'')) (homOfLE (data.le₂₃ r hr pq'')) + (homOfLE (by simpa only [← data.hc₁₃ r hr pq' pq'' hpq', data.hc₀₂ r hr pq pq' hpq] + using data.le₁₂ pq')) (homOfLE (data.le₀₁ r hr pq)) + (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r hr pq)) := by + refine ShortComplex.isoMk + (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr pq pq' hpq; lia) + _ _ _ _ rfl rfl rfl rfl) + (pageXIso X data _ _ _ _ _ _ _ _ hn₂' _ _ _ _ + (by rw [data.hc₀₂ r hr pq' pq'' hpq']) (by rw [data.hc₁₃ r hr pq' pq'' hpq']) + (by rw [data.hc₀₂ r hr pq pq' hpq]) (by rw [data.hc₁₃ r hr pq pq' hpq])) + (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr pq' pq'' hpq'; lia) + _ _ _ _ rfl rfl rfl rfl) ?_ ?_ + · dsimp + rw [paged_eq X data r hr pq pq' hpq, assoc, assoc, Iso.inv_hom_id, comp_id] + · exact (data.hc₀₂ r hr pq' pq'' hpq').symm + · exact (data.hc₁₃ r hr pq' pq'' hpq').symm + · dsimp + rw [paged_eq X data r hr pq' pq'' hpq', assoc, assoc, Iso.inv_hom_id, comp_id] + · rfl + · rfl + +section + +variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq pq' pq'' : κ) (hpq : (c r).prev pq' = pq) (hpq' : (c r).next pq' = pq'') + (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + (hn₁' : n₁ = data.deg pq') + (i₀' i₀ i₁ i₂ i₃ i₃' : ι) + (hi₀' : i₀' = data.i₀ r' (hr.trans ((@Int.le_add_one r r (le_refl _)).trans hrr'.le)) pq') + (hi₀ : i₀ = data.i₀ r hr pq') + (hi₁ : i₁ = data.i₁ pq') + (hi₂ : i₂ = data.i₂ pq') + (hi₃ : i₃ = data.i₃ r hr pq') + (hi₃' : i₃' = data.i₃ r' (hr.trans ((@Int.le_add_one r r (le_refl _)).trans hrr'.le)) pq') + +namespace HomologyData + +def f₁ : i₀' ⟶ i₀ := homOfLE (by simpa only [hi₀, hi₀'] using data.i₀_le r r' hrr' hr pq') +def f₂ : i₀ ⟶ i₁ := homOfLE (by simpa only [hi₀, hi₁] using data.le₀₁ r hr pq') +def f₃ : i₁ ⟶ i₂ := homOfLE (by simpa only [hi₁, hi₂] using data.le₁₂ pq') +def f₄ : i₂ ⟶ i₃ := homOfLE (by simpa only [hi₂, hi₃] using data.le₂₃ r hr pq') +def f₅ : i₃ ⟶ i₃' := homOfLE (by simpa only [hi₃, hi₃'] using data.i₃_le r r' hrr' hr pq') + +section + +variable {r r'} {i₀' i₀ i₁ i₂ i₃ i₃'} + +include hi₀ hi₀' in +lemma le₀'₀ : i₀' ≤ i₀ := by simpa only [hi₀, hi₀'] using data.i₀_le r r' hrr' hr pq' +include hi₀ hi₁ in +lemma le₀₁ : i₀ ≤ i₁ := by simpa only [hi₀, hi₁] using data.le₀₁ r hr pq' +include hi₁ hi₂ in +lemma le₁₂ : i₁ ≤ i₂ := by simpa only [hi₁, hi₂] using data.le₁₂ pq' +include hi₂ hi₃ in +lemma le₂₃ : i₂ ≤ i₃ := by simpa only [hi₂, hi₃] using data.le₂₃ r hr pq' +include hi₃ hi₃' in +lemma le₃₃' : i₃ ≤ i₃' := by simpa only [hi₃, hi₃'] using data.i₃_le r r' hrr' hr pq' + +end + +noncomputable def mk₃π := + fourδ₄Toδ₃ (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀ ≫ f₂ data r hr pq' i₀ i₁ hi₀ hi₁) + (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) + (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') _ rfl + +instance : Epi (X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ + (mk₃π data r r' hrr' hr pq' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃')) := by + dsimp only [mk₃π] + infer_instance + +lemma mk₃fac : + fourδ₁Toδ₀' i₀' i₀ i₁ i₂ i₃ (le₀'₀ data hrr' hr pq' hi₀' hi₀) + (le₀₁ data hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃) ≫ + fourδ₄Toδ₃' i₀ i₁ i₂ i₃ i₃' _ _ _ (le₃₃' data hrr' hr pq' hi₃ hi₃') = + fourδ₄Toδ₃' i₀' i₁ i₂ i₃ i₃' _ _ _ (le₃₃' data hrr' hr pq' hi₃ hi₃') ≫ + fourδ₁Toδ₀' i₀' i₀ i₁ i₂ i₃' (le₀'₀ data hrr' hr pq' hi₀' hi₀) _ _ _ := by + rfl + +lemma kf_w : + (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃ (le₀'₀ data hrr' hr pq' hi₀' hi₀) + (le₀₁ data hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃) ≫ + (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).inv) ≫ + (page X data r hr).d pq' pq'' = 0 := by + by_cases h : (c r).Rel pq' pq'' + · dsimp + rw [paged_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl + (homOfLE (by simpa only [hi₀', data.i₀_prev r r' hrr' hr _ _ h] using data.le₀₁ r hr pq'')) + (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) + (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) hn₁' + rfl (by rw [hi₀', data.i₀_prev r r' hrr' hr pq' pq'' h]) hi₀ hi₁ hi₂ hi₃, + assoc, Iso.inv_hom_id_assoc] + erw [EMap_fourδ₁Toδ₀_d_assoc, zero_comp] + · rw [HomologicalComplex.shape _ _ _ h, comp_zero] + +@[simp] +noncomputable def kf : KernelFork ((page X data r hr).d pq' pq'') := + KernelFork.ofι _ (kf_w X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) + +@[simps!] +noncomputable def ksSc : ShortComplex C := + ShortComplex.mk _ _ (kf_w X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) + +instance : Mono (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).f := by + dsimp + infer_instance + +variable [X.HasSpectralSequence data] in +include hpq' hn₁' in +lemma isIso_EMapFourδ₁Toδ₀' (h : ¬ (c r).Rel pq' pq'') : + IsIso (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ + i₀' i₀ i₁ i₂ i₃ (le₀'₀ data hrr' hr pq' hi₀' hi₀) (le₀₁ data hr pq' hi₀ hi₁) + (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃)) := by + apply X.isIso_EMap_fourδ₁Toδ₀_of_isZero + refine X.isZero_H_obj_mk₁_i₀_le' data r r' hrr' hr pq' + (fun k hk ↦ ?_) _ (by lia) _ _ hi₀' hi₀ + obtain rfl := (c r).next_eq' hk + subst hpq' + exact h hk + +variable [X.HasSpectralSequence data] in +include hpq' in +lemma ksSc_exact : (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).Exact := by + by_cases h : (c r).Rel pq' pq'' + · refine ShortComplex.exact_of_iso (Iso.symm ?_) + (X.dKernelSequence_exact n₀ n₁ n₂ _ hn₁ hn₂ rfl + (homOfLE (show data.i₀ r hr pq'' ≤ i₀' by + simpa only [hi₀', data.i₀_prev r r' hrr' hr _ _ h] using data.le₀₁ r hr pq'')) + (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) + (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) _ rfl) + refine ShortComplex.isoMk (Iso.refl _) + (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) + (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr _ _ h; lia) _ _ _ _ + rfl (by rw [hi₀', data.i₀_prev r r' hrr' hr _ _ h]) (by rw [hi₀, data.hc₀₂ r hr _ _ h]) + (by rw [hi₁, data.hc₁₃ r hr _ _ h])) ?_ ?_ + · dsimp + rw [id_comp, assoc, Iso.inv_hom_id, comp_id] + rfl + · dsimp + rw [paged_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl + (homOfLE (show data.i₀ r hr pq'' ≤ i₀' by + simpa only [hi₀', data.i₀_prev r r' hrr' hr _ _ h] using data.le₀₁ r hr pq'')) + (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) + (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃), assoc, assoc, + Iso.inv_hom_id, comp_id] + · rfl + · rw [hi₀', data.i₀_prev r r' hrr' hr _ _ h] + · rw [ShortComplex.exact_iff_epi]; swap + · exact (page X data r hr).shape _ _ h + have := isIso_EMapFourδ₁Toδ₀' X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ + hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃ h + apply epi_comp + +variable [X.HasSpectralSequence data] in +noncomputable def hkf : + IsLimit (kf X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) := + (ksSc_exact X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).fIsKernel + +lemma cc_w : + (page X data r hr).d pq pq' ≫ + (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).hom ≫ + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₃' _ _ _ + (le₃₃' data hrr' hr pq' hi₃ hi₃') = 0 := by + by_cases h : (c r).Rel pq pq' + · dsimp + rw [paged_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ + (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) + (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) + (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') + (homOfLE (by simpa only [hi₃', data.i₃_next r r' hrr' hr _ _ h] using data.le₂₃ r hr pq)) + (by have := data.hc r hr pq pq' h; lia) hi₀ hi₁ (by rw [hi₂, data.hc₀₂ r hr _ _ h]) + (by rw [hi₃, data.hc₁₃ r hr _ _ h]) (by rw [hi₃', data.i₃_next r r' hrr' hr _ _ h]) rfl, + assoc, assoc, Iso.inv_hom_id_assoc] + erw [d_EMap_fourδ₄Toδ₃] + rw [comp_zero] + · rw [HomologicalComplex.shape _ _ _ h, zero_comp] + +@[simp] +noncomputable def cc : CokernelCofork ((page X data r hr).d pq pq') := + CokernelCofork.ofπ _ + (cc_w X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') + +@[simps!] +noncomputable def ccSc : ShortComplex C := + ShortComplex.mk _ _ (cc_w X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') + +instance : Epi (ccSc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').g := by + refine @epi_comp _ _ _ _ _ _ inferInstance _ ?_ + apply epi_EMap + all_goals rfl + +variable [X.HasSpectralSequence data] in +include hpq hn₁' in +lemma isIso_EMapFourδ₄Toδ₃' (h : ¬ (c r).Rel pq pq') : + IsIso (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₃' + (le₀₁ data hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) + (le₂₃ data hr pq' hi₂ hi₃) (le₃₃' data hrr' hr pq' hi₃ hi₃')) := by + apply X.isIso_EMap_fourδ₄Toδ₃_of_isZero + refine X.isZero_H_obj_mk₁_i₃_le' data r r' hrr' hr pq' ?_ _ (by lia) _ _ hi₃ hi₃' + intro k hk + obtain rfl := (c r).prev_eq' hk + subst hpq + exact h hk + +variable [X.HasSpectralSequence data] in +include hpq in +lemma ccSc_exact : + (ccSc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').Exact := by + by_cases h : (c r).Rel pq pq' + · refine ShortComplex.exact_of_iso (Iso.symm ?_) + (X.dCokernelSequence_exact (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ + (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) + (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) + (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') + (show i₃' ⟶ data.i₃ r hr pq from homOfLE (by + simpa only [hi₃', data.i₃_next r r' hrr' hr _ _ h] using data.le₂₃ r hr pq)) _ rfl) + refine ShortComplex.isoMk + (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr _ _ h; lia) _ _ _ _ + (by rw [hi₂, data.hc₀₂ r hr _ _ h]) (by rw [hi₃, data.hc₁₃ r hr _ _ h]) + (by rw [hi₃', data.i₃_next r r' hrr' hr _ _ h]) rfl) + (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) (Iso.refl _) ?_ ?_ + · dsimp + rw [paged_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ + (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) (f₃ data pq' i₁ i₂ hi₁ hi₂) + (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃'), + assoc, assoc, Iso.inv_hom_id, comp_id] + · exact hi₀ + · exact hi₁ + · dsimp + rw [comp_id, Iso.cancel_iso_hom_left] + rfl + · rw [ShortComplex.exact_iff_mono]; swap + · exact (page X data r hr).shape _ _ h + have := isIso_EMapFourδ₄Toδ₃' X data r r' hrr' hr pq pq' hpq n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃' h + dsimp + infer_instance + +variable [X.HasSpectralSequence data] in +noncomputable def hcc : + IsColimit (cc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') := + (ccSc_exact X data r r' hrr' hr pq pq' hpq n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').gIsCokernel + +lemma fac : + (kf X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).ι ≫ + (cc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').π = + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀' i₁ i₂ i₃ i₃' _ _ _ (le₃₃' data hrr' hr pq' hi₃ hi₃') ≫ + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃' + (le₀'₀ data hrr' hr pq' hi₀' hi₀) _ _ _ := by + dsimp + simpa only [assoc, Iso.inv_hom_id_assoc, EMap_comp] using + congr_arg (X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _) + (mk₃fac data r r' hrr' hr pq' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃') + +end HomologyData + +variable [X.HasSpectralSequence data] + +open HomologyData in +@[simps!] +noncomputable def homologyData : ((page X data r hr).sc' pq pq' pq'').HomologyData := + ShortComplex.HomologyData.ofEpiMonoFactorisation + ((page X data r hr).sc' pq pq' pq'') + (hkf X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) + (hcc X data r r' hrr' hr pq pq' hpq n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') + (fac X data r r' hrr' hr pq pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' + hi₀' hi₀ hi₁ hi₂ hi₃ hi₃') + +/-- homologyIso' -/ +noncomputable def homologyIso' : + ((page X data r hr).sc' pq pq' pq'').homology ≅ (page X data r' (by lia)).X pq' := + (homologyData X data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.homologyIso ≪≫ + (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀' hi₁ hi₂ hi₃').symm + +noncomputable def homologyIso : + (page X data r hr).homology pq' ≅ + (page X data r' (hr.trans (by rw [← hrr']; exact Int.le.intro 1 rfl))).X pq' := + homologyIso' X data r r' hrr' hr _ pq' _ rfl rfl + (data.deg pq' - 1) (data.deg pq') (data.deg pq' + 1) (by simp) + rfl rfl _ _ _ _ _ _ rfl rfl rfl rfl rfl rfl + +end + +end + +end SpectralSequence + +section + +variable [X.HasSpectralSequence data] in +noncomputable def spectralSequence : SpectralSequence C c r₀ where + page := SpectralSequence.page X data + iso r r' pq hrr' hr := SpectralSequence.homologyIso X data r r' hrr' hr pq + +@[nolint unusedArguments] +abbrev i₀ (_ : SpectralObject C ι) (data : SpectralSequenceMkData ι c r₀) + (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : ι := + data.i₀ r hr pq + +@[nolint unusedArguments] +abbrev i₃ (_ : SpectralObject C ι) (data : SpectralSequenceMkData ι c r₀) + (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : ι := + data.i₃ r hr pq + +lemma antitone_i₀ (r r' : ℤ) (hrr' : r ≤ r') (hr : r₀ ≤ r) (pq : κ) + {i₀ i₀' : ι} + (hi₀ : i₀ = X.i₀ data r pq) (hi₀' : i₀' = X.i₀ data r' pq) : + i₀' ≤ i₀ := by + rw [hi₀, hi₀'] + apply data.antitone_i₀ + exact hrr' + +lemma monotone_i₃ (r r' : ℤ) (hrr' : r ≤ r') (hr : r₀ ≤ r) (pq : κ) + {i₃ i₃' : ι} + (hi₃ : i₃ = X.i₃ data r pq) (hi₃' : i₃' = X.i₃ data r' pq) : + i₃ ≤ i₃' := by + rw [hi₃, hi₃'] + apply data.monotone_i₃ + exact hrr' + +lemma le₀'₀ {r r' : ℤ} (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq' : κ) + {i₀' i₀ : ι} + (hi₀' : i₀' = X.i₀ data r' pq') + (hi₀ : i₀ = X.i₀ data r pq') : + i₀' ≤ i₀ := by + rw [hi₀', hi₀] + apply data.antitone_i₀ + lia + +lemma le₀₁ (r : ℤ) (hr : r₀ ≤ r) (pq' : κ) + {i₀ i₁ : ι} + (hi₀ : i₀ = X.i₀ data r pq') + (hi₁ : i₁ = data.i₁ pq') : + i₀ ≤ i₁ := by + simpa only [hi₀, hi₁] using data.le₀₁ r _ pq' + +@[nolint unusedArguments] +lemma le₁₂ (_ : SpectralObject C ι) + (data : SpectralSequenceMkData ι c r₀) + (pq' : κ) {i₁ i₂ : ι} (hi₁ : i₁ = data.i₁ pq') (hi₂ : i₂ = data.i₂ pq') : + i₁ ≤ i₂ := by + simpa only [hi₁, hi₂] using data.le₁₂ pq' + +lemma le₂₃ (r : ℤ) (hr : r₀ ≤ r) (pq' : κ) + {i₂ i₃ : ι} + (hi₂ : i₂ = data.i₂ pq') + (hi₃ : i₃ = X.i₃ data r pq') : + i₂ ≤ i₃ := by + simpa only [hi₂, hi₃] using data.le₂₃ r _ pq' + +/-- le₃₃' -/ +lemma le₃₃' {r r' : ℤ} (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq' : κ) + {i₃ i₃' : ι} + (hi₃ : i₃ = X.i₃ data r pq') + (hi₃' : i₃' = X.i₃ data r' pq') : + i₃ ≤ i₃' := by + rw [hi₃, hi₃'] + apply data.monotone_i₃ + lia + +variable [X.HasSpectralSequence data] + +noncomputable def spectralSequencePageXIso (r : ℤ) (hr : r₀ ≤ r) + (pq : κ) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) + (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = X.i₀ data r pq) + (h₁ : i₁ = data.i₁ pq) (h₂ : i₂ = data.i₂ pq) + (h₃ : i₃ = X.i₃ data r pq) : + ((X.spectralSequence data).page r).X pq ≅ + X.E n₀ n₁ n₂ hn₁ hn₂ + (homOfLE (X.le₀₁ data r hr pq h₀ h₁)) + (homOfLE (X.le₁₂ data pq h₁ h₂)) + (homOfLE (X.le₂₃ data r hr pq h₂ h₃)) := + SpectralSequence.pageXIso X data _ _ _ _ _ _ _ _ h _ _ _ _ h₀ h₁ h₂ h₃ + +lemma spectralSequence_page_d_eq (r : ℤ) (hr : r₀ ≤ r) + (pq pq' : κ) (hpq : (c r).Rel pq pq') + (n₀ n₁ n₂ n₃ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) + {i₀ i₁ i₂ i₃ i₄ i₅ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) (hn₁' : n₁ = data.deg pq) + (h₀ : i₀ = X.i₀ data r pq') (h₁ : i₁ = data.i₁ pq') + (h₂ : i₂ = X.i₀ data r pq) + (h₃ : i₃ = data.i₁ pq) (h₄ : i₄ = data.i₂ pq) (h₅ : i₅ = X.i₃ data r pq) : + ((X.spectralSequence data).page r).d pq pq' = + (X.spectralSequencePageXIso data r hr _ _ _ _ _ _ hn₁' _ _ _ _ h₂ h₃ h₄ h₅).hom ≫ + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ + (X.spectralSequencePageXIso data r hr _ _ _ _ _ _ + (by simpa only [← hn₂, hn₁'] using data.hc r hr pq pq' hpq) _ _ _ _ h₀ h₁ + (by rw [h₂, ← data.hc₀₂ r _ pq pq' hpq]) + (by rw [h₃, data.hc₁₃ r _ pq pq' hpq])).inv := by + apply SpectralSequence.paged_eq + exact hpq + +lemma isZero_spectralSequence_page_X_iff (r : ℤ) (hr : r₀ ≤ r) (pq : κ) + (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) + (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = X.i₀ data r pq) + (h₁ : i₁ = data.i₁ pq) (h₂ : i₂ = data.i₂ pq) + (h₃ : i₃ = X.i₃ data r pq) : + IsZero (((X.spectralSequence data).page r).X pq) ↔ + IsZero (X.E n₀ n₁ n₂ hn₁ hn₂ + (homOfLE (X.le₀₁ data r hr pq h₀ h₁)) + (homOfLE (X.le₁₂ data pq h₁ h₂)) + (homOfLE (X.le₂₃ data r hr pq h₂ h₃))) := + Iso.isZero_iff (X.spectralSequencePageXIso data r hr pq n₀ n₁ n₂ hn₁ hn₂ h i₀ i₁ i₂ i₃ + h₀ h₁ h₂ h₃) + +lemma isZero_spectralSequence_page_X_of_isZero_H (r : ℤ) (hr : r₀ ≤ r) + (pq : κ) (n : ℤ) (hn : n = data.deg pq) + (i₁ i₂ : ι) (h₁ : i₁ = data.i₁ pq) (h₂ : i₂ = data.i₂ pq) + (h : IsZero ((X.H n).obj + (mk₁ (homOfLE (by simpa only [h₁, h₂] using data.le₁₂ pq) : i₁ ⟶ i₂)))) : + IsZero (((X.spectralSequence data).page r).X pq) := by + rw [X.isZero_spectralSequence_page_X_iff data r hr pq (n - 1) n (n + 1) (by simp) rfl hn + _ i₁ i₂ _ rfl h₁ h₂ rfl] + apply isZero_E_of_isZero_H + exact h + +/-- isZero_spectralSequence_page_X_of_isZero_H' -/ +lemma isZero_spectralSequence_page_X_of_isZero_H' (r : ℤ) (hr : r₀ ≤ r) + (pq : κ) + (h : IsZero ((X.H (data.deg pq)).obj (mk₁ (homOfLE (data.le₁₂ pq))))) : + IsZero (((X.spectralSequence data).page r).X pq) := + X.isZero_spectralSequence_page_X_of_isZero_H data r hr pq _ rfl _ _ rfl rfl h + +section +variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) + (pq pq' pq'' : κ) (hpq : (c r).prev pq' = pq) (hpq' : (c r).next pq' = pq'') + (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + (hn₁' : n₁ = data.deg pq') + (i₀' i₀ i₁ i₂ i₃ i₃' : ι) + (hi₀' : i₀' = X.i₀ data r' pq') + (hi₀ : i₀ = X.i₀ data r pq') + (hi₁ : i₁ = data.i₁ pq') + (hi₂ : i₂ = data.i₂ pq') + (hi₃ : i₃ = X.i₃ data r pq') + (hi₃' : i₃' = X.i₃ data r' pq') + +@[simps! left_K left_H left_π right_Q right_H right_ι iso_hom iso_inv] +noncomputable def spectralSequenceHomologyData : + (((X.spectralSequence data).page r hr).sc' pq pq' pq'').HomologyData := + SpectralSequence.homologyData X data r r' hrr' hr + pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃' + +@[simp] +lemma spectralSequenceHomologyData_left_i : + (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.i = + X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃ + (X.le₀'₀ data hrr' hr pq' hi₀' hi₀) _ _ _ ≫ + (X.spectralSequencePageXIso data r hr pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ hi₀ hi₁ hi₂ hi₃).inv := rfl + +@[simp] +lemma spectralSequenceHomologyData_right_p : + (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').right.p = + (X.spectralSequencePageXIso data r hr pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀ i₁ i₂ i₃ hi₀ hi₁ hi₂ hi₃).hom ≫ + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₃' _ _ _ + (X.le₃₃' data hrr' hr pq' hi₃ hi₃') := rfl + +lemma spectralSequenceHomologyData_right_homologyIso_eq_left_homologyIso : + (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').right.homologyIso = + (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.homologyIso := by + ext1 + rw [ShortComplex.HomologyData.right_homologyIso_eq_left_homologyIso_trans_iso] + dsimp + rw [comp_id] + +end + +end + +section + +variable (Y : SpectralObject C EInt) + +noncomputable abbrev E₂SpectralSequence : E₂CohomologicalSpectralSequence C := + Y.spectralSequence mkDataE₂Cohomological + +section + +variable [Y.IsFirstQuadrant] + +example (r : ℤ) (hr : 2 ≤ r) (p q : ℤ) (hq : q < 0) : + IsZero ((Y.E₂SpectralSequence.page r).X ⟨p, q⟩) := by + apply isZero_spectralSequence_page_X_of_isZero_H' _ _ _ hr + apply Y.isZero₁_of_isFirstQuadrant + simp + lia + +example (r : ℤ) (hr : 2 ≤ r) (p q : ℤ) (hp : p < 0) : + IsZero ((Y.E₂SpectralSequence.page r).X ⟨p, q⟩) := by + apply isZero_spectralSequence_page_X_of_isZero_H' _ _ _ hr + apply Y.isZero₂_of_isFirstQuadrant + simp + lia + +noncomputable abbrev E₂SpectralSequenceNat := Y.spectralSequence mkDataE₂CohomologicalNat + +end + +section + +variable [Y.IsThirdQuadrant] + +example (r : ℤ) (hr : 2 ≤ r) (p q : ℤ) (hq : 0 < q) : + IsZero ((Y.E₂SpectralSequence.page r).X ⟨p, q⟩) := by + apply isZero_spectralSequence_page_X_of_isZero_H' _ _ _ hr + apply Y.isZero₁_of_isThirdQuadrant + simp + lia + +example (r : ℤ) (hr : 2 ≤ r) (p q : ℤ) (hp : 0 < p) : + IsZero ((Y.E₂SpectralSequence.page r).X ⟨p, q⟩) := by + apply isZero_spectralSequence_page_X_of_isZero_H' _ _ _ hr + apply Y.isZero₂_of_isThirdQuadrant + simp + lia + +noncomputable abbrev E₂HomologicalSpectralSequenceNat := Y.spectralSequence mkDataE₂HomologicalNat + +end + +end + +end SpectralObject + +end Abelian + +end CategoryTheory From 78d3403e246e8372d25bd25ee82a2f38218d4a05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 23:09:32 +0100 Subject: [PATCH 20/72] removed EInt.mk --- .../SpectralObject/HasSpectralSequence.lean | 40 +++++++++---------- .../Triangulated/TStructure/ETrunc.lean | 24 +++++------ Mathlib/Data/EInt/Basic.lean | 11 ++--- 3 files changed, 36 insertions(+), 39 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index 389269ffaa6d56..1df8cb53cd071a 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -130,10 +130,10 @@ indexed by `ℤ × ℤ` from a spectral object indexed by `EInt`. -/ def mkDataE₂Cohomological : SpectralSequenceMkData EInt (fun r ↦ ComplexShape.up' (⟨r, 1 - r⟩ : ℤ × ℤ)) 2 where deg pq := pq.1 + pq.2 - i₀ r hr pq := EInt.mk (pq.2 - r + 2) - i₁ pq := EInt.mk pq.2 - i₂ pq := EInt.mk (pq.2 + 1) - i₃ r hr pq := EInt.mk (pq.2 + r - 1) + i₀ r hr pq := (pq.2 - r + 2 :) + i₁ pq := pq.2 + i₂ pq := (pq.2 + 1 :) + i₃ r hr pq := (pq.2 + r - 1 :) le₀₁ r hr pq := by simp; lia le₁₂ pq := by simp le₂₃ r hr pq := by simp; lia @@ -153,10 +153,10 @@ def mkDataE₂CohomologicalNat : SpectralSequenceMkData EInt (fun r ↦ ComplexShape.spectralSequenceNat ⟨r, 1 - r⟩) 2 where deg pq := pq.1 + pq.2 - i₀ r hr pq := EInt.mk (pq.2 - r + 2) - i₁ pq := EInt.mk pq.2 - i₂ pq := EInt.mk (pq.2 + 1) - i₃ r hr pq := EInt.mk (pq.2 + r - 1) + i₀ r hr pq := (pq.2 - r + 2 :) + i₁ pq := (pq.2 : ℤ) + i₂ pq := (pq.2 + 1 : ℤ) + i₃ r hr pq := (pq.2 + r - 1 : ℤ) le₀₁ r hr pq := by simp; lia le₁₂ pq := by simp le₂₃ r hr pq := by simp; lia @@ -238,10 +238,10 @@ def mkDataE₂HomologicalNat : SpectralSequenceMkData EInt (fun r ↦ ComplexShape.spectralSequenceNat ⟨-r, r - 1⟩) 2 where deg pq := - pq.1 - pq.2 - i₀ r hr pq := EInt.mk (-pq.2 - r + 2) - i₁ pq := EInt.mk (-pq.2) - i₂ pq := EInt.mk (-pq.2 + 1) - i₃ r hr pq := EInt.mk (-pq.2 + r - 1) + i₀ r hr pq := (-pq.2 - r + 2 :) + i₁ pq := (-pq.2 : ℤ) + i₂ pq := (-pq.2 + 1 : ℤ) + i₃ r hr pq := (-pq.2 + r - 1 :) le₀₁ r hr pq := by simp; lia le₁₂ pq := by simp le₂₃ r hr pq := by simp; lia @@ -369,18 +369,18 @@ variable (Y : SpectralObject C EInt) /-- The conditions on a spectral object indexed by `EInt` which allow to obtain a (convergent) first quadrant `E₂` cohomological spectral sequence. -/ class IsFirstQuadrant : Prop where - isZero₁ (i j : EInt) (hij : i ≤ j) (hj : j ≤ EInt.mk 0) (n : ℤ) : + isZero₁ (i j : EInt) (hij : i ≤ j) (hj : j ≤ (0 : ℤ)) (n : ℤ) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) - isZero₂ (i j : EInt) (hij : i ≤ j) (n : ℤ) (hi : EInt.mk n < i) : + isZero₂ (i j : EInt) (hij : i ≤ j) (n : ℤ) (hi : n < i) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) variable [Y.IsFirstQuadrant] -lemma isZero₁_of_isFirstQuadrant (i j : EInt) (hij : i ≤ j) (hj : j ≤ EInt.mk 0) (n : ℤ) : +lemma isZero₁_of_isFirstQuadrant (i j : EInt) (hij : i ≤ j) (hj : j ≤ (0 : ℤ)) (n : ℤ) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := IsFirstQuadrant.isZero₁ i j hij hj n -lemma isZero₂_of_isFirstQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hi : EInt.mk n < i) : +lemma isZero₂_of_isFirstQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hi : n < i) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := IsFirstQuadrant.isZero₂ i j hij n hi @@ -416,18 +416,18 @@ variable (Y : SpectralObject C EInt) to obtain a (convergent) third quadrant `E₂` cohomological spectral sequence, or a (convergent) first quadrant `E₂` *homological* spectral sequence -/ class IsThirdQuadrant where - isZero₁ (i j : EInt) (hij : i ≤ j) (hi : EInt.mk 0 < i) (n : ℤ) : + isZero₁ (i j : EInt) (hij : i ≤ j) (hi : (0 : ℤ) < i) (n : ℤ) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) - isZero₂ (i j : EInt) (hij : i ≤ j) (n : ℤ) (hj : j ≤ EInt.mk n) : + isZero₂ (i j : EInt) (hij : i ≤ j) (n : ℤ) (hj : j ≤ n) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) variable [Y.IsThirdQuadrant] -lemma isZero₁_of_isThirdQuadrant (i j : EInt) (hij : i ≤ j) (hi : EInt.mk 0 < i) (n : ℤ) : +lemma isZero₁_of_isThirdQuadrant (i j : EInt) (hij : i ≤ j) (hi : (0 : ℤ) < i) (n : ℤ) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := IsThirdQuadrant.isZero₁ i j hij hi n -lemma isZero₂_of_isThirdQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hj : j ≤ EInt.mk n) : +lemma isZero₂_of_isThirdQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hj : j ≤ n) : IsZero ((Y.H n).obj (mk₁ (homOfLE hij))) := IsThirdQuadrant.isZero₂ i j hij n hj diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean index 5e0da4f7daf1a3..45a881b526b71d 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -71,11 +71,11 @@ lemma eTruncLT_obj_top : t.eTruncLT.obj ⊤ = 𝟭 _ := rfl lemma eTruncLT_obj_bot : t.eTruncLT.obj ⊥ = 0 := rfl @[simp] -lemma eTruncLT_obj_mk (n : ℤ) : t.eTruncLT.obj (EInt.mk n) = t.truncLT n := rfl +lemma eTruncLT_obj_coe (n : ℤ) : t.eTruncLT.obj n = t.truncLT n := rfl @[simp] lemma eTruncLT_map_eq_truncLTι (n : ℤ) : - t.eTruncLT.map (homOfLE (show EInt.mk n ≤ ⊤ by simp)) = t.truncLTι n := rfl + t.eTruncLT.map (homOfLE (show (n : EInt) ≤ ⊤ by simp)) = t.truncLTι n := rfl instance (i : EInt) : (t.eTruncLT.obj i).Additive := by induction i <;> constructor <;> cat_disch @@ -120,7 +120,7 @@ lemma eTruncGE_obj_top : t.eTruncGE.obj ⊤ = 0 := rfl @[simp] -lemma eTruncGE_obj_mk (n : ℤ) : t.eTruncGE.obj (EInt.mk n) = t.truncGE n := rfl +lemma eTruncGE_obj_coe (n : ℤ) : t.eTruncGE.obj n = t.truncGE n := rfl instance (i : EInt) : (t.eTruncGE.obj i).Additive := by induction i <;> constructor <;> cat_disch @@ -144,8 +144,8 @@ noncomputable def eTruncGEδLT : simp [t.truncGEδLT_comp_whiskerRight_natTransTruncLTOfLE] @[simp] -lemma eTruncGEδLT_mk (n : ℤ) : - t.eTruncGEδLT.app (EInt.mk n) = t.truncGEδLT n := rfl +lemma eTruncGEδLT_coe (n : ℤ) : + t.eTruncGEδLT.app n = t.truncGEδLT n := rfl /-- The natural transformation `t.eTruncLT.obj i ⟶ 𝟭 C` for all `i : EInt`. -/ noncomputable abbrev eTruncLTι (i : EInt) : t.eTruncLT.obj i ⟶ 𝟭 _ := @@ -245,7 +245,7 @@ instance (X : C) (n : ℤ) [t.IsGE X n] (i : EInt) : | coe _ => dsimp; infer_instance | top => exact isGE_of_isZero _ (by simp) _ -lemma isGE_eTruncGE_obj_obj (n : ℤ) (i : EInt) (h : EInt.mk n ≤ i) (X : C) : +lemma isGE_eTruncGE_obj_obj (n : ℤ) (i : EInt) (h : n ≤ i) (X : C) : t.IsGE ((t.eTruncGE.obj i).obj X) n := by induction i with | bot => simp at h @@ -254,7 +254,7 @@ lemma isGE_eTruncGE_obj_obj (n : ℤ) (i : EInt) (h : EInt.mk n ≤ i) (X : C) : exact t.isGE_of_GE _ _ _ (by simpa using h) | top => exact t.isGE_of_isZero (Functor.zero_obj _) _ -lemma isLE_eTruncLT_obj_obj (n : ℤ) (i : EInt) (h : i ≤ EInt.mk (n + 1)) (X : C) : +lemma isLE_eTruncLT_obj_obj (n : ℤ) (i : EInt) (h : i ≤ (n + 1 :)) (X : C) : t.IsLE (((t.eTruncLT.obj i)).obj X) n := by induction i with | bot => exact t.isLE_of_isZero (by simp) _ @@ -264,7 +264,7 @@ lemma isLE_eTruncLT_obj_obj (n : ℤ) (i : EInt) (h : i ≤ EInt.mk (n + 1)) (X exact t.isLE_of_LE _ (i - 1) n (by lia) | top => simp at h -lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j ≤ EInt.mk n) : +lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j ≤ n) : IsZero ((t.eTruncLT.obj j).obj X) := by induction j with | bot => simp @@ -273,7 +273,7 @@ lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j exact t.isZero_truncLT_obj_of_isGE _ _ | top => simp at hj -lemma isZero_eTruncGE_obj_obj (X : C) (n : ℤ) [t.IsLE X n] (j : EInt) (hj : EInt.mk n < j) : +lemma isZero_eTruncGE_obj_obj (X : C) (n : ℤ) [t.IsLE X n] (j : EInt) (hj : n < j) : IsZero ((t.eTruncGE.obj j).obj X) := by induction j with | bot => simp at hj @@ -454,11 +454,11 @@ instance : IsIso (t.eTruncLTGELTSelfToLTGE a b) := by induction a with | bot => simpa using inferInstanceAs (IsIso ((t.truncLT b).map ((t.truncLTι b).app X))) | coe a => - simp only [eTruncLT_obj_mk, eTruncGE_obj_mk, Functor.comp_obj, eTruncLTGELTSelfToLTGE_app, + simp only [eTruncLT_obj_coe, eTruncGE_obj_coe, Functor.comp_obj, eTruncLTGELTSelfToLTGE_app, eTruncLT_map_eq_truncLTι] infer_instance | top => - simp only [eTruncLT_obj_mk, eTruncGE_obj_top, Functor.comp_obj, eTruncLTGELTSelfToLTGE_app, + simp only [eTruncLT_obj_coe, eTruncGE_obj_top, Functor.comp_obj, eTruncLTGELTSelfToLTGE_app, eTruncLT_map_eq_truncLTι, zero_map, Functor.map_zero, isIsoZero_iff_source_target_isZero] constructor all_goals exact Functor.map_isZero _ (Functor.zero_obj _) @@ -476,7 +476,7 @@ instance : IsIso (t.eTruncLTGELTSelfToGELT a b) := by | bot => simpa [isIsoZero_iff_source_target_isZero] using (t.eTruncGE.obj a).map_isZero (Functor.zero_obj _) | coe b => - simp only [eTruncLT_obj_mk, eTruncGE_obj_mk, Functor.comp_obj, eTruncLTGELTSelfToGELT_app, + simp only [eTruncLT_obj_coe, eTruncGE_obj_coe, Functor.comp_obj, eTruncLTGELTSelfToGELT_app, eTruncLT_map_eq_truncLTι] infer_instance | top => simpa using inferInstanceAs (IsIso (𝟙 _)) diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean index 7397e3be68f3c2..d0a286e212d96e 100644 --- a/Mathlib/Data/EInt/Basic.lean +++ b/Mathlib/Data/EInt/Basic.lean @@ -41,9 +41,6 @@ theorem coe_injective : Function.Injective Int.toEInt := lemma coe_monotone : Monotone Int.toEInt := coe_strictMono.monotone -/-- The constructor `ℤ → EInt`. -/ -abbrev mk (a : ℤ) : EInt := a - section variable {motive : EInt → Sort*} @@ -64,23 +61,23 @@ end @[simp] lemma coe_le_coe_iff (a b : ℤ) : - mk a ≤ mk b ↔ a ≤ b := + (a : EInt) ≤ b ↔ a ≤ b := coe_strictMono.le_iff_le @[simp] lemma coe_lt_coe_iff (a b : ℤ) : - mk a < mk b ↔ a < b := + (a : EInt) < b ↔ a < b := coe_strictMono.lt_iff_lt @[simp] lemma coe_eq_bot_iff (a : ℤ) : - EInt.mk a = ⊥ ↔ False := by + (a : EInt) = ⊥ ↔ False := by simp only [iff_false] rintro ⟨⟩ @[simp] lemma coe_eq_top_iff (a : ℤ) : - EInt.mk a = ⊤ ↔ False := by + (a : EInt) = ⊤ ↔ False := by simp only [iff_false] rintro ⟨⟩ From 766326ee100566aa2a2b69cc99a950d8332db756 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 23:11:14 +0100 Subject: [PATCH 21/72] removed EInt.mk --- Mathlib/Data/EInt/Basic.lean | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean index 7397e3be68f3c2..d0a286e212d96e 100644 --- a/Mathlib/Data/EInt/Basic.lean +++ b/Mathlib/Data/EInt/Basic.lean @@ -41,9 +41,6 @@ theorem coe_injective : Function.Injective Int.toEInt := lemma coe_monotone : Monotone Int.toEInt := coe_strictMono.monotone -/-- The constructor `ℤ → EInt`. -/ -abbrev mk (a : ℤ) : EInt := a - section variable {motive : EInt → Sort*} @@ -64,23 +61,23 @@ end @[simp] lemma coe_le_coe_iff (a b : ℤ) : - mk a ≤ mk b ↔ a ≤ b := + (a : EInt) ≤ b ↔ a ≤ b := coe_strictMono.le_iff_le @[simp] lemma coe_lt_coe_iff (a b : ℤ) : - mk a < mk b ↔ a < b := + (a : EInt) < b ↔ a < b := coe_strictMono.lt_iff_lt @[simp] lemma coe_eq_bot_iff (a : ℤ) : - EInt.mk a = ⊥ ↔ False := by + (a : EInt) = ⊥ ↔ False := by simp only [iff_false] rintro ⟨⟩ @[simp] lemma coe_eq_top_iff (a : ℤ) : - EInt.mk a = ⊤ ↔ False := by + (a : EInt) = ⊤ ↔ False := by simp only [iff_false] rintro ⟨⟩ From ffeca7df924af133044a21ddb45c4f02caff4984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Mon, 12 Jan 2026 23:56:18 +0100 Subject: [PATCH 22/72] fix --- Mathlib/Data/EInt/Basic.lean | 25 ++++++------------------- 1 file changed, 6 insertions(+), 19 deletions(-) diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean index d0a286e212d96e..4254158a6e7b5c 100644 --- a/Mathlib/Data/EInt/Basic.lean +++ b/Mathlib/Data/EInt/Basic.lean @@ -60,31 +60,18 @@ protected def rec : ∀ a : EInt, motive a end @[simp] -lemma coe_le_coe_iff (a b : ℤ) : +lemma coe_le_coe_iff {a b : ℤ} : (a : EInt) ≤ b ↔ a ≤ b := coe_strictMono.le_iff_le @[simp] -lemma coe_lt_coe_iff (a b : ℤ) : +lemma coe_lt_coe_iff {a b : ℤ} : (a : EInt) < b ↔ a < b := coe_strictMono.lt_iff_lt -@[simp] -lemma coe_eq_bot_iff (a : ℤ) : - (a : EInt) = ⊥ ↔ False := by - simp only [iff_false] - rintro ⟨⟩ - -@[simp] -lemma coe_eq_top_iff (a : ℤ) : - (a : EInt) = ⊤ ↔ False := by - simp only [iff_false] - rintro ⟨⟩ - -@[simp] -lemma top_eq_bot_iff : - (⊤ : EInt) = ⊥ ↔ False := by - simp only [iff_false] - exact ne_of_beq_false rfl +@[simp] lemma coe_ne_bot (a : ℤ) : (a : EInt) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma coe_ne_top (a : ℤ) : (a : EInt) ≠ ⊤ := by rintro ⟨⟩ +@[simp] lemma top_ne_bot : (⊤ : EInt) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma bot_ne_top : (⊤ : EInt) ≠ ⊥ := by rintro ⟨⟩ end EInt From 097c820168388ab96a6b9e66b403740d6ddfcac2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:07:31 +0100 Subject: [PATCH 23/72] Update Mathlib/Data/EInt/Basic.lean MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Violeta Hernández Palacios --- Mathlib/Data/EInt/Basic.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean index d0a286e212d96e..d119626d1aef31 100644 --- a/Mathlib/Data/EInt/Basic.lean +++ b/Mathlib/Data/EInt/Basic.lean @@ -70,8 +70,7 @@ lemma coe_lt_coe_iff (a b : ℤ) : coe_strictMono.lt_iff_lt @[simp] -lemma coe_eq_bot_iff (a : ℤ) : - (a : EInt) = ⊥ ↔ False := by +lemma coe_ne_bot (a : ℤ) : (a : EInt) ≠ ⊥ := by simp only [iff_false] rintro ⟨⟩ From 76afde790016a37d3683150e33aac10c728c9fb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= <37772949+joelriou@users.noreply.github.com> Date: Tue, 13 Jan 2026 09:07:39 +0100 Subject: [PATCH 24/72] Update Mathlib/Data/EInt/Basic.lean MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Violeta Hernández Palacios --- Mathlib/Data/EInt/Basic.lean | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean index d119626d1aef31..b133cfb7a04694 100644 --- a/Mathlib/Data/EInt/Basic.lean +++ b/Mathlib/Data/EInt/Basic.lean @@ -60,8 +60,7 @@ protected def rec : ∀ a : EInt, motive a end @[simp] -lemma coe_le_coe_iff (a b : ℤ) : - (a : EInt) ≤ b ↔ a ≤ b := +lemma coe_le_coe_iff {a b : ℤ} : (a : EInt) ≤ b ↔ a ≤ b := coe_strictMono.le_iff_le @[simp] From 0fa847111e3433014eeb11d4b0aaf15c81cde738 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 13 Jan 2026 09:11:21 +0100 Subject: [PATCH 25/72] better lemmas --- Mathlib/Data/EInt/Basic.lean | 24 ++++++------------------ 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean index b133cfb7a04694..e78af3cd72f804 100644 --- a/Mathlib/Data/EInt/Basic.lean +++ b/Mathlib/Data/EInt/Basic.lean @@ -60,29 +60,17 @@ protected def rec : ∀ a : EInt, motive a end @[simp] -lemma coe_le_coe_iff {a b : ℤ} : (a : EInt) ≤ b ↔ a ≤ b := +lemma coe_le_coe_iff {a b : ℤ} : + (a : EInt) ≤ b ↔ a ≤ b := coe_strictMono.le_iff_le @[simp] -lemma coe_lt_coe_iff (a b : ℤ) : +lemma coe_lt_coe_iff {a b : ℤ} : (a : EInt) < b ↔ a < b := coe_strictMono.lt_iff_lt -@[simp] -lemma coe_ne_bot (a : ℤ) : (a : EInt) ≠ ⊥ := by - simp only [iff_false] - rintro ⟨⟩ - -@[simp] -lemma coe_eq_top_iff (a : ℤ) : - (a : EInt) = ⊤ ↔ False := by - simp only [iff_false] - rintro ⟨⟩ - -@[simp] -lemma top_eq_bot_iff : - (⊤ : EInt) = ⊥ ↔ False := by - simp only [iff_false] - exact ne_of_beq_false rfl +@[simp] lemma coe_ne_bot (a : ℤ) : (a : EInt) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma coe_ne_top (a : ℤ) : (a : EInt) ≠ ⊤ := by rintro ⟨⟩ +@[simp] lemma top_ne_bot : (⊤ : EInt) ≠ ⊥ := by rintro ⟨⟩ end EInt From 08a57c002f9475b6b3ac97760e019a1651401050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 13 Jan 2026 09:39:50 +0100 Subject: [PATCH 26/72] fix --- Mathlib.lean | 1 + .../SpectralObject/HasSpectralSequence.lean | 8 +- .../Triangulated/TStructure/ETrunc.lean | 82 ++++++++++--------- .../TStructure/SpectralObject.lean | 2 +- Mathlib/Data/EInt/Basic.lean | 17 ++-- Mathlib/Order/WithBotTop.lean | 78 ++++++++++++++++++ 6 files changed, 135 insertions(+), 53 deletions(-) create mode 100644 Mathlib/Order/WithBotTop.lean diff --git a/Mathlib.lean b/Mathlib.lean index 41e1b305b346e6..b875477ba53549 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5690,6 +5690,7 @@ public import Mathlib.Order.WellFounded public import Mathlib.Order.WellFoundedSet public import Mathlib.Order.WellQuasiOrder public import Mathlib.Order.WithBot +public import Mathlib.Order.WithBotTop public import Mathlib.Order.Zorn public import Mathlib.Order.ZornAtoms public import Mathlib.Probability.BorelCantelli diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index 1df8cb53cd071a..f4a8c6e85e3f1e 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -389,7 +389,7 @@ instance : Y.HasSpectralSequence mkDataE₂CohomologicalNat where rintro r _ rfl hr ⟨p, q⟩ hpq n rfl apply isZero₁_of_isFirstQuadrant dsimp - simp only [EInt.coe_le_coe_iff] + simp only [WithBotTop.coe_le_coe] by_contra! obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p + r by lia) obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q + 1 - r by lia) @@ -399,7 +399,7 @@ instance : Y.HasSpectralSequence mkDataE₂CohomologicalNat where rintro r _ rfl hr ⟨p, q⟩ hpq n rfl apply isZero₂_of_isFirstQuadrant dsimp - simp only [EInt.coe_lt_coe_iff, Int.sub_lt_sub_right_iff] + simp only [WithBotTop.coe_lt_coe_iff] by_contra! obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p - r by lia) obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q - 1 + r by lia) @@ -436,7 +436,7 @@ instance : Y.HasSpectralSequence mkDataE₂HomologicalNat where rintro r _ rfl hr ⟨p, q⟩ hpq n rfl apply isZero₂_of_isThirdQuadrant dsimp - simp only [EInt.coe_le_coe_iff] + simp only [WithBotTop.coe_le_coe] by_contra! obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p - r by lia) obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q + r - 1 by lia) @@ -446,7 +446,7 @@ instance : Y.HasSpectralSequence mkDataE₂HomologicalNat where rintro r _ rfl hr ⟨p, q⟩ hpq n rfl apply isZero₁_of_isThirdQuadrant dsimp - simp only [EInt.coe_lt_coe_iff] + simp only [WithBotTop.coe_lt_coe_iff] by_contra! obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p + r by lia) obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q + 1 - r by lia) diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean index 45a881b526b71d..02003821be3582 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -37,32 +37,33 @@ variable (t : TStructure C) `n : ℤ` to `t.truncLT n` and `⊤` to `𝟭 C`. -/ noncomputable def eTruncLT : EInt ⥤ C ⥤ C where obj n := by - induction n with + induction n using WithBotTop.rec with | bot => exact 0 | coe a => exact t.truncLT a | top => exact 𝟭 C map {x y} f := by - induction x with + induction x using WithBotTop.rec with | bot => - induction y with + induction y using WithBotTop.rec with | bot => exact 𝟙 _ | coe b => exact 0 | top => exact 0 | coe a => - induction y with + induction y using WithBotTop.rec with | bot => exact 0 | coe b => exact t.natTransTruncLTOfLE a b (by simpa using leOfHom f) | top => exact t.truncLTι a | top => - induction y with + induction y using WithBotTop.rec with | bot => exact 0 | coe b => exact 0 | top => exact 𝟙 _ - map_id n := by induction n <;> simp + map_id n := by induction n using WithBotTop.rec <;> simp map_comp {x y z} f g := by have f' := leOfHom f have g' := leOfHom g - induction x <;> induction y <;> induction z <;> cat_disch + induction x using WithBotTop.rec <;> induction y using WithBotTop.rec <;> + induction z using WithBotTop.rec <;> cat_disch @[simp] lemma eTruncLT_obj_top : t.eTruncLT.obj ⊤ = 𝟭 _ := rfl @@ -78,38 +79,39 @@ lemma eTruncLT_map_eq_truncLTι (n : ℤ) : t.eTruncLT.map (homOfLE (show (n : EInt) ≤ ⊤ by simp)) = t.truncLTι n := rfl instance (i : EInt) : (t.eTruncLT.obj i).Additive := by - induction i <;> constructor <;> cat_disch + induction i using WithBotTop.rec <;> constructor <;> cat_disch /-- The functor `EInt ⥤ C ⥤ C` which sends `⊥` to `𝟭 C`, `n : ℤ` to `t.truncGE n` and `⊤` to the zero functor. -/ noncomputable def eTruncGE : EInt ⥤ C ⥤ C where obj n := by - induction n with + induction n using WithBotTop.rec with | bot => exact 𝟭 C | coe a => exact t.truncGE a | top => exact 0 map {x y} f := by - induction x with + induction x using WithBotTop.rec with | bot => - induction y with + induction y using WithBotTop.rec with | bot => exact 𝟙 _ | coe b => exact t.truncGEπ b | top => exact 0 | coe a => - induction y with + induction y using WithBotTop.rec with | bot => exact 0 | coe b => exact t.natTransTruncGEOfLE a b (by simpa using leOfHom f) | top => exact 0 | top => - induction y with + induction y using WithBotTop.rec with | bot => exact 0 | coe b => exact 0 | top => exact 𝟙 _ - map_id n := by induction n <;> simp + map_id n := by induction n using WithBotTop.rec <;> simp map_comp {x y z} f g := by have f' := leOfHom f have g' := leOfHom g - induction x <;> induction y <;> induction z <;> cat_disch + induction x using WithBotTop.rec <;> induction y using WithBotTop.rec <;> + induction z using WithBotTop.rec <;> cat_disch @[simp] lemma eTruncGE_obj_bot : @@ -123,23 +125,23 @@ lemma eTruncGE_obj_top : lemma eTruncGE_obj_coe (n : ℤ) : t.eTruncGE.obj n = t.truncGE n := rfl instance (i : EInt) : (t.eTruncGE.obj i).Additive := by - induction i <;> constructor <;> cat_disch + induction i using WithBotTop.rec <;> constructor <;> cat_disch /-- The connecting homomorphism from `t.eTruncGE` to the shift by `1` of `t.eTruncLT`. -/ noncomputable def eTruncGEδLT : t.eTruncGE ⟶ t.eTruncLT ⋙ ((Functor.whiskeringRight C C C).obj (shiftFunctor C (1 : ℤ))) where app a := by - induction a with + induction a using WithBotTop.rec with | bot => exact 0 | coe a => exact t.truncGEδLT a | top => exact 0 naturality {a b} hab := by replace hab := leOfHom hab - induction a; rotate_right + induction a using WithBotTop.rec ; rotate_right · apply (isZero_zero _).eq_of_src all_goals - induction b <;> simp at hab <;> + induction b using WithBotTop.rec <;> simp at hab <;> dsimp [eTruncGE, eTruncLT] <;> simp [t.truncGEδLT_comp_whiskerRight_natTransTruncLTOfLE] @@ -174,7 +176,7 @@ lemma eTruncLT_map_app_eTruncLTι_app {i j : EInt} (f : i ⟶ j) (X : C) : lemma eTruncLT_obj_map_eTruncLTι_app (i : EInt) (X : C) : (t.eTruncLT.obj i).map ((t.eTruncLTι i).app X) = (t.eTruncLTι i).app ((t.eTruncLT.obj i).obj X) := by - induction i with + induction i using WithBotTop.rec with | bot => simp | coe n => simp [truncLT_map_truncLTι_app] | top => simp @@ -206,7 +208,7 @@ lemma eTruncGEπ_app_eTruncGE_map_app {i j : EInt} (f : i ⟶ j) (X : C) : lemma eTruncGE_obj_map_eTruncGEπ_app (i : EInt) (X : C) : (t.eTruncGE.obj i).map ((t.eTruncGEπ i).app X) = (t.eTruncGEπ i).app ((t.eTruncGE.obj i).obj X) := by - induction i with + induction i using WithBotTop.rec with | bot => simp | coe n => simp [truncGE_map_truncGEπ_app] | top => simp @@ -220,7 +222,7 @@ noncomputable def eTriangleLTGE : EInt ⥤ C ⥤ Triangle C where lemma eTriangleLTGE_distinguished (i : EInt) (X : C) : (t.eTriangleLTGE.obj i).obj X ∈ distTriang _ := by - induction i with + induction i using WithBotTop.rec with | bot => rw [Triangle.distinguished_iff_of_isZero₁ _ (Functor.zero_obj X)] dsimp @@ -233,21 +235,21 @@ lemma eTriangleLTGE_distinguished (i : EInt) (X : C) : instance (X : C) (n : ℤ) [t.IsLE X n] (i : EInt) : t.IsLE ((t.eTruncLT.obj i).obj X) n := by - induction i with + induction i using WithBotTop.rec with | bot => exact isLE_of_isZero _ (by simp) _ | coe _ => dsimp; infer_instance | top => dsimp; infer_instance instance (X : C) (n : ℤ) [t.IsGE X n] (i : EInt) : t.IsGE ((t.eTruncGE.obj i).obj X) n := by - induction i with + induction i using WithBotTop.rec with | bot => dsimp; infer_instance | coe _ => dsimp; infer_instance | top => exact isGE_of_isZero _ (by simp) _ lemma isGE_eTruncGE_obj_obj (n : ℤ) (i : EInt) (h : n ≤ i) (X : C) : t.IsGE ((t.eTruncGE.obj i).obj X) n := by - induction i with + induction i using WithBotTop.rec with | bot => simp at h | coe i => dsimp @@ -256,17 +258,17 @@ lemma isGE_eTruncGE_obj_obj (n : ℤ) (i : EInt) (h : n ≤ i) (X : C) : lemma isLE_eTruncLT_obj_obj (n : ℤ) (i : EInt) (h : i ≤ (n + 1 :)) (X : C) : t.IsLE (((t.eTruncLT.obj i)).obj X) n := by - induction i with + induction i using WithBotTop.rec with | bot => exact t.isLE_of_isZero (by simp) _ | coe i => - simp only [EInt.coe_le_coe_iff] at h + simp only [WithBotTop.coe_le_coe] at h dsimp exact t.isLE_of_LE _ (i - 1) n (by lia) | top => simp at h lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j ≤ n) : IsZero ((t.eTruncLT.obj j).obj X) := by - induction j with + induction j using WithBotTop.rec with | bot => simp | coe j => have := t.isGE_of_GE X j n (by simpa using hj) @@ -275,10 +277,10 @@ lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j lemma isZero_eTruncGE_obj_obj (X : C) (n : ℤ) [t.IsLE X n] (j : EInt) (hj : n < j) : IsZero ((t.eTruncGE.obj j).obj X) := by - induction j with + induction j using WithBotTop.rec with | bot => simp at hj | coe j => - simp only [EInt.coe_lt_coe_iff] at hj + simp only [WithBotTop.coe_lt_coe_iff] at hj have := t.isLE_of_LE X n (j - 1) (by lia) exact t.isZero_truncGE_obj_of_isLE (j - 1) j (by lia) _ | top => simp @@ -289,12 +291,12 @@ variable [IsTriangulated C] lemma isIso_eTruncGE_obj_map_truncGEπ_app (a b : EInt) (h : a ≤ b) (X : C) : IsIso ((t.eTruncGE.obj b).map ((t.eTruncGEπ a).app X)) := by - induction b with + induction b using WithBotTop.rec with | bot => obtain rfl : a = ⊥ := by simpa using h infer_instance | coe b => - induction a with + induction a using WithBotTop.rec with | bot => dsimp; infer_instance | coe a => exact t.isIso_truncGE_map_truncGEπ_app b a (by simpa using h) X | top => simp at h @@ -302,10 +304,10 @@ lemma isIso_eTruncGE_obj_map_truncGEπ_app (a b : EInt) (h : a ≤ b) (X : C) : lemma isIso_eTruncLT_obj_map_truncLTπ_app (a b : EInt) (h : a ≤ b) (X : C) : IsIso ((t.eTruncLT.obj a).map ((t.eTruncLTι b).app X)) := by - induction a with + induction a using WithBotTop.rec with | bot => exact ⟨0, IsZero.eq_of_src (by simp) _ _, IsZero.eq_of_src (by simp) _ _⟩ | coe a => - induction b with + induction b using WithBotTop.rec with | bot => simp at h | coe b => exact t.isIso_truncLT_map_truncLTι_app a b (by simpa using h) X @@ -323,14 +325,14 @@ instance (a : EInt) (X : C) : IsIso ((t.eTruncLTι a).app ((t.eTruncLT.obj a).ob instance (X : C) (n : ℤ) [t.IsGE X n] (i : EInt) : t.IsGE ((t.eTruncLT.obj i).obj X) n := by - induction i with + induction i using WithBotTop.rec with | bot => exact isGE_of_isZero _ (by simp) _ | coe _ => dsimp; infer_instance | top => dsimp; infer_instance instance (X : C) (n : ℤ) [t.IsLE X n] (i : EInt) : t.IsLE ((t.eTruncGE.obj i).obj X) n := by - induction i with + induction i using WithBotTop.rec with | bot => dsimp; infer_instance | coe _ => dsimp; infer_instance | top => exact isLE_of_isZero _ (by simp) _ @@ -448,10 +450,10 @@ noncomputable def eTruncLTGELTSelfToGELT : instance : IsIso (t.eTruncLTGELTSelfToLTGE a b) := by rw [NatTrans.isIso_iff_isIso_app] intro X - induction b with + induction b using WithBotTop.rec with | bot => simp [isIsoZero_iff_source_target_isZero] | coe b => - induction a with + induction a using WithBotTop.rec with | bot => simpa using inferInstanceAs (IsIso ((t.truncLT b).map ((t.truncLTι b).app X))) | coe a => simp only [eTruncLT_obj_coe, eTruncGE_obj_coe, Functor.comp_obj, eTruncLTGELTSelfToLTGE_app, @@ -469,10 +471,10 @@ variable (b : EInt) (X : C) instance : IsIso (t.eTruncLTGELTSelfToGELT a b) := by rw [NatTrans.isIso_iff_isIso_app] intro X - induction a with + induction a using WithBotTop.rec with | bot => simpa using inferInstanceAs (IsIso ((t.eTruncLTι b).app ((t.eTruncLT.obj b).obj X))) | coe a => - induction b with + induction b using WithBotTop.rec with | bot => simpa [isIsoZero_iff_source_target_isZero] using (t.eTruncGE.obj a).map_isZero (Functor.zero_obj _) | coe b => diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean index c041877fba77be..e7d9fef6daf5cf 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean @@ -123,7 +123,7 @@ noncomputable def triangleω₁δObjIso (X : C) : rw [← homOfLE_comp hbc le_top, Functor.map_comp, NatTrans.comp_app, NatTrans.naturality] congr 1 - induction c with + induction c using WithBotTop.rec with | bot => simp | coe c => simp [truncLT_map_truncLTι_app] | top => simp diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean index 4254158a6e7b5c..e2ff646571d2ae 100644 --- a/Mathlib/Data/EInt/Basic.lean +++ b/Mathlib/Data/EInt/Basic.lean @@ -5,7 +5,7 @@ Authors: Joël Riou, Kevin Buzzard -/ module -public import Mathlib.Order.WithBot +public import Mathlib.Order.WithBotTop /-! # The extended integers @@ -18,18 +18,19 @@ implemented as `WithBot (WithTop ℤ)`. @[expose] public section /-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ -def EInt := WithBot (WithTop ℤ) +abbrev EInt := WithBotTop ℤ --WithBot (WithTop ℤ) +/- /-- The canonical inclusion from integers to e-integers. Registered as a coercion. -/ @[coe] def Int.toEInt : ℤ → EInt := WithBot.some ∘ WithTop.some namespace EInt -instance : LinearOrder EInt := inferInstanceAs (LinearOrder (WithBot (WithTop ℤ))) - -instance : OrderBot EInt := inferInstanceAs (OrderBot (WithBot (WithTop ℤ))) - -instance : OrderTop EInt := inferInstanceAs (OrderTop (WithBot (WithTop ℤ))) +--instance : LinearOrder EInt := inferInstanceAs (LinearOrder (WithBot (WithTop ℤ))) +-- +--instance : OrderBot EInt := inferInstanceAs (OrderBot (WithBot (WithTop ℤ))) +-- +--instance : OrderTop EInt := inferInstanceAs (OrderTop (WithBot (WithTop ℤ))) instance : Coe ℤ EInt := ⟨Int.toEInt⟩ @@ -74,4 +75,4 @@ lemma coe_lt_coe_iff {a b : ℤ} : @[simp] lemma top_ne_bot : (⊤ : EInt) ≠ ⊥ := by rintro ⟨⟩ @[simp] lemma bot_ne_top : (⊤ : EInt) ≠ ⊥ := by rintro ⟨⟩ -end EInt +end EInt-/ diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean new file mode 100644 index 00000000000000..8c6f5711afa6ee --- /dev/null +++ b/Mathlib/Order/WithBotTop.lean @@ -0,0 +1,78 @@ +/- +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, Kevin Buzzard +-/ +module + +public import Mathlib.Order.WithBot + +/-! +# Adding both `⊥` and `⊤` to a type + +This files defines an abbreviation `WithBotTop ι` for `WithBot (WithTop ι)`. + +-/ + +@[expose] public section + +variable {ι : Type*} + +variable (ι) in +/-- The type obtained by adding both `⊥` and `⊤` to a type. -/ +abbrev WithBotTop := WithBot (WithTop ι) + +/-- The canonical inclusion from integers to e-integers. Registered as a coercion. -/ +@[coe] def WithBotTop.coe : ι → WithBotTop ι := WithBot.some ∘ WithTop.some + +namespace WithBotTop + +instance : Coe ι (WithBotTop ι) := ⟨WithBotTop.coe⟩ + +section + +variable {motive : (WithBotTop ι) → Sort*} + (bot : motive ⊥) (coe : ∀ a : ι, motive a) (top : motive ⊤) + +/-- A recursor for `EInt` in terms of the coercion. -/ +@[elab_as_elim] +protected def rec : ∀ a, motive a + | ⊥ => bot + | (a : ι) => coe a + | ⊤ => top + +@[simp] lemma rec_bot : WithBotTop.rec (motive := motive) bot coe top ⊥ = bot := rfl +@[simp] lemma rec_coe (a : ι) : WithBotTop.rec (motive := motive) bot coe top a = coe a := rfl +@[simp] lemma rec_top : WithBotTop.rec (motive := motive) bot coe top ⊤ = top := rfl + +end + +@[simp] +lemma coe_le_coe [LE ι] {a b : ι} : + (a : WithBotTop ι) ≤ b ↔ a ≤ b := by + rw [← WithTop.coe_le_coe (α := ι)] + exact WithBot.coe_le_coe + +@[simp] +lemma coe_lt_coe_iff [LT ι] {a b : ι} : + (a : WithBotTop ι) < b ↔ a < b := by + rw [← WithTop.coe_lt_coe (α := ι)] + exact WithBot.coe_lt_coe + +theorem coe_strictMono [Preorder ι] : StrictMono (WithBotTop.coe : ι → _) := + WithBot.coe_strictMono.comp WithTop.coe_strictMono + +theorem coe_injective : Function.Injective (WithBotTop.coe : ι → _) := by rintro _ _ ⟨⟩; rfl + +lemma coe_monotone [Preorder ι] : Monotone (WithBotTop.coe : ι → _) := + fun _ _ _ ↦ by simpa + +@[simp] lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ +@[simp] lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma bot_ne_top : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ + +/-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ +abbrev EInt := WithBotTop ℤ + +end WithBotTop From 22f62b50b68a48aa1ae960047f8d895398b2e0d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 13 Jan 2026 09:42:44 +0100 Subject: [PATCH 27/72] fix --- .../SpectralObject/HasSpectralSequence.lean | 4 ++-- .../Triangulated/TStructure/ETrunc.lean | 2 +- Mathlib/Order/WithBotTop.lean | 21 ++++++++++--------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index f4a8c6e85e3f1e..d4bfae62ec247f 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -399,7 +399,7 @@ instance : Y.HasSpectralSequence mkDataE₂CohomologicalNat where rintro r _ rfl hr ⟨p, q⟩ hpq n rfl apply isZero₂_of_isFirstQuadrant dsimp - simp only [WithBotTop.coe_lt_coe_iff] + simp only [WithBotTop.coe_lt_coe] by_contra! obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p - r by lia) obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q - 1 + r by lia) @@ -446,7 +446,7 @@ instance : Y.HasSpectralSequence mkDataE₂HomologicalNat where rintro r _ rfl hr ⟨p, q⟩ hpq n rfl apply isZero₁_of_isThirdQuadrant dsimp - simp only [WithBotTop.coe_lt_coe_iff] + simp only [WithBotTop.coe_lt_coe] by_contra! obtain ⟨p', hp'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ p + r by lia) obtain ⟨q', hq'⟩ := Int.eq_ofNat_of_zero_le (show 0 ≤ q + 1 - r by lia) diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean index 02003821be3582..d9e3f3d27f9940 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -280,7 +280,7 @@ lemma isZero_eTruncGE_obj_obj (X : C) (n : ℤ) [t.IsLE X n] (j : EInt) (hj : n induction j using WithBotTop.rec with | bot => simp at hj | coe j => - simp only [WithBotTop.coe_lt_coe_iff] at hj + simp only [WithBotTop.coe_lt_coe] at hj have := t.isLE_of_LE X n (j - 1) (by lia) exact t.isZero_truncGE_obj_of_isLE (j - 1) j (by lia) _ | top => simp diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean index 8c6f5711afa6ee..6f9ea35bafc6aa 100644 --- a/Mathlib/Order/WithBotTop.lean +++ b/Mathlib/Order/WithBotTop.lean @@ -11,6 +11,7 @@ public import Mathlib.Order.WithBot # Adding both `⊥` and `⊤` to a type This files defines an abbreviation `WithBotTop ι` for `WithBot (WithTop ι)`. +We also introduce an abbreviation `EInt` for `WithBotTop ℤ`. -/ @@ -22,19 +23,26 @@ variable (ι) in /-- The type obtained by adding both `⊥` and `⊤` to a type. -/ abbrev WithBotTop := WithBot (WithTop ι) -/-- The canonical inclusion from integers to e-integers. Registered as a coercion. -/ +/-- The canonical inclusion `ι → WithBotTop ι`. Registered as a coercion. -/ @[coe] def WithBotTop.coe : ι → WithBotTop ι := WithBot.some ∘ WithTop.some namespace WithBotTop instance : Coe ι (WithBotTop ι) := ⟨WithBotTop.coe⟩ +theorem coe_injective : Function.Injective (WithBotTop.coe : ι → _) := by rintro _ _ ⟨⟩; rfl + +@[simp] lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ +@[simp] lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma bot_ne_top : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ + section variable {motive : (WithBotTop ι) → Sort*} (bot : motive ⊥) (coe : ∀ a : ι, motive a) (top : motive ⊤) -/-- A recursor for `EInt` in terms of the coercion. -/ +/-- A recursor for `WithBotTop` in terms of the coercion. -/ @[elab_as_elim] protected def rec : ∀ a, motive a | ⊥ => bot @@ -54,7 +62,7 @@ lemma coe_le_coe [LE ι] {a b : ι} : exact WithBot.coe_le_coe @[simp] -lemma coe_lt_coe_iff [LT ι] {a b : ι} : +lemma coe_lt_coe [LT ι] {a b : ι} : (a : WithBotTop ι) < b ↔ a < b := by rw [← WithTop.coe_lt_coe (α := ι)] exact WithBot.coe_lt_coe @@ -62,16 +70,9 @@ lemma coe_lt_coe_iff [LT ι] {a b : ι} : theorem coe_strictMono [Preorder ι] : StrictMono (WithBotTop.coe : ι → _) := WithBot.coe_strictMono.comp WithTop.coe_strictMono -theorem coe_injective : Function.Injective (WithBotTop.coe : ι → _) := by rintro _ _ ⟨⟩; rfl - lemma coe_monotone [Preorder ι] : Monotone (WithBotTop.coe : ι → _) := fun _ _ _ ↦ by simpa -@[simp] lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ -@[simp] lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ -@[simp] lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ -@[simp] lemma bot_ne_top : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ - /-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ abbrev EInt := WithBotTop ℤ From 9197af97a8e0dd5dac4181bc0ec0f76f66060a1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 13 Jan 2026 09:43:39 +0100 Subject: [PATCH 28/72] WithBotTop --- Mathlib.lean | 2 +- Mathlib/Data/EInt/Basic.lean | 76 --------------------------------- Mathlib/Order/WithBotTop.lean | 79 +++++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 77 deletions(-) delete mode 100644 Mathlib/Data/EInt/Basic.lean create mode 100644 Mathlib/Order/WithBotTop.lean diff --git a/Mathlib.lean b/Mathlib.lean index 7bb992cde53ca8..859f42eb8ce3dc 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3457,7 +3457,6 @@ public import Mathlib.Data.DFinsupp.Small public import Mathlib.Data.DFinsupp.Submonoid public import Mathlib.Data.DFinsupp.WellFounded public import Mathlib.Data.DList.Instances -public import Mathlib.Data.EInt.Basic public import Mathlib.Data.ENNReal.Action public import Mathlib.Data.ENNReal.Basic public import Mathlib.Data.ENNReal.BigOperators @@ -5676,6 +5675,7 @@ public import Mathlib.Order.WellFounded public import Mathlib.Order.WellFoundedSet public import Mathlib.Order.WellQuasiOrder public import Mathlib.Order.WithBot +public import Mathlib.Order.WithBotTop public import Mathlib.Order.Zorn public import Mathlib.Order.ZornAtoms public import Mathlib.Probability.BorelCantelli diff --git a/Mathlib/Data/EInt/Basic.lean b/Mathlib/Data/EInt/Basic.lean deleted file mode 100644 index e78af3cd72f804..00000000000000 --- a/Mathlib/Data/EInt/Basic.lean +++ /dev/null @@ -1,76 +0,0 @@ -/- -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, Kevin Buzzard --/ -module - -public import Mathlib.Order.WithBot - -/-! -# The extended integers - -This file defines `EInt`, `ℤ` with a top element `⊤` and a bottom element `⊥`, -implemented as `WithBot (WithTop ℤ)`. - --/ - -@[expose] public section - -/-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ -def EInt := WithBot (WithTop ℤ) - -/-- The canonical inclusion from integers to e-integers. Registered as a coercion. -/ -@[coe] def Int.toEInt : ℤ → EInt := WithBot.some ∘ WithTop.some - -namespace EInt - -instance : LinearOrder EInt := inferInstanceAs (LinearOrder (WithBot (WithTop ℤ))) - -instance : OrderBot EInt := inferInstanceAs (OrderBot (WithBot (WithTop ℤ))) - -instance : OrderTop EInt := inferInstanceAs (OrderTop (WithBot (WithTop ℤ))) - -instance : Coe ℤ EInt := ⟨Int.toEInt⟩ - -theorem coe_strictMono : StrictMono Int.toEInt := - WithBot.coe_strictMono.comp WithTop.coe_strictMono - -theorem coe_injective : Function.Injective Int.toEInt := - coe_strictMono.injective - -lemma coe_monotone : Monotone Int.toEInt := coe_strictMono.monotone - -section - -variable {motive : EInt → Sort*} - (bot : motive ⊥) (coe : ∀ a : ℤ, motive a) (top : motive ⊤) - -/-- A recursor for `EInt` in terms of the coercion. -/ -@[elab_as_elim, induction_eliminator, cases_eliminator] -protected def rec : ∀ a : EInt, motive a - | ⊥ => bot - | (a : ℤ) => coe a - | ⊤ => top - -@[simp] lemma rec_bot : EInt.rec (motive := motive) bot coe top ⊥ = bot := rfl -@[simp] lemma rec_coe (a : ℤ) : EInt.rec (motive := motive) bot coe top a = coe a := rfl -@[simp] lemma rec_top : EInt.rec (motive := motive) bot coe top ⊤ = top := rfl - -end - -@[simp] -lemma coe_le_coe_iff {a b : ℤ} : - (a : EInt) ≤ b ↔ a ≤ b := - coe_strictMono.le_iff_le - -@[simp] -lemma coe_lt_coe_iff {a b : ℤ} : - (a : EInt) < b ↔ a < b := - coe_strictMono.lt_iff_lt - -@[simp] lemma coe_ne_bot (a : ℤ) : (a : EInt) ≠ ⊥ := by rintro ⟨⟩ -@[simp] lemma coe_ne_top (a : ℤ) : (a : EInt) ≠ ⊤ := by rintro ⟨⟩ -@[simp] lemma top_ne_bot : (⊤ : EInt) ≠ ⊥ := by rintro ⟨⟩ - -end EInt diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean new file mode 100644 index 00000000000000..6f9ea35bafc6aa --- /dev/null +++ b/Mathlib/Order/WithBotTop.lean @@ -0,0 +1,79 @@ +/- +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, Kevin Buzzard +-/ +module + +public import Mathlib.Order.WithBot + +/-! +# Adding both `⊥` and `⊤` to a type + +This files defines an abbreviation `WithBotTop ι` for `WithBot (WithTop ι)`. +We also introduce an abbreviation `EInt` for `WithBotTop ℤ`. + +-/ + +@[expose] public section + +variable {ι : Type*} + +variable (ι) in +/-- The type obtained by adding both `⊥` and `⊤` to a type. -/ +abbrev WithBotTop := WithBot (WithTop ι) + +/-- The canonical inclusion `ι → WithBotTop ι`. Registered as a coercion. -/ +@[coe] def WithBotTop.coe : ι → WithBotTop ι := WithBot.some ∘ WithTop.some + +namespace WithBotTop + +instance : Coe ι (WithBotTop ι) := ⟨WithBotTop.coe⟩ + +theorem coe_injective : Function.Injective (WithBotTop.coe : ι → _) := by rintro _ _ ⟨⟩; rfl + +@[simp] lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ +@[simp] lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[simp] lemma bot_ne_top : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ + +section + +variable {motive : (WithBotTop ι) → Sort*} + (bot : motive ⊥) (coe : ∀ a : ι, motive a) (top : motive ⊤) + +/-- A recursor for `WithBotTop` in terms of the coercion. -/ +@[elab_as_elim] +protected def rec : ∀ a, motive a + | ⊥ => bot + | (a : ι) => coe a + | ⊤ => top + +@[simp] lemma rec_bot : WithBotTop.rec (motive := motive) bot coe top ⊥ = bot := rfl +@[simp] lemma rec_coe (a : ι) : WithBotTop.rec (motive := motive) bot coe top a = coe a := rfl +@[simp] lemma rec_top : WithBotTop.rec (motive := motive) bot coe top ⊤ = top := rfl + +end + +@[simp] +lemma coe_le_coe [LE ι] {a b : ι} : + (a : WithBotTop ι) ≤ b ↔ a ≤ b := by + rw [← WithTop.coe_le_coe (α := ι)] + exact WithBot.coe_le_coe + +@[simp] +lemma coe_lt_coe [LT ι] {a b : ι} : + (a : WithBotTop ι) < b ↔ a < b := by + rw [← WithTop.coe_lt_coe (α := ι)] + exact WithBot.coe_lt_coe + +theorem coe_strictMono [Preorder ι] : StrictMono (WithBotTop.coe : ι → _) := + WithBot.coe_strictMono.comp WithTop.coe_strictMono + +lemma coe_monotone [Preorder ι] : Monotone (WithBotTop.coe : ι → _) := + fun _ _ _ ↦ by simpa + +/-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ +abbrev EInt := WithBotTop ℤ + +end WithBotTop From e75e4770ce6727b497c9eeca598ada7356af1e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 13 Jan 2026 10:08:07 +0100 Subject: [PATCH 29/72] fix --- .../Preadditive/AdditiveFunctor.lean | 5 ++ .../Triangulated/Subcategory.lean | 65 ++++++++----------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean b/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean index cc330ecf789c62..19642fe3ba6b14 100644 --- a/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean +++ b/Mathlib/CategoryTheory/Preadditive/AdditiveFunctor.lean @@ -144,6 +144,11 @@ end InducedCategory instance fullSubcategoryInclusion_additive {C : Type*} [Category* C] [Preadditive C] (Z : ObjectProperty C) : Z.ι.Additive where +instance {C D : Type*} [Category* C] [Category* D] [Preadditive C] [Preadditive D] + (F : D ⥤ C) [F.Additive] (P : ObjectProperty C) + (hF : ∀ (X : D), P (F.obj X)) : + (P.lift F hF).Additive where + section -- To talk about preservation of biproducts we need to specify universes explicitly. diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index d633893d692229..cf4cbe3a0504c6 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -52,6 +52,9 @@ open Category Limits Preadditive ZeroObject Pretriangulated Triangulated variable {C : Type*} [Category* C] [HasZeroObject C] [HasShift C ℤ] [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] + {D : Type*} [Category* D] [Preadditive D] [HasZeroObject D] [HasShift D ℤ] + [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + {E : Type*} [Category* E] [HasShift E ℤ] namespace ObjectProperty @@ -385,7 +388,7 @@ noncomputable instance hasShift : instance commShiftι : P.ι.CommShift ℤ := Functor.CommShift.ofHasShiftOfFullyFaithful _ _ _ --- these definitions are made irreducible to prevent (at least temporarily) any abuse of defeq +-- these definitions are made irreducible to prevent any abuse of defeq attribute [irreducible] hasShift commShiftι instance (n : ℤ) : (shiftFunctor P.FullSubcategory n).Additive := by @@ -397,24 +400,21 @@ instance : HasZeroObject P.FullSubcategory where obtain ⟨Z, hZ, mem⟩ := P.exists_prop_of_containsZero refine ⟨⟨Z, mem⟩, ?_⟩ rw [IsZero.iff_id_eq_zero] - apply ObjectProperty.hom_ext - apply hZ.eq_of_src + exact ObjectProperty.hom_ext _ (hZ.eq_of_src _ _) noncomputable instance : Pretriangulated P.FullSubcategory where distinguishedTriangles := fun T => P.ι.mapTriangle.obj T ∈ distTriang C isomorphic_distinguished := fun T₁ hT₁ T₂ e => isomorphic_distinguished _ hT₁ _ (P.ι.mapTriangle.mapIso e) - contractible_distinguished X := by - refine isomorphic_distinguished _ (contractible_distinguished (P.ι.obj X)) _ ?_ - exact Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) P.ι.mapZeroObject + contractible_distinguished X := + isomorphic_distinguished _ (contractible_distinguished (P.ι.obj X)) _ + (Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) P.ι.mapZeroObject) distinguished_cocone_triangle {X Y} f := by obtain ⟨Z', g', h', mem⟩ := distinguished_cocone_triangle (P.ι.map f) obtain ⟨Z'', hZ'', ⟨e⟩⟩ := P.ext_of_isTriangulatedClosed₃' _ mem X.2 Y.2 - let Z : P.FullSubcategory := ⟨Z'', hZ''⟩ - refine ⟨Z, P.fullyFaithfulι.preimage (g' ≫ e.hom), + exact ⟨⟨Z'', hZ''⟩, P.fullyFaithfulι.preimage (g' ≫ e.hom), P.fullyFaithfulι.preimage (e.inv ≫ h' ≫ (P.ι.commShiftIso (1 : ℤ)).inv.app X), - isomorphic_distinguished _ mem _ ?_⟩ - exact Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) e.symm + isomorphic_distinguished _ mem _ (Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) e.symm)⟩ rotate_distinguished_triangle T := (rotate_distinguished_triangle (P.ι.mapTriangle.obj T)).trans (distinguished_iff_of_iso (P.ι.mapTriangleRotateIso.app T)) @@ -435,9 +435,7 @@ instance [IsTriangulated C] : IsTriangulated P.FullSubcategory := section -variable {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] - [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] +variable (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] instance : (F.essImage).IsTriangulated where isStableUnderShiftBy n := @@ -458,29 +456,18 @@ end section -variable {D : Type*} [Category* D] (F : D ⥤ C) (hF : ∀ (X : D), P (F.obj X)) - --- some of these are general API, not specific to triangulated subcategories - -instance [F.Faithful] : (P.lift F hF).Faithful := - Functor.Faithful.of_comp_iso (P.liftCompιIso F hF) +variable (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) -instance [F.Full] : (P.lift F hF).Full := - Functor.Full.of_comp_faithful_iso (P.liftCompιIso F hF) - --- should be generalized -instance [Preadditive D] [F.Additive] : (P.lift F hF).Additive where - -noncomputable instance [HasShift D ℤ] [F.CommShift ℤ] : +noncomputable instance [F.CommShift ℤ] : (P.lift F hF).CommShift ℤ := Functor.CommShift.ofComp (P.liftCompιIso F hF) ℤ -noncomputable instance [HasShift D ℤ] [F.CommShift ℤ] : +noncomputable instance [F.CommShift ℤ] : NatTrans.CommShift (P.liftCompιIso F hF).hom ℤ := Functor.CommShift.ofComp_compatibility _ _ -instance isTriangulated_lift [HasShift D ℤ] [Preadditive D] [F.CommShift ℤ] [HasZeroObject D] - [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] [F.IsTriangulated] : +instance isTriangulated_lift [Preadditive E] [F.CommShift ℤ] [HasZeroObject E] + [∀ (n : ℤ), (shiftFunctor E n).Additive] [Pretriangulated E] [F.IsTriangulated] : (P.lift F hF).IsTriangulated := by rw [Functor.isTriangulated_iff_comp_right (P.liftCompιIso F hF)] infer_instance @@ -489,9 +476,7 @@ end section -variable {D : Type*} [Category D] [Preadditive D] [HasZeroObject D] [HasShift D ℤ] - [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - (F : D ⥤ C) [F.CommShift ℤ] [F.IsTriangulated] +variable (F : D ⥤ C) [F.CommShift ℤ] [F.IsTriangulated] [P.IsClosedUnderIsomorphisms] instance : (P.inverseImage F).IsTriangulated where @@ -525,13 +510,15 @@ variable {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] instance : (P.map F).IsTriangulated := by - convert inferInstanceAs (P.ι ⋙ F).essImage.IsTriangulated - ext Y - constructor - · rintro ⟨X, hX, ⟨e⟩⟩ - exact ⟨⟨X, hX⟩, ⟨e⟩⟩ - · rintro ⟨X, ⟨e⟩⟩ - exact ⟨X.1, X.2, ⟨e⟩⟩ + have : P.map F = (P.ι ⋙ F).essImage := by + ext Y + constructor + · rintro ⟨X, hX, ⟨e⟩⟩ + exact ⟨⟨X, hX⟩, ⟨e⟩⟩ + · rintro ⟨X, ⟨e⟩⟩ + exact ⟨X.1, X.2, ⟨e⟩⟩ + rw [this] + infer_instance end From c5b0c564a719438ed5bbf52afc52b95da37820eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 13 Jan 2026 14:35:49 +0100 Subject: [PATCH 30/72] fix --- Mathlib/Order/WithBotTop.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean index 6f9ea35bafc6aa..33d2356c746ddc 100644 --- a/Mathlib/Order/WithBotTop.lean +++ b/Mathlib/Order/WithBotTop.lean @@ -35,7 +35,6 @@ theorem coe_injective : Function.Injective (WithBotTop.coe : ι → _) := by rin @[simp] lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ @[simp] lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ @[simp] lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ -@[simp] lemma bot_ne_top : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ section From 9252ac98efda549eb1a26269496e257918370930 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 13 Jan 2026 14:35:58 +0100 Subject: [PATCH 31/72] fix --- Mathlib/Order/WithBotTop.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean index 6f9ea35bafc6aa..33d2356c746ddc 100644 --- a/Mathlib/Order/WithBotTop.lean +++ b/Mathlib/Order/WithBotTop.lean @@ -35,7 +35,6 @@ theorem coe_injective : Function.Injective (WithBotTop.coe : ι → _) := by rin @[simp] lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ @[simp] lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ @[simp] lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ -@[simp] lemma bot_ne_top : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ section From 17cba25db6fd750fa5375b6b6bf44bea7e6098e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 15 Jan 2026 11:02:25 +0100 Subject: [PATCH 32/72] cleaning up --- Mathlib.lean | 1 + .../Homology/SpectralObject/EpiMono.lean | 265 ++++++++++ .../SpectralObject/HasSpectralSequence.lean | 258 +++++----- .../Homology/SpectralObject/Homology.lean | 89 +--- .../SpectralObject/SpectralSequence.lean | 479 +++++------------- 5 files changed, 546 insertions(+), 546 deletions(-) create mode 100644 Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean diff --git a/Mathlib.lean b/Mathlib.lean index b875477ba53549..686df51023f9fd 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -648,6 +648,7 @@ public import Mathlib.Algebra.Homology.SingleHomology public import Mathlib.Algebra.Homology.SpectralObject.Basic public import Mathlib.Algebra.Homology.SpectralObject.Cycles public import Mathlib.Algebra.Homology.SpectralObject.Differentials +public import Mathlib.Algebra.Homology.SpectralObject.EpiMono public import Mathlib.Algebra.Homology.SpectralObject.HasSpectralSequence public import Mathlib.Algebra.Homology.SpectralObject.Homology public import Mathlib.Algebra.Homology.SpectralObject.Page diff --git a/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean b/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean new file mode 100644 index 00000000000000..18152089b3e559 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean @@ -0,0 +1,265 @@ +/- +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.SpectralObject.Differentials +public import Mathlib.CategoryTheory.ComposableArrows.Four + +/-! +# Spectral objects in abelian categories + + +## References +* [Jean-Louis Verdier, *Des catégories dérivées des catégories abéliennes*, II.4][verdier1996] + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category Limits ComposableArrows + +namespace Abelian + +namespace SpectralObject + +variable {C ι ι' κ : Type*} [Category C] [Abelian C] [Category ι] [Preorder ι'] + (X : SpectralObject C ι) (X' : SpectralObject C ι') + +section + +variable (n₀ n₁ n₂ n₃ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + {i₀' i₀ i₁ i₂ i₃ i₃' : ι} (f₁ : i₀ ⟶ i₁) + (f₁' : i₀' ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) (f₃' : i₂ ⟶ i₃') + +lemma epi_EMap (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁ f₂ f₃') + (hα₀ : α.app 0 = 𝟙 _) (hα₁ : α.app 1 = 𝟙 _) (hα₂ : α.app 2 = 𝟙 _) : + Epi (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁ f₂ f₃' α) := by + have := X.πE_EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ α (𝟙 _) (by cat_disch) + rw [cyclesMap_id, id_comp] at this + exact epi_of_epi_fac this + +lemma mono_EMap (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁' f₂ f₃) + (hα₁ : α.app 1 = 𝟙 _) (hα₂ : α.app 2 = 𝟙 _) (hα₃ : α.app 3 = 𝟙 _) : + Mono (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂ f₃ α) := by + have := X.EMap_ιE n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ α (𝟙 _) (by cat_disch) + rw [opcyclesMap_id, comp_id] at this + exact mono_of_mono_fac this + +end + +section + +variable (n₀ n₁ n₂ n₃ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) + {i₀ i₁ i₂ i₃ i₄ i₅ i₆ i₇ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) + (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) + (f₂₃ : i₁ ⟶ i₃) (h₂₃ : f₂ ≫ f₃ = f₂₃) + (f₃₄ : i₂ ⟶ i₄) (h₃₄ : f₃ ≫ f₄ = f₃₄) + +@[reassoc (attr := simp)] +lemma d_EMap_fourδ₄Toδ₃ : + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ + X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄) = 0 := by + rw [← cancel_epi (X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅), + ← cancel_epi (X.toCycles n₁ f₃ f₄ f₃₄ h₃₄), comp_zero, comp_zero, + X.toCycles_πE_d_assoc n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ _ rfl f₃₄ h₃₄, + X.πE_EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ + (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄) (𝟙 _) (by ext <;> simp; rfl), + cyclesMap_id, Category.id_comp, δ_toCycles_assoc, δToCycles_πE] + +instance : + Epi (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := + X.epi_EMap _ _ _ _ _ _ _ _ _ _ rfl rfl rfl + +lemma isIso_EMap_fourδ₄Toδ₃ (h : ((X.H n₁).map (twoδ₁Toδ₀ f₃ f₄ f₃₄ h₃₄) = 0)) : + IsIso (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := by + apply ShortComplex.isIso_homologyMap_of_epi_of_isIso_of_mono' + · exact (X.exact₂ _ f₃ f₄ f₃₄ h₃₄).epi_f h + · dsimp + convert inferInstanceAs (IsIso ((X.H n₂).map (𝟙 _))) + cat_disch + · dsimp + convert inferInstanceAs (Mono ((X.H n₃).map (𝟙 (mk₁ f₁)))) + cat_disch + +lemma isIso_EMap_fourδ₄Toδ₃_of_isZero (h : IsZero ((X.H n₁).obj (mk₁ f₄))) : + IsIso (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := by + apply X.isIso_EMap_fourδ₄Toδ₃ + apply h.eq_of_tgt + +@[reassoc (attr := simp)] +lemma EMap_fourδ₁Toδ₀_d : + X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) ≫ + X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ = 0 := by + rw [← cancel_mono (X.ιE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃), + ← cancel_mono (X.fromOpcycles n₂ f₂ f₃ f₂₃ h₂₃), zero_comp, zero_comp, assoc, + assoc, X.d_ιE_fromOpcycles n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₂₃ h₂₃ _ rfl _ rfl] + rw [X.EMap_ιE_assoc n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ + (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) (𝟙 _) (by ext <;> simp <;> rfl), + opcyclesMap_id, fromOpcyles_δ, id_comp, ιE_δFromOpcycles] + +instance : + Mono (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := + X.mono_EMap _ _ _ _ _ _ _ _ _ _ rfl rfl rfl + +lemma isIso_EMap_fourδ₁Toδ₀ (h : ((X.H n₂).map (twoδ₂Toδ₁ f₂ f₃ f₂₃ h₂₃) = 0)) : + IsIso (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := by + apply ShortComplex.isIso_homologyMap_of_epi_of_isIso_of_mono' + · dsimp + convert inferInstanceAs (Epi ((X.H n₀).map (𝟙 _))) + cat_disch + · dsimp + convert inferInstanceAs (IsIso ((X.H n₁).map (𝟙 _))) + cat_disch + · exact (X.exact₂ n₂ f₂ f₃ f₂₃ h₂₃).mono_g h + +lemma isIso_EMap_fourδ₁Toδ₀_of_isZero (h : IsZero ((X.H n₂).obj (mk₁ f₂))) : + IsIso (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := by + apply X.isIso_EMap_fourδ₁Toδ₀ + apply h.eq_of_src + +end + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + (i₀ i₁ i₂ i₃ i₄ i₅ : ι') (hi₀₁ : i₀ ≤ i₁) + (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) (hi₃₄ : i₃ ≤ i₄) (hi₄₅ : i₄ ≤ i₅) + +/-- EMapFourδ₁Toδ₀' -/ +noncomputable abbrev EMapFourδ₁Toδ₀' := + X'.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₁Toδ₀' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + + +/-- EMapFourδ₄Toδ₃' -/ +noncomputable abbrev EMapFourδ₄Toδ₃' := + X'.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₄Toδ₃' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +@[reassoc] +lemma EMapFourδ₁Toδ₀'_comp : + X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₃ i₄ i₅ hi₀₁ (hi₁₂.trans hi₂₃) hi₃₄ hi₄₅ ≫ + X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₁ i₂ i₃ i₄ i₅ hi₁₂ hi₂₃ hi₃₄ hi₄₅ = + X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₂ i₃ i₄ i₅ (hi₀₁.trans hi₁₂) hi₂₃ hi₃₄ hi₄₅ := by + rw [← EMap_comp] + rfl + +@[reassoc] +lemma EMapFourδ₄Toδ₃'_comp : + X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₄ i₅ hi₀₁ hi₁₂ (hi₂₃.trans hi₃₄) hi₄₅ = + X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₅ hi₀₁ hi₁₂ hi₂₃ (hi₃₄.trans hi₄₅) := by + dsimp [EMapFourδ₄Toδ₃'] + rw [← EMap_comp] + rfl + +@[reassoc] +lemma EMapFourδ₁Toδ₀'_EMapFourδ₃Toδ₃' : + X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₁ i₂ i₃ i₄ i₅ hi₁₂ hi₂₃ hi₃₄ hi₄₅ = + X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₂ i₃ i₄ i₅ _ _ _ hi₄₅ ≫ + X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₅ hi₀₁ _ _ _ := by + dsimp [EMapFourδ₁Toδ₀', EMapFourδ₄Toδ₃'] + rw [← EMap_comp, ← EMap_comp] + rfl + +section + +variable (h : IsZero ((X'.H n₂).obj (mk₁ (homOfLE hi₀₁)))) + +include h in +lemma isIso_EMapFourδ₁Toδ₀' : + IsIso (X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + apply X'.isIso_EMap_fourδ₁Toδ₀_of_isZero + exact h + +/-- isoEMapFourδ₁Toδ₀' -/ +@[simps! hom] +noncomputable def isoEMapFourδ₁Toδ₀' : + X'.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE (hi₀₁.trans hi₁₂)) (homOfLE hi₂₃) (homOfLE hi₃₄) ≅ + X'.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₁₂) (homOfLE hi₂₃) (homOfLE hi₃₄) := + have := X'.isIso_EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h + asIso (X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₁Toδ₀'_hom_inv_id : + X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + (X'.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv = 𝟙 _ := + (X'.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).hom_inv_id + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₁Toδ₀'_inv_hom_id : + (X'.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv ≫ + X'.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ = 𝟙 _ := + (X'.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv_hom_id + +end + +section + +variable (h : IsZero ((X'.H n₀).obj (mk₁ (homOfLE hi₃₄)))) + +include h in +lemma isIso_EMapFourδ₄Toδ₃' : + IsIso (X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + apply X'.isIso_EMap_fourδ₄Toδ₃_of_isZero + exact h + +/-- isoEMapFourδ₄Toδ₃' -/ +@[simps! hom] +noncomputable def isoEMapFourδ₄Toδ₃' : + X'.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE hi₂₃) ≅ + X'.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE (hi₂₃.trans hi₃₄)) := + have := X'.isIso_EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h + asIso (X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₄Toδ₄'_hom_inv_id : + X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ + (X'.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv = 𝟙 _ := + (X'.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).hom_inv_id + +@[reassoc (attr := simp)] +lemma isoEMapFourδ₄Toδ₄'_inv_hom_id : + (X'.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv ≫ + X'.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ = 𝟙 _ := + (X'.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv_hom_id + +end + +section + +variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) + (i₀ i₁ i₂ i₃ i₄ i₅ : ι') (hi₀₁ : i₀ ≤ i₁) + (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) (hi₃₄ : i₃ ≤ i₄) (hi₄₅ : i₄ ≤ i₅) + +/-- EMapFourδ₂Toδ₁' -/ +noncomputable abbrev EMapFourδ₂Toδ₁' := + X'.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₂Toδ₁' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) + +/-- isIso_EMapFourδ₂Toδ₁' -/ +lemma isIso_EMapFourδ₂Toδ₁' + (h₁ : IsIso ((X'.H n₁).map (twoδ₁Toδ₀' i₁ i₂ i₃ hi₁₂ hi₂₃))) + (h₂ : IsIso ((X'.H n₂).map (twoδ₂Toδ₁' i₀ i₁ i₂ hi₀₁ hi₁₂))) : + IsIso (X'.EMapFourδ₂Toδ₁' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by + apply X'.isIso_EMap + · dsimp + erw [Functor.map_id] + infer_instance + · exact h₁ + · exact h₂ + +end + +end + +end SpectralObject + +end Abelian + +end CategoryTheory diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index d4bfae62ec247f..ec03bbe83c88d9 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -74,53 +74,84 @@ structure SpectralSequenceMkData where /-- The cohomological degree of objects in the pages -/ deg : κ → ℤ /-- The zeroth index -/ - i₀ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : ι + i₀ (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : ι /-- The first index -/ i₁ (pq : κ) : ι /-- The second index -/ i₂ (pq : κ) : ι /-- The third index -/ - i₃ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : ι - le₀₁ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : i₀ r hr pq ≤ i₁ pq + i₃ (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : ι + le₀₁ (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : i₀ r pq ≤ i₁ pq le₁₂ (pq : κ) : i₁ pq ≤ i₂ pq - le₂₃ (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : i₂ pq ≤ i₃ r hr pq - hc (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : deg pq + 1 = deg pq' - hc₀₂ (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : i₀ r hr pq = i₂ pq' - hc₁₃ (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : i₁ pq = i₃ r hr pq' - antitone_i₀ (r r' : ℤ) (hr : r₀ ≤ r) (hrr' : r ≤ r') (pq : κ) : - i₀ r' (by lia) pq ≤ i₀ r hr pq - monotone_i₃ (r r' : ℤ) (hr : r₀ ≤ r) (hrr' : r ≤ r') (pq : κ) : - i₃ r hr pq ≤ i₃ r' (by lia) pq - i₀_prev' (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : - i₀ (r + 1) (by lia) pq = i₁ pq' - i₃_next' (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') : - i₃ (r + 1) (by lia) pq' = i₂ pq + le₂₃ (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : i₂ pq ≤ i₃ r pq + hc (r : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hr : r₀ ≤ r := by lia) : deg pq + 1 = deg pq' + hc₀₂ (r : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hr : r₀ ≤ r := by lia) : i₀ r pq = i₂ pq' + hc₁₃ (r : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hr : r₀ ≤ r := by lia) : i₁ pq = i₃ r pq' + antitone_i₀ (r r' : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) (hrr' : r ≤ r' := by lia) : + i₀ r' pq ≤ i₀ r pq + monotone_i₃ (r r' : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) (hrr' : r ≤ r' := by lia) : + i₃ r pq ≤ i₃ r' pq + i₀_prev' (r : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hr : r₀ ≤ r := by lia) : + i₀ (r + 1) pq = i₁ pq' + i₃_next' (r : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hr : r₀ ≤ r := by lia): + i₃ (r + 1) pq' = i₂ pq namespace SpectralSequenceMkData variable (data : SpectralSequenceMkData ι c r₀) -lemma i₀_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) : - data.i₀ r' (by lia) pq ≤ data.i₀ r hr pq := by - apply data.antitone_i₀ - lia +lemma i₀_le (r r' : ℤ) (pq : κ) (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + data.i₀ r' pq ≤ data.i₀ r pq := + data.antitone_i₀ r r' pq -lemma i₃_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) : - data.i₃ r hr pq ≤ data.i₃ r' (by lia) pq := by - apply data.monotone_i₃ - lia +lemma i₃_le (r r' : ℤ) (pq : κ) (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + data.i₃ r pq ≤ data.i₃ r' pq := + data.monotone_i₃ r r' pq -lemma i₀_prev (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq pq' : κ) - (hpq : (c r).Rel pq pq') : - data.i₀ r' (by lia) pq = data.i₁ pq' := by +lemma i₀_prev (r r' : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') + (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + data.i₀ r' pq = data.i₁ pq' := by subst hrr' - exact data.i₀_prev' r hr pq pq' hpq + exact data.i₀_prev' r pq pq' hpq -lemma i₃_next (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq pq' : κ) - (hpq : (c r).Rel pq pq') : - data.i₃ r' (by lia) pq' = data.i₂ pq := by +lemma i₃_next (r r' : ℤ) (pq pq' : κ) + (hpq : (c r).Rel pq pq') (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + data.i₃ r' pq' = data.i₂ pq := by subst hrr' - exact data.i₃_next' r hr pq pq' hpq + exact data.i₃_next' r pq pq' hpq + +lemma le₀'₀ {r r' : ℤ} (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq' : κ) + {i₀' i₀ : ι} + (hi₀' : i₀' = data.i₀ r' pq') + (hi₀ : i₀ = data.i₀ r pq') : + i₀' ≤ i₀ := by + rw [hi₀', hi₀] + exact data.antitone_i₀ r r' pq' + +lemma le₀₁' (r : ℤ) (hr : r₀ ≤ r) (pq' : κ) {i₀ i₁ : ι} + (hi₀ : i₀ = data.i₀ r pq') + (hi₁ : i₁ = data.i₁ pq') : + i₀ ≤ i₁ := by + have := data.le₀₁ r pq' + simpa only [hi₀, hi₁] using data.le₀₁ r pq' + +lemma le₁₂' (pq' : κ) {i₁ i₂ : ι} (hi₁ : i₁ = data.i₁ pq') (hi₂ : i₂ = data.i₂ pq') : + i₁ ≤ i₂ := by + simpa only [hi₁, hi₂] using data.le₁₂ pq' + +lemma le₂₃' (r : ℤ) (hr : r₀ ≤ r) (pq' : κ) + {i₂ i₃ : ι} + (hi₂ : i₂ = data.i₂ pq') + (hi₃ : i₃ = data.i₃ r pq') : + i₂ ≤ i₃ := by + simpa only [hi₂, hi₃] using data.le₂₃ r pq' + +lemma le₃₃' {r r' : ℤ} (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq' : κ) + {i₃ i₃' : ι} + (hi₃ : i₃ = data.i₃ r pq') + (hi₃' : i₃' = data.i₃ r' pq') : + i₃ ≤ i₃' := by + simpa only [hi₃, hi₃'] using data.monotone_i₃ r r' pq' end SpectralSequenceMkData @@ -130,20 +161,20 @@ indexed by `ℤ × ℤ` from a spectral object indexed by `EInt`. -/ def mkDataE₂Cohomological : SpectralSequenceMkData EInt (fun r ↦ ComplexShape.up' (⟨r, 1 - r⟩ : ℤ × ℤ)) 2 where deg pq := pq.1 + pq.2 - i₀ r hr pq := (pq.2 - r + 2 :) + i₀ r pq hr := (pq.2 - r + 2 :) i₁ pq := pq.2 i₂ pq := (pq.2 + 1 :) - i₃ r hr pq := (pq.2 + r - 1 :) - le₀₁ r hr pq := by simp; lia + i₃ r pq hr := (pq.2 + r - 1 :) + le₀₁ r pq hr := by simp; lia le₁₂ pq := by simp - le₂₃ r hr pq := by simp; lia - hc := by rintro r _ pq _ rfl; dsimp; lia - hc₀₂ := by rintro r hr pq _ rfl; simp; lia - hc₁₃ := by rintro r hr pq _ rfl; simp; lia - antitone_i₀ r r' hr hrr' pq := by simp; lia - monotone_i₃ r r' hr hrr' pq := by simp; lia - i₀_prev' := by rintro r hr pq _ rfl; dsimp; lia - i₃_next' := by rintro r hr pq _ rfl; dsimp; lia + le₂₃ r pq hr := by simp; lia + hc := by rintro r pq _ rfl _; dsimp; lia + hc₀₂ := by rintro r pq hr rfl _ ; simp; lia + hc₁₃ := by rintro r pq hr rfl _; simp; lia + antitone_i₀ r r' pq hr hrr' := by simp; lia + monotone_i₃ r r' pq hr hrr' := by simp; lia + i₀_prev' := by rintro r hr pq rfl _; dsimp; lia + i₃_next' := by rintro r hr pq rfl _; dsimp; lia /-- The data which allows to construct an `E₂`-cohomological spectral sequence indexed by `ℕ × ℕ` from a spectral object indexed by `EInt`. (Note: additional @@ -153,26 +184,26 @@ def mkDataE₂CohomologicalNat : SpectralSequenceMkData EInt (fun r ↦ ComplexShape.spectralSequenceNat ⟨r, 1 - r⟩) 2 where deg pq := pq.1 + pq.2 - i₀ r hr pq := (pq.2 - r + 2 :) + i₀ r pq hr := (pq.2 - r + 2 :) i₁ pq := (pq.2 : ℤ) i₂ pq := (pq.2 + 1 : ℤ) - i₃ r hr pq := (pq.2 + r - 1 : ℤ) - le₀₁ r hr pq := by simp; lia + i₃ r pq hr := (pq.2 + r - 1 : ℤ) + le₀₁ r pq hr := by simp; lia le₁₂ pq := by simp - le₂₃ r hr pq := by simp; lia - hc r _ pq pq' hpq := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq; lia - hc₀₂ r hr pq pq' hpq := by + le₂₃ r pq hr := by simp; lia + hc r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq; lia + hc₀₂ r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - hc₁₃ r hr pq pq' hpq := by + hc₁₃ r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - antitone_i₀ r r' hrr' hr pq := by simp; lia - monotone_i₃ r r' hrr' hr pq := by simp; lia - i₀_prev' r hr pq pq' hpq := by + antitone_i₀ r r' pq hr hrr' := by simp; lia + monotone_i₃ r r' pq hr hrr' := by simp; lia + i₀_prev' r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - i₃_next' r hr pq pq' hpq := by + i₃_next' r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia @@ -189,43 +220,43 @@ def mkDataE₂CohomologicalFin (l : ℕ) : SpectralSequenceMkData (Fin (l + 1)) (fun r ↦ ComplexShape.spectralSequenceFin l ⟨r, 1 - r⟩) 2 where deg pq := pq.1 + pq.2.1 - i₀ r hr pq := ⟨(pq.2.1 - (r - 2)).toNat, by grind⟩ + i₀ r pq hr := ⟨(pq.2.1 - (r - 2)).toNat, by grind⟩ i₁ pq := pq.2.castSucc i₂ pq := pq.2.succ - i₃ r hr pq := Fin.clamp (pq.2.1 + (r - 1)).toNat _ - le₀₁ r hr := by rintro ⟨p, q, hq⟩; simp; lia + i₃ r pq hr := Fin.clamp (pq.2.1 + (r - 1)).toNat _ + le₀₁ := by rintro r ⟨p, q, hq⟩ hr; simp; lia le₁₂ pq := by simp [Fin.le_iff_val_le_val] - le₂₃ r hr pq := by + le₂₃ r pq hr := by simp only [Fin.le_iff_val_le_val, Fin.val_succ, le_min_iff, Fin.clamp] grind - hc _ _ _ _ := fun ⟨h₁, h₂⟩ ↦ by lia - hc₀₂ r hr := by - rintro ⟨a₁, ⟨a₂, _⟩⟩ ⟨b₁, ⟨b₂, _⟩⟩ ⟨h₁, h₂⟩ + hc _ _ _ := fun ⟨h₁, h₂⟩ ↦ by lia + hc₀₂ r := by + rintro ⟨a₁, ⟨a₂, _⟩⟩ ⟨b₁, ⟨b₂, _⟩⟩ ⟨h₁, h₂⟩ hr ext grind - hc₁₃ r hr := by - rintro ⟨a₁, ⟨a₂, _⟩⟩ ⟨b₁, ⟨b₂, _⟩⟩ ⟨h₁, h₂⟩ + hc₁₃ r := by + rintro ⟨a₁, ⟨a₂, _⟩⟩ ⟨b₁, ⟨b₂, _⟩⟩ ⟨h₁, h₂⟩ hr rw [Fin.ext_iff] dsimp at h₁ h₂ ⊢ grind - antitone_i₀ r r' hr hrr' := by - rintro ⟨a, ⟨a', _⟩⟩ + antitone_i₀ := by + rintro r r' ⟨a, ⟨a', _⟩⟩ hr hrr' dsimp rw [Fin.mk_le_mk] lia - monotone_i₃ r r' hr hrr' := by - rintro ⟨a, ⟨a', _⟩⟩ + monotone_i₃ := by + rintro r r' ⟨a, ⟨a', _⟩⟩ hr hrr' dsimp rw [Fin.mk_le_mk] apply Fin.clamp_le_clamp lia - i₀_prev' r hr := by - rintro ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ + i₀_prev' := by + rintro r ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ hr ext dsimp at h₁ h₂ ⊢ lia - i₃_next' r hr := by - rintro ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ + i₃_next' := by + rintro r ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ hr ext dsimp at h₁ h₂ ⊢ grind @@ -238,28 +269,28 @@ def mkDataE₂HomologicalNat : SpectralSequenceMkData EInt (fun r ↦ ComplexShape.spectralSequenceNat ⟨-r, r - 1⟩) 2 where deg pq := - pq.1 - pq.2 - i₀ r hr pq := (-pq.2 - r + 2 :) + i₀ r pq hr := (-pq.2 - r + 2 :) i₁ pq := (-pq.2 : ℤ) i₂ pq := (-pq.2 + 1 : ℤ) - i₃ r hr pq := (-pq.2 + r - 1 :) - le₀₁ r hr pq := by simp; lia + i₃ r pq hr := (-pq.2 + r - 1 :) + le₀₁ r pq hr := by simp; lia le₁₂ pq := by simp - le₂₃ r hr pq := by simp; lia - hc r _ pq pq' hpq := by + le₂₃ r pq hr := by simp; lia + hc r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - hc₀₂ r hr pq pq' hpq := by + hc₀₂ r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - hc₁₃ r hr pq pq' hpq := by + hc₁₃ r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - antitone_i₀ r r' hrr' hr pq := by simp; lia - monotone_i₃ r r' hrr' hr pq := by simp; lia - i₀_prev' r hr pq pq' hpq := by + antitone_i₀ r r' pq hr hrr' := by simp; lia + monotone_i₃ r r' pq hr hrr' := by simp; lia + i₀_prev' r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - i₃_next' r hr pq pq' hpq := by + i₃_next' r pq pq' hpq hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia @@ -270,56 +301,57 @@ the property which allows to construct a spectral sequence by using the recipe g by `data`. The conditions given allow to show that the homology of a page identifies to the next page. -/ class HasSpectralSequence : Prop where - isZero_H_obj_mk₁_i₀_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) - (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) - (n : ℤ) (hn : n = data.deg pq + 1) : - IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₀_le r r' hrr' hr pq)))) - isZero_H_obj_mk₁_i₃_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) - (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) - (n : ℤ) (hn : n = data.deg pq - 1) : - IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₃_le r r' hrr' hr pq)))) + isZero_H_obj_mk₁_i₀_le (r r' : ℤ) (pq : κ) + (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) + (n : ℤ) (hn : n = data.deg pq + 1 ) + (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₀_le r r' pq)))) + isZero_H_obj_mk₁_i₃_le (r r' : ℤ) (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) + (n : ℤ) (hn : n = data.deg pq - 1) + (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₃_le r r' pq)))) variable [X.HasSpectralSequence data] lemma isZero_H_obj_mk₁_i₀_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) (n : ℤ) (hn : n = data.deg pq + 1) : - IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₀_le r r' hrr' hr pq)))) := - HasSpectralSequence.isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq n hn + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₀_le r r' pq)))) := + HasSpectralSequence.isZero_H_obj_mk₁_i₀_le r r' pq hpq n hn /-- isZero_H_obj_mk₁_i₀_le' -/ lemma isZero_H_obj_mk₁_i₀_le' (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) (n : ℤ) (hn : n = data.deg pq + 1) (i₀' i₀ : ι) - (hi₀' : i₀' = data.i₀ r' (by lia) pq) - (hi₀ : i₀ = data.i₀ r hr pq) : + (hi₀' : i₀' = data.i₀ r' pq) + (hi₀ : i₀ = data.i₀ r pq) : IsZero ((X.H n).obj (mk₁ (homOfLE (show i₀' ≤ i₀ by - simpa only [hi₀', hi₀] using data.i₀_le r r' hrr' hr pq)))) := by + simpa only [hi₀', hi₀] using data.i₀_le r r' pq)))) := by subst hi₀' hi₀ - exact HasSpectralSequence.isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq n hn + exact HasSpectralSequence.isZero_H_obj_mk₁_i₀_le r r' pq hpq n hn lemma isZero_H_obj_mk₁_i₃_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) (n : ℤ) (hn : n = data.deg pq - 1) : - IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₃_le r r' hrr' hr pq)))) := - HasSpectralSequence.isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq n hn + IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₃_le r r' pq)))) := + HasSpectralSequence.isZero_H_obj_mk₁_i₃_le r r' pq hpq n hn /-- isZero_H_obj_mk₁_i₃_le' -/ lemma isZero_H_obj_mk₁_i₃_le' (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) (n : ℤ) (hn : n = data.deg pq - 1) (i₃ i₃' : ι) - (hi₃ : i₃ = data.i₃ r hr pq) - (hi₃' : i₃' = data.i₃ r' (by lia) pq) : + (hi₃ : i₃ = data.i₃ r pq) + (hi₃' : i₃' = data.i₃ r' pq) : IsZero ((X.H n).obj (mk₁ (homOfLE (show i₃ ≤ i₃' by - simpa only [hi₃, hi₃'] using data.i₃_le r r' hrr' hr pq)))) := by + simpa only [hi₃, hi₃'] using data.i₃_le r r' pq)))) := by subst hi₃ hi₃' - exact HasSpectralSequence.isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq n hn + exact HasSpectralSequence.isZero_H_obj_mk₁_i₃_le r r' pq hpq n hn instance (E : SpectralObject C EInt) : E.HasSpectralSequence mkDataE₂Cohomological where - isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq := by + isZero_H_obj_mk₁_i₀_le r r' pq hpq n hn hrr' hr := by exfalso exact hpq _ rfl - isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq := by + isZero_H_obj_mk₁_i₃_le r r' pq hpq n hn hrr' hr := by exfalso exact hpq (pq - (r, 1-r)) (by simp) @@ -330,9 +362,9 @@ lemma _root_.Fin.clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : instance {l : ℕ} (E : SpectralObject C (Fin (l + 1))) : E.HasSpectralSequence (mkDataE₂CohomologicalFin l) where - isZero_H_obj_mk₁_i₀_le r r' hrr' hr pq hpq n hn := by - have : (mkDataE₂CohomologicalFin l).i₀ r' (by lia) pq = - (mkDataE₂CohomologicalFin l).i₀ r hr pq := by + isZero_H_obj_mk₁_i₀_le r r' pq hpq n hn hrr' hr := by + have : (mkDataE₂CohomologicalFin l).i₀ r' pq = + (mkDataE₂CohomologicalFin l).i₀ r pq := by subst hrr' obtain ⟨k, rfl⟩ := Int.le.dest hr obtain ⟨p, q, hq⟩ := pq @@ -346,9 +378,9 @@ instance {l : ℕ} (E : SpectralObject C (Fin (l + 1))) : lia have := isIso_homOfLE this apply E.isZero_H_map_mk₁_of_isIso - isZero_H_obj_mk₁_i₃_le r r' hrr' hr pq hpq n hn := by - have : (mkDataE₂CohomologicalFin l).i₃ r hr pq = - (mkDataE₂CohomologicalFin l).i₃ r' (by lia) pq := by + isZero_H_obj_mk₁_i₃_le r r' pq hpq n hn hrr' hr := by + have : (mkDataE₂CohomologicalFin l).i₃ r pq = + (mkDataE₂CohomologicalFin l).i₃ r' pq := by subst hrr' obtain ⟨p, q, hq⟩ := pq have h : l < q + r := by @@ -386,7 +418,7 @@ lemma isZero₂_of_isFirstQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hi : instance : Y.HasSpectralSequence mkDataE₂CohomologicalNat where isZero_H_obj_mk₁_i₀_le := by - rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + rintro r _ ⟨p, q⟩ hpq n rfl rfl hr apply isZero₁_of_isFirstQuadrant dsimp simp only [WithBotTop.coe_le_coe] @@ -396,7 +428,7 @@ instance : Y.HasSpectralSequence mkDataE₂CohomologicalNat where simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq exact hpq ⟨p', q'⟩ (by constructor <;> lia) isZero_H_obj_mk₁_i₃_le := by - rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + rintro r _ ⟨p, q⟩ hpq n rfl rfl hr apply isZero₂_of_isFirstQuadrant dsimp simp only [WithBotTop.coe_lt_coe] @@ -433,7 +465,7 @@ lemma isZero₂_of_isThirdQuadrant (i j : EInt) (hij : i ≤ j) (n : ℤ) (hj : instance : Y.HasSpectralSequence mkDataE₂HomologicalNat where isZero_H_obj_mk₁_i₀_le := by - rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + rintro r _ ⟨p, q⟩ hpq n rfl rfl hr apply isZero₂_of_isThirdQuadrant dsimp simp only [WithBotTop.coe_le_coe] @@ -443,7 +475,7 @@ instance : Y.HasSpectralSequence mkDataE₂HomologicalNat where simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq exact hpq ⟨p', q'⟩ (by constructor <;> lia) isZero_H_obj_mk₁_i₃_le := by - rintro r _ rfl hr ⟨p, q⟩ hpq n rfl + rintro r _ ⟨p, q⟩ hpq n rfl rfl hr apply isZero₁_of_isThirdQuadrant dsimp simp only [WithBotTop.coe_lt_coe] diff --git a/Mathlib/Algebra/Homology/SpectralObject/Homology.lean b/Mathlib/Algebra/Homology/SpectralObject/Homology.lean index ae3f763e084422..beff73ba6982f2 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Homology.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Homology.lean @@ -5,8 +5,7 @@ Authors: Joël Riou -/ module -public import Mathlib.Algebra.Homology.SpectralObject.Differentials -public import Mathlib.CategoryTheory.ComposableArrows.Four +public import Mathlib.Algebra.Homology.SpectralObject.EpiMono /-! # The homology of the differentials of a spectral object @@ -40,29 +39,6 @@ variable (X : SpectralObject C ι) section -variable (n₀ n₁ n₂ n₃ : ℤ) - (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) - {i₀' i₀ i₁ i₂ i₃ i₃' : ι} (f₁ : i₀ ⟶ i₁) - (f₁' : i₀' ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) (f₃' : i₂ ⟶ i₃') - -lemma epi_EMap (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁ f₂ f₃') - (hα₀ : α.app 0 = 𝟙 _) (hα₁ : α.app 1 = 𝟙 _) (hα₂ : α.app 2 = 𝟙 _) : - Epi (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁ f₂ f₃' α) := by - have := X.πE_EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ α (𝟙 _) (by cat_disch) - rw [cyclesMap_id, id_comp] at this - exact epi_of_epi_fac this - -lemma mono_EMap (α : mk₃ f₁ f₂ f₃ ⟶ mk₃ f₁' f₂ f₃) - (hα₁ : α.app 1 = 𝟙 _) (hα₂ : α.app 2 = 𝟙 _) (hα₃ : α.app 3 = 𝟙 _) : - Mono (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃ f₁' f₂ f₃ α) := by - have := X.EMap_ιE n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ α (𝟙 _) (by cat_disch) - rw [opcyclesMap_id, comp_id] at this - exact mono_of_mono_fac this - -end - -section - variable (n₀ n₁ n₂ n₃ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) {i₀ i₁ i₂ i₃ i₄ i₅ i₆ i₇ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) @@ -70,69 +46,6 @@ variable (n₀ n₁ n₂ n₃ : ℤ) (f₂₃ : i₁ ⟶ i₃) (h₂₃ : f₂ ≫ f₃ = f₂₃) (f₃₄ : i₂ ⟶ i₄) (h₃₄ : f₃ ≫ f₄ = f₃₄) -@[reassoc (attr := simp)] -lemma d_EMap_fourδ₄Toδ₃ : - X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ - X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄) = 0 := by - rw [← cancel_epi (X.πE n₀ n₁ n₂ hn₁ hn₂ f₃ f₄ f₅), - ← cancel_epi (X.toCycles n₁ f₃ f₄ f₃₄ h₃₄), comp_zero, comp_zero, - X.toCycles_πE_d_assoc n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ _ rfl f₃₄ h₃₄, - X.πE_EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ - (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄) (𝟙 _) (by ext <;> simp; rfl), - cyclesMap_id, Category.id_comp, δ_toCycles_assoc, δToCycles_πE] - -instance : - Epi (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := - X.epi_EMap _ _ _ _ _ _ _ _ _ _ rfl rfl rfl - -lemma isIso_EMap_fourδ₄Toδ₃ (h : ((X.H n₁).map (twoδ₁Toδ₀ f₃ f₄ f₃₄ h₃₄) = 0)) : - IsIso (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := by - apply ShortComplex.isIso_homologyMap_of_epi_of_isIso_of_mono' - · exact (X.exact₂ _ f₃ f₄ f₃₄ h₃₄).epi_f h - · dsimp - convert inferInstanceAs (IsIso ((X.H n₂).map (𝟙 _))) - cat_disch - · dsimp - convert inferInstanceAs (Mono ((X.H n₃).map (𝟙 (mk₁ f₁)))) - cat_disch - -lemma isIso_EMap_fourδ₄Toδ₃_of_isZero (h : IsZero ((X.H n₁).obj (mk₁ f₄))) : - IsIso (X.EMap n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃ f₁ f₂ f₃₄ (fourδ₄Toδ₃ f₁ f₂ f₃ f₄ f₃₄ h₃₄)) := by - apply X.isIso_EMap_fourδ₄Toδ₃ - apply h.eq_of_tgt - -@[reassoc (attr := simp)] -lemma EMap_fourδ₁Toδ₀_d : - X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) ≫ - X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ = 0 := by - rw [← cancel_mono (X.ιE n₁ n₂ n₃ hn₂ hn₃ f₁ f₂ f₃), - ← cancel_mono (X.fromOpcycles n₂ f₂ f₃ f₂₃ h₂₃), zero_comp, zero_comp, assoc, - assoc, X.d_ιE_fromOpcycles n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ f₂₃ h₂₃ _ rfl _ rfl] - rw [X.EMap_ιE_assoc n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ - (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃) (𝟙 _) (by ext <;> simp <;> rfl), - opcyclesMap_id, fromOpcyles_δ, id_comp, ιE_δFromOpcycles] - -instance : - Mono (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := - X.mono_EMap _ _ _ _ _ _ _ _ _ _ rfl rfl rfl - -lemma isIso_EMap_fourδ₁Toδ₀ (h : ((X.H n₂).map (twoδ₂Toδ₁ f₂ f₃ f₂₃ h₂₃) = 0)) : - IsIso (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := by - apply ShortComplex.isIso_homologyMap_of_epi_of_isIso_of_mono' - · dsimp - convert inferInstanceAs (Epi ((X.H n₀).map (𝟙 _))) - cat_disch - · dsimp - convert inferInstanceAs (IsIso ((X.H n₁).map (𝟙 _))) - cat_disch - · exact (X.exact₂ n₂ f₂ f₃ f₂₃ h₂₃).mono_g h - -lemma isIso_EMap_fourδ₁Toδ₀_of_isZero (h : IsZero ((X.H n₂).obj (mk₁ f₂))) : - IsIso (X.EMap n₀ n₁ n₂ hn₁ hn₂ f₂₃ f₄ f₅ f₃ f₄ f₅ (fourδ₁Toδ₀ f₂ f₃ f₄ f₅ f₂₃ h₂₃)) := by - apply X.isIso_EMap_fourδ₁Toδ₀ - apply h.eq_of_src - - /-- The (exact) sequence expressing `E^n(f₁, f₂, f₃ ≫ f₄)` as the cokernel of the differential `E^{n-1}(f₃, f₄, f₅) ⟶ E^n(f₁, f₂, f₃)` -/ @[simps!] diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index b2eb93172be9cd..a60557e9e376ff 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -20,7 +20,7 @@ public import Batteries.Tactic.Lint namespace CategoryTheory -open Category Limits ComposableArrows +open Limits ComposableArrows namespace Abelian @@ -30,237 +30,93 @@ variable {C ι κ : Type*} [Category C] [Abelian C] [Preorder ι] (X : SpectralObject C ι) {c : ℤ → ComplexShape κ} {r₀ : ℤ} -section - -variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) - (i₀ i₁ i₂ i₃ i₄ i₅ : ι) (hi₀₁ : i₀ ≤ i₁) - (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) (hi₃₄ : i₃ ≤ i₄) (hi₄₅ : i₄ ≤ i₅) - -/-- EMapFourδ₁Toδ₀' -/ -noncomputable abbrev EMapFourδ₁Toδ₀' := - X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₁Toδ₀' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) - -/-- mono_EMapFourδ₁Toδ₀' -/ -instance mono_EMapFourδ₁Toδ₀' : - Mono (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by - dsimp [EMapFourδ₁Toδ₀'] - infer_instance - -/-- EMapFourδ₄Toδ₃' -/ -noncomputable abbrev EMapFourδ₄Toδ₃' := - X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₄Toδ₃' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) - -/-- epi_EMapFourδ₄Toδ₃' -/ -instance epi_EMapFourδ₄Toδ₃' : - Epi (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by - dsimp [EMapFourδ₄Toδ₃'] - infer_instance - -@[reassoc] -lemma EMapFourδ₁Toδ₀'_comp : - X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₃ i₄ i₅ hi₀₁ (hi₁₂.trans hi₂₃) hi₃₄ hi₄₅ ≫ - X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₁ i₂ i₃ i₄ i₅ hi₁₂ hi₂₃ hi₃₄ hi₄₅ = - X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₂ i₃ i₄ i₅ (hi₀₁.trans hi₁₂) hi₂₃ hi₃₄ hi₄₅ := by - rw [← EMap_comp] - rfl - -@[reassoc] -lemma EMapFourδ₄Toδ₃'_comp : - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₄ i₅ hi₀₁ hi₁₂ (hi₂₃.trans hi₃₄) hi₄₅ = - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₅ hi₀₁ hi₁₂ hi₂₃ (hi₃₄.trans hi₄₅) := by - dsimp [EMapFourδ₄Toδ₃'] - rw [← EMap_comp] - rfl - -/-- EMapFourδ₁Toδ₀'_EMapFourδ₃Toδ₃' -/ -@[reassoc] -lemma EMapFourδ₁Toδ₀'_EMapFourδ₃Toδ₃' : - X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₁ i₂ i₃ i₄ i₅ hi₁₂ hi₂₃ hi₃₄ hi₄₅ = - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₂ i₃ i₄ i₅ _ _ _ hi₄₅ ≫ - X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₅ hi₀₁ _ _ _ := by - dsimp [EMapFourδ₁Toδ₀', EMapFourδ₄Toδ₃'] - rw [← EMap_comp, ← EMap_comp] - rfl - -section - -variable (h : IsZero ((H X n₂).obj (mk₁ (homOfLE hi₀₁)))) - -include h in -lemma isIso_EMapFourδ₁Toδ₀' : - IsIso (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by - apply X.isIso_EMap_fourδ₁Toδ₀_of_isZero - exact h - -/-- isoEMapFourδ₁Toδ₀' -/ -@[simps! hom] -noncomputable def isoEMapFourδ₁Toδ₀' : - X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE (hi₀₁.trans hi₁₂)) (homOfLE hi₂₃) (homOfLE hi₃₄) ≅ - X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₁₂) (homOfLE hi₂₃) (homOfLE hi₃₄) := - have := X.isIso_EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h - asIso (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) - -@[reassoc (attr := simp)] -lemma isoEMapFourδ₁Toδ₀'_hom_inv_id : - X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ - (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv = 𝟙 _ := - (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).hom_inv_id - -@[reassoc (attr := simp)] -lemma isoEMapFourδ₁Toδ₀'_inv_hom_id : - (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv ≫ - X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ = 𝟙 _ := - (X.isoEMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv_hom_id - -end - -section - -variable (h : IsZero ((H X n₀).obj (mk₁ (homOfLE hi₃₄)))) - -include h in -lemma isIso_EMapFourδ₄Toδ₃' : - IsIso (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by - apply X.isIso_EMap_fourδ₄Toδ₃_of_isZero - exact h - -/-- isoEMapFourδ₄Toδ₃' -/ -@[simps! hom] -noncomputable def isoEMapFourδ₄Toδ₃' : - X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE hi₂₃) ≅ - X.E n₀ n₁ n₂ hn₁ hn₂ (homOfLE hi₀₁) (homOfLE hi₁₂) (homOfLE (hi₂₃.trans hi₃₄)) := - have := X.isIso_EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h - asIso (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) - -@[reassoc (attr := simp)] -lemma isoEMapFourδ₄Toδ₄'_hom_inv_id : - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ ≫ - (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv = 𝟙 _ := - (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).hom_inv_id - -@[reassoc (attr := simp)] -lemma isoEMapFourδ₄Toδ₄'_inv_hom_id : - (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv ≫ - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ = 𝟙 _ := - (X.isoEMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄ h).inv_hom_id - -end - -section - -variable (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) - (i₀ i₁ i₂ i₃ i₄ i₅ : ι) (hi₀₁ : i₀ ≤ i₁) - (hi₁₂ : i₁ ≤ i₂) (hi₂₃ : i₂ ≤ i₃) (hi₃₄ : i₃ ≤ i₄) (hi₄₅ : i₄ ≤ i₅) - -/-- EMapFourδ₂Toδ₁' -/ -noncomputable abbrev EMapFourδ₂Toδ₁' := - X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ (fourδ₂Toδ₁' i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) - -/-- isIso_EMapFourδ₂Toδ₁' -/ -lemma isIso_EMapFourδ₂Toδ₁' - (h₁ : IsIso ((X.H n₁).map (twoδ₁Toδ₀' i₁ i₂ i₃ hi₁₂ hi₂₃))) - (h₂ : IsIso ((X.H n₂).map (twoδ₂Toδ₁' i₀ i₁ i₂ hi₀₁ hi₁₂))) : - IsIso (X.EMapFourδ₂Toδ₁' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by - apply X.isIso_EMap - · dsimp - erw [Functor.map_id] - infer_instance - · exact h₁ - · exact h₂ - -end - -end - variable (data : SpectralSequenceMkData ι c r₀) namespace SpectralSequence -noncomputable def pageX (r : ℤ) (hr : r₀ ≤ r) (pq : κ) : C := +noncomputable def pageX (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : C := X.E (data.deg pq - 1) (data.deg pq) (data.deg pq + 1) (by simp) rfl - (homOfLE (data.le₀₁ r hr pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r hr pq)) + (homOfLE (data.le₀₁ r pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r pq)) noncomputable def pageXIso (r : ℤ) (hr : r₀ ≤ r) (pq : κ) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) - (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = data.i₀ r hr pq) (h₁ : i₁ = data.i₁ pq) - (h₂ : i₂ = data.i₂ pq) (h₃ : i₃ = data.i₃ r hr pq) : - pageX X data r hr pq ≅ X.E n₀ n₁ n₂ hn₁ hn₂ - (homOfLE (by subst h₀ h₁; exact data.le₀₁ r hr pq) : i₀ ⟶ i₁) + (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = data.i₀ r pq) (h₁ : i₁ = data.i₁ pq) + (h₂ : i₂ = data.i₂ pq) (h₃ : i₃ = data.i₃ r pq) : + pageX X data r pq hr ≅ X.E n₀ n₁ n₂ hn₁ hn₂ + (homOfLE (by subst h₀ h₁; exact data.le₀₁ r pq) : i₀ ⟶ i₁) (homOfLE (by subst h₁ h₂; exact data.le₁₂ pq) : i₁ ⟶ i₂) - (homOfLE (by subst h₂ h₃; exact data.le₂₃ r hr pq) : i₂ ⟶ i₃) := + (homOfLE (by subst h₂ h₃; exact data.le₂₃ r pq) : i₂ ⟶ i₃) := eqToIso (by obtain rfl : n₀ = n₁ - 1 := by lia subst h hn₂ h₀ h₁ h₂ h₃ rfl) open Classical in -noncomputable def paged (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) : - pageX X data r hr pq ⟶ pageX X data r hr pq' := +noncomputable def pageD (r : ℤ) (pq pq' : κ) (hr : r₀ ≤ r := by lia) : + pageX X data r pq hr ⟶ pageX X data r pq' hr := if hpq : (c r).Rel pq pq' then X.d (data.deg pq - 1) (data.deg pq) (data.deg pq + 1) (data.deg pq + 2) _ rfl - (by lia) (homOfLE (data.le₀₁ r hr pq')) - (homOfLE (by simpa only [data.hc₀₂ r hr pq pq' hpq] using data.le₁₂ pq')) - (homOfLE (data.le₀₁ r hr pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r hr pq)) ≫ - (pageXIso _ _ _ _ _ _ _ _ _ _ (data.hc r hr pq pq' hpq) _ _ _ _ rfl rfl - (data.hc₀₂ r hr pq pq' hpq) (data.hc₁₃ r hr pq pq' hpq)).inv + (by lia) (homOfLE (data.le₀₁ r pq')) + (homOfLE (by simpa only [data.hc₀₂ r pq pq' hpq] using data.le₁₂ pq')) + (homOfLE (data.le₀₁ r pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r pq)) ≫ + (pageXIso _ _ _ _ _ _ _ _ _ _ (data.hc r pq pq' hpq) _ _ _ _ rfl rfl + (data.hc₀₂ r pq pq' hpq) (data.hc₁₃ r pq pq' hpq)).inv else 0 -lemma paged_eq (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') +lemma pageD_eq (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') (n₀ n₁ n₂ n₃ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) {i₀ i₁ i₂ i₃ i₄ i₅ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) (hn₁' : n₁ = data.deg pq) - (h₀ : i₀ = data.i₀ r hr pq') (h₁ : i₁ = data.i₁ pq') (h₂ : i₂ = data.i₀ r hr pq) - (h₃ : i₃ = data.i₁ pq) (h₄ : i₄ = data.i₂ pq) (h₅ : i₅ = data.i₃ r hr pq) : - paged X data r hr pq pq' = + (h₀ : i₀ = data.i₀ r pq') (h₁ : i₁ = data.i₁ pq') (h₂ : i₂ = data.i₀ r pq) + (h₃ : i₃ = data.i₁ pq) (h₄ : i₄ = data.i₂ pq) (h₅ : i₅ = data.i₃ r pq) : + pageD X data r pq pq' = (pageXIso _ _ _ _ _ _ _ _ _ _ hn₁' _ _ _ _ h₂ h₃ h₄ h₅).hom ≫ X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ (pageXIso _ _ _ _ _ _ _ _ _ _ - (by simpa only [← hn₂, hn₁'] using data.hc r hr pq pq' hpq) _ _ _ _ h₀ h₁ - (by rw [h₂, data.hc₀₂ r hr pq pq' hpq]) - (by rw [h₃, data.hc₁₃ r hr pq pq' hpq])).inv := by + (by simpa only [← hn₂, hn₁'] using data.hc r pq pq' hpq) _ _ _ _ h₀ h₁ + (by rw [h₂, data.hc₀₂ r pq pq' hpq]) + (by rw [h₃, data.hc₁₃ r pq pq' hpq])).inv := by subst hn₁' h₀ h₁ h₂ h₃ h₄ h₅ obtain rfl : n₀ = data.deg pq - 1 := by lia obtain rfl : n₂ = data.deg pq + 1 := by lia obtain rfl : n₃ = data.deg pq + 2 := by lia - dsimp [paged, pageXIso] - rw [dif_pos hpq, id_comp] + dsimp [pageD, pageXIso] + rw [dif_pos hpq, Category.id_comp] rfl @[reassoc (attr := simp)] -lemma paged_paged (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) : - paged X data r hr pq pq' ≫ paged X data r hr pq' pq'' = 0 := by +lemma pageD_pageD (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) : + pageD X data r pq pq' hr ≫ pageD X data r pq' pq'' hr = 0 := by by_cases hpq : (c r).Rel pq pq' · by_cases hpq' : (c r).Rel pq' pq'' - · let f₁ := homOfLE (data.le₀₁ r hr pq'') + · let f₁ := homOfLE (data.le₀₁ r pq'') let f₂ := homOfLE (data.le₁₂ pq'') - let f₃ := homOfLE (data.le₂₃ r hr pq'') - let f₄ : data.i₃ r hr pq'' ⟶ data.i₀ r hr pq := homOfLE (by - simpa only [← data.hc₁₃ r hr pq' pq'' hpq', - data.hc₀₂ r hr pq pq' hpq] using data.le₁₂ pq') - let f₅ := homOfLE (data.le₀₁ r hr pq) + let f₃ := homOfLE (data.le₂₃ r pq'') + let f₄ : data.i₃ r pq'' ⟶ data.i₀ r pq := homOfLE (by + simpa only [← data.hc₁₃ r pq' pq'' hpq', + data.hc₀₂ r pq pq' hpq] using data.le₁₂ pq') + let f₅ := homOfLE (data.le₀₁ r pq) let f₆ := homOfLE (data.le₁₂ pq) - let f₇ := homOfLE (data.le₂₃ r hr pq) - rw [paged_eq X data r hr pq pq' hpq (data.deg pq - 1) (data.deg pq) _ _ (by simp) - rfl rfl f₃ f₄ f₅ f₆ f₇ rfl (data.hc₀₂ r hr pq' pq'' hpq').symm - (data.hc₁₃ r hr pq' pq'' hpq').symm rfl rfl rfl rfl, - paged_eq X data r hr pq' pq'' hpq' (data.deg pq) _ _ _ rfl rfl rfl f₁ f₂ f₃ f₄ f₅ - (data.hc r hr pq pq' hpq) rfl rfl (data.hc₀₂ r hr pq' pq'' hpq').symm - (data.hc₁₃ r hr pq' pq'' hpq').symm (data.hc₀₂ r hr pq pq' hpq) - (data.hc₁₃ r hr pq pq' hpq), assoc, assoc, Iso.inv_hom_id_assoc, + let f₇ := homOfLE (data.le₂₃ r pq) + rw [pageD_eq X data r hr pq pq' hpq (data.deg pq - 1) (data.deg pq) _ _ (by simp) + rfl rfl f₃ f₄ f₅ f₆ f₇ rfl (data.hc₀₂ r pq' pq'' hpq').symm + (data.hc₁₃ r pq' pq'' hpq').symm rfl rfl rfl rfl, + pageD_eq X data r hr pq' pq'' hpq' (data.deg pq) _ _ _ rfl rfl rfl f₁ f₂ f₃ f₄ f₅ + (data.hc r pq pq' hpq) rfl rfl (data.hc₀₂ r pq' pq'' hpq').symm + (data.hc₁₃ r pq' pq'' hpq').symm (data.hc₀₂ r pq pq' hpq) + (data.hc₁₃ r pq pq' hpq), Category.assoc, Category.assoc, Iso.inv_hom_id_assoc, d_d_assoc, zero_comp, comp_zero] - · dsimp only [paged] + · dsimp only [pageD] rw [dif_neg hpq', comp_zero] - · dsimp only [paged] + · dsimp only [pageD] rw [dif_neg hpq, zero_comp] @[simps] noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : HomologicalComplex C (c r) where - X pq := pageX X data r hr pq - d := paged X data r hr + X pq := pageX X data r pq + d := pageD X data r shape pq pq' hpq := dif_neg hpq section @@ -271,25 +127,27 @@ noncomputable def shortComplexIso (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) (hn₄ : n₃ + 1 = n₄) (hn₂' : n₂ = data.deg pq') : (page X data r hr).sc' pq pq' pq'' ≅ - X.dShortComplex n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ (homOfLE (data.le₀₁ r hr pq'')) - (homOfLE (data.le₁₂ pq'')) (homOfLE (data.le₂₃ r hr pq'')) - (homOfLE (by simpa only [← data.hc₁₃ r hr pq' pq'' hpq', data.hc₀₂ r hr pq pq' hpq] - using data.le₁₂ pq')) (homOfLE (data.le₀₁ r hr pq)) - (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r hr pq)) := by + X.dShortComplex n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ (homOfLE (data.le₀₁ r pq'')) + (homOfLE (data.le₁₂ pq'')) (homOfLE (data.le₂₃ r pq'')) + (homOfLE (by simpa only [← data.hc₁₃ r pq' pq'' hpq', data.hc₀₂ r pq pq' hpq] + using data.le₁₂ pq')) (homOfLE (data.le₀₁ r pq)) + (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r pq)) := by refine ShortComplex.isoMk - (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr pq pq' hpq; lia) - _ _ _ _ rfl rfl rfl rfl) - (pageXIso X data _ _ _ _ _ _ _ _ hn₂' _ _ _ _ - (by rw [data.hc₀₂ r hr pq' pq'' hpq']) (by rw [data.hc₁₃ r hr pq' pq'' hpq']) - (by rw [data.hc₀₂ r hr pq pq' hpq]) (by rw [data.hc₁₃ r hr pq pq' hpq])) - (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr pq' pq'' hpq'; lia) + (pageXIso X data _ hr _ _ _ _ _ _ (by have := data.hc r pq pq' hpq; lia) _ _ _ _ + rfl rfl rfl rfl) + (pageXIso X data _ hr _ _ _ _ _ _ hn₂' _ _ _ _ + (by rw [data.hc₀₂ r pq' pq'' hpq']) (by rw [data.hc₁₃ r pq' pq'' hpq']) + (by rw [data.hc₀₂ r pq pq' hpq]) (by rw [data.hc₁₃ r pq pq' hpq])) + (pageXIso X data _ hr _ _ _ _ _ _ (by have := data.hc r pq' pq'' hpq'; lia) _ _ _ _ rfl rfl rfl rfl) ?_ ?_ · dsimp - rw [paged_eq X data r hr pq pq' hpq, assoc, assoc, Iso.inv_hom_id, comp_id] - · exact (data.hc₀₂ r hr pq' pq'' hpq').symm - · exact (data.hc₁₃ r hr pq' pq'' hpq').symm + rw [pageD_eq X data r hr pq pq' hpq, Category.assoc, Category.assoc, + Iso.inv_hom_id, Category.comp_id] + · exact (data.hc₀₂ r pq' pq'' hpq').symm + · exact (data.hc₁₃ r pq' pq'' hpq').symm · dsimp - rw [paged_eq X data r hr pq' pq'' hpq', assoc, assoc, Iso.inv_hom_id, comp_id] + rw [pageD_eq X data r hr pq' pq'' hpq', Category.assoc, Category.assoc, + Iso.inv_hom_id, Category.comp_id] · rfl · rfl @@ -300,35 +158,35 @@ variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₁' : n₁ = data.deg pq') (i₀' i₀ i₁ i₂ i₃ i₃' : ι) - (hi₀' : i₀' = data.i₀ r' (hr.trans ((@Int.le_add_one r r (le_refl _)).trans hrr'.le)) pq') - (hi₀ : i₀ = data.i₀ r hr pq') + (hi₀' : i₀' = data.i₀ r' pq') + (hi₀ : i₀ = data.i₀ r pq') (hi₁ : i₁ = data.i₁ pq') (hi₂ : i₂ = data.i₂ pq') - (hi₃ : i₃ = data.i₃ r hr pq') - (hi₃' : i₃' = data.i₃ r' (hr.trans ((@Int.le_add_one r r (le_refl _)).trans hrr'.le)) pq') + (hi₃ : i₃ = data.i₃ r pq') + (hi₃' : i₃' = data.i₃ r' pq') namespace HomologyData -def f₁ : i₀' ⟶ i₀ := homOfLE (by simpa only [hi₀, hi₀'] using data.i₀_le r r' hrr' hr pq') -def f₂ : i₀ ⟶ i₁ := homOfLE (by simpa only [hi₀, hi₁] using data.le₀₁ r hr pq') +def f₁ : i₀' ⟶ i₀ := homOfLE (by simpa only [hi₀, hi₀'] using data.i₀_le r r' pq') +def f₂ : i₀ ⟶ i₁ := homOfLE (by simpa only [hi₀, hi₁] using data.le₀₁ r pq') def f₃ : i₁ ⟶ i₂ := homOfLE (by simpa only [hi₁, hi₂] using data.le₁₂ pq') -def f₄ : i₂ ⟶ i₃ := homOfLE (by simpa only [hi₂, hi₃] using data.le₂₃ r hr pq') -def f₅ : i₃ ⟶ i₃' := homOfLE (by simpa only [hi₃, hi₃'] using data.i₃_le r r' hrr' hr pq') +def f₄ : i₂ ⟶ i₃ := homOfLE (by simpa only [hi₂, hi₃] using data.le₂₃ r pq') +def f₅ : i₃ ⟶ i₃' := homOfLE (by simpa only [hi₃, hi₃'] using data.i₃_le r r' pq') section variable {r r'} {i₀' i₀ i₁ i₂ i₃ i₃'} include hi₀ hi₀' in -lemma le₀'₀ : i₀' ≤ i₀ := by simpa only [hi₀, hi₀'] using data.i₀_le r r' hrr' hr pq' +lemma le₀'₀ : i₀' ≤ i₀ := by simpa only [hi₀, hi₀'] using data.i₀_le r r' pq' include hi₀ hi₁ in -lemma le₀₁ : i₀ ≤ i₁ := by simpa only [hi₀, hi₁] using data.le₀₁ r hr pq' +lemma le₀₁ : i₀ ≤ i₁ := by simpa only [hi₀, hi₁] using data.le₀₁ r pq' include hi₁ hi₂ in lemma le₁₂ : i₁ ≤ i₂ := by simpa only [hi₁, hi₂] using data.le₁₂ pq' include hi₂ hi₃ in -lemma le₂₃ : i₂ ≤ i₃ := by simpa only [hi₂, hi₃] using data.le₂₃ r hr pq' +lemma le₂₃ : i₂ ≤ i₃ := by simpa only [hi₂, hi₃] using data.le₂₃ r pq' include hi₃ hi₃' in -lemma le₃₃' : i₃ ≤ i₃' := by simpa only [hi₃, hi₃'] using data.i₃_le r r' hrr' hr pq' +lemma le₃₃' : i₃ ≤ i₃' := by simpa only [hi₃, hi₃'] using data.i₃_le r r' pq' end @@ -352,17 +210,17 @@ lemma mk₃fac : lemma kf_w : (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃ (le₀'₀ data hrr' hr pq' hi₀' hi₀) - (le₀₁ data hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃) ≫ - (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).inv) ≫ + (data.le₀₁' r hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃) ≫ + (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).inv) ≫ (page X data r hr).d pq' pq'' = 0 := by by_cases h : (c r).Rel pq' pq'' · dsimp - rw [paged_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl - (homOfLE (by simpa only [hi₀', data.i₀_prev r r' hrr' hr _ _ h] using data.le₀₁ r hr pq'')) + rw [pageD_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl + (homOfLE (by simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) hn₁' - rfl (by rw [hi₀', data.i₀_prev r r' hrr' hr pq' pq'' h]) hi₀ hi₁ hi₂ hi₃, - assoc, Iso.inv_hom_id_assoc] + rfl (by rw [hi₀', data.i₀_prev r r' pq' pq'' h]) hi₀ hi₁ hi₂ hi₃, + Category.assoc, Iso.inv_hom_id_assoc] erw [EMap_fourδ₁Toδ₀_d_assoc, zero_comp] · rw [HomologicalComplex.shape _ _ _ h, comp_zero] @@ -401,27 +259,27 @@ lemma ksSc_exact : (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ by_cases h : (c r).Rel pq' pq'' · refine ShortComplex.exact_of_iso (Iso.symm ?_) (X.dKernelSequence_exact n₀ n₁ n₂ _ hn₁ hn₂ rfl - (homOfLE (show data.i₀ r hr pq'' ≤ i₀' by - simpa only [hi₀', data.i₀_prev r r' hrr' hr _ _ h] using data.le₀₁ r hr pq'')) + (homOfLE (show data.i₀ r pq'' ≤ i₀' by + simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) _ rfl) refine ShortComplex.isoMk (Iso.refl _) - (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) - (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr _ _ h; lia) _ _ _ _ - rfl (by rw [hi₀', data.i₀_prev r r' hrr' hr _ _ h]) (by rw [hi₀, data.hc₀₂ r hr _ _ h]) - (by rw [hi₁, data.hc₁₃ r hr _ _ h])) ?_ ?_ + (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) + (pageXIso X data _ hr _ _ _ _ _ _ (by have := data.hc r _ _ h; lia) _ _ _ _ + rfl (by rw [hi₀', data.i₀_prev r r' _ _ h]) (by rw [hi₀, data.hc₀₂ r _ _ h]) + (by rw [hi₁, data.hc₁₃ r _ _ h])) ?_ ?_ · dsimp - rw [id_comp, assoc, Iso.inv_hom_id, comp_id] + rw [Category.id_comp, Category.assoc, Iso.inv_hom_id, Category.comp_id] rfl · dsimp - rw [paged_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl - (homOfLE (show data.i₀ r hr pq'' ≤ i₀' by - simpa only [hi₀', data.i₀_prev r r' hrr' hr _ _ h] using data.le₀₁ r hr pq'')) + rw [pageD_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl + (homOfLE (show data.i₀ r pq'' ≤ i₀' by + simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) - (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃), assoc, assoc, - Iso.inv_hom_id, comp_id] + (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃), + Category.assoc, Category.assoc, Iso.inv_hom_id, Category.comp_id] · rfl - · rw [hi₀', data.i₀_prev r r' hrr' hr _ _ h] + · rw [hi₀', data.i₀_prev r r' _ _ h] · rw [ShortComplex.exact_iff_epi]; swap · exact (page X data r hr).shape _ _ h have := isIso_EMapFourδ₁Toδ₀' X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ @@ -437,19 +295,19 @@ noncomputable def hkf : lemma cc_w : (page X data r hr).d pq pq' ≫ - (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).hom ≫ + (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).hom ≫ X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₃' _ _ _ (le₃₃' data hrr' hr pq' hi₃ hi₃') = 0 := by by_cases h : (c r).Rel pq pq' · dsimp - rw [paged_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ + rw [pageD_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') - (homOfLE (by simpa only [hi₃', data.i₃_next r r' hrr' hr _ _ h] using data.le₂₃ r hr pq)) - (by have := data.hc r hr pq pq' h; lia) hi₀ hi₁ (by rw [hi₂, data.hc₀₂ r hr _ _ h]) - (by rw [hi₃, data.hc₁₃ r hr _ _ h]) (by rw [hi₃', data.i₃_next r r' hrr' hr _ _ h]) rfl, - assoc, assoc, Iso.inv_hom_id_assoc] + (homOfLE (by simpa only [hi₃', data.i₃_next r r' _ _ h] using data.le₂₃ r pq)) + (by have := data.hc r pq pq' h; lia) hi₀ hi₁ (by rw [hi₂, data.hc₀₂ r _ _ h]) + (by rw [hi₃, data.hc₁₃ r _ _ h]) (by rw [hi₃', data.i₃_next r r' _ _ h]) rfl, + Category.assoc, Category.assoc, Iso.inv_hom_id_assoc] erw [d_EMap_fourδ₄Toδ₃] rw [comp_zero] · rw [HomologicalComplex.shape _ _ _ h, zero_comp] @@ -494,22 +352,22 @@ lemma ccSc_exact : (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') - (show i₃' ⟶ data.i₃ r hr pq from homOfLE (by - simpa only [hi₃', data.i₃_next r r' hrr' hr _ _ h] using data.le₂₃ r hr pq)) _ rfl) + (show i₃' ⟶ data.i₃ r pq from homOfLE (by + simpa only [hi₃', data.i₃_next r r' _ _ h] using data.le₂₃ r pq)) _ rfl) refine ShortComplex.isoMk - (pageXIso X data _ _ _ _ _ _ _ _ (by have := data.hc r hr _ _ h; lia) _ _ _ _ - (by rw [hi₂, data.hc₀₂ r hr _ _ h]) (by rw [hi₃, data.hc₁₃ r hr _ _ h]) - (by rw [hi₃', data.i₃_next r r' hrr' hr _ _ h]) rfl) - (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) (Iso.refl _) ?_ ?_ + (pageXIso X data _ hr _ _ _ _ _ _ (by have := data.hc r _ _ h; lia) _ _ _ _ + (by rw [hi₂, data.hc₀₂ r _ _ h]) (by rw [hi₃, data.hc₁₃ r _ _ h]) + (by rw [hi₃', data.i₃_next r r' _ _ h]) rfl) + (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) (Iso.refl _) ?_ ?_ · dsimp - rw [paged_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ + rw [pageD_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃'), - assoc, assoc, Iso.inv_hom_id, comp_id] + Category.assoc, Category.assoc, Iso.inv_hom_id, Category.comp_id] · exact hi₀ · exact hi₁ · dsimp - rw [comp_id, Iso.cancel_iso_hom_left] + rw [Category.comp_id, Iso.cancel_iso_hom_left] rfl · rw [ShortComplex.exact_iff_mono]; swap · exact (page X data r hr).shape _ _ h @@ -533,7 +391,7 @@ lemma fac : X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃' (le₀'₀ data hrr' hr pq' hi₀' hi₀) _ _ _ := by dsimp - simpa only [assoc, Iso.inv_hom_id_assoc, EMap_comp] using + simpa only [Category.assoc, Iso.inv_hom_id_assoc, EMap_comp] using congr_arg (X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _) (mk₃fac data r r' hrr' hr pq' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃') @@ -558,7 +416,7 @@ noncomputable def homologyIso' : ((page X data r hr).sc' pq pq' pq'').homology ≅ (page X data r' (by lia)).X pq' := (homologyData X data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.homologyIso ≪≫ - (pageXIso X data _ _ _ _ _ _ _ _ hn₁' _ _ _ _ hi₀' hi₁ hi₂ hi₃').symm + (pageXIso X data _ (by lia) _ _ _ _ _ _ hn₁' _ _ _ _ hi₀' hi₁ hi₂ hi₃').symm noncomputable def homologyIso : (page X data r hr).homology pq' ≅ @@ -580,114 +438,47 @@ noncomputable def spectralSequence : SpectralSequence C c r₀ where page := SpectralSequence.page X data iso r r' pq hrr' hr := SpectralSequence.homologyIso X data r r' hrr' hr pq -@[nolint unusedArguments] -abbrev i₀ (_ : SpectralObject C ι) (data : SpectralSequenceMkData ι c r₀) - (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : ι := - data.i₀ r hr pq - -@[nolint unusedArguments] -abbrev i₃ (_ : SpectralObject C ι) (data : SpectralSequenceMkData ι c r₀) - (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : ι := - data.i₃ r hr pq - -lemma antitone_i₀ (r r' : ℤ) (hrr' : r ≤ r') (hr : r₀ ≤ r) (pq : κ) - {i₀ i₀' : ι} - (hi₀ : i₀ = X.i₀ data r pq) (hi₀' : i₀' = X.i₀ data r' pq) : - i₀' ≤ i₀ := by - rw [hi₀, hi₀'] - apply data.antitone_i₀ - exact hrr' - -lemma monotone_i₃ (r r' : ℤ) (hrr' : r ≤ r') (hr : r₀ ≤ r) (pq : κ) - {i₃ i₃' : ι} - (hi₃ : i₃ = X.i₃ data r pq) (hi₃' : i₃' = X.i₃ data r' pq) : - i₃ ≤ i₃' := by - rw [hi₃, hi₃'] - apply data.monotone_i₃ - exact hrr' - -lemma le₀'₀ {r r' : ℤ} (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq' : κ) - {i₀' i₀ : ι} - (hi₀' : i₀' = X.i₀ data r' pq') - (hi₀ : i₀ = X.i₀ data r pq') : - i₀' ≤ i₀ := by - rw [hi₀', hi₀] - apply data.antitone_i₀ - lia - -lemma le₀₁ (r : ℤ) (hr : r₀ ≤ r) (pq' : κ) - {i₀ i₁ : ι} - (hi₀ : i₀ = X.i₀ data r pq') - (hi₁ : i₁ = data.i₁ pq') : - i₀ ≤ i₁ := by - simpa only [hi₀, hi₁] using data.le₀₁ r _ pq' - -@[nolint unusedArguments] -lemma le₁₂ (_ : SpectralObject C ι) - (data : SpectralSequenceMkData ι c r₀) - (pq' : κ) {i₁ i₂ : ι} (hi₁ : i₁ = data.i₁ pq') (hi₂ : i₂ = data.i₂ pq') : - i₁ ≤ i₂ := by - simpa only [hi₁, hi₂] using data.le₁₂ pq' - -lemma le₂₃ (r : ℤ) (hr : r₀ ≤ r) (pq' : κ) - {i₂ i₃ : ι} - (hi₂ : i₂ = data.i₂ pq') - (hi₃ : i₃ = X.i₃ data r pq') : - i₂ ≤ i₃ := by - simpa only [hi₂, hi₃] using data.le₂₃ r _ pq' - -/-- le₃₃' -/ -lemma le₃₃' {r r' : ℤ} (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq' : κ) - {i₃ i₃' : ι} - (hi₃ : i₃ = X.i₃ data r pq') - (hi₃' : i₃' = X.i₃ data r' pq') : - i₃ ≤ i₃' := by - rw [hi₃, hi₃'] - apply data.monotone_i₃ - lia - variable [X.HasSpectralSequence data] noncomputable def spectralSequencePageXIso (r : ℤ) (hr : r₀ ≤ r) (pq : κ) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) - (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = X.i₀ data r pq) + (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = data.i₀ r pq) (h₁ : i₁ = data.i₁ pq) (h₂ : i₂ = data.i₂ pq) - (h₃ : i₃ = X.i₃ data r pq) : + (h₃ : i₃ = data.i₃ r pq) : ((X.spectralSequence data).page r).X pq ≅ X.E n₀ n₁ n₂ hn₁ hn₂ - (homOfLE (X.le₀₁ data r hr pq h₀ h₁)) - (homOfLE (X.le₁₂ data pq h₁ h₂)) - (homOfLE (X.le₂₃ data r hr pq h₂ h₃)) := - SpectralSequence.pageXIso X data _ _ _ _ _ _ _ _ h _ _ _ _ h₀ h₁ h₂ h₃ + (homOfLE (data.le₀₁' r hr pq h₀ h₁)) + (homOfLE (data.le₁₂' pq h₁ h₂)) + (homOfLE (data.le₂₃' r hr pq h₂ h₃)) := + SpectralSequence.pageXIso X data _ hr _ _ _ _ _ _ h _ _ _ _ h₀ h₁ h₂ h₃ lemma spectralSequence_page_d_eq (r : ℤ) (hr : r₀ ≤ r) (pq pq' : κ) (hpq : (c r).Rel pq pq') (n₀ n₁ n₂ n₃ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) {i₀ i₁ i₂ i₃ i₄ i₅ : ι} (f₁ : i₀ ⟶ i₁) (f₂ : i₁ ⟶ i₂) (f₃ : i₂ ⟶ i₃) (f₄ : i₃ ⟶ i₄) (f₅ : i₄ ⟶ i₅) (hn₁' : n₁ = data.deg pq) - (h₀ : i₀ = X.i₀ data r pq') (h₁ : i₁ = data.i₁ pq') - (h₂ : i₂ = X.i₀ data r pq) - (h₃ : i₃ = data.i₁ pq) (h₄ : i₄ = data.i₂ pq) (h₅ : i₅ = X.i₃ data r pq) : + (h₀ : i₀ = data.i₀ r pq') (h₁ : i₁ = data.i₁ pq') + (h₂ : i₂ = data.i₀ r pq) + (h₃ : i₃ = data.i₁ pq) (h₄ : i₄ = data.i₂ pq) (h₅ : i₅ = data.i₃ r pq) : ((X.spectralSequence data).page r).d pq pq' = (X.spectralSequencePageXIso data r hr _ _ _ _ _ _ hn₁' _ _ _ _ h₂ h₃ h₄ h₅).hom ≫ X.d n₀ n₁ n₂ n₃ hn₁ hn₂ hn₃ f₁ f₂ f₃ f₄ f₅ ≫ (X.spectralSequencePageXIso data r hr _ _ _ _ _ _ - (by simpa only [← hn₂, hn₁'] using data.hc r hr pq pq' hpq) _ _ _ _ h₀ h₁ - (by rw [h₂, ← data.hc₀₂ r _ pq pq' hpq]) - (by rw [h₃, data.hc₁₃ r _ pq pq' hpq])).inv := by - apply SpectralSequence.paged_eq - exact hpq + (by simpa only [← hn₂, hn₁'] using data.hc r pq pq' hpq) _ _ _ _ h₀ h₁ + (by rw [h₂, ← data.hc₀₂ r pq pq' hpq]) + (by rw [h₃, data.hc₁₃ r pq pq' hpq])).inv := + SpectralSequence.pageD_eq _ _ _ hr _ _ hpq .. lemma isZero_spectralSequence_page_X_iff (r : ℤ) (hr : r₀ ≤ r) (pq : κ) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) - (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = X.i₀ data r pq) + (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = data.i₀ r pq) (h₁ : i₁ = data.i₁ pq) (h₂ : i₂ = data.i₂ pq) - (h₃ : i₃ = X.i₃ data r pq) : + (h₃ : i₃ = data.i₃ r pq) : IsZero (((X.spectralSequence data).page r).X pq) ↔ IsZero (X.E n₀ n₁ n₂ hn₁ hn₂ - (homOfLE (X.le₀₁ data r hr pq h₀ h₁)) - (homOfLE (X.le₁₂ data pq h₁ h₂)) - (homOfLE (X.le₂₃ data r hr pq h₂ h₃))) := + (homOfLE (data.le₀₁' r hr pq h₀ h₁)) + (homOfLE (data.le₁₂' pq h₁ h₂)) + (homOfLE (data.le₂₃' r hr pq h₂ h₃))) := Iso.isZero_iff (X.spectralSequencePageXIso data r hr pq n₀ n₁ n₂ hn₁ hn₂ h i₀ i₁ i₂ i₃ h₀ h₁ h₂ h₃) @@ -715,12 +506,12 @@ variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₁' : n₁ = data.deg pq') (i₀' i₀ i₁ i₂ i₃ i₃' : ι) - (hi₀' : i₀' = X.i₀ data r' pq') - (hi₀ : i₀ = X.i₀ data r pq') + (hi₀' : i₀' = data.i₀ r' pq') + (hi₀ : i₀ = data.i₀ r pq') (hi₁ : i₁ = data.i₁ pq') (hi₂ : i₂ = data.i₂ pq') - (hi₃ : i₃ = X.i₃ data r pq') - (hi₃' : i₃' = X.i₃ data r' pq') + (hi₃ : i₃ = data.i₃ r pq') + (hi₃' : i₃' = data.i₃ r' pq') @[simps! left_K left_H left_π right_Q right_H right_ι iso_hom iso_inv] noncomputable def spectralSequenceHomologyData : @@ -733,7 +524,7 @@ lemma spectralSequenceHomologyData_left_i : (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.i = X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃ - (X.le₀'₀ data hrr' hr pq' hi₀' hi₀) _ _ _ ≫ + (data.le₀'₀ hrr' hr pq' hi₀' hi₀) _ _ _ ≫ (X.spectralSequencePageXIso data r hr pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ hi₀ hi₁ hi₂ hi₃).inv := rfl @@ -744,7 +535,7 @@ lemma spectralSequenceHomologyData_right_p : (X.spectralSequencePageXIso data r hr pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ hi₀ hi₁ hi₂ hi₃).hom ≫ X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₃' _ _ _ - (X.le₃₃' data hrr' hr pq' hi₃ hi₃') := rfl + (data.le₃₃' hrr' hr pq' hi₃ hi₃') := rfl lemma spectralSequenceHomologyData_right_homologyIso_eq_left_homologyIso : (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' @@ -752,9 +543,7 @@ lemma spectralSequenceHomologyData_right_homologyIso_eq_left_homologyIso : (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.homologyIso := by ext1 - rw [ShortComplex.HomologyData.right_homologyIso_eq_left_homologyIso_trans_iso] - dsimp - rw [comp_id] + simp [ShortComplex.HomologyData.right_homologyIso_eq_left_homologyIso_trans_iso] end From 31dff02827875c4f98f697d81cff424dfbc3631b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 15 Jan 2026 11:50:24 +0100 Subject: [PATCH 33/72] wip --- .../SpectralObject/HasSpectralSequence.lean | 46 +++--- .../SpectralObject/SpectralSequence.lean | 141 +++++++----------- 2 files changed, 75 insertions(+), 112 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index ec03bbe83c88d9..dfa7518b1249a5 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -91,10 +91,12 @@ structure SpectralSequenceMkData where i₀ r' pq ≤ i₀ r pq monotone_i₃ (r r' : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) (hrr' : r ≤ r' := by lia) : i₃ r pq ≤ i₃ r' pq - i₀_prev' (r : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hr : r₀ ≤ r := by lia) : - i₀ (r + 1) pq = i₁ pq' - i₃_next' (r : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hr : r₀ ≤ r := by lia): - i₃ (r + 1) pq' = i₂ pq + i₀_prev (r r' : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hrr' : r + 1 = r' := by lia) + (hr : r₀ ≤ r := by lia) : + i₀ r' pq = i₁ pq' + i₃_next (r r' : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') (hrr' : r + 1 = r' := by lia) + (hr : r₀ ≤ r := by lia) : + i₃ r' pq' = i₂ pq namespace SpectralSequenceMkData @@ -108,22 +110,8 @@ lemma i₃_le (r r' : ℤ) (pq : κ) (hrr' : r + 1 = r' := by lia) (hr : r₀ data.i₃ r pq ≤ data.i₃ r' pq := data.monotone_i₃ r r' pq -lemma i₀_prev (r r' : ℤ) (pq pq' : κ) (hpq : (c r).Rel pq pq') - (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : - data.i₀ r' pq = data.i₁ pq' := by - subst hrr' - exact data.i₀_prev' r pq pq' hpq - -lemma i₃_next (r r' : ℤ) (pq pq' : κ) - (hpq : (c r).Rel pq pq') (hrr' : r + 1 = r' := by lia) (hr : r₀ ≤ r := by lia) : - data.i₃ r' pq' = data.i₂ pq := by - subst hrr' - exact data.i₃_next' r pq pq' hpq - lemma le₀'₀ {r r' : ℤ} (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq' : κ) - {i₀' i₀ : ι} - (hi₀' : i₀' = data.i₀ r' pq') - (hi₀ : i₀ = data.i₀ r pq') : + {i₀' i₀ : ι} (hi₀' : i₀' = data.i₀ r' pq') (hi₀ : i₀ = data.i₀ r pq') : i₀' ≤ i₀ := by rw [hi₀', hi₀] exact data.antitone_i₀ r r' pq' @@ -173,8 +161,8 @@ def mkDataE₂Cohomological : hc₁₃ := by rintro r pq hr rfl _; simp; lia antitone_i₀ r r' pq hr hrr' := by simp; lia monotone_i₃ r r' pq hr hrr' := by simp; lia - i₀_prev' := by rintro r hr pq rfl _; dsimp; lia - i₃_next' := by rintro r hr pq rfl _; dsimp; lia + i₀_prev := by rintro r r' hr pq rfl _ _; dsimp; lia + i₃_next := by rintro r r' hr pq rfl _ _; dsimp; lia /-- The data which allows to construct an `E₂`-cohomological spectral sequence indexed by `ℕ × ℕ` from a spectral object indexed by `EInt`. (Note: additional @@ -200,10 +188,10 @@ def mkDataE₂CohomologicalNat : lia antitone_i₀ r r' pq hr hrr' := by simp; lia monotone_i₃ r r' pq hr hrr' := by simp; lia - i₀_prev' r pq pq' hpq hr := by + i₀_prev r r' pq pq' hpq hrr' hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - i₃_next' r pq pq' hpq hr := by + i₃_next r r' pq pq' hpq hrr' hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia @@ -250,13 +238,13 @@ def mkDataE₂CohomologicalFin (l : ℕ) : rw [Fin.mk_le_mk] apply Fin.clamp_le_clamp lia - i₀_prev' := by - rintro r ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ hr + i₀_prev := by + rintro r r' ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ hrr' hr ext dsimp at h₁ h₂ ⊢ lia - i₃_next' := by - rintro r ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ hr + i₃_next := by + rintro r r' ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ hrr' hr ext dsimp at h₁ h₂ ⊢ grind @@ -287,10 +275,10 @@ def mkDataE₂HomologicalNat : lia antitone_i₀ r r' pq hr hrr' := by simp; lia monotone_i₃ r r' pq hr hrr' := by simp; lia - i₀_prev' r pq pq' hpq hr := by + i₀_prev r r' pq pq' hpq hrr' hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - i₃_next' r pq pq' hpq hr := by + i₃_next r r' pq pq' hpq hrr' hr := by simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index a60557e9e376ff..2016aa02177539 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -34,31 +34,35 @@ variable (data : SpectralSequenceMkData ι c r₀) namespace SpectralSequence +/-- The object on position `pq` on the `r`th page of the spectral sequence. -/ noncomputable def pageX (r : ℤ) (pq : κ) (hr : r₀ ≤ r := by lia) : C := X.E (data.deg pq - 1) (data.deg pq) (data.deg pq + 1) (by simp) rfl (homOfLE (data.le₀₁ r pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r pq)) +/-- The object on position `pq` on the `r`th page of the spectral sequence identifies +to `E^{deg pq}(i₀ ≤ i₁ ≤ i₂ ≤ i₃)`. -/ noncomputable def pageXIso (r : ℤ) (hr : r₀ ≤ r) (pq : κ) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = data.i₀ r pq) (h₁ : i₁ = data.i₁ pq) (h₂ : i₂ = data.i₂ pq) (h₃ : i₃ = data.i₃ r pq) : pageX X data r pq hr ≅ X.E n₀ n₁ n₂ hn₁ hn₂ - (homOfLE (by subst h₀ h₁; exact data.le₀₁ r pq) : i₀ ⟶ i₁) - (homOfLE (by subst h₁ h₂; exact data.le₁₂ pq) : i₁ ⟶ i₂) - (homOfLE (by subst h₂ h₃; exact data.le₂₃ r pq) : i₂ ⟶ i₃) := + (homOfLE (data.le₀₁' r hr pq h₀ h₁)) + (homOfLE (data.le₁₂' pq h₁ h₂)) + (homOfLE (data.le₂₃' r hr pq h₂ h₃)) := eqToIso (by obtain rfl : n₀ = n₁ - 1 := by lia subst h hn₂ h₀ h₁ h₂ h₃ rfl) open Classical in +/-- The differential on the `r`th page of the spectral sequence. -/ noncomputable def pageD (r : ℤ) (pq pq' : κ) (hr : r₀ ≤ r := by lia) : pageX X data r pq hr ⟶ pageX X data r pq' hr := if hpq : (c r).Rel pq pq' then X.d (data.deg pq - 1) (data.deg pq) (data.deg pq + 1) (data.deg pq + 2) _ rfl (by lia) (homOfLE (data.le₀₁ r pq')) - (homOfLE (by simpa only [data.hc₀₂ r pq pq' hpq] using data.le₁₂ pq')) + (homOfLE (data.le₁₂' pq' rfl (data.hc₀₂ r pq pq' hpq))) (homOfLE (data.le₀₁ r pq)) (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r pq)) ≫ (pageXIso _ _ _ _ _ _ _ _ _ _ (data.hc r pq pq' hpq) _ _ _ _ rfl rfl (data.hc₀₂ r pq pq' hpq) (data.hc₁₃ r pq pq' hpq)).inv @@ -90,19 +94,12 @@ lemma pageD_pageD (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) : pageD X data r pq pq' hr ≫ pageD X data r pq' pq'' hr = 0 := by by_cases hpq : (c r).Rel pq pq' · by_cases hpq' : (c r).Rel pq' pq'' - · let f₁ := homOfLE (data.le₀₁ r pq'') - let f₂ := homOfLE (data.le₁₂ pq'') - let f₃ := homOfLE (data.le₂₃ r pq'') - let f₄ : data.i₃ r pq'' ⟶ data.i₀ r pq := homOfLE (by - simpa only [← data.hc₁₃ r pq' pq'' hpq', - data.hc₀₂ r pq pq' hpq] using data.le₁₂ pq') - let f₅ := homOfLE (data.le₀₁ r pq) - let f₆ := homOfLE (data.le₁₂ pq) - let f₇ := homOfLE (data.le₂₃ r pq) - rw [pageD_eq X data r hr pq pq' hpq (data.deg pq - 1) (data.deg pq) _ _ (by simp) - rfl rfl f₃ f₄ f₅ f₆ f₇ rfl (data.hc₀₂ r pq' pq'' hpq').symm + · rw [pageD_eq X data r hr pq pq' hpq (data.deg pq - 1) (data.deg pq) _ _ (by simp) + rfl rfl (data.le₂₃ r pq'').hom (data.le₁₂' pq' (data.hc₁₃ r pq' pq'' hpq').symm + (data.hc₀₂ r pq pq' hpq)).hom (data.le₀₁ r pq).hom (data.le₁₂ pq).hom + (data.le₂₃ r pq).hom rfl (data.hc₀₂ r pq' pq'' hpq').symm (data.hc₁₃ r pq' pq'' hpq').symm rfl rfl rfl rfl, - pageD_eq X data r hr pq' pq'' hpq' (data.deg pq) _ _ _ rfl rfl rfl f₁ f₂ f₃ f₄ f₅ + pageD_eq X data r hr pq' pq'' hpq' (data.deg pq) _ _ _ rfl rfl rfl _ _ _ _ _ (data.hc r pq pq' hpq) rfl rfl (data.hc₀₂ r pq' pq'' hpq').symm (data.hc₁₃ r pq' pq'' hpq').symm (data.hc₀₂ r pq pq' hpq) (data.hc₁₃ r pq pq' hpq), Category.assoc, Category.assoc, Iso.inv_hom_id_assoc, @@ -112,6 +109,7 @@ lemma pageD_pageD (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) : · dsimp only [pageD] rw [dif_neg hpq, zero_comp] +/-- The `r`th page of the spectral sequence. -/ @[simps] noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : HomologicalComplex C (c r) where @@ -121,6 +119,8 @@ noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : section +/-- The short complexe of the `r`th page of the spectral sequence on position `pq'` +identifies to the short complex given by the differentials of the spectral object. -/ noncomputable def shortComplexIso (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) (hpq : (c r).Rel pq pq') (hpq' : (c r).Rel pq' pq'') (n₀ n₁ n₂ n₃ n₄ : ℤ) @@ -167,58 +167,24 @@ variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) namespace HomologyData -def f₁ : i₀' ⟶ i₀ := homOfLE (by simpa only [hi₀, hi₀'] using data.i₀_le r r' pq') -def f₂ : i₀ ⟶ i₁ := homOfLE (by simpa only [hi₀, hi₁] using data.le₀₁ r pq') -def f₃ : i₁ ⟶ i₂ := homOfLE (by simpa only [hi₁, hi₂] using data.le₁₂ pq') -def f₄ : i₂ ⟶ i₃ := homOfLE (by simpa only [hi₂, hi₃] using data.le₂₃ r pq') -def f₅ : i₃ ⟶ i₃' := homOfLE (by simpa only [hi₃, hi₃'] using data.i₃_le r r' pq') - -section - -variable {r r'} {i₀' i₀ i₁ i₂ i₃ i₃'} - -include hi₀ hi₀' in -lemma le₀'₀ : i₀' ≤ i₀ := by simpa only [hi₀, hi₀'] using data.i₀_le r r' pq' -include hi₀ hi₁ in -lemma le₀₁ : i₀ ≤ i₁ := by simpa only [hi₀, hi₁] using data.le₀₁ r pq' -include hi₁ hi₂ in -lemma le₁₂ : i₁ ≤ i₂ := by simpa only [hi₁, hi₂] using data.le₁₂ pq' -include hi₂ hi₃ in -lemma le₂₃ : i₂ ≤ i₃ := by simpa only [hi₂, hi₃] using data.le₂₃ r pq' -include hi₃ hi₃' in -lemma le₃₃' : i₃ ≤ i₃' := by simpa only [hi₃, hi₃'] using data.i₃_le r r' pq' - -end - -noncomputable def mk₃π := - fourδ₄Toδ₃ (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀ ≫ f₂ data r hr pq' i₀ i₁ hi₀ hi₁) - (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) - (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') _ rfl - -instance : Epi (X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _ - (mk₃π data r r' hrr' hr pq' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃')) := by - dsimp only [mk₃π] - infer_instance - lemma mk₃fac : - fourδ₁Toδ₀' i₀' i₀ i₁ i₂ i₃ (le₀'₀ data hrr' hr pq' hi₀' hi₀) - (le₀₁ data hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃) ≫ - fourδ₄Toδ₃' i₀ i₁ i₂ i₃ i₃' _ _ _ (le₃₃' data hrr' hr pq' hi₃ hi₃') = - fourδ₄Toδ₃' i₀' i₁ i₂ i₃ i₃' _ _ _ (le₃₃' data hrr' hr pq' hi₃ hi₃') ≫ - fourδ₁Toδ₀' i₀' i₀ i₁ i₂ i₃' (le₀'₀ data hrr' hr pq' hi₀' hi₀) _ _ _ := by + fourδ₁Toδ₀' i₀' i₀ i₁ i₂ i₃ (data.le₀'₀ hrr' hr pq' hi₀' hi₀) + (data.le₀₁' r hr pq' hi₀ hi₁) (data.le₁₂' pq' hi₁ hi₂) (data.le₂₃' r hr pq' hi₂ hi₃) ≫ + fourδ₄Toδ₃' i₀ i₁ i₂ i₃ i₃' _ _ _ (data.le₃₃' hrr' hr pq' hi₃ hi₃') = + fourδ₄Toδ₃' i₀' i₁ i₂ i₃ i₃' _ _ _ (data.le₃₃' hrr' hr pq' hi₃ hi₃') ≫ + fourδ₁Toδ₀' i₀' i₀ i₁ i₂ i₃' (data.le₀'₀ hrr' hr pq' hi₀' hi₀) _ _ _ := by rfl lemma kf_w : - (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃ (le₀'₀ data hrr' hr pq' hi₀' hi₀) - (data.le₀₁' r hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃) ≫ + (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃ (data.le₀'₀ hrr' hr pq' hi₀' hi₀) + (data.le₀₁' r hr pq' hi₀ hi₁) (data.le₁₂' pq' hi₁ hi₂) (data.le₂₃' r hr pq' hi₂ hi₃) ≫ (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).inv) ≫ (page X data r hr).d pq' pq'' = 0 := by by_cases h : (c r).Rel pq' pq'' · dsimp rw [pageD_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl (homOfLE (by simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) - (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) - (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) hn₁' + (data.le₀'₀ hrr' hr pq' hi₀' hi₀).hom _ _ _ hn₁' rfl (by rw [hi₀', data.i₀_prev r r' pq' pq'' h]) hi₀ hi₁ hi₂ hi₃, Category.assoc, Iso.inv_hom_id_assoc] erw [EMap_fourδ₁Toδ₀_d_assoc, zero_comp] @@ -243,8 +209,8 @@ variable [X.HasSpectralSequence data] in include hpq' hn₁' in lemma isIso_EMapFourδ₁Toδ₀' (h : ¬ (c r).Rel pq' pq'') : IsIso (X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ - i₀' i₀ i₁ i₂ i₃ (le₀'₀ data hrr' hr pq' hi₀' hi₀) (le₀₁ data hr pq' hi₀ hi₁) - (le₁₂ data pq' hi₁ hi₂) (le₂₃ data hr pq' hi₂ hi₃)) := by + i₀' i₀ i₁ i₂ i₃ (data.le₀'₀ hrr' hr pq' hi₀' hi₀) (data.le₀₁' r hr pq' hi₀ hi₁) + (data.le₁₂' pq' hi₁ hi₂) (data.le₂₃' r hr pq' hi₂ hi₃)) := by apply X.isIso_EMap_fourδ₁Toδ₀_of_isZero refine X.isZero_H_obj_mk₁_i₀_le' data r r' hrr' hr pq' (fun k hk ↦ ?_) _ (by lia) _ _ hi₀' hi₀ @@ -261,8 +227,8 @@ lemma ksSc_exact : (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ (X.dKernelSequence_exact n₀ n₁ n₂ _ hn₁ hn₂ rfl (homOfLE (show data.i₀ r pq'' ≤ i₀' by simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) - (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) - (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) _ rfl) + (data.le₀'₀ hrr' hr pq' hi₀' hi₀).hom (data.le₀₁' r hr pq' hi₀ hi₁).hom + (data.le₁₂' pq' hi₁ hi₂).hom (data.le₂₃' r hr pq' hi₂ hi₃).hom _ rfl) refine ShortComplex.isoMk (Iso.refl _) (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) (pageXIso X data _ hr _ _ _ _ _ _ (by have := data.hc r _ _ h; lia) _ _ _ _ @@ -270,13 +236,10 @@ lemma ksSc_exact : (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ (by rw [hi₁, data.hc₁₃ r _ _ h])) ?_ ?_ · dsimp rw [Category.id_comp, Category.assoc, Iso.inv_hom_id, Category.comp_id] - rfl · dsimp rw [pageD_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl (homOfLE (show data.i₀ r pq'' ≤ i₀' by - simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) - (f₁ data r r' hrr' hr pq' i₀' i₀ hi₀' hi₀) (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) - (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃), + simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')), Category.assoc, Category.assoc, Iso.inv_hom_id, Category.comp_id] · rfl · rw [hi₀', data.i₀_prev r r' _ _ h] @@ -297,13 +260,11 @@ lemma cc_w : (page X data r hr).d pq pq' ≫ (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃).hom ≫ X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₃' _ _ _ - (le₃₃' data hrr' hr pq' hi₃ hi₃') = 0 := by + (data.le₃₃' hrr' hr pq' hi₃ hi₃') = 0 := by by_cases h : (c r).Rel pq pq' · dsimp - rw [pageD_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ - (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) - (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) - (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') + rw [pageD_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ _ + _ (data.le₂₃' r hr pq' hi₂ hi₃).hom (data.le₃₃' hrr' hr pq' hi₃ hi₃').hom (homOfLE (by simpa only [hi₃', data.i₃_next r r' _ _ h] using data.le₂₃ r pq)) (by have := data.hc r pq pq' h; lia) hi₀ hi₁ (by rw [hi₂, data.hc₀₂ r _ _ h]) (by rw [hi₃, data.hc₁₃ r _ _ h]) (by rw [hi₃', data.i₃_next r r' _ _ h]) rfl, @@ -332,8 +293,8 @@ variable [X.HasSpectralSequence data] in include hpq hn₁' in lemma isIso_EMapFourδ₄Toδ₃' (h : ¬ (c r).Rel pq pq') : IsIso (X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₃' - (le₀₁ data hr pq' hi₀ hi₁) (le₁₂ data pq' hi₁ hi₂) - (le₂₃ data hr pq' hi₂ hi₃) (le₃₃' data hrr' hr pq' hi₃ hi₃')) := by + (data.le₀₁' r hr pq' hi₀ hi₁) (data.le₁₂' pq' hi₁ hi₂) + (data.le₂₃' r hr pq' hi₂ hi₃) (data.le₃₃' hrr' hr pq' hi₃ hi₃')) := by apply X.isIso_EMap_fourδ₄Toδ₃_of_isZero refine X.isZero_H_obj_mk₁_i₃_le' data r r' hrr' hr pq' ?_ _ (by lia) _ _ hi₃ hi₃' intro k hk @@ -349,9 +310,9 @@ lemma ccSc_exact : by_cases h : (c r).Rel pq pq' · refine ShortComplex.exact_of_iso (Iso.symm ?_) (X.dCokernelSequence_exact (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ - (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) - (f₃ data pq' i₁ i₂ hi₁ hi₂) (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) - (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃') + (data.le₀₁' r hr pq' hi₀ hi₁).hom + (data.le₁₂' pq' hi₁ hi₂).hom (data.le₂₃' r hr pq' hi₂ hi₃).hom + (data.le₃₃' hrr' hr pq' hi₃ hi₃').hom (show i₃' ⟶ data.i₃ r pq from homOfLE (by simpa only [hi₃', data.i₃_next r r' _ _ h] using data.le₂₃ r pq)) _ rfl) refine ShortComplex.isoMk @@ -360,15 +321,12 @@ lemma ccSc_exact : (by rw [hi₃', data.i₃_next r r' _ _ h]) rfl) (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) (Iso.refl _) ?_ ?_ · dsimp - rw [pageD_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ - (f₂ data r hr pq' i₀ i₁ hi₀ hi₁) (f₃ data pq' i₁ i₂ hi₁ hi₂) - (f₄ data r hr pq' i₂ i₃ hi₂ hi₃) (f₅ data r r' hrr' hr pq' i₃ i₃' hi₃ hi₃'), + rw [pageD_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂, Category.assoc, Category.assoc, Iso.inv_hom_id, Category.comp_id] · exact hi₀ · exact hi₁ · dsimp rw [Category.comp_id, Iso.cancel_iso_hom_left] - rfl · rw [ShortComplex.exact_iff_mono]; swap · exact (page X data r hr).shape _ _ h have := isIso_EMapFourδ₄Toδ₃' X data r r' hrr' hr pq pq' hpq n₀ n₁ n₂ hn₁ hn₂ hn₁' @@ -387,9 +345,9 @@ lemma fac : (kf X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).ι ≫ (cc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').π = - X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀' i₁ i₂ i₃ i₃' _ _ _ (le₃₃' data hrr' hr pq' hi₃ hi₃') ≫ + X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀' i₁ i₂ i₃ i₃' _ _ _ (data.le₃₃' hrr' hr pq' hi₃ hi₃') ≫ X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃' - (le₀'₀ data hrr' hr pq' hi₀' hi₀) _ _ _ := by + (data.le₀'₀ hrr' hr pq' hi₀' hi₀) _ _ _ := by dsimp simpa only [Category.assoc, Iso.inv_hom_id_assoc, EMap_comp] using congr_arg (X.EMap n₀ n₁ n₂ hn₁ hn₂ _ _ _ _ _ _) @@ -400,6 +358,9 @@ end HomologyData variable [X.HasSpectralSequence data] open HomologyData in +/-- The homology data for the short complex given by differentials on the +`r`th page of the spectral sequence which shows that the homology identifies +to an object on the next page. -/ @[simps!] noncomputable def homologyData : ((page X data r hr).sc' pq pq' pq'').HomologyData := ShortComplex.HomologyData.ofEpiMonoFactorisation @@ -411,13 +372,16 @@ noncomputable def homologyData : ((page X data r hr).sc' pq pq' pq'').HomologyDa (fac X data r r' hrr' hr pq pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃') -/-- homologyIso' -/ +/-- The homology of the differentials on a page of the spectral sequence identifies +to the objects on the next page. -/ noncomputable def homologyIso' : ((page X data r hr).sc' pq pq' pq'').homology ≅ (page X data r' (by lia)).X pq' := (homologyData X data r r' hrr' hr pq pq' pq'' hpq hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.homologyIso ≪≫ (pageXIso X data _ (by lia) _ _ _ _ _ _ hn₁' _ _ _ _ hi₀' hi₁ hi₂ hi₃').symm +/-- The homology of the differentials on a page of the spectral sequence identifies +to the objects on the next page. -/ noncomputable def homologyIso : (page X data r hr).homology pq' ≅ (page X data r' (hr.trans (by rw [← hrr']; exact Int.le.intro 1 rfl))).X pq' := @@ -434,12 +398,15 @@ end SpectralSequence section variable [X.HasSpectralSequence data] in +/-- The spectral sequence attached to a spectral object in an abelian category. -/ noncomputable def spectralSequence : SpectralSequence C c r₀ where page := SpectralSequence.page X data iso r r' pq hrr' hr := SpectralSequence.homologyIso X data r r' hrr' hr pq variable [X.HasSpectralSequence data] +/-- The objects on the pages of a spectral sequence attached to a spectral object `X` +identifies an object `X.E`. -/ noncomputable def spectralSequencePageXIso (r : ℤ) (hr : r₀ ≤ r) (pq : κ) (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (h : n₁ = data.deg pq) (i₀ i₁ i₂ i₃ : ι) (h₀ : i₀ = data.i₀ r pq) @@ -513,6 +480,8 @@ variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (hi₃ : i₃ = data.i₃ r pq') (hi₃' : i₃' = data.i₃ r' pq') +/-- The homology data for the short complexes given by the differentials +of a spectral sequence attached to a spectral object in an abelian category. -/ @[simps! left_K left_H left_π right_Q right_H right_ι iso_hom iso_inv] noncomputable def spectralSequenceHomologyData : (((X.spectralSequence data).page r hr).sc' pq pq' pq'').HomologyData := @@ -553,6 +522,8 @@ section variable (Y : SpectralObject C EInt) +/-- The `E₂` cohomologial spectral sequence indexed by `ℤ × ℤ` attached to +a first quadrant spectral object indexed by `EInt`. -/ noncomputable abbrev E₂SpectralSequence : E₂CohomologicalSpectralSequence C := Y.spectralSequence mkDataE₂Cohomological @@ -574,6 +545,8 @@ example (r : ℤ) (hr : 2 ≤ r) (p q : ℤ) (hp : p < 0) : simp lia +/-- The `E₂` cohomologial spectral sequence indexed by `ℕ × ℕ` attached to +a first quadrant spectral object indexed by `EInt`. -/ noncomputable abbrev E₂SpectralSequenceNat := Y.spectralSequence mkDataE₂CohomologicalNat end @@ -596,6 +569,8 @@ example (r : ℤ) (hr : 2 ≤ r) (p q : ℤ) (hp : 0 < p) : simp lia +/-- The `E₂` homologial spectral sequence indexed by `ℕ × ℕ` attached to +a third quadrant spectral object indexed by `EInt`. -/ noncomputable abbrev E₂HomologicalSpectralSequenceNat := Y.spectralSequence mkDataE₂HomologicalNat end From 3d14ea14962608b0199eac684b9a14e7de7448f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 15 Jan 2026 11:56:56 +0100 Subject: [PATCH 34/72] wip --- .../SpectralObject/SpectralSequence.lean | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index 2016aa02177539..37bc9b364761bb 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -95,9 +95,10 @@ lemma pageD_pageD (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) : by_cases hpq : (c r).Rel pq pq' · by_cases hpq' : (c r).Rel pq' pq'' · rw [pageD_eq X data r hr pq pq' hpq (data.deg pq - 1) (data.deg pq) _ _ (by simp) - rfl rfl (data.le₂₃ r pq'').hom (data.le₁₂' pq' (data.hc₁₃ r pq' pq'' hpq').symm - (data.hc₀₂ r pq pq' hpq)).hom (data.le₀₁ r pq).hom (data.le₁₂ pq).hom - (data.le₂₃ r pq).hom rfl (data.hc₀₂ r pq' pq'' hpq').symm + rfl rfl (homOfLE (data.le₂₃ r pq'')) + (homOfLE (data.le₁₂' pq' (data.hc₁₃ r pq' pq'' hpq').symm + (data.hc₀₂ r pq pq' hpq))) (homOfLE (data.le₀₁ r pq)) (homOfLE (data.le₁₂ pq)) + (homOfLE (data.le₂₃ r pq)) rfl (data.hc₀₂ r pq' pq'' hpq').symm (data.hc₁₃ r pq' pq'' hpq').symm rfl rfl rfl rfl, pageD_eq X data r hr pq' pq'' hpq' (data.deg pq) _ _ _ rfl rfl rfl _ _ _ _ _ (data.hc r pq pq' hpq) rfl rfl (data.hc₀₂ r pq' pq'' hpq').symm @@ -184,7 +185,7 @@ lemma kf_w : · dsimp rw [pageD_eq X data r hr pq' pq'' h n₀ n₁ n₂ _ hn₁ hn₂ rfl (homOfLE (by simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) - (data.le₀'₀ hrr' hr pq' hi₀' hi₀).hom _ _ _ hn₁' + (homOfLE (data.le₀'₀ hrr' hr pq' hi₀' hi₀)) _ _ _ hn₁' rfl (by rw [hi₀', data.i₀_prev r r' pq' pq'' h]) hi₀ hi₁ hi₂ hi₃, Category.assoc, Iso.inv_hom_id_assoc] erw [EMap_fourδ₁Toδ₀_d_assoc, zero_comp] @@ -227,8 +228,8 @@ lemma ksSc_exact : (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ (X.dKernelSequence_exact n₀ n₁ n₂ _ hn₁ hn₂ rfl (homOfLE (show data.i₀ r pq'' ≤ i₀' by simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) - (data.le₀'₀ hrr' hr pq' hi₀' hi₀).hom (data.le₀₁' r hr pq' hi₀ hi₁).hom - (data.le₁₂' pq' hi₁ hi₂).hom (data.le₂₃' r hr pq' hi₂ hi₃).hom _ rfl) + (homOfLE (data.le₀'₀ hrr' hr pq' hi₀' hi₀)) (homOfLE (data.le₀₁' r hr pq' hi₀ hi₁)) + (homOfLE (data.le₁₂' pq' hi₁ hi₂)) (homOfLE (data.le₂₃' r hr pq' hi₂ hi₃)) _ rfl) refine ShortComplex.isoMk (Iso.refl _) (pageXIso X data _ hr _ _ _ _ _ _ hn₁' _ _ _ _ hi₀ hi₁ hi₂ hi₃) (pageXIso X data _ hr _ _ _ _ _ _ (by have := data.hc r _ _ h; lia) _ _ _ _ @@ -264,7 +265,7 @@ lemma cc_w : by_cases h : (c r).Rel pq pq' · dsimp rw [pageD_eq X data r hr pq pq' h (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ _ - _ (data.le₂₃' r hr pq' hi₂ hi₃).hom (data.le₃₃' hrr' hr pq' hi₃ hi₃').hom + _ (homOfLE (data.le₂₃' r hr pq' hi₂ hi₃)) (homOfLE (data.le₃₃' hrr' hr pq' hi₃ hi₃')) (homOfLE (by simpa only [hi₃', data.i₃_next r r' _ _ h] using data.le₂₃ r pq)) (by have := data.hc r pq pq' h; lia) hi₀ hi₁ (by rw [hi₂, data.hc₀₂ r _ _ h]) (by rw [hi₃, data.hc₁₃ r _ _ h]) (by rw [hi₃', data.i₃_next r r' _ _ h]) rfl, @@ -310,9 +311,9 @@ lemma ccSc_exact : by_cases h : (c r).Rel pq pq' · refine ShortComplex.exact_of_iso (Iso.symm ?_) (X.dCokernelSequence_exact (n₀ - 1) n₀ n₁ n₂ (by simp) hn₁ hn₂ - (data.le₀₁' r hr pq' hi₀ hi₁).hom - (data.le₁₂' pq' hi₁ hi₂).hom (data.le₂₃' r hr pq' hi₂ hi₃).hom - (data.le₃₃' hrr' hr pq' hi₃ hi₃').hom + (homOfLE (data.le₀₁' r hr pq' hi₀ hi₁)) + (homOfLE (data.le₁₂' pq' hi₁ hi₂)) (homOfLE (data.le₂₃' r hr pq' hi₂ hi₃)) + (homOfLE (data.le₃₃' hrr' hr pq' hi₃ hi₃')) (show i₃' ⟶ data.i₃ r pq from homOfLE (by simpa only [hi₃', data.i₃_next r r' _ _ h] using data.le₂₃ r pq)) _ rfl) refine ShortComplex.isoMk From 66d5120c61c2a82fe2b897cf254f5680539bb568 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 15 Jan 2026 12:33:25 +0100 Subject: [PATCH 35/72] fix --- .../Limits/Shapes/CombinedProducts.lean | 6 +++--- .../Limits/Shapes/Multiequalizer.lean | 18 +++++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/Mathlib/CategoryTheory/Limits/Shapes/CombinedProducts.lean b/Mathlib/CategoryTheory/Limits/Shapes/CombinedProducts.lean index 642073cfb5a837..e863cbe3b03c93 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/CombinedProducts.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/CombinedProducts.lean @@ -48,10 +48,10 @@ variable {c₁ c₂ bc} points, then the fan constructed from `combPairHoms` is a limit cone. -/ def combPairIsLimit : IsLimit (Fan.mk bc.pt (combPairHoms c₁ c₂ bc)) := mkFanLimit _ - (fun s ↦ Fan.IsLimit.desc h <| fun i ↦ by + (fun s ↦ Fan.IsLimit.lift h <| fun i ↦ by cases i - · exact Fan.IsLimit.desc h₁ (fun a ↦ s.proj (.inl a)) - · exact Fan.IsLimit.desc h₂ (fun a ↦ s.proj (.inr a))) + · exact Fan.IsLimit.lift h₁ (fun a ↦ s.proj (.inl a)) + · exact Fan.IsLimit.lift h₂ (fun a ↦ s.proj (.inr a))) (fun s w ↦ by cases w <;> · simp only [fan_mk_proj, combPairHoms] diff --git a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean index f08b98c059fa7a..db53a5c25c3861 100644 --- a/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean +++ b/Mathlib/CategoryTheory/Limits/Shapes/Multiequalizer.lean @@ -337,11 +337,11 @@ def multicospan : WalkingMulticospan J ⥤ C where /-- The induced map `∏ᶜ I.left ⟶ ∏ᶜ I.right` via `I.fst` for limiting fans. -/ def fstPiMapOfIsLimit (c : Fan I.left) {d : Fan I.right} (hd : IsLimit d) : c.pt ⟶ d.pt := - Fan.IsLimit.desc hd fun i ↦ c.proj _ ≫ I.fst i + Fan.IsLimit.lift hd fun i ↦ c.proj _ ≫ I.fst i /-- The induced map `∏ᶜ I.left ⟶ ∏ᶜ I.right` via `I.snd` for limiting fans. -/ def sndPiMapOfIsLimit (c : Fan I.left) {d : Fan I.right} (hd : IsLimit d) : c.pt ⟶ d.pt := - Fan.IsLimit.desc hd fun i ↦ c.proj _ ≫ I.snd i + Fan.IsLimit.lift hd fun i ↦ c.proj _ ≫ I.snd i @[reassoc (attr := simp)] lemma fstPiMapOfIsLimit_proj (c : Fan I.left) {d : Fan I.right} (hd : IsLimit d) (i) : @@ -615,8 +615,8 @@ variable {c : Fan I.left} (hc : IsLimit c) {d : Fan I.right} (hd : IsLimit d) @[reassoc (attr := simp)] theorem pi_condition : - Fan.IsLimit.desc hc K.ι ≫ I.fstPiMapOfIsLimit c hd = - Fan.IsLimit.desc hc K.ι ≫ I.sndPiMapOfIsLimit c hd := by + Fan.IsLimit.lift hc K.ι ≫ I.fstPiMapOfIsLimit c hd = + Fan.IsLimit.lift hc K.ι ≫ I.sndPiMapOfIsLimit c hd := by apply Fan.IsLimit.hom_ext hd simp @@ -624,17 +624,17 @@ theorem pi_condition : @[simps! pt] def toPiFork (K : Multifork I) : Fork (I.fstPiMapOfIsLimit c hd) (I.sndPiMapOfIsLimit c hd) := - .ofι (Fan.IsLimit.desc hc K.ι) (by simp) + .ofι (Fan.IsLimit.lift hc K.ι) (by simp) @[simp] theorem toPiFork_π_app_zero : - (K.toPiFork hc hd).ι = Fan.IsLimit.desc hc K.ι := + (K.toPiFork hc hd).ι = Fan.IsLimit.lift hc K.ι := rfl @[simp] theorem toPiFork_π_app_one : (K.toPiFork hc hd).π.app WalkingParallelPair.one = - Fan.IsLimit.desc hc K.ι ≫ I.fstPiMapOfIsLimit c hd := + Fan.IsLimit.lift hc K.ι ≫ I.fstPiMapOfIsLimit c hd := rfl variable {hd} in @@ -688,10 +688,6 @@ def toPiForkFunctor : · apply Fan.IsLimit.hom_ext hc simp · apply Fan.IsLimit.hom_ext hd - intro j - simp only [Multifork.toPiFork_π_app_one, Multifork.pi_condition, - Category.assoc] - dsimp [MulticospanIndex.sndPiMapOfIsLimit, Fan.proj, Fan.IsLimit.desc] simp } /-- `Multifork.ofPiFork` as a functor. -/ From 7a3f03bd07d11aa4138369f3451090ce1a6f5f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Thu, 15 Jan 2026 12:39:59 +0100 Subject: [PATCH 36/72] fix --- .../Algebra/Homology/SpectralObject/HasSpectralSequence.lean | 2 +- Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index dfa7518b1249a5..133a00f770bec1 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -157,7 +157,7 @@ def mkDataE₂Cohomological : le₁₂ pq := by simp le₂₃ r pq hr := by simp; lia hc := by rintro r pq _ rfl _; dsimp; lia - hc₀₂ := by rintro r pq hr rfl _ ; simp; lia + hc₀₂ := by rintro r pq hr rfl _; simp; lia hc₁₃ := by rintro r pq hr rfl _; simp; lia antitone_i₀ r r' pq hr hrr' := by simp; lia monotone_i₃ r r' pq hr hrr' := by simp; lia diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean index d9e3f3d27f9940..b24b2eae4df341 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -138,7 +138,7 @@ noncomputable def eTruncGEδLT : | top => exact 0 naturality {a b} hab := by replace hab := leOfHom hab - induction a using WithBotTop.rec ; rotate_right + induction a using WithBotTop.rec; rotate_right · apply (isZero_zero _).eq_of_src all_goals induction b using WithBotTop.rec <;> simp at hab <;> From 64fd131b23ed9825b6c95150b32cf6e0c0ec07a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 16 Jan 2026 17:23:21 +0100 Subject: [PATCH 37/72] trying abbrev for ComposableArrows.mk_2 --- Mathlib/CategoryTheory/ComposableArrows/Basic.lean | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean index 41a389b24f18cd..e9f5c9b5664333 100644 --- a/Mathlib/CategoryTheory/ComposableArrows/Basic.lean +++ b/Mathlib/CategoryTheory/ComposableArrows/Basic.lean @@ -408,24 +408,20 @@ def precomp {X : C} (f : X ⟶ F.left) : ComposableArrows C (n + 1) where map_comp g g' := Precomp.map_comp F f (leOfHom g) (leOfHom g') /-- Constructor for `ComposableArrows C 2`. -/ -@[reducible] -def mk₂ {X₀ X₁ X₂ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) : ComposableArrows C 2 := +abbrev mk₂ {X₀ X₁ X₂ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) : ComposableArrows C 2 := (mk₁ g).precomp f /-- Constructor for `ComposableArrows C 3`. -/ -@[reducible] -def mk₃ {X₀ X₁ X₂ X₃ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) : ComposableArrows C 3 := +abbrev mk₃ {X₀ X₁ X₂ X₃ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) : ComposableArrows C 3 := (mk₂ g h).precomp f /-- Constructor for `ComposableArrows C 4`. -/ -@[reducible] -def mk₄ {X₀ X₁ X₂ X₃ X₄ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) : +abbrev mk₄ {X₀ X₁ X₂ X₃ X₄ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) : ComposableArrows C 4 := (mk₃ g h i).precomp f /-- Constructor for `ComposableArrows C 5`. -/ -@[reducible] -def mk₅ {X₀ X₁ X₂ X₃ X₄ X₅ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) +abbrev mk₅ {X₀ X₁ X₂ X₃ X₄ X₅ : C} (f : X₀ ⟶ X₁) (g : X₁ ⟶ X₂) (h : X₂ ⟶ X₃) (i : X₃ ⟶ X₄) (j : X₄ ⟶ X₅) : ComposableArrows C 5 := (mk₄ g h i j).precomp f From 3ff188ee6796ffcf853f406bcacc54ed5583c5d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 16 Jan 2026 23:53:32 +0100 Subject: [PATCH 38/72] fix --- Mathlib/Algebra/Homology/ShortComplex/Exact.lean | 4 ++-- Mathlib/Algebra/Homology/SpectralObject/Cycles.lean | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean index 38285d78155ea9..8da2a46cc41216 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Exact.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Exact.lean @@ -829,7 +829,7 @@ section Abelian variable [Abelian C] -section +/-section variable {X Y : C} (f : X ⟶ Y) @@ -857,7 +857,7 @@ lemma kernelSequence_exact : (kernelSequence f).Exact := lemma cokernelSequence_exact : (cokernelSequence f).Exact := exact_of_g_is_cokernel _ (cokernelIsCokernel f) -end +end-/ /-- Given a morphism of short complexes `φ : S₁ ⟶ S₂` in an abelian category, if `S₁.f` and `S₁.g` are zero (e.g. when `S₁` is of the form `0 ⟶ S₁.X₂ ⟶ 0`) and `S₂.f = 0` diff --git a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean index 1670bb9091ee3b..b289b6bd28c810 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Homology.SpectralObject.Basic public import Mathlib.Algebra.Homology.ExactSequenceFour +public import Mathlib.CategoryTheory.Abelian.Exact public import Batteries.Tactic.Lint /-! @@ -140,12 +141,12 @@ instance : Epi (X.cokernelSequenceOpcycles n₀ n₁ hn₁ f g).g := by lemma kernelSequenceCycles_exact : (X.kernelSequenceCycles n₀ n₁ hn₁ f g).Exact := by subst hn₁ - exact ShortComplex.kernelSequence_exact _ + apply ShortComplex.exact_kernel lemma cokernelSequenceOpcycles_exact : (X.cokernelSequenceOpcycles n₀ n₁ hn₁ f g).Exact := by obtain rfl : n₀ = n₁ - 1 := by lia - exact ShortComplex.cokernelSequence_exact _ + apply ShortComplex.exact_cokernel section From 4cebd4e682286fbfc4c4f710d225b67a59012d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 12:20:59 +0100 Subject: [PATCH 39/72] stability under finite products of ObjectProperty --- Mathlib.lean | 1 + .../ObjectProperty/FiniteProducts.lean | 103 ++++++++++++++++++ .../ObjectProperty/LimitsOfShape.lean | 5 + .../Triangulated/Subcategory.lean | 50 +++------ 4 files changed, 124 insertions(+), 35 deletions(-) create mode 100644 Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean diff --git a/Mathlib.lean b/Mathlib.lean index 1c582fe150157a..b4919735d37519 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2946,6 +2946,7 @@ public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero public import Mathlib.CategoryTheory.ObjectProperty.EpiMono public import Mathlib.CategoryTheory.ObjectProperty.Equivalence public import Mathlib.CategoryTheory.ObjectProperty.Extensions +public import Mathlib.CategoryTheory.ObjectProperty.FiniteProducts public import Mathlib.CategoryTheory.ObjectProperty.FullSubcategory public import Mathlib.CategoryTheory.ObjectProperty.FunctorCategory.PreservesLimits public import Mathlib.CategoryTheory.ObjectProperty.HasCardinalLT diff --git a/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean new file mode 100644 index 00000000000000..c1ff247209bf22 --- /dev/null +++ b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean @@ -0,0 +1,103 @@ +/- +Copyright (c) 2026 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.Limits.Shapes.FiniteProducts +public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero +public import Mathlib.CategoryTheory.ObjectProperty.LimitsOfShape + +/-! +# Properties of objects that are stable under finite products + +We introduce typeclasses `IsClosedUnderBinaryProducts` and +`IsClosedUnderFiniteProducts` expressing that `P : ObjectProperty C` +is closed under binary products or finite products. +We introduce a constructor for `P.IsClosedUnderFiniteProducts` +assuming `P.IsClosedUnderBinaryProducts`, +`P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)` and that `C` +has finite products. + +-/ + +@[expose] public section + +namespace CategoryTheory.ObjectProperty + +open Limits + +variable {C : Type*} [Category* C] (P : ObjectProperty C) + +/-- The typeclass saying that `P : ObjectProperty C` is stable under binary products. -/ +abbrev IsClosedUnderBinaryProducts := + P.IsClosedUnderLimitsOfShape (Discrete WalkingPair) + +lemma prop_prod [P.IsClosedUnderBinaryProducts] (X Y : C) [HasBinaryProduct X Y] + (hX : P X) (hY : P Y) : + P (X ⨯ Y) := + P.prop_limit _ (by rintro ⟨_ | _⟩ <;> assumption) + +lemma prop_of_isTerminal [P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)] + (X : C) (hX : IsTerminal X) : + P X := + P.prop_of_isLimit hX (by rintro ⟨⟨⟩⟩) + +/-- The typeclass saying that `P : ObjectProperty C` is stable under finite products. -/ +class IsClosedUnderFiniteProducts : Prop where + isClosedUnderLimitsOfShape (J : Type) [Finite J] : + P.IsClosedUnderLimitsOfShape (Discrete J) := by infer_instance + +instance [P.IsClosedUnderFiniteProducts] (J : Type*) [Finite J] : + P.IsClosedUnderLimitsOfShape (Discrete J) := by + obtain ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J + have : P.IsClosedUnderLimitsOfShape (Discrete (Fin n)) := + IsClosedUnderFiniteProducts.isClosedUnderLimitsOfShape _ + exact IsClosedUnderLimitsOfShape.of_equivalence (Discrete.equivalence e.symm) + +instance [P.ContainsZero] [P.IsClosedUnderIsomorphisms] : + P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty) where + limitsOfShape_le := by + rintro X ⟨p⟩ + obtain ⟨Z, hZ, hZ₂⟩ := P.exists_prop_of_containsZero + have hX : IsTerminal X := + (IsLimit.equivOfNatIsoOfIso p.diag.uniqueFromEmpty _ _ + (by exact Cones.ext (Iso.refl _) (by rintro ⟨⟨⟩⟩))).1 p.isLimit + exact P.prop_of_isZero (IsZero.of_iso hZ + (IsLimit.conePointUniqueUpToIso hX (IsZero.isTerminal hZ))) + +variable {P} in +lemma IsClosedUnderFiniteProducts.mk' [HasFiniteProducts C] + [P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)] + [P.IsClosedUnderBinaryProducts] : + P.IsClosedUnderFiniteProducts := by + suffices ∀ (J : Type) [Finite J], P.IsClosedUnderLimitsOfShape (Discrete J) from ⟨this⟩ + intro J _ + induction J using Finite.induction_empty_option with + | of_equiv e => + exact IsClosedUnderLimitsOfShape.of_equivalence (Discrete.equivalence e) + | h_empty => infer_instance + | @h_option α => + constructor + rintro X ⟨p⟩ + have hc : IsLimit + (BinaryFan.mk (Pi.lift (fun j ↦ p.π.app (.mk (some j)))) (p.π.app (.mk none))) := + BinaryFan.IsLimit.mk _ + (fun f₁ f₂ ↦ p.isLimit.lift (Cone.mk _ (Discrete.natTrans (fun ⟨j⟩ ↦ by + induction j with + | some j => exact f₁ ≫ Pi.π _ j + | none => exact f₂)))) + (fun _ _ ↦ by dsimp; ext; simp [p.isLimit.fac]) + (fun _ _ ↦ by simp [p.isLimit.fac]) + (fun f₁ f₂ l hl₁ hl₂ ↦ by + refine p.isLimit.hom_ext (fun ⟨j⟩ ↦ ?_) + induction j with + | some j => simp [p.isLimit.fac, ← hl₁] + | none => simpa [p.isLimit.fac]) + refine P.prop_of_isLimit hc ?_ + rintro ⟨_ | _⟩ + · exact P.prop_limit _ (fun _ ↦ p.prop_diag_obj _) + · exact p.prop_diag_obj _ + +end CategoryTheory.ObjectProperty diff --git a/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean b/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean index 924388ab5a17ac..42e763d05742bb 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean @@ -206,6 +206,11 @@ lemma prop_limit (F : J ⥤ C) [HasLimit F] (hF : ∀ (j : J), P (F.obj j)) : end +lemma prop_pi {J : Type*} [P.IsClosedUnderLimitsOfShape (Discrete J)] (X : J → C) + [HasProduct X] (hF : ∀ (j : J), P (X j)) : + P (∏ᶜ X) := + P.prop_of_isLimit (productIsProduct X) (fun _ ↦ hF _) + variable {J} in lemma limitsOfShape_le_of_initial (G : J ⥤ J') [G.Initial] : P.limitsOfShape J' ≤ P.limitsOfShape J := diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index cf4cbe3a0504c6..15964f723baeb1 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -7,7 +7,7 @@ module public import Mathlib.CategoryTheory.Localization.CalculusOfFractions public import Mathlib.CategoryTheory.Localization.Triangulated -public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero +public import Mathlib.CategoryTheory.ObjectProperty.FiniteProducts public import Mathlib.CategoryTheory.ObjectProperty.LimitsOfShape public import Mathlib.CategoryTheory.ObjectProperty.Shift public import Mathlib.CategoryTheory.Shift.Localization @@ -307,38 +307,18 @@ instance [IsTriangulated C] [P.IsTriangulated] : P.trW.IsCompatibleWithTriangula exact ⟨φ.hom₃, P.trW.comp_mem _ _ (trW.mk P H.mem mem₄') (trW.mk' P H'.mem mem₅'), by simpa [φ] using φ.comm₂, by simpa [φ] using φ.comm₃⟩⟩ -lemma prop_prod_of_isTriangulated [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] - (X₁ X₂ : C) (hX₁ : P X₁) (hX₂ : P X₂) : - P (X₁ ⨯ X₂) := - P.ext_of_isTriangulatedClosed₂ _ (binaryProductTriangle_distinguished X₁ X₂) hX₁ hX₂ - -lemma prop_pi_of_isTriangulated [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] - {J : Type} [Finite J] (X : J → C) (hX : ∀ j, P (X j)) : - P (∏ᶜ X) := by - revert hX X - let Q (J : Type) : Prop := ∀ [hJ : Finite J] (X : J → C) (_ : ∀ j, P (X j)), P (∏ᶜ X) - suffices Q J by exact this - induction J using Finite.induction_empty_option with - | @of_equiv J₁ J₂ e hJ₁ => - intro _ X hX - have : Finite J₁ := Finite.of_equiv _ e.symm - exact prop_of_iso _ (Pi.whiskerEquiv e (fun _ ↦ Iso.refl _)) - (hJ₁ (fun j₁ ↦ X (e j₁)) (fun j₁ ↦ hX _)) - | h_empty => - intro _ X _ - refine prop_of_iso _ (IsZero.isoZero ?_).symm P.prop_zero - rw [IsZero.iff_id_eq_zero] - ext ⟨⟩ - | @h_option J _ hJ => - intro _ X hX - let iso : ∏ᶜ X ≅ (∏ᶜ fun b ↦ X (some b)) ⨯ X none := - { hom := prod.lift (Pi.lift (fun b ↦ Pi.π _ (some b))) (Pi.π _ none) - inv := Pi.lift (fun b ↦ match b with - | some j => prod.fst ≫ Pi.π _ j - | none => prod.snd) } - exact prop_of_iso _ iso.symm - (P.prop_prod_of_isTriangulated _ _ - (hJ (fun j => X (some j)) (fun j => hX _)) (hX none)) +instance [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] : + P.IsClosedUnderBinaryProducts where + limitsOfShape_le := by + rintro X ⟨p⟩ + refine P.prop_of_iso ?_ (P.ext_of_isTriangulatedClosed₂ _ + (binaryProductTriangle_distinguished _ _) + (p.prop_diag_obj (.mk .left)) (p.prop_diag_obj (.mk .right))) + exact IsLimit.conePointUniqueUpToIso (prodIsProd _ _) + ((IsLimit.postcomposeHomEquiv (diagramIsoPair p.diag) _).2 p.isLimit) + +instance [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] : + P.IsClosedUnderFiniteProducts := .mk' instance [P.IsTriangulated] : P.trW.IsStableUnderFiniteProducts := by rw [← trW_isoClosure] @@ -347,7 +327,7 @@ instance [P.IsTriangulated] : P.trW.IsStableUnderFiniteProducts := by intro _ _ X₁ X₂ f hf exact trW.mk _ (productTriangle_distinguished _ (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose)) - (prop_pi_of_isTriangulated _ _ + (P.isoClosure.prop_pi _ (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose_spec))⟩ lemma closedUnderLimitsOfShape_discrete_of_isTriangulated @@ -359,7 +339,7 @@ lemma closedUnderLimitsOfShape_discrete_of_isTriangulated have e : Discrete.functor G ≅ p.diag := Discrete.natIso (fun _ ↦ Iso.refl _) have := IsLimit.conePointUniqueUpToIso (limit.isLimit _) ((IsLimit.postcomposeInvEquiv e _).2 p.isLimit) - exact P.prop_of_iso this (P.prop_pi_of_isTriangulated G (fun j ↦ p.prop_diag_obj _)) + exact P.prop_of_iso this (P.prop_pi G (fun j ↦ p.prop_diag_obj _)) section From 12d40bc057f3aad62bbe68be786a6af0d15738fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 12:49:29 +0100 Subject: [PATCH 40/72] feat(CategoryTheory/ObjectProperty): stability unfer finite products --- Mathlib.lean | 1 + .../ObjectProperty/FiniteProducts.lean | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean diff --git a/Mathlib.lean b/Mathlib.lean index 101c0efff87c0f..803122f91a11a4 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2936,6 +2936,7 @@ public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero public import Mathlib.CategoryTheory.ObjectProperty.EpiMono public import Mathlib.CategoryTheory.ObjectProperty.Equivalence public import Mathlib.CategoryTheory.ObjectProperty.Extensions +public import Mathlib.CategoryTheory.ObjectProperty.FiniteProducts public import Mathlib.CategoryTheory.ObjectProperty.FullSubcategory public import Mathlib.CategoryTheory.ObjectProperty.FunctorCategory.PreservesLimits public import Mathlib.CategoryTheory.ObjectProperty.HasCardinalLT diff --git a/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean new file mode 100644 index 00000000000000..ff3af46173ad67 --- /dev/null +++ b/Mathlib/CategoryTheory/ObjectProperty/FiniteProducts.lean @@ -0,0 +1,103 @@ +/- +Copyright (c) 2026 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.Limits.Shapes.FiniteProducts +public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero +public import Mathlib.CategoryTheory.ObjectProperty.LimitsOfShape + +/-! +# Properties of objects that are stable under finite products + +We introduce typeclasses `IsClosedUnderBinaryProducts` and +`IsClosedUnderFiniteProducts` expressing that `P : ObjectProperty C` +is closed under binary products or finite products. +We introduce a constructor for `P.IsClosedUnderFiniteProducts` +assuming `P.IsClosedUnderBinaryProducts`, +`P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)` and that `C` +has finite products. + +-/ + +@[expose] public section + +namespace CategoryTheory.ObjectProperty + +open Limits + +variable {C : Type*} [Category* C] (P : ObjectProperty C) + +/-- The typeclass saying that `P : ObjectProperty C` is stable under binary products. -/ +abbrev IsClosedUnderBinaryProducts := + P.IsClosedUnderLimitsOfShape (Discrete WalkingPair) + +lemma prop_prod [P.IsClosedUnderBinaryProducts] (X Y : C) [HasBinaryProduct X Y] + (hX : P X) (hY : P Y) : + P (X ⨯ Y) := + P.prop_limit _ (by rintro ⟨_ | _⟩ <;> assumption) + +lemma prop_of_isTerminal [P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)] + (X : C) (hX : IsTerminal X) : + P X := + P.prop_of_isLimit hX (by rintro ⟨⟨⟩⟩) + +/-- The typeclass saying that `P : ObjectProperty C` is stable under finite products. -/ +class IsClosedUnderFiniteProducts : Prop where + isClosedUnderLimitsOfShape (J : Type) [Finite J] : + P.IsClosedUnderLimitsOfShape (Discrete J) := by infer_instance + +instance [P.IsClosedUnderFiniteProducts] (J : Type*) [Finite J] : + P.IsClosedUnderLimitsOfShape (Discrete J) := by + obtain ⟨n, ⟨e⟩⟩ := Finite.exists_equiv_fin J + have : P.IsClosedUnderLimitsOfShape (Discrete (Fin n)) := + IsClosedUnderFiniteProducts.isClosedUnderLimitsOfShape _ + exact IsClosedUnderLimitsOfShape.of_equivalence (Discrete.equivalence e.symm) + +instance [P.ContainsZero] [P.IsClosedUnderIsomorphisms] : + P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty) where + limitsOfShape_le := by + rintro X ⟨p⟩ + obtain ⟨Z, hZ, hZ₂⟩ := P.exists_prop_of_containsZero + have hX : IsTerminal X := + (IsLimit.equivOfNatIsoOfIso p.diag.uniqueFromEmpty _ _ + (by exact Cones.ext (Iso.refl _) (by rintro ⟨⟨⟩⟩))).1 p.isLimit + exact P.prop_of_isZero (IsZero.of_iso hZ + (IsLimit.conePointUniqueUpToIso hX (IsZero.isTerminal hZ))) + +variable {P} in +lemma IsClosedUnderFiniteProducts.mk' [HasFiniteProducts C] + [P.IsClosedUnderLimitsOfShape (Discrete.{0} PEmpty)] + [P.IsClosedUnderBinaryProducts] : + P.IsClosedUnderFiniteProducts := by + suffices ∀ (J : Type) [Finite J], P.IsClosedUnderLimitsOfShape (Discrete J) from ⟨this⟩ + intro J _ + induction J using Finite.induction_empty_option with + | of_equiv e => + exact IsClosedUnderLimitsOfShape.of_equivalence (Discrete.equivalence e) + | h_empty => infer_instance + | h_option => + constructor + rintro X ⟨p⟩ + have hc : IsLimit + (BinaryFan.mk (Pi.lift (fun j ↦ p.π.app (.mk (some j)))) (p.π.app (.mk none))) := + BinaryFan.IsLimit.mk _ + (fun f₁ f₂ ↦ p.isLimit.lift (Cone.mk _ (Discrete.natTrans (fun ⟨j⟩ ↦ by + induction j with + | some j => exact f₁ ≫ Pi.π _ j + | none => exact f₂)))) + (fun _ _ ↦ by dsimp; ext; simp [p.isLimit.fac]) + (fun _ _ ↦ by simp [p.isLimit.fac]) + (fun f₁ f₂ l hl₁ hl₂ ↦ by + refine p.isLimit.hom_ext (fun ⟨j⟩ ↦ ?_) + induction j with + | some j => simp [p.isLimit.fac, ← hl₁] + | none => simpa [p.isLimit.fac]) + refine P.prop_of_isLimit hc ?_ + rintro ⟨_ | _⟩ + · exact P.prop_limit _ (fun _ ↦ p.prop_diag_obj _) + · exact p.prop_diag_obj _ + +end CategoryTheory.ObjectProperty From 02de8e8e07ae1bbe0a71945ea7096e514435c614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 13:41:37 +0100 Subject: [PATCH 41/72] cleaning up --- Mathlib.lean | 1 + Mathlib/CategoryTheory/EssentialImage.lean | 9 + .../CategoryTheory/ObjectProperty/Shift.lean | 41 ++++- .../Triangulated/Subcategory.lean | 171 +++++------------- 4 files changed, 100 insertions(+), 122 deletions(-) diff --git a/Mathlib.lean b/Mathlib.lean index b4919735d37519..68c8d0c6cc36be 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -3028,6 +3028,7 @@ public import Mathlib.CategoryTheory.Shift.Adjunction public import Mathlib.CategoryTheory.Shift.Basic public import Mathlib.CategoryTheory.Shift.CommShift public import Mathlib.CategoryTheory.Shift.CommShiftTwo +public import Mathlib.CategoryTheory.Shift.FullSubcategory public import Mathlib.CategoryTheory.Shift.Induced public import Mathlib.CategoryTheory.Shift.InducedShiftSequence public import Mathlib.CategoryTheory.Shift.Linear diff --git a/Mathlib/CategoryTheory/EssentialImage.lean b/Mathlib/CategoryTheory/EssentialImage.lean index 1fec6f2027418f..85a90cb4e8608c 100644 --- a/Mathlib/CategoryTheory/EssentialImage.lean +++ b/Mathlib/CategoryTheory/EssentialImage.lean @@ -184,6 +184,15 @@ factor through `essImage.liftFunctor G F hG`. -/ NatIso.ofComponents (fun i ↦ F.essImage.ι.mapIso (F.toEssImage.objObjPreimageIso ⟨G.obj i, hG _⟩)) +lemma essImage_ι_comp (F : C ⥤ D) (P : ObjectProperty C) : + (P.ι ⋙ F).essImage = P.map F := by + ext Y + constructor + · rintro ⟨X, ⟨e⟩⟩ + exact ⟨X.1, X.2, ⟨e⟩⟩ + · rintro ⟨X, hX, ⟨e⟩⟩ + exact ⟨⟨X, hX⟩, ⟨e⟩⟩ + end Functor end CategoryTheory diff --git a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean index f9e3c8f85d64ab..1077a32348b9ad 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean @@ -6,7 +6,8 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.ObjectProperty.ClosedUnderIsomorphisms -public import Mathlib.CategoryTheory.Shift.Basic +public import Mathlib.CategoryTheory.Preadditive.AdditiveFunctor +public import Mathlib.CategoryTheory.Shift.CommShift /-! # Properties of objects on categories equipped with shift @@ -26,6 +27,7 @@ namespace CategoryTheory variable {C : Type*} [Category* C] (P Q : ObjectProperty C) {A : Type*} [AddMonoid A] [HasShift C A] + {E : Type*} [Category* E] [HasShift E A] namespace ObjectProperty @@ -93,6 +95,43 @@ lemma prop_shift_iff_of_isStableUnderShift {G : Type*} [AddGroup G] [HasShift C rw [← P.shift_zero G, ← P.shift_shift g (-g) 0 (by simp)] exact P.le_shift (-g) _ hX +variable [P.IsStableUnderShift A] + +noncomputable instance hasShift : + HasShift P.FullSubcategory A := + P.fullyFaithfulι.hasShift (fun n ↦ ObjectProperty.lift _ (P.ι ⋙ shiftFunctor C n) + (fun X ↦ P.le_shift n _ X.2)) (fun _ => P.liftCompιIso _ _) + +instance commShiftι : P.ι.CommShift A := + Functor.CommShift.ofHasShiftOfFullyFaithful _ _ _ + +-- these definitions are made irreducible to prevent any abuse of defeq +attribute [irreducible] hasShift commShiftι + +instance [Preadditive C] (n : A) [(shiftFunctor C n).Additive] : + (shiftFunctor P.FullSubcategory n).Additive := by + have := Functor.additive_of_iso (P.ι.commShiftIso n).symm + apply Functor.additive_of_comp_faithful _ P.ι + +section + +variable (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) + +noncomputable instance [F.CommShift A] : + (P.lift F hF).CommShift A := + Functor.CommShift.ofComp (P.liftCompιIso F hF) A + +noncomputable instance [F.CommShift A] : + NatTrans.CommShift (P.liftCompιIso F hF).hom A := + Functor.CommShift.ofComp_compatibility _ _ + +end + +instance [P.IsClosedUnderIsomorphisms] (F : E ⥤ C) [F.CommShift A] : + (P.inverseImage F).IsStableUnderShift A where + isStableUnderShiftBy n := + { le_shift _ hY := P.prop_of_iso ((F.commShiftIso n).symm.app _) (P.le_shift n _ hY) } + end ObjectProperty end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index 15964f723baeb1..f33d26a9fe655a 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -8,7 +8,6 @@ module public import Mathlib.CategoryTheory.Localization.CalculusOfFractions public import Mathlib.CategoryTheory.Localization.Triangulated public import Mathlib.CategoryTheory.ObjectProperty.FiniteProducts -public import Mathlib.CategoryTheory.ObjectProperty.LimitsOfShape public import Mathlib.CategoryTheory.ObjectProperty.Shift public import Mathlib.CategoryTheory.Shift.Localization public import Mathlib.CategoryTheory.MorphismProperty.Limits @@ -261,6 +260,31 @@ lemma trW_iff_of_distinguished' [P.IsStableUnderShift ℤ] simpa [P.prop_shift_iff_of_isStableUnderShift] using P.trW_iff_of_distinguished _ (rot_of_distTriang _ hT) +section + +variable (F : D ⥤ C) [F.CommShift ℤ] [F.IsTriangulated] + [P.IsClosedUnderIsomorphisms] + +instance [P.IsTriangulated] : (P.inverseImage F).IsTriangulated where + toIsTriangulatedClosed₂ := .mk' (fun T hT h₁ h₃ ↦ + P.ext_of_isTriangulatedClosed₂ _ (F.map_distinguished T hT) h₁ h₃) + +lemma inverseImage_trW_iff {X Y : D} (s : X ⟶ Y) : + (P.inverseImage F).trW s ↔ P.trW (F.map s) := by + obtain ⟨Z, g, h, hT⟩ := distinguished_cocone_triangle s + have eq₁ := (P.inverseImage F).trW_iff_of_distinguished _ hT + have eq₂ := P.trW_iff_of_distinguished _ (F.map_distinguished _ hT) + dsimp at eq₁ eq₂ + rw [eq₁, prop_inverseImage_iff, eq₂] + +lemma inverseImage_trW_isInverted {E : Type*} [Category E] + (L : C ⥤ E) [L.IsLocalization P.trW] : + (P.inverseImage F).trW.IsInvertedBy (F ⋙ L) := + fun X Y f hf => Localization.inverts L P.trW (F.map f) + (by simpa only [inverseImage_trW_iff] using hf) + +end + instance [IsTriangulated C] [P.IsTriangulated] : P.trW.HasLeftCalculusOfFractions where exists_leftFraction X Y φ := by obtain ⟨Z, f, g, H, mem⟩ := φ.hs @@ -307,6 +331,17 @@ instance [IsTriangulated C] [P.IsTriangulated] : P.trW.IsCompatibleWithTriangula exact ⟨φ.hom₃, P.trW.comp_mem _ _ (trW.mk P H.mem mem₄') (trW.mk' P H'.mem mem₅'), by simpa [φ] using φ.comm₂, by simpa [φ] using φ.comm₃⟩⟩ +instance (P' : ObjectProperty C) [P.IsTriangulatedClosed₂] [P.IsClosedUnderIsomorphisms] + [P'.IsTriangulatedClosed₂] : + (P ⊓ P').IsTriangulatedClosed₂ where + ext₂' T hT h₁ h₃ := by + obtain ⟨X₂, h₂, ⟨e⟩⟩ := P'.ext_of_isTriangulatedClosed₂' T hT h₁.2 h₃.2 + exact ⟨X₂, ⟨P.prop_of_iso e (P.ext_of_isTriangulatedClosed₂ T hT h₁.1 h₃.1), h₂⟩, ⟨e⟩⟩ + +instance (P' : ObjectProperty C) [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] + [P'.IsTriangulated] : + (P ⊓ P').IsTriangulated where + instance [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] : P.IsClosedUnderBinaryProducts where limitsOfShape_le := by @@ -330,61 +365,13 @@ instance [P.IsTriangulated] : P.trW.IsStableUnderFiniteProducts := by (P.isoClosure.prop_pi _ (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose_spec))⟩ -lemma closedUnderLimitsOfShape_discrete_of_isTriangulated - [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] (J : Type) [Finite J] : - P.IsClosedUnderLimitsOfShape (Discrete J) where - limitsOfShape_le := by - rintro X ⟨p⟩ - let G (j : J) : C := p.diag.obj ⟨j⟩ - have e : Discrete.functor G ≅ p.diag := Discrete.natIso (fun _ ↦ Iso.refl _) - have := IsLimit.conePointUniqueUpToIso (limit.isLimit _) - ((IsLimit.postcomposeInvEquiv e _).2 p.isLimit) - exact P.prop_of_iso this (P.prop_pi G (fun j ↦ p.prop_diag_obj _)) - -section - -instance (P' : ObjectProperty C) [P.IsTriangulatedClosed₂] [P.IsClosedUnderIsomorphisms] - [P'.IsTriangulatedClosed₂] : - (P ⊓ P').IsTriangulatedClosed₂ where - ext₂' T hT h₁ h₃ := by - obtain ⟨X₂, h₂, ⟨e⟩⟩ := P'.ext_of_isTriangulatedClosed₂' T hT h₁.2 h₃.2 - exact ⟨X₂, ⟨P.prop_of_iso e (P.ext_of_isTriangulatedClosed₂ T hT h₁.1 h₃.1), h₂⟩, ⟨e⟩⟩ - -instance (P' : ObjectProperty C) [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] - [P'.IsTriangulated] : - (P ⊓ P').IsTriangulated where - -end - section variable [P.IsTriangulated] -noncomputable instance hasShift : - HasShift P.FullSubcategory ℤ := - P.fullyFaithfulι.hasShift (fun n ↦ ObjectProperty.lift _ (P.ι ⋙ shiftFunctor C n) - (fun X ↦ P.le_shift n _ X.2)) (fun _ => P.liftCompιIso _ _) - -instance commShiftι : P.ι.CommShift ℤ := - Functor.CommShift.ofHasShiftOfFullyFaithful _ _ _ - --- these definitions are made irreducible to prevent any abuse of defeq -attribute [irreducible] hasShift commShiftι - -instance (n : ℤ) : (shiftFunctor P.FullSubcategory n).Additive := by - have := Functor.additive_of_iso (P.ι.commShiftIso n).symm - apply Functor.additive_of_comp_faithful _ P.ι - -instance : HasZeroObject P.FullSubcategory where - zero := by - obtain ⟨Z, hZ, mem⟩ := P.exists_prop_of_containsZero - refine ⟨⟨Z, mem⟩, ?_⟩ - rw [IsZero.iff_id_eq_zero] - exact ObjectProperty.hom_ext _ (hZ.eq_of_src _ _) - noncomputable instance : Pretriangulated P.FullSubcategory where - distinguishedTriangles := fun T => P.ι.mapTriangle.obj T ∈ distTriang C - isomorphic_distinguished := fun T₁ hT₁ T₂ e => + distinguishedTriangles T := P.ι.mapTriangle.obj T ∈ distTriang C + isomorphic_distinguished T₁ hT₁ T₂ e := isomorphic_distinguished _ hT₁ _ (P.ι.mapTriangle.mapIso e) contractible_distinguished X := isomorphic_distinguished _ (contractible_distinguished (P.ι.obj X)) _ @@ -402,22 +389,20 @@ noncomputable instance : Pretriangulated P.FullSubcategory where obtain ⟨c, ⟨hc₁, hc₂⟩⟩ := complete_distinguished_triangle_morphism (P.ι.mapTriangle.obj T₁) (P.ι.mapTriangle.obj T₂) hT₁ hT₂ (P.ι.map a) (P.ι.map b) (by simpa using P.ι.congr_map comm) - have := P.ι.commShiftIso_hom_naturality a (1 : ℤ) refine ⟨P.fullyFaithfulι.preimage c, ⟨by cat_disch, ?_⟩⟩ ext + have := P.ι.commShiftIso_hom_naturality a (1 : ℤ) rw [← cancel_mono ((Functor.commShiftIso P.ι (1 : ℤ)).hom.app T₂.obj₁)] cat_disch -instance : P.ι.IsTriangulated := ⟨fun _ hT => hT⟩ +instance : P.ι.IsTriangulated where + map_distinguished _ hT := hT instance [IsTriangulated C] : IsTriangulated P.FullSubcategory := IsTriangulated.of_fully_faithful_triangulated_functor P.ι -section - -variable (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] - -instance : (F.essImage).IsTriangulated where +instance (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] : + (F.essImage).IsTriangulated where isStableUnderShiftBy n := { le_shift := by rintro Y ⟨X, ⟨e⟩⟩ @@ -432,78 +417,22 @@ instance : (F.essImage).IsTriangulated where (isoTriangleOfIso₁₃ _ _ (F.map_distinguished _ H) hT e₁ e₃ (by simp [hh, ← Functor.map_comp]))⟩⟩) -end - -section - -variable (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) - -noncomputable instance [F.CommShift ℤ] : - (P.lift F hF).CommShift ℤ := - Functor.CommShift.ofComp (P.liftCompιIso F hF) ℤ - -noncomputable instance [F.CommShift ℤ] : - NatTrans.CommShift (P.liftCompιIso F hF).hom ℤ := - Functor.CommShift.ofComp_compatibility _ _ - -instance isTriangulated_lift [Preadditive E] [F.CommShift ℤ] [HasZeroObject E] +instance isTriangulated_lift (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) + [Preadditive E] [F.CommShift ℤ] [HasZeroObject E] [∀ (n : ℤ), (shiftFunctor E n).Additive] [Pretriangulated E] [F.IsTriangulated] : (P.lift F hF).IsTriangulated := by rw [Functor.isTriangulated_iff_comp_right (P.liftCompιIso F hF)] infer_instance -end - -section - -variable (F : D ⥤ C) [F.CommShift ℤ] [F.IsTriangulated] - [P.IsClosedUnderIsomorphisms] - -instance : (P.inverseImage F).IsTriangulated where - isStableUnderShiftBy n := - { le_shift _ hY := P.prop_of_iso ((F.commShiftIso n).symm.app _) (P.le_shift n _ hY) } - toIsTriangulatedClosed₂ := .mk' (fun T hT h₁ h₃ ↦ - P.ext_of_isTriangulatedClosed₂ _ (F.map_distinguished T hT) h₁ h₃) - -omit [P.IsTriangulated] in -lemma inverseImage_trW_iff {X Y : D} (s : X ⟶ Y) : - (P.inverseImage F).trW s ↔ P.trW (F.map s) := by - obtain ⟨Z, g, h, hT⟩ := distinguished_cocone_triangle s - have eq₁ := (P.inverseImage F).trW_iff_of_distinguished _ hT - have eq₂ := P.trW_iff_of_distinguished _ (F.map_distinguished _ hT) - dsimp at eq₁ eq₂ - rw [eq₁, prop_inverseImage_iff, eq₂] - -omit [P.IsTriangulated] in -lemma inverseImage_trW_isInverted {E : Type*} [Category E] - (L : C ⥤ E) [L.IsLocalization P.trW] : - (P.inverseImage F).trW.IsInvertedBy (F ⋙ L) := - fun X Y f hf => Localization.inverts L P.trW (F.map f) - (by simpa only [inverseImage_trW_iff] using hf) - -end - -section - -variable {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] - [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] - -instance : (P.map F).IsTriangulated := by - have : P.map F = (P.ι ⋙ F).essImage := by - ext Y - constructor - · rintro ⟨X, hX, ⟨e⟩⟩ - exact ⟨⟨X, hX⟩, ⟨e⟩⟩ - · rintro ⟨X, ⟨e⟩⟩ - exact ⟨X.1, X.2, ⟨e⟩⟩ - rw [this] +instance {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] + [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] : + (P.map F).IsTriangulated := by + rw [← F.essImage_ι_comp] infer_instance end -end - end ObjectProperty namespace Triangulated From f5ac3cf198d4438012d5e7f673cf0dc918463f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 13:43:33 +0100 Subject: [PATCH 42/72] feat(CategoryTheory/Shift): the shift on a full subcategory --- .../CategoryTheory/ObjectProperty/Shift.lean | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean index f9e3c8f85d64ab..1077a32348b9ad 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean @@ -6,7 +6,8 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.ObjectProperty.ClosedUnderIsomorphisms -public import Mathlib.CategoryTheory.Shift.Basic +public import Mathlib.CategoryTheory.Preadditive.AdditiveFunctor +public import Mathlib.CategoryTheory.Shift.CommShift /-! # Properties of objects on categories equipped with shift @@ -26,6 +27,7 @@ namespace CategoryTheory variable {C : Type*} [Category* C] (P Q : ObjectProperty C) {A : Type*} [AddMonoid A] [HasShift C A] + {E : Type*} [Category* E] [HasShift E A] namespace ObjectProperty @@ -93,6 +95,43 @@ lemma prop_shift_iff_of_isStableUnderShift {G : Type*} [AddGroup G] [HasShift C rw [← P.shift_zero G, ← P.shift_shift g (-g) 0 (by simp)] exact P.le_shift (-g) _ hX +variable [P.IsStableUnderShift A] + +noncomputable instance hasShift : + HasShift P.FullSubcategory A := + P.fullyFaithfulι.hasShift (fun n ↦ ObjectProperty.lift _ (P.ι ⋙ shiftFunctor C n) + (fun X ↦ P.le_shift n _ X.2)) (fun _ => P.liftCompιIso _ _) + +instance commShiftι : P.ι.CommShift A := + Functor.CommShift.ofHasShiftOfFullyFaithful _ _ _ + +-- these definitions are made irreducible to prevent any abuse of defeq +attribute [irreducible] hasShift commShiftι + +instance [Preadditive C] (n : A) [(shiftFunctor C n).Additive] : + (shiftFunctor P.FullSubcategory n).Additive := by + have := Functor.additive_of_iso (P.ι.commShiftIso n).symm + apply Functor.additive_of_comp_faithful _ P.ι + +section + +variable (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) + +noncomputable instance [F.CommShift A] : + (P.lift F hF).CommShift A := + Functor.CommShift.ofComp (P.liftCompιIso F hF) A + +noncomputable instance [F.CommShift A] : + NatTrans.CommShift (P.liftCompιIso F hF).hom A := + Functor.CommShift.ofComp_compatibility _ _ + +end + +instance [P.IsClosedUnderIsomorphisms] (F : E ⥤ C) [F.CommShift A] : + (P.inverseImage F).IsStableUnderShift A where + isStableUnderShiftBy n := + { le_shift _ hY := P.prop_of_iso ((F.commShiftIso n).symm.app _) (P.le_shift n _ hY) } + end ObjectProperty end CategoryTheory From c30c8f2bce9d52155d40cfbaf349bafef43a711b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 13:48:21 +0100 Subject: [PATCH 43/72] wip --- Mathlib/CategoryTheory/EssentialImage.lean | 9 ++ .../Triangulated/Subcategory.lean | 139 +++++++++++++++++- 2 files changed, 147 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/EssentialImage.lean b/Mathlib/CategoryTheory/EssentialImage.lean index 1fec6f2027418f..85a90cb4e8608c 100644 --- a/Mathlib/CategoryTheory/EssentialImage.lean +++ b/Mathlib/CategoryTheory/EssentialImage.lean @@ -184,6 +184,15 @@ factor through `essImage.liftFunctor G F hG`. -/ NatIso.ofComponents (fun i ↦ F.essImage.ι.mapIso (F.toEssImage.objObjPreimageIso ⟨G.obj i, hG _⟩)) +lemma essImage_ι_comp (F : C ⥤ D) (P : ObjectProperty C) : + (P.ι ⋙ F).essImage = P.map F := by + ext Y + constructor + · rintro ⟨X, ⟨e⟩⟩ + exact ⟨X.1, X.2, ⟨e⟩⟩ + · rintro ⟨X, hX, ⟨e⟩⟩ + exact ⟨⟨X, hX⟩, ⟨e⟩⟩ + end Functor end CategoryTheory diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index e85fdf21a18769..f33d26a9fe655a 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -7,9 +7,10 @@ module public import Mathlib.CategoryTheory.Localization.CalculusOfFractions public import Mathlib.CategoryTheory.Localization.Triangulated -public import Mathlib.CategoryTheory.ObjectProperty.ContainsZero +public import Mathlib.CategoryTheory.ObjectProperty.FiniteProducts public import Mathlib.CategoryTheory.ObjectProperty.Shift public import Mathlib.CategoryTheory.Shift.Localization +public import Mathlib.CategoryTheory.MorphismProperty.Limits /-! # Triangulated subcategories @@ -50,6 +51,9 @@ open Category Limits Preadditive ZeroObject Pretriangulated Triangulated variable {C : Type*} [Category* C] [HasZeroObject C] [HasShift C ℤ] [Preadditive C] [∀ (n : ℤ), (shiftFunctor C n).Additive] [Pretriangulated C] + {D : Type*} [Category* D] [Preadditive D] [HasZeroObject D] [HasShift D ℤ] + [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + {E : Type*} [Category* E] [HasShift E ℤ] namespace ObjectProperty @@ -250,6 +254,37 @@ lemma trW_iff_of_distinguished · intro h exact ⟨_, _, _, hT, h⟩ +lemma trW_iff_of_distinguished' [P.IsStableUnderShift ℤ] + [P.IsClosedUnderIsomorphisms] (T : Triangle C) (hT : T ∈ distTriang C) : + P.trW T.mor₂ ↔ P T.obj₁ := by + simpa [P.prop_shift_iff_of_isStableUnderShift] + using P.trW_iff_of_distinguished _ (rot_of_distTriang _ hT) + +section + +variable (F : D ⥤ C) [F.CommShift ℤ] [F.IsTriangulated] + [P.IsClosedUnderIsomorphisms] + +instance [P.IsTriangulated] : (P.inverseImage F).IsTriangulated where + toIsTriangulatedClosed₂ := .mk' (fun T hT h₁ h₃ ↦ + P.ext_of_isTriangulatedClosed₂ _ (F.map_distinguished T hT) h₁ h₃) + +lemma inverseImage_trW_iff {X Y : D} (s : X ⟶ Y) : + (P.inverseImage F).trW s ↔ P.trW (F.map s) := by + obtain ⟨Z, g, h, hT⟩ := distinguished_cocone_triangle s + have eq₁ := (P.inverseImage F).trW_iff_of_distinguished _ hT + have eq₂ := P.trW_iff_of_distinguished _ (F.map_distinguished _ hT) + dsimp at eq₁ eq₂ + rw [eq₁, prop_inverseImage_iff, eq₂] + +lemma inverseImage_trW_isInverted {E : Type*} [Category E] + (L : C ⥤ E) [L.IsLocalization P.trW] : + (P.inverseImage F).trW.IsInvertedBy (F ⋙ L) := + fun X Y f hf => Localization.inverts L P.trW (F.map f) + (by simpa only [inverseImage_trW_iff] using hf) + +end + instance [IsTriangulated C] [P.IsTriangulated] : P.trW.HasLeftCalculusOfFractions where exists_leftFraction X Y φ := by obtain ⟨Z, f, g, H, mem⟩ := φ.hs @@ -296,6 +331,108 @@ instance [IsTriangulated C] [P.IsTriangulated] : P.trW.IsCompatibleWithTriangula exact ⟨φ.hom₃, P.trW.comp_mem _ _ (trW.mk P H.mem mem₄') (trW.mk' P H'.mem mem₅'), by simpa [φ] using φ.comm₂, by simpa [φ] using φ.comm₃⟩⟩ +instance (P' : ObjectProperty C) [P.IsTriangulatedClosed₂] [P.IsClosedUnderIsomorphisms] + [P'.IsTriangulatedClosed₂] : + (P ⊓ P').IsTriangulatedClosed₂ where + ext₂' T hT h₁ h₃ := by + obtain ⟨X₂, h₂, ⟨e⟩⟩ := P'.ext_of_isTriangulatedClosed₂' T hT h₁.2 h₃.2 + exact ⟨X₂, ⟨P.prop_of_iso e (P.ext_of_isTriangulatedClosed₂ T hT h₁.1 h₃.1), h₂⟩, ⟨e⟩⟩ + +instance (P' : ObjectProperty C) [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] + [P'.IsTriangulated] : + (P ⊓ P').IsTriangulated where + +instance [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] : + P.IsClosedUnderBinaryProducts where + limitsOfShape_le := by + rintro X ⟨p⟩ + refine P.prop_of_iso ?_ (P.ext_of_isTriangulatedClosed₂ _ + (binaryProductTriangle_distinguished _ _) + (p.prop_diag_obj (.mk .left)) (p.prop_diag_obj (.mk .right))) + exact IsLimit.conePointUniqueUpToIso (prodIsProd _ _) + ((IsLimit.postcomposeHomEquiv (diagramIsoPair p.diag) _).2 p.isLimit) + +instance [P.IsTriangulated] [P.IsClosedUnderIsomorphisms] : + P.IsClosedUnderFiniteProducts := .mk' + +instance [P.IsTriangulated] : P.trW.IsStableUnderFiniteProducts := by + rw [← trW_isoClosure] + exact ⟨fun J _ => by + refine MorphismProperty.IsStableUnderProductsOfShape.mk _ _ ?_ + intro _ _ X₁ X₂ f hf + exact trW.mk _ (productTriangle_distinguished _ + (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose)) + (P.isoClosure.prop_pi _ + (fun j => (hf j).choose_spec.choose_spec.choose_spec.choose_spec))⟩ + +section + +variable [P.IsTriangulated] + +noncomputable instance : Pretriangulated P.FullSubcategory where + distinguishedTriangles T := P.ι.mapTriangle.obj T ∈ distTriang C + isomorphic_distinguished T₁ hT₁ T₂ e := + isomorphic_distinguished _ hT₁ _ (P.ι.mapTriangle.mapIso e) + contractible_distinguished X := + isomorphic_distinguished _ (contractible_distinguished (P.ι.obj X)) _ + (Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) P.ι.mapZeroObject) + distinguished_cocone_triangle {X Y} f := by + obtain ⟨Z', g', h', mem⟩ := distinguished_cocone_triangle (P.ι.map f) + obtain ⟨Z'', hZ'', ⟨e⟩⟩ := P.ext_of_isTriangulatedClosed₃' _ mem X.2 Y.2 + exact ⟨⟨Z'', hZ''⟩, P.fullyFaithfulι.preimage (g' ≫ e.hom), + P.fullyFaithfulι.preimage (e.inv ≫ h' ≫ (P.ι.commShiftIso (1 : ℤ)).inv.app X), + isomorphic_distinguished _ mem _ (Triangle.isoMk _ _ (Iso.refl _) (Iso.refl _) e.symm)⟩ + rotate_distinguished_triangle T := + (rotate_distinguished_triangle (P.ι.mapTriangle.obj T)).trans + (distinguished_iff_of_iso (P.ι.mapTriangleRotateIso.app T)) + complete_distinguished_triangle_morphism T₁ T₂ hT₁ hT₂ a b comm := by + obtain ⟨c, ⟨hc₁, hc₂⟩⟩ := complete_distinguished_triangle_morphism (P.ι.mapTriangle.obj T₁) + (P.ι.mapTriangle.obj T₂) hT₁ hT₂ (P.ι.map a) (P.ι.map b) + (by simpa using P.ι.congr_map comm) + refine ⟨P.fullyFaithfulι.preimage c, ⟨by cat_disch, ?_⟩⟩ + ext + have := P.ι.commShiftIso_hom_naturality a (1 : ℤ) + rw [← cancel_mono ((Functor.commShiftIso P.ι (1 : ℤ)).hom.app T₂.obj₁)] + cat_disch + +instance : P.ι.IsTriangulated where + map_distinguished _ hT := hT + +instance [IsTriangulated C] : IsTriangulated P.FullSubcategory := + IsTriangulated.of_fully_faithful_triangulated_functor P.ι + +instance (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] : + (F.essImage).IsTriangulated where + isStableUnderShiftBy n := + { le_shift := by + rintro Y ⟨X, ⟨e⟩⟩ + exact ⟨X⟦n⟧, ⟨(F.commShiftIso n).app _ ≪≫ (shiftFunctor D n).mapIso e⟩⟩ } + exists_zero := ⟨0, isZero_zero D, ⟨0, ⟨F.mapZeroObject⟩⟩⟩ + toIsTriangulatedClosed₂ := .mk' (by + rintro T hT ⟨X₁, ⟨e₁⟩⟩ ⟨X₃, ⟨e₃⟩⟩ + have ⟨h, hh⟩ := F.map_surjective (e₃.hom ≫ T.mor₃ ≫ e₁.inv⟦1⟧' ≫ + (F.commShiftIso (1 : ℤ)).inv.app X₁) + obtain ⟨X₂, f, g, H⟩ := distinguished_cocone_triangle₂ h + exact ⟨X₂, ⟨Triangle.π₂.mapIso + (isoTriangleOfIso₁₃ _ _ (F.map_distinguished _ H) hT e₁ e₃ + (by simp [hh, ← Functor.map_comp]))⟩⟩) + +instance isTriangulated_lift (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) + [Preadditive E] [F.CommShift ℤ] [HasZeroObject E] + [∀ (n : ℤ), (shiftFunctor E n).Additive] [Pretriangulated E] [F.IsTriangulated] : + (P.lift F hF).IsTriangulated := by + rw [Functor.isTriangulated_iff_comp_right (P.liftCompιIso F hF)] + infer_instance + +instance {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] + [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] : + (P.map F).IsTriangulated := by + rw [← F.essImage_ι_comp] + infer_instance + +end + end ObjectProperty namespace Triangulated From 053068299741ec875a10b75557456aacaad3541c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 13:54:31 +0100 Subject: [PATCH 44/72] fix --- Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean | 5 +++++ Mathlib/CategoryTheory/Triangulated/Subcategory.lean | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean b/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean index 924388ab5a17ac..42e763d05742bb 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/LimitsOfShape.lean @@ -206,6 +206,11 @@ lemma prop_limit (F : J ⥤ C) [HasLimit F] (hF : ∀ (j : J), P (F.obj j)) : end +lemma prop_pi {J : Type*} [P.IsClosedUnderLimitsOfShape (Discrete J)] (X : J → C) + [HasProduct X] (hF : ∀ (j : J), P (X j)) : + P (∏ᶜ X) := + P.prop_of_isLimit (productIsProduct X) (fun _ ↦ hF _) + variable {J} in lemma limitsOfShape_le_of_initial (G : J ⥤ J') [G.Initial] : P.limitsOfShape J' ≤ P.limitsOfShape J := diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index f33d26a9fe655a..5a6132cd27e033 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -21,10 +21,8 @@ subcategory, we introduce a class of morphisms `P.trW : MorphismProperty C` consisting of the morphisms whose "cone" belongs to `P` (up to isomorphisms), and we show that it has both calculus of left and right fractions. -## TODO - -* show that the fullsubcategory attached to `P` (such that `P.IsTriangulated`) - is a pretriangulated category. +We also show that `P.FullSubcategory` is equipped with a pretriangulated structure, +which is triangulated if `C` is. ## Implementation notes From 859e44e3c8dd239d6e454987cbb9dffb6e6e7000 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 14:15:17 +0100 Subject: [PATCH 45/72] to_dual --- Mathlib/Order/WithBotTop.lean | 42 ++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean index 33d2356c746ddc..ddee2bb3e2e71c 100644 --- a/Mathlib/Order/WithBotTop.lean +++ b/Mathlib/Order/WithBotTop.lean @@ -21,20 +21,26 @@ variable {ι : Type*} variable (ι) in /-- The type obtained by adding both `⊥` and `⊤` to a type. -/ +@[to_dual] abbrev WithBotTop := WithBot (WithTop ι) /-- The canonical inclusion `ι → WithBotTop ι`. Registered as a coercion. -/ -@[coe] def WithBotTop.coe : ι → WithBotTop ι := WithBot.some ∘ WithTop.some +@[to_dual (attr := coe)] def WithBotTop.coe : ι → WithBotTop ι := + WithBot.some ∘ WithTop.some namespace WithBotTop instance : Coe ι (WithBotTop ι) := ⟨WithBotTop.coe⟩ +@[to_dual] theorem coe_injective : Function.Injective (WithBotTop.coe : ι → _) := by rintro _ _ ⟨⟩; rfl -@[simp] lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ -@[simp] lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ -@[simp] lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[to_dual (attr := simp)] +lemma coe_ne_bot (a : ι) : (a : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ +@[to_dual (attr := simp)] +lemma coe_ne_top (a : ι) : (a : WithBotTop ι) ≠ ⊤ := by rintro ⟨⟩ +@[to_dual (attr := simp)] +lemma top_ne_bot : (⊤ : WithBotTop ι) ≠ ⊥ := by rintro ⟨⟩ section @@ -42,37 +48,47 @@ variable {motive : (WithBotTop ι) → Sort*} (bot : motive ⊥) (coe : ∀ a : ι, motive a) (top : motive ⊤) /-- A recursor for `WithBotTop` in terms of the coercion. -/ -@[elab_as_elim] +@[to_dual (attr := elab_as_elim)] protected def rec : ∀ a, motive a | ⊥ => bot | (a : ι) => coe a | ⊤ => top -@[simp] lemma rec_bot : WithBotTop.rec (motive := motive) bot coe top ⊥ = bot := rfl -@[simp] lemma rec_coe (a : ι) : WithBotTop.rec (motive := motive) bot coe top a = coe a := rfl -@[simp] lemma rec_top : WithBotTop.rec (motive := motive) bot coe top ⊤ = top := rfl +@[to_dual (attr := simp)] +lemma rec_bot : WithBotTop.rec (motive := motive) bot coe top ⊥ = bot := rfl +@[to_dual (attr := simp)] +lemma rec_coe (a : ι) : WithBotTop.rec (motive := motive) bot coe top a = coe a := rfl +@[to_dual (attr := simp)] +lemma rec_top : WithBotTop.rec (motive := motive) bot coe top ⊤ = top := rfl end -@[simp] +@[to_dual (attr := simp)] lemma coe_le_coe [LE ι] {a b : ι} : (a : WithBotTop ι) ≤ b ↔ a ≤ b := by rw [← WithTop.coe_le_coe (α := ι)] exact WithBot.coe_le_coe -@[simp] +@[to_dual (attr := simp)] lemma coe_lt_coe [LT ι] {a b : ι} : (a : WithBotTop ι) < b ↔ a < b := by rw [← WithTop.coe_lt_coe (α := ι)] exact WithBot.coe_lt_coe +@[to_dual (attr := simp)] theorem coe_strictMono [Preorder ι] : StrictMono (WithBotTop.coe : ι → _) := WithBot.coe_strictMono.comp WithTop.coe_strictMono -lemma coe_monotone [Preorder ι] : Monotone (WithBotTop.coe : ι → _) := +lemma coe_monotone [Preorder ι] : + Monotone (WithBotTop.coe : ι → _) := + fun _ _ _ ↦ by simpa only [coe_le_coe] + +end WithBotTop + +@[to_dual existing] +lemma WithTopBot.coe_monotone [Preorder ι] : + Monotone (WithTopBot.coe : ι → _) := fun _ _ _ ↦ by simpa /-- The type of extended integers `[-∞, ∞]`, constructed as `WithBot (WithTop ℤ)`. -/ abbrev EInt := WithBotTop ℤ - -end WithBotTop From c82779470aae4d7972b0224f2b0982eb756dab0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 14:21:23 +0100 Subject: [PATCH 46/72] better syntax --- Mathlib/Order/WithBotTop.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean index ddee2bb3e2e71c..8018f1481a7d19 100644 --- a/Mathlib/Order/WithBotTop.lean +++ b/Mathlib/Order/WithBotTop.lean @@ -81,7 +81,7 @@ theorem coe_strictMono [Preorder ι] : StrictMono (WithBotTop.coe : ι → _) := lemma coe_monotone [Preorder ι] : Monotone (WithBotTop.coe : ι → _) := - fun _ _ _ ↦ by simpa only [coe_le_coe] + fun _ _ _ ↦ by simpa end WithBotTop From 20b7b2b4e2d3d825fc56b960c3797fe878bb7875 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 24 Jan 2026 22:18:57 +0100 Subject: [PATCH 47/72] docstrings --- Mathlib/Order/WithBotTop.lean | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Mathlib/Order/WithBotTop.lean b/Mathlib/Order/WithBotTop.lean index 8018f1481a7d19..f7f95aada42213 100644 --- a/Mathlib/Order/WithBotTop.lean +++ b/Mathlib/Order/WithBotTop.lean @@ -21,11 +21,13 @@ variable {ι : Type*} variable (ι) in /-- The type obtained by adding both `⊥` and `⊤` to a type. -/ -@[to_dual] +@[to_dual /-- The type obtained by adding both `⊤` and `⊥` to a type. -/] abbrev WithBotTop := WithBot (WithTop ι) /-- The canonical inclusion `ι → WithBotTop ι`. Registered as a coercion. -/ -@[to_dual (attr := coe)] def WithBotTop.coe : ι → WithBotTop ι := +@[to_dual (attr := coe) + /-- The canonical inclusion `ι → WithTopBot ι`. Registered as a coercion. -/] +def WithBotTop.coe : ι → WithBotTop ι := WithBot.some ∘ WithTop.some namespace WithBotTop @@ -48,7 +50,8 @@ variable {motive : (WithBotTop ι) → Sort*} (bot : motive ⊥) (coe : ∀ a : ι, motive a) (top : motive ⊤) /-- A recursor for `WithBotTop` in terms of the coercion. -/ -@[to_dual (attr := elab_as_elim)] +@[to_dual (attr := elab_as_elim) + /-- A recursor for `WithTopBot` in terms of the coercion. -/] protected def rec : ∀ a, motive a | ⊥ => bot | (a : ι) => coe a From 562178987415120423c89cb4cb9c1dbd79be4443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 12:30:29 +0100 Subject: [PATCH 48/72] fix --- Mathlib/CategoryTheory/Triangulated/Subcategory.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index 5a6132cd27e033..582df463ec9e58 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -424,7 +424,7 @@ instance isTriangulated_lift (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) instance {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] : + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] : (P.map F).IsTriangulated := by rw [← F.essImage_ι_comp] infer_instance From f832a5fb5b9bfc672b01b6bf21ca3c450f3af453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 12:41:58 +0100 Subject: [PATCH 49/72] typo --- .../SpectralObject/SpectralSequence.lean | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index 3f967f7f29919e..a3719406858db6 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -13,6 +13,25 @@ public import Mathlib.Order.WithBotTop /-! # The spectral sequence of a spectral object +The main definition in this file is `Abelian.SpectralObject.spectralSequence`. +Assume that `X` is a spectral object indexed by `ι` in an abelian category `C`, +and that we have `data : SpectralSequenceMkData ι c r₀` a family +of complexes shapes `c : ℤ → ComplexShape κ` for a type `κ` and `r₀ : ℤ`. +Then, under the assumption `X.HasSpectralSequence data` (see the file +`Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean`), +we obtain `X.spectralSequence data` which is a spectral sequence starting +on page `r₀`, such that the `r`th page (for `r₀ ≤ r`) is a homological +complex of shape `c r`. + +In particular, when `X` is a spectral object indexed by the extended +integers `EInt`, we obtain the `E₂`-cohomological spectral sequence +`X.E₂SpectralSequence` where the objects of each page are indexed by +`ℤ × ℤ` (the condition `HasSpectralSequence` is automatically satisfied). +Under the `X.IsFirstQuadrant` assumption, we obtain +`X.E₂SpectralSequenceNat` which is a first quadrant `E₂`-spectral +sequence (the objects in the pages are indexed by `ℕ × ℕ` instead +of `ℤ × ℤ`). + -/ @[expose] public section @@ -190,17 +209,17 @@ lemma kf_w : erw [EMap_fourδ₁Toδ₀_d_assoc, zero_comp] · rw [HomologicalComplex.shape _ _ _ h, comp_zero] -@[simp] -noncomputable def kf : KernelFork ((page X data r hr).d pq' pq'') := +noncomputable abbrev kf : + KernelFork ((page X data r hr).d pq' pq'') := KernelFork.ofι _ (kf_w X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) @[simps!] -noncomputable def ksSc : ShortComplex C := +noncomputable def kfSc : ShortComplex C := ShortComplex.mk _ _ (kf_w X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) -instance : Mono (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' +instance : Mono (kfSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).f := by dsimp infer_instance @@ -220,7 +239,7 @@ lemma isIso_EMapFourδ₁Toδ₀' (h : ¬ (c r).Rel pq' pq'') : variable [X.HasSpectralSequence data] in include hpq' in -lemma ksSc_exact : (ksSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' +lemma kfSc_exact : (kfSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).Exact := by by_cases h : (c r).Rel pq' pq'' · refine ShortComplex.exact_of_iso (Iso.symm ?_) @@ -253,7 +272,7 @@ variable [X.HasSpectralSequence data] in noncomputable def hkf : IsLimit (kf X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) := - (ksSc_exact X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + (kfSc_exact X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).fIsKernel lemma cc_w : @@ -273,8 +292,8 @@ lemma cc_w : rw [comp_zero] · rw [HomologicalComplex.shape _ _ _ h, zero_comp] -@[simp] -noncomputable def cc : CokernelCofork ((page X data r hr).d pq pq') := +noncomputable abbrev cc : + CokernelCofork ((page X data r hr).d pq pq') := CokernelCofork.ofπ _ (cc_w X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') From a563684a52aadb1bb262aa48bcfb84466f3a2148 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 12:45:50 +0100 Subject: [PATCH 50/72] wip --- .../Algebra/Homology/SpectralObject/SpectralSequence.lean | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index a3719406858db6..6f2836dfd24e56 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -205,8 +205,7 @@ lemma kf_w : (homOfLE (by simpa only [hi₀', data.i₀_prev r r' _ _ h] using data.le₀₁ r pq'')) (homOfLE (data.le₀'₀ hrr' hr pq' hi₀' hi₀)) _ _ _ hn₁' rfl (by rw [hi₀', data.i₀_prev r r' pq' pq'' h]) hi₀ hi₁ hi₂ hi₃, - Category.assoc, Iso.inv_hom_id_assoc] - erw [EMap_fourδ₁Toδ₀_d_assoc, zero_comp] + Category.assoc, Iso.inv_hom_id_assoc, EMap_fourδ₁Toδ₀_d_assoc, zero_comp] · rw [HomologicalComplex.shape _ _ _ h, comp_zero] noncomputable abbrev kf : @@ -287,9 +286,7 @@ lemma cc_w : (homOfLE (by simpa only [hi₃', data.i₃_next r r' _ _ h] using data.le₂₃ r pq)) (by have := data.hc r pq pq' h; lia) hi₀ hi₁ (by rw [hi₂, data.hc₀₂ r _ _ h]) (by rw [hi₃, data.hc₁₃ r _ _ h]) (by rw [hi₃', data.i₃_next r r' _ _ h]) rfl, - Category.assoc, Category.assoc, Iso.inv_hom_id_assoc] - erw [d_EMap_fourδ₄Toδ₃] - rw [comp_zero] + Category.assoc, Category.assoc, Iso.inv_hom_id_assoc, d_EMap_fourδ₄Toδ₃, comp_zero] · rw [HomologicalComplex.shape _ _ _ h, zero_comp] noncomputable abbrev cc : From b6fb660bc41dbaa82f0ffb832ca6ee63f0d0e595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 12:51:08 +0100 Subject: [PATCH 51/72] fix --- Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean b/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean index 18152089b3e559..bde6568077e232 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean @@ -246,13 +246,9 @@ noncomputable abbrev EMapFourδ₂Toδ₁' := lemma isIso_EMapFourδ₂Toδ₁' (h₁ : IsIso ((X'.H n₁).map (twoδ₁Toδ₀' i₁ i₂ i₃ hi₁₂ hi₂₃))) (h₂ : IsIso ((X'.H n₂).map (twoδ₂Toδ₁' i₀ i₁ i₂ hi₀₁ hi₁₂))) : - IsIso (X'.EMapFourδ₂Toδ₁' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := by - apply X'.isIso_EMap - · dsimp - erw [Functor.map_id] - infer_instance - · exact h₁ - · exact h₂ + IsIso (X'.EMapFourδ₂Toδ₁' n₀ n₁ n₂ hn₁ hn₂ i₀ i₁ i₂ i₃ i₄ hi₀₁ hi₁₂ hi₂₃ hi₃₄) := + X'.isIso_EMap _ _ _ _ _ _ _ _ _ _ _ _ + (inferInstanceAs (IsIso ((X'.H n₀).map (𝟙 _)))) h₁ h₂ end From f166e47df7a80b62594ee5ca8081549b29779324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 12:57:06 +0100 Subject: [PATCH 52/72] typo --- Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index 6f2836dfd24e56..1837812798749a 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -138,7 +138,7 @@ noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : section -/-- The short complexe of the `r`th page of the spectral sequence on position `pq'` +/-- The short complex of the `r`th page of the spectral sequence on position `pq'` identifies to the short complex given by the differentials of the spectral object. -/ noncomputable def shortComplexIso (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) (hpq : (c r).Rel pq pq') (hpq' : (c r).Rel pq' pq'') From 150589829ccd1d824ba05f89a22c6d41584f757b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 13:09:12 +0100 Subject: [PATCH 53/72] wip --- .../Algebra/Homology/SpectralObject/SpectralSequence.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index 1837812798749a..0f33cf0e91eed4 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -301,9 +301,8 @@ noncomputable def ccSc : ShortComplex C := instance : Epi (ccSc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').g := by - refine @epi_comp _ _ _ _ _ _ inferInstance _ ?_ - apply epi_EMap - all_goals rfl + dsimp + infer_instance variable [X.HasSpectralSequence data] in include hpq hn₁' in @@ -400,7 +399,7 @@ noncomputable def homologyIso' : to the objects on the next page. -/ noncomputable def homologyIso : (page X data r hr).homology pq' ≅ - (page X data r' (hr.trans (by rw [← hrr']; exact Int.le.intro 1 rfl))).X pq' := + (page X data r' (hr.trans (by lia))).X pq' := homologyIso' X data r r' hrr' hr _ pq' _ rfl rfl (data.deg pq' - 1) (data.deg pq') (data.deg pq' + 1) (by simp) rfl rfl _ _ _ _ _ _ rfl rfl rfl rfl rfl rfl @@ -484,6 +483,7 @@ lemma isZero_spectralSequence_page_X_of_isZero_H' (r : ℤ) (hr : r₀ ≤ r) X.isZero_spectralSequence_page_X_of_isZero_H data r hr pq _ rfl _ _ rfl rfl h section + variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq pq' pq'' : κ) (hpq : (c r).prev pq' = pq) (hpq' : (c r).next pq' = pq'') (n₀ n₁ n₂ : ℤ) (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) From b1848e2428b22d49155062380db24974356061c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 14:23:33 +0100 Subject: [PATCH 54/72] cleaning up --- .../SpectralObject/SpectralSequence.lean | 115 ++++++++++++++++-- 1 file changed, 105 insertions(+), 10 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index 0f33cf0e91eed4..5ea9c99b4b6f2f 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -15,7 +15,7 @@ public import Mathlib.Order.WithBotTop The main definition in this file is `Abelian.SpectralObject.spectralSequence`. Assume that `X` is a spectral object indexed by `ι` in an abelian category `C`, -and that we have `data : SpectralSequenceMkData ι c r₀` a family +and that we have `data : SpectralSequenceMkData ι c r₀` for a family of complexes shapes `c : ℤ → ComplexShape κ` for a type `κ` and `r₀ : ℤ`. Then, under the assumption `X.HasSpectralSequence data` (see the file `Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean`), @@ -23,8 +23,51 @@ we obtain `X.spectralSequence data` which is a spectral sequence starting on page `r₀`, such that the `r`th page (for `r₀ ≤ r`) is a homological complex of shape `c r`. -In particular, when `X` is a spectral object indexed by the extended -integers `EInt`, we obtain the `E₂`-cohomological spectral sequence +## Outline of the construction + +The construction of the spectral sequence is as follows. If `r₀ ≤ r` +and `pq : κ`, we define the object of the spectral sequence in position `pq` +on the `r`th page as `E^d(i₀ r pq ≤ i₁ pq ≤ i₂ pq ≤ i₃ r pq)` +where `d := data.deg pq` and the indices `i₀`, `i₁`, `i₂`, `i₃` are given +by data (they all depend on `pq`, and `i₀` and `i₃` also depend on the page `r`), +see `spectralSequencePageXIso`. + +When `(c r).Rel pq pq'`, the differential from the object in position `pq` +to the object in position `pq'` on the `r`th page can be related to +the differential `X.d` of the spectral object (see the lemma +`spectralSequence_page_d_eq`). Indeed, the assumptions that +are part of `data` give equalities of indices `i₂ r pq' = i₀ r pq` +and `i₃ pq' = i₁ pq`, so that we have a chain of inequalities +`i₀ r pq' ≤ i₁ pq' ≤ i₂ pq' ≤ i₃ r pq' ≤ i₂ pq ≤ i₄ r pq` for which +the API of spectral objects provides a differential +`X.d : E^n(i₀ r pq ≤ i₁ pq ≤ i₂ pq ≤ i₃ r pq) ⟶ E^{n + 1}(i₀ r pq' ≤ i₁ pq' ≤ i₂ pq' ≤ i₃ r pq')`. + +Now, fix `r` and three positions `pq`, `pq'` and `pq''` such that +`pq` is the previous object of `pq'` for `c r` and `pq''` is the next +object of `pq'`. (Note that in case there are no nontrivial differentials +to the object `pq'` for the complex shape `c r`, according to the homological +complex API, we have `pq = pq'` and the differential is zero. Similarly, +when there are no nontrivial differentials from the object in position `pq'`, +we have `pq'' = pq` and the corresponding differential is zero.) +In the favourable case where both `(c r).Rel pq pq'` and `(c r).Rel pq' pq''` +hold, the definitions `SpectralObject.SpectralSequence.shortComplexIso` and +`SpectralObject.spectralSequencePageSc'Iso` in this file can be +used in combination to `SpectralObject.SpectralSequence.dHomologyIso` in order to compute +the homology of the differentials.) + +In the general case, using the assumptions in `X.HasSpectralSequence data`, +we provide a limit kernel fork `kf` and +a limit cokernel cofork `cc` of the differentials on the `r`th page, +together with an epi-mono factorization `fac` which allows +to obtain that the homology of the `r`th page identifies to the homology +of the next page (see the definitions +`SpectralObject.SpectralSequence.homologyData` and +`SpectralObject.spectralSequenceHomologyData`). + +## Spectral objects indexed by `EInt`. + +When `X` is a spectral object indexed by the extended integers `EInt`, +we obtain the `E₂`-cohomological spectral sequence `X.E₂SpectralSequence` where the objects of each page are indexed by `ℤ × ℤ` (the condition `HasSpectralSequence` is automatically satisfied). Under the `X.IsFirstQuadrant` assumption, we obtain @@ -139,7 +182,11 @@ noncomputable def page (r : ℤ) (hr : r₀ ≤ r) : section /-- The short complex of the `r`th page of the spectral sequence on position `pq'` -identifies to the short complex given by the differentials of the spectral object. -/ +identifies to the short complex given by the differentials of the spectral object. +Then, the homology of this short complex can be computed using +`SpectralSequence.dHomologyIso`. +(This only applies in the favourable case when there are `pq` and `pq''` such +that `(c r).Rel pq pq'` and `(c r).Rel pq' pq''` hold.) -/ noncomputable def shortComplexIso (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) (hpq : (c r).Rel pq pq') (hpq' : (c r).Rel pq' pq'') (n₀ n₁ n₂ n₃ n₄ : ℤ) @@ -208,11 +255,14 @@ lemma kf_w : Category.assoc, Iso.inv_hom_id_assoc, EMap_fourδ₁Toδ₀_d_assoc, zero_comp] · rw [HomologicalComplex.shape _ _ _ h, comp_zero] +/-- A (limit) kernel fork of the differential on the `r`th page whose point +identifies to an object `X.E` -/ noncomputable abbrev kf : KernelFork ((page X data r hr).d pq' pq'') := KernelFork.ofι _ (kf_w X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) +/-- The (exact) short complex attached to the kernel fork `kf`. -/ @[simps!] noncomputable def kfSc : ShortComplex C := ShortComplex.mk _ _ (kf_w X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' @@ -265,10 +315,12 @@ lemma kfSc_exact : (kfSc X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ · exact (page X data r hr).shape _ _ h have := isIso_EMapFourδ₁Toδ₀' X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃ h - apply epi_comp + dsimp + infer_instance variable [X.HasSpectralSequence data] in -noncomputable def hkf : +/-- The kernel fork `kf` is a limit. -/ +noncomputable def isLimitKf : IsLimit (kf X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) := (kfSc_exact X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' @@ -289,11 +341,14 @@ lemma cc_w : Category.assoc, Category.assoc, Iso.inv_hom_id_assoc, d_EMap_fourδ₄Toδ₃, comp_zero] · rw [HomologicalComplex.shape _ _ _ h, zero_comp] +/-- A (limit) cokernel cofork of the differential on the `r`th page whose point +identifies to an object `X.E` -/ noncomputable abbrev cc : CokernelCofork ((page X data r hr).d pq pq') := CokernelCofork.ofπ _ (cc_w X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') +/-- The (exact) short complex attached to the cokernel cofork `cc`. -/ @[simps!] noncomputable def ccSc : ShortComplex C := ShortComplex.mk _ _ (cc_w X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' @@ -350,7 +405,8 @@ lemma ccSc_exact : infer_instance variable [X.HasSpectralSequence data] in -noncomputable def hcc : +/-- The cokernel cofork `cc` is a colimit. -/ +noncomputable def isColimitCc : IsColimit (cc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') := (ccSc_exact X data r r' hrr' hr pq pq' hpq n₀ n₁ n₂ hn₁ hn₂ hn₁' @@ -359,7 +415,7 @@ noncomputable def hcc : lemma fac : (kf X data r r' hrr' hr pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃).ι ≫ (cc X data r r' hrr' hr pq pq' n₀ n₁ n₂ hn₁ hn₂ hn₁' - i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').π = + i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃').π = X.EMapFourδ₄Toδ₃' n₀ n₁ n₂ hn₁ hn₂ i₀' i₁ i₂ i₃ i₃' _ _ _ (data.le₃₃' hrr' hr pq' hi₃ hi₃') ≫ X.EMapFourδ₁Toδ₀' n₀ n₁ n₂ hn₁ hn₂ i₀' i₀ i₁ i₂ i₃' (data.le₀'₀ hrr' hr pq' hi₀' hi₀) _ _ _ := by @@ -380,9 +436,9 @@ to an object on the next page. -/ noncomputable def homologyData : ((page X data r hr).sc' pq pq' pq'').HomologyData := ShortComplex.HomologyData.ofEpiMonoFactorisation ((page X data r hr).sc' pq pq' pq'') - (hkf X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' + (isLimitKf X data r r' hrr' hr pq' pq'' hpq' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ hi₀' hi₀ hi₁ hi₂ hi₃) - (hcc X data r r' hrr' hr pq pq' hpq n₀ n₁ n₂ hn₁ hn₂ hn₁' + (isColimitCc X data r r' hrr' hr pq pq' hpq n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀ i₁ i₂ i₃ i₃' hi₀ hi₁ hi₂ hi₃ hi₃') (fac X data r r' hrr' hr pq pq' pq'' n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃') @@ -482,6 +538,25 @@ lemma isZero_spectralSequence_page_X_of_isZero_H' (r : ℤ) (hr : r₀ ≤ r) IsZero (((X.spectralSequence data).page r).X pq) := X.isZero_spectralSequence_page_X_of_isZero_H data r hr pq _ rfl _ _ rfl rfl h +/-- The short complex of the `r`th page of the spectral sequence on position `pq'` +identifies to the short complex given by the differentials of the spectral object. +Then, the homology of this short complex can be computed using +`SpectralSequence.dHomologyIso`. +(This only applies in the favourable case when there are `pq` and `pq''` such +that `(c r).Rel pq pq'` and `(c r).Rel pq' pq''` hold.) -/ +noncomputable def spectralSequencePageSc'Iso (r : ℤ) (hr : r₀ ≤ r) (pq pq' pq'' : κ) + (hpq : (c r).Rel pq pq') (hpq' : (c r).Rel pq' pq'') + (n₀ n₁ n₂ n₃ n₄ : ℤ) + (hn₁ : n₀ + 1 = n₁) (hn₂ : n₁ + 1 = n₂) (hn₃ : n₂ + 1 = n₃) (hn₄ : n₃ + 1 = n₄) + (hn₂' : n₂ = data.deg pq') : + ((X.spectralSequence data).page r).sc' pq pq' pq'' ≅ + X.dShortComplex n₀ n₁ n₂ n₃ n₄ hn₁ hn₂ hn₃ hn₄ (homOfLE (data.le₀₁ r pq'')) + (homOfLE (data.le₁₂ pq'')) (homOfLE (data.le₂₃ r pq'')) + (homOfLE (by simpa only [← data.hc₁₃ r pq' pq'' hpq', data.hc₀₂ r pq pq' hpq] + using data.le₁₂ pq')) (homOfLE (data.le₀₁ r pq)) + (homOfLE (data.le₁₂ pq)) (homOfLE (data.le₂₃ r pq)) := + SpectralSequence.shortComplexIso _ _ _ hr _ _ _ hpq hpq' _ _ _ _ _ _ _ _ _ hn₂' + section variable (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) @@ -530,6 +605,26 @@ lemma spectralSequenceHomologyData_right_homologyIso_eq_left_homologyIso : ext1 simp [ShortComplex.HomologyData.right_homologyIso_eq_left_homologyIso_trans_iso] +lemma spectralSequence_iso : + (X.spectralSequence data).iso r r' pq' = + ((X.spectralSequence data).page r).homologyIsoSc' pq pq' pq'' hpq hpq' ≪≫ + (X.spectralSequenceHomologyData data r r' hrr' hr pq pq' pq'' hpq hpq' + n₀ n₁ n₂ hn₁ hn₂ hn₁' i₀' i₀ i₁ i₂ i₃ i₃' hi₀' hi₀ hi₁ hi₂ hi₃ hi₃').left.homologyIso ≪≫ + (X.spectralSequencePageXIso data r' (by lia) _ _ _ _ _ _ hn₁' _ _ _ _ + hi₀' hi₁ hi₂ hi₃').symm := by + obtain rfl : n₀ = n₁ - 1 := by lia + obtain rfl : n₂ = n₁ + 1 := by lia + subst hpq hpq' hn₁' hi₀ hi₁ hi₂ hi₃ hi₀' hi₃' + ext + dsimp [ + spectralSequencePageXIso, spectralSequence, + spectralSequenceHomologyData, + SpectralSequence.pageX, SpectralSequence.pageXIso, + SpectralSequence.homologyIso, SpectralSequence.homologyIso'] + rw [Category.comp_id] + convert (Category.id_comp _).symm + apply ShortComplex.homologyMap_id + end end From 95b1cf1e5a9b43f8fd30a5ac90d9c1da685b2e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 14:57:25 +0100 Subject: [PATCH 55/72] computation of the first page --- Mathlib.lean | 1 + .../Homology/SpectralObject/FirstPage.lean | 134 ++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean diff --git a/Mathlib.lean b/Mathlib.lean index 46fad692c243ba..5887d489f248c7 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -655,6 +655,7 @@ public import Mathlib.Algebra.Homology.SpectralObject.Basic public import Mathlib.Algebra.Homology.SpectralObject.Cycles public import Mathlib.Algebra.Homology.SpectralObject.Differentials public import Mathlib.Algebra.Homology.SpectralObject.EpiMono +public import Mathlib.Algebra.Homology.SpectralObject.FirstPage public import Mathlib.Algebra.Homology.SpectralObject.HasSpectralSequence public import Mathlib.Algebra.Homology.SpectralObject.Homology public import Mathlib.Algebra.Homology.SpectralObject.Page diff --git a/Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean b/Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean new file mode 100644 index 00000000000000..c1f0e39d7830a1 --- /dev/null +++ b/Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean @@ -0,0 +1,134 @@ +/- +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.SpectralObject.SpectralSequence + +/-! +# The first page of the spectral sequence of a spectral object + +Let `ι` be a preordered type, `X` a spectral object in an abelian +category indexed by `ι`. Let `data : SpectralSequenceMkData ι c r₀`. +Assume that `X.HasSpectralSequence data` holds. In this file, +we introduce a property `data.HasFirstPageComputation` which allows +to "compute" the objects of the `r₀`th page of the spectral +sequence attached to `X` in terms of objects of the form `X.H`, +and we compute the differential on the first page in terms of `X.δ`. + +-/ + +@[expose] public section + +namespace CategoryTheory + +open Category ComposableArrows + +namespace Abelian + +namespace SpectralObject + +variable {C ι κ : Type*} [Category C] [Abelian C] [Preorder ι] + (X : SpectralObject C ι) + {c : ℤ → ComplexShape κ} {r₀ : ℤ} + (data : SpectralSequenceMkData ι c r₀) + +namespace SpectralSequenceMkData + +/-- Given `data : SpectralSequenceMkData ι c r₀`, this is the property +that on the page `r₀`, indices `i₀` and `i₁` are equal, +and indices `i₂` and `i₃` are equal. This condition allows +to express the objects of the `r₀`th page of the spectral sequences +obtained using a spectral object `X` indexed by `ι` and `data` as objects +of the form `X.H`, see `SpectralObject.spectralSequenceFirstPageXIso`. -/ +class HasFirstPageComputation : Prop where + hi₀₁ (pq : κ) : data.i₀ r₀ pq = data.i₁ pq + hi₂₃ (pq : κ) : data.i₂ pq = data.i₃ r₀ pq + +export HasFirstPageComputation (hi₀₁ hi₂₃) + +instance : mkDataE₂Cohomological.HasFirstPageComputation where + hi₀₁ pq := by dsimp; congr 1; lia + hi₂₃ pq := by dsimp; congr 1; lia + +instance : mkDataE₂CohomologicalNat.HasFirstPageComputation where + hi₀₁ pq := by dsimp; congr 1; lia + hi₂₃ pq := by dsimp; congr 1; lia + +instance : mkDataE₂HomologicalNat.HasFirstPageComputation where + hi₀₁ pq := by dsimp; congr 1; lia + hi₂₃ pq := by dsimp; congr 1; lia + +end SpectralSequenceMkData + +variable [data.HasFirstPageComputation] [X.HasSpectralSequence data] + +/-- If `data : SpectralSequenceMkData ι c r₀` is such that +`data.HasFirstPageComputation` holds, this is an isomorphisms which +allows to "compute" the objects on the `r₀`th page of the spectral sequence +obtained from a spectral object `X` indexed by `i` using data as objects +of the form `X.H`. See also `spectralSequence_first_page_d_eq` for the relation +between the differentials of the first page of the spectral sequence and `X.δ`. +-/ +noncomputable def spectralSequenceFirstPageXIso (pq : κ) (n : ℤ) (hn : n = data.deg pq) + (i₁ i₂ : ι) (hi₁ : i₁ = data.i₁ pq) (hi₂ : i₂ = data.i₂ pq) : + ((X.spectralSequence data).page r₀).X pq ≅ + (X.H n).obj (mk₁ (homOfLE (by grind [data.le₁₂ pq]) : i₁ ⟶ i₂)) := + X.spectralSequencePageXIso data _ (by rfl) _ _ _ _ _ _ hn _ _ _ _ + (by rw [hi₁, ← data.hi₀₁]) hi₁ hi₂ (by rw [hi₂, data.hi₂₃]) ≪≫ + X.EIsoH (n - 1) n (n + 1) (by simp) rfl (homOfLE _) + +@[reassoc] +lemma spectralSequenceFirstPageXIso_hom (pq : κ) (n : ℤ) (hn : n = data.deg pq) + (i₁ i₂ : ι) (hi₁ : i₁ = data.i₁ pq) (hi₂ : i₂ = data.i₂ pq) + (n₀ n₂ : ℤ) (hn₀ : n₀ + 1 = n) (hn₂ : n + 1 = n₂) : + (X.spectralSequenceFirstPageXIso data pq n hn i₁ i₂ hi₁ hi₂).hom = + (X.spectralSequencePageXIso data r₀ (by rfl) _ _ _ _ _ _ hn _ _ _ _ + (by rw [hi₁, ← data.hi₀₁]) hi₁ hi₂ (by rw [hi₂, data.hi₂₃])).hom ≫ + (X.EIsoH n₀ n n₂ hn₀ hn₂ _).hom := by + obtain rfl : n₀ = n - 1 := by lia + obtain rfl := hn₂ + rfl + +@[reassoc] +lemma spectralSequenceFirstPageXIso_inv (pq : κ) (n : ℤ) (hn : n = data.deg pq) + (i₁ i₂ : ι) (hi₁ : i₁ = data.i₁ pq) (hi₂ : i₂ = data.i₂ pq) + (n₀ n₂ : ℤ) (hn₀ : n₀ + 1 = n) (hn₂ : n + 1 = n₂) : + (X.spectralSequenceFirstPageXIso data pq n hn i₁ i₂ hi₁ hi₂).inv = + (X.EIsoH n₀ n n₂ hn₀ hn₂ _).inv ≫ + (X.spectralSequencePageXIso data r₀ (by rfl) _ _ _ _ _ _ hn _ _ _ _ + (by rw [hi₁, ← data.hi₀₁]) hi₁ hi₂ (by rw [hi₂, data.hi₂₃])).inv := by + obtain rfl : n₀ = n - 1 := by lia + obtain rfl := hn₂ + rfl + +lemma spectralSequence_first_page_d_eq (pq pq' : κ) + (hpq : (c r₀).Rel pq pq') (n n' : ℤ) (hn : n = data.deg pq) + (hn' : n + 1 = n') (i j k : ι) + (hi : i = data.i₁ pq') (hj : j = data.i₁ pq) (hk : k = data.i₂ pq) : + ((X.spectralSequence data).page r₀).d pq pq' = + (X.spectralSequenceFirstPageXIso data pq n hn j k hj hk).hom ≫ + X.δ n n' hn' (homOfLE + (by simpa only [hi, hj, data.hc₁₃ r₀ pq pq' hpq, ← data.hi₂₃ pq'] + using data.le₁₂ pq') : i ⟶ j) + (homOfLE (by simpa only [hj, hk] using data.le₁₂ pq) : j ⟶ k) ≫ + (X.spectralSequenceFirstPageXIso data pq' n' + (by rw [← hn', hn, data.hc r₀ pq pq' hpq]) + i j hi (by rw [hj, ← data.hc₀₂ r₀ pq pq' hpq, data.hi₀₁ pq])).inv := by + simp only [assoc, X.spectralSequenceFirstPageXIso_hom data pq n hn + j k hj hk (n - 1) n' (by simp) hn', + ← X.d_EIsoH_hom_assoc (n - 1) n n' (n' + 1) (by simp) hn' rfl, + X.spectralSequenceFirstPageXIso_inv data pq' n' + (by rw [← hn', hn, data.hc r₀ pq pq' hpq]) i j hi + (by rw [hj, data.hi₂₃, data.hc₁₃ r₀ pq pq' hpq]) n (n' + 1) hn' rfl, + Iso.hom_inv_id_assoc] + apply spectralSequence_page_d_eq + exact hpq + +end SpectralObject + +end Abelian + +end CategoryTheory From c4aed581d7a667c327df0c04520308ca89583b64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 16:50:53 +0100 Subject: [PATCH 56/72] wip --- Mathlib/CategoryTheory/Triangulated/Subcategory.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index f33d26a9fe655a..40b9b53d632a33 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -426,7 +426,7 @@ instance isTriangulated_lift (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) instance {D : Type*} [Category D] [HasZeroObject D] [Preadditive D] [HasShift D ℤ] [∀ (n : ℤ), (shiftFunctor D n).Additive] [Pretriangulated D] - (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] [F.Faithful] : + (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] : (P.map F).IsTriangulated := by rw [← F.essImage_ι_comp] infer_instance From dfc88e0648adddb7f3904ec15ca49a7b694b208e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 17:13:47 +0100 Subject: [PATCH 57/72] split files --- Mathlib.lean | 1 + .../CategoryTheory/ObjectProperty/Shift.lean | 6 --- .../ObjectProperty/ShiftAdditive.lean | 38 +++++++++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 Mathlib/CategoryTheory/ObjectProperty/ShiftAdditive.lean diff --git a/Mathlib.lean b/Mathlib.lean index e1548e4d49d742..0bf62dda9a6338 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -2952,6 +2952,7 @@ 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.ShiftAdditive public import Mathlib.CategoryTheory.ObjectProperty.SiteLocal public import Mathlib.CategoryTheory.ObjectProperty.Small public import Mathlib.CategoryTheory.Opposites diff --git a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean index 1077a32348b9ad..6317221f7193be 100644 --- a/Mathlib/CategoryTheory/ObjectProperty/Shift.lean +++ b/Mathlib/CategoryTheory/ObjectProperty/Shift.lean @@ -6,7 +6,6 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.ObjectProperty.ClosedUnderIsomorphisms -public import Mathlib.CategoryTheory.Preadditive.AdditiveFunctor public import Mathlib.CategoryTheory.Shift.CommShift /-! @@ -108,11 +107,6 @@ instance commShiftι : P.ι.CommShift A := -- these definitions are made irreducible to prevent any abuse of defeq attribute [irreducible] hasShift commShiftι -instance [Preadditive C] (n : A) [(shiftFunctor C n).Additive] : - (shiftFunctor P.FullSubcategory n).Additive := by - have := Functor.additive_of_iso (P.ι.commShiftIso n).symm - apply Functor.additive_of_comp_faithful _ P.ι - section variable (F : E ⥤ C) (hF : ∀ (X : E), P (F.obj X)) diff --git a/Mathlib/CategoryTheory/ObjectProperty/ShiftAdditive.lean b/Mathlib/CategoryTheory/ObjectProperty/ShiftAdditive.lean new file mode 100644 index 00000000000000..12881aa4af4893 --- /dev/null +++ b/Mathlib/CategoryTheory/ObjectProperty/ShiftAdditive.lean @@ -0,0 +1,38 @@ +/- +Copyright (c) 2026 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.Shift +public import Mathlib.CategoryTheory.Preadditive.AdditiveFunctor + +/-! +# Properties of objects on preadditive categories equipped with shift + +In this file, we show that if `C` is a preadditive category +equipped with a shift by an additive monoid `A`, and +`P : ObjectProperty C` is stable under the shift, +then the shift functors on the full subcategory associated +to `P` are additive if the shift functors on `C` are. + +This instance is put in a separate file in order to reduce imports. + +-/ + +@[expose] public section + +open CategoryTheory Category + +namespace CategoryTheory.ObjectProperty + +instance {C : Type*} [Category* C] (P : ObjectProperty C) + {A : Type*} [AddMonoid A] [HasShift C A] + [P.IsStableUnderShift A] [Preadditive C] (n : A) + [(shiftFunctor C n).Additive] : + (shiftFunctor P.FullSubcategory n).Additive := by + have := Functor.additive_of_iso (P.ι.commShiftIso n).symm + apply Functor.additive_of_comp_faithful _ P.ι + +end CategoryTheory.ObjectProperty From a16182524af2427e39a324c10a00d2d72e28367f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Tue, 27 Jan 2026 17:22:03 +0100 Subject: [PATCH 58/72] fix --- Mathlib/CategoryTheory/Triangulated/Subcategory.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index 582df463ec9e58..896d78f85783ee 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -8,7 +8,7 @@ module public import Mathlib.CategoryTheory.Localization.CalculusOfFractions public import Mathlib.CategoryTheory.Localization.Triangulated public import Mathlib.CategoryTheory.ObjectProperty.FiniteProducts -public import Mathlib.CategoryTheory.ObjectProperty.Shift +public import Mathlib.CategoryTheory.ObjectProperty.ShiftAdditive public import Mathlib.CategoryTheory.Shift.Localization public import Mathlib.CategoryTheory.MorphismProperty.Limits From f6fd431fe832975fce58627b585fcabb3ebaa836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 30 Jan 2026 17:33:47 +0100 Subject: [PATCH 59/72] parentheses --- Mathlib/CategoryTheory/Triangulated/Subcategory.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean index 896d78f85783ee..cd8eeca99d57b2 100644 --- a/Mathlib/CategoryTheory/Triangulated/Subcategory.lean +++ b/Mathlib/CategoryTheory/Triangulated/Subcategory.lean @@ -400,7 +400,7 @@ instance [IsTriangulated C] : IsTriangulated P.FullSubcategory := IsTriangulated.of_fully_faithful_triangulated_functor P.ι instance (F : C ⥤ D) [F.CommShift ℤ] [F.IsTriangulated] [F.Full] : - (F.essImage).IsTriangulated where + F.essImage.IsTriangulated where isStableUnderShiftBy n := { le_shift := by rintro Y ⟨X, ⟨e⟩⟩ From 929fd996322209ebcea42c7a4d2669f39af65862 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Fri, 30 Jan 2026 18:51:55 +0100 Subject: [PATCH 60/72] fix --- .../Triangulated/TStructure/ETrunc.lean | 8 ++++---- .../Triangulated/TStructure/TruncLTGE.lean | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean index 8db69be766aae7..b4f80e711b5412 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -253,7 +253,7 @@ lemma isGE_eTruncGE_obj_obj (n : ℤ) (i : EInt) (h : n ≤ i) (X : C) : | bot => simp at h | coe i => dsimp - exact t.isGE_of_GE _ _ _ (by simpa using h) + exact t.isGE_of_ge _ _ _ (by simpa using h) | top => exact t.isGE_of_isZero (Functor.zero_obj _) _ lemma isLE_eTruncLT_obj_obj (n : ℤ) (i : EInt) (h : i ≤ (n + 1 :)) (X : C) : @@ -263,7 +263,7 @@ lemma isLE_eTruncLT_obj_obj (n : ℤ) (i : EInt) (h : i ≤ (n + 1 :)) (X : C) : | coe i => simp only [WithBotTop.coe_le_coe] at h dsimp - exact t.isLE_of_LE _ (i - 1) n (by lia) + exact t.isLE_of_le _ (i - 1) n (by lia) | top => simp at h lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j ≤ n) : @@ -271,7 +271,7 @@ lemma isZero_eTruncLT_obj_obj (X : C) (n : ℤ) [t.IsGE X n] (j : EInt) (hj : j induction j using WithBotTop.rec with | bot => simp | coe j => - have := t.isGE_of_GE X j n (by simpa using hj) + have := t.isGE_of_ge X j n (by simpa using hj) exact t.isZero_truncLT_obj_of_isGE _ _ | top => simp at hj @@ -281,7 +281,7 @@ lemma isZero_eTruncGE_obj_obj (X : C) (n : ℤ) [t.IsLE X n] (j : EInt) (hj : n | bot => simp at hj | coe j => simp only [WithBotTop.coe_lt_coe] at hj - have := t.isLE_of_LE X n (j - 1) (by lia) + have := t.isLE_of_le X n (j - 1) (by lia) exact t.isZero_truncGE_obj_of_isLE (j - 1) j (by lia) _ | top => simp diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean index fd97466755f213..b2c893c432e5ef 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean @@ -254,7 +254,7 @@ lemma truncGEπ_naturality (n : ℤ) {X Y : C} (f : X ⟶ Y) : lemma isLE_truncLT_obj (X : C) (a b : ℤ) (hn : a ≤ b + 1 := by lia) : t.IsLE ((t.truncLT a).obj X) b := by have : t.IsLE ((t.truncLT a).obj X) (a - 1) := by dsimp [truncLT]; infer_instance - exact t.isLE_of_LE _ (a - 1) _ (by lia) + exact t.isLE_of_le _ (a - 1) _ (by lia) instance (X : C) (n : ℤ) : t.IsLE ((t.truncLT n).obj X) (n - 1) := t.isLE_truncLT_obj .. @@ -265,7 +265,7 @@ instance (X : C) (n : ℤ) : t.IsLE ((t.truncLT (n + 1)).obj X) n := lemma isGE_truncGE_obj (X : C) (a b : ℤ) (hn : b ≤ a := by lia) : t.IsGE ((t.truncGE a).obj X) b := by have : t.IsGE ((t.truncGE a).obj X) a := by dsimp [truncGE]; infer_instance - exact t.isGE_of_GE _ _ a (by lia) + exact t.isGE_of_ge _ _ a (by lia) instance (X : C) (n : ℤ) : t.IsGE ((t.truncGE n).obj X) n := t.isGE_truncGE_obj .. @@ -610,15 +610,15 @@ instance : t.minus.IsTriangulated where exists_zero := ⟨0, isZero_zero C, 0, inferInstance⟩ toIsTriangulatedClosed₂ := .mk' (fun T hT ↦ by rintro ⟨i₁, hi₁⟩ ⟨i₃, hi₃⟩ - exact ⟨max i₁ i₃, t.isLE₂ T hT _ (t.isLE_of_LE _ _ _ (le_max_left i₁ i₃)) - (t.isLE_of_LE _ _ _ (le_max_right i₁ i₃))⟩) + exact ⟨max i₁ i₃, t.isLE₂ T hT _ (t.isLE_of_le _ _ _ (le_max_left i₁ i₃)) + (t.isLE_of_le _ _ _ (le_max_right i₁ i₃))⟩) instance : t.plus.IsTriangulated where exists_zero := ⟨0, isZero_zero C, 0, inferInstance⟩ toIsTriangulatedClosed₂ := .mk' (fun T hT ↦ by rintro ⟨i₁, hi₁⟩ ⟨i₃, hi₃⟩ - exact ⟨min i₁ i₃, t.isGE₂ T hT _ (t.isGE_of_GE _ _ _ (min_le_left i₁ i₃)) - (t.isGE_of_GE _ _ _ (min_le_right i₁ i₃))⟩) + exact ⟨min i₁ i₃, t.isGE₂ T hT _ (t.isGE_of_ge _ _ _ (min_le_left i₁ i₃)) + (t.isGE_of_ge _ _ _ (min_le_right i₁ i₃))⟩) instance : t.bounded.IsTriangulated := by dsimp [bounded] @@ -660,13 +660,13 @@ lemma isIso_truncGE_map_iff {Y Z : C} (g : Y ⟶ Z) (n₀ n₁ : ℤ) (hn : n₀ instance (X : C) (a b : ℤ) [t.IsLE X b] : t.IsLE ((t.truncLT a).obj X) b := by by_cases h : a ≤ b + 1 · exact t.isLE_truncLT_obj .. - · have := (t.isLE_iff_isIso_truncLTι_app (a - 1) a (by lia) X).1 (t.isLE_of_LE _ b _ (by lia)) + · have := (t.isLE_iff_isIso_truncLTι_app (a - 1) a (by lia) X).1 (t.isLE_of_le _ b _ (by lia)) exact t.isLE_of_iso (show X ≅ _ from (asIso ((t.truncLTι a).app X)).symm) _ instance (X : C) (a b : ℤ) [t.IsGE X a] : t.IsGE ((t.truncGE b).obj X) a := by by_cases h : a ≤ b · exact t.isGE_truncGE_obj .. - · have : t.IsGE X b := t.isGE_of_GE X b a (by lia) + · have : t.IsGE X b := t.isGE_of_ge X b a (by lia) exact t.isGE_of_iso (show X ≅ _ from asIso ((t.truncGEπ b).app X)) _ /-- The composition `t.truncLT b ⋙ t.truncGE a`. -/ @@ -742,7 +742,7 @@ lemma isIso_truncGE_map_truncGEπ_app (a b : ℤ) (h : b ≤ a) (X : C) : lemma isIso_truncLT_map_truncLTι_app (a b : ℤ) (h : a ≤ b) (X : C) : IsIso ((t.truncLT a).map ((t.truncLTι b).app X)) := t.isIso₁_truncLT_map_of_isGE _ (t.triangleLTGE_distinguished b X) a - (t.isGE_of_GE ((t.truncGE b).obj X) a b (by lia)) + (t.isGE_of_ge ((t.truncGE b).obj X) a b (by lia)) instance (X : C) (n : ℤ) : IsIso ((t.truncLT n).map ((t.truncLTι n).app X)) := isIso_truncLT_map_truncLTι_app t _ _ (by rfl) X From b2742c36927721b84005c646ce29be4201b7539f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 31 Jan 2026 10:52:16 +0100 Subject: [PATCH 61/72] fix --- Mathlib/Algebra/Homology/ShortComplex/Abelian.lean | 1 - 1 file changed, 1 deletion(-) diff --git a/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean b/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean index 7baff2279806bd..b0cee5debaaea2 100644 --- a/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean +++ b/Mathlib/Algebra/Homology/ShortComplex/Abelian.lean @@ -9,7 +9,6 @@ public import Mathlib.Algebra.Homology.ShortComplex.Homology public import Mathlib.Algebra.Homology.ShortComplex.Limits public import Mathlib.Algebra.Homology.ShortComplex.Preadditive public import Mathlib.CategoryTheory.Abelian.Basic -public import Batteries.Tactic.Lint /-! # Abelian categories have homology From c18c1dc6684c2c01053332865aa8bbcc64a9adf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 31 Jan 2026 10:54:23 +0100 Subject: [PATCH 62/72] fix --- .../Algebra/Homology/SpectralObject/Page.lean | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/Page.lean b/Mathlib/Algebra/Homology/SpectralObject/Page.lean index 50d7fe424a68a2..197dee3cc08a96 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Page.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Page.lean @@ -182,19 +182,19 @@ noncomputable def leftHomologyDataShortComplexE : have : hi.lift (KernelFork.ofι _ (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).zero) = X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃ := Fork.IsLimit.hom_ext hi (by simpa using hi.fac _ .zero) - refine { - K := X.cycles n₁ f₁ f₂ - H := cokernel (X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃) - i := X.iCycles n₁ f₁ f₂ - π := cokernel.π _ - wi := by simp - hi := hi - wπ := by rw [this]; simp - hπ := by - refine (IsColimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 - (cokernelIsCokernel (X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃)) - · exact parallelPair.ext (Iso.refl _) (Iso.refl _) (by simpa) (by simp) - · exact Cofork.ext (Iso.refl _)} + exact { + K := X.cycles n₁ f₁ f₂ + H := cokernel (X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃) + i := X.iCycles n₁ f₁ f₂ + π := cokernel.π _ + wi := by simp + hi := hi + wπ := by rw [this]; simp + hπ := by + refine (IsColimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 + (cokernelIsCokernel (X.δToCycles n₀ n₁ hn₁ f₁ f₂ f₃)) + · exact parallelPair.ext (Iso.refl _) (Iso.refl _) (by simpa) (by simp) + · exact Cofork.ext (Iso.refl _)} @[simp] lemma leftHomologyDataShortComplexE_f' : @@ -271,19 +271,19 @@ noncomputable def rightHomologyDataShortComplexE : have : hp.desc (CokernelCofork.ofπ _ (X.shortComplexE n₀ n₁ n₂ hn₁ hn₂ f₁ f₂ f₃).zero) = X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃ := Cofork.IsColimit.hom_ext hp (by simpa using hp.fac _ .one) - refine { - Q := X.opcycles n₁ f₂ f₃ - H := kernel (X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃) - p := X.pOpcycles n₁ f₂ f₃ - ι := kernel.ι _ - wp := by simp - hp := hp - wι := by rw [this]; simp - hι := by - refine (IsLimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 - (kernelIsKernel (X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃)) - · exact parallelPair.ext (Iso.refl _) (Iso.refl _) (by simpa) (by simp) - · exact Fork.ext (Iso.refl _) } + exact { + Q := X.opcycles n₁ f₂ f₃ + H := kernel (X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃) + p := X.pOpcycles n₁ f₂ f₃ + ι := kernel.ι _ + wp := by simp + hp := hp + wι := by rw [this]; simp + hι := by + refine (IsLimit.equivOfNatIsoOfIso ?_ _ _ ?_).2 + (kernelIsKernel (X.δFromOpcycles n₁ n₂ hn₂ f₁ f₂ f₃)) + · exact parallelPair.ext (Iso.refl _) (Iso.refl _) (by simpa) (by simp) + · exact Fork.ext (Iso.refl _) } @[simp] lemma rightHomologyDataShortComplexE_g' : From 917c7541371991a7c6de5afe18e71bf9306b0ec0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sat, 31 Jan 2026 10:57:10 +0100 Subject: [PATCH 63/72] fix --- Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean | 1 - Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean | 7 ------- 2 files changed, 8 deletions(-) diff --git a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean index 47da4efac3e493..d2c7aee9d43f18 100644 --- a/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean +++ b/Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean @@ -544,7 +544,6 @@ instance : HasBinaryBiproducts C := ⟨fun X₁ X₃ => by instance : HasFiniteProducts C := hasFiniteProducts_of_has_binary_and_terminal instance : HasFiniteCoproducts C := hasFiniteCoproducts_of_has_binary_and_initial instance : HasFiniteBiproducts C := HasFiniteBiproducts.of_hasFiniteProducts -instance : HasBinaryProducts C := inferInstance lemma exists_iso_binaryBiproduct_of_distTriang (T : Triangle C) (hT : T ∈ distTriang C) (zero : T.mor₃ = 0) : diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean index 0784c46325aeb5..839dca7fa8ce9e 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean @@ -29,13 +29,6 @@ use depending on the context. ## TODO -<<<<<<< HEAD -======= - -* define functors `t.truncLE n : C ⥤ C`, `t.truncGE n : C ⥤ C` and the - associated distinguished triangles -* promote these truncations to a (functorial) spectral object ->>>>>>> origin/master * define the heart of `t` and show it is an abelian category ## References From 654e29c5e8799d089990754496bb39726d4c7af8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 16:49:52 +0100 Subject: [PATCH 64/72] year --- Mathlib/Algebra/Homology/SpectralObject/Basic.lean | 2 +- Mathlib/Algebra/Homology/SpectralObject/Cycles.lean | 2 +- Mathlib/Algebra/Homology/SpectralObject/Differentials.lean | 2 +- Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean | 2 +- Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean | 2 +- .../Algebra/Homology/SpectralObject/HasSpectralSequence.lean | 2 +- Mathlib/Algebra/Homology/SpectralObject/Homology.lean | 2 +- Mathlib/Algebra/Homology/SpectralObject/Page.lean | 2 +- Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean | 2 +- Mathlib/Algebra/Homology/SpectralSequence/Basic.lean | 2 +- Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean | 2 +- Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean | 2 +- Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean | 2 +- .../CategoryTheory/Triangulated/TStructure/SpectralObject.lean | 2 +- Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/Basic.lean b/Mathlib/Algebra/Homology/SpectralObject/Basic.lean index dc327d0a3c3c5b..ac796f96615664 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Basic.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Basic.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/Cycles.lean b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean index b289b6bd28c810..edb54907353497 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/Differentials.lean b/Mathlib/Algebra/Homology/SpectralObject/Differentials.lean index ccd0f9b960d826..af3ce320f85882 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Differentials.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Differentials.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/EpiMono.lean b/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean index bde6568077e232..ac8efa1e2f5da0 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/EpiMono.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/FirstPage.lean b/Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean index c1f0e39d7830a1..34e37db497fd06 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/FirstPage.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index 4b90670554ed41..b383817e96bd96 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/Homology.lean b/Mathlib/Algebra/Homology/SpectralObject/Homology.lean index beff73ba6982f2..298123d7ee7a7b 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Homology.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Homology.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/Page.lean b/Mathlib/Algebra/Homology/SpectralObject/Page.lean index 197dee3cc08a96..ab5e1f432eeca2 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Page.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Page.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralObject/SpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean index 5ea9c99b4b6f2f..5c08b75587f4b6 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/SpectralSequence.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralSequence/Basic.lean b/Mathlib/Algebra/Homology/SpectralSequence/Basic.lean index c77d056ab17174..39fd06b2d1e620 100644 --- a/Mathlib/Algebra/Homology/SpectralSequence/Basic.lean +++ b/Mathlib/Algebra/Homology/SpectralSequence/Basic.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 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/SpectralSequence/ComplexShape.lean b/Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean index fdf82adb1039a1..aeb6a6dba6b71e 100644 --- a/Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean +++ b/Mathlib/Algebra/Homology/SpectralSequence/ComplexShape.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 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/CategoryTheory/Triangulated/TStructure/ETrunc.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean index b4f80e711b5412..b34c95662a8b64 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/ETrunc.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2024 Joël Riou. All rights reserved. +Copyright (c) 2026 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/CategoryTheory/Triangulated/TStructure/Induced.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean index ec8f11d310a847..bfe893a496f585 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 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/CategoryTheory/Triangulated/TStructure/SpectralObject.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean index e7d9fef6daf5cf..a984d060e8f313 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/SpectralObject.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 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/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean index 25beaa581aa3a1..bf4482420ce068 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLEGT.lean @@ -1,5 +1,5 @@ /- -Copyright (c) 2025 Joël Riou. All rights reserved. +Copyright (c) 2026 Joël Riou. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. Authors: Joël Riou -/ From f64c48fcf633db9bc2403a08529d36be46536118 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 17:12:00 +0100 Subject: [PATCH 65/72] fix --- Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean | 2 +- Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean index 839dca7fa8ce9e..f68f0ed4ec437c 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Basic.lean @@ -7,7 +7,7 @@ module public import Mathlib.CategoryTheory.ObjectProperty.CompleteLattice public import Mathlib.CategoryTheory.ObjectProperty.Shift -public import Mathlib.CategoryTheory.Triangulated.Subcategory +public import Mathlib.CategoryTheory.Triangulated.Pretriangulated /-! # t-structures on triangulated categories diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean index b2c893c432e5ef..3ae1a209d394e9 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/TruncLTGE.lean @@ -6,6 +6,7 @@ Authors: Joël Riou module public import Mathlib.CategoryTheory.Triangulated.TStructure.Basic +public import Mathlib.CategoryTheory.Triangulated.Subcategory /-! # Truncations for a t-structure From 0489677b3979fa2fc0d980dc9cadc4cc9de4061b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 17:24:56 +0100 Subject: [PATCH 66/72] typo --- Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean b/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean index bfe893a496f585..927b92bc66fcdf 100644 --- a/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean +++ b/Mathlib/CategoryTheory/Triangulated/TStructure/Induced.lean @@ -12,7 +12,7 @@ public import Mathlib.CategoryTheory.Triangulated.TStructure.TruncLEGT /-! # Induced t-structures -Let `t` be a t-structure on a pretriangulated cateogry `C`. +Let `t` be a t-structure on a pretriangulated category `C`. If `P` is a triangulated subcategory of `C`, we introduce a typeclass `P.HasInducedTStructure t` which essentially says that up to isomorphisms `P` is stable by the application of the truncation functors. From dc699c9cab28b034f65ab93ab8f80d9b26cdec29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 18:08:55 +0100 Subject: [PATCH 67/72] removed docstring --- .../Algebra/Homology/SpectralObject/HasSpectralSequence.lean | 2 -- 1 file changed, 2 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index b383817e96bd96..2e755c67334a93 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -306,7 +306,6 @@ lemma isZero_H_obj_mk₁_i₀_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₀_le r r' pq)))) := HasSpectralSequence.isZero_H_obj_mk₁_i₀_le r r' pq hpq n hn -/-- isZero_H_obj_mk₁_i₀_le' -/ lemma isZero_H_obj_mk₁_i₀_le' (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq pq')) (n : ℤ) (hn : n = data.deg pq + 1) (i₀' i₀ : ι) @@ -323,7 +322,6 @@ lemma isZero_H_obj_mk₁_i₃_le (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ IsZero ((X.H n).obj (mk₁ (homOfLE (data.i₃_le r r' pq)))) := HasSpectralSequence.isZero_H_obj_mk₁_i₃_le r r' pq hpq n hn -/-- isZero_H_obj_mk₁_i₃_le' -/ lemma isZero_H_obj_mk₁_i₃_le' (r r' : ℤ) (hrr' : r + 1 = r') (hr : r₀ ≤ r) (pq : κ) (hpq : ∀ (pq' : κ), ¬ ((c r).Rel pq' pq)) (n : ℤ) (hn : n = data.deg pq - 1) (i₃ i₃' : ι) From a1f4a5528463fe9d92054cd7ed6bd522054044b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 18:26:53 +0100 Subject: [PATCH 68/72] feat(Order/Fin): lemmas about Fin.clamp --- Mathlib.lean | 1 + Mathlib/Order/Fin/Clamp.lean | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 Mathlib/Order/Fin/Clamp.lean diff --git a/Mathlib.lean b/Mathlib.lean index cd72d6d36a5d31..4ba5892a13215b 100644 --- a/Mathlib.lean +++ b/Mathlib.lean @@ -5658,6 +5658,7 @@ public import Mathlib.Order.Filter.Ultrafilter.Basic public import Mathlib.Order.Filter.Ultrafilter.Defs public import Mathlib.Order.Filter.ZeroAndBoundedAtFilter public import Mathlib.Order.Fin.Basic +public import Mathlib.Order.Fin.Clamp public import Mathlib.Order.Fin.Finset public import Mathlib.Order.Fin.SuccAboveOrderIso public import Mathlib.Order.Fin.Tuple diff --git a/Mathlib/Order/Fin/Clamp.lean b/Mathlib/Order/Fin/Clamp.lean new file mode 100644 index 00000000000000..6db65d84f3a361 --- /dev/null +++ b/Mathlib/Order/Fin/Clamp.lean @@ -0,0 +1,29 @@ +/- +Copyright (c) 2026 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 Batteries.Data.Fin.Lemmas +public import Mathlib.Order.Fin.Basic +public import Mathlib.Order.MinMax + +/-! +# Lemmas about `Fin.clamp` + +-/ + +namespace Fin + +lemma Fin.clamp_mono {m : ℕ} : Monotone (fun n ↦ Fin.clamp n m) := by + intro a b h + rw [Fin.le_iff_val_le_val] + exact min_le_min_right m h + +lemma Fin.clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : + Fin.clamp n m = Fin.last _ := by + ext + simpa + +end Fin From e590fc20d263a6291575dca319442726854c81a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 18:27:40 +0100 Subject: [PATCH 69/72] better syntax --- Mathlib/Order/Fin/Clamp.lean | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Mathlib/Order/Fin/Clamp.lean b/Mathlib/Order/Fin/Clamp.lean index 6db65d84f3a361..05bb73927bcfe0 100644 --- a/Mathlib/Order/Fin/Clamp.lean +++ b/Mathlib/Order/Fin/Clamp.lean @@ -16,13 +16,13 @@ public import Mathlib.Order.MinMax namespace Fin -lemma Fin.clamp_mono {m : ℕ} : Monotone (fun n ↦ Fin.clamp n m) := by +lemma clamp_mono {m : ℕ} : Monotone (fun n ↦ clamp n m) := by intro a b h - rw [Fin.le_iff_val_le_val] + rw [le_iff_val_le_val] exact min_le_min_right m h -lemma Fin.clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : - Fin.clamp n m = Fin.last _ := by +lemma clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : + clamp n m = last _ := by ext simpa From ddb6e8b9517de367b9ba5299839fa190d49e6374 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 18:29:07 +0100 Subject: [PATCH 70/72] wip --- .../SpectralObject/HasSpectralSequence.lean | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index 2e755c67334a93..75714f23def6f7 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -194,12 +194,18 @@ def mkDataE₂CohomologicalNat : simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia + -- to be moved -lemma _root_.Fin.clamp_le_clamp {a b : ℕ} (h : a ≤ b) (m : ℕ) : - Fin.clamp a m ≤ Fin.clamp b m := by +lemma _root_.Fin.clamp_mono {m : ℕ} : Monotone (fun n ↦ Fin.clamp n m) := by + intro a b h rw [Fin.le_iff_val_le_val] exact min_le_min_right m h +lemma _root_.Fin.clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : + Fin.clamp n m = Fin.last _ := by + ext + simpa + /-- The data which allows to construct an `E₂`-cohomological spectral sequence indexed by `ℤ × Fin l` from a spectral object indexed by `Fin (l + 1)`. -/ @[simps deg i₀ i₁ i₂ i₃] @@ -235,8 +241,7 @@ def mkDataE₂CohomologicalFin (l : ℕ) : rintro r r' ⟨a, ⟨a', _⟩⟩ hr hrr' dsimp rw [Fin.mk_le_mk] - apply Fin.clamp_le_clamp - lia + exact Fin.clamp_mono (by lia) i₀_prev := by rintro r r' ⟨a, ⟨a', _⟩⟩ ⟨b, ⟨b', _⟩⟩ ⟨h₁, h₂⟩ hrr' hr ext @@ -340,11 +345,6 @@ instance (E : SpectralObject C EInt) : E.HasSpectralSequence mkDataE₂Cohomolog exfalso exact hpq (pq - (r, 1-r)) (by simp) -lemma _root_.Fin.clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : - Fin.clamp n m = Fin.last _ := by - ext - simpa - instance {l : ℕ} (E : SpectralObject C (Fin (l + 1))) : E.HasSpectralSequence (mkDataE₂CohomologicalFin l) where isZero_H_obj_mk₁_i₀_le r r' pq hpq n hn hrr' hr := by From 617601d4c167a09c281341849460c254def31969 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 18:30:46 +0100 Subject: [PATCH 71/72] wip --- .../SpectralObject/HasSpectralSequence.lean | 13 +------------ Mathlib/Order/Fin/Clamp.lean | 4 ++-- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean index 75714f23def6f7..07bcb9f64f75c6 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/HasSpectralSequence.lean @@ -7,6 +7,7 @@ module public import Mathlib.Algebra.Homology.SpectralObject.Basic public import Mathlib.Algebra.Homology.SpectralSequence.ComplexShape +public import Mathlib.Order.Fin.Clamp public import Mathlib.Order.WithBotTop /-! @@ -194,18 +195,6 @@ def mkDataE₂CohomologicalNat : simp only [ComplexShape.spectralSequenceNat_rel_iff] at hpq lia - --- to be moved -lemma _root_.Fin.clamp_mono {m : ℕ} : Monotone (fun n ↦ Fin.clamp n m) := by - intro a b h - rw [Fin.le_iff_val_le_val] - exact min_le_min_right m h - -lemma _root_.Fin.clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : - Fin.clamp n m = Fin.last _ := by - ext - simpa - /-- The data which allows to construct an `E₂`-cohomological spectral sequence indexed by `ℤ × Fin l` from a spectral object indexed by `Fin (l + 1)`. -/ @[simps deg i₀ i₁ i₂ i₃] diff --git a/Mathlib/Order/Fin/Clamp.lean b/Mathlib/Order/Fin/Clamp.lean index 05bb73927bcfe0..cbe5cfd1ab8208 100644 --- a/Mathlib/Order/Fin/Clamp.lean +++ b/Mathlib/Order/Fin/Clamp.lean @@ -16,12 +16,12 @@ public import Mathlib.Order.MinMax namespace Fin -lemma clamp_mono {m : ℕ} : Monotone (fun n ↦ clamp n m) := by +public lemma clamp_mono {m : ℕ} : Monotone (fun n ↦ clamp n m) := by intro a b h rw [le_iff_val_le_val] exact min_le_min_right m h -lemma clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : +public lemma clamp_eq_last (n m : ℕ) (hnm : m ≤ n) : clamp n m = last _ := by ext simpa From e88c20bf5b8ea627bc979e49b508629060c070b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl=20Riou?= Date: Sun, 15 Feb 2026 18:51:06 +0100 Subject: [PATCH 72/72] fix --- Mathlib/Algebra/Homology/SpectralObject/Cycles.lean | 1 - Mathlib/Algebra/Homology/SpectralObject/Page.lean | 1 - 2 files changed, 2 deletions(-) diff --git a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean index edb54907353497..a9d2d011e6a29a 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Cycles.lean @@ -8,7 +8,6 @@ module public import Mathlib.Algebra.Homology.SpectralObject.Basic public import Mathlib.Algebra.Homology.ExactSequenceFour public import Mathlib.CategoryTheory.Abelian.Exact -public import Batteries.Tactic.Lint /-! # Kernel and cokernel of the differentiel of a spectral object diff --git a/Mathlib/Algebra/Homology/SpectralObject/Page.lean b/Mathlib/Algebra/Homology/SpectralObject/Page.lean index ab5e1f432eeca2..b1822ad0383348 100644 --- a/Mathlib/Algebra/Homology/SpectralObject/Page.lean +++ b/Mathlib/Algebra/Homology/SpectralObject/Page.lean @@ -9,7 +9,6 @@ public import Mathlib.Algebra.Homology.SpectralObject.Cycles public import Mathlib.Algebra.Homology.ShortComplex.ShortExact public import Mathlib.CategoryTheory.Abelian.Refinements public import Mathlib.CategoryTheory.ComposableArrows.Three -public import Batteries.Tactic.Lint /-! # Spectral objects in abelian categories