l3lab/ntp-mathlib huggingface dataset:
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; 

Proof state:
case refine'_4.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
x✝ : ↑I
y✝ : { j // j ≠ i } → ↑I
⊢ (ContinuousMap.toFun
        (ContinuousMap.mk fun t =>
          { val := (homotopyTo i H) t,
            property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) })
        (1, x✝))
      y✝ =
    ((toLoop i q).toContinuousMap x✝) y✝
case refine'_3.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
x✝ : ↑I
y✝ : { j // j ≠ i } → ↑I
⊢ H ((0, x✝).1, (Cube.insertAt i) ((0, x✝).2, y✝)) = p ((Cube.insertAt i) (x✝, y✝))
case refine'_5
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
⊢ ∀ (t x_1 : ↑I),
    x_1 ∈ {0, 1} →
      (ContinuousMap.mk fun x_2 =>
            ContinuousMap.toFun
              {
                  toContinuousMap :=
                    ContinuousMap.mk fun t =>
                      { val := (homotopyTo i H) t,
                        property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) },
                  map_zero_left :=
                    (_ :
                      ∀ (x_3 : ↑I),
                        ContinuousMap.toFun
                            (ContinuousMap.mk fun t =>
                              { val := (homotopyTo i H) t,
                                property := (_ : (homotopyTo i H) t ∈ Ω^ { j // j ≠ i } X x) })
                            (0, x_3) =
                          (toLoop i p).toContinuousMap x_3),
                  map_one_left :=
                    (_ :
                      ∀ (x_3 : ↑I),
                        ContinuousMap.toFun
                            (ContinuousMap.mk fun t =>
                              { val := (homotopyTo i H) t,
                                property := (_ : (homotopyTo i H) t ∈ Ω^ { j // j ≠ i } X x) })
                            (1, x_3) =
                          (toLoop i q).toContinuousMap x_3) }.toContinuousMap
              (t, x_2))
          x_1 =
        (toLoop i p).toContinuousMap x_1

Next tactic:
erw [homotopyTo_apply, toLoop_apply]
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; 

Proof state:
case refine'_4.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
x✝ : ↑I
y✝ : { j // j ≠ i } → ↑I
⊢ H ((1, x✝).1, (Cube.insertAt i) ((1, x✝).2, y✝)) = q ((Cube.insertAt i) (x✝, y✝))
case refine'_3.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
x✝ : ↑I
y✝ : { j // j ≠ i } → ↑I
⊢ H ((0, x✝).1, (Cube.insertAt i) ((0, x✝).2, y✝)) = p ((Cube.insertAt i) (x✝, y✝))
case refine'_5
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
⊢ ∀ (t x_1 : ↑I),
    x_1 ∈ {0, 1} →
      (ContinuousMap.mk fun x_2 =>
            ContinuousMap.toFun
              {
                  toContinuousMap :=
                    ContinuousMap.mk fun t =>
                      { val := (homotopyTo i H) t,
                        property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) },
                  map_zero_left :=
                    (_ :
                      ∀ (x_3 : ↑I),
                        ContinuousMap.toFun
                            (ContinuousMap.mk fun t =>
                              { val := (homotopyTo i H) t,
                                property := (_ : (homotopyTo i H) t ∈ Ω^ { j // j ≠ i } X x) })
                            (0, x_3) =
                          (toLoop i p).toContinuousMap x_3),
                  map_one_left :=
                    (_ :
                      ∀ (x_3 : ↑I),
                        ContinuousMap.toFun
                            (ContinuousMap.mk fun t =>
                              { val := (homotopyTo i H) t,
                                property := (_ : (homotopyTo i H) t ∈ Ω^ { j // j ≠ i } X x) })
                            (1, x_3) =
                          (toLoop i q).toContinuousMap x_3) }.toContinuousMap
              (t, x_2))
          x_1 =
        (toLoop i p).toContinuousMap x_1

Next tactic:
swap
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · 

Proof state:
case refine'_3.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
x✝ : ↑I
y✝ : { j // j ≠ i } → ↑I
⊢ H ((0, x✝).1, (Cube.insertAt i) ((0, x✝).2, y✝)) = p ((Cube.insertAt i) (x✝, y✝))

Next tactic:
apply H.apply_zero
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · 

Proof state:
case refine'_4.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
x✝ : ↑I
y✝ : { j // j ≠ i } → ↑I
⊢ H ((1, x✝).1, (Cube.insertAt i) ((1, x✝).2, y✝)) = q ((Cube.insertAt i) (x✝, y✝))

Next tactic:
apply H.apply_one
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · apply H.apply_one
  

Proof state:
case refine'_5
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
⊢ ∀ (t x_1 : ↑I),
    x_1 ∈ {0, 1} →
      (ContinuousMap.mk fun x_2 =>
            ContinuousMap.toFun
              {
                  toContinuousMap :=
                    ContinuousMap.mk fun t =>
                      { val := (homotopyTo i H) t,
                        property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) },
                  map_zero_left :=
                    (_ :
                      ∀ (x_3 : ↑I),
                        ContinuousMap.toFun
                            (ContinuousMap.mk fun t =>
                              { val := (homotopyTo i H) t,
                                property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) })
                            (0, x_3) =
                          (toLoop i p).toContinuousMap x_3),
                  map_one_left :=
                    (_ :
                      ∀ (x_3 : ↑I),
                        ContinuousMap.toFun
                            (ContinuousMap.mk fun t =>
                              { val := (homotopyTo i H) t,
                                property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) })
                            (1, x_3) =
                          (toLoop i q).toContinuousMap x_3) }.toContinuousMap
              (t, x_2))
          x_1 =
        (toLoop i p).toContinuousMap x_1

Next tactic:
intro t y yH
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · apply H.apply_one
  intro t y yH
  

Proof state:
case refine'_5
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
t y : ↑I
yH : y ∈ {0, 1}
⊢ (ContinuousMap.mk fun x_1 =>
        ContinuousMap.toFun
          {
              toContinuousMap :=
                ContinuousMap.mk fun t =>
                  { val := (homotopyTo i H) t,
                    property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) },
              map_zero_left :=
                (_ :
                  ∀ (x_2 : ↑I),
                    ContinuousMap.toFun
                        (ContinuousMap.mk fun t =>
                          { val := (homotopyTo i H) t,
                            property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) })
                        (0, x_2) =
                      (toLoop i p).toContinuousMap x_2),
              map_one_left :=
                (_ :
                  ∀ (x_2 : ↑I),
                    ContinuousMap.toFun
                        (ContinuousMap.mk fun t =>
                          { val := (homotopyTo i H) t,
                            property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) })
                        (1, x_2) =
                      (toLoop i q).toContinuousMap x_2) }.toContinuousMap
          (t, x_1))
      y =
    (toLoop i p).toContinuousMap y

Next tactic:
ext
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · apply H.apply_one
  intro t y yH
  ext; 

Proof state:
case refine'_5.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
t y : ↑I
yH : y ∈ {0, 1}
y✝ : { j // j ≠ i } → ↑I
⊢ ((ContinuousMap.mk fun x_1 =>
          ContinuousMap.toFun
            {
                toContinuousMap :=
                  ContinuousMap.mk fun t =>
                    { val := (homotopyTo i H) t,
                      property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) },
                map_zero_left :=
                  (_ :
                    ∀ (x_2 : ↑I),
                      ContinuousMap.toFun
                          (ContinuousMap.mk fun t =>
                            { val := (homotopyTo i H) t,
                              property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) })
                          (0, x_2) =
                        (toLoop i p).toContinuousMap x_2),
                map_one_left :=
                  (_ :
                    ∀ (x_2 : ↑I),
                      ContinuousMap.toFun
                          (ContinuousMap.mk fun t =>
                            { val := (homotopyTo i H) t,
                              property := (_ : ∀ y ∈ Cube.boundary { j // j ≠ i }, ((homotopyTo i H) t) y = x) })
                          (1, x_2) =
                        (toLoop i q).toContinuousMap x_2) }.toContinuousMap
            (t, x_1))
        y)
      y✝ =
    ((toLoop i p).toContinuousMap y) y✝

Next tactic:
erw [homotopyTo_apply]
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · apply H.apply_one
  intro t y yH
  ext; erw [homotopyTo_apply]
  

Proof state:
case refine'_5.H
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
t y : ↑I
yH : y ∈ {0, 1}
y✝ : { j // j ≠ i } → ↑I
⊢ H ((t, y).1, (Cube.insertAt i) ((t, y).2, y✝)) = ((toLoop i p).toContinuousMap y) y✝

Next tactic:
apply H.eq_fst
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · apply H.apply_one
  intro t y yH
  ext; erw [homotopyTo_apply]
  apply H.eq_fst; 

Proof state:
case refine'_5.H.hx
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
t y : ↑I
yH : y ∈ {0, 1}
y✝ : { j // j ≠ i } → ↑I
⊢ (Cube.insertAt i) ((t, y).2, y✝) ∈ Cube.boundary N

Next tactic:
use i
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · apply H.apply_one
  intro t y yH
  ext; erw [homotopyTo_apply]
  apply H.eq_fst; use i
  

Proof state:
case h
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
t y : ↑I
yH : y ∈ {0, 1}
y✝ : { j // j ≠ i } → ↑I
⊢ (Cube.insertAt i) ((t, y).2, y✝) i = 0 ∨ (Cube.insertAt i) ((t, y).2, y✝) i = 1

Next tactic:
rw [funSplitAt_symm_apply, dif_pos rfl]
theorem homotopicTo (i : N) {p q : Ω^ N X x} :
    Homotopic p q → (toLoop i p).Homotopic (toLoop i q) := by
  refine' Nonempty.map fun H => ⟨⟨⟨fun t => ⟨homotopyTo i H t, _⟩, _⟩, _, _⟩, _⟩
  · rintro y ⟨i, iH⟩
    rw [homotopyTo_apply, H.eq_fst, p.2]
    all_goals apply Cube.insertAt_boundary; right; exact ⟨i, iH⟩
  · continuity
  iterate 2 intro; ext; erw [homotopyTo_apply, toLoop_apply]; swap
  · apply H.apply_zero
  · apply H.apply_one
  intro t y yH
  ext; erw [homotopyTo_apply]
  apply H.eq_fst; use i
  rw [funSplitAt_symm_apply, dif_pos rfl]; 

Proof state:
case h
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : ContinuousMap.HomotopyRel (↑p) (↑q) (Cube.boundary N)
t y : ↑I
yH : y ∈ {0, 1}
y✝ : { j // j ≠ i } → ↑I
⊢ ((t, y).2, y✝).1 = 0 ∨ ((t, y).2, y✝).1 = 1

Next tactic:
exact yH
/-- The converse to `GenLoop.homotopyTo`: a homotopy between two loops in the space of
  `n`-dimensional loops can be seen as a homotopy between two `n+1`-dimensional paths. -/
@[simps!] def homotopyFrom (i : N) {p q : Ω^ N X x} (H : (toLoop i p).Homotopy (toLoop i q)) :
    C(I × I^N, X) :=
  (ContinuousMap.comp ⟨_, ContinuousMap.continuous_uncurry⟩
          (ContinuousMap.comp ⟨Subtype.val, by 

Proof state:
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
⊢ Continuous Subtype.val

Next tactic:
continuity
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  

Proof state:
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
⊢ Path.Homotopic (toLoop i p) (toLoop i q) → Homotopic p q

Next tactic:
refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  

Proof state:
case refine'_1
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
⊢ ∀ (x_1 : N → ↑I), ContinuousMap.toFun (homotopyFrom i H) (0, x_1) = ↑p x_1
case refine'_2
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
⊢ ∀ (x_1 : N → ↑I), ContinuousMap.toFun (homotopyFrom i H) (1, x_1) = ↑q x_1
case refine'_3
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
⊢ ∀ (t : ↑I),
    ∀ x_1 ∈ Cube.boundary N,
      (ContinuousMap.mk fun x_2 =>
            ContinuousMap.toFun
              { toContinuousMap := homotopyFrom i H, map_zero_left := ?refine'_1,
                  map_one_left := ?refine'_2 }.toContinuousMap
              (t, x_2))
          x_1 =
        ↑p x_1

Next tactic:
pick_goal 3
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  pick_goal 3
  · 

Proof state:
case refine'_3
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
⊢ ∀ (t : ↑I),
    ∀ x_1 ∈ Cube.boundary N,
      (ContinuousMap.mk fun x_2 =>
            ContinuousMap.toFun
              { toContinuousMap := homotopyFrom i H, map_zero_left := ?refine'_1,
                  map_one_left := ?refine'_2 }.toContinuousMap
              (t, x_2))
          x_1 =
        ↑p x_1

Next tactic:
rintro t y ⟨j, jH⟩
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  pick_goal 3
  · rintro t y ⟨j, jH⟩
    

Proof state:
case refine'_3.intro
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
t : ↑I
y : N → ↑I
j : N
jH : y j = 0 ∨ y j = 1
⊢ (ContinuousMap.mk fun x_1 =>
        ContinuousMap.toFun
          { toContinuousMap := homotopyFrom i H, map_zero_left := ?refine'_1,
              map_one_left := ?refine'_2 }.toContinuousMap
          (t, x_1))
      y =
    ↑p y

Next tactic:
erw [homotopyFrom_apply]
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  pick_goal 3
  · rintro t y ⟨j, jH⟩
    erw [homotopyFrom_apply]
    

Proof state:
case refine'_3.intro
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
t : ↑I
y : N → ↑I
j : N
jH : y j = 0 ∨ y j = 1
⊢ (↑(H ((t, y).1, (t, y).2 i)) fun j => (t, y).2 ↑j) = ↑p y
case refine'_1
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
⊢ ∀ (x_1 : N → ↑I), ContinuousMap.toFun (homotopyFrom i H) (0, x_1) = ↑p x_1
case refine'_2
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
⊢ ∀ (x_1 : N → ↑I), ContinuousMap.toFun (homotopyFrom i H) (1, x_1) = ↑q x_1

Next tactic:
obtain rfl | h := eq_or_ne j i
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  pick_goal 3
  · rintro t y ⟨j, jH⟩
    erw [homotopyFrom_apply]
    obtain rfl | h := eq_or_ne j i
    · 

Proof state:
case refine'_3.intro.inl
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
p q : ↑(Ω^ N X x)
t : ↑I
y : N → ↑I
j : N
jH : y j = 0 ∨ y j = 1
H : Path.Homotopy (toLoop j p) (toLoop j q)
⊢ (↑(H ((t, y).1, (t, y).2 j)) fun j_1 => (t, y).2 ↑j_1) = ↑p y

Next tactic:
rw [H.eq_fst]
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  pick_goal 3
  · rintro t y ⟨j, jH⟩
    erw [homotopyFrom_apply]
    obtain rfl | h := eq_or_ne j i
    · rw [H.eq_fst]; 

Proof state:
case refine'_3.intro.inl
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
p q : ↑(Ω^ N X x)
t : ↑I
y : N → ↑I
j : N
jH : y j = 0 ∨ y j = 1
H : Path.Homotopy (toLoop j p) (toLoop j q)
⊢ (↑((toLoop j p).toContinuousMap ((t, y).2 j)) fun j_1 => (t, y).2 ↑j_1) = ↑p y
case refine'_3.intro.inl.hx
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
p q : ↑(Ω^ N X x)
t : ↑I
y : N → ↑I
j : N
jH : y j = 0 ∨ y j = 1
H : Path.Homotopy (toLoop j p) (toLoop j q)
⊢ (t, y).2 j ∈ {0, 1}

Next tactic:
exacts [congr_arg p ((Cube.splitAt j).left_inv _), jH]
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  pick_goal 3
  · rintro t y ⟨j, jH⟩
    erw [homotopyFrom_apply]
    obtain rfl | h := eq_or_ne j i
    · rw [H.eq_fst]; exacts [congr_arg p ((Cube.splitAt j).left_inv _), jH]
    · 

Proof state:
case refine'_3.intro.inr
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
t : ↑I
y : N → ↑I
j : N
jH : y j = 0 ∨ y j = 1
h : j ≠ i
⊢ (↑(H ((t, y).1, (t, y).2 i)) fun j => (t, y).2 ↑j) = ↑p y

Next tactic:
rw [p.2 _ ⟨j, jH⟩]
theorem homotopicFrom (i : N) {p q : Ω^ N X x} :
    (toLoop i p).Homotopic (toLoop i q) → Homotopic p q := by
  refine' Nonempty.map fun H => ⟨⟨homotopyFrom i H, _, _⟩, _⟩
  pick_goal 3
  · rintro t y ⟨j, jH⟩
    erw [homotopyFrom_apply]
    obtain rfl | h := eq_or_ne j i
    · rw [H.eq_fst]; exacts [congr_arg p ((Cube.splitAt j).left_inv _), jH]
    · rw [p.2 _ ⟨j, jH⟩]; 

Proof state:
case refine'_3.intro.inr
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
p q : ↑(Ω^ N X x)
H : Path.Homotopy (toLoop i p) (toLoop i q)
t : ↑I
y : N → ↑I
j : N
jH : y j = 0 ∨ y j = 1
h : j ≠ i
⊢ (↑(H ((t, y).1, (t, y).2 i)) fun j => (t, y).2 ↑j) = x

Next tactic:
apply boundary