l3lab/ntp-mathlib huggingface dataset:
lemma exact_iff_mono [HasZeroObject C] (hf : S.f = 0) :
    S.Exact ↔ Mono S.g := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.36174, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hf : S.f = 0
this : HasHomology S
h : IsZero (homology S)
⊢ Mono S.g

Next tactic:
have := S.isIso_pOpcycles hf
lemma exact_iff_mono [HasZeroObject C] (hf : S.f = 0) :
    S.Exact ↔ Mono S.g := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    have := S.isIso_pOpcycles hf
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.36174, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hf : S.f = 0
this✝ : HasHomology S
h : IsZero (homology S)
this : IsIso (pOpcycles S)
⊢ Mono S.g

Next tactic:
have := mono_of_isZero_kernel' _ S.homologyIsKernel h
lemma exact_iff_mono [HasZeroObject C] (hf : S.f = 0) :
    S.Exact ↔ Mono S.g := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    have := S.isIso_pOpcycles hf
    have := mono_of_isZero_kernel' _ S.homologyIsKernel h
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.36174, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hf : S.f = 0
this✝¹ : HasHomology S
h : IsZero (homology S)
this✝ : IsIso (pOpcycles S)
this : Mono (fromOpcycles S)
⊢ Mono S.g

Next tactic:
rw [← S.p_fromOpcycles]
lemma exact_iff_mono [HasZeroObject C] (hf : S.f = 0) :
    S.Exact ↔ Mono S.g := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    have := S.isIso_pOpcycles hf
    have := mono_of_isZero_kernel' _ S.homologyIsKernel h
    rw [← S.p_fromOpcycles]
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.36174, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hf : S.f = 0
this✝¹ : HasHomology S
h : IsZero (homology S)
this✝ : IsIso (pOpcycles S)
this : Mono (fromOpcycles S)
⊢ Mono (pOpcycles S ≫ fromOpcycles S)

Next tactic:
apply mono_comp
lemma exact_iff_mono [HasZeroObject C] (hf : S.f = 0) :
    S.Exact ↔ Mono S.g := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    have := S.isIso_pOpcycles hf
    have := mono_of_isZero_kernel' _ S.homologyIsKernel h
    rw [← S.p_fromOpcycles]
    apply mono_comp
  · 

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

Next tactic:
intro
lemma exact_iff_mono [HasZeroObject C] (hf : S.f = 0) :
    S.Exact ↔ Mono S.g := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    have := S.isIso_pOpcycles hf
    have := mono_of_isZero_kernel' _ S.homologyIsKernel h
    rw [← S.p_fromOpcycles]
    apply mono_comp
  · intro
    

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

Next tactic:
rw [(HomologyData.ofIsLimitKernelFork S hf _
      (KernelFork.IsLimit.ofMonoOfIsZero (KernelFork.ofι (0 : 0 ⟶ S.X₂) zero_comp)
        inferInstance (isZero_zero C))).exact_iff]
lemma exact_iff_mono [HasZeroObject C] (hf : S.f = 0) :
    S.Exact ↔ Mono S.g := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    have := S.isIso_pOpcycles hf
    have := mono_of_isZero_kernel' _ S.homologyIsKernel h
    rw [← S.p_fromOpcycles]
    apply mono_comp
  · intro
    rw [(HomologyData.ofIsLimitKernelFork S hf _
      (KernelFork.IsLimit.ofMonoOfIsZero (KernelFork.ofι (0 : 0 ⟶ S.X₂) zero_comp)
        inferInstance (isZero_zero C))).exact_iff]
    

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.36174, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hf : S.f = 0
a✝ : Mono S.g
⊢ IsZero
    (HomologyData.ofIsLimitKernelFork S hf (KernelFork.ofι 0 (_ : 0 ≫ S.g = 0))
          (KernelFork.IsLimit.ofMonoOfIsZero (KernelFork.ofι 0 (_ : 0 ≫ S.g = 0)) (_ : Mono S.g) (_ : IsZero 0))).left.H

Next tactic:
exact isZero_zero C
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
⊢ Exact S ↔ Epi S.f

Next tactic:
constructor
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · 

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
⊢ Exact S → Epi S.f

Next tactic:
intro h
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
h : Exact S
⊢ Epi S.f

Next tactic:
have := h.hasHomology
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
h : Exact S
this : HasHomology S
⊢ Epi S.f

Next tactic:
simp only [exact_iff_isZero_homology] at h
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
this : HasHomology S
h : IsZero (homology S)
⊢ Epi S.f

Next tactic:
haveI := S.isIso_iCycles hg
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    haveI := S.isIso_iCycles hg
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
this✝ : HasHomology S
h : IsZero (homology S)
this : IsIso (iCycles S)
⊢ Epi S.f

Next tactic:
haveI : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    haveI := S.isIso_iCycles hg
    haveI : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
this✝¹ : HasHomology S
h : IsZero (homology S)
this✝ : IsIso (iCycles S)
this : Epi (toCycles S)
⊢ Epi S.f

Next tactic:
rw [← S.toCycles_i]
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    haveI := S.isIso_iCycles hg
    haveI : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h
    rw [← S.toCycles_i]
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
this✝¹ : HasHomology S
h : IsZero (homology S)
this✝ : IsIso (iCycles S)
this : Epi (toCycles S)
⊢ Epi (toCycles S ≫ iCycles S)

Next tactic:
apply epi_comp
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    haveI := S.isIso_iCycles hg
    haveI : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h
    rw [← S.toCycles_i]
    apply epi_comp
  · 

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
⊢ Epi S.f → Exact S

Next tactic:
intro
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    haveI := S.isIso_iCycles hg
    haveI : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h
    rw [← S.toCycles_i]
    apply epi_comp
  · intro
    

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
a✝ : Epi S.f
⊢ Exact S

Next tactic:
rw [(HomologyData.ofIsColimitCokernelCofork S hg _
      (CokernelCofork.IsColimit.ofEpiOfIsZero (CokernelCofork.ofπ (0 : S.X₂ ⟶ 0) comp_zero)
        inferInstance (isZero_zero C))).exact_iff]
lemma exact_iff_epi [HasZeroObject C] (hg : S.g = 0) :
    S.Exact ↔ Epi S.f := by
  constructor
  · intro h
    have := h.hasHomology
    simp only [exact_iff_isZero_homology] at h
    haveI := S.isIso_iCycles hg
    haveI : Epi S.toCycles := epi_of_isZero_cokernel' _ S.homologyIsCokernel h
    rw [← S.toCycles_i]
    apply epi_comp
  · intro
    rw [(HomologyData.ofIsColimitCokernelCofork S hg _
      (CokernelCofork.IsColimit.ofEpiOfIsZero (CokernelCofork.ofπ (0 : S.X₂ ⟶ 0) comp_zero)
        inferInstance (isZero_zero C))).exact_iff]
    

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.38189, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasZeroObject C
hg : S.g = 0
a✝ : Epi S.f
⊢ IsZero
    (HomologyData.ofIsColimitCokernelCofork S hg (CokernelCofork.ofπ 0 (_ : S.f ≫ 0 = 0))
          (CokernelCofork.IsColimit.ofEpiOfIsZero (CokernelCofork.ofπ 0 (_ : S.f ≫ 0 = 0)) (_ : Epi S.f)
            (_ : IsZero 0))).left.H

Next tactic:
exact isZero_zero C
lemma Exact.epi_f' (hS : S.Exact) (h : LeftHomologyData S) : Epi h.f' :=
  epi_of_isZero_cokernel' _ h.hπ (by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.40446, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
h : LeftHomologyData S
⊢ IsZero (CokernelCofork.ofπ h.π (_ : IsLimit.lift h.hi (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) ≫ h.π = 0)).pt

Next tactic:
haveI := hS.hasHomology
lemma Exact.epi_f' (hS : S.Exact) (h : LeftHomologyData S) : Epi h.f' :=
  epi_of_isZero_cokernel' _ h.hπ (by
    haveI := hS.hasHomology
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.40446, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
h : LeftHomologyData S
this : HasHomology S
⊢ IsZero (CokernelCofork.ofπ h.π (_ : IsLimit.lift h.hi (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) ≫ h.π = 0)).pt

Next tactic:
dsimp
lemma Exact.epi_f' (hS : S.Exact) (h : LeftHomologyData S) : Epi h.f' :=
  epi_of_isZero_cokernel' _ h.hπ (by
    haveI := hS.hasHomology
    dsimp
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.40446, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
h : LeftHomologyData S
this : HasHomology S
⊢ IsZero h.H

Next tactic:
simpa only [← h.exact_iff] using hS
lemma Exact.mono_g' (hS : S.Exact) (h : RightHomologyData S) : Mono h.g' :=
  mono_of_isZero_kernel' _ h.hι (by
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.41379, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
h : RightHomologyData S
⊢ IsZero (KernelFork.ofι h.ι (_ : h.ι ≫ IsColimit.desc h.hp (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)) = 0)).pt

Next tactic:
haveI := hS.hasHomology
lemma Exact.mono_g' (hS : S.Exact) (h : RightHomologyData S) : Mono h.g' :=
  mono_of_isZero_kernel' _ h.hι (by
    haveI := hS.hasHomology
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.41379, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
h : RightHomologyData S
this : HasHomology S
⊢ IsZero (KernelFork.ofι h.ι (_ : h.ι ≫ IsColimit.desc h.hp (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)) = 0)).pt

Next tactic:
dsimp
lemma Exact.mono_g' (hS : S.Exact) (h : RightHomologyData S) : Mono h.g' :=
  mono_of_isZero_kernel' _ h.hι (by
    haveI := hS.hasHomology
    dsimp
    

Proof state:
C : Type u_1
D : Type u_2
inst✝³ : Category.{u_3, u_1} C
inst✝² : Category.{?u.41379, u_2} D
inst✝¹ : Preadditive C
inst✝ : Preadditive D
S : ShortComplex C
hS : Exact S
h : RightHomologyData S
this : HasHomology S
⊢ IsZero h.H

Next tactic:
simpa only [← h.exact_iff] using hS
lemma LeftHomologyData.exact_iff_epi_f' [S.HasHomology] (h : LeftHomologyData S) :
    S.Exact ↔ Epi h.f' := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.43150, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : LeftHomologyData S
⊢ Exact S ↔ Epi (f' h)

Next tactic:
constructor
lemma LeftHomologyData.exact_iff_epi_f' [S.HasHomology] (h : LeftHomologyData S) :
    S.Exact ↔ Epi h.f' := by
  constructor
  · 

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.43150, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : LeftHomologyData S
⊢ Exact S → Epi (f' h)

Next tactic:
intro hS
lemma LeftHomologyData.exact_iff_epi_f' [S.HasHomology] (h : LeftHomologyData S) :
    S.Exact ↔ Epi h.f' := by
  constructor
  · intro hS
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.43150, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : LeftHomologyData S
hS : Exact S
⊢ Epi (f' h)

Next tactic:
exact hS.epi_f' h
lemma LeftHomologyData.exact_iff_epi_f' [S.HasHomology] (h : LeftHomologyData S) :
    S.Exact ↔ Epi h.f' := by
  constructor
  · intro hS
    exact hS.epi_f' h
  · 

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.43150, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : LeftHomologyData S
⊢ Epi (f' h) → Exact S

Next tactic:
intro
lemma LeftHomologyData.exact_iff_epi_f' [S.HasHomology] (h : LeftHomologyData S) :
    S.Exact ↔ Epi h.f' := by
  constructor
  · intro hS
    exact hS.epi_f' h
  · intro
    

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.43150, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : LeftHomologyData S
a✝ : Epi (f' h)
⊢ Exact S

Next tactic:
simp only [h.exact_iff, IsZero.iff_id_eq_zero, ← cancel_epi h.π, ← cancel_epi h.f',
      comp_id, h.f'_π, comp_zero]
lemma RightHomologyData.exact_iff_mono_g' [S.HasHomology] (h : RightHomologyData S) :
    S.Exact ↔ Mono h.g' := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.44224, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : RightHomologyData S
⊢ Exact S ↔ Mono (g' h)

Next tactic:
constructor
lemma RightHomologyData.exact_iff_mono_g' [S.HasHomology] (h : RightHomologyData S) :
    S.Exact ↔ Mono h.g' := by
  constructor
  · 

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.44224, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : RightHomologyData S
⊢ Exact S → Mono (g' h)

Next tactic:
intro hS
lemma RightHomologyData.exact_iff_mono_g' [S.HasHomology] (h : RightHomologyData S) :
    S.Exact ↔ Mono h.g' := by
  constructor
  · intro hS
    

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.44224, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : RightHomologyData S
hS : Exact S
⊢ Mono (g' h)

Next tactic:
exact hS.mono_g' h
lemma RightHomologyData.exact_iff_mono_g' [S.HasHomology] (h : RightHomologyData S) :
    S.Exact ↔ Mono h.g' := by
  constructor
  · intro hS
    exact hS.mono_g' h
  · 

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.44224, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : RightHomologyData S
⊢ Mono (g' h) → Exact S

Next tactic:
intro
lemma RightHomologyData.exact_iff_mono_g' [S.HasHomology] (h : RightHomologyData S) :
    S.Exact ↔ Mono h.g' := by
  constructor
  · intro hS
    exact hS.mono_g' h
  · intro
    

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁴ : Category.{u_3, u_1} C
inst✝³ : Category.{?u.44224, u_2} D
inst✝² : Preadditive C
inst✝¹ : Preadditive D
S : ShortComplex C
inst✝ : HasHomology S
h : RightHomologyData S
a✝ : Mono (g' h)
⊢ Exact S

Next tactic:
simp only [h.exact_iff, IsZero.iff_id_eq_zero, ← cancel_mono h.ι, ← cancel_mono h.g',
      id_comp, h.ι_g', zero_comp]
/-- 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 

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
⊢ (Iso.refl kf.pt).hom ≫ Fork.ι (KernelFork.ofι (Fork.ι kf) (_ : Fork.ι kf ≫ S.g = 0)) = Fork.ι kf

Next tactic:
simp
/-- 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
    

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
⊢ Epi (IsLimit.lift (IsLimit.ofIsoLimit hkf (Fork.ext (Iso.refl kf.pt))) (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)))

Next tactic:
have := hS.hasHomology
/-- 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
    

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
⊢ Epi (IsLimit.lift (IsLimit.ofIsoLimit hkf (Fork.ext (Iso.refl kf.pt))) (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)))

Next tactic:
refine' ((MorphismProperty.RespectsIso.epimorphisms C).arrow_mk_iso_iff _).1
      hS.epi_toCycles
/-- 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
    

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
⊢ Arrow.mk (toCycles S) ≅
    Arrow.mk
      (IsLimit.lift (IsLimit.ofIsoLimit hkf (Fork.ext (Iso.refl kf.pt))) (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)))

Next tactic:
refine' Arrow.isoMk (Iso.refl _)
      (IsLimit.conePointUniqueUpToIso S.cyclesIsKernel hkf) _
/-- 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) _
    

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 =
    (Arrow.mk (toCycles S)).hom ≫ (IsLimit.conePointUniqueUpToIso (cyclesIsKernel S) hkf).hom

Next tactic:
apply Fork.IsLimit.hom_ext hkf