-- Mathlib/CategoryTheory/Triangulated/Basic.lean
lemma productTriangle.zero₃₁ [HasZeroMorphisms C]
    (h : ∀ j, (T j).mor₃ ≫ (T j).mor₁⟦(1 : ℤ)⟧' = 0) :
    (productTriangle T).mor₃ ≫ (productTriangle T).mor₁⟦1⟧' = 0

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ (productTriangle T).mor₃ ≫ (shiftFunctor C 1).map (productTriangle T).mor₁ = 0

Tactic:
dsimp

Result:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫ inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁)) ≫
      (shiftFunctor C 1).map (Limits.Pi.map fun j => (T j).mor₁) =
    0

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫ inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁)) ≫
      (shiftFunctor C 1).map (Limits.Pi.map fun j => (T j).mor₁) =
    0

Tactic:
change _ ≫ (Pi.lift (fun j => Pi.π _ j ≫ (T j).mor₁))⟦(1 : ℤ)⟧' = 0

Result:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫ inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁)) ≫
      (shiftFunctor C 1).map (Pi.lift fun j => Pi.π (fun j => (T j).obj₁) j ≫ (T j).mor₁) =
    0

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫ inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁)) ≫
      (shiftFunctor C 1).map (Pi.lift fun j => Pi.π (fun j => (T j).obj₁) j ≫ (T j).mor₁) =
    0

Tactic:
rw [assoc, ← cancel_mono (piComparison _ _), zero_comp, assoc, assoc]

Result:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫
      inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁) ≫
        (shiftFunctor C 1).map (Pi.lift fun j => Pi.π (fun j => (T j).obj₁) j ≫ (T j).mor₁) ≫
          piComparison (shiftFunctor C 1) fun j => (T j).obj₂) =
    0

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
⊢ (productTriangle T).mor₃ ≫ (shiftFunctor C 1).map (productTriangle T).mor₁ = 0

Tactic:
have : HasProduct (fun j => (T j).obj₂⟦(1 : ℤ)⟧) :=
  ⟨_, isLimitFanMkObjOfIsLimit (shiftFunctor C (1 : ℤ)) _ _
    (productIsProduct (fun j => (T j).obj₂))⟩

Result:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ (productTriangle T).mor₃ ≫ (shiftFunctor C 1).map (productTriangle T).mor₁ = 0

Proof state:
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫
      inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁) ≫
        (shiftFunctor C 1).map (Pi.lift fun j => Pi.π (fun j => (T j).obj₁) j ≫ (T j).mor₁) ≫
          piComparison (shiftFunctor C 1) fun j => (T j).obj₂) =
    0

Tactic:
ext j

Result:
case h
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
j : J
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫
        inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁) ≫
          (shiftFunctor C 1).map (Pi.lift fun j => Pi.π (fun j => (T j).obj₁) j ≫ (T j).mor₁) ≫
            piComparison (shiftFunctor C 1) fun j => (T j).obj₂) ≫
      Pi.π (fun b => (shiftFunctor C 1).obj (T b).obj₂) j =
    0 ≫ Pi.π (fun b => (shiftFunctor C 1).obj (T b).obj₂) j

Proof state:
case h
C : Type u
inst✝⁶ : Category.{v, u} C
inst✝⁵ : HasShift C ℤ
J : Type u_1
T : J → Triangle C
inst✝⁴ : HasProduct fun j => (T j).obj₁
inst✝³ : HasProduct fun j => (T j).obj₂
inst✝² : HasProduct fun j => (T j).obj₃
inst✝¹ : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₁
inst✝ : HasZeroMorphisms C
h : ∀ (j : J), (T j).mor₃ ≫ (shiftFunctor C 1).map (T j).mor₁ = 0
this : HasProduct fun j => (shiftFunctor C 1).obj (T j).obj₂
j : J
⊢ ((Limits.Pi.map fun j => (T j).mor₃) ≫
        inv (piComparison (shiftFunctor C 1) fun j => (T j).obj₁) ≫
          (shiftFunctor C 1).map (Pi.lift fun j => Pi.π (fun j => (T j).obj₁) j ≫ (T j).mor₁) ≫
            piComparison (shiftFunctor C 1) fun j => (T j).obj₂) ≫
      Pi.π (fun b => (shiftFunctor C 1).obj (T b).obj₂) j =
    0 ≫ Pi.π (fun b => (shiftFunctor C 1).obj (T b).obj₂) j

Tactic:
simp only [map_lift_piComparison, assoc, limit.lift_π, Fan.mk_π_app, zero_comp,
  Functor.map_comp, ← piComparison_comp_π_assoc, IsIso.inv_hom_id_assoc,
  limMap_π_assoc, Discrete.natTrans_app, h j, comp_zero]

Result:
no goals