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

Commit d9327e4

Browse files
committed
refactor(geometry/manifold/real_instances): use fact instead of lt_class (#2521)
To define a manifold with boundary structure on the interval `[x, y]`, typeclass inference needs to know that `x < y`. This used to be provided by the introduction of a dummy class `lt_class`. The new mechanism based on `fact` makes it possible to remove this dummy class.
1 parent 2b95532 commit d9327e4

File tree

1 file changed

+28
-35
lines changed

1 file changed

+28
-35
lines changed

src/geometry/manifold/real_instances.lean

Lines changed: 28 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import linear_algebra.finite_dimensional
99
/-!
1010
# Constructing examples of manifolds over ℝ
1111
12-
We introduce the necessary bits to be able to define manifolds modelled over ℝ^n, boundaryless
12+
We introduce the necessary bits to be able to define manifolds modelled over `ℝ^n`, boundaryless
1313
or with boundary or with corners. As a concrete example, we construct explicitly the manifold with
14-
boundary structure on the real interval [x, y].
14+
boundary structure on the real interval `[x, y]`.
1515
1616
More specifically, we introduce
1717
* `euclidean_space n` for a model vector space of dimension `n`.
@@ -22,30 +22,29 @@ to define `n`-dimensional real manifolds with corners
2222
2323
## Implementation notes
2424
25-
The manifold structure on the interval [x, y] = Icc x y requires the assumption `x < y`. We
26-
introduce a dummy class `lt_class x y` for this, to make such an assumption available to typeclass
27-
search. This should hopefully not be necessary any more in Lean 4.
25+
The manifold structure on the interval `[x, y] = Icc x y` requires the assumption `x < y` as a
26+
typeclass. We provide it as `[fact (x < y)]`.
2827
-/
2928

3029
noncomputable theory
3130
open set
3231

3332
/--
34-
The space ℝ^n. Note that the name is slightly misleading, as we only need a normed space
35-
structure on ℝ^n, but the one we use here is the sup norm and not the euclidean one -- this is not
33+
The space `ℝ^n`. Note that the name is slightly misleading, as we only need a normed space
34+
structure on `ℝ^n`, but the one we use here is the sup norm and not the euclidean one -- this is not
3635
a problem for the manifold applications, but should probably be refactored at some point.
3736
-/
3837
def euclidean_space (n : ℕ) : Type := (fin n → ℝ)
3938

4039
/--
41-
The half-space in ℝ^n, used to model manifolds with boundary. We only define it when `1 ≤ n`, as the
42-
definition only makes sense in this case.
40+
The half-space in `ℝ^n`, used to model manifolds with boundary. We only define it when
41+
`1 ≤ n`, as the definition only makes sense in this case.
4342
-/
4443
def euclidean_half_space (n : ℕ) [has_zero (fin n)] : Type :=
4544
{x : euclidean_space n // 0 ≤ x 0}
4645

4746
/--
48-
The quadrant in ℝ^n, used to model manifolds with corners, made of all vectors with nonnegative
47+
The quadrant in `ℝ^n`, used to model manifolds with corners, made of all vectors with nonnegative
4948
coordinates.
5049
-/
5150
def euclidean_quadrant (n : ℕ) : Type := {x : euclidean_space n // ∀i:fin n, 0 ≤ x i}
@@ -77,7 +76,7 @@ by simp
7776
end
7877

7978
/--
80-
Definition of the model with corners (euclidean_space n, euclidean_half_space n), used as a
79+
Definition of the model with corners `(euclidean_space n, euclidean_half_space n)`, used as a
8180
model for manifolds with boundary.
8281
-/
8382
def model_with_corners_euclidean_half_space (n : ℕ) [has_zero (fin n)] :
@@ -135,7 +134,7 @@ def model_with_corners_euclidean_half_space (n : ℕ) [has_zero (fin n)] :
135134
end }
136135

137136
/--
138-
Definition of the model with corners (euclidean_space n, euclidean_quadrant n), used as a
137+
Definition of the model with corners `(euclidean_space n, euclidean_quadrant n)`, used as a
139138
model for manifolds with corners -/
140139
def model_with_corners_euclidean_quadrant (n : ℕ) :
141140
model_with_corners ℝ (euclidean_space n) (euclidean_quadrant n) :=
@@ -187,22 +186,15 @@ def model_with_corners_euclidean_quadrant (n : ℕ) :
187186
end }
188187

189188
/--
190-
Dummy class to make an assumption such as `x < y` available to typeclass search. Such an
191-
assumption is used to define a manifold structure on [x, y] when `x < y`. Should be fixed in Lean 4.
192-
-/
193-
def lt_class {α : Type*} [has_lt α] (x y : α) : Prop := x < y
194-
attribute [class] lt_class
195-
196-
/--
197-
The left chart for the topological space [x, y], defined on [x,y) and sending x to 0 in
189+
The left chart for the topological space `[x, y]`, defined on `[x,y)` and sending `x` to `0` in
198190
`euclidean_half_space 1`.
199191
-/
200-
def Icc_left_chart (x y : ℝ) [h : lt_class x y] :
192+
def Icc_left_chart (x y : ℝ) [fact (x < y)] :
201193
local_homeomorph (Icc x y) (euclidean_half_space 1) :=
202194
{ source := {z : Icc x y | z.val < y},
203195
target := {z : euclidean_half_space 1 | z.val 0 < y - x},
204196
to_fun := λ(z : Icc x y), ⟨λi, z.val - x, sub_nonneg.mpr z.property.1⟩,
205-
inv_fun := λz, ⟨min (z.val 0 + x) y, by simp [le_refl, z.property, le_of_lt h]⟩,
197+
inv_fun := λz, ⟨min (z.val 0 + x) y, by simp [le_refl, z.property, le_of_lt ‹x < y›]⟩,
206198
map_source := by simp,
207199
map_target := by { simp, assume z hz, left, linarith },
208200
left_inv := by { rintros ⟨z, hz⟩ h'z, simp at hz h'z, simp [hz, h'z] },
@@ -242,15 +234,16 @@ def Icc_left_chart (x y : ℝ) [h : lt_class x y] :
242234
end }
243235

244236
/--
245-
The right chart for the topological space [x, y], defined on (x,y] and sending y to 0 in
237+
The right chart for the topological space `[x, y]`, defined on `(x,y]` and sending `y` to `0` in
246238
`euclidean_half_space 1`.
247239
-/
248-
def Icc_right_chart (x y : ℝ) [h : lt_class x y] :
240+
def Icc_right_chart (x y : ℝ) [fact (x < y)] :
249241
local_homeomorph (Icc x y) (euclidean_half_space 1) :=
250242
{ source := {z : Icc x y | x < z.val},
251243
target := {z : euclidean_half_space 1 | z.val 0 < y - x},
252244
to_fun := λ(z : Icc x y), ⟨λi, y - z.val, sub_nonneg.mpr z.property.2⟩,
253-
inv_fun := λz, ⟨max (y - z.val 0) x, by simp [le_refl, z.property, le_of_lt h, sub_eq_add_neg]⟩,
245+
inv_fun := λz,
246+
⟨max (y - z.val 0) x, by simp [le_refl, z.property, le_of_lt ‹x < y›, sub_eq_add_neg]⟩,
254247
map_source := by simp,
255248
map_target := by { simp, assume z hz, left, linarith },
256249
left_inv := by { rintros ⟨z, hz⟩ h'z, simp at hz h'z, simp [hz, h'z, sub_eq_add_neg] },
@@ -290,25 +283,25 @@ def Icc_right_chart (x y : ℝ) [h : lt_class x y] :
290283
end }
291284

292285
/--
293-
Manifold with boundary structure on [x, y], using only two charts.
286+
Manifold with boundary structure on `[x, y]`, using only two charts.
294287
-/
295-
instance Icc_manifold (x y : ℝ) [h : lt_class x y] : manifold (euclidean_half_space 1) (Icc x y) :=
288+
instance Icc_manifold (x y : ℝ) [fact (x < y)] : manifold (euclidean_half_space 1) (Icc x y) :=
296289
{ atlas := {Icc_left_chart x y, Icc_right_chart x y},
297290
chart_at := λz, if z.val < y then Icc_left_chart x y else Icc_right_chart x y,
298291
mem_chart_source := λz, begin
299292
by_cases h' : z.val < y,
300293
{ simp only [h', if_true],
301294
exact h' },
302295
{ simp only [h', if_false],
303-
apply lt_of_lt_of_le h,
296+
apply lt_of_lt_of_le ‹x < y›,
304297
simpa using h' }
305298
end,
306299
chart_mem_atlas := λz, by { by_cases h' : z.val < y; simp [h'] } }
307300

308301
/--
309-
The manifold structure on [x, y] is smooth.
302+
The manifold structure on `[x, y]` is smooth.
310303
-/
311-
instance Icc_smooth_manifold (x y : ℝ) [lt_class x y] :
304+
instance Icc_smooth_manifold (x y : ℝ) [fact (x < y)] :
312305
smooth_manifold_with_corners (model_with_corners_euclidean_half_space 1) (Icc x y) :=
313306
begin
314307
have M : times_cont_diff_on ℝ ⊤ (λz : fin 1 → ℝ, (λi : fin 1, y - x) - z) univ,
@@ -320,14 +313,14 @@ begin
320313
apply has_groupoid_of_pregroupoid,
321314
assume e e' he he',
322315
simp [atlas] at he he',
323-
/- We need to check that any composition of two charts gives a C^∞ function. Each chart can be
316+
/- We need to check that any composition of two charts gives a `C^∞` function. Each chart can be
324317
either the left chart or the right chart, leaving 4 possibilities that we handle successively.
325318
-/
326319
rcases he with rfl | rfl; rcases he' with rfl | rfl,
327-
{ -- e = right chart, e' = right chart
320+
{ -- `e = right chart`, `e' = right chart`
328321
refine ((mem_groupoid_of_pregroupoid _ _).mpr _).1,
329322
exact symm_trans_mem_times_cont_diff_groupoid _ _ _ },
330-
{ -- e = right chart, e' = left chart
323+
{ -- `e = right chart`, `e' = left chart`
331324
apply M.congr_mono _ (subset_univ _),
332325
assume z hz,
333326
simp [-mem_range, range_half_space, model_with_corners_euclidean_half_space,
@@ -338,7 +331,7 @@ begin
338331
rw subsingleton.elim i 0,
339332
simp [model_with_corners_euclidean_half_space, Icc_left_chart, Icc_right_chart, A, B,
340333
sub_right_comm y] },
341-
{ -- e = left chart, e' = right chart
334+
{ -- `e = left chart`, `e' = right chart`
342335
apply M.congr_mono _ (subset_univ _),
343336
assume z hz,
344337
simp [-mem_range, range_half_space, model_with_corners_euclidean_half_space,
@@ -349,7 +342,7 @@ begin
349342
rw subsingleton.elim i 0,
350343
simp [model_with_corners_euclidean_half_space, Icc_left_chart, Icc_right_chart, A, B,
351344
sub_add_eq_sub_sub_swap] },
352-
{ -- e = left chart, e' = left chart
345+
{ -- `e = left chart`, `e' = left chart`
353346
refine ((mem_groupoid_of_pregroupoid _ _).mpr _).1,
354347
exact symm_trans_mem_times_cont_diff_groupoid _ _ _ }
355348
end,

0 commit comments

Comments
 (0)