l3lab/ntp-mathlib huggingface dataset:
/-- Given an exact short complex `S` and a limit kernel fork `kf` for `S.g`, this is the
left homology data for `S` with `K := kf.pt` and `H := 0`. -/
@[simps]
noncomputable def Exact.leftHomologyDataOfIsLimitKernelFork
    (hS : S.Exact) [HasZeroObject C] (kf : KernelFork S.g) (hkf : IsLimit kf) :
    S.LeftHomologyData where
  K := kf.pt
  H := 0
  i := kf.ι
  π := 0
  wi := kf.condition
  hi := IsLimit.ofIsoLimit hkf (Fork.ext (Iso.refl _) (by simp))
  wπ := comp_zero
  hπ := CokernelCofork.IsColimit.ofEpiOfIsZero _ (by
    have := hS.hasHomology
    refine' ((MorphismProperty.RespectsIso.epimorphisms C).arrow_mk_iso_iff _).1
      hS.epi_toCycles
    refine' Arrow.isoMk (Iso.refl _)
      (IsLimit.conePointUniqueUpToIso S.cyclesIsKernel hkf) _
    apply Fork.IsLimit.hom_ext hkf
    

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.45300, u_1} C
inst✝³ : Category.{?u.45304, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : Exact S
inst✝ : HasZeroObject C
kf : KernelFork S.g
hkf : IsLimit kf
this : HasHomology S
⊢ ((Iso.refl (Arrow.mk (toCycles S)).left).hom ≫
        (Arrow.mk
            (IsLimit.lift (IsLimit.ofIsoLimit hkf (Fork.ext (Iso.refl kf.pt)))
              (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)))).hom) ≫
      Fork.ι kf =
    ((Arrow.mk (toCycles S)).hom ≫ (IsLimit.conePointUniqueUpToIso (cyclesIsKernel S) hkf).hom) ≫ Fork.ι kf

Next tactic:
simp [IsLimit.conePointUniqueUpToIso]
/-- Given an exact short complex `S` and a colimit cokernel cofork `cc` for `S.f`, this is the
right homology data for `S` with `Q := cc.pt` and `H := 0`. -/
@[simps]
noncomputable def Exact.rightHomologyDataOfIsColimitCokernelCofork
    (hS : S.Exact) [HasZeroObject C] (cc : CokernelCofork S.f) (hcc : IsColimit cc) :
    S.RightHomologyData where
  Q := cc.pt
  H := 0
  p := cc.π
  ι := 0
  wp := cc.condition
  hp := IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl _) (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.50575, u_1} C
inst✝³ : Category.{?u.50579, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : Exact S
inst✝ : HasZeroObject C
cc : CokernelCofork S.f
hcc : IsColimit cc
⊢ Cofork.π cc ≫ (Iso.refl cc.pt).hom = Cofork.π (CokernelCofork.ofπ (Cofork.π cc) (_ : S.f ≫ Cofork.π cc = 0))

Next tactic:
simp
/-- Given an exact short complex `S` and a colimit cokernel cofork `cc` for `S.f`, this is the
right homology data for `S` with `Q := cc.pt` and `H := 0`. -/
@[simps]
noncomputable def Exact.rightHomologyDataOfIsColimitCokernelCofork
    (hS : S.Exact) [HasZeroObject C] (cc : CokernelCofork S.f) (hcc : IsColimit cc) :
    S.RightHomologyData where
  Q := cc.pt
  H := 0
  p := cc.π
  ι := 0
  wp := cc.condition
  hp := IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl _) (by simp))
  wι := zero_comp
  hι := KernelFork.IsLimit.ofMonoOfIsZero _ (by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.50575, u_1} C
inst✝³ : Category.{?u.50579, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : Exact S
inst✝ : HasZeroObject C
cc : CokernelCofork S.f
hcc : IsColimit cc
⊢ Mono
    (IsColimit.desc (IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl cc.pt)))
      (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))

Next tactic:
have := hS.hasHomology
/-- Given an exact short complex `S` and a colimit cokernel cofork `cc` for `S.f`, this is the
right homology data for `S` with `Q := cc.pt` and `H := 0`. -/
@[simps]
noncomputable def Exact.rightHomologyDataOfIsColimitCokernelCofork
    (hS : S.Exact) [HasZeroObject C] (cc : CokernelCofork S.f) (hcc : IsColimit cc) :
    S.RightHomologyData where
  Q := cc.pt
  H := 0
  p := cc.π
  ι := 0
  wp := cc.condition
  hp := IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl _) (by simp))
  wι := zero_comp
  hι := KernelFork.IsLimit.ofMonoOfIsZero _ (by
    have := hS.hasHomology
    

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.50575, u_1} C
inst✝³ : Category.{?u.50579, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : Exact S
inst✝ : HasZeroObject C
cc : CokernelCofork S.f
hcc : IsColimit cc
this : HasHomology S
⊢ Mono
    (IsColimit.desc (IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl cc.pt)))
      (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))

Next tactic:
refine' ((MorphismProperty.RespectsIso.monomorphisms C).arrow_mk_iso_iff _).2
      hS.mono_fromOpcycles
/-- Given an exact short complex `S` and a colimit cokernel cofork `cc` for `S.f`, this is the
right homology data for `S` with `Q := cc.pt` and `H := 0`. -/
@[simps]
noncomputable def Exact.rightHomologyDataOfIsColimitCokernelCofork
    (hS : S.Exact) [HasZeroObject C] (cc : CokernelCofork S.f) (hcc : IsColimit cc) :
    S.RightHomologyData where
  Q := cc.pt
  H := 0
  p := cc.π
  ι := 0
  wp := cc.condition
  hp := IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl _) (by simp))
  wι := zero_comp
  hι := KernelFork.IsLimit.ofMonoOfIsZero _ (by
    have := hS.hasHomology
    refine' ((MorphismProperty.RespectsIso.monomorphisms C).arrow_mk_iso_iff _).2
      hS.mono_fromOpcycles
    

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.50575, u_1} C
inst✝³ : Category.{?u.50579, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : Exact S
inst✝ : HasZeroObject C
cc : CokernelCofork S.f
hcc : IsColimit cc
this : HasHomology S
⊢ Arrow.mk
      (IsColimit.desc (IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl cc.pt)))
        (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))) ≅
    Arrow.mk (fromOpcycles S)

Next tactic:
refine' Arrow.isoMk (IsColimit.coconePointUniqueUpToIso hcc S.opcyclesIsCokernel)
      (Iso.refl _) _
/-- Given an exact short complex `S` and a colimit cokernel cofork `cc` for `S.f`, this is the
right homology data for `S` with `Q := cc.pt` and `H := 0`. -/
@[simps]
noncomputable def Exact.rightHomologyDataOfIsColimitCokernelCofork
    (hS : S.Exact) [HasZeroObject C] (cc : CokernelCofork S.f) (hcc : IsColimit cc) :
    S.RightHomologyData where
  Q := cc.pt
  H := 0
  p := cc.π
  ι := 0
  wp := cc.condition
  hp := IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl _) (by simp))
  wι := zero_comp
  hι := KernelFork.IsLimit.ofMonoOfIsZero _ (by
    have := hS.hasHomology
    refine' ((MorphismProperty.RespectsIso.monomorphisms C).arrow_mk_iso_iff _).2
      hS.mono_fromOpcycles
    refine' Arrow.isoMk (IsColimit.coconePointUniqueUpToIso hcc S.opcyclesIsCokernel)
      (Iso.refl _) _
    

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.50575, u_1} C
inst✝³ : Category.{?u.50579, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : Exact S
inst✝ : HasZeroObject C
cc : CokernelCofork S.f
hcc : IsColimit cc
this : HasHomology S
⊢ (IsColimit.coconePointUniqueUpToIso hcc (opcyclesIsCokernel S)).hom ≫ (Arrow.mk (fromOpcycles S)).hom =
    (Arrow.mk
          (IsColimit.desc (IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl cc.pt)))
            (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))).hom ≫
      (Iso.refl
          (Arrow.mk
              (IsColimit.desc (IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl cc.pt)))
                (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))).right).hom

Next tactic:
apply Cofork.IsColimit.hom_ext hcc
/-- Given an exact short complex `S` and a colimit cokernel cofork `cc` for `S.f`, this is the
right homology data for `S` with `Q := cc.pt` and `H := 0`. -/
@[simps]
noncomputable def Exact.rightHomologyDataOfIsColimitCokernelCofork
    (hS : S.Exact) [HasZeroObject C] (cc : CokernelCofork S.f) (hcc : IsColimit cc) :
    S.RightHomologyData where
  Q := cc.pt
  H := 0
  p := cc.π
  ι := 0
  wp := cc.condition
  hp := IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl _) (by simp))
  wι := zero_comp
  hι := KernelFork.IsLimit.ofMonoOfIsZero _ (by
    have := hS.hasHomology
    refine' ((MorphismProperty.RespectsIso.monomorphisms C).arrow_mk_iso_iff _).2
      hS.mono_fromOpcycles
    refine' Arrow.isoMk (IsColimit.coconePointUniqueUpToIso hcc S.opcyclesIsCokernel)
      (Iso.refl _) _
    apply Cofork.IsColimit.hom_ext hcc
    

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{?u.50575, u_1} C
inst✝³ : Category.{?u.50579, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : Exact S
inst✝ : HasZeroObject C
cc : CokernelCofork S.f
hcc : IsColimit cc
this : HasHomology S
⊢ Cofork.π cc ≫ (IsColimit.coconePointUniqueUpToIso hcc (opcyclesIsCokernel S)).hom ≫ (Arrow.mk (fromOpcycles S)).hom =
    Cofork.π cc ≫
      (Arrow.mk
            (IsColimit.desc (IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl cc.pt)))
              (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))).hom ≫
        (Iso.refl
            (Arrow.mk
                (IsColimit.desc (IsColimit.ofIsoColimit hcc (Cofork.ext (Iso.refl cc.pt)))
                  (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))).right).hom

Next tactic:
simp [IsColimit.coconePointUniqueUpToIso]
lemma exact_iff_epi_kernel_lift [S.HasHomology] [HasKernel S.g] :
    S.Exact ↔ Epi (kernel.lift S.g S.f S.zero) := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.57006, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasKernel S.g
⊢ Exact S ↔ Epi (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))

Next tactic:
rw [exact_iff_epi_toCycles]
lemma exact_iff_epi_kernel_lift [S.HasHomology] [HasKernel S.g] :
    S.Exact ↔ Epi (kernel.lift S.g S.f S.zero) := by
  rw [exact_iff_epi_toCycles]
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.57006, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasKernel S.g
⊢ Epi (toCycles S) ↔ Epi (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))

Next tactic:
apply (MorphismProperty.RespectsIso.epimorphisms C).arrow_mk_iso_iff
lemma exact_iff_epi_kernel_lift [S.HasHomology] [HasKernel S.g] :
    S.Exact ↔ Epi (kernel.lift S.g S.f S.zero) := by
  rw [exact_iff_epi_toCycles]
  apply (MorphismProperty.RespectsIso.epimorphisms C).arrow_mk_iso_iff
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.57006, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasKernel S.g
⊢ Arrow.mk (toCycles S) ≅ Arrow.mk (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))

Next tactic:
exact Arrow.isoMk (Iso.refl _) S.cyclesIsoKernel (by aesop_cat)
lemma exact_iff_epi_kernel_lift [S.HasHomology] [HasKernel S.g] :
    S.Exact ↔ Epi (kernel.lift S.g S.f S.zero) := by
  rw [exact_iff_epi_toCycles]
  apply (MorphismProperty.RespectsIso.epimorphisms C).arrow_mk_iso_iff
  exact Arrow.isoMk (Iso.refl _) S.cyclesIsoKernel (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.57006, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasKernel S.g
⊢ (Iso.refl (Arrow.mk (toCycles S)).left).hom ≫ (Arrow.mk (kernel.lift S.g S.f (_ : S.f ≫ S.g = 0))).hom =
    (Arrow.mk (toCycles S)).hom ≫ (cyclesIsoKernel S).hom

Next tactic:
aesop_cat
lemma exact_iff_mono_cokernel_desc [S.HasHomology] [HasCokernel S.f] :
    S.Exact ↔ Mono (cokernel.desc S.f S.g S.zero) := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.60151, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasCokernel S.f
⊢ Exact S ↔ Mono (cokernel.desc S.f S.g (_ : S.f ≫ S.g = 0))

Next tactic:
rw [exact_iff_mono_fromOpcycles]
lemma exact_iff_mono_cokernel_desc [S.HasHomology] [HasCokernel S.f] :
    S.Exact ↔ Mono (cokernel.desc S.f S.g S.zero) := by
  rw [exact_iff_mono_fromOpcycles]
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.60151, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasCokernel S.f
⊢ Mono (fromOpcycles S) ↔ Mono (cokernel.desc S.f S.g (_ : S.f ≫ S.g = 0))

Next tactic:
refine' (MorphismProperty.RespectsIso.monomorphisms C).arrow_mk_iso_iff (Iso.symm _)
lemma exact_iff_mono_cokernel_desc [S.HasHomology] [HasCokernel S.f] :
    S.Exact ↔ Mono (cokernel.desc S.f S.g S.zero) := by
  rw [exact_iff_mono_fromOpcycles]
  refine' (MorphismProperty.RespectsIso.monomorphisms C).arrow_mk_iso_iff (Iso.symm _)
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.60151, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasCokernel S.f
⊢ Arrow.mk (cokernel.desc S.f S.g (_ : S.f ≫ S.g = 0)) ≅ Arrow.mk (fromOpcycles S)

Next tactic:
exact Arrow.isoMk S.opcyclesIsoCokernel.symm (Iso.refl _) (by aesop_cat)
lemma exact_iff_mono_cokernel_desc [S.HasHomology] [HasCokernel S.f] :
    S.Exact ↔ Mono (cokernel.desc S.f S.g S.zero) := by
  rw [exact_iff_mono_fromOpcycles]
  refine' (MorphismProperty.RespectsIso.monomorphisms C).arrow_mk_iso_iff (Iso.symm _)
  exact Arrow.isoMk S.opcyclesIsoCokernel.symm (Iso.refl _) (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.60151, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : HasHomology S
inst✝ : HasCokernel S.f
⊢ (opcyclesIsoCokernel S).symm.hom ≫ (Arrow.mk (fromOpcycles S)).hom =
    (Arrow.mk (cokernel.desc S.f S.g (_ : S.f ≫ S.g = 0))).hom ≫
      (Iso.refl (Arrow.mk (cokernel.desc S.f S.g (_ : S.f ≫ S.g = 0))).right).hom

Next tactic:
aesop_cat
lemma QuasiIso.exact_iff {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    [S₁.HasHomology] [S₂.HasHomology] [QuasiIso φ] : S₁.Exact ↔ S₂.Exact := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁶ : Category.{u_3, u_1} C
inst✝⁵ : Category.{?u.63805, u_2} D
inst✝⁴ : Preadditive C
inst✝³ : Preadditive D
S S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
inst✝² : HasHomology S₁
inst✝¹ : HasHomology S₂
inst✝ : QuasiIso φ
⊢ Exact S₁ ↔ Exact S₂

Next tactic:
simp only [exact_iff_isZero_homology]
lemma QuasiIso.exact_iff {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    [S₁.HasHomology] [S₂.HasHomology] [QuasiIso φ] : S₁.Exact ↔ S₂.Exact := by
  simp only [exact_iff_isZero_homology]
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁶ : Category.{u_3, u_1} C
inst✝⁵ : Category.{?u.63805, u_2} D
inst✝⁴ : Preadditive C
inst✝³ : Preadditive D
S S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
inst✝² : HasHomology S₁
inst✝¹ : HasHomology S₂
inst✝ : QuasiIso φ
⊢ IsZero (homology S₁) ↔ IsZero (homology S₂)

Next tactic:
exact Iso.isZero_iff (asIso (homologyMap φ))
lemma exact_of_f_is_kernel (hS : IsLimit (KernelFork.ofι S.f S.zero))
    [S.HasHomology] : S.Exact := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.64959, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ Exact S

Next tactic:
rw [exact_iff_epi_toCycles]
lemma exact_of_f_is_kernel (hS : IsLimit (KernelFork.ofι S.f S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_epi_toCycles]
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.64959, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ Epi (toCycles S)

Next tactic:
have : IsSplitEpi S.toCycles :=
    ⟨⟨{ section_ := hS.lift (KernelFork.ofι S.iCycles S.iCycles_g)
        id := by
          rw [← cancel_mono S.iCycles, assoc, toCycles_i, id_comp]
          exact Fork.IsLimit.lift_ι hS }⟩⟩
lemma exact_of_f_is_kernel (hS : IsLimit (KernelFork.ofι S.f S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_epi_toCycles]
  have : IsSplitEpi S.toCycles :=
    ⟨⟨{ section_ := hS.lift (KernelFork.ofι S.iCycles S.iCycles_g)
        id := by
          

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.64959, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ IsLimit.lift hS (KernelFork.ofι (iCycles S) (_ : iCycles S ≫ S.g = 0)) ≫ toCycles S = 𝟙 (cycles S)

Next tactic:
rw [← cancel_mono S.iCycles, assoc, toCycles_i, id_comp]
lemma exact_of_f_is_kernel (hS : IsLimit (KernelFork.ofι S.f S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_epi_toCycles]
  have : IsSplitEpi S.toCycles :=
    ⟨⟨{ section_ := hS.lift (KernelFork.ofι S.iCycles S.iCycles_g)
        id := by
          rw [← cancel_mono S.iCycles, assoc, toCycles_i, id_comp]
          

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.64959, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ IsLimit.lift hS (KernelFork.ofι (iCycles S) (_ : iCycles S ≫ S.g = 0)) ≫ S.f = iCycles S

Next tactic:
exact Fork.IsLimit.lift_ι hS
lemma exact_of_f_is_kernel (hS : IsLimit (KernelFork.ofι S.f S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_epi_toCycles]
  have : IsSplitEpi S.toCycles :=
    ⟨⟨{ section_ := hS.lift (KernelFork.ofι S.iCycles S.iCycles_g)
        id := by
          rw [← cancel_mono S.iCycles, assoc, toCycles_i, id_comp]
          exact Fork.IsLimit.lift_ι hS }⟩⟩
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.64959, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
this : IsSplitEpi (toCycles S)
⊢ Epi (toCycles S)

Next tactic:
infer_instance
lemma exact_of_g_is_cokernel (hS : IsColimit (CokernelCofork.ofπ S.g S.zero))
    [S.HasHomology] : S.Exact := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.68601, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ Exact S

Next tactic:
rw [exact_iff_mono_fromOpcycles]
lemma exact_of_g_is_cokernel (hS : IsColimit (CokernelCofork.ofπ S.g S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_mono_fromOpcycles]
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.68601, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ Mono (fromOpcycles S)

Next tactic:
have : IsSplitMono S.fromOpcycles :=
    ⟨⟨{ retraction := hS.desc (CokernelCofork.ofπ S.pOpcycles S.f_pOpcycles)
        id := by
          rw [← cancel_epi S.pOpcycles, p_fromOpcycles_assoc, comp_id]
          exact Cofork.IsColimit.π_desc hS }⟩⟩
lemma exact_of_g_is_cokernel (hS : IsColimit (CokernelCofork.ofπ S.g S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_mono_fromOpcycles]
  have : IsSplitMono S.fromOpcycles :=
    ⟨⟨{ retraction := hS.desc (CokernelCofork.ofπ S.pOpcycles S.f_pOpcycles)
        id := by
          

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.68601, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ fromOpcycles S ≫ IsColimit.desc hS (CokernelCofork.ofπ (pOpcycles S) (_ : S.f ≫ pOpcycles S = 0)) = 𝟙 (opcycles S)

Next tactic:
rw [← cancel_epi S.pOpcycles, p_fromOpcycles_assoc, comp_id]
lemma exact_of_g_is_cokernel (hS : IsColimit (CokernelCofork.ofπ S.g S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_mono_fromOpcycles]
  have : IsSplitMono S.fromOpcycles :=
    ⟨⟨{ retraction := hS.desc (CokernelCofork.ofπ S.pOpcycles S.f_pOpcycles)
        id := by
          rw [← cancel_epi S.pOpcycles, p_fromOpcycles_assoc, comp_id]
          

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.68601, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
⊢ S.g ≫ IsColimit.desc hS (CokernelCofork.ofπ (pOpcycles S) (_ : S.f ≫ pOpcycles S = 0)) = pOpcycles S

Next tactic:
exact Cofork.IsColimit.π_desc hS
lemma exact_of_g_is_cokernel (hS : IsColimit (CokernelCofork.ofπ S.g S.zero))
    [S.HasHomology] : S.Exact := by
  rw [exact_iff_mono_fromOpcycles]
  have : IsSplitMono S.fromOpcycles :=
    ⟨⟨{ retraction := hS.desc (CokernelCofork.ofπ S.pOpcycles S.f_pOpcycles)
        id := by
          rw [← cancel_epi S.pOpcycles, p_fromOpcycles_assoc, comp_id]
          exact Cofork.IsColimit.π_desc hS }⟩⟩
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.68601, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
hS : IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))
inst✝ : HasHomology S
this : IsSplitMono (fromOpcycles S)
⊢ Mono (fromOpcycles S)

Next tactic:
infer_instance
lemma Exact.mono_g (hS : S.Exact) (hf : S.f = 0) : Mono S.g := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.71700, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
hf : S.f = 0
⊢ Mono S.g

Next tactic:
have := hS.hasHomology
lemma Exact.mono_g (hS : S.Exact) (hf : S.f = 0) : Mono S.g := by
  have := hS.hasHomology
  

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.71700, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
hf : S.f = 0
this : HasHomology S
⊢ Mono S.g

Next tactic:
have := hS.epi_toCycles
lemma Exact.mono_g (hS : S.Exact) (hf : S.f = 0) : Mono S.g := by
  have := hS.hasHomology
  have := hS.epi_toCycles
  

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.71700, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
hf : S.f = 0
this✝ : HasHomology S
this : Epi (toCycles S)
⊢ Mono S.g

Next tactic:
have : S.iCycles = 0 := by rw [← cancel_epi S.toCycles, comp_zero, toCycles_i, hf]
lemma Exact.mono_g (hS : S.Exact) (hf : S.f = 0) : Mono S.g := by
  have := hS.hasHomology
  have := hS.epi_toCycles
  have : S.iCycles = 0 := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.71700, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
hf : S.f = 0
this✝ : HasHomology S
this : Epi (toCycles S)
⊢ iCycles S = 0

Next tactic:
rw [← cancel_epi S.toCycles, comp_zero, toCycles_i, hf]
lemma Exact.mono_g (hS : S.Exact) (hf : S.f = 0) : Mono S.g := by
  have := hS.hasHomology
  have := hS.epi_toCycles
  have : S.iCycles = 0 := by rw [← cancel_epi S.toCycles, comp_zero, toCycles_i, hf]
  

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.71700, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
hf : S.f = 0
this✝¹ : HasHomology S
this✝ : Epi (toCycles S)
this : iCycles S = 0
⊢ Mono S.g

Next tactic:
apply Preadditive.mono_of_cancel_zero
lemma Exact.mono_g (hS : S.Exact) (hf : S.f = 0) : Mono S.g := by
  have := hS.hasHomology
  have := hS.epi_toCycles
  have : S.iCycles = 0 := by rw [← cancel_epi S.toCycles, comp_zero, toCycles_i, hf]
  apply Preadditive.mono_of_cancel_zero
  

Proof state:
case h
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.71700, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
hf : S.f = 0
this✝¹ : HasHomology S
this✝ : Epi (toCycles S)
this : iCycles S = 0
⊢ ∀ {P : C} (g : P ⟶ S.X₂), g ≫ S.g = 0 → g = 0

Next tactic:
intro A x₂ hx₂