l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem trans_symm (γ : Path x y) (γ' : Path y z) : (γ.trans γ').symm = γ'.symm.trans γ.symm := by
  ext t
  simp only [trans_apply, ← one_div, symm_apply, not_le, Function.comp_apply]
  split_ifs with h h₁ h₂ <;> rw [coe_symm_eq] at h
  · have ht : (t : ℝ) = 1 / 2 := by linarith
    norm_num [ht]
  · refine' congr_arg _ (Subtype.ext _)
    norm_num [sub_sub_eq_add_sub, mul_sub]
  · refine' congr_arg _ (Subtype.ext _)
    norm_num [mul_sub, h]
    ring -- TODO norm_num should really do this
  · exfalso
    

Proof state:
case neg.h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ✝ γ : Path x y
γ' : Path y z
t : ↑I
h✝ : ¬↑(σ t) ≤ 1 / 2
h : ¬1 - ↑t ≤ 1 / 2
h₂ : ¬↑t ≤ 1 / 2
⊢ False

Next tactic:
linarith
@[simp]
theorem refl_trans_refl {a : X} :
    (Path.refl a).trans (Path.refl a) = Path.refl a := by
  

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a : X
⊢ trans (refl a) (refl a) = refl a

Next tactic:
ext
@[simp]
theorem refl_trans_refl {a : X} :
    (Path.refl a).trans (Path.refl a) = Path.refl a := by
  ext
  

Proof state:
case a.h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a : X
x✝ : ↑I
⊢ (trans (refl a) (refl a)) x✝ = (refl a) x✝

Next tactic:
simp only [Path.trans, ite_self, one_div, Path.refl_extend]
@[simp]
theorem refl_trans_refl {a : X} :
    (Path.refl a).trans (Path.refl a) = Path.refl a := by
  ext
  simp only [Path.trans, ite_self, one_div, Path.refl_extend]
  

Proof state:
case a.h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a : X
x✝ : ↑I
⊢ { toContinuousMap := ContinuousMap.mk ((fun t => a) ∘ Subtype.val),
        source' := (_ : ContinuousMap.toFun (ContinuousMap.mk ((fun t => a) ∘ Subtype.val)) 0 = a),
        target' := (_ : ContinuousMap.toFun (ContinuousMap.mk ((fun t => a) ∘ Subtype.val)) 1 = a) }
      x✝ =
    (refl a) x✝

Next tactic:
rfl
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
⊢ range ⇑(trans γ₁ γ₂) = range ⇑γ₁ ∪ range ⇑γ₂

Next tactic:
rw [Path.trans]
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
⊢ range
      ⇑{
          toContinuousMap :=
            ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
          source' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
          target' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) } =
    range ⇑γ₁ ∪ range ⇑γ₂

Next tactic:
apply eq_of_subset_of_subset
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · 

Proof state:
case a
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
⊢ range
      ⇑{
          toContinuousMap :=
            ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
          source' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
          target' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) } ⊆
    range ⇑γ₁ ∪ range ⇑γ₂

Next tactic:
rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    

Proof state:
case a.intro.mk.intro
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
⊢ x ∈ range ⇑γ₁ ∪ range ⇑γ₂

Next tactic:
by_cases h : t ≤ 1 / 2
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · 

Proof state:
case pos
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : t ≤ 1 / 2
⊢ x ∈ range ⇑γ₁ ∪ range ⇑γ₂

Next tactic:
left
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      

Proof state:
case pos.h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : t ≤ 1 / 2
⊢ x ∈ range ⇑γ₁

Next tactic:
use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : t ≤ 1 / 2
⊢ 0 ≤ 2 * t

Next tactic:
linarith
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : t ≤ 1 / 2
⊢ 2 * t ≤ 1

Next tactic:
linarith
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      

Proof state:
case h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : t ≤ 1 / 2
⊢ γ₁ { val := 2 * t, property := (_ : 0 ≤ 2 * t ∧ 2 * t ≤ 1) } = x

Next tactic:
rw [← γ₁.extend_extends]
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      

Proof state:
case h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : t ≤ 1 / 2
⊢ extend γ₁ (2 * t) = x

Next tactic:
rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · 

Proof state:
case neg
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : ¬t ≤ 1 / 2
⊢ x ∈ range ⇑γ₁ ∪ range ⇑γ₂

Next tactic:
right
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      

Proof state:
case neg.h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : ¬t ≤ 1 / 2
⊢ x ∈ range ⇑γ₂

Next tactic:
use ⟨2 * t - 1, ⟨by linarith, by linarith⟩⟩
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : ¬t ≤ 1 / 2
⊢ 0 ≤ 2 * t - 1

Next tactic:
linarith
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by linarith, by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : ¬t ≤ 1 / 2
⊢ 2 * t - 1 ≤ 1

Next tactic:
linarith
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by linarith, by linarith⟩⟩
      

Proof state:
case h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : ¬t ≤ 1 / 2
⊢ γ₂ { val := 2 * t - 1, property := (_ : 0 ≤ 2 * t - 1 ∧ 2 * t - 1 ≤ 1) } = x

Next tactic:
rw [← γ₂.extend_extends]
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by linarith, by linarith⟩⟩
      rw [← γ₂.extend_extends]
      

Proof state:
case h
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt :
  {
        toContinuousMap :=
          ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
        source' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
        target' :=
          (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }
      { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } =
    x
h : ¬t ≤ 1 / 2
⊢ extend γ₂ (2 * t - 1) = x

Next tactic:
rwa [coe_mk_mk, Function.comp_apply, if_neg h] at hxt
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by linarith, by linarith⟩⟩
      rw [← γ₂.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_neg h] at hxt
  · 

Proof state:
case a
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x y z : X
ι : Type u_3
γ : Path x y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
⊢ range ⇑γ₁ ∪ range ⇑γ₂ ⊆
    range
      ⇑{
          toContinuousMap :=
            ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
          source' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
          target' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }

Next tactic:
rintro x (⟨⟨t, ht0, ht1⟩, hxt⟩ | ⟨⟨t, ht0, ht1⟩, hxt⟩)
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by linarith, by linarith⟩⟩
      rw [← γ₂.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_neg h] at hxt
  · rintro x (⟨⟨t, ht0, ht1⟩, hxt⟩ | ⟨⟨t, ht0, ht1⟩, hxt⟩)
    · 

Proof state:
case a.inl.intro.mk.intro
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt : γ₁ { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } = x
⊢ x ∈
    range
      ⇑{
          toContinuousMap :=
            ContinuousMap.mk ((fun t => if t ≤ 1 / 2 then extend γ₁ (2 * t) else extend γ₂ (2 * t - 1)) ∘ Subtype.val),
          source' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 0 = a),
          target' :=
            (_ : ((fun x => if x ≤ 1 / 2 then extend γ₁ (2 * x) else extend γ₂ (2 * x - 1)) ∘ Subtype.val) 1 = c) }

Next tactic:
use ⟨t / 2, ⟨by linarith, by linarith⟩⟩
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by linarith, by linarith⟩⟩
      rw [← γ₂.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_neg h] at hxt
  · rintro x (⟨⟨t, ht0, ht1⟩, hxt⟩ | ⟨⟨t, ht0, ht1⟩, hxt⟩)
    · use ⟨t / 2, ⟨by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt : γ₁ { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } = x
⊢ 0 ≤ t / 2

Next tactic:
linarith
theorem trans_range {a b c : X} (γ₁ : Path a b) (γ₂ : Path b c) :
    range (γ₁.trans γ₂) = range γ₁ ∪ range γ₂ := by
  rw [Path.trans]
  apply eq_of_subset_of_subset
  · rintro x ⟨⟨t, ht0, ht1⟩, hxt⟩
    by_cases h : t ≤ 1 / 2
    · left
      use ⟨2 * t, ⟨by linarith, by linarith⟩⟩
      rw [← γ₁.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_pos h] at hxt
    · right
      use ⟨2 * t - 1, ⟨by linarith, by linarith⟩⟩
      rw [← γ₂.extend_extends]
      rwa [coe_mk_mk, Function.comp_apply, if_neg h] at hxt
  · rintro x (⟨⟨t, ht0, ht1⟩, hxt⟩ | ⟨⟨t, ht0, ht1⟩, hxt⟩)
    · use ⟨t / 2, ⟨by linarith, by 

Proof state:
X : Type u_1
Y : Type u_2
inst✝¹ : TopologicalSpace X
inst✝ : TopologicalSpace Y
x✝ y z : X
ι : Type u_3
γ : Path x✝ y
a b c : X
γ₁ : Path a b
γ₂ : Path b c
x : X
t : ℝ
ht0 : 0 ≤ t
ht1 : t ≤ 1
hxt : γ₁ { val := t, property := (_ : 0 ≤ t ∧ t ≤ 1) } = x
⊢ t / 2 ≤ 1

Next tactic:
linarith