l3lab/ntp-mathlib huggingface dataset:
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⟩]; apply boundary; 

Proof state:
case refine'_3.intro.inr.a
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
⊢ (fun j => (t, y).2 ↑j) ∈ Cube.boundary { j // ¬j = i }

Next tactic:
exact ⟨⟨j, h⟩, 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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    

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

Next tactic:
all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      first
      | apply congr_arg p
      | apply congr_arg q
      apply (Cube.splitAt i).left_inv
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      

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

Next tactic:
intro
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      

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✝ : N → ↑I
⊢ ContinuousMap.toFun (homotopyFrom i H) (0, x✝) = ↑p x✝

Next tactic:
apply (homotopyFrom_apply _ _ _).trans
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      

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✝ : N → ↑I
⊢ (↑(H ((0, x✝).1, (0, x✝).2 i)) fun j => (0, x✝).2 ↑j) = ↑p x✝

Next tactic:
first
      | rw [H.apply_zero]
      | rw [H.apply_one]
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | 

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✝ : N → ↑I
⊢ (↑(H ((0, x✝).1, (0, x✝).2 i)) fun j => (0, x✝).2 ↑j) = ↑p x✝

Next tactic:
rw [H.apply_zero]
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      

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✝ : N → ↑I
⊢ (↑((toLoop i p).toContinuousMap ((0, x✝).2 i)) fun j => (0, x✝).2 ↑j) = ↑p x✝

Next tactic:
first
      | apply congr_arg p
      | apply congr_arg q
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      first
      | 

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✝ : N → ↑I
⊢ (↑((toLoop i p).toContinuousMap ((0, x✝).2 i)) fun j => (0, x✝).2 ↑j) = ↑p x✝

Next tactic:
apply congr_arg p
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      first
      | apply congr_arg p
      | apply congr_arg q
      

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✝ : N → ↑I
⊢ (Homeomorph.toContinuousMap (Cube.insertAt i)) ((0, x✝).2 i, fun j => (0, x✝).2 ↑j) = x✝

Next tactic:
apply (Cube.splitAt i).left_inv
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      

Proof state:
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:
intro
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      

Proof state:
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✝ : N → ↑I
⊢ ContinuousMap.toFun (homotopyFrom i H) (1, x✝) = ↑q x✝

Next tactic:
apply (homotopyFrom_apply _ _ _).trans
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      

Proof state:
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✝ : N → ↑I
⊢ (↑(H ((1, x✝).1, (1, x✝).2 i)) fun j => (1, x✝).2 ↑j) = ↑q x✝

Next tactic:
first
      | rw [H.apply_zero]
      | rw [H.apply_one]
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | 

Proof state:
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✝ : N → ↑I
⊢ (↑(H ((1, x✝).1, (1, x✝).2 i)) fun j => (1, x✝).2 ↑j) = ↑q x✝

Next tactic:
rw [H.apply_zero]
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | 

Proof state:
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✝ : N → ↑I
⊢ (↑(H ((1, x✝).1, (1, x✝).2 i)) fun j => (1, x✝).2 ↑j) = ↑q x✝

Next tactic:
rw [H.apply_one]
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      

Proof state:
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✝ : N → ↑I
⊢ (↑((toLoop i q).toContinuousMap ((1, x✝).2 i)) fun j => (1, x✝).2 ↑j) = ↑q x✝

Next tactic:
first
      | apply congr_arg p
      | apply congr_arg q
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      first
      | 

Proof state:
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✝ : N → ↑I
⊢ (↑((toLoop i q).toContinuousMap ((1, x✝).2 i)) fun j => (1, x✝).2 ↑j) = ↑q x✝

Next tactic:
apply congr_arg p
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      first
      | apply congr_arg p
      | 

Proof state:
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✝ : N → ↑I
⊢ (↑((toLoop i q).toContinuousMap ((1, x✝).2 i)) fun j => (1, x✝).2 ↑j) = ↑q x✝

Next tactic:
apply congr_arg q
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⟩]; apply boundary; exact ⟨⟨j, h⟩, jH⟩
    /- porting note: the following is indented two spaces more than it should be due to
      strange behavior of `erw` -/
    all_goals
      intro
      apply (homotopyFrom_apply _ _ _).trans
      first
      | rw [H.apply_zero]
      | rw [H.apply_one]
      first
      | apply congr_arg p
      | apply congr_arg q
      

Proof state:
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✝ : N → ↑I
⊢ (Homeomorph.toContinuousMap (Cube.insertAt i)) ((1, x✝).2 i, fun j => (1, x✝).2 ↑j) = x✝

Next tactic:
apply (Cube.splitAt i).left_inv
/-- Concatenation of two `GenLoop`s along the `i`th coordinate. -/
def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x :=
  copy (fromLoop i <| (toLoop i f).trans <| toLoop i g)
    (fun t => if (t i : ℝ) ≤ 1 / 2
      then f (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i))
      else g (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i - 1)))
    (by
      

Proof state:
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
⊢ (fun t =>
      if ↑(t i) ≤ 1 / 2 then f (Function.update t i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(t i))))
      else g (Function.update t i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(t i) - 1)))) =
    ⇑(fromLoop i (Path.trans (toLoop i f) (toLoop i g)))

Next tactic:
ext1
/-- Concatenation of two `GenLoop`s along the `i`th coordinate. -/
def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x :=
  copy (fromLoop i <| (toLoop i f).trans <| toLoop i g)
    (fun t => if (t i : ℝ) ≤ 1 / 2
      then f (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i))
      else g (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i - 1)))
    (by
      ext1; 

Proof state:
case h
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
x✝ : N → ↑I
⊢ (if ↑(x✝ i) ≤ 1 / 2 then f (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i))))
    else g (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i) - 1)))) =
    (fromLoop i (Path.trans (toLoop i f) (toLoop i g))) x✝

Next tactic:
symm
/-- Concatenation of two `GenLoop`s along the `i`th coordinate. -/
def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x :=
  copy (fromLoop i <| (toLoop i f).trans <| toLoop i g)
    (fun t => if (t i : ℝ) ≤ 1 / 2
      then f (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i))
      else g (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i - 1)))
    (by
      ext1; symm
      

Proof state:
case h
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
x✝ : N → ↑I
⊢ (fromLoop i (Path.trans (toLoop i f) (toLoop i g))) x✝ =
    if ↑(x✝ i) ≤ 1 / 2 then f (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i))))
    else g (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i) - 1)))

Next tactic:
dsimp only [Path.trans, fromLoop, Path.coe_mk_mk, Function.comp_apply, mk_apply,
        ContinuousMap.comp_apply, toContinuousMap_apply, funSplitAt_apply,
        ContinuousMap.uncurry_apply, ContinuousMap.coe_mk, Function.uncurry_apply_pair]
/-- Concatenation of two `GenLoop`s along the `i`th coordinate. -/
def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x :=
  copy (fromLoop i <| (toLoop i f).trans <| toLoop i g)
    (fun t => if (t i : ℝ) ≤ 1 / 2
      then f (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i))
      else g (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i - 1)))
    (by
      ext1; symm
      dsimp only [Path.trans, fromLoop, Path.coe_mk_mk, Function.comp_apply, mk_apply,
        ContinuousMap.comp_apply, toContinuousMap_apply, funSplitAt_apply,
        ContinuousMap.uncurry_apply, ContinuousMap.coe_mk, Function.uncurry_apply_pair]
      

Proof state:
case h
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
x✝ : N → ↑I
⊢ (↑(if ↑(x✝ i) ≤ 1 / 2 then Path.extend (toLoop i f) (2 * ↑(x✝ i)) else Path.extend (toLoop i g) (2 * ↑(x✝ i) - 1))
      fun j => x✝ ↑j) =
    if ↑(x✝ i) ≤ 1 / 2 then f (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i))))
    else g (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i) - 1)))

Next tactic:
split_ifs
/-- Concatenation of two `GenLoop`s along the `i`th coordinate. -/
def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x :=
  copy (fromLoop i <| (toLoop i f).trans <| toLoop i g)
    (fun t => if (t i : ℝ) ≤ 1 / 2
      then f (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i))
      else g (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i - 1)))
    (by
      ext1; symm
      dsimp only [Path.trans, fromLoop, Path.coe_mk_mk, Function.comp_apply, mk_apply,
        ContinuousMap.comp_apply, toContinuousMap_apply, funSplitAt_apply,
        ContinuousMap.uncurry_apply, ContinuousMap.coe_mk, Function.uncurry_apply_pair]
      split_ifs; 

Proof state:
case pos
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
x✝ : N → ↑I
h✝ : ↑(x✝ i) ≤ 1 / 2
⊢ (↑(Path.extend (toLoop i f) (2 * ↑(x✝ i))) fun j => x✝ ↑j) =
    f (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i))))
case neg
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
x✝ : N → ↑I
h✝ : ¬↑(x✝ i) ≤ 1 / 2
⊢ (↑(Path.extend (toLoop i g) (2 * ↑(x✝ i) - 1)) fun j => x✝ ↑j) =
    g (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i) - 1)))

Next tactic:
change f _ = _
/-- Concatenation of two `GenLoop`s along the `i`th coordinate. -/
def transAt (i : N) (f g : Ω^ N X x) : Ω^ N X x :=
  copy (fromLoop i <| (toLoop i f).trans <| toLoop i g)
    (fun t => if (t i : ℝ) ≤ 1 / 2
      then f (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i))
      else g (Function.update t i <| Set.projIcc 0 1 zero_le_one (2 * t i - 1)))
    (by
      ext1; symm
      dsimp only [Path.trans, fromLoop, Path.coe_mk_mk, Function.comp_apply, mk_apply,
        ContinuousMap.comp_apply, toContinuousMap_apply, funSplitAt_apply,
        ContinuousMap.uncurry_apply, ContinuousMap.coe_mk, Function.uncurry_apply_pair]
      split_ifs; change f _ = _; 

Proof state:
case pos
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
x✝ : N → ↑I
h✝ : ↑(x✝ i) ≤ 1 / 2
⊢ f
      ((Homeomorph.toContinuousMap (Cube.insertAt i))
        (Set.projIcc 0 1 Path.extend.proof_1 (2 * ↑(x✝ i)), fun j => x✝ ↑j)) =
    f (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i))))
case neg
N : Type u_1
X : Type u_2
inst✝¹ : TopologicalSpace X
x : X
inst✝ : DecidableEq N
i : N
f g : ↑(Ω^ N X x)
x✝ : N → ↑I
h✝ : ¬↑(x✝ i) ≤ 1 / 2
⊢ (↑(Path.extend (toLoop i g) (2 * ↑(x✝ i) - 1)) fun j => x✝ ↑j) =
    g (Function.update x✝ i (Set.projIcc 0 1 (_ : 0 ≤ 1) (2 * ↑(x✝ i) - 1)))

Next tactic:
swap