l3lab/ntp-mathlib huggingface dataset:
/-- The norm of the components as a euclidean vector equals the norm of the quaternion. -/
theorem norm_piLp_equiv_symm_equivTuple (x : ℍ) :
    ‖(WithLp.equiv 2 (Fin 4 → _)).symm (equivTuple ℝ x)‖ = ‖x‖ := by
  rw [norm_eq_sqrt_real_inner, norm_eq_sqrt_real_inner, inner_self, normSq_def', PiLp.inner_apply,
    Fin.sum_univ_four]
  simp_rw [IsROrC.inner_apply, starRingEnd_apply, star_trivial, ← sq]
  

Proof state:
x : ℍ
⊢ Real.sqrt
      ((WithLp.equiv 2 (Fin 4 → ℝ)).symm ((equivTuple ℝ) x) 0 ^ 2 +
            (WithLp.equiv 2 (Fin 4 → ℝ)).symm ((equivTuple ℝ) x) 1 ^ 2 +
          (WithLp.equiv 2 (Fin 4 → ℝ)).symm ((equivTuple ℝ) x) 2 ^ 2 +
        (WithLp.equiv 2 (Fin 4 → ℝ)).symm ((equivTuple ℝ) x) 3 ^ 2) =
    Real.sqrt (x.re ^ 2 + x.imI ^ 2 + x.imJ ^ 2 + x.imK ^ 2)

Next tactic:
rfl
@[continuity]
theorem continuous_normSq : Continuous (normSq : ℍ → ℝ) := by
  

Proof state:
⊢ Continuous ⇑normSq

Next tactic:
simpa [← normSq_eq_norm_mul_self] using
    (continuous_norm.mul continuous_norm : Continuous fun q : ℍ => ‖q‖ * ‖q‖)
@[continuity]
theorem continuous_im : Continuous fun q : ℍ => q.im := by
  

Proof state:
⊢ Continuous fun q => im q

Next tactic:
simpa only [← sub_self_re] using continuous_id.sub (continuous_coe.comp continuous_re)
instance : CompleteSpace ℍ :=
  haveI : UniformEmbedding linearIsometryEquivTuple.toLinearEquiv.toEquiv.symm :=
    linearIsometryEquivTuple.toContinuousLinearEquiv.symm.uniformEmbedding
  (completeSpace_congr this).1 (by 

Proof state:
this : UniformEmbedding ⇑(LinearEquiv.toEquiv linearIsometryEquivTuple.toLinearEquiv).symm
⊢ CompleteSpace (EuclideanSpace ℝ (Fin 4))

Next tactic:
infer_instance
@[simp, norm_cast]
theorem hasSum_coe {f : α → ℝ} {r : ℝ} : HasSum (fun a => (f a : ℍ)) (↑r : ℍ) ↔ HasSum f r :=
  ⟨fun h => by 

Proof state:
α : Type u_1
f : α → ℝ
r : ℝ
h : HasSum (fun a => ↑(f a)) ↑r
⊢ HasSum f r

Next tactic:
simpa only using h.map (show ℍ →ₗ[ℝ] ℝ from QuaternionAlgebra.reₗ _ _) continuous_re
@[simp, norm_cast]
theorem hasSum_coe {f : α → ℝ} {r : ℝ} : HasSum (fun a => (f a : ℍ)) (↑r : ℍ) ↔ HasSum f r :=
  ⟨fun h => by simpa only using h.map (show ℍ →ₗ[ℝ] ℝ from QuaternionAlgebra.reₗ _ _) continuous_re,
    fun h => by 

Proof state:
α : Type u_1
f : α → ℝ
r : ℝ
h : HasSum f r
⊢ HasSum (fun a => ↑(f a)) ↑r

Next tactic:
simpa only using h.map (algebraMap ℝ ℍ) (continuous_algebraMap _ _)
@[simp, norm_cast]
theorem summable_coe {f : α → ℝ} : (Summable fun a => (f a : ℍ)) ↔ Summable f := by
  

Proof state:
α : Type u_1
f : α → ℝ
⊢ (Summable fun a => ↑(f a)) ↔ Summable f

Next tactic:
simpa only using
    Summable.map_iff_of_leftInverse (algebraMap ℝ ℍ) (show ℍ →ₗ[ℝ] ℝ from QuaternionAlgebra.reₗ _ _)
      (continuous_algebraMap _ _) continuous_re coe_re
@[norm_cast]
theorem tsum_coe (f : α → ℝ) : (∑' a, (f a : ℍ)) = ↑(∑' a, f a) := by
  

Proof state:
α : Type u_1
f : α → ℝ
⊢ ∑' (a : α), ↑(f a) = ↑(∑' (a : α), f a)

Next tactic:
by_cases hf : Summable f
@[norm_cast]
theorem tsum_coe (f : α → ℝ) : (∑' a, (f a : ℍ)) = ↑(∑' a, f a) := by
  by_cases hf : Summable f
  · 

Proof state:
case pos
α : Type u_1
f : α → ℝ
hf : Summable f
⊢ ∑' (a : α), ↑(f a) = ↑(∑' (a : α), f a)

Next tactic:
exact (hasSum_coe.mpr hf.hasSum).tsum_eq
@[norm_cast]
theorem tsum_coe (f : α → ℝ) : (∑' a, (f a : ℍ)) = ↑(∑' a, f a) := by
  by_cases hf : Summable f
  · exact (hasSum_coe.mpr hf.hasSum).tsum_eq
  · 

Proof state:
case neg
α : Type u_1
f : α → ℝ
hf : ¬Summable f
⊢ ∑' (a : α), ↑(f a) = ↑(∑' (a : α), f a)

Next tactic:
simp [tsum_eq_zero_of_not_summable hf, tsum_eq_zero_of_not_summable (summable_coe.not.mpr hf)]
@[simp]
lemma ShortComplex.zero_apply
    [Limits.HasZeroMorphisms C] [(forget₂ C Ab).PreservesZeroMorphisms]
    (S : ShortComplex C) (x : (forget₂ C Ab).obj S.X₁) :
    ((forget₂ C Ab).map S.g) (((forget₂ C Ab).map S.f) x) = 0 := by
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasForget₂ C Ab
inst✝¹ : HasZeroMorphisms C
inst✝ : Functor.PreservesZeroMorphisms (forget₂ C Ab)
S : ShortComplex C
x : ↑((forget₂ C Ab).obj S.X₁)
⊢ ((forget₂ C Ab).map S.g) (((forget₂ C Ab).map S.f) x) = 0

Next tactic:
erw [← comp_apply, ← Functor.map_comp, S.zero, Functor.map_zero]
@[simp]
lemma ShortComplex.zero_apply
    [Limits.HasZeroMorphisms C] [(forget₂ C Ab).PreservesZeroMorphisms]
    (S : ShortComplex C) (x : (forget₂ C Ab).obj S.X₁) :
    ((forget₂ C Ab).map S.g) (((forget₂ C Ab).map S.f) x) = 0 := by
  erw [← comp_apply, ← Functor.map_comp, S.zero, Functor.map_zero]
  

Proof state:
C : Type u
inst✝⁴ : Category.{v, u} C
inst✝³ : ConcreteCategory C
inst✝² : HasForget₂ C Ab
inst✝¹ : HasZeroMorphisms C
inst✝ : Functor.PreservesZeroMorphisms (forget₂ C Ab)
S : ShortComplex C
x : ↑((forget₂ C Ab).obj S.X₁)
⊢ 0 x = 0

Next tactic:
rfl
lemma Preadditive.mono_iff_injective {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget₂ C Ab).map f) := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Mono f ↔ Function.Injective ⇑((forget₂ C Ab).map f)

Next tactic:
rw [← AddCommGroupCat.mono_iff_injective]
lemma Preadditive.mono_iff_injective {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.mono_iff_injective]
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Mono f ↔ Mono ((forget₂ C Ab).map f)

Next tactic:
constructor
lemma Preadditive.mono_iff_injective {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.mono_iff_injective]
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Mono f → Mono ((forget₂ C Ab).map f)

Next tactic:
intro
lemma Preadditive.mono_iff_injective {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.mono_iff_injective]
  constructor
  · intro
    

Proof state:
case mp
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
a✝ : Mono f
⊢ Mono ((forget₂ C Ab).map f)

Next tactic:
infer_instance
lemma Preadditive.mono_iff_injective {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.mono_iff_injective]
  constructor
  · intro
    infer_instance
  · 

Proof state:
case mpr
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Mono ((forget₂ C Ab).map f) → Mono f

Next tactic:
apply Functor.mono_of_mono_map
lemma Preadditive.mono_iff_injective' {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget C).map f) := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Mono f ↔ Function.Injective ((forget C).map f)

Next tactic:
simp only [mono_iff_injective, ← CategoryTheory.mono_iff_injective]
lemma Preadditive.mono_iff_injective' {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget C).map f) := by
  simp only [mono_iff_injective, ← CategoryTheory.mono_iff_injective]
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Mono ⇑((forget₂ C Ab).map f) ↔ Mono ((forget C).map f)

Next tactic:
apply (MorphismProperty.RespectsIso.monomorphisms (Type w)).arrow_mk_iso_iff
lemma Preadditive.mono_iff_injective' {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget C).map f) := by
  simp only [mono_iff_injective, ← CategoryTheory.mono_iff_injective]
  apply (MorphismProperty.RespectsIso.monomorphisms (Type w)).arrow_mk_iso_iff
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Arrow.mk ⇑((forget₂ C Ab).map f) ≅ Arrow.mk ((forget C).map f)

Next tactic:
have e : forget₂ C Ab ⋙ forget Ab ≅ forget C := eqToIso (HasForget₂.forget_comp)
lemma Preadditive.mono_iff_injective' {X Y : C} (f : X ⟶ Y) :
    Mono f ↔ Function.Injective ((forget C).map f) := by
  simp only [mono_iff_injective, ← CategoryTheory.mono_iff_injective]
  apply (MorphismProperty.RespectsIso.monomorphisms (Type w)).arrow_mk_iso_iff
  have e : forget₂ C Ab ⋙ forget Ab ≅ forget C := eqToIso (HasForget₂.forget_comp)
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
e : forget₂ C Ab ⋙ forget Ab ≅ forget C
⊢ Arrow.mk ⇑((forget₂ C Ab).map f) ≅ Arrow.mk ((forget C).map f)

Next tactic:
exact Arrow.isoOfNatIso e (Arrow.mk f)
lemma Preadditive.epi_iff_injective {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget₂ C Ab).map f) := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Epi f ↔ Function.Surjective ⇑((forget₂ C Ab).map f)

Next tactic:
rw [← AddCommGroupCat.epi_iff_surjective]
lemma Preadditive.epi_iff_injective {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.epi_iff_surjective]
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Epi f ↔ Epi ((forget₂ C Ab).map f)

Next tactic:
constructor
lemma Preadditive.epi_iff_injective {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.epi_iff_surjective]
  constructor
  · 

Proof state:
case mp
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Epi f → Epi ((forget₂ C Ab).map f)

Next tactic:
intro
lemma Preadditive.epi_iff_injective {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.epi_iff_surjective]
  constructor
  · intro
    

Proof state:
case mp
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
a✝ : Epi f
⊢ Epi ((forget₂ C Ab).map f)

Next tactic:
infer_instance
lemma Preadditive.epi_iff_injective {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget₂ C Ab).map f) := by
  rw [← AddCommGroupCat.epi_iff_surjective]
  constructor
  · intro
    infer_instance
  · 

Proof state:
case mpr
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Epi ((forget₂ C Ab).map f) → Epi f

Next tactic:
apply Functor.epi_of_epi_map
lemma Preadditive.epi_iff_surjective' {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget C).map f) := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Epi f ↔ Function.Surjective ((forget C).map f)

Next tactic:
simp only [epi_iff_injective, ← CategoryTheory.epi_iff_surjective]
lemma Preadditive.epi_iff_surjective' {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget C).map f) := by
  simp only [epi_iff_injective, ← CategoryTheory.epi_iff_surjective]
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Epi ⇑((forget₂ C Ab).map f) ↔ Epi ((forget C).map f)

Next tactic:
apply (MorphismProperty.RespectsIso.epimorphisms (Type w)).arrow_mk_iso_iff
lemma Preadditive.epi_iff_surjective' {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget C).map f) := by
  simp only [epi_iff_injective, ← CategoryTheory.epi_iff_surjective]
  apply (MorphismProperty.RespectsIso.epimorphisms (Type w)).arrow_mk_iso_iff
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
⊢ Arrow.mk ⇑((forget₂ C Ab).map f) ≅ Arrow.mk ((forget C).map f)

Next tactic:
have e : forget₂ C Ab ⋙ forget Ab ≅ forget C := eqToIso (HasForget₂.forget_comp)
lemma Preadditive.epi_iff_surjective' {X Y : C} (f : X ⟶ Y) :
    Epi f ↔ Function.Surjective ((forget C).map f) := by
  simp only [epi_iff_injective, ← CategoryTheory.epi_iff_surjective]
  apply (MorphismProperty.RespectsIso.epimorphisms (Type w)).arrow_mk_iso_iff
  have e : forget₂ C Ab ⋙ forget Ab ≅ forget C := eqToIso (HasForget₂.forget_comp)
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
X Y : C
f : X ⟶ Y
e : forget₂ C Ab ⋙ forget Ab ≅ forget C
⊢ Arrow.mk ⇑((forget₂ C Ab).map f) ≅ Arrow.mk ((forget C).map f)

Next tactic:
exact Arrow.isoOfNatIso e (Arrow.mk f)
lemma exact_iff_of_concreteCategory [S.HasHomology] :
    S.Exact ↔ ∀ (x₂ : (forget₂ C Ab).obj S.X₂) (_ : ((forget₂ C Ab).map S.g) x₂ = 0),
      ∃ (x₁ : (forget₂ C Ab).obj S.X₁), ((forget₂ C Ab).map S.f) x₁ = x₂ := by
  

Proof state:
C : Type u
inst✝⁷ : Category.{v, u} C
inst✝⁶ : ConcreteCategory C
inst✝⁵ : HasForget₂ C Ab
inst✝⁴ : Preadditive C
inst✝³ : Functor.Additive (forget₂ C Ab)
inst✝² : Functor.PreservesHomology (forget₂ C Ab)
inst✝¹ : HasZeroObject C
S : ShortComplex C
inst✝ : HasHomology S
⊢ Exact S ↔
    ∀ (x₂ : ↑((forget₂ C Ab).obj S.X₂)), ((forget₂ C Ab).map S.g) x₂ = 0 → ∃ x₁, ((forget₂ C Ab).map S.f) x₁ = x₂

Next tactic:
rw [S.exact_iff_exact_map_forget₂, ab_exact_iff]
lemma exact_iff_of_concreteCategory [S.HasHomology] :
    S.Exact ↔ ∀ (x₂ : (forget₂ C Ab).obj S.X₂) (_ : ((forget₂ C Ab).map S.g) x₂ = 0),
      ∃ (x₁ : (forget₂ C Ab).obj S.X₁), ((forget₂ C Ab).map S.f) x₁ = x₂ := by
  rw [S.exact_iff_exact_map_forget₂, ab_exact_iff]
  

Proof state:
C : Type u
inst✝⁷ : Category.{v, u} C
inst✝⁶ : ConcreteCategory C
inst✝⁵ : HasForget₂ C Ab
inst✝⁴ : Preadditive C
inst✝³ : Functor.Additive (forget₂ C Ab)
inst✝² : Functor.PreservesHomology (forget₂ C Ab)
inst✝¹ : HasZeroObject C
S : ShortComplex C
inst✝ : HasHomology S
⊢ (∀ (x₂ : ↑(map S (forget₂ C Ab)).X₂), (map S (forget₂ C Ab)).g x₂ = 0 → ∃ x₁, (map S (forget₂ C Ab)).f x₁ = x₂) ↔
    ∀ (x₂ : ↑((forget₂ C Ab).obj S.X₂)), ((forget₂ C Ab).map S.g) x₂ = 0 → ∃ x₁, ((forget₂ C Ab).map S.f) x₁ = x₂

Next tactic:
rfl
lemma ShortExact.injective_f (hS : S.ShortExact) :
    Function.Injective ((forget₂ C Ab).map S.f) := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
hS : ShortExact S
⊢ Function.Injective ⇑((forget₂ C Ab).map S.f)

Next tactic:
rw [← Preadditive.mono_iff_injective]
lemma ShortExact.injective_f (hS : S.ShortExact) :
    Function.Injective ((forget₂ C Ab).map S.f) := by
  rw [← Preadditive.mono_iff_injective]
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
hS : ShortExact S
⊢ Mono S.f

Next tactic:
exact hS.mono_f
lemma ShortExact.surjective_g (hS : S.ShortExact) :
    Function.Surjective ((forget₂ C Ab).map S.g) := by
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
hS : ShortExact S
⊢ Function.Surjective ⇑((forget₂ C Ab).map S.g)

Next tactic:
rw [← Preadditive.epi_iff_injective]
lemma ShortExact.surjective_g (hS : S.ShortExact) :
    Function.Surjective ((forget₂ C Ab).map S.g) := by
  rw [← Preadditive.epi_iff_injective]
  

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : ConcreteCategory C
inst✝⁴ : HasForget₂ C Ab
inst✝³ : Preadditive C
inst✝² : Functor.Additive (forget₂ C Ab)
inst✝¹ : Functor.PreservesHomology (forget₂ C Ab)
inst✝ : HasZeroObject C
S : ShortComplex C
hS : ShortExact S
⊢ Epi S.g

Next tactic:
exact hS.epi_g
/-- This lemma allows the computation of the connecting homomorphism
`D.δ` when `D : SnakeInput C` and `C` is a concrete category. -/
lemma δ_apply (x₃ : D.L₀.X₃) (x₂ : D.L₁.X₂) (x₁ : D.L₂.X₁)
    (h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃) (h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂) :
    D.δ x₃ = D.v₂₃.τ₁ x₁ := by
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : ConcreteCategory C
inst✝³ : HasForget₂ C Ab
inst✝² : Abelian C
inst✝¹ : Functor.Additive (forget₂ C Ab)
inst✝ : Functor.PreservesHomology (forget₂ C Ab)
D : SnakeInput C
x₃ : (forget C).obj D.L₀.X₃
x₂ : (forget C).obj D.L₁.X₂
x₁ : (forget C).obj D.L₂.X₁
h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃
h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂
⊢ (δ D) x₃ = D.v₂₃.τ₁ x₁

Next tactic:
have := (forget₂ C Ab).preservesFiniteLimitsOfPreservesHomology
/-- This lemma allows the computation of the connecting homomorphism
`D.δ` when `D : SnakeInput C` and `C` is a concrete category. -/
lemma δ_apply (x₃ : D.L₀.X₃) (x₂ : D.L₁.X₂) (x₁ : D.L₂.X₁)
    (h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃) (h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂) :
    D.δ x₃ = D.v₂₃.τ₁ x₁ := by
  have := (forget₂ C Ab).preservesFiniteLimitsOfPreservesHomology
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : ConcreteCategory C
inst✝³ : HasForget₂ C Ab
inst✝² : Abelian C
inst✝¹ : Functor.Additive (forget₂ C Ab)
inst✝ : Functor.PreservesHomology (forget₂ C Ab)
D : SnakeInput C
x₃ : (forget C).obj D.L₀.X₃
x₂ : (forget C).obj D.L₁.X₂
x₁ : (forget C).obj D.L₂.X₁
h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃
h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂
this : PreservesFiniteLimits (forget₂ C Ab)
⊢ (δ D) x₃ = D.v₂₃.τ₁ x₁

Next tactic:
have : PreservesFiniteLimits (forget C) := by
    have : forget₂ C Ab ⋙ forget Ab = forget C := HasForget₂.forget_comp
    simpa only [← this] using compPreservesFiniteLimits _ _
/-- This lemma allows the computation of the connecting homomorphism
`D.δ` when `D : SnakeInput C` and `C` is a concrete category. -/
lemma δ_apply (x₃ : D.L₀.X₃) (x₂ : D.L₁.X₂) (x₁ : D.L₂.X₁)
    (h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃) (h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂) :
    D.δ x₃ = D.v₂₃.τ₁ x₁ := by
  have := (forget₂ C Ab).preservesFiniteLimitsOfPreservesHomology
  have : PreservesFiniteLimits (forget C) := by
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : ConcreteCategory C
inst✝³ : HasForget₂ C Ab
inst✝² : Abelian C
inst✝¹ : Functor.Additive (forget₂ C Ab)
inst✝ : Functor.PreservesHomology (forget₂ C Ab)
D : SnakeInput C
x₃ : (forget C).obj D.L₀.X₃
x₂ : (forget C).obj D.L₁.X₂
x₁ : (forget C).obj D.L₂.X₁
h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃
h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂
this : PreservesFiniteLimits (forget₂ C Ab)
⊢ PreservesFiniteLimits (forget C)

Next tactic:
have : forget₂ C Ab ⋙ forget Ab = forget C := HasForget₂.forget_comp
/-- This lemma allows the computation of the connecting homomorphism
`D.δ` when `D : SnakeInput C` and `C` is a concrete category. -/
lemma δ_apply (x₃ : D.L₀.X₃) (x₂ : D.L₁.X₂) (x₁ : D.L₂.X₁)
    (h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃) (h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂) :
    D.δ x₃ = D.v₂₃.τ₁ x₁ := by
  have := (forget₂ C Ab).preservesFiniteLimitsOfPreservesHomology
  have : PreservesFiniteLimits (forget C) := by
    have : forget₂ C Ab ⋙ forget Ab = forget C := HasForget₂.forget_comp
    

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : ConcreteCategory C
inst✝³ : HasForget₂ C Ab
inst✝² : Abelian C
inst✝¹ : Functor.Additive (forget₂ C Ab)
inst✝ : Functor.PreservesHomology (forget₂ C Ab)
D : SnakeInput C
x₃ : (forget C).obj D.L₀.X₃
x₂ : (forget C).obj D.L₁.X₂
x₁ : (forget C).obj D.L₂.X₁
h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃
h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂
this✝ : PreservesFiniteLimits (forget₂ C Ab)
this : forget₂ C Ab ⋙ forget Ab = forget C
⊢ PreservesFiniteLimits (forget C)

Next tactic:
simpa only [← this] using compPreservesFiniteLimits _ _
/-- This lemma allows the computation of the connecting homomorphism
`D.δ` when `D : SnakeInput C` and `C` is a concrete category. -/
lemma δ_apply (x₃ : D.L₀.X₃) (x₂ : D.L₁.X₂) (x₁ : D.L₂.X₁)
    (h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃) (h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂) :
    D.δ x₃ = D.v₂₃.τ₁ x₁ := by
  have := (forget₂ C Ab).preservesFiniteLimitsOfPreservesHomology
  have : PreservesFiniteLimits (forget C) := by
    have : forget₂ C Ab ⋙ forget Ab = forget C := HasForget₂.forget_comp
    simpa only [← this] using compPreservesFiniteLimits _ _
  

Proof state:
C : Type u
inst✝⁵ : Category.{v, u} C
inst✝⁴ : ConcreteCategory C
inst✝³ : HasForget₂ C Ab
inst✝² : Abelian C
inst✝¹ : Functor.Additive (forget₂ C Ab)
inst✝ : Functor.PreservesHomology (forget₂ C Ab)
D : SnakeInput C
x₃ : (forget C).obj D.L₀.X₃
x₂ : (forget C).obj D.L₁.X₂
x₁ : (forget C).obj D.L₂.X₁
h₂ : D.L₁.g x₂ = D.v₀₁.τ₃ x₃
h₁ : D.L₂.f x₁ = D.v₁₂.τ₂ x₂
this✝ : PreservesFiniteLimits (forget₂ C Ab)
this : PreservesFiniteLimits (forget C)
⊢ (δ D) x₃ = D.v₂₃.τ₁ x₁

Next tactic:
have eq := congr_fun ((forget C).congr_map D.snd_δ)
    (Limits.Concrete.pullbackMk D.L₁.g D.v₀₁.τ₃ x₂ x₃ h₂)