l3lab/ntp-mathlib huggingface dataset:
@[simp] lemma ofIsLimitKernelFork_f' (hf : S.f = 0) (c : KernelFork S.g) (hc : IsLimit c) :
    (ofIsLimitKernelFork S hf c hc).f' = 0 := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
c : KernelFork S.g
hc : IsLimit c
⊢ f' (ofIsLimitKernelFork S hf c hc) = 0

Next tactic:
rw [← cancel_mono (ofIsLimitKernelFork S hf c hc).i, f'_i, hf, zero_comp]
/-- When both `S.f` and `S.g` are zero, the middle object `S.X₂` gives a left homology data on S -/
@[simps]
def ofZeros (hf : S.f = 0) (hg : S.g = 0) : S.LeftHomologyData where
  K := S.X₂
  H := S.X₂
  i := 𝟙 _
  π := 𝟙 _
  wi := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.31313, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
hg : S.g = 0
⊢ 𝟙 S.X₂ ≫ S.g = 0

Next tactic:
rw [id_comp, hg]
/-- When both `S.f` and `S.g` are zero, the middle object `S.X₂` gives a left homology data on S -/
@[simps]
def ofZeros (hf : S.f = 0) (hg : S.g = 0) : S.LeftHomologyData where
  K := S.X₂
  H := S.X₂
  i := 𝟙 _
  π := 𝟙 _
  wi := by rw [id_comp, hg]
  hi := KernelFork.IsLimit.ofId _ hg
  wπ := by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.31313, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
hg : S.g = 0
⊢ IsLimit.lift (KernelFork.IsLimit.ofId S.g hg) (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) ≫ 𝟙 S.X₂ = 0

Next tactic:
change S.f ≫ 𝟙 _ = 0
/-- When both `S.f` and `S.g` are zero, the middle object `S.X₂` gives a left homology data on S -/
@[simps]
def ofZeros (hf : S.f = 0) (hg : S.g = 0) : S.LeftHomologyData where
  K := S.X₂
  H := S.X₂
  i := 𝟙 _
  π := 𝟙 _
  wi := by rw [id_comp, hg]
  hi := KernelFork.IsLimit.ofId _ hg
  wπ := by
    change S.f ≫ 𝟙 _ = 0
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.31313, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
hg : S.g = 0
⊢ S.f ≫ 𝟙 S.X₂ = 0

Next tactic:
simp only [hf, zero_comp]
@[simp] lemma ofZeros_f' (hf : S.f = 0) (hg : S.g = 0) :
    (ofZeros S hf hg).f' = 0 := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : LeftHomologyData S
A : C
hf : S.f = 0
hg : S.g = 0
⊢ f' (ofZeros S hf hg) = 0

Next tactic:
rw [← cancel_mono ((ofZeros S hf hg).i), zero_comp, f'_i, hf]
instance : Subsingleton (LeftHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.54704, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
ψ₁ ψ₂ : LeftHomologyMapData φ h₁ h₂
⊢ ψ₁ = ψ₂

Next tactic:
have hK : ψ₁.φK = ψ₂.φK := by rw [← cancel_mono h₂.i, commi, commi]
instance : Subsingleton (LeftHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hK : ψ₁.φK = ψ₂.φK := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.54704, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
ψ₁ ψ₂ : LeftHomologyMapData φ h₁ h₂
⊢ ψ₁.φK = ψ₂.φK

Next tactic:
rw [← cancel_mono h₂.i, commi, commi]
instance : Subsingleton (LeftHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hK : ψ₁.φK = ψ₂.φK := by rw [← cancel_mono h₂.i, commi, commi]
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.54704, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
ψ₁ ψ₂ : LeftHomologyMapData φ h₁ h₂
hK : ψ₁.φK = ψ₂.φK
⊢ ψ₁ = ψ₂

Next tactic:
have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_epi h₁.π, commπ, commπ, hK]
instance : Subsingleton (LeftHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hK : ψ₁.φK = ψ₂.φK := by rw [← cancel_mono h₂.i, commi, commi]
    have hH : ψ₁.φH = ψ₂.φH := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.54704, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
ψ₁ ψ₂ : LeftHomologyMapData φ h₁ h₂
hK : ψ₁.φK = ψ₂.φK
⊢ ψ₁.φH = ψ₂.φH

Next tactic:
rw [← cancel_epi h₁.π, commπ, commπ, hK]
instance : Subsingleton (LeftHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hK : ψ₁.φK = ψ₂.φK := by rw [← cancel_mono h₂.i, commi, commi]
    have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_epi h₁.π, commπ, commπ, hK]
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.54704, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
ψ₁ ψ₂ : LeftHomologyMapData φ h₁ h₂
hK : ψ₁.φK = ψ₂.φK
hH : ψ₁.φH = ψ₂.φH
⊢ ψ₁ = ψ₂

Next tactic:
cases ψ₁
instance : Subsingleton (LeftHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hK : ψ₁.φK = ψ₂.φK := by rw [← cancel_mono h₂.i, commi, commi]
    have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_epi h₁.π, commπ, commπ, hK]
    cases ψ₁
    

Proof state:
case mk
C : Type u_1
inst✝¹ : Category.{?u.54704, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
ψ₂ : LeftHomologyMapData φ h₁ h₂
φK✝ : h₁.K ⟶ h₂.K
φH✝ : h₁.H ⟶ h₂.H
commi✝ : φK✝ ≫ h₂.i = h₁.i ≫ φ.τ₂
commf'✝ : LeftHomologyData.f' h₁ ≫ φK✝ = φ.τ₁ ≫ LeftHomologyData.f' h₂
commπ✝ : h₁.π ≫ φH✝ = φK✝ ≫ h₂.π
hK : (mk φK✝ φH✝).φK = ψ₂.φK
hH : (mk φK✝ φH✝).φH = ψ₂.φH
⊢ mk φK✝ φH✝ = ψ₂

Next tactic:
cases ψ₂
instance : Subsingleton (LeftHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hK : ψ₁.φK = ψ₂.φK := by rw [← cancel_mono h₂.i, commi, commi]
    have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_epi h₁.π, commπ, commπ, hK]
    cases ψ₁
    cases ψ₂
    

Proof state:
case mk.mk
C : Type u_1
inst✝¹ : Category.{?u.54704, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK✝¹ : h₁.K ⟶ h₂.K
φH✝¹ : h₁.H ⟶ h₂.H
commi✝¹ : φK✝¹ ≫ h₂.i = h₁.i ≫ φ.τ₂
commf'✝¹ : LeftHomologyData.f' h₁ ≫ φK✝¹ = φ.τ₁ ≫ LeftHomologyData.f' h₂
commπ✝¹ : h₁.π ≫ φH✝¹ = φK✝¹ ≫ h₂.π
φK✝ : h₁.K ⟶ h₂.K
φH✝ : h₁.H ⟶ h₂.H
commi✝ : φK✝ ≫ h₂.i = h₁.i ≫ φ.τ₂
commf'✝ : LeftHomologyData.f' h₁ ≫ φK✝ = φ.τ₁ ≫ LeftHomologyData.f' h₂
commπ✝ : h₁.π ≫ φH✝ = φK✝ ≫ h₂.π
hK : (mk φK✝¹ φH✝¹).φK = (mk φK✝ φH✝).φK
hH : (mk φK✝¹ φH✝¹).φH = (mk φK✝ φH✝).φH
⊢ mk φK✝¹ φH✝¹ = mk φK✝ φH✝

Next tactic:
congr
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
⊢ LeftHomologyMapData φ h₁ h₂

Next tactic:
let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
⊢ (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0

Next tactic:
rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp]
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
  

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK : h₁.K ⟶ h₂.K := LeftHomologyData.liftK h₂ (h₁.i ≫ φ.τ₂) (_ : (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0)
⊢ LeftHomologyMapData φ h₁ h₂

Next tactic:
have commf' : h₁.f' ≫ φK = φ.τ₁ ≫ h₂.f' := by
    rw [← cancel_mono h₂.i, assoc, assoc, LeftHomologyData.liftK_i,
      LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i, φ.comm₁₂]
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
  have commf' : h₁.f' ≫ φK = φ.τ₁ ≫ h₂.f' := by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK : h₁.K ⟶ h₂.K := LeftHomologyData.liftK h₂ (h₁.i ≫ φ.τ₂) (_ : (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0)
⊢ LeftHomologyData.f' h₁ ≫ φK = φ.τ₁ ≫ LeftHomologyData.f' h₂

Next tactic:
rw [← cancel_mono h₂.i, assoc, assoc, LeftHomologyData.liftK_i,
      LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i, φ.comm₁₂]
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
  have commf' : h₁.f' ≫ φK = φ.τ₁ ≫ h₂.f' := by
    rw [← cancel_mono h₂.i, assoc, assoc, LeftHomologyData.liftK_i,
      LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i, φ.comm₁₂]
  

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK : h₁.K ⟶ h₂.K := LeftHomologyData.liftK h₂ (h₁.i ≫ φ.τ₂) (_ : (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0)
commf' : LeftHomologyData.f' h₁ ≫ φK = φ.τ₁ ≫ LeftHomologyData.f' h₂
⊢ LeftHomologyMapData φ h₁ h₂

Next tactic:
let φH : h₁.H ⟶ h₂.H := h₁.descH (φK ≫ h₂.π)
    (by rw [reassoc_of% commf', h₂.f'_π, comp_zero])
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
  have commf' : h₁.f' ≫ φK = φ.τ₁ ≫ h₂.f' := by
    rw [← cancel_mono h₂.i, assoc, assoc, LeftHomologyData.liftK_i,
      LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i, φ.comm₁₂]
  let φH : h₁.H ⟶ h₂.H := h₁.descH (φK ≫ h₂.π)
    (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK : h₁.K ⟶ h₂.K := LeftHomologyData.liftK h₂ (h₁.i ≫ φ.τ₂) (_ : (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0)
commf' : LeftHomologyData.f' h₁ ≫ φK = φ.τ₁ ≫ LeftHomologyData.f' h₂
⊢ LeftHomologyData.f' h₁ ≫ φK ≫ h₂.π = 0

Next tactic:
rw [reassoc_of% commf', h₂.f'_π, comp_zero]
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
  have commf' : h₁.f' ≫ φK = φ.τ₁ ≫ h₂.f' := by
    rw [← cancel_mono h₂.i, assoc, assoc, LeftHomologyData.liftK_i,
      LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i, φ.comm₁₂]
  let φH : h₁.H ⟶ h₂.H := h₁.descH (φK ≫ h₂.π)
    (by rw [reassoc_of% commf', h₂.f'_π, comp_zero])
  

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK : h₁.K ⟶ h₂.K := LeftHomologyData.liftK h₂ (h₁.i ≫ φ.τ₂) (_ : (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0)
commf' : LeftHomologyData.f' h₁ ≫ φK = φ.τ₁ ≫ LeftHomologyData.f' h₂
φH : h₁.H ⟶ h₂.H := LeftHomologyData.descH h₁ (φK ≫ h₂.π) (_ : LeftHomologyData.f' h₁ ≫ φK ≫ h₂.π = 0)
⊢ LeftHomologyMapData φ h₁ h₂

Next tactic:
exact ⟨φK, φH, by simp, commf', by simp⟩
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
  have commf' : h₁.f' ≫ φK = φ.τ₁ ≫ h₂.f' := by
    rw [← cancel_mono h₂.i, assoc, assoc, LeftHomologyData.liftK_i,
      LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i, φ.comm₁₂]
  let φH : h₁.H ⟶ h₂.H := h₁.descH (φK ≫ h₂.π)
    (by rw [reassoc_of% commf', h₂.f'_π, comp_zero])
  exact ⟨φK, φH, by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK : h₁.K ⟶ h₂.K := LeftHomologyData.liftK h₂ (h₁.i ≫ φ.τ₂) (_ : (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0)
commf' : LeftHomologyData.f' h₁ ≫ φK = φ.τ₁ ≫ LeftHomologyData.f' h₂
φH : h₁.H ⟶ h₂.H := LeftHomologyData.descH h₁ (φK ≫ h₂.π) (_ : LeftHomologyData.f' h₁ ≫ φK ≫ h₂.π = 0)
⊢ φK ≫ h₂.i = h₁.i ≫ φ.τ₂

Next tactic:
simp
instance : Inhabited (LeftHomologyMapData φ h₁ h₂) := ⟨by
  let φK : h₁.K ⟶ h₂.K := h₂.liftK (h₁.i ≫ φ.τ₂)
    (by rw [assoc, φ.comm₂₃, h₁.wi_assoc, zero_comp])
  have commf' : h₁.f' ≫ φK = φ.τ₁ ≫ h₂.f' := by
    rw [← cancel_mono h₂.i, assoc, assoc, LeftHomologyData.liftK_i,
      LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i, φ.comm₁₂]
  let φH : h₁.H ⟶ h₂.H := h₁.descH (φK ≫ h₂.π)
    (by rw [reassoc_of% commf', h₂.f'_π, comp_zero])
  exact ⟨φK, φH, by simp, commf', by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.57189, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φK : h₁.K ⟶ h₂.K := LeftHomologyData.liftK h₂ (h₁.i ≫ φ.τ₂) (_ : (h₁.i ≫ φ.τ₂) ≫ S₂.g = 0)
commf' : LeftHomologyData.f' h₁ ≫ φK = φ.τ₁ ≫ LeftHomologyData.f' h₂
φH : h₁.H ⟶ h₂.H := LeftHomologyData.descH h₁ (φK ≫ h₂.π) (_ : LeftHomologyData.f' h₁ ≫ φK ≫ h₂.π = 0)
⊢ h₁.π ≫ φH = φK ≫ h₂.π

Next tactic:
simp
lemma congr_φH {γ₁ γ₂ : LeftHomologyMapData φ h₁ h₂} (eq : γ₁ = γ₂) : γ₁.φH = γ₂.φH := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
γ₁ γ₂ : LeftHomologyMapData φ h₁ h₂
eq : γ₁ = γ₂
⊢ γ₁.φH = γ₂.φH

Next tactic:
rw [eq]
lemma congr_φK {γ₁ γ₂ : LeftHomologyMapData φ h₁ h₂} (eq : γ₁ = γ₂) : γ₁.φK = γ₂.φK := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
γ₁ γ₂ : LeftHomologyMapData φ h₁ h₂
eq : γ₁ = γ₂
⊢ γ₁.φK = γ₂.φK

Next tactic:
rw [eq]
/-- When `S₁.g` and `S₂.g` are zero and we have chosen colimit cokernel coforks `c₁` and `c₂`
for `S₁.f` and `S₂.f` respectively, the action on left homology of a morphism `φ : S₁ ⟶ S₂` of
short complexes is given by the unique morphism `f : c₁.pt ⟶ c₂.pt` such that
`φ.τ₂ ≫ c₂.π = c₁.π ≫ f`. -/
@[simps]
def ofIsColimitCokernelCofork (φ : S₁ ⟶ S₂)
    (hg₁ : S₁.g = 0) (c₁ : CokernelCofork S₁.f) (hc₁ : IsColimit c₁)
    (hg₂ : S₂.g = 0) (c₂ : CokernelCofork S₂.f) (hc₂ : IsColimit c₂) (f : c₁.pt ⟶ c₂.pt)
    (comm : φ.τ₂ ≫ c₂.π = c₁.π ≫ f) :
    LeftHomologyMapData φ (LeftHomologyData.ofIsColimitCokernelCofork S₁ hg₁ c₁ hc₁)
      (LeftHomologyData.ofIsColimitCokernelCofork S₂ hg₂ c₂ hc₂) where
  φK := φ.τ₂
  φH := f
  commπ := comm.symm
  commf' := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.66976, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ✝ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
φ : S₁ ⟶ S₂
hg₁ : S₁.g = 0
c₁ : CokernelCofork S₁.f
hc₁ : IsColimit c₁
hg₂ : S₂.g = 0
c₂ : CokernelCofork S₂.f
hc₂ : IsColimit c₂
f : c₁.pt ⟶ c₂.pt
comm : φ.τ₂ ≫ Cofork.π c₂ = Cofork.π c₁ ≫ f
⊢ LeftHomologyData.f' (LeftHomologyData.ofIsColimitCokernelCofork S₁ hg₁ c₁ hc₁) ≫ φ.τ₂ =
    φ.τ₁ ≫ LeftHomologyData.f' (LeftHomologyData.ofIsColimitCokernelCofork S₂ hg₂ c₂ hc₂)

Next tactic:
simp only [LeftHomologyData.ofIsColimitCokernelCofork_f', φ.comm₁₂]
instance : Mono S.iCycles := by
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.88053, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
⊢ Mono (iCycles S)

Next tactic:
dsimp only [iCycles]
instance : Mono S.iCycles := by
  dsimp only [iCycles]
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.88053, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
⊢ Mono (leftHomologyData S).i

Next tactic:
infer_instance
instance : Epi S.leftHomologyπ := by
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.88431, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
⊢ Epi (leftHomologyπ S)

Next tactic:
dsimp only [leftHomologyπ]
instance : Epi S.leftHomologyπ := by
  dsimp only [leftHomologyπ]
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.88431, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
⊢ Epi (leftHomologyData S).π

Next tactic:
infer_instance
lemma leftHomology_ext_iff (f₁ f₂ : S.leftHomology ⟶ A) :
    f₁ = f₂ ↔ S.leftHomologyπ ≫ f₁ = S.leftHomologyπ ≫ f₂ := by
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
A : C
f₁ f₂ : leftHomology S ⟶ A
⊢ f₁ = f₂ ↔ leftHomologyπ S ≫ f₁ = leftHomologyπ S ≫ f₂

Next tactic:
rw [cancel_epi]
@[ext]
lemma leftHomology_ext (f₁ f₂ : S.leftHomology ⟶ A)
    (h : S.leftHomologyπ ≫ f₁ = S.leftHomologyπ ≫ f₂) : f₁ = f₂ := by
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
A : C
f₁ f₂ : leftHomology S ⟶ A
h : leftHomologyπ S ≫ f₁ = leftHomologyπ S ≫ f₂
⊢ f₁ = f₂

Next tactic:
simpa only [leftHomology_ext_iff] using h
lemma cycles_ext_iff (f₁ f₂ : A ⟶ S.cycles) :
    f₁ = f₂ ↔ f₁ ≫ S.iCycles = f₂ ≫ S.iCycles := by
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
A : C
f₁ f₂ : A ⟶ cycles S
⊢ f₁ = f₂ ↔ f₁ ≫ iCycles S = f₂ ≫ iCycles S

Next tactic:
rw [cancel_mono]
@[ext]
lemma cycles_ext (f₁ f₂ : A ⟶ S.cycles) (h : f₁ ≫ S.iCycles = f₂ ≫ S.iCycles) : f₁ = f₂ := by
  

Proof state:
C : Type u_1
inst✝² : Category.{u_2, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
A : C
f₁ f₂ : A ⟶ cycles S
h : f₁ ≫ iCycles S = f₂ ≫ iCycles S
⊢ f₁ = f₂

Next tactic:
simpa only [cycles_ext_iff] using h
/-- When `S.g = 0`, this is the canonical isomorphism `S.cycles ≅ S.X₂` induced by `S.iCycles`. -/
@[simps! hom]
noncomputable def cyclesIsoX₂ (hg : S.g = 0) : S.cycles ≅ S.X₂ := by
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.92167, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
hg : S.g = 0
⊢ cycles S ≅ S.X₂

Next tactic:
have := S.isIso_iCycles hg
/-- When `S.g = 0`, this is the canonical isomorphism `S.cycles ≅ S.X₂` induced by `S.iCycles`. -/
@[simps! hom]
noncomputable def cyclesIsoX₂ (hg : S.g = 0) : S.cycles ≅ S.X₂ := by
  have := S.isIso_iCycles hg
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.92167, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
hg : S.g = 0
this : IsIso (iCycles S)
⊢ cycles S ≅ S.X₂

Next tactic:
exact asIso S.iCycles
/-- When `S.f = 0`, this is the canonical isomorphism `S.cycles ≅ S.leftHomology` induced
by `S.leftHomologyπ`. -/
@[simps! hom]
noncomputable def cyclesIsoLeftHomology (hf : S.f = 0) : S.cycles ≅ S.leftHomology := by
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.95085, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
hf : S.f = 0
⊢ cycles S ≅ leftHomology S

Next tactic:
have := S.isIso_leftHomologyπ hf
/-- When `S.f = 0`, this is the canonical isomorphism `S.cycles ≅ S.leftHomology` induced
by `S.leftHomologyπ`. -/
@[simps! hom]
noncomputable def cyclesIsoLeftHomology (hf : S.f = 0) : S.cycles ≅ S.leftHomology := by
  have := S.isIso_leftHomologyπ hf
  

Proof state:
C : Type u_1
inst✝² : Category.{?u.95085, u_1} C
inst✝¹ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
inst✝ : HasLeftHomology S
hf : S.f = 0
this : IsIso (leftHomologyπ S)
⊢ cycles S ≅ leftHomology S

Next tactic:
exact asIso S.leftHomologyπ
@[reassoc (attr := simp)]
lemma f'_cyclesMap' : h₁.f' ≫ cyclesMap' φ h₁ h₂ = φ.τ₁ ≫ h₂.f' := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
⊢ LeftHomologyData.f' h₁ ≫ cyclesMap' φ h₁ h₂ = φ.τ₁ ≫ LeftHomologyData.f' h₂

Next tactic:
simp only [← cancel_mono h₂.i, assoc, φ.comm₁₂, cyclesMap'_i,
    LeftHomologyData.f'_i_assoc, LeftHomologyData.f'_i]
@[reassoc]
lemma leftHomologyMap'_comp (φ₁ : S₁ ⟶ S₂) (φ₂ : S₂ ⟶ S₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) (h₃ : S₃.LeftHomologyData) :
    leftHomologyMap' (φ₁ ≫ φ₂) h₁ h₃ = leftHomologyMap' φ₁ h₁ h₂ ≫
      leftHomologyMap' φ₂ h₂ h₃ := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ₁ : S₁ ⟶ S₂
φ₂ : S₂ ⟶ S₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
h₃ : LeftHomologyData S₃
⊢ leftHomologyMap' (φ₁ ≫ φ₂) h₁ h₃ = leftHomologyMap' φ₁ h₁ h₂ ≫ leftHomologyMap' φ₂ h₂ h₃

Next tactic:
let γ₁ := leftHomologyMapData φ₁ h₁ h₂
@[reassoc]
lemma leftHomologyMap'_comp (φ₁ : S₁ ⟶ S₂) (φ₂ : S₂ ⟶ S₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) (h₃ : S₃.LeftHomologyData) :
    leftHomologyMap' (φ₁ ≫ φ₂) h₁ h₃ = leftHomologyMap' φ₁ h₁ h₂ ≫
      leftHomologyMap' φ₂ h₂ h₃ := by
  let γ₁ := leftHomologyMapData φ₁ h₁ h₂
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ₁ : S₁ ⟶ S₂
φ₂ : S₂ ⟶ S₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
h₃ : LeftHomologyData S₃
γ₁ : LeftHomologyMapData φ₁ h₁ h₂ := leftHomologyMapData φ₁ h₁ h₂
⊢ leftHomologyMap' (φ₁ ≫ φ₂) h₁ h₃ = leftHomologyMap' φ₁ h₁ h₂ ≫ leftHomologyMap' φ₂ h₂ h₃

Next tactic:
let γ₂ := leftHomologyMapData φ₂ h₂ h₃
@[reassoc]
lemma leftHomologyMap'_comp (φ₁ : S₁ ⟶ S₂) (φ₂ : S₂ ⟶ S₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) (h₃ : S₃.LeftHomologyData) :
    leftHomologyMap' (φ₁ ≫ φ₂) h₁ h₃ = leftHomologyMap' φ₁ h₁ h₂ ≫
      leftHomologyMap' φ₂ h₂ h₃ := by
  let γ₁ := leftHomologyMapData φ₁ h₁ h₂
  let γ₂ := leftHomologyMapData φ₂ h₂ h₃
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ₁ : S₁ ⟶ S₂
φ₂ : S₂ ⟶ S₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
h₃ : LeftHomologyData S₃
γ₁ : LeftHomologyMapData φ₁ h₁ h₂ := leftHomologyMapData φ₁ h₁ h₂
γ₂ : LeftHomologyMapData φ₂ h₂ h₃ := leftHomologyMapData φ₂ h₂ h₃
⊢ leftHomologyMap' (φ₁ ≫ φ₂) h₁ h₃ = leftHomologyMap' φ₁ h₁ h₂ ≫ leftHomologyMap' φ₂ h₂ h₃

Next tactic:
rw [γ₁.leftHomologyMap'_eq, γ₂.leftHomologyMap'_eq, (γ₁.comp γ₂).leftHomologyMap'_eq,
    LeftHomologyMapData.comp_φH]
@[reassoc]
lemma cyclesMap'_comp (φ₁ : S₁ ⟶ S₂) (φ₂ : S₂ ⟶ S₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) (h₃ : S₃.LeftHomologyData) :
    cyclesMap' (φ₁ ≫ φ₂) h₁ h₃ = cyclesMap' φ₁ h₁ h₂ ≫ cyclesMap' φ₂ h₂ h₃ := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ₁ : S₁ ⟶ S₂
φ₂ : S₂ ⟶ S₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
h₃ : LeftHomologyData S₃
⊢ cyclesMap' (φ₁ ≫ φ₂) h₁ h₃ = cyclesMap' φ₁ h₁ h₂ ≫ cyclesMap' φ₂ h₂ h₃

Next tactic:
let γ₁ := leftHomologyMapData φ₁ h₁ h₂
@[reassoc]
lemma cyclesMap'_comp (φ₁ : S₁ ⟶ S₂) (φ₂ : S₂ ⟶ S₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) (h₃ : S₃.LeftHomologyData) :
    cyclesMap' (φ₁ ≫ φ₂) h₁ h₃ = cyclesMap' φ₁ h₁ h₂ ≫ cyclesMap' φ₂ h₂ h₃ := by
  let γ₁ := leftHomologyMapData φ₁ h₁ h₂
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ₁ : S₁ ⟶ S₂
φ₂ : S₂ ⟶ S₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
h₃ : LeftHomologyData S₃
γ₁ : LeftHomologyMapData φ₁ h₁ h₂ := leftHomologyMapData φ₁ h₁ h₂
⊢ cyclesMap' (φ₁ ≫ φ₂) h₁ h₃ = cyclesMap' φ₁ h₁ h₂ ≫ cyclesMap' φ₂ h₂ h₃

Next tactic:
let γ₂ := leftHomologyMapData φ₂ h₂ h₃
@[reassoc]
lemma cyclesMap'_comp (φ₁ : S₁ ⟶ S₂) (φ₂ : S₂ ⟶ S₃)
    (h₁ : S₁.LeftHomologyData) (h₂ : S₂.LeftHomologyData) (h₃ : S₃.LeftHomologyData) :
    cyclesMap' (φ₁ ≫ φ₂) h₁ h₃ = cyclesMap' φ₁ h₁ h₂ ≫ cyclesMap' φ₂ h₂ h₃ := by
  let γ₁ := leftHomologyMapData φ₁ h₁ h₂
  let γ₂ := leftHomologyMapData φ₂ h₂ h₃
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ₁ : S₁ ⟶ S₂
φ₂ : S₂ ⟶ S₃
h₁ : LeftHomologyData S₁
h₂ : LeftHomologyData S₂
h₃ : LeftHomologyData S₃
γ₁ : LeftHomologyMapData φ₁ h₁ h₂ := leftHomologyMapData φ₁ h₁ h₂
γ₂ : LeftHomologyMapData φ₂ h₂ h₃ := leftHomologyMapData φ₂ h₂ h₃
⊢ cyclesMap' (φ₁ ≫ φ₂) h₁ h₃ = cyclesMap' φ₁ h₁ h₂ ≫ cyclesMap' φ₂ h₂ h₃

Next tactic:
rw [γ₁.cyclesMap'_eq, γ₂.cyclesMap'_eq, (γ₁.comp γ₂).cyclesMap'_eq,
    LeftHomologyMapData.comp_φK]