|
| 1 | +/- |
| 2 | +Copyright (c) 2025 Sebastian Kumar. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Sebastian Kumar |
| 5 | +-/ |
| 6 | +module |
| 7 | + |
| 8 | +public import Mathlib.AlgebraicTopology.FundamentalGroupoid.Basic |
| 9 | + |
| 10 | +/-! |
| 11 | +# Subpaths |
| 12 | +
|
| 13 | +This file defines `Path.subpath` as a restriction of a path to a subinterval, |
| 14 | +reparameterized to have domain `[0, 1]` and possibly with a reverse of direction. |
| 15 | +
|
| 16 | +The main result `Path.Homotopy.subpathTransSubpath` shows that subpaths concatenate nicely. |
| 17 | +In particular: following the subpath of `γ` from `t₀` to `t₁`, and then that from `t₁` to `t₂`, |
| 18 | +is in natural homotopy with following the subpath of `γ` from `t₀` to `t₂`. |
| 19 | +
|
| 20 | +`Path.subpath` is similar in behavior to `Path.truncate`. When t₀ ≤ t₁, they are reparameterizations |
| 21 | +of each other (not yet proven). However, `Path.subpath` works without assuming an order on `t₀` and |
| 22 | +`t₁`, and is convenient for concrete manipulations (e.g., `Path.Homotopy.subpathTransSubpath`). |
| 23 | +
|
| 24 | +## TODO |
| 25 | +
|
| 26 | +Prove that `Path.truncateOfLE` and `Path.subpath` are reparameterizations of each other. |
| 27 | +-/ |
| 28 | + |
| 29 | +@[expose] public noncomputable section |
| 30 | + |
| 31 | +open unitInterval Set Function |
| 32 | + |
| 33 | +universe u |
| 34 | + |
| 35 | +variable {X : Type u} [TopologicalSpace X] {a b : X} |
| 36 | + |
| 37 | +namespace Path |
| 38 | + |
| 39 | +/-- Auxillary function for defining subpaths. -/ |
| 40 | +@[simp] |
| 41 | +def subpathAux (t₀ t₁ s : I) : I := ⟨(1 - s) * t₀ + s * t₁, |
| 42 | + (convex_Icc 0 1) t₀.prop t₁.prop (one_minus_nonneg s) s.prop.left (sub_add_cancel 1 _)⟩ |
| 43 | + |
| 44 | +lemma subpathAux_zero (t₀ t₁ : I) : subpathAux t₀ t₁ 0 = t₀ := by simp |
| 45 | + |
| 46 | +lemma subpathAux_one (t₀ t₁ : I) : subpathAux t₀ t₁ 1 = t₁ := by simp |
| 47 | + |
| 48 | +/-- `subpathAux` is continuous as an uncurried function `I × I × I → I`. -/ |
| 49 | +@[continuity, fun_prop] |
| 50 | +lemma subpathAux_continuous : Continuous (fun x ↦ subpathAux x.1 x.2.1 x.2.2 : I × I × I → I) := by |
| 51 | + unfold subpathAux |
| 52 | + fun_prop |
| 53 | + |
| 54 | +/-- The subpath of `γ` from `t₀` to `t₁`. -/ |
| 55 | +def subpath (γ : Path a b) (t₀ t₁ : I) : Path (γ t₀) (γ t₁) where |
| 56 | + toFun := γ ∘ (subpathAux t₀ t₁) |
| 57 | + source' := by rw [comp_apply, subpathAux_zero] |
| 58 | + target' := by rw [comp_apply, subpathAux_one] |
| 59 | + continuous_toFun := by fun_prop |
| 60 | + |
| 61 | +/-- Reversing `γ.subpath t₀ t₁` results in `γ.subpath t₁ t₀`. -/ |
| 62 | +@[simp] |
| 63 | +theorem symm_subpath (γ : Path a b) (t₀ t₁ : I) : symm (γ.subpath t₀ t₁) = γ.subpath t₁ t₀ := by |
| 64 | + ext s |
| 65 | + simp [subpath, add_comm] |
| 66 | + |
| 67 | +lemma range_subpathAux (t₀ t₁ : I) : range (subpathAux t₀ t₁) = uIcc t₀ t₁ := by |
| 68 | + rw [range_eq_iff] |
| 69 | + constructor |
| 70 | + · intro s |
| 71 | + exact convex_uIcc (t₀ : ℝ) t₁ left_mem_uIcc right_mem_uIcc |
| 72 | + (one_minus_nonneg s) (nonneg s) (sub_add_cancel _ _) |
| 73 | + · intro t (ht : (t : ℝ) ∈ uIcc (t₀ : ℝ) (t₁ : ℝ)) |
| 74 | + rw [← segment_eq_uIcc, segment_eq_image] at ht |
| 75 | + obtain ⟨s, hs, hst⟩ := ht |
| 76 | + use ⟨s, hs⟩ |
| 77 | + ext |
| 78 | + exact hst |
| 79 | + |
| 80 | +/-- The range of a subpath is the image of the original path on the relevant interval. -/ |
| 81 | +@[simp] |
| 82 | +theorem range_subpath (γ : Path a b) (t₀ t₁ : I) : |
| 83 | + range (γ.subpath t₀ t₁) = γ '' (uIcc t₀ t₁) := by |
| 84 | + rw [← range_subpathAux, ← range_comp] |
| 85 | + rfl |
| 86 | + |
| 87 | +lemma range_subpath_of_le (γ : Path a b) (t₀ t₁ : I) (h : t₀ ≤ t₁) : |
| 88 | + range (γ.subpath t₀ t₁) = γ '' (Icc t₀ t₁) := by |
| 89 | + simp [h] |
| 90 | + |
| 91 | +lemma range_subpath_of_ge (γ : Path a b) (t₀ t₁ : I) (h : t₁ ≤ t₀) : |
| 92 | + range (γ.subpath t₀ t₁) = γ '' (Icc t₁ t₀) := by |
| 93 | + simp [h] |
| 94 | + |
| 95 | +/-- The subpath of `γ` from `t` to `t` is just the constant path at `γ t`. -/ |
| 96 | +@[simp] |
| 97 | +theorem subpath_self (γ : Path a b) (t : I) : γ.subpath t t = Path.refl (γ t) := by |
| 98 | + ext s |
| 99 | + simp [subpath, ← add_mul, sub_add_cancel, one_mul] |
| 100 | + |
| 101 | +/-- The subpath of `γ` from `0` to `1` is just `γ`, with a slightly different type. -/ |
| 102 | +@[simp] |
| 103 | +theorem subpath_zero_one (γ : Path a b) : γ.subpath 0 1 = γ.cast γ.source γ.target := by |
| 104 | + ext s |
| 105 | + simp [subpath] |
| 106 | + |
| 107 | +/-- For a path `γ`, `γ.subpath` gives a "continuous family of paths", by which we mean |
| 108 | +the uncurried function which maps `(t₀, t₁, s)` to `γ.subpath t₀ t₁ s` is continuous. -/ |
| 109 | +@[continuity] |
| 110 | +theorem subpath_continuous_family (γ : Path a b) : |
| 111 | + Continuous (fun x => γ.subpath x.1 x.2.1 x.2.2 : I × I × I → X) := |
| 112 | + Continuous.comp' (map_continuous γ) subpathAux_continuous |
| 113 | + |
| 114 | +namespace Homotopy |
| 115 | + |
| 116 | +/-- Auxillary homotopy for `Path.Homotopy.subpathTransSubpath` which includes an unnecessary |
| 117 | +copy of `Path.refl`. -/ |
| 118 | +def subpathTransSubpathRefl (γ : Path a b) (t₀ t₁ t₂ : I) : Homotopy |
| 119 | + ((γ.subpath t₀ t₁).trans (γ.subpath t₁ t₂)) ((γ.subpath t₀ t₂).trans (Path.refl _)) where |
| 120 | + toFun x := ((γ.subpath t₀ (subpathAux t₁ t₂ x.1)).trans (γ.subpath _ t₂)) x.2 |
| 121 | + continuous_toFun := by |
| 122 | + let γ₁ (t : I) := γ.subpath t₀ (subpathAux t₁ t₂ t) |
| 123 | + let γ₂ (t : I) := γ.subpath (subpathAux t₁ t₂ t) t₂ |
| 124 | + refine Path.trans_continuous_family γ₁ ?_ γ₂ ?_ <;> |
| 125 | + refine γ.subpath_continuous_family.comp (.prodMk ?_ <| .prodMk ?_ ?_) <;> |
| 126 | + fun_prop |
| 127 | + map_zero_left := by |
| 128 | + intro _ |
| 129 | + rw [subpathAux_zero] |
| 130 | + rfl |
| 131 | + map_one_left := by |
| 132 | + intro _ |
| 133 | + rw [subpathAux_one, subpath_self] |
| 134 | + rfl |
| 135 | + prop' := by |
| 136 | + intro _ _ hx |
| 137 | + rcases hx with rfl | rfl <;> |
| 138 | + simp |
| 139 | + |
| 140 | +/-- Following the subpath of `γ` from `t₀` to `t₁`, and then that from `t₁` to `t₂`, |
| 141 | +is in natural homotopy with following the subpath of `γ` from `t₀` to `t₂`. -/ |
| 142 | +def subpathTransSubpath (γ : Path a b) (t₀ t₁ t₂ : I) : Homotopy |
| 143 | + ((γ.subpath t₀ t₁).trans (γ.subpath t₁ t₂)) (γ.subpath t₀ t₂) := |
| 144 | + trans (subpathTransSubpathRefl γ t₀ t₁ t₂) (transRefl _) |
| 145 | + |
| 146 | +end Path.Homotopy |
| 147 | +end |
0 commit comments