l3lab/ntp-mathlib huggingface dataset:
theorem trans_apply {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) (x : I × X) :
    (F.trans G) x =
      if h : (x.1 : ℝ) ≤ 1 / 2 then
        F (⟨2 * x.1, (unitInterval.mul_pos_mem_iff zero_lt_two).2 ⟨x.1.2.1, h⟩⟩, x.2)
      else
        G (⟨2 * x.1 - 1, unitInterval.two_mul_sub_one_mem_iff.2 ⟨(not_le.1 h).le, x.1.2.2⟩⟩, x.2) :=
  show ite _ _ _ = _ by
    split_ifs <;>
      · rw [extend, ContinuousMap.coe_IccExtend, Set.IccExtend_of_mem]
        

Proof state:
case pos
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
x : ↑I × X
h✝ : ↑x.1 ≤ 1 / 2
⊢ ((curry F) { val := 2 * ↑x.1, property := ?pos.hx✝ }) x.2 =
    F ({ val := 2 * ↑x.1, property := (_ : 2 * ↑x.1 ∈ I) }, x.2)
case pos.hx
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
x : ↑I × X
h✝ : ↑x.1 ≤ 1 / 2
⊢ 2 * ↑x.1 ∈ Set.Icc 0 1

Next tactic:
rfl
theorem trans_apply {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) (x : I × X) :
    (F.trans G) x =
      if h : (x.1 : ℝ) ≤ 1 / 2 then
        F (⟨2 * x.1, (unitInterval.mul_pos_mem_iff zero_lt_two).2 ⟨x.1.2.1, h⟩⟩, x.2)
      else
        G (⟨2 * x.1 - 1, unitInterval.two_mul_sub_one_mem_iff.2 ⟨(not_le.1 h).le, x.1.2.2⟩⟩, x.2) :=
  show ite _ _ _ = _ by
    split_ifs <;>
      · 

Proof state:
case neg
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
x : ↑I × X
h✝ : ¬↑x.1 ≤ 1 / 2
⊢ ((extend G) (2 * ↑x.1 - 1)) x.2 = G ({ val := 2 * ↑x.1 - 1, property := (_ : 2 * ↑x.1 - 1 ∈ I) }, x.2)

Next tactic:
rw [extend, ContinuousMap.coe_IccExtend, Set.IccExtend_of_mem]
theorem trans_apply {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) (x : I × X) :
    (F.trans G) x =
      if h : (x.1 : ℝ) ≤ 1 / 2 then
        F (⟨2 * x.1, (unitInterval.mul_pos_mem_iff zero_lt_two).2 ⟨x.1.2.1, h⟩⟩, x.2)
      else
        G (⟨2 * x.1 - 1, unitInterval.two_mul_sub_one_mem_iff.2 ⟨(not_le.1 h).le, x.1.2.2⟩⟩, x.2) :=
  show ite _ _ _ = _ by
    split_ifs <;>
      · rw [extend, ContinuousMap.coe_IccExtend, Set.IccExtend_of_mem]
        

Proof state:
case neg
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
x : ↑I × X
h✝ : ¬↑x.1 ≤ 1 / 2
⊢ ((curry G) { val := 2 * ↑x.1 - 1, property := ?neg.hx✝ }) x.2 =
    G ({ val := 2 * ↑x.1 - 1, property := (_ : 2 * ↑x.1 - 1 ∈ I) }, x.2)
case neg.hx
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
x : ↑I × X
h✝ : ¬↑x.1 ≤ 1 / 2
⊢ 2 * ↑x.1 - 1 ∈ Set.Icc 0 1

Next tactic:
rfl
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
⊢ symm (trans F G) = trans (symm G) (symm F)

Next tactic:
ext ⟨t, _⟩
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  

Proof state:
case h.mk
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
⊢ (symm (trans F G)) (t, snd✝) = (trans (symm G) (symm F)) (t, snd✝)

Next tactic:
rw [trans_apply, symm_apply, trans_apply]
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  

Proof state:
case h.mk
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
⊢ (if h : ↑(σ (t, snd✝).1, (t, snd✝).2).1 ≤ 1 / 2 then
      F
        ({ val := 2 * ↑(σ (t, snd✝).1, (t, snd✝).2).1, property := (_ : 2 * ↑(σ (t, snd✝).1, (t, snd✝).2).1 ∈ I) },
          (σ (t, snd✝).1, (t, snd✝).2).2)
    else
      G
        ({ val := 2 * ↑(σ (t, snd✝).1, (t, snd✝).2).1 - 1,
            property := (_ : 2 * ↑(σ (t, snd✝).1, (t, snd✝).2).1 - 1 ∈ I) },
          (σ (t, snd✝).1, (t, snd✝).2).2)) =
    if h : ↑(t, snd✝).1 ≤ 1 / 2 then
      (symm G) ({ val := 2 * ↑(t, snd✝).1, property := (_ : 2 * ↑(t, snd✝).1 ∈ I) }, (t, snd✝).2)
    else (symm F) ({ val := 2 * ↑(t, snd✝).1 - 1, property := (_ : 2 * ↑(t, snd✝).1 - 1 ∈ I) }, (t, snd✝).2)

Next tactic:
simp only [coe_symm_eq, symm_apply]
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  

Proof state:
case h.mk
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
⊢ (if h : 1 - ↑t ≤ 1 / 2 then F ({ val := 2 * (1 - ↑t), property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t))) }, snd✝)
    else G ({ val := 2 * (1 - ↑t) - 1, property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t) - 1)) }, snd✝)) =
    if h : ↑t ≤ 1 / 2 then G (σ { val := 2 * ↑t, property := (_ : 2 * ↑(t, snd✝).1 ∈ I) }, snd✝)
    else F (σ { val := 2 * ↑t - 1, property := (_ : 2 * ↑(t, snd✝).1 - 1 ∈ I) }, snd✝)

Next tactic:
split_ifs with h₁ h₂ h₂
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · 

Proof state:
case pos
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : 1 - ↑t ≤ 1 / 2
h₂ : ↑t ≤ 1 / 2
⊢ F ({ val := 2 * (1 - ↑t), property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t))) }, snd✝) =
    G (σ { val := 2 * ↑t, property := (_ : 2 * ↑(t, snd✝).1 ∈ I) }, snd✝)

Next tactic:
have ht : (t : ℝ) = 1 / 2 := by linarith
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by 

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : 1 - ↑t ≤ 1 / 2
h₂ : ↑t ≤ 1 / 2
⊢ ↑t = 1 / 2

Next tactic:
linarith
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    

Proof state:
case pos
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : 1 - ↑t ≤ 1 / 2
h₂ : ↑t ≤ 1 / 2
ht : ↑t = 1 / 2
⊢ F ({ val := 2 * (1 - ↑t), property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t))) }, snd✝) =
    G (σ { val := 2 * ↑t, property := (_ : 2 * ↑(t, snd✝).1 ∈ I) }, snd✝)

Next tactic:
norm_num [ht]
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · 

Proof state:
case neg
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : 1 - ↑t ≤ 1 / 2
h₂ : ¬↑t ≤ 1 / 2
⊢ F ({ val := 2 * (1 - ↑t), property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t))) }, snd✝) =
    F (σ { val := 2 * ↑t - 1, property := (_ : 2 * ↑(t, snd✝).1 - 1 ∈ I) }, snd✝)

Next tactic:
congr 2
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    

Proof state:
case neg.h.e_6.h.e_fst
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : 1 - ↑t ≤ 1 / 2
h₂ : ¬↑t ≤ 1 / 2
⊢ { val := 2 * (1 - ↑t), property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t))) } =
    σ { val := 2 * ↑t - 1, property := (_ : 2 * ↑(t, snd✝).1 - 1 ∈ I) }

Next tactic:
apply Subtype.ext
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    

Proof state:
case neg.h.e_6.h.e_fst.a
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : 1 - ↑t ≤ 1 / 2
h₂ : ¬↑t ≤ 1 / 2
⊢ ↑{ val := 2 * (1 - ↑t), property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t))) } =
    ↑(σ { val := 2 * ↑t - 1, property := (_ : 2 * ↑(t, snd✝).1 - 1 ∈ I) })

Next tactic:
simp only [coe_symm_eq]
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    

Proof state:
case neg.h.e_6.h.e_fst.a
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : 1 - ↑t ≤ 1 / 2
h₂ : ¬↑t ≤ 1 / 2
⊢ 2 * (1 - ↑t) = 1 - (2 * ↑t - 1)

Next tactic:
linarith
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · 

Proof state:
case pos
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : ¬1 - ↑t ≤ 1 / 2
h₂ : ↑t ≤ 1 / 2
⊢ G ({ val := 2 * (1 - ↑t) - 1, property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t) - 1)) }, snd✝) =
    G (σ { val := 2 * ↑t, property := (_ : 2 * ↑(t, snd✝).1 ∈ I) }, snd✝)

Next tactic:
congr 2
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · congr 2
    

Proof state:
case pos.h.e_6.h.e_fst
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : ¬1 - ↑t ≤ 1 / 2
h₂ : ↑t ≤ 1 / 2
⊢ { val := 2 * (1 - ↑t) - 1, property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t) - 1)) } =
    σ { val := 2 * ↑t, property := (_ : 2 * ↑(t, snd✝).1 ∈ I) }

Next tactic:
apply Subtype.ext
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · congr 2
    apply Subtype.ext
    

Proof state:
case pos.h.e_6.h.e_fst.a
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : ¬1 - ↑t ≤ 1 / 2
h₂ : ↑t ≤ 1 / 2
⊢ ↑{ val := 2 * (1 - ↑t) - 1, property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t) - 1)) } =
    ↑(σ { val := 2 * ↑t, property := (_ : 2 * ↑(t, snd✝).1 ∈ I) })

Next tactic:
simp only [coe_symm_eq]
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    

Proof state:
case pos.h.e_6.h.e_fst.a
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : ¬1 - ↑t ≤ 1 / 2
h₂ : ↑t ≤ 1 / 2
⊢ 2 * (1 - ↑t) - 1 = 1 - 2 * ↑t

Next tactic:
linarith
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · 

Proof state:
case neg
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : ¬1 - ↑t ≤ 1 / 2
h₂ : ¬↑t ≤ 1 / 2
⊢ G ({ val := 2 * (1 - ↑t) - 1, property := (_ : (fun x => x ∈ I) (2 * (1 - ↑t) - 1)) }, snd✝) =
    F (σ { val := 2 * ↑t - 1, property := (_ : 2 * ↑(t, snd✝).1 - 1 ∈ I) }, snd✝)

Next tactic:
exfalso
theorem symm_trans {f₀ f₁ f₂ : C(X, Y)} (F : Homotopy f₀ f₁) (G : Homotopy f₁ f₂) :
    (F.trans G).symm = G.symm.trans F.symm := by
  ext ⟨t, _⟩
  rw [trans_apply, symm_apply, trans_apply]
  simp only [coe_symm_eq, symm_apply]
  split_ifs with h₁ h₂ h₂
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · congr 2
    apply Subtype.ext
    simp only [coe_symm_eq]
    linarith
  · exfalso
    

Proof state:
case neg.h
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ f₂ : C(X, Y)
F : Homotopy f₀ f₁
G : Homotopy f₁ f₂
t : ↑I
snd✝ : X
h₁ : ¬1 - ↑t ≤ 1 / 2
h₂ : ¬↑t ≤ 1 / 2
⊢ False

Next tactic:
linarith
/-- Casting a `Homotopy f₀ f₁` to a `Homotopy g₀ g₁` where `f₀ = g₀` and `f₁ = g₁`.
-/
@[simps]
def cast {f₀ f₁ g₀ g₁ : C(X, Y)} (F : Homotopy f₀ f₁) (h₀ : f₀ = g₀) (h₁ : f₁ = g₁) :
    Homotopy g₀ g₁ where
  toFun := F
  map_zero_left := by 

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ g₀ g₁ : C(X, Y)
F : Homotopy f₀ f₁
h₀ : f₀ = g₀
h₁ : f₁ = g₁
⊢ ∀ (x : X), ContinuousMap.toFun (ContinuousMap.mk ⇑F) (0, x) = g₀ x

Next tactic:
simp [← h₀]
/-- Casting a `Homotopy f₀ f₁` to a `Homotopy g₀ g₁` where `f₀ = g₀` and `f₁ = g₁`.
-/
@[simps]
def cast {f₀ f₁ g₀ g₁ : C(X, Y)} (F : Homotopy f₀ f₁) (h₀ : f₀ = g₀) (h₁ : f₁ = g₁) :
    Homotopy g₀ g₁ where
  toFun := F
  map_zero_left := by simp [← h₀]
  map_one_left := by 

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ g₀ g₁ : C(X, Y)
F : Homotopy f₀ f₁
h₀ : f₀ = g₀
h₁ : f₁ = g₁
⊢ ∀ (x : X), ContinuousMap.toFun (ContinuousMap.mk ⇑F) (1, x) = g₁ x

Next tactic:
simp [← h₁]
/-- If we have a `Homotopy f₀ f₁` and a `Homotopy g₀ g₁`, then we can compose them and get a
`Homotopy (g₀.comp f₀) (g₁.comp f₁)`.
-/
@[simps]
def hcomp {f₀ f₁ : C(X, Y)} {g₀ g₁ : C(Y, Z)} (F : Homotopy f₀ f₁) (G : Homotopy g₀ g₁) :
    Homotopy (g₀.comp f₀) (g₁.comp f₁) where
  toFun x := G (x.1, F x)
  map_zero_left := by 

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ : C(X, Y)
g₀ g₁ : C(Y, Z)
F : Homotopy f₀ f₁
G : Homotopy g₀ g₁
⊢ ∀ (x : X), ContinuousMap.toFun (ContinuousMap.mk fun x => G (x.1, F x)) (0, x) = (comp g₀ f₀) x

Next tactic:
simp
/-- If we have a `Homotopy f₀ f₁` and a `Homotopy g₀ g₁`, then we can compose them and get a
`Homotopy (g₀.comp f₀) (g₁.comp f₁)`.
-/
@[simps]
def hcomp {f₀ f₁ : C(X, Y)} {g₀ g₁ : C(Y, Z)} (F : Homotopy f₀ f₁) (G : Homotopy g₀ g₁) :
    Homotopy (g₀.comp f₀) (g₁.comp f₁) where
  toFun x := G (x.1, F x)
  map_zero_left := by simp
  map_one_left := by 

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
f₀ f₁ : C(X, Y)
g₀ g₁ : C(Y, Z)
F : Homotopy f₀ f₁
G : Homotopy g₀ g₁
⊢ ∀ (x : X), ContinuousMap.toFun (ContinuousMap.mk fun x => G (x.1, F x)) (1, x) = (comp g₁ f₁) x

Next tactic:
simp
theorem equivalence : Equivalence (@Homotopic X Y _ _) :=
  ⟨refl, by 

Proof state:
F : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
⊢ ∀ {x y : C(X, Y)}, Homotopic x y → Homotopic y x

Next tactic:
apply symm
theorem equivalence : Equivalence (@Homotopic X Y _ _) :=
  ⟨refl, by apply symm, by 

Proof state:
F : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
⊢ ∀ {x y z : C(X, Y)}, Homotopic x y → Homotopic y z → Homotopic x z

Next tactic:
apply trans
/--
Given `HomotopyWith f₀ f₁ P` and `HomotopyWith f₁ f₂ P`, we can define a `HomotopyWith f₀ f₂ P`
by putting the first homotopy on `[0, 1/2]` and the second on `[1/2, 1]`.
-/
def trans {f₀ f₁ f₂ : C(X, Y)} (F : HomotopyWith f₀ f₁ P) (G : HomotopyWith f₁ f₂ P) :
    HomotopyWith f₀ f₂ P :=
  { F.toHomotopy.trans G.toHomotopy with
    prop' := fun t => by
      

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
P : C(X, Y) → Prop
f₀ f₁ f₂ : C(X, Y)
F : HomotopyWith f₀ f₁ P
G : HomotopyWith f₁ f₂ P
src✝ : Homotopy f₀ f₂ := Homotopy.trans F.toHomotopy G.toHomotopy
t : ↑I
⊢ P
    (ContinuousMap.mk fun x =>
      ContinuousMap.toFun
        { toContinuousMap := src✝.toContinuousMap,
            map_zero_left := (_ : ∀ (x : X), ContinuousMap.toFun src✝.toContinuousMap (0, x) = f₀ x),
            map_one_left := (_ : ∀ (x : X), ContinuousMap.toFun src✝.toContinuousMap (1, x) = f₂ x) }.toContinuousMap
        (t, x))

Next tactic:
simp only [Homotopy.trans]
/--
Given `HomotopyWith f₀ f₁ P` and `HomotopyWith f₁ f₂ P`, we can define a `HomotopyWith f₀ f₂ P`
by putting the first homotopy on `[0, 1/2]` and the second on `[1/2, 1]`.
-/
def trans {f₀ f₁ f₂ : C(X, Y)} (F : HomotopyWith f₀ f₁ P) (G : HomotopyWith f₁ f₂ P) :
    HomotopyWith f₀ f₂ P :=
  { F.toHomotopy.trans G.toHomotopy with
    prop' := fun t => by
      simp only [Homotopy.trans]
      

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
P : C(X, Y) → Prop
f₀ f₁ f₂ : C(X, Y)
F : HomotopyWith f₀ f₁ P
G : HomotopyWith f₁ f₂ P
src✝ : Homotopy f₀ f₂ := Homotopy.trans F.toHomotopy G.toHomotopy
t : ↑I
⊢ P
    (ContinuousMap.mk fun x =>
      if ↑t ≤ 1 / 2 then ((Homotopy.extend F.toHomotopy) (2 * ↑t)) x
      else ((Homotopy.extend G.toHomotopy) (2 * ↑t - 1)) x)

Next tactic:
change P ⟨fun _ => ite ((t : ℝ) ≤ _) _ _, _⟩
/--
Given `HomotopyWith f₀ f₁ P` and `HomotopyWith f₁ f₂ P`, we can define a `HomotopyWith f₀ f₂ P`
by putting the first homotopy on `[0, 1/2]` and the second on `[1/2, 1]`.
-/
def trans {f₀ f₁ f₂ : C(X, Y)} (F : HomotopyWith f₀ f₁ P) (G : HomotopyWith f₁ f₂ P) :
    HomotopyWith f₀ f₂ P :=
  { F.toHomotopy.trans G.toHomotopy with
    prop' := fun t => by
      simp only [Homotopy.trans]
      change P ⟨fun _ => ite ((t : ℝ) ≤ _) _ _, _⟩
      

Proof state:
F✝ : Type u_1
X : Type u
Y : Type v
Z : Type w
Z' : Type x
inst✝³ : TopologicalSpace X
inst✝² : TopologicalSpace Y
inst✝¹ : TopologicalSpace Z
inst✝ : TopologicalSpace Z'
P : C(X, Y) → Prop
f₀ f₁ f₂ : C(X, Y)
F : HomotopyWith f₀ f₁ P
G : HomotopyWith f₁ f₂ P
src✝ : Homotopy f₀ f₂ := Homotopy.trans F.toHomotopy G.toHomotopy
t : ↑I
⊢ P
    (ContinuousMap.mk fun x =>
      if ↑t ≤ 1 / 2 then ((Homotopy.extend F.toHomotopy) (2 * ↑t)) x
      else ((Homotopy.extend G.toHomotopy) (2 * ↑t - 1)) x)

Next tactic:
split_ifs