l3lab/ntp-mathlib huggingface dataset:
theorem tendsto_nat_ceil_mul_div_atTop {a : R} (ha : 0 ≤ a) :
    Tendsto (fun x ↦ (⌈a * x⌉₊ : R) / x) atTop (𝓝 a) := by
  have A : Tendsto (fun x : R ↦ a + x⁻¹) atTop (𝓝 (a + 0)) :=
    tendsto_const_nhds.add tendsto_inv_atTop_zero
  rw [add_zero] at A
  apply tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds A
  · 

Proof state:
case hgf
α : Type u_1
β : Type u_2
ι : Type u_3
R : Type u_4
inst✝³ : TopologicalSpace R
inst✝² : LinearOrderedField R
inst✝¹ : OrderTopology R
inst✝ : FloorRing R
a : R
ha : 0 ≤ a
A : Tendsto (fun x => a + x⁻¹) atTop (𝓝 a)
⊢ ∀ᶠ (b : R) in atTop, a ≤ ↑⌈a * b⌉₊ / b

Next tactic:
refine' eventually_atTop.2 ⟨1, fun x hx ↦ _⟩
theorem tendsto_nat_ceil_mul_div_atTop {a : R} (ha : 0 ≤ a) :
    Tendsto (fun x ↦ (⌈a * x⌉₊ : R) / x) atTop (𝓝 a) := by
  have A : Tendsto (fun x : R ↦ a + x⁻¹) atTop (𝓝 (a + 0)) :=
    tendsto_const_nhds.add tendsto_inv_atTop_zero
  rw [add_zero] at A
  apply tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds A
  · refine' eventually_atTop.2 ⟨1, fun x hx ↦ _⟩
    

Proof state:
case hgf
α : Type u_1
β : Type u_2
ι : Type u_3
R : Type u_4
inst✝³ : TopologicalSpace R
inst✝² : LinearOrderedField R
inst✝¹ : OrderTopology R
inst✝ : FloorRing R
a : R
ha : 0 ≤ a
A : Tendsto (fun x => a + x⁻¹) atTop (𝓝 a)
x : R
hx : x ≥ 1
⊢ a ≤ ↑⌈a * x⌉₊ / x

Next tactic:
rw [le_div_iff (zero_lt_one.trans_le hx)]
theorem tendsto_nat_ceil_mul_div_atTop {a : R} (ha : 0 ≤ a) :
    Tendsto (fun x ↦ (⌈a * x⌉₊ : R) / x) atTop (𝓝 a) := by
  have A : Tendsto (fun x : R ↦ a + x⁻¹) atTop (𝓝 (a + 0)) :=
    tendsto_const_nhds.add tendsto_inv_atTop_zero
  rw [add_zero] at A
  apply tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds A
  · refine' eventually_atTop.2 ⟨1, fun x hx ↦ _⟩
    rw [le_div_iff (zero_lt_one.trans_le hx)]
    

Proof state:
case hgf
α : Type u_1
β : Type u_2
ι : Type u_3
R : Type u_4
inst✝³ : TopologicalSpace R
inst✝² : LinearOrderedField R
inst✝¹ : OrderTopology R
inst✝ : FloorRing R
a : R
ha : 0 ≤ a
A : Tendsto (fun x => a + x⁻¹) atTop (𝓝 a)
x : R
hx : x ≥ 1
⊢ a * x ≤ ↑⌈a * x⌉₊

Next tactic:
exact Nat.le_ceil _
theorem tendsto_nat_ceil_mul_div_atTop {a : R} (ha : 0 ≤ a) :
    Tendsto (fun x ↦ (⌈a * x⌉₊ : R) / x) atTop (𝓝 a) := by
  have A : Tendsto (fun x : R ↦ a + x⁻¹) atTop (𝓝 (a + 0)) :=
    tendsto_const_nhds.add tendsto_inv_atTop_zero
  rw [add_zero] at A
  apply tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds A
  · refine' eventually_atTop.2 ⟨1, fun x hx ↦ _⟩
    rw [le_div_iff (zero_lt_one.trans_le hx)]
    exact Nat.le_ceil _
  · 

Proof state:
case hfh
α : Type u_1
β : Type u_2
ι : Type u_3
R : Type u_4
inst✝³ : TopologicalSpace R
inst✝² : LinearOrderedField R
inst✝¹ : OrderTopology R
inst✝ : FloorRing R
a : R
ha : 0 ≤ a
A : Tendsto (fun x => a + x⁻¹) atTop (𝓝 a)
⊢ ∀ᶠ (b : R) in atTop, ↑⌈a * b⌉₊ / b ≤ a + b⁻¹

Next tactic:
refine' eventually_atTop.2 ⟨1, fun x hx ↦ _⟩
theorem tendsto_nat_ceil_mul_div_atTop {a : R} (ha : 0 ≤ a) :
    Tendsto (fun x ↦ (⌈a * x⌉₊ : R) / x) atTop (𝓝 a) := by
  have A : Tendsto (fun x : R ↦ a + x⁻¹) atTop (𝓝 (a + 0)) :=
    tendsto_const_nhds.add tendsto_inv_atTop_zero
  rw [add_zero] at A
  apply tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds A
  · refine' eventually_atTop.2 ⟨1, fun x hx ↦ _⟩
    rw [le_div_iff (zero_lt_one.trans_le hx)]
    exact Nat.le_ceil _
  · refine' eventually_atTop.2 ⟨1, fun x hx ↦ _⟩
    

Proof state:
case hfh
α : Type u_1
β : Type u_2
ι : Type u_3
R : Type u_4
inst✝³ : TopologicalSpace R
inst✝² : LinearOrderedField R
inst✝¹ : OrderTopology R
inst✝ : FloorRing R
a : R
ha : 0 ≤ a
A : Tendsto (fun x => a + x⁻¹) atTop (𝓝 a)
x : R
hx : x ≥ 1
⊢ ↑⌈a * x⌉₊ / x ≤ a + x⁻¹

Next tactic:
simp [div_le_iff (zero_lt_one.trans_le hx), inv_mul_cancel (zero_lt_one.trans_le hx).ne',
      (Nat.ceil_lt_add_one (mul_nonneg ha (zero_le_one.trans hx))).le, add_mul]
theorem tendsto_nat_ceil_div_atTop : Tendsto (fun x ↦ (⌈x⌉₊ : R) / x) atTop (𝓝 1) := by
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
R : Type u_4
inst✝³ : TopologicalSpace R
inst✝² : LinearOrderedField R
inst✝¹ : OrderTopology R
inst✝ : FloorRing R
⊢ Tendsto (fun x => ↑⌈x⌉₊ / x) atTop (𝓝 1)

Next tactic:
simpa using tendsto_nat_ceil_mul_div_atTop (zero_le_one' R)
lemma Nat.tendsto_div_const_atTop {n : ℕ} (hn : n ≠ 0) : Tendsto (λ x ↦ x / n) atTop atTop := by
  

Proof state:
α : Type u_1
β : Type u_2
ι : Type u_3
R : Type u_4
inst✝³ : TopologicalSpace R
inst✝² : LinearOrderedField R
inst✝¹ : OrderTopology R
inst✝ : FloorRing R
n : ℕ
hn : n ≠ 0
⊢ Tendsto (fun x => x / n) atTop atTop

Next tactic:
rw [Tendsto, map_div_atTop_eq_nat n hn.bot_lt]
@[reassoc]
lemma ι_descQ_eq_zero_of_boundary (k : S.X₂ ⟶ A) (x : S.X₃ ⟶ A) (hx : k = S.g ≫ x) :
    h.ι ≫ h.descQ k (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.11929, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
k : S.X₂ ⟶ A
x : S.X₃ ⟶ A
hx : k = S.g ≫ x
⊢ S.f ≫ k = 0

Next tactic:
rw [hx, S.zero_assoc, zero_comp]
@[reassoc]
lemma ι_descQ_eq_zero_of_boundary (k : S.X₂ ⟶ A) (x : S.X₃ ⟶ A) (hx : k = S.g ≫ x) :
    h.ι ≫ h.descQ k (by rw [hx, S.zero_assoc, zero_comp]) = 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 : RightHomologyData S
A : C
k : S.X₂ ⟶ A
x : S.X₃ ⟶ A
hx : k = S.g ≫ x
⊢ h.ι ≫ descQ h k (_ : S.f ≫ k = 0) = 0

Next tactic:
rw [show 0 = h.ι ≫ h.g' ≫ x by simp]
@[reassoc]
lemma ι_descQ_eq_zero_of_boundary (k : S.X₂ ⟶ A) (x : S.X₃ ⟶ A) (hx : k = S.g ≫ x) :
    h.ι ≫ h.descQ k (by rw [hx, S.zero_assoc, zero_comp]) = 0 := by
  rw [show 0 = h.ι ≫ h.g' ≫ x by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
k : S.X₂ ⟶ A
x : S.X₃ ⟶ A
hx : k = S.g ≫ x
⊢ 0 = h.ι ≫ g' h ≫ x

Next tactic:
simp
@[reassoc]
lemma ι_descQ_eq_zero_of_boundary (k : S.X₂ ⟶ A) (x : S.X₃ ⟶ A) (hx : k = S.g ≫ x) :
    h.ι ≫ h.descQ k (by rw [hx, S.zero_assoc, zero_comp]) = 0 := by
  rw [show 0 = h.ι ≫ h.g' ≫ x by simp]
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
k : S.X₂ ⟶ A
x : S.X₃ ⟶ A
hx : k = S.g ≫ x
⊢ h.ι ≫ descQ h k (_ : S.f ≫ k = 0) = h.ι ≫ g' h ≫ x

Next tactic:
congr 1
@[reassoc]
lemma ι_descQ_eq_zero_of_boundary (k : S.X₂ ⟶ A) (x : S.X₃ ⟶ A) (hx : k = S.g ≫ x) :
    h.ι ≫ h.descQ k (by rw [hx, S.zero_assoc, zero_comp]) = 0 := by
  rw [show 0 = h.ι ≫ h.g' ≫ x by simp]
  congr 1
  

Proof state:
case e_a
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
k : S.X₂ ⟶ A
x : S.X₃ ⟶ A
hx : k = S.g ≫ x
⊢ descQ h k (_ : S.f ≫ k = 0) = g' h ≫ x

Next tactic:
simp only [← cancel_epi h.p, hx, p_descQ, p_g'_assoc]
lemma isIso_p (hf : S.f = 0) : IsIso h.p :=
  ⟨h.descQ (𝟙 S.X₂) (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hf : S.f = 0
⊢ S.f ≫ 𝟙 S.X₂ = 0

Next tactic:
rw [hf, comp_id]
lemma isIso_p (hf : S.f = 0) : IsIso h.p :=
  ⟨h.descQ (𝟙 S.X₂) (by rw [hf, comp_id]), p_descQ _ _ _, by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hf : S.f = 0
⊢ descQ h (𝟙 S.X₂) (_ : S.f ≫ 𝟙 S.X₂ = 0) ≫ h.p = 𝟙 h.Q

Next tactic:
simp only [← cancel_epi h.p, p_descQ_assoc, id_comp, comp_id]
lemma isIso_ι (hg : S.g = 0) : IsIso h.ι := by
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hg : S.g = 0
⊢ IsIso h.ι

Next tactic:
have ⟨φ, hφ⟩ := KernelFork.IsLimit.lift' h.hι' (𝟙 _)
    (by rw [← cancel_epi h.p, id_comp, p_g', comp_zero, hg])
lemma isIso_ι (hg : S.g = 0) : IsIso h.ι := by
  have ⟨φ, hφ⟩ := KernelFork.IsLimit.lift' 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
h : RightHomologyData S
A : C
hg : S.g = 0
⊢ 𝟙 h.Q ≫ g' h = 0

Next tactic:
rw [← cancel_epi h.p, id_comp, p_g', comp_zero, hg]
lemma isIso_ι (hg : S.g = 0) : IsIso h.ι := by
  have ⟨φ, hφ⟩ := KernelFork.IsLimit.lift' h.hι' (𝟙 _)
    (by rw [← cancel_epi h.p, id_comp, p_g', comp_zero, hg])
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hg : S.g = 0
φ : h.Q ⟶ (KernelFork.ofι h.ι (_ : h.ι ≫ g' h = 0)).pt
hφ : φ ≫ Fork.ι (KernelFork.ofι h.ι (_ : h.ι ≫ g' h = 0)) = 𝟙 h.Q
⊢ IsIso h.ι

Next tactic:
dsimp at hφ
lemma isIso_ι (hg : S.g = 0) : IsIso h.ι := by
  have ⟨φ, hφ⟩ := KernelFork.IsLimit.lift' h.hι' (𝟙 _)
    (by rw [← cancel_epi h.p, id_comp, p_g', comp_zero, hg])
  dsimp at hφ
  

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hg : S.g = 0
φ : h.Q ⟶ (KernelFork.ofι h.ι (_ : h.ι ≫ g' h = 0)).pt
hφ : φ ≫ h.ι = 𝟙 h.Q
⊢ IsIso h.ι

Next tactic:
exact ⟨φ, by rw [← cancel_mono h.ι, assoc, hφ, comp_id, id_comp], hφ⟩
lemma isIso_ι (hg : S.g = 0) : IsIso h.ι := by
  have ⟨φ, hφ⟩ := KernelFork.IsLimit.lift' h.hι' (𝟙 _)
    (by rw [← cancel_epi h.p, id_comp, p_g', comp_zero, hg])
  dsimp at hφ
  exact ⟨φ, by 

Proof state:
C : Type u_1
inst✝¹ : Category.{u_2, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hg : S.g = 0
φ : h.Q ⟶ (KernelFork.ofι h.ι (_ : h.ι ≫ g' h = 0)).pt
hφ : φ ≫ h.ι = 𝟙 h.Q
⊢ h.ι ≫ φ = 𝟙 h.H

Next tactic:
rw [← cancel_mono h.ι, assoc, hφ, comp_id, id_comp]
/-- When the first map `S.f` is zero, this is the right homology data on `S` given
by any limit kernel fork of `S.g` -/
@[simps]
def ofIsLimitKernelFork (hf : S.f = 0) (c : KernelFork S.g) (hc : IsLimit c) :
    S.RightHomologyData where
  Q := S.X₂
  H := c.pt
  p := 𝟙 _
  ι := c.ι
  wp := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.20413, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hf : S.f = 0
c : KernelFork S.g
hc : IsLimit c
⊢ S.f ≫ 𝟙 S.X₂ = 0

Next tactic:
rw [comp_id, hf]
/-- When the first map `S.f` is zero, this is the right homology data on `S` given
by any limit kernel fork of `S.g` -/
@[simps]
def ofIsLimitKernelFork (hf : S.f = 0) (c : KernelFork S.g) (hc : IsLimit c) :
    S.RightHomologyData where
  Q := S.X₂
  H := c.pt
  p := 𝟙 _
  ι := c.ι
  wp := by rw [comp_id, hf]
  hp := CokernelCofork.IsColimit.ofId _ hf
  wι := KernelFork.condition _
  hι := IsLimit.ofIsoLimit hc (Fork.ext (Iso.refl _) (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.20413, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hf : S.f = 0
c : KernelFork S.g
hc : IsLimit c
⊢ (Iso.refl c.pt).hom ≫ Fork.ι (KernelFork.ofι (Fork.ι c) (_ : Fork.ι c ≫ S.g = 0)) = Fork.ι c

Next tactic:
aesop_cat
@[simp] lemma ofIsLimitKernelFork_g' (hf : S.f = 0) (c : KernelFork S.g)
    (hc : IsLimit c) : (ofIsLimitKernelFork S hf c hc).g' = S.g := by
  

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

Next tactic:
rw [← cancel_epi (ofIsLimitKernelFork S hf c hc).p, p_g',
    ofIsLimitKernelFork_p, id_comp]
/-- When the second map `S.g` is zero, this is the right homology data on `S` given
by any colimit cokernel cofork of `S.g` -/
@[simps]
def ofIsColimitCokernelCofork (hg : S.g = 0) (c : CokernelCofork S.f) (hc : IsColimit c) :
    S.RightHomologyData where
  Q := c.pt
  H := c.pt
  p := c.π
  ι := 𝟙 _
  wp := CokernelCofork.condition _
  hp := IsColimit.ofIsoColimit hc (Cofork.ext (Iso.refl _) (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.25759, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ Cofork.π c ≫ (Iso.refl c.pt).hom = Cofork.π (CokernelCofork.ofπ (Cofork.π c) (_ : S.f ≫ Cofork.π c = 0))

Next tactic:
aesop_cat
/-- When the second map `S.g` is zero, this is the right homology data on `S` given
by any colimit cokernel cofork of `S.g` -/
@[simps]
def ofIsColimitCokernelCofork (hg : S.g = 0) (c : CokernelCofork S.f) (hc : IsColimit c) :
    S.RightHomologyData where
  Q := c.pt
  H := c.pt
  p := c.π
  ι := 𝟙 _
  wp := CokernelCofork.condition _
  hp := IsColimit.ofIsoColimit hc (Cofork.ext (Iso.refl _) (by aesop_cat))
  wι := Cofork.IsColimit.hom_ext hc (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.25759, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ Cofork.π c ≫
      𝟙 c.pt ≫
        IsColimit.desc (IsColimit.ofIsoColimit hc (Cofork.ext (Iso.refl c.pt)))
          (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)) =
    Cofork.π c ≫ 0

Next tactic:
simp [hg]
/-- When the second map `S.g` is zero, this is the right homology data on `S` given
by any colimit cokernel cofork of `S.g` -/
@[simps]
def ofIsColimitCokernelCofork (hg : S.g = 0) (c : CokernelCofork S.f) (hc : IsColimit c) :
    S.RightHomologyData where
  Q := c.pt
  H := c.pt
  p := c.π
  ι := 𝟙 _
  wp := CokernelCofork.condition _
  hp := IsColimit.ofIsoColimit hc (Cofork.ext (Iso.refl _) (by aesop_cat))
  wι := Cofork.IsColimit.hom_ext hc (by simp [hg])
  hι := KernelFork.IsLimit.ofId _ (Cofork.IsColimit.hom_ext hc (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.25759, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ Cofork.π c ≫
      IsColimit.desc (IsColimit.ofIsoColimit hc (Cofork.ext (Iso.refl c.pt)))
        (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)) =
    Cofork.π c ≫ 0

Next tactic:
simp [hg]
@[simp] lemma ofIsColimitCokernelCofork_g' (hg : S.g = 0) (c : CokernelCofork S.f)
  (hc : IsColimit c) : (ofIsColimitCokernelCofork S hg c hc).g' = 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 : RightHomologyData S
A : C
hg : S.g = 0
c : CokernelCofork S.f
hc : IsColimit c
⊢ g' (ofIsColimitCokernelCofork S hg c hc) = 0

Next tactic:
rw [← cancel_epi (ofIsColimitCokernelCofork S hg c hc).p, p_g', hg, comp_zero]
/-- When both `S.f` and `S.g` are zero, the middle object `S.X₂`
gives a right homology data on S -/
@[simps]
def ofZeros (hf : S.f = 0) (hg : S.g = 0) : S.RightHomologyData where
  Q := S.X₂
  H := S.X₂
  p := 𝟙 _
  ι := 𝟙 _
  wp := by 

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

Next tactic:
rw [comp_id, hf]
/-- When both `S.f` and `S.g` are zero, the middle object `S.X₂`
gives a right homology data on S -/
@[simps]
def ofZeros (hf : S.f = 0) (hg : S.g = 0) : S.RightHomologyData where
  Q := S.X₂
  H := S.X₂
  p := 𝟙 _
  ι := 𝟙 _
  wp := by rw [comp_id, hf]
  hp := CokernelCofork.IsColimit.ofId _ hf
  wι := by
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.31644, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
h : RightHomologyData S
A : C
hf : S.f = 0
hg : S.g = 0
⊢ 𝟙 S.X₂ ≫ IsColimit.desc (CokernelCofork.IsColimit.ofId S.f hf) (CokernelCofork.ofπ S.g (_ : S.f ≫ S.g = 0)) = 0

Next tactic:
change 𝟙 _ ≫ S.g = 0
/-- When both `S.f` and `S.g` are zero, the middle object `S.X₂`
gives a right homology data on S -/
@[simps]
def ofZeros (hf : S.f = 0) (hg : S.g = 0) : S.RightHomologyData where
  Q := S.X₂
  H := S.X₂
  p := 𝟙 _
  ι := 𝟙 _
  wp := by rw [comp_id, hf]
  hp := CokernelCofork.IsColimit.ofId _ hf
  wι := by
    change 𝟙 _ ≫ S.g = 0
    

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

Next tactic:
simp only [hg, comp_zero]
@[simp]
lemma ofZeros_g' (hf : S.f = 0) (hg : S.g = 0) :
    (ofZeros S hf hg).g' = 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 : RightHomologyData S
A : C
hf : S.f = 0
hg : S.g = 0
⊢ g' (ofZeros S hf hg) = 0

Next tactic:
rw [← cancel_epi ((ofZeros S hf hg).p), comp_zero, p_g', hg]
instance : Subsingleton (RightHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    

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

Next tactic:
have hQ : ψ₁.φQ = ψ₂.φQ := by rw [← cancel_epi h₁.p, commp, commp]
instance : Subsingleton (RightHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hQ : ψ₁.φQ = ψ₂.φQ := by 

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

Next tactic:
rw [← cancel_epi h₁.p, commp, commp]
instance : Subsingleton (RightHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hQ : ψ₁.φQ = ψ₂.φQ := by rw [← cancel_epi h₁.p, commp, commp]
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.62642, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
ψ₁ ψ₂ : RightHomologyMapData φ h₁ h₂
hQ : ψ₁.φQ = ψ₂.φQ
⊢ ψ₁ = ψ₂

Next tactic:
have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_mono h₂.ι, commι, commι, hQ]
instance : Subsingleton (RightHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hQ : ψ₁.φQ = ψ₂.φQ := by rw [← cancel_epi h₁.p, commp, commp]
    have hH : ψ₁.φH = ψ₂.φH := by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.62642, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
ψ₁ ψ₂ : RightHomologyMapData φ h₁ h₂
hQ : ψ₁.φQ = ψ₂.φQ
⊢ ψ₁.φH = ψ₂.φH

Next tactic:
rw [← cancel_mono h₂.ι, commι, commι, hQ]
instance : Subsingleton (RightHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hQ : ψ₁.φQ = ψ₂.φQ := by rw [← cancel_epi h₁.p, commp, commp]
    have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_mono h₂.ι, commι, commι, hQ]
    

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.62642, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
ψ₁ ψ₂ : RightHomologyMapData φ h₁ h₂
hQ : ψ₁.φQ = ψ₂.φQ
hH : ψ₁.φH = ψ₂.φH
⊢ ψ₁ = ψ₂

Next tactic:
cases ψ₁
instance : Subsingleton (RightHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hQ : ψ₁.φQ = ψ₂.φQ := by rw [← cancel_epi h₁.p, commp, commp]
    have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_mono h₂.ι, commι, commι, hQ]
    cases ψ₁
    

Proof state:
case mk
C : Type u_1
inst✝¹ : Category.{?u.62642, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
ψ₂ : RightHomologyMapData φ h₁ h₂
φQ✝ : h₁.Q ⟶ h₂.Q
φH✝ : h₁.H ⟶ h₂.H
commp✝ : h₁.p ≫ φQ✝ = φ.τ₂ ≫ h₂.p
commg'✝ : φQ✝ ≫ RightHomologyData.g' h₂ = RightHomologyData.g' h₁ ≫ φ.τ₃
commι✝ : φH✝ ≫ h₂.ι = h₁.ι ≫ φQ✝
hQ : (mk φQ✝ φH✝).φQ = ψ₂.φQ
hH : (mk φQ✝ φH✝).φH = ψ₂.φH
⊢ mk φQ✝ φH✝ = ψ₂

Next tactic:
cases ψ₂
instance : Subsingleton (RightHomologyMapData φ h₁ h₂) :=
  ⟨fun ψ₁ ψ₂ => by
    have hQ : ψ₁.φQ = ψ₂.φQ := by rw [← cancel_epi h₁.p, commp, commp]
    have hH : ψ₁.φH = ψ₂.φH := by rw [← cancel_mono h₂.ι, commι, commι, hQ]
    cases ψ₁
    cases ψ₂
    

Proof state:
case mk.mk
C : Type u_1
inst✝¹ : Category.{?u.62642, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
φQ✝¹ : h₁.Q ⟶ h₂.Q
φH✝¹ : h₁.H ⟶ h₂.H
commp✝¹ : h₁.p ≫ φQ✝¹ = φ.τ₂ ≫ h₂.p
commg'✝¹ : φQ✝¹ ≫ RightHomologyData.g' h₂ = RightHomologyData.g' h₁ ≫ φ.τ₃
commι✝¹ : φH✝¹ ≫ h₂.ι = h₁.ι ≫ φQ✝¹
φQ✝ : h₁.Q ⟶ h₂.Q
φH✝ : h₁.H ⟶ h₂.H
commp✝ : h₁.p ≫ φQ✝ = φ.τ₂ ≫ h₂.p
commg'✝ : φQ✝ ≫ RightHomologyData.g' h₂ = RightHomologyData.g' h₁ ≫ φ.τ₃
commι✝ : φH✝ ≫ h₂.ι = h₁.ι ≫ φQ✝
hQ : (mk φQ✝¹ φH✝¹).φQ = (mk φQ✝ φH✝).φQ
hH : (mk φQ✝¹ φH✝¹).φH = (mk φQ✝ φH✝).φH
⊢ mk φQ✝¹ φH✝¹ = mk φQ✝ φH✝

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

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

Next tactic:
let φQ : h₁.Q ⟶ h₂.Q := h₁.descQ (φ.τ₂ ≫ h₂.p) (by rw [← φ.comm₁₂_assoc, h₂.wp, comp_zero])
instance : Inhabited (RightHomologyMapData φ h₁ h₂) := ⟨by
  let φQ : h₁.Q ⟶ h₂.Q := h₁.descQ (φ.τ₂ ≫ h₂.p) (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.65140, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
⊢ S₁.f ≫ φ.τ₂ ≫ h₂.p = 0

Next tactic:
rw [← φ.comm₁₂_assoc, h₂.wp, comp_zero]
instance : Inhabited (RightHomologyMapData φ h₁ h₂) := ⟨by
  let φQ : h₁.Q ⟶ h₂.Q := h₁.descQ (φ.τ₂ ≫ h₂.p) (by rw [← φ.comm₁₂_assoc, h₂.wp, comp_zero])
  

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.65140, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
φQ : h₁.Q ⟶ h₂.Q := RightHomologyData.descQ h₁ (φ.τ₂ ≫ h₂.p) (_ : S₁.f ≫ φ.τ₂ ≫ h₂.p = 0)
⊢ RightHomologyMapData φ h₁ h₂

Next tactic:
have commg' : φQ ≫ h₂.g' = h₁.g' ≫ φ.τ₃ :=
    by rw [← cancel_epi h₁.p, RightHomologyData.p_descQ_assoc, assoc,
      RightHomologyData.p_g', φ.comm₂₃, RightHomologyData.p_g'_assoc]
instance : Inhabited (RightHomologyMapData φ h₁ h₂) := ⟨by
  let φQ : h₁.Q ⟶ h₂.Q := h₁.descQ (φ.τ₂ ≫ h₂.p) (by rw [← φ.comm₁₂_assoc, h₂.wp, comp_zero])
  have commg' : φQ ≫ h₂.g' = h₁.g' ≫ φ.τ₃ :=
    by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.65140, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
φQ : h₁.Q ⟶ h₂.Q := RightHomologyData.descQ h₁ (φ.τ₂ ≫ h₂.p) (_ : S₁.f ≫ φ.τ₂ ≫ h₂.p = 0)
⊢ φQ ≫ RightHomologyData.g' h₂ = RightHomologyData.g' h₁ ≫ φ.τ₃

Next tactic:
rw [← cancel_epi h₁.p, RightHomologyData.p_descQ_assoc, assoc,
      RightHomologyData.p_g', φ.comm₂₃, RightHomologyData.p_g'_assoc]
instance : Inhabited (RightHomologyMapData φ h₁ h₂) := ⟨by
  let φQ : h₁.Q ⟶ h₂.Q := h₁.descQ (φ.τ₂ ≫ h₂.p) (by rw [← φ.comm₁₂_assoc, h₂.wp, comp_zero])
  have commg' : φQ ≫ h₂.g' = h₁.g' ≫ φ.τ₃ :=
    by rw [← cancel_epi h₁.p, RightHomologyData.p_descQ_assoc, assoc,
      RightHomologyData.p_g', φ.comm₂₃, RightHomologyData.p_g'_assoc]
  

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.65140, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
φQ : h₁.Q ⟶ h₂.Q := RightHomologyData.descQ h₁ (φ.τ₂ ≫ h₂.p) (_ : S₁.f ≫ φ.τ₂ ≫ h₂.p = 0)
commg' : φQ ≫ RightHomologyData.g' h₂ = RightHomologyData.g' h₁ ≫ φ.τ₃
⊢ RightHomologyMapData φ h₁ h₂

Next tactic:
let φH : h₁.H ⟶ h₂.H := h₂.liftH (h₁.ι ≫ φQ)
    (by rw [assoc, commg', RightHomologyData.ι_g'_assoc, zero_comp])
instance : Inhabited (RightHomologyMapData φ h₁ h₂) := ⟨by
  let φQ : h₁.Q ⟶ h₂.Q := h₁.descQ (φ.τ₂ ≫ h₂.p) (by rw [← φ.comm₁₂_assoc, h₂.wp, comp_zero])
  have commg' : φQ ≫ h₂.g' = h₁.g' ≫ φ.τ₃ :=
    by rw [← cancel_epi h₁.p, RightHomologyData.p_descQ_assoc, assoc,
      RightHomologyData.p_g', φ.comm₂₃, RightHomologyData.p_g'_assoc]
  let φH : h₁.H ⟶ h₂.H := h₂.liftH (h₁.ι ≫ φQ)
    (by 

Proof state:
C : Type u_1
inst✝¹ : Category.{?u.65140, u_1} C
inst✝ : HasZeroMorphisms C
S S₁ S₂ S₃ : ShortComplex C
φ : S₁ ⟶ S₂
h₁ : RightHomologyData S₁
h₂ : RightHomologyData S₂
φQ : h₁.Q ⟶ h₂.Q := RightHomologyData.descQ h₁ (φ.τ₂ ≫ h₂.p) (_ : S₁.f ≫ φ.τ₂ ≫ h₂.p = 0)
commg' : φQ ≫ RightHomologyData.g' h₂ = RightHomologyData.g' h₁ ≫ φ.τ₃
⊢ (h₁.ι ≫ φQ) ≫ RightHomologyData.g' h₂ = 0

Next tactic:
rw [assoc, commg', RightHomologyData.ι_g'_assoc, zero_comp]