Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit b51f18f

Browse files
committed
feat(topology): properties about intervals and paths (#9914)
* From the sphere eversion project * Properties about paths, the interval, and `proj_Icc`
1 parent 8d52be4 commit b51f18f

File tree

5 files changed

+104
-18
lines changed

5 files changed

+104
-18
lines changed

src/analysis/special_functions/trigonometric/inverse.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ inj_on_arcsin.eq_iff ⟨hx₁, hx₂⟩ ⟨hy₁, hy₂⟩
6868

6969
@[continuity]
7070
lemma continuous_arcsin : continuous arcsin :=
71-
continuous_subtype_coe.comp sin_order_iso.symm.continuous.Icc_extend
71+
continuous_subtype_coe.comp sin_order_iso.symm.continuous.Icc_extend'
7272

7373
lemma continuous_at_arcsin {x : ℝ} : continuous_at arcsin x :=
7474
continuous_arcsin.continuous_at

src/data/set/intervals/proj_Icc.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,21 @@ by simp [proj_Icc, hx, h]
4242
@[simp] lemma proj_Icc_right : proj_Icc a b h b = ⟨b, right_mem_Icc.2 h⟩ :=
4343
proj_Icc_of_right_le h le_rfl
4444

45+
lemma proj_Icc_eq_left (h : a < b) : proj_Icc a b h.le x = ⟨a, left_mem_Icc.mpr h.le⟩ ↔ x ≤ a :=
46+
begin
47+
refine ⟨λ h', _, proj_Icc_of_le_left _⟩,
48+
simp_rw [subtype.ext_iff_val, proj_Icc, max_eq_left_iff, min_le_iff, h.not_le, false_or] at h',
49+
exact h'
50+
end
51+
52+
lemma proj_Icc_eq_right (h : a < b) : proj_Icc a b h.le x = ⟨b, right_mem_Icc.mpr h.le⟩ ↔ b ≤ x :=
53+
begin
54+
refine ⟨λ h', _, proj_Icc_of_right_le _⟩,
55+
simp_rw [subtype.ext_iff_val, proj_Icc] at h',
56+
have := ((max_choice _ _).resolve_left (by simp [h.ne', h'])).symm.trans h',
57+
exact min_eq_left_iff.mp this
58+
end
59+
4560
lemma proj_Icc_of_mem (hx : x ∈ Icc a b) : proj_Icc a b h x = ⟨x, hx⟩ :=
4661
by simp [proj_Icc, hx.1, hx.2]
4762

src/topology/algebra/ordered/proj_Icc.lean

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,18 @@ In this file we prove that the projection `set.proj_Icc f a b h` is a quotient m
1313
to show that `Icc_extend h f` is continuous if and only if `f` is continuous.
1414
-/
1515

16-
variables {α β : Type*} [topological_space α] [linear_order α] [order_topology α]
17-
[topological_space β] {a b : α} {h : a ≤ b}
16+
open set filter
17+
open_locale filter topological_space
1818

19-
open set
19+
variables {α β γ : Type*} [linear_order α] [topological_space γ] {a b c : α} {h : a ≤ b}
20+
21+
lemma filter.tendsto.Icc_extend (f : γ → Icc a b → β) {z : γ} {l : filter α} {l' : filter β}
22+
(hf : tendsto ↿f (𝓝 z ×ᶠ l.map (proj_Icc a b h)) l') :
23+
tendsto ↿(Icc_extend h ∘ f) (𝓝 z ×ᶠ l) l' :=
24+
show tendsto (↿f ∘ prod.map id (proj_Icc a b h)) (𝓝 z ×ᶠ l) l', from
25+
hf.comp $ tendsto_id.prod_map tendsto_map
26+
27+
variables [topological_space α] [order_topology α] [topological_space β]
2028

2129
@[continuity]
2230
lemma continuous_proj_Icc : continuous (proj_Icc a b h) :=
@@ -31,7 +39,18 @@ quotient_map_iff.2 ⟨proj_Icc_surjective h, λ s,
3139
continuous (Icc_extend h f) ↔ continuous f :=
3240
quotient_map_proj_Icc.continuous_iff.symm
3341

42+
/-- See Note [continuity lemma statement]. -/
43+
lemma continuous.Icc_extend {f : γ → Icc a b → β} {g : γ → α}
44+
(hf : continuous ↿f) (hg : continuous g) : continuous (λ a, Icc_extend h (f a) (g a)) :=
45+
hf.comp $ continuous_id.prod_mk $ continuous_proj_Icc.comp hg
46+
47+
/-- A useful special case of `continuous.Icc_extend`. -/
3448
@[continuity]
35-
lemma continuous.Icc_extend {f : Icc a b → β} (hf : continuous f) :
36-
continuous (Icc_extend h f) :=
49+
lemma continuous.Icc_extend' {f : Icc a b → β} (hf : continuous f) : continuous (Icc_extend h f) :=
3750
hf.comp continuous_proj_Icc
51+
52+
lemma continuous_at.Icc_extend {x : γ} (f : γ → Icc a b → β) {g : γ → α}
53+
(hf : continuous_at ↿f (x, proj_Icc a b h (g x))) (hg : continuous_at g x) :
54+
continuous_at (λ a, Icc_extend h (f a) (g a)) x :=
55+
show continuous_at (↿f ∘ λ x, (x, proj_Icc a b h (g x))) x, from
56+
continuous_at.comp hf $ continuous_at_id.prod $ continuous_proj_Icc.continuous_at.comp hg

src/topology/path_connected.lean

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ noncomputable theory
6262
open_locale classical topological_space filter unit_interval
6363
open filter set function unit_interval
6464

65-
variables {X : Type*} [topological_space X] {x y z : X} {ι : Type*}
65+
variables {X Y : Type*} [topological_space X] [topological_space Y] {x y z : X} {ι : Type*}
6666

6767
/-! ### Paths -/
6868

@@ -74,8 +74,7 @@ structure path (x y : X) extends C(I, X) :=
7474

7575
instance : has_coe_to_fun (path x y) (λ _, I → X) := ⟨λ p, p.to_fun⟩
7676

77-
@[ext] protected lemma path.ext {X : Type*} [topological_space X] {x y : X} :
78-
∀ {γ₁ γ₂ : path x y}, (γ₁ : I → X) = γ₂ → γ₁ = γ₂
77+
@[ext] protected lemma path.ext : ∀ {γ₁ γ₂ : path x y}, (γ₁ : I → X) = γ₂ → γ₁ = γ₂
7978
| ⟨⟨x, h11⟩, h12, h13⟩ ⟨⟨.(x), h21⟩, h22, h23⟩ rfl := rfl
8079

8180
namespace path
@@ -114,8 +113,7 @@ instance has_uncurry_path {X α : Type*} [topological_space X] {x y : α → X}
114113
source' := rfl,
115114
target' := rfl }
116115

117-
@[simp] lemma refl_range {X : Type*} [topological_space X] {a : X} :
118-
range (path.refl a) = {a} :=
116+
@[simp] lemma refl_range {a : X} : range (path.refl a) = {a} :=
119117
by simp [path.refl, has_coe_to_fun.coe, coe_fn]
120118

121119
/-- The reverse of a path from `x` to `y`, as a path from `y` to `x` -/
@@ -128,12 +126,10 @@ by simp [path.refl, has_coe_to_fun.coe, coe_fn]
128126
@[simp] lemma symm_symm {γ : path x y} : γ.symm.symm = γ :=
129127
by { ext, simp }
130128

131-
@[simp] lemma refl_symm {X : Type*} [topological_space X] {a : X} :
132-
(path.refl a).symm = path.refl a :=
129+
@[simp] lemma refl_symm {a : X} : (path.refl a).symm = path.refl a :=
133130
by { ext, refl }
134131

135-
@[simp] lemma symm_range {X : Type*} [topological_space X] {a b : X} (γ : path a b) :
136-
range γ.symm = range γ :=
132+
@[simp] lemma symm_range {a b : X} (γ : path a b) : range γ.symm = range γ :=
137133
begin
138134
ext x,
139135
simp only [mem_range, path.symm, has_coe_to_fun.coe, coe_fn, unit_interval.symm, set_coe.exists,
@@ -145,9 +141,26 @@ end
145141
/-- A continuous map extending a path to `ℝ`, constant before `0` and after `1`. -/
146142
def extend : ℝ → X := Icc_extend zero_le_one γ
147143

144+
/-- See Note [continuity lemma statement]. -/
145+
lemma _root_.continuous.path_extend {γ : Y → path x y} {f : Y → ℝ} (hγ : continuous ↿γ)
146+
(hf : continuous f) : continuous (λ t, (γ t).extend (f t)) :=
147+
continuous.Icc_extend hγ hf
148+
149+
/-- A useful special case of `continuous.path_extend`. -/
148150
@[continuity]
149151
lemma continuous_extend : continuous γ.extend :=
150-
γ.continuous.Icc_extend
152+
γ.continuous.Icc_extend'
153+
154+
lemma _root_.filter.tendsto.path_extend {X Y : Type*} [topological_space X] [topological_space Y]
155+
{l r : Y → X} {y : Y} {l₁ : filter ℝ} {l₂ : filter X} {γ : ∀ y, path (l y) (r y)}
156+
(hγ : tendsto ↿γ (𝓝 y ×ᶠ l₁.map (proj_Icc 0 1 zero_le_one)) l₂) :
157+
tendsto ↿(λ x, (γ x).extend) (𝓝 y ×ᶠ l₁) l₂ :=
158+
filter.tendsto.Icc_extend _ hγ
159+
160+
lemma _root_.continuous_at.path_extend {g : Y → ℝ} {l r : Y → X} (γ : ∀ y, path (l y) (r y)) {y : Y}
161+
(hγ : continuous_at ↿γ (y, proj_Icc 0 1 zero_le_one (g y)))
162+
(hg : continuous_at g y) : continuous_at (λ i, (γ i).extend (g i)) y :=
163+
hγ.Icc_extend (λ x, γ x) hg
151164

152165
@[simp] lemma extend_extends {X : Type*} [topological_space X] {a b : X}
153166
(γ : path a b) {t : ℝ} (ht : t ∈ (Icc 0 1 : set ℝ)) : γ.extend t = γ ⟨t, ht⟩ :=

src/topology/unit_interval.lean

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ Authors: Patrick Massot, Scott Morrison
55
-/
66
import topology.instances.real
77
import topology.algebra.field
8+
import data.set.intervals.proj_Icc
89

910
/-!
1011
# The unit interval, as a topological space
1112
1213
Use `open_locale unit_interval` to turn on the notation `I := set.Icc (0 : ℝ) (1 : ℝ)`.
1314
1415
We provide basic instances, as well as a custom tactic for discharging
15-
`0 ≤ x`, `0 ≤ 1 - x`, `x ≤ 1`, and `1 - x ≤ 1` when `x : I`.
16+
`0 ≤ x`, `0 ≤ 1 - x`, `x ≤ 1`, and `1 - x ≤ 1` when `x : I`.
1617
1718
-/
1819

@@ -41,14 +42,41 @@ instance has_zero : has_zero I := ⟨⟨0, by split ; norm_num⟩⟩
4142

4243
@[simp] lemma mk_zero (h : (0 : ℝ) ∈ Icc (0 : ℝ) 1) : (⟨0, h⟩ : I) = 0 := rfl
4344

45+
@[simp, norm_cast] lemma coe_eq_zero {x : I} : (x : ℝ) = 0 ↔ x = 0 :=
46+
by { symmetry, exact subtype.ext_iff }
47+
4448
instance has_one : has_one I := ⟨⟨1, by split ; norm_num⟩⟩
4549

4650
@[simp, norm_cast] lemma coe_one : ((1 : I) : ℝ) = 1 := rfl
4751

52+
lemma coe_ne_zero {x : I} : (x : ℝ) ≠ 0 ↔ x ≠ 0 :=
53+
not_iff_not.mpr coe_eq_zero
54+
4855
@[simp] lemma mk_one (h : (1 : ℝ) ∈ Icc (0 : ℝ) 1) : (⟨1, h⟩ : I) = 1 := rfl
4956

57+
@[simp, norm_cast] lemma coe_eq_one {x : I} : (x : ℝ) = 1 ↔ x = 1 :=
58+
by { symmetry, exact subtype.ext_iff }
59+
60+
lemma coe_ne_one {x : I} : (x : ℝ) ≠ 1 ↔ x ≠ 1 :=
61+
not_iff_not.mpr coe_eq_one
62+
5063
instance : nonempty I := ⟨0
5164

65+
lemma mul_mem (x y : I) : (x : ℝ) * y ∈ I :=
66+
⟨mul_nonneg x.2.1 y.2.1, (mul_le_mul x.2.2 y.2.2 y.2.1 zero_le_one).trans_eq $ one_mul 1
67+
68+
instance : has_mul I := ⟨λ x y, ⟨x * y, mul_mem x y⟩⟩
69+
70+
@[simp, norm_cast] lemma coe_mul {x y : I} : ((x * y : I) : ℝ) = x * y := rfl
71+
72+
-- todo: we could set up a `linear_ordered_comm_monoid_with_zero I` instance
73+
74+
lemma mul_le_left {x y : I} : x * y ≤ x :=
75+
subtype.coe_le_coe.mp $ (mul_le_mul_of_nonneg_left y.2.2 x.2.1).trans_eq $ mul_one x
76+
77+
lemma mul_le_right {x y : I} : x * y ≤ y :=
78+
subtype.coe_le_coe.mp $ (mul_le_mul_of_nonneg_right x.2.2 y.2.1).trans_eq $ one_mul y
79+
5280
/-- Unit interval central symmetry. -/
5381
def symm : I → I := λ t, ⟨1 - t.val, mem_iff_one_sub_mem.mp t.property⟩
5482

@@ -80,6 +108,11 @@ lemma one_minus_nonneg (x : I) : 0 ≤ 1 - (x : ℝ) := by simpa using x.2.2
80108
lemma le_one (x : I) : (x : ℝ) ≤ 1 := x.2.2
81109
lemma one_minus_le_one (x : I) : 1 - (x : ℝ) ≤ 1 := by simpa using x.2.1
82110

111+
/-- like `unit_interval.nonneg`, but with the inequality in `I`. -/
112+
lemma nonneg' {t : I} : 0 ≤ t := t.2.1
113+
/-- like `unit_interval.le_one`, but with the inequality in `I`. -/
114+
lemma le_one' {t : I} : t ≤ 1 := t.2.2
115+
83116
lemma mul_pos_mem_iff {a t : ℝ} (ha : 0 < a) : a * t ∈ I ↔ t ∈ set.Icc (0 : ℝ) (1/a) :=
84117
begin
85118
split; rintros ⟨h₁, h₂⟩; split,
@@ -94,9 +127,15 @@ by split; rintros ⟨h₁, h₂⟩; split; linarith
94127

95128
end unit_interval
96129

130+
@[simp] lemma proj_Icc_eq_zero {x : ℝ} : proj_Icc (0 : ℝ) 1 zero_le_one x = 0 ↔ x ≤ 0 :=
131+
proj_Icc_eq_left zero_lt_one
132+
133+
@[simp] lemma proj_Icc_eq_one {x : ℝ} : proj_Icc (0 : ℝ) 1 zero_le_one x = 11 ≤ x :=
134+
proj_Icc_eq_right zero_lt_one
135+
97136
namespace tactic.interactive
98137

99-
/-- A tactic that solves `0 ≤ x`, `0 ≤ 1 - x`, `x ≤ 1`, and `1 - x ≤ 1` for `x : I`. -/
138+
/-- A tactic that solves `0 ≤ x`, `0 ≤ 1 - x`, `x ≤ 1`, and `1 - x ≤ 1` for `x : I`. -/
100139
meta def unit_interval : tactic unit :=
101140
`[apply unit_interval.nonneg] <|> `[apply unit_interval.one_minus_nonneg] <|>
102141
`[apply unit_interval.le_one] <|> `[apply unit_interval.one_minus_le_one]

0 commit comments

Comments
 (0)