l3lab/ntp-mathlib huggingface dataset:
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed cochain complexes,
working by induction.

You need to provide the components of the homotopy in degrees 0 and 1,
show that these satisfy the homotopy condition,
and then give a construction of each component,
and the fact that it satisfies the homotopy condition,
using as an inductive hypothesis the data and homotopy condition for the previous two components.
-/
def mkCoinductive : Homotopy e 0 where
  hom i j :=
    if h : j + 1 = i then
      (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).2.1
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    rw [add_comm]
    refine' (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [toPrev, mkCoinductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [toPrev]
        simp only [CochainComplex.prev_nat_succ, dite_true]
        

Proof state:
case e_a.e_a.succ
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i : ι
P Q : CochainComplex V ℕ
e : P ⟶ Q
zero : X P 1 ⟶ X Q 0
comm_zero : Hom.f e 0 = d P 0 1 ≫ zero
one : X P 2 ⟶ X Q 1
comm_one : Hom.f e 1 = zero ≫ d Q 0 1 + d P 1 2 ≫ one
succ :
  (n : ℕ) →
    (p :
        (f : X P (n + 1) ⟶ X Q n) ×'
          (f' : X P (n + 2) ⟶ X Q (n + 1)) ×' Hom.f e (n + 1) = f ≫ d Q n (n + 1) + d P (n + 1) (n + 2) ≫ f') →
      (f'' : X P (n + 3) ⟶ X Q (n + 2)) ×' Hom.f e (n + 2) = p.snd.fst ≫ d Q (n + 1) (n + 2) + d P (n + 2) (n + 3) ≫ f''
n✝ : ℕ
⊢ (mkCoinductiveAux₁ e zero one comm_one succ n✝).fst ≫ (xPrevIso Q (_ : n✝ + 1 = n✝ + 1)).inv =
    (xNextIso P (_ : ComplexShape.prev (ComplexShape.up ℕ) (Nat.succ n✝) + 1 = Nat.succ n✝)).inv ≫
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ
            (ComplexShape.prev (ComplexShape.up ℕ) (Nat.succ n✝))).snd.fst

Next tactic:
rw [mkCoinductiveAux₃ e zero comm_zero one comm_one succ]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed cochain complexes,
working by induction.

You need to provide the components of the homotopy in degrees 0 and 1,
show that these satisfy the homotopy condition,
and then give a construction of each component,
and the fact that it satisfies the homotopy condition,
using as an inductive hypothesis the data and homotopy condition for the previous two components.
-/
def mkCoinductive : Homotopy e 0 where
  hom i j :=
    if h : j + 1 = i then
      (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).2.1
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    rw [add_comm]
    refine' (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [toPrev, mkCoinductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [toPrev]
        simp only [CochainComplex.prev_nat_succ, dite_true]
        rw [mkCoinductiveAux₃ e zero comm_zero one comm_one succ]
        

Proof state:
case e_a.e_a.succ
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i : ι
P Q : CochainComplex V ℕ
e : P ⟶ Q
zero : X P 1 ⟶ X Q 0
comm_zero : Hom.f e 0 = d P 0 1 ≫ zero
one : X P 2 ⟶ X Q 1
comm_one : Hom.f e 1 = zero ≫ d Q 0 1 + d P 1 2 ≫ one
succ :
  (n : ℕ) →
    (p :
        (f : X P (n + 1) ⟶ X Q n) ×'
          (f' : X P (n + 2) ⟶ X Q (n + 1)) ×' Hom.f e (n + 1) = f ≫ d Q n (n + 1) + d P (n + 1) (n + 2) ≫ f') →
      (f'' : X P (n + 3) ⟶ X Q (n + 2)) ×' Hom.f e (n + 2) = p.snd.fst ≫ d Q (n + 1) (n + 2) + d P (n + 2) (n + 3) ≫ f''
n✝ : ℕ
⊢ (mkCoinductiveAux₁ e zero one comm_one succ n✝).fst ≫ (xPrevIso Q (_ : n✝ + 1 = n✝ + 1)).inv =
    (mkCoinductiveAux₂ e zero comm_zero one comm_one succ (Nat.succ n✝)).fst ≫
      (xPrevIso Q (_ : ComplexShape.prev (ComplexShape.up ℕ) (Nat.succ n✝) + 1 = Nat.succ n✝)).hom

Next tactic:
dsimp [xPrevIso]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed cochain complexes,
working by induction.

You need to provide the components of the homotopy in degrees 0 and 1,
show that these satisfy the homotopy condition,
and then give a construction of each component,
and the fact that it satisfies the homotopy condition,
using as an inductive hypothesis the data and homotopy condition for the previous two components.
-/
def mkCoinductive : Homotopy e 0 where
  hom i j :=
    if h : j + 1 = i then
      (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).2.1
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    rw [add_comm]
    refine' (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [toPrev, mkCoinductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [toPrev]
        simp only [CochainComplex.prev_nat_succ, dite_true]
        rw [mkCoinductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xPrevIso]
        

Proof state:
case e_a.e_a.succ
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i : ι
P Q : CochainComplex V ℕ
e : P ⟶ Q
zero : X P 1 ⟶ X Q 0
comm_zero : Hom.f e 0 = d P 0 1 ≫ zero
one : X P 2 ⟶ X Q 1
comm_one : Hom.f e 1 = zero ≫ d Q 0 1 + d P 1 2 ≫ one
succ :
  (n : ℕ) →
    (p :
        (f : X P (n + 1) ⟶ X Q n) ×'
          (f' : X P (n + 2) ⟶ X Q (n + 1)) ×' Hom.f e (n + 1) = f ≫ d Q n (n + 1) + d P (n + 1) (n + 2) ≫ f') →
      (f'' : X P (n + 3) ⟶ X Q (n + 2)) ×' Hom.f e (n + 2) = p.snd.fst ≫ d Q (n + 1) (n + 2) + d P (n + 2) (n + 3) ≫ f''
n✝ : ℕ
⊢ (mkCoinductiveAux₁ e zero one comm_one succ n✝).fst ≫ eqToHom (_ : X Q n✝ = xPrev Q (n✝ + 1)) =
    ((mkCoinductiveAux₁ e zero one comm_one succ n✝).fst ≫ eqToHom (_ : X Q n✝ = xPrev Q (n✝ + 1))) ≫
      𝟙 (xPrev Q (Nat.succ n✝))

Next tactic:
rw [comp_id]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed cochain complexes,
working by induction.

You need to provide the components of the homotopy in degrees 0 and 1,
show that these satisfy the homotopy condition,
and then give a construction of each component,
and the fact that it satisfies the homotopy condition,
using as an inductive hypothesis the data and homotopy condition for the previous two components.
-/
def mkCoinductive : Homotopy e 0 where
  hom i j :=
    if h : j + 1 = i then
      (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).2.1
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    rw [add_comm]
    refine' (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [toPrev, mkCoinductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [toPrev]
        simp only [CochainComplex.prev_nat_succ, dite_true]
        rw [mkCoinductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xPrevIso]
        rw [comp_id]
    · 

Proof state:
case e_a.e_a
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i✝ : ι
P Q : CochainComplex V ℕ
e : P ⟶ Q
zero : X P 1 ⟶ X Q 0
comm_zero : Hom.f e 0 = d P 0 1 ≫ zero
one : X P 2 ⟶ X Q 1
comm_one : Hom.f e 1 = zero ≫ d Q 0 1 + d P 1 2 ≫ one
succ :
  (n : ℕ) →
    (p :
        (f : X P (n + 1) ⟶ X Q n) ×'
          (f' : X P (n + 2) ⟶ X Q (n + 1)) ×' Hom.f e (n + 1) = f ≫ d Q n (n + 1) + d P (n + 1) (n + 2) ≫ f') →
      (f'' : X P (n + 3) ⟶ X Q (n + 2)) ×' Hom.f e (n + 2) = p.snd.fst ≫ d Q (n + 1) (n + 2) + d P (n + 2) (n + 3) ≫ f''
i : ℕ
⊢ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst =
    (fromNext i) fun i j =>
      if h : j + 1 = i then (xNextIso P h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).snd.fst else 0

Next tactic:
dsimp [fromNext]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed cochain complexes,
working by induction.

You need to provide the components of the homotopy in degrees 0 and 1,
show that these satisfy the homotopy condition,
and then give a construction of each component,
and the fact that it satisfies the homotopy condition,
using as an inductive hypothesis the data and homotopy condition for the previous two components.
-/
def mkCoinductive : Homotopy e 0 where
  hom i j :=
    if h : j + 1 = i then
      (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).2.1
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    rw [add_comm]
    refine' (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [toPrev, mkCoinductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [toPrev]
        simp only [CochainComplex.prev_nat_succ, dite_true]
        rw [mkCoinductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xPrevIso]
        rw [comp_id]
    · dsimp [fromNext]
      

Proof state:
case e_a.e_a
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i✝ : ι
P Q : CochainComplex V ℕ
e : P ⟶ Q
zero : X P 1 ⟶ X Q 0
comm_zero : Hom.f e 0 = d P 0 1 ≫ zero
one : X P 2 ⟶ X Q 1
comm_one : Hom.f e 1 = zero ≫ d Q 0 1 + d P 1 2 ≫ one
succ :
  (n : ℕ) →
    (p :
        (f : X P (n + 1) ⟶ X Q n) ×'
          (f' : X P (n + 2) ⟶ X Q (n + 1)) ×' Hom.f e (n + 1) = f ≫ d Q n (n + 1) + d P (n + 1) (n + 2) ≫ f') →
      (f'' : X P (n + 3) ⟶ X Q (n + 2)) ×' Hom.f e (n + 2) = p.snd.fst ≫ d Q (n + 1) (n + 2) + d P (n + 2) (n + 3) ≫ f''
i : ℕ
⊢ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst =
    if h : i + 1 = ComplexShape.next (ComplexShape.up ℕ) i then
      (xNextIso P h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst
    else 0

Next tactic:
erw [dif_pos, id_comp]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed cochain complexes,
working by induction.

You need to provide the components of the homotopy in degrees 0 and 1,
show that these satisfy the homotopy condition,
and then give a construction of each component,
and the fact that it satisfies the homotopy condition,
using as an inductive hypothesis the data and homotopy condition for the previous two components.
-/
def mkCoinductive : Homotopy e 0 where
  hom i j :=
    if h : j + 1 = i then
      (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).2.1
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    rw [add_comm]
    refine' (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [toPrev, mkCoinductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [toPrev]
        simp only [CochainComplex.prev_nat_succ, dite_true]
        rw [mkCoinductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xPrevIso]
        rw [comp_id]
    · dsimp [fromNext]
      erw [dif_pos, id_comp]
      

Proof state:
case e_a.e_a.hc
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i✝ : ι
P Q : CochainComplex V ℕ
e : P ⟶ Q
zero : X P 1 ⟶ X Q 0
comm_zero : Hom.f e 0 = d P 0 1 ≫ zero
one : X P 2 ⟶ X Q 1
comm_one : Hom.f e 1 = zero ≫ d Q 0 1 + d P 1 2 ≫ one
succ :
  (n : ℕ) →
    (p :
        (f : X P (n + 1) ⟶ X Q n) ×'
          (f' : X P (n + 2) ⟶ X Q (n + 1)) ×' Hom.f e (n + 1) = f ≫ d Q n (n + 1) + d P (n + 1) (n + 2) ≫ f') →
      (f'' : X P (n + 3) ⟶ X Q (n + 2)) ×' Hom.f e (n + 2) = p.snd.fst ≫ d Q (n + 1) (n + 2) + d P (n + 2) (n + 3) ≫ f''
i : ℕ
⊢ i + 1 = ComplexShape.next (ComplexShape.up ℕ) i
case e_a.e_a.hc
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h k : D ⟶ E
i✝ : ι
P Q : CochainComplex V ℕ
e : P ⟶ Q
zero : X P 1 ⟶ X Q 0
comm_zero : Hom.f e 0 = d P 0 1 ≫ zero
one : X P 2 ⟶ X Q 1
comm_one : Hom.f e 1 = zero ≫ d Q 0 1 + d P 1 2 ≫ one
succ :
  (n : ℕ) →
    (p :
        (f : X P (n + 1) ⟶ X Q n) ×'
          (f' : X P (n + 2) ⟶ X Q (n + 1)) ×' Hom.f e (n + 1) = f ≫ d Q n (n + 1) + d P (n + 1) (n + 2) ≫ f') →
      (f'' : X P (n + 3) ⟶ X Q (n + 2)) ×' Hom.f e (n + 2) = p.snd.fst ≫ d Q (n + 1) (n + 2) + d P (n + 2) (n + 3) ≫ f''
i : ℕ
⊢ i + 1 = ComplexShape.next (ComplexShape.up ℕ) i

Next tactic:
simp only [CochainComplex.next]
/-- Any complex is homotopy equivalent to itself. -/
@[refl]
def refl (C : HomologicalComplex V c) : HomotopyEquiv C C where
  hom := 𝟙 C
  inv := 𝟙 C
  homotopyHomInvId := Homotopy.ofEq (by 

Proof state:
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C✝ D E : HomologicalComplex V c
f g : C✝ ⟶ D
h k : D ⟶ E
i : ι
C : HomologicalComplex V c
⊢ 𝟙 C ≫ 𝟙 C = 𝟙 C

Next tactic:
simp
/-- Any complex is homotopy equivalent to itself. -/
@[refl]
def refl (C : HomologicalComplex V c) : HomotopyEquiv C C where
  hom := 𝟙 C
  inv := 𝟙 C
  homotopyHomInvId := Homotopy.ofEq (by simp)
  homotopyInvHomId := Homotopy.ofEq (by 

Proof state:
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C✝ D E : HomologicalComplex V c
f g : C✝ ⟶ D
h k : D ⟶ E
i : ι
C : HomologicalComplex V c
⊢ 𝟙 C ≫ 𝟙 C = 𝟙 C

Next tactic:
simp
/-- Homotopy equivalence is a transitive relation. -/
@[trans]
def trans {C D E : HomologicalComplex V c} (f : HomotopyEquiv C D) (g : HomotopyEquiv D E) :
    HomotopyEquiv C E where
  hom := f.hom ≫ g.hom
  inv := g.inv ≫ f.inv
  homotopyHomInvId := by 

Proof state:
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C✝ D✝ E✝ : HomologicalComplex V c
f✝ g✝ : C✝ ⟶ D✝
h k : D✝ ⟶ E✝
i : ι
C D E : HomologicalComplex V c
f : HomotopyEquiv C D
g : HomotopyEquiv D E
⊢ Homotopy ((f.hom ≫ g.hom) ≫ g.inv ≫ f.inv) (𝟙 C)

Next tactic:
simpa using
    ((g.homotopyHomInvId.compRightId f.inv).compLeft f.hom).trans f.homotopyHomInvId
/-- Homotopy equivalence is a transitive relation. -/
@[trans]
def trans {C D E : HomologicalComplex V c} (f : HomotopyEquiv C D) (g : HomotopyEquiv D E) :
    HomotopyEquiv C E where
  hom := f.hom ≫ g.hom
  inv := g.inv ≫ f.inv
  homotopyHomInvId := by simpa using
    ((g.homotopyHomInvId.compRightId f.inv).compLeft f.hom).trans f.homotopyHomInvId
  homotopyInvHomId := by 

Proof state:
ι : Type u_1
V : Type u
inst✝¹ : Category.{v, u} V
inst✝ : Preadditive V
c : ComplexShape ι
C✝ D✝ E✝ : HomologicalComplex V c
f✝ g✝ : C✝ ⟶ D✝
h k : D✝ ⟶ E✝
i : ι
C D E : HomologicalComplex V c
f : HomotopyEquiv C D
g : HomotopyEquiv D E
⊢ Homotopy ((g.inv ≫ f.inv) ≫ f.hom ≫ g.hom) (𝟙 E)

Next tactic:
simpa using
    ((f.homotopyInvHomId.compRightId g.hom).compLeft g.inv).trans g.homotopyInvHomId
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ (homology'Functor V c i).map f = (homology'Functor V c i).map g

Next tactic:
dsimp [homology'Functor]
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  dsimp [homology'Functor]
  

Proof state:
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ homology'.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo f i) (Hom.sqFrom f i)
      (_ : (Hom.sqTo f i).right = (Hom.sqTo f i).right) =
    homology'.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo g i) (Hom.sqFrom g i)
      (_ : (Hom.sqTo g i).right = (Hom.sqTo g i).right)

Next tactic:
apply eq_of_sub_eq_zero
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  dsimp [homology'Functor]
  apply eq_of_sub_eq_zero
  

Proof state:
case h
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ homology'.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo f i) (Hom.sqFrom f i)
        (_ : (Hom.sqTo f i).right = (Hom.sqTo f i).right) -
      homology'.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo g i) (Hom.sqFrom g i)
        (_ : (Hom.sqTo g i).right = (Hom.sqTo g i).right) =
    0

Next tactic:
ext
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  dsimp [homology'Functor]
  apply eq_of_sub_eq_zero
  ext
  

Proof state:
case h.p
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ homology'.π (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0) ≫
      (homology'.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo f i) (Hom.sqFrom f i)
          (_ : (Hom.sqTo f i).right = (Hom.sqTo f i).right) -
        homology'.map (_ : dTo C i ≫ dFrom C i = 0) (_ : dTo D i ≫ dFrom D i = 0) (Hom.sqTo g i) (Hom.sqFrom g i)
          (_ : (Hom.sqTo g i).right = (Hom.sqTo g i).right)) =
    homology'.π (dTo C i) (dFrom C i) (_ : dTo C i ≫ dFrom C i = 0) ≫ 0

Next tactic:
simp only [homology'.π_map, comp_zero, Preadditive.comp_sub]
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  dsimp [homology'Functor]
  apply eq_of_sub_eq_zero
  ext
  simp only [homology'.π_map, comp_zero, Preadditive.comp_sub]
  

Proof state:
case h.p
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ kernelSubobjectMap (Hom.sqFrom f i) ≫ homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) -
      kernelSubobjectMap (Hom.sqFrom g i) ≫ homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) =
    0

Next tactic:
dsimp [kernelSubobjectMap]
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  dsimp [homology'Functor]
  apply eq_of_sub_eq_zero
  ext
  simp only [homology'.π_map, comp_zero, Preadditive.comp_sub]
  dsimp [kernelSubobjectMap]
  

Proof state:
case h.p
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ Subobject.factorThru (kernelSubobject (dFrom D i)) (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ Hom.f f i)
          (_ :
            Subobject.Factors (kernelSubobject (dFrom D i))
              (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ (Hom.sqFrom f i).left)) ≫
        homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) -
      Subobject.factorThru (kernelSubobject (dFrom D i)) (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ Hom.f g i)
          (_ :
            Subobject.Factors (kernelSubobject (dFrom D i))
              (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ (Hom.sqFrom g i).left)) ≫
        homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) =
    0

Next tactic:
simp_rw [h.comm i]
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  dsimp [homology'Functor]
  apply eq_of_sub_eq_zero
  ext
  simp only [homology'.π_map, comp_zero, Preadditive.comp_sub]
  dsimp [kernelSubobjectMap]
  simp_rw [h.comm i]
  

Proof state:
case h.p
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ Subobject.factorThru (kernelSubobject (dFrom D i))
          (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ ((dNext i) h.hom + (prevD i) h.hom + Hom.f g i))
          (_ :
            Subobject.Factors (kernelSubobject (dFrom D i))
              (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ ((dNext i) h.hom + (prevD i) h.hom + Hom.f g i))) ≫
        homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) -
      Subobject.factorThru (kernelSubobject (dFrom D i)) (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ Hom.f g i)
          (_ :
            Subobject.Factors (kernelSubobject (dFrom D i))
              (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ (Hom.sqFrom g i).left)) ≫
        homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) =
    0

Next tactic:
simp only [zero_add, zero_comp, dNext_eq_dFrom_fromNext, kernelSubobject_arrow_comp_assoc,
    Preadditive.comp_add]
/-- Homotopic maps induce the same map on homology.
-/
theorem homology'_map_eq_of_homotopy (h : Homotopy f g) (i : ι) :
    (homology'Functor V c i).map f = (homology'Functor V c i).map g := by
  dsimp [homology'Functor]
  apply eq_of_sub_eq_zero
  ext
  simp only [homology'.π_map, comp_zero, Preadditive.comp_sub]
  dsimp [kernelSubobjectMap]
  simp_rw [h.comm i]
  simp only [zero_add, zero_comp, dNext_eq_dFrom_fromNext, kernelSubobject_arrow_comp_assoc,
    Preadditive.comp_add]
  

Proof state:
case h.p
ι : Type u_1
V : Type u
inst✝⁵ : Category.{v, u} V
inst✝⁴ : Preadditive V
c : ComplexShape ι
C D E : HomologicalComplex V c
f g : C ⟶ D
h✝ k : D ⟶ E
i✝ : ι
inst✝³ : HasEqualizers V
inst✝² : HasCokernels V
inst✝¹ : HasImages V
inst✝ : HasImageMaps V
h : Homotopy f g
i : ι
⊢ Subobject.factorThru (kernelSubobject (dFrom D i))
          (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ (prevD i) h.hom +
            Subobject.arrow (kernelSubobject (dFrom C i)) ≫ Hom.f g i)
          (_ :
            Subobject.Factors (kernelSubobject (dFrom D i))
              (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ (prevD i) h.hom +
                Subobject.arrow (kernelSubobject (dFrom C i)) ≫ Hom.f g i)) ≫
        homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) -
      Subobject.factorThru (kernelSubobject (dFrom D i)) (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ Hom.f g i)
          (_ :
            Subobject.Factors (kernelSubobject (dFrom D i))
              (Subobject.arrow (kernelSubobject (dFrom C i)) ≫ (Hom.sqFrom g i).left)) ≫
        homology'.π (dTo D i) (dFrom D i) (_ : dTo D i ≫ dFrom D i = 0) =
    0

Next tactic:
rw [← Preadditive.sub_comp]