l3lab/ntp-mathlib huggingface dataset:
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed chain 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 mkInductive : Homotopy e 0 where
  hom i j :=
    if h : i + 1 = j then
      (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.1 ≫ (Q.xPrevIso h).hom
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    refine' (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [fromNext, mkInductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [fromNext]
        simp only [ChainComplex.next_nat_succ, dite_true]
        rw [mkInductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xNextIso]
        

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 : ChainComplex V ℕ
e : P ⟶ Q
zero : X P 0 ⟶ X Q 1
comm_zero : Hom.f e 0 = zero ≫ d Q 1 0
one : X P 1 ⟶ X Q 2
comm_one : Hom.f e 1 = d P 1 0 ≫ zero + one ≫ d Q 2 1
succ :
  (n : ℕ) →
    (p :
        (f : X P n ⟶ X Q (n + 1)) ×'
          (f' : X P (n + 1) ⟶ X Q (n + 2)) ×' Hom.f e (n + 1) = d P (n + 1) n ≫ f + f' ≫ d Q (n + 2) (n + 1)) →
      (f'' : X P (n + 2) ⟶ X Q (n + 3)) ×' Hom.f e (n + 2) = d P (n + 2) (n + 1) ≫ p.snd.fst + f'' ≫ d Q (n + 3) (n + 2)
n✝ : ℕ
⊢ eqToHom (_ : xNext P (n✝ + 1) = X P n✝) ≫ (mkInductiveAux₁ e zero one comm_one succ n✝).fst =
    𝟙 (xNext P (Nat.succ n✝)) ≫
      eqToHom (_ : xNext P (n✝ + 1) = X P n✝) ≫ (mkInductiveAux₁ e zero one comm_one succ n✝).fst

Next tactic:
rw [id_comp]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed chain 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 mkInductive : Homotopy e 0 where
  hom i j :=
    if h : i + 1 = j then
      (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.1 ≫ (Q.xPrevIso h).hom
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    refine' (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [fromNext, mkInductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [fromNext]
        simp only [ChainComplex.next_nat_succ, dite_true]
        rw [mkInductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xNextIso]
        rw [id_comp]
    · 

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 : ChainComplex V ℕ
e : P ⟶ Q
zero : X P 0 ⟶ X Q 1
comm_zero : Hom.f e 0 = zero ≫ d Q 1 0
one : X P 1 ⟶ X Q 2
comm_one : Hom.f e 1 = d P 1 0 ≫ zero + one ≫ d Q 2 1
succ :
  (n : ℕ) →
    (p :
        (f : X P n ⟶ X Q (n + 1)) ×'
          (f' : X P (n + 1) ⟶ X Q (n + 2)) ×' Hom.f e (n + 1) = d P (n + 1) n ≫ f + f' ≫ d Q (n + 2) (n + 1)) →
      (f'' : X P (n + 2) ⟶ X Q (n + 3)) ×' Hom.f e (n + 2) = d P (n + 2) (n + 1) ≫ p.snd.fst + f'' ≫ d Q (n + 3) (n + 2)
i : ℕ
⊢ (mkInductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst =
    (toPrev i) fun i j =>
      if h : i + 1 = j then (mkInductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst ≫ (xPrevIso Q h).hom else 0

Next tactic:
dsimp [toPrev]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed chain 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 mkInductive : Homotopy e 0 where
  hom i j :=
    if h : i + 1 = j then
      (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.1 ≫ (Q.xPrevIso h).hom
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    refine' (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [fromNext, mkInductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [fromNext]
        simp only [ChainComplex.next_nat_succ, dite_true]
        rw [mkInductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xNextIso]
        rw [id_comp]
    · dsimp [toPrev]
      

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 : ChainComplex V ℕ
e : P ⟶ Q
zero : X P 0 ⟶ X Q 1
comm_zero : Hom.f e 0 = zero ≫ d Q 1 0
one : X P 1 ⟶ X Q 2
comm_one : Hom.f e 1 = d P 1 0 ≫ zero + one ≫ d Q 2 1
succ :
  (n : ℕ) →
    (p :
        (f : X P n ⟶ X Q (n + 1)) ×'
          (f' : X P (n + 1) ⟶ X Q (n + 2)) ×' Hom.f e (n + 1) = d P (n + 1) n ≫ f + f' ≫ d Q (n + 2) (n + 1)) →
      (f'' : X P (n + 2) ⟶ X Q (n + 3)) ×' Hom.f e (n + 2) = d P (n + 2) (n + 1) ≫ p.snd.fst + f'' ≫ d Q (n + 3) (n + 2)
i : ℕ
⊢ (mkInductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst =
    if h : i + 1 = ComplexShape.prev (ComplexShape.down ℕ) i then
      (mkInductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst ≫ (xPrevIso Q h).hom
    else 0

Next tactic:
erw [dif_pos, comp_id]
/-- A constructor for a `Homotopy e 0`, for `e` a chain map between `ℕ`-indexed chain 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 mkInductive : Homotopy e 0 where
  hom i j :=
    if h : i + 1 = j then
      (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.1 ≫ (Q.xPrevIso h).hom
    else 0
  zero i j w := by dsimp; rw [dif_neg]; exact w
  comm i := by
    dsimp
    simp only [add_zero]
    refine' (mkInductiveAux₂ e zero comm_zero one comm_one succ i).2.2.trans _
    congr
    · cases i
      · dsimp [fromNext, mkInductiveAux₂]
        rw [dif_neg]
        decide
      · dsimp [fromNext]
        simp only [ChainComplex.next_nat_succ, dite_true]
        rw [mkInductiveAux₃ e zero comm_zero one comm_one succ]
        dsimp [xNextIso]
        rw [id_comp]
    · dsimp [toPrev]
      erw [dif_pos, comp_id]
      

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 : ChainComplex V ℕ
e : P ⟶ Q
zero : X P 0 ⟶ X Q 1
comm_zero : Hom.f e 0 = zero ≫ d Q 1 0
one : X P 1 ⟶ X Q 2
comm_one : Hom.f e 1 = d P 1 0 ≫ zero + one ≫ d Q 2 1
succ :
  (n : ℕ) →
    (p :
        (f : X P n ⟶ X Q (n + 1)) ×'
          (f' : X P (n + 1) ⟶ X Q (n + 2)) ×' Hom.f e (n + 1) = d P (n + 1) n ≫ f + f' ≫ d Q (n + 2) (n + 1)) →
      (f'' : X P (n + 2) ⟶ X Q (n + 3)) ×' Hom.f e (n + 2) = d P (n + 2) (n + 1) ≫ p.snd.fst + f'' ≫ d Q (n + 3) (n + 2)
i : ℕ
⊢ i + 1 = ComplexShape.prev (ComplexShape.down ℕ) 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 : ChainComplex V ℕ
e : P ⟶ Q
zero : X P 0 ⟶ X Q 1
comm_zero : Hom.f e 0 = zero ≫ d Q 1 0
one : X P 1 ⟶ X Q 2
comm_one : Hom.f e 1 = d P 1 0 ≫ zero + one ≫ d Q 2 1
succ :
  (n : ℕ) →
    (p :
        (f : X P n ⟶ X Q (n + 1)) ×'
          (f' : X P (n + 1) ⟶ X Q (n + 2)) ×' Hom.f e (n + 1) = d P (n + 1) n ≫ f + f' ≫ d Q (n + 2) (n + 1)) →
      (f'' : X P (n + 2) ⟶ X Q (n + 3)) ×' Hom.f e (n + 2) = d P (n + 2) (n + 1) ≫ p.snd.fst + f'' ≫ d Q (n + 3) (n + 2)
i : ℕ
⊢ i + 1 = ComplexShape.prev (ComplexShape.down ℕ) i

Next tactic:
simp only [ChainComplex.prev]
@[simp 1100]
theorem dNext_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) (j : ℕ) :
    dNext j f = P.d _ _ ≫ f (j + 1) j := 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 : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
j : ℕ
⊢ (dNext j) f = d P j (j + 1) ≫ f (j + 1) j

Next tactic:
dsimp [dNext]
@[simp 1100]
theorem dNext_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) (j : ℕ) :
    dNext j f = P.d _ _ ≫ f (j + 1) j := by
  dsimp [dNext]
  

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 : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
j : ℕ
⊢ d P j (ComplexShape.next (ComplexShape.up ℕ) j) ≫ f (ComplexShape.next (ComplexShape.up ℕ) j) j =
    d P j (j + 1) ≫ f (j + 1) j

Next tactic:
have : (ComplexShape.up ℕ).next j = j + 1 := CochainComplex.next ℕ j
@[simp 1100]
theorem dNext_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) (j : ℕ) :
    dNext j f = P.d _ _ ≫ f (j + 1) j := by
  dsimp [dNext]
  have : (ComplexShape.up ℕ).next j = j + 1 := CochainComplex.next ℕ j
  

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 : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
j : ℕ
this : ComplexShape.next (ComplexShape.up ℕ) j = j + 1
⊢ d P j (ComplexShape.next (ComplexShape.up ℕ) j) ≫ f (ComplexShape.next (ComplexShape.up ℕ) j) j =
    d P j (j + 1) ≫ f (j + 1) j

Next tactic:
congr 2
@[simp 1100]
theorem prevD_succ_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) (i : ℕ) :
    prevD (i + 1) f = f (i + 1) _ ≫ Q.d i (i + 1) := 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✝ : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
i : ℕ
⊢ (prevD (i + 1)) f = f (i + 1) i ≫ d Q i (i + 1)

Next tactic:
dsimp [prevD]
@[simp 1100]
theorem prevD_succ_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) (i : ℕ) :
    prevD (i + 1) f = f (i + 1) _ ≫ Q.d i (i + 1) := by
  dsimp [prevD]
  

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✝ : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
i : ℕ
⊢ f (i + 1) (ComplexShape.prev (ComplexShape.up ℕ) (i + 1)) ≫
      d Q (ComplexShape.prev (ComplexShape.up ℕ) (i + 1)) (i + 1) =
    f (i + 1) i ≫ d Q i (i + 1)

Next tactic:
have : (ComplexShape.up ℕ).prev (i + 1) = i := CochainComplex.prev_nat_succ i
@[simp 1100]
theorem prevD_succ_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) (i : ℕ) :
    prevD (i + 1) f = f (i + 1) _ ≫ Q.d i (i + 1) := by
  dsimp [prevD]
  have : (ComplexShape.up ℕ).prev (i + 1) = i := CochainComplex.prev_nat_succ i
  

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✝ : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
i : ℕ
this : ComplexShape.prev (ComplexShape.up ℕ) (i + 1) = i
⊢ f (i + 1) (ComplexShape.prev (ComplexShape.up ℕ) (i + 1)) ≫
      d Q (ComplexShape.prev (ComplexShape.up ℕ) (i + 1)) (i + 1) =
    f (i + 1) i ≫ d Q i (i + 1)

Next tactic:
congr 2
@[simp 1100]
theorem prevD_zero_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) : prevD 0 f = 0 := 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 : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
⊢ (prevD 0) f = 0

Next tactic:
dsimp [prevD]
@[simp 1100]
theorem prevD_zero_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) : prevD 0 f = 0 := by
  dsimp [prevD]
  

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 : ι
P Q : CochainComplex V ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
⊢ f 0 (ComplexShape.prev (ComplexShape.up ℕ) 0) ≫ d Q (ComplexShape.prev (ComplexShape.up ℕ) 0) 0 = 0

Next tactic:
rw [Q.shape, comp_zero]
@[simp 1100]
theorem prevD_zero_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) : prevD 0 f = 0 := by
  dsimp [prevD]
  rw [Q.shape, comp_zero]
  

Proof state:
case 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 ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
⊢ ¬ComplexShape.Rel (ComplexShape.up ℕ) (ComplexShape.prev (ComplexShape.up ℕ) 0) 0

Next tactic:
rw [CochainComplex.prev_nat_zero]
@[simp 1100]
theorem prevD_zero_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) : prevD 0 f = 0 := by
  dsimp [prevD]
  rw [Q.shape, comp_zero]
  rw [CochainComplex.prev_nat_zero]; 

Proof state:
case 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 ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
⊢ ¬ComplexShape.Rel (ComplexShape.up ℕ) 0 0

Next tactic:
dsimp
@[simp 1100]
theorem prevD_zero_cochainComplex (f : ∀ i j, P.X i ⟶ Q.X j) : prevD 0 f = 0 := by
  dsimp [prevD]
  rw [Q.shape, comp_zero]
  rw [CochainComplex.prev_nat_zero]; dsimp; 

Proof state:
case 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 ℕ
f : (i j : ℕ) → X P i ⟶ X Q j
⊢ ¬0 + 1 = 0

Next tactic:
decide
/-- An auxiliary construction for `mkInductive`.
-/
def mkCoinductiveAux₂ :
    ∀ n, Σ' (f : P.X n ⟶ Q.xPrev n) (f' : P.xNext n ⟶ Q.X n), e.f n = f ≫ Q.dTo n + P.dFrom n ≫ f'
  | 0 => ⟨0, (P.xNextIso rfl).hom ≫ zero, 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 : ι
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''
⊢ Hom.f e 0 = 0 ≫ dTo Q 0 + dFrom P 0 ≫ (xNextIso P (_ : 0 + 1 = 0 + 1)).hom ≫ zero

Next tactic:
simpa using comm_zero
/-- An auxiliary construction for `mkInductive`.
-/
def mkCoinductiveAux₂ :
    ∀ n, Σ' (f : P.X n ⟶ Q.xPrev n) (f' : P.xNext n ⟶ Q.X n), e.f n = f ≫ Q.dTo n + P.dFrom n ≫ f'
  | 0 => ⟨0, (P.xNextIso rfl).hom ≫ zero, by simpa using comm_zero⟩
  | n + 1 =>
    let I := mkCoinductiveAux₁ e zero one comm_one succ n
    ⟨I.1 ≫ (Q.xPrevIso rfl).inv, (P.xNextIso rfl).hom ≫ I.2.1, 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 : ι
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 : ℕ
I : (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' :=
  mkCoinductiveAux₁ e zero one comm_one succ n
⊢ Hom.f e (n + 1) =
    (I.fst ≫ (xPrevIso Q (_ : n + 1 = n + 1)).inv) ≫ dTo Q (n + 1) +
      dFrom P (n + 1) ≫ (xNextIso P (_ : n + 1 + 1 = n + 1 + 1)).hom ≫ I.snd.fst

Next tactic:
simpa using I.2.2
theorem mkCoinductiveAux₃ (i j : ℕ) (h : i + 1 = j) :
    (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.1 =
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).1 ≫ (Q.xPrevIso h).hom := 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✝ : ι
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 j : ℕ
h : i + 1 = j
⊢ (xNextIso P h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst =
    (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).fst ≫ (xPrevIso Q h).hom

Next tactic:
subst j
theorem mkCoinductiveAux₃ (i j : ℕ) (h : i + 1 = j) :
    (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.1 =
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).1 ≫ (Q.xPrevIso h).hom := by
  subst j
  

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✝ : ι
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 : ℕ
⊢ (xNextIso P (_ : i + 1 = i + 1)).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).snd.fst =
    (mkCoinductiveAux₂ e zero comm_zero one comm_one succ (i + 1)).fst ≫ (xPrevIso Q (_ : i + 1 = i + 1)).hom

Next tactic:
rcases i with (_ | _ | i)
theorem mkCoinductiveAux₃ (i j : ℕ) (h : i + 1 = j) :
    (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.1 =
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).1 ≫ (Q.xPrevIso h).hom := by
  subst j
  rcases i with (_ | _ | i) <;> 

Proof state:
case zero
ι : 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''
⊢ (xNextIso P (_ : Nat.zero + 1 = Nat.zero + 1)).inv ≫
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ Nat.zero).snd.fst =
    (mkCoinductiveAux₂ e zero comm_zero one comm_one succ (Nat.zero + 1)).fst ≫
      (xPrevIso Q (_ : Nat.zero + 1 = Nat.zero + 1)).hom

Next tactic:
simp [mkCoinductiveAux₂]
theorem mkCoinductiveAux₃ (i j : ℕ) (h : i + 1 = j) :
    (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.1 =
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).1 ≫ (Q.xPrevIso h).hom := by
  subst j
  rcases i with (_ | _ | i) <;> 

Proof state:
case succ.zero
ι : 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''
⊢ (xNextIso P (_ : Nat.succ Nat.zero + 1 = Nat.succ Nat.zero + 1)).inv ≫
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ (Nat.succ Nat.zero)).snd.fst =
    (mkCoinductiveAux₂ e zero comm_zero one comm_one succ (Nat.succ Nat.zero + 1)).fst ≫
      (xPrevIso Q (_ : Nat.succ Nat.zero + 1 = Nat.succ Nat.zero + 1)).hom

Next tactic:
simp [mkCoinductiveAux₂]
theorem mkCoinductiveAux₃ (i j : ℕ) (h : i + 1 = j) :
    (P.xNextIso h).inv ≫ (mkCoinductiveAux₂ e zero comm_zero one comm_one succ i).2.1 =
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ j).1 ≫ (Q.xPrevIso h).hom := by
  subst j
  rcases i with (_ | _ | i) <;> 

Proof state:
case succ.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''
i : ℕ
⊢ (xNextIso P (_ : Nat.succ (Nat.succ i) + 1 = Nat.succ (Nat.succ i) + 1)).inv ≫
      (mkCoinductiveAux₂ e zero comm_zero one comm_one succ (Nat.succ (Nat.succ i))).snd.fst =
    (mkCoinductiveAux₂ e zero comm_zero one comm_one succ (Nat.succ (Nat.succ i) + 1)).fst ≫
      (xPrevIso Q (_ : Nat.succ (Nat.succ i) + 1 = Nat.succ (Nat.succ i) + 1)).hom

Next tactic:
simp [mkCoinductiveAux₂]
/-- 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 

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✝ : ι
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 j : ℕ
w : ¬ComplexShape.Rel (ComplexShape.up ℕ) j 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)
      i j =
    0

Next tactic:
dsimp