-- Mathlib/CategoryTheory/Triangulated/Pretriangulated.lean
/-- A product of distinguished triangles is distinguished -/
lemma productTriangle_distinguished {J : Type*} (T : J → Triangle C)
    (hT : ∀ j, T j ∈ distTriang C)
    [HasProduct (fun j => (T j).obj₁)] [HasProduct (fun j => (T j).obj₂)]
    [HasProduct (fun j => (T j).obj₃)] [HasProduct (fun j => (T j).obj₁⟦(1 : ℤ)⟧)] :
    productTriangle T ∈ distTriang C

Proof state:
C : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : HasZeroObject C
inst✝⁶ : HasShift C ℤ
inst✝⁵ : Preadditive C
inst✝⁴ : ∀ (n : ℤ), (shiftFunctor C n).Additive
hC : Pretriangulated C
J : Type u_1
T : J → Triangle C
hT : ∀ (j : J), T j ∈ distinguishedTriangles
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₁
f₁ : (∏ᶜ fun j => (T j).obj₁) ⟶ ∏ᶜ fun j => (T j).obj₂ := Limits.Pi.map fun j => (T j).mor₁
Z : C
f₂ : (∏ᶜ fun j => (T j).obj₂) ⟶ Z
f₃ : Z ⟶ (shiftFunctor C 1).obj (∏ᶜ fun j => (T j).obj₁)
T' : Triangle C := Triangle.mk f₁ f₂ f₃
hT' : T' ∈ distinguishedTriangles
φ : (j : J) → T' ⟶ T j :=
  fun j =>
    completeDistinguishedTriangleMorphism T' (T j) hT' ⋯ (Pi.π (fun j => (T j).obj₁) j) (Pi.π (fun j => (T j).obj₂) j) ⋯
φ' : T' ⟶ productTriangle T := productTriangle.lift T φ
h₁ : φ'.hom₁ = 𝟙 T'.obj₁
h₂ : φ'.hom₂ = 𝟙 T'.obj₂
this✝ : IsIso φ'.hom₁
this : IsIso φ'.hom₂
A : C
a : A ⟶ (productTriangle T).obj₃
a' : A ⟶ Z
ha' : a' ≫ T'.mor₃ = a ≫ (productTriangle T).mor₃
j : J
⊢ a ≫ (productTriangle T).mor₃ ≫ (shiftFunctor C 1).map (productTriangle.π T j).hom₁ -
      a' ≫ φ'.hom₃ ≫ (productTriangle T).mor₃ ≫ (shiftFunctor C 1).map (productTriangle.π T j).hom₁ =
    0

Tactic:
rw [← φ'.comm₃_assoc]

Result:
C : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : HasZeroObject C
inst✝⁶ : HasShift C ℤ
inst✝⁵ : Preadditive C
inst✝⁴ : ∀ (n : ℤ), (shiftFunctor C n).Additive
hC : Pretriangulated C
J : Type u_1
T : J → Triangle C
hT : ∀ (j : J), T j ∈ distinguishedTriangles
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₁
f₁ : (∏ᶜ fun j => (T j).obj₁) ⟶ ∏ᶜ fun j => (T j).obj₂ := Limits.Pi.map fun j => (T j).mor₁
Z : C
f₂ : (∏ᶜ fun j => (T j).obj₂) ⟶ Z
f₃ : Z ⟶ (shiftFunctor C 1).obj (∏ᶜ fun j => (T j).obj₁)
T' : Triangle C := Triangle.mk f₁ f₂ f₃
hT' : T' ∈ distinguishedTriangles
φ : (j : J) → T' ⟶ T j :=
  fun j =>
    completeDistinguishedTriangleMorphism T' (T j) hT' ⋯ (Pi.π (fun j => (T j).obj₁) j) (Pi.π (fun j => (T j).obj₂) j) ⋯
φ' : T' ⟶ productTriangle T := productTriangle.lift T φ
h₁ : φ'.hom₁ = 𝟙 T'.obj₁
h₂ : φ'.hom₂ = 𝟙 T'.obj₂
this✝ : IsIso φ'.hom₁
this : IsIso φ'.hom₂
A : C
a : A ⟶ (productTriangle T).obj₃
a' : A ⟶ Z
ha' : a' ≫ T'.mor₃ = a ≫ (productTriangle T).mor₃
j : J
⊢ a ≫ (productTriangle T).mor₃ ≫ (shiftFunctor C 1).map (productTriangle.π T j).hom₁ -
      a' ≫ T'.mor₃ ≫ (shiftFunctor C 1).map φ'.hom₁ ≫ (shiftFunctor C 1).map (productTriangle.π T j).hom₁ =
    0

Proof state:
case intro.intro.intro
C : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : HasZeroObject C
inst✝⁶ : HasShift C ℤ
inst✝⁵ : Preadditive C
inst✝⁴ : ∀ (n : ℤ), (shiftFunctor C n).Additive
hC : Pretriangulated C
J : Type u_1
T : J → Triangle C
hT : ∀ (j : J), T j ∈ distinguishedTriangles
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₁
f₁ : (∏ᶜ fun j => (T j).obj₁) ⟶ ∏ᶜ fun j => (T j).obj₂ := Limits.Pi.map fun j => (T j).mor₁
Z : C
f₂ : (∏ᶜ fun j => (T j).obj₂) ⟶ Z
f₃ : Z ⟶ (shiftFunctor C 1).obj (∏ᶜ fun j => (T j).obj₁)
T' : Triangle C := Triangle.mk f₁ f₂ f₃
hT' : T' ∈ distinguishedTriangles
φ : (j : J) → T' ⟶ T j :=
  fun j =>
    completeDistinguishedTriangleMorphism T' (T j) hT' ⋯ (Pi.π (fun j => (T j).obj₁) j) (Pi.π (fun j => (T j).obj₂) j) ⋯
φ' : T' ⟶ productTriangle T := productTriangle.lift T φ
h₁ : φ'.hom₁ = 𝟙 T'.obj₁
h₂ : φ'.hom₂ = 𝟙 T'.obj₂
this✝ : IsIso φ'.hom₁
this : IsIso φ'.hom₂
⊢ IsIso φ'.hom₃

Tactic:
refine isIso_of_yoneda_map_bijective _ (fun A => ⟨?_, ?_⟩)

Result:
case intro.intro.intro.refine_1
C : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : HasZeroObject C
inst✝⁶ : HasShift C ℤ
inst✝⁵ : Preadditive C
inst✝⁴ : ∀ (n : ℤ), (shiftFunctor C n).Additive
hC : Pretriangulated C
J : Type u_1
T : J → Triangle C
hT : ∀ (j : J), T j ∈ distinguishedTriangles
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₁
f₁ : (∏ᶜ fun j => (T j).obj₁) ⟶ ∏ᶜ fun j => (T j).obj₂ := Limits.Pi.map fun j => (T j).mor₁
Z : C
f₂ : (∏ᶜ fun j => (T j).obj₂) ⟶ Z
f₃ : Z ⟶ (shiftFunctor C 1).obj (∏ᶜ fun j => (T j).obj₁)
T' : Triangle C := Triangle.mk f₁ f₂ f₃
hT' : T' ∈ distinguishedTriangles
φ : (j : J) → T' ⟶ T j :=
  fun j =>
    completeDistinguishedTriangleMorphism T' (T j) hT' ⋯ (Pi.π (fun j => (T j).obj₁) j) (Pi.π (fun j => (T j).obj₂) j) ⋯
φ' : T' ⟶ productTriangle T := productTriangle.lift T φ
h₁ : φ'.hom₁ = 𝟙 T'.obj₁
h₂ : φ'.hom₂ = 𝟙 T'.obj₂
this✝ : IsIso φ'.hom₁
this : IsIso φ'.hom₂
A : C
⊢ Function.Injective fun x => x ≫ φ'.hom₃

case intro.intro.intro.refine_2
C : Type u
inst✝⁸ : Category.{v, u} C
inst✝⁷ : HasZeroObject C
inst✝⁶ : HasShift C ℤ
inst✝⁵ : Preadditive C
inst✝⁴ : ∀ (n : ℤ), (shiftFunctor C n).Additive
hC : Pretriangulated C
J : Type u_1
T : J → Triangle C
hT : ∀ (j : J), T j ∈ distinguishedTriangles
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₁
f₁ : (∏ᶜ fun j => (T j).obj₁) ⟶ ∏ᶜ fun j => (T j).obj₂ := Limits.Pi.map fun j => (T j).mor₁
Z : C
f₂ : (∏ᶜ fun j => (T j).obj₂) ⟶ Z
f₃ : Z ⟶ (shiftFunctor C 1).obj (∏ᶜ fun j => (T j).obj₁)
T' : Triangle C := Triangle.mk f₁ f₂ f₃
hT' : T' ∈ distinguishedTriangles
φ : (j : J) → T' ⟶ T j :=
  fun j =>
    completeDistinguishedTriangleMorphism T' (T j) hT' ⋯ (Pi.π (fun j => (T j).obj₁) j) (Pi.π (fun j => (T j).obj₂) j) ⋯
φ' : T' ⟶ productTriangle T := productTriangle.lift T φ
h₁ : φ'.hom₁ = 𝟙 T'.obj₁
h₂ : φ'.hom₂ = 𝟙 T'.obj₂
this✝ : IsIso φ'.hom₁
this : IsIso φ'.hom₂
A : C
⊢ Function.Surjective fun x => x ≫ φ'.hom₃