Theorem: ContinuousMap.Homotopy.eq_diag_path
File: Mathlib/AlgebraicTopology/FundamentalGroupoid/InducedMaps.lean

Proof steps:
state_before: X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (π.map f).map p ≫ ⟦H.evalAt x₁⟧ = H.diagonalPath' p ∧ ⟦H.evalAt x₀⟧ ≫ (π.map g).map p = H.diagonalPath' p
state_after: X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 0 })) p) ≫ hcast ⋯) ≫ ⟦H.evalAt x₁⟧ =
      H.diagonalPath' p ∧
    (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI uhpath01 (𝟙 (fromTop x₀))) ≫ hcast ⋯) ≫
        hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 1 })) p) ≫ hcast ⋯ =
      H.diagonalPath' p
tactic: rw [H.apply_zero_path, H.apply_one_path, H.evalAt_eq]
state_before: X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 0 })) p) ≫ hcast ⋯) ≫ ⟦H.evalAt x₁⟧ =
      H.diagonalPath' p ∧
    (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI uhpath01 (𝟙 (fromTop x₀))) ≫ hcast ⋯) ≫
        hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 1 })) p) ≫ hcast ⋯ =
      H.diagonalPath' p
state_after: X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 0 })) p) ≫ hcast ⋯) ≫
        hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI uhpath01 (𝟙 (fromTop (fromTop x₁).as))) ≫ hcast ⋯ =
      H.diagonalPath' p ∧
    (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI uhpath01 (𝟙 (fromTop x₀))) ≫ hcast ⋯) ≫
        hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 1 })) p) ≫ hcast ⋯ =
      H.diagonalPath' p
tactic: erw [H.evalAt_eq]
state_before: X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 0 })) p) ≫ hcast ⋯) ≫
        hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI uhpath01 (𝟙 (fromTop (fromTop x₁).as))) ≫ hcast ⋯ =
      H.diagonalPath' p ∧
    (hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI uhpath01 (𝟙 (fromTop x₀))) ≫ hcast ⋯) ≫
        hcast ⋯ ≫ (π.map H.uliftMap).map (prodToProdTopI (𝟙 (fromTop { down := 1 })) p) ≫ hcast ⋯ =
      H.diagonalPath' p
state_after: X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (𝟙 (fromTop { down := 0 }), p)) ≫
            hcast ⋯) ≫
        hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (uhpath01, 𝟙 (fromTop x₁))) ≫
            hcast ⋯ =
      H.diagonalPath' p ∧
    (hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (uhpath01, 𝟙 (fromTop x₀))) ≫
            hcast ⋯) ≫
        hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (𝟙 (fromTop { down := 1 }), p)) ≫
            hcast ⋯ =
      H.diagonalPath' p
tactic: dsimp only [prodToProdTopI]
state_before: X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (𝟙 (fromTop { down := 0 }), p)) ≫
            hcast ⋯) ≫
        hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (uhpath01, 𝟙 (fromTop x₁))) ≫
            hcast ⋯ =
      H.diagonalPath' p ∧
    (hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (uhpath01, 𝟙 (fromTop x₀))) ≫
            hcast ⋯) ≫
        hcast ⋯ ≫
          (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (𝟙 (fromTop { down := 1 }), p)) ≫
            hcast ⋯ =
      H.diagonalPath' p
state_after: case left
X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫
        (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (𝟙 (fromTop { down := 0 }), p)) ≫
          hcast ⋯) ≫
      hcast ⋯ ≫
        (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (uhpath01, 𝟙 (fromTop x₁))) ≫
          hcast ⋯ =
    H.diagonalPath' p

case right
X Y : TopCat
f g : C(↑X, ↑Y)
H : f.Homotopy g
x₀ x₁ : ↑X
p : fromTop x₀ ⟶ fromTop x₁
⊢ (hcast ⋯ ≫
        (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (uhpath01, 𝟙 (fromTop x₀))) ≫
          hcast ⋯) ≫
      hcast ⋯ ≫
        (π.map H.uliftMap).map ((prodToProdTop (TopCat.of (ULift.{u, 0} ↑I)) X).map (𝟙 (fromTop { down := 1 }), p)) ≫
          hcast ⋯ =
    H.diagonalPath' p
tactic: constructor