l3lab/ntp-mathlib huggingface dataset:
/-- In a balanced category, if a short complex `S` is exact and `S.f` is a mono, then
`S.X₁` is the kernel of `S.g`. -/
noncomputable def fIsKernel [Mono S.f] : IsLimit (KernelFork.ofι S.f S.zero) := by
  have := hS.hasHomology
  have := hS.isIso_toCycles
  

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

Next tactic:
exact IsLimit.ofIsoLimit S.cyclesIsKernel
    (Fork.ext (asIso S.toCycles).symm (by simp))
/-- In a balanced category, if a short complex `S` is exact and `S.f` is a mono, then
`S.X₁` is the kernel of `S.g`. -/
noncomputable def fIsKernel [Mono S.f] : IsLimit (KernelFork.ofι S.f S.zero) := by
  have := hS.hasHomology
  have := hS.isIso_toCycles
  exact IsLimit.ofIsoLimit S.cyclesIsKernel
    (Fork.ext (asIso S.toCycles).symm (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{?u.149920, u_1} C
inst✝⁴ : Category.{?u.149924, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
hS : Exact S
inst✝ : Mono S.f
this✝ : HasHomology S
this : IsIso (toCycles S)
⊢ (asIso (toCycles S)).symm.hom ≫ Fork.ι (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)) =
    Fork.ι (KernelFork.ofι (iCycles S) (_ : iCycles S ≫ S.g = 0))

Next tactic:
simp
/-- In a balanced category, if a short complex `S` is exact and `S.g` is an epi, then
`S.X₃` is the cokernel of `S.g`. -/
noncomputable def gIsCokernel [Epi S.g] : IsColimit (CokernelCofork.ofπ S.g S.zero) := by
  

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

Next tactic:
have := hS.hasHomology
/-- In a balanced category, if a short complex `S` is exact and `S.g` is an epi, then
`S.X₃` is the cokernel of `S.g`. -/
noncomputable def gIsCokernel [Epi S.g] : IsColimit (CokernelCofork.ofπ S.g S.zero) := by
  have := hS.hasHomology
  

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

Next tactic:
have := hS.isIso_fromOpcycles
/-- In a balanced category, if a short complex `S` is exact and `S.g` is an epi, then
`S.X₃` is the cokernel of `S.g`. -/
noncomputable def gIsCokernel [Epi S.g] : IsColimit (CokernelCofork.ofπ S.g S.zero) := by
  have := hS.hasHomology
  have := hS.isIso_fromOpcycles
  

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

Next tactic:
exact IsColimit.ofIsoColimit S.opcyclesIsCokernel
    (Cofork.ext (asIso S.fromOpcycles) (by simp))
/-- In a balanced category, if a short complex `S` is exact and `S.g` is an epi, then
`S.X₃` is the cokernel of `S.g`. -/
noncomputable def gIsCokernel [Epi S.g] : IsColimit (CokernelCofork.ofπ S.g S.zero) := by
  have := hS.hasHomology
  have := hS.isIso_fromOpcycles
  exact IsColimit.ofIsoColimit S.opcyclesIsCokernel
    (Cofork.ext (asIso S.fromOpcycles) (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{?u.154768, u_1} C
inst✝⁴ : Category.{?u.154772, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
hS : Exact S
inst✝ : Epi S.g
this✝ : HasHomology S
this : IsIso (fromOpcycles S)
⊢ Cofork.π (CokernelCofork.ofπ (pOpcycles S) (_ : S.f ≫ pOpcycles S = 0)) ≫ (asIso (fromOpcycles S)).hom =
    Cofork.π (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))

Next tactic:
simp
lemma lift' {A : C} (k : A ⟶ S.X₂) (hk : k ≫ S.g = 0) [Mono S.f] :
    ∃ (l : A ⟶ S.X₁), l ≫ S.f = k :=
  ⟨hS.lift k hk, by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.161349, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
hS : Exact S
A : C
k : A ⟶ S.X₂
hk : k ≫ S.g = 0
inst✝ : Mono S.f
⊢ lift hS k hk ≫ S.f = k

Next tactic:
simp
lemma desc' {A : C} (k : S.X₂ ⟶ A) (hk : S.f ≫ k = 0) [Epi S.g] :
    ∃ (l : S.X₃ ⟶ A), S.g ≫ l = k :=
  ⟨hS.desc k hk, by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.164487, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
hS : Exact S
A : C
k : S.X₂ ⟶ A
hk : S.f ≫ k = 0
inst✝ : Epi S.g
⊢ S.g ≫ desc hS k hk = k

Next tactic:
simp
lemma mono_τ₂_of_exact_of_mono {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₁ : S₁.Exact) [Mono S₁.f] [Mono S₂.f] [Mono φ.τ₁] [Mono φ.τ₃] : Mono φ.τ₂ := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.165388, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : Exact S₁
inst✝³ : Mono S₁.f
inst✝² : Mono S₂.f
inst✝¹ : Mono φ.τ₁
inst✝ : Mono φ.τ₃
⊢ Mono φ.τ₂

Next tactic:
rw [mono_iff_cancel_zero]
lemma mono_τ₂_of_exact_of_mono {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₁ : S₁.Exact) [Mono S₁.f] [Mono S₂.f] [Mono φ.τ₁] [Mono φ.τ₃] : Mono φ.τ₂ := by
  rw [mono_iff_cancel_zero]
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.165388, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : Exact S₁
inst✝³ : Mono S₁.f
inst✝² : Mono S₂.f
inst✝¹ : Mono φ.τ₁
inst✝ : Mono φ.τ₃
⊢ ∀ (P : C) (g : P ⟶ S₁.X₂), g ≫ φ.τ₂ = 0 → g = 0

Next tactic:
intro A x₂ hx₂
lemma mono_τ₂_of_exact_of_mono {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₁ : S₁.Exact) [Mono S₁.f] [Mono S₂.f] [Mono φ.τ₁] [Mono φ.τ₃] : Mono φ.τ₂ := by
  rw [mono_iff_cancel_zero]
  intro A x₂ hx₂
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.165388, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : Exact S₁
inst✝³ : Mono S₁.f
inst✝² : Mono S₂.f
inst✝¹ : Mono φ.τ₁
inst✝ : Mono φ.τ₃
A : C
x₂ : A ⟶ S₁.X₂
hx₂ : x₂ ≫ φ.τ₂ = 0
⊢ x₂ = 0

Next tactic:
obtain ⟨x₁, hx₁⟩ : ∃ x₁, x₁ ≫ S₁.f = x₂ := ⟨_, h₁.lift_f x₂
    (by simp only [← cancel_mono φ.τ₃, assoc, zero_comp, ← φ.comm₂₃, reassoc_of% hx₂])⟩
lemma mono_τ₂_of_exact_of_mono {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₁ : S₁.Exact) [Mono S₁.f] [Mono S₂.f] [Mono φ.τ₁] [Mono φ.τ₃] : Mono φ.τ₂ := by
  rw [mono_iff_cancel_zero]
  intro A x₂ hx₂
  obtain ⟨x₁, hx₁⟩ : ∃ x₁, x₁ ≫ S₁.f = x₂ := ⟨_, h₁.lift_f x₂
    (by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.165388, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : Exact S₁
inst✝³ : Mono S₁.f
inst✝² : Mono S₂.f
inst✝¹ : Mono φ.τ₁
inst✝ : Mono φ.τ₃
A : C
x₂ : A ⟶ S₁.X₂
hx₂ : x₂ ≫ φ.τ₂ = 0
⊢ x₂ ≫ S₁.g = 0

Next tactic:
simp only [← cancel_mono φ.τ₃, assoc, zero_comp, ← φ.comm₂₃, reassoc_of% hx₂]
lemma mono_τ₂_of_exact_of_mono {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₁ : S₁.Exact) [Mono S₁.f] [Mono S₂.f] [Mono φ.τ₁] [Mono φ.τ₃] : Mono φ.τ₂ := by
  rw [mono_iff_cancel_zero]
  intro A x₂ hx₂
  obtain ⟨x₁, hx₁⟩ : ∃ x₁, x₁ ≫ S₁.f = x₂ := ⟨_, h₁.lift_f x₂
    (by simp only [← cancel_mono φ.τ₃, assoc, zero_comp, ← φ.comm₂₃, reassoc_of% hx₂])⟩
  

Proof state:
case intro
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.165388, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : Exact S₁
inst✝³ : Mono S₁.f
inst✝² : Mono S₂.f
inst✝¹ : Mono φ.τ₁
inst✝ : Mono φ.τ₃
A : C
x₂ : A ⟶ S₁.X₂
hx₂ : x₂ ≫ φ.τ₂ = 0
x₁ : A ⟶ S₁.X₁
hx₁ : x₁ ≫ S₁.f = x₂
⊢ x₂ = 0

Next tactic:
suffices x₁ = 0 by rw [← hx₁, this, zero_comp]
lemma mono_τ₂_of_exact_of_mono {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₁ : S₁.Exact) [Mono S₁.f] [Mono S₂.f] [Mono φ.τ₁] [Mono φ.τ₃] : Mono φ.τ₂ := by
  rw [mono_iff_cancel_zero]
  intro A x₂ hx₂
  obtain ⟨x₁, hx₁⟩ : ∃ x₁, x₁ ≫ S₁.f = x₂ := ⟨_, h₁.lift_f x₂
    (by simp only [← cancel_mono φ.τ₃, assoc, zero_comp, ← φ.comm₂₃, reassoc_of% hx₂])⟩
  suffices x₁ = 0 by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.165388, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : Exact S₁
inst✝³ : Mono S₁.f
inst✝² : Mono S₂.f
inst✝¹ : Mono φ.τ₁
inst✝ : Mono φ.τ₃
A : C
x₂ : A ⟶ S₁.X₂
hx₂ : x₂ ≫ φ.τ₂ = 0
x₁ : A ⟶ S₁.X₁
hx₁ : x₁ ≫ S₁.f = x₂
this : x₁ = 0
⊢ x₂ = 0

Next tactic:
rw [← hx₁, this, zero_comp]
lemma mono_τ₂_of_exact_of_mono {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₁ : S₁.Exact) [Mono S₁.f] [Mono S₂.f] [Mono φ.τ₁] [Mono φ.τ₃] : Mono φ.τ₂ := by
  rw [mono_iff_cancel_zero]
  intro A x₂ hx₂
  obtain ⟨x₁, hx₁⟩ : ∃ x₁, x₁ ≫ S₁.f = x₂ := ⟨_, h₁.lift_f x₂
    (by simp only [← cancel_mono φ.τ₃, assoc, zero_comp, ← φ.comm₂₃, reassoc_of% hx₂])⟩
  suffices x₁ = 0 by rw [← hx₁, this, zero_comp]
  

Proof state:
case intro
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.165388, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : Exact S₁
inst✝³ : Mono S₁.f
inst✝² : Mono S₂.f
inst✝¹ : Mono φ.τ₁
inst✝ : Mono φ.τ₃
A : C
x₂ : A ⟶ S₁.X₂
hx₂ : x₂ ≫ φ.τ₂ = 0
x₁ : A ⟶ S₁.X₁
hx₁ : x₁ ≫ S₁.f = x₂
⊢ x₁ = 0

Next tactic:
simp only [← cancel_mono φ.τ₁, ← cancel_mono S₂.f, assoc, φ.comm₁₂, zero_comp,
    reassoc_of% hx₁, hx₂]
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
⊢ Epi φ.τ₂

Next tactic:
have : Mono S₁.op.f := by dsimp; infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
⊢ Mono (op S₁).f

Next tactic:
dsimp
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
⊢ Mono S₁.g.op

Next tactic:
infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this : Mono (op S₁).f
⊢ Epi φ.τ₂

Next tactic:
have : Mono S₂.op.f := by dsimp; infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this : Mono (op S₁).f
⊢ Mono (op S₂).f

Next tactic:
dsimp
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this : Mono (op S₁).f
⊢ Mono S₂.g.op

Next tactic:
infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝ : Mono (op S₁).f
this : Mono (op S₂).f
⊢ Epi φ.τ₂

Next tactic:
have : Mono (opMap φ).τ₁ := by dsimp; infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  have : Mono (opMap φ).τ₁ := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝ : Mono (op S₁).f
this : Mono (op S₂).f
⊢ Mono (opMap φ).τ₁

Next tactic:
dsimp
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  have : Mono (opMap φ).τ₁ := by dsimp; 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝ : Mono (op S₁).f
this : Mono (op S₂).f
⊢ Mono φ.τ₃.op

Next tactic:
infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  have : Mono (opMap φ).τ₁ := by dsimp; infer_instance
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝¹ : Mono (op S₁).f
this✝ : Mono (op S₂).f
this : Mono (opMap φ).τ₁
⊢ Epi φ.τ₂

Next tactic:
have : Mono (opMap φ).τ₃ := by dsimp; infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  have : Mono (opMap φ).τ₁ := by dsimp; infer_instance
  have : Mono (opMap φ).τ₃ := by 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝¹ : Mono (op S₁).f
this✝ : Mono (op S₂).f
this : Mono (opMap φ).τ₁
⊢ Mono (opMap φ).τ₃

Next tactic:
dsimp
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  have : Mono (opMap φ).τ₁ := by dsimp; infer_instance
  have : Mono (opMap φ).τ₃ := by dsimp; 

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝¹ : Mono (op S₁).f
this✝ : Mono (op S₂).f
this : Mono (opMap φ).τ₁
⊢ Mono φ.τ₁.op

Next tactic:
infer_instance
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  have : Mono (opMap φ).τ₁ := by dsimp; infer_instance
  have : Mono (opMap φ).τ₃ := by dsimp; infer_instance
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝² : Mono (op S₁).f
this✝¹ : Mono (op S₂).f
this✝ : Mono (opMap φ).τ₁
this : Mono (opMap φ).τ₃
⊢ Epi φ.τ₂

Next tactic:
have := mono_τ₂_of_exact_of_mono (opMap φ) h₂.op
lemma epi_τ₂_of_exact_of_epi {S₁ S₂ : ShortComplex C} (φ : S₁ ⟶ S₂)
    (h₂ : S₂.Exact) [Epi S₁.g] [Epi S₂.g] [Epi φ.τ₁] [Epi φ.τ₃] : Epi φ.τ₂ := by
  have : Mono S₁.op.f := by dsimp; infer_instance
  have : Mono S₂.op.f := by dsimp; infer_instance
  have : Mono (opMap φ).τ₁ := by dsimp; infer_instance
  have : Mono (opMap φ).τ₃ := by dsimp; infer_instance
  have := mono_τ₂_of_exact_of_mono (opMap φ) h₂.op
  

Proof state:
C : Type u_1
D : Type u_2
inst✝⁸ : Category.{u_3, u_1} C
inst✝⁷ : Category.{?u.168986, u_2} D
inst✝⁶ : Preadditive C
inst✝⁵ : Preadditive D
S : ShortComplex C
inst✝⁴ : Balanced C
S₁ S₂ : ShortComplex C
φ : S₁ ⟶ S₂
h₂ : Exact S₂
inst✝³ : Epi S₁.g
inst✝² : Epi S₂.g
inst✝¹ : Epi φ.τ₁
inst✝ : Epi φ.τ₃
this✝³ : Mono (op S₁).f
this✝² : Mono (op S₂).f
this✝¹ : Mono (opMap φ).τ₁
this✝ : Mono (opMap φ).τ₃
this : Mono (opMap φ).τ₂
⊢ Epi φ.τ₂

Next tactic:
exact unop_epi_of_mono (opMap φ).τ₂
lemma exact_and_mono_f_iff_f_is_kernel [S.HasHomology] :
    S.Exact ∧ Mono S.f ↔ Nonempty (IsLimit (KernelFork.ofι 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.173202, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
⊢ Exact S ∧ Mono S.f ↔ Nonempty (IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)))

Next tactic:
constructor
lemma exact_and_mono_f_iff_f_is_kernel [S.HasHomology] :
    S.Exact ∧ Mono S.f ↔ Nonempty (IsLimit (KernelFork.ofι S.f S.zero)) := by
  constructor
  · 

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.173202, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
⊢ Exact S ∧ Mono S.f → Nonempty (IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)))

Next tactic:
intro ⟨hS, _⟩
lemma exact_and_mono_f_iff_f_is_kernel [S.HasHomology] :
    S.Exact ∧ Mono S.f ↔ Nonempty (IsLimit (KernelFork.ofι S.f S.zero)) := 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.173202, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
hS : Exact S
right✝ : Mono S.f
⊢ Nonempty (IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0)))

Next tactic:
exact ⟨hS.fIsKernel⟩
lemma exact_and_mono_f_iff_f_is_kernel [S.HasHomology] :
    S.Exact ∧ Mono S.f ↔ Nonempty (IsLimit (KernelFork.ofι S.f S.zero)) := by
  constructor
  · intro ⟨hS, _⟩
    exact ⟨hS.fIsKernel⟩
  · 

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.173202, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
⊢ Nonempty (IsLimit (KernelFork.ofι S.f (_ : S.f ≫ S.g = 0))) → Exact S ∧ Mono S.f

Next tactic:
intro ⟨hS⟩
lemma exact_and_mono_f_iff_f_is_kernel [S.HasHomology] :
    S.Exact ∧ Mono S.f ↔ Nonempty (IsLimit (KernelFork.ofι S.f S.zero)) := by
  constructor
  · intro ⟨hS, _⟩
    exact ⟨hS.fIsKernel⟩
  · intro ⟨hS⟩
    

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

Next tactic:
exact ⟨S.exact_of_f_is_kernel hS, mono_of_isLimit_fork hS⟩
lemma exact_and_epi_g_iff_g_is_cokernel [S.HasHomology] :
    S.Exact ∧ Epi S.g ↔ Nonempty (IsColimit (CokernelCofork.ofπ 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.174454, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
⊢ Exact S ∧ Epi S.g ↔ Nonempty (IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))

Next tactic:
constructor
lemma exact_and_epi_g_iff_g_is_cokernel [S.HasHomology] :
    S.Exact ∧ Epi S.g ↔ Nonempty (IsColimit (CokernelCofork.ofπ S.g S.zero)) := by
  constructor
  · 

Proof state:
case mp
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.174454, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
⊢ Exact S ∧ Epi S.g → Nonempty (IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))

Next tactic:
intro ⟨hS, _⟩
lemma exact_and_epi_g_iff_g_is_cokernel [S.HasHomology] :
    S.Exact ∧ Epi S.g ↔ Nonempty (IsColimit (CokernelCofork.ofπ S.g S.zero)) := 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.174454, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
hS : Exact S
right✝ : Epi S.g
⊢ Nonempty (IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)))

Next tactic:
exact ⟨hS.gIsCokernel⟩
lemma exact_and_epi_g_iff_g_is_cokernel [S.HasHomology] :
    S.Exact ∧ Epi S.g ↔ Nonempty (IsColimit (CokernelCofork.ofπ S.g S.zero)) := by
  constructor
  · intro ⟨hS, _⟩
    exact ⟨hS.gIsCokernel⟩
  · 

Proof state:
case mpr
C : Type u_1
D : Type u_2
inst✝⁵ : Category.{u_3, u_1} C
inst✝⁴ : Category.{?u.174454, u_2} D
inst✝³ : Preadditive C
inst✝² : Preadditive D
S : ShortComplex C
inst✝¹ : Balanced C
inst✝ : HasHomology S
⊢ Nonempty (IsColimit (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0))) → Exact S ∧ Epi S.g

Next tactic:
intro ⟨hS⟩