Skip to content

Commit b26977f

Browse files
sgouezelgrunweg
andcommitted
feat: require that the range of a real or complex model with corners is convex (#25824)
This is important to ensure that the distance coming from a Riemannian metric generates the same topology as the original one. See Zulip discussion at [#mathlib4 > Fixing the definition of models with corners @ 💬](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Fixing.20the.20definition.20of.20models.20with.20corners/near/522572964) Co-authored-by: Michael Rothgang <rothgang@math.uni-bonn.de>
1 parent 7f78223 commit b26977f

File tree

3 files changed

+181
-63
lines changed

3 files changed

+181
-63
lines changed

Mathlib/Geometry/Manifold/Diffeomorph.lean

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -399,16 +399,25 @@ variable (I) (e : E ≃L[𝕜] E')
399399
def transContinuousLinearEquiv : ModelWithCorners 𝕜 E' H where
400400
toPartialEquiv := I.toPartialEquiv.trans e.toEquiv.toPartialEquiv
401401
source_eq := by simp
402-
uniqueDiffOn' := by simp [I.uniqueDiffOn]
403-
target_subset_closure_interior := by
404-
simp only [PartialEquiv.trans_target, Equiv.toPartialEquiv_target,
405-
Equiv.toPartialEquiv_symm_apply, target_eq, univ_inter]
406-
change e.toHomeomorph.symm ⁻¹' _ ⊆ closure (interior (e.toHomeomorph.symm ⁻¹' (range I)))
407-
rw [← e.toHomeomorph.symm.isOpenMap.preimage_interior_eq_interior_preimage
408-
e.toHomeomorph.continuous_symm,
409-
← e.toHomeomorph.symm.isOpenMap.preimage_closure_eq_closure_preimage
410-
e.toHomeomorph.continuous_symm]
411-
exact preimage_mono I.range_subset_closure_interior
402+
convex_range' := by
403+
split_ifs with h
404+
· simp only [PartialEquiv.coe_trans, Equiv.toPartialEquiv_apply, LinearEquiv.coe_toEquiv,
405+
ContinuousLinearEquiv.coe_toLinearEquiv, toPartialEquiv_coe]
406+
rw [range_comp]
407+
letI := h.rclike
408+
letI := NormedSpace.restrictScalars ℝ 𝕜 E
409+
letI := NormedSpace.restrictScalars ℝ 𝕜 E'
410+
let eR : E →L[ℝ] E' := ContinuousLinearMap.restrictScalars ℝ (e : E →L[𝕜] E')
411+
change Convex ℝ (⇑eR '' range ↑I)
412+
apply I.convex_range.linear_image
413+
· simp [range_eq_univ_of_not_isRCLikeNormedField I h, range_comp]
414+
nonempty_interior' := by
415+
simp only [PartialEquiv.coe_trans, Equiv.toPartialEquiv_apply, LinearEquiv.coe_toEquiv,
416+
ContinuousLinearEquiv.coe_toLinearEquiv, toPartialEquiv_coe, range_comp,
417+
ContinuousLinearEquiv.image_eq_preimage]
418+
apply Nonempty.mono (preimage_interior_subset_interior_preimage e.symm.continuous)
419+
rw [← ContinuousLinearEquiv.image_eq_preimage]
420+
simpa using I.nonempty_interior
412421
continuous_toFun := e.continuous.comp I.continuous
413422
continuous_invFun := I.continuous_symm.comp e.symm.continuous
414423

Mathlib/Geometry/Manifold/Instances/Real.lean

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ noncomputable section
4646

4747
open Set Function
4848

49-
open scoped Manifold ContDiff
49+
open scoped Manifold ContDiff ENNReal
5050

5151
/-- The half-space in `ℝ^n`, used to model manifolds with boundary. We only define it when
5252
`1 ≤ n`, as the definition only makes sense in this case.
@@ -115,10 +115,9 @@ instance : LocPathConnectedSpace (EuclideanQuadrant n) :=
115115
EuclideanQuadrant.convex.locPathConnectedSpace
116116

117117
theorem range_euclideanHalfSpace (n : ℕ) [NeZero n] :
118-
(range fun x : EuclideanHalfSpace n => x.val) = { y | 0 ≤ y 0 } :=
118+
range (Subtype.val : EuclideanHalfSpace n → _) = { y | 0 ≤ y 0 } :=
119119
Subtype.range_val
120120

121-
open ENNReal in
122121
@[simp]
123122
theorem interior_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) :
124123
interior { y : PiLp p (fun _ : Fin n ↦ ℝ) | a ≤ y i } = { y | a < y i } := by
@@ -129,7 +128,6 @@ theorem interior_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) :
129128

130129
@[deprecated (since := "2024-11-12")] alias interior_halfspace := interior_halfSpace
131130

132-
open ENNReal in
133131
@[simp]
134132
theorem closure_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) :
135133
closure { y : PiLp p (fun _ : Fin n ↦ ℝ) | a ≤ y i } = { y | a ≤ y i } := by
@@ -140,7 +138,6 @@ theorem closure_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) :
140138

141139
@[deprecated (since := "2024-11-12")] alias closure_halfspace := closure_halfSpace
142140

143-
open ENNReal in
144141
@[simp]
145142
theorem closure_open_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) :
146143
closure { y : PiLp p (fun _ : Fin n ↦ ℝ) | a < y i } = { y | a ≤ y i } := by
@@ -151,7 +148,6 @@ theorem closure_open_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n)
151148

152149
@[deprecated (since := "2024-11-12")] alias closure_open_halfspace := closure_open_halfSpace
153150

154-
open ENNReal in
155151
@[simp]
156152
theorem frontier_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) :
157153
frontier { y : PiLp p (fun _ : Fin n ↦ ℝ) | a ≤ y i } = { y | a = y i } := by
@@ -161,9 +157,22 @@ theorem frontier_halfSpace {n : ℕ} (p : ℝ≥0∞) (a : ℝ) (i : Fin n) :
161157
@[deprecated (since := "2024-11-12")] alias frontier_halfspace := frontier_halfSpace
162158

163159
theorem range_euclideanQuadrant (n : ℕ) :
164-
(range fun x : EuclideanQuadrant n => x.val) = { y | ∀ i : Fin n, 0 ≤ y i } :=
160+
range (Subtype.val : EuclideanQuadrant n → _) = { y | ∀ i : Fin n, 0 ≤ y i } :=
165161
Subtype.range_val
166162

163+
theorem interior_euclideanQuadrant (n : ℕ) (p : ℝ≥0∞) (a : ℝ) :
164+
interior { y : PiLp p (fun _ : Fin n ↦ ℝ) | ∀ i : Fin n, a ≤ y i } =
165+
{ y | ∀ i : Fin n, a < y i } := by
166+
let f : Fin n → (Π _ : Fin n, ℝ) →L[ℝ] ℝ := fun i ↦ ContinuousLinearMap.proj i
167+
have h : { y : PiLp p (fun _ : Fin n ↦ ℝ) | ∀ i : Fin n, a ≤ y i } = ⋂ i, (f i )⁻¹' Ici a := by
168+
ext; simp; rfl
169+
have h' : { y : PiLp p (fun _ : Fin n ↦ ℝ) | ∀ i : Fin n, a < y i } = ⋂ i, (f i )⁻¹' Ioi a := by
170+
ext; simp; rfl
171+
rw [h, h', interior_iInter_of_finite]
172+
apply iInter_congr fun i ↦ ?_
173+
rw [(f i).interior_preimage, interior_Ici]
174+
apply Function.surjective_eval
175+
167176
end
168177

169178
/--
@@ -183,12 +192,14 @@ def modelWithCornersEuclideanHalfSpace (n : ℕ) [NeZero n] :
183192
exact ⟨max_eq_left xprop, fun i _ => rfl⟩
184193
right_inv' _ hx := update_eq_iff.2 ⟨max_eq_left hx, fun _ _ => rfl⟩
185194
source_eq := rfl
186-
uniqueDiffOn' := by
187-
have : UniqueDiffOn ℝ _ :=
188-
UniqueDiffOn.pi (Fin n) (fun _ => ℝ) _ _ fun i (_ : i ∈ ({0} : Set (Fin n))) =>
189-
uniqueDiffOn_Ici 0
190-
simpa only [singleton_pi] using this
191-
target_subset_closure_interior := by simp
195+
convex_range' := by
196+
simp only [instIsRCLikeNormedField, ↓reduceDIte]
197+
apply Convex.convex_isRCLikeNormedField
198+
rw [range_euclideanHalfSpace n]
199+
exact EuclideanHalfSpace.convex (n := n)
200+
nonempty_interior' := by
201+
rw [range_euclideanHalfSpace, interior_halfSpace]
202+
refine ⟨fun i ↦ 1, by simp⟩
192203
continuous_toFun := continuous_subtype_val
193204
continuous_invFun := by
194205
exact (continuous_id.update 0 <| (continuous_apply 0).max continuous_const).subtype_mk _
@@ -207,16 +218,14 @@ def modelWithCornersEuclideanQuadrant (n : ℕ) :
207218
left_inv' x _ := by ext i; simp only [x.2 i, max_eq_left]
208219
right_inv' x hx := by ext1 i; simp only [hx i, max_eq_left]
209220
source_eq := rfl
210-
uniqueDiffOn' := by
211-
have this : UniqueDiffOn ℝ _ :=
212-
UniqueDiffOn.univ_pi (Fin n) (fun _ => ℝ) _ fun _ => uniqueDiffOn_Ici 0
213-
simpa only [pi_univ_Ici] using this
214-
target_subset_closure_interior := by
215-
have : {x : EuclideanSpace ℝ (Fin n) | ∀ (i : Fin n), 0 ≤ x i}
216-
= Set.pi univ (fun i ↦ Ici 0) := by aesop
217-
simp only [this, interior_pi_set finite_univ]
218-
rw [closure_pi_set]
219-
simp
221+
convex_range' := by
222+
simp only [instIsRCLikeNormedField, ↓reduceDIte]
223+
apply Convex.convex_isRCLikeNormedField
224+
rw [range_euclideanQuadrant]
225+
exact EuclideanQuadrant.convex
226+
nonempty_interior' := by
227+
rw [range_euclideanQuadrant, interior_euclideanQuadrant]
228+
exact ⟨fun i ↦ 1, by simp⟩
220229
continuous_toFun := continuous_subtype_val
221230
continuous_invFun := Continuous.subtype_mk
222231
(continuous_pi fun i => (continuous_id.max continuous_const).comp (continuous_apply i)) _
@@ -505,7 +514,6 @@ section
505514

506515
instance : ChartedSpace (EuclideanHalfSpace 1) (Icc (0 : ℝ) 1) := by infer_instance
507516

508-
instance {n : WithTop ℕ∞} : IsManifold (𝓡∂ 1) n (Icc (0 : ℝ) 1) := by
509-
infer_instance
517+
instance {n : WithTop ℕ∞} : IsManifold (𝓡∂ 1) n (Icc (0 : ℝ) 1) := by infer_instance
510518

511519
end

Mathlib/Geometry/Manifold/IsManifold/Basic.lean

Lines changed: 129 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Sébastien Gouëzel
55
-/
66
import Mathlib.Analysis.Calculus.ContDiff.Operations
77
import Mathlib.Analysis.Normed.Module.Convex
8+
import Mathlib.Analysis.RCLike.TangentCone
89
import Mathlib.Data.Bundle
910
import Mathlib.Geometry.Manifold.ChartedSpace
1011

@@ -135,39 +136,62 @@ open scoped Manifold Topology ContDiff
135136

136137
/-! ### Models with corners. -/
137138

138-
139+
open scoped Classical in
139140
/-- A structure containing information on the way a space `H` embeds in a
140141
model vector space `E` over the field `𝕜`. This is all what is needed to
141142
define a `C^n` manifold with model space `H`, and model vector space `E`.
142143
143-
We require two conditions `uniqueDiffOn'` and `target_subset_closure_interior`, which
144-
are satisfied in the relevant cases (where `range I = univ` or a half space or a quadrant) and
145-
useful for technical reasons. The former makes sure that manifold derivatives are uniquely
146-
defined, the latter ensures that for `C^2` maps the second derivatives are symmetric even for points
147-
on the boundary, as these are limit points of interior points where symmetry holds. If further
148-
conditions turn out to be useful, they can be added here.
144+
We require that, when the field is `ℝ` or `ℂ`, the range is `ℝ`-convex, as this is what is needed
145+
to do calculus and covers the standard examples of manifolds with boundary. Over other fields,
146+
we require that the range is `univ`, as there is no relevant notion of manifold of boundary there.
149147
-/
150148
@[ext]
151149
structure ModelWithCorners (𝕜 : Type*) [NontriviallyNormedField 𝕜] (E : Type*)
152150
[NormedAddCommGroup E] [NormedSpace 𝕜 E] (H : Type*) [TopologicalSpace H] extends
153151
PartialEquiv H E where
154152
source_eq : source = univ
155-
uniqueDiffOn' : UniqueDiffOn 𝕜 toPartialEquiv.target
156-
target_subset_closure_interior : toPartialEquiv.target ⊆ closure (interior toPartialEquiv.target)
153+
/-- To check this condition when the space already has a real normed space structure,
154+
use `Convex.convex_isRCLikeNormedField` which eliminates the `letI`s below, or the constructor
155+
`ModelWithCorners.of_convex_range` -/
156+
convex_range' :
157+
if h : IsRCLikeNormedField 𝕜 then
158+
letI := h.rclike 𝕜;
159+
letI : NormedSpace ℝ E := NormedSpace.restrictScalars ℝ 𝕜 E
160+
Convex ℝ (range toPartialEquiv)
161+
else range toPartialEquiv = univ
162+
nonempty_interior' : (interior (range toPartialEquiv)).Nonempty
157163
continuous_toFun : Continuous toFun := by continuity
158164
continuous_invFun : Continuous invFun := by continuity
159165

166+
lemma ModelWithCorners.range_eq_target {𝕜 E H : Type*} [NontriviallyNormedField 𝕜]
167+
[NormedAddCommGroup E] [NormedSpace 𝕜 E] [TopologicalSpace H] (I : ModelWithCorners 𝕜 E H) :
168+
range I.toPartialEquiv = I.target := by
169+
rw [← I.image_source_eq_target, I.source_eq, image_univ.symm]
170+
171+
/-- If a model with corners has full range, the `convex_range'` condition is satisfied. -/
172+
def ModelWithCorners.of_target_univ (𝕜 : Type*) [NontriviallyNormedField 𝕜]
173+
{E : Type*} [NormedAddCommGroup E] [NormedSpace 𝕜 E] {H : Type*} [TopologicalSpace H]
174+
(φ : PartialEquiv H E) (hsource : φ.source = univ) (htarget : φ.target = univ)
175+
(hcont : Continuous φ) (hcont_inv : Continuous φ.symm) : ModelWithCorners 𝕜 E H where
176+
toPartialEquiv := φ
177+
source_eq := hsource
178+
convex_range' := by
179+
have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm]
180+
simp only [this, htarget, dite_else_true]
181+
intro h
182+
letI := h.rclike 𝕜
183+
letI := NormedSpace.restrictScalars ℝ 𝕜 E
184+
exact convex_univ
185+
nonempty_interior' := by
186+
have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm]
187+
simp [this, htarget]
188+
160189
attribute [simp, mfld_simps] ModelWithCorners.source_eq
161190

162191
/-- A vector space is a model with corners, denoted as `𝓘(𝕜, E)` within the `Manifold` namespace. -/
163192
def modelWithCornersSelf (𝕜 : Type*) [NontriviallyNormedField 𝕜] (E : Type*)
164-
[NormedAddCommGroup E] [NormedSpace 𝕜 E] : ModelWithCorners 𝕜 E E where
165-
toPartialEquiv := PartialEquiv.refl E
166-
source_eq := rfl
167-
uniqueDiffOn' := uniqueDiffOn_univ
168-
target_subset_closure_interior := by simp
169-
continuous_toFun := continuous_id
170-
continuous_invFun := continuous_id
193+
[NormedAddCommGroup E] [NormedSpace 𝕜 E] : ModelWithCorners 𝕜 E E :=
194+
ModelWithCorners.of_target_univ 𝕜 (PartialEquiv.refl E) rfl rfl continuous_id continuous_id
171195

172196
@[inherit_doc] scoped[Manifold] notation "𝓘(" 𝕜 ", " E ")" => modelWithCornersSelf 𝕜 E
173197

@@ -252,12 +276,76 @@ theorem target_eq : I.target = range (I : H → E) := by
252276
rw [← image_univ, ← I.source_eq]
253277
exact I.image_source_eq_target.symm
254278

255-
protected theorem uniqueDiffOn : UniqueDiffOn 𝕜 (range I) :=
256-
I.target_eq ▸ I.uniqueDiffOn'
279+
theorem nonempty_interior : (interior (range I)).Nonempty :=
280+
I.nonempty_interior'
281+
282+
theorem range_eq_univ_of_not_isRCLikeNormedField (h : ¬ IsRCLikeNormedField 𝕜) :
283+
range I = univ := by
284+
simpa [h] using I.convex_range'
285+
286+
/-- If a set is `ℝ`-convex for some normed space structure, then it is `ℝ`-convex for the
287+
normed space structure coming from an `IsRCLikeNormedField 𝕜`. Useful when constructing model
288+
spaces to avoid diamond issues when populating the field `convex_range'`. -/
289+
lemma _root_.Convex.convex_isRCLikeNormedField [NormedSpace ℝ E] [h : IsRCLikeNormedField 𝕜]
290+
{s : Set E} (hs : Convex ℝ s) :
291+
letI := h.rclike
292+
letI := NormedSpace.restrictScalars ℝ 𝕜 E
293+
Convex ℝ s := by
294+
letI := h.rclike
295+
letI := NormedSpace.restrictScalars ℝ 𝕜 E
296+
simp only [Convex, StarConvex] at hs ⊢
297+
intro u hu v hv a b ha hb hab
298+
convert hs hu hv ha hb hab using 2
299+
· rw [← @algebraMap_smul (R := ℝ) (A := 𝕜), ← @algebraMap_smul (R := ℝ) (A := 𝕜)]
300+
· rw [← @algebraMap_smul (R := ℝ) (A := 𝕜), ← @algebraMap_smul (R := ℝ) (A := 𝕜)]
301+
302+
/-- Construct a model with corners over `ℝ` from a continuous partial equiv with convex range. -/
303+
def of_convex_range
304+
{E : Type*} [NormedAddCommGroup E] [NormedSpace ℝ E] {H : Type*} [TopologicalSpace H]
305+
(φ : PartialEquiv H E) (hsource : φ.source = univ) (htarget : Convex ℝ φ.target)
306+
(hcont : Continuous φ) (hcont_inv : Continuous φ.symm) (hint : (interior φ.target).Nonempty) :
307+
ModelWithCorners ℝ E H where
308+
toPartialEquiv := φ
309+
source_eq := hsource
310+
convex_range' := by
311+
have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm]
312+
simp only [instIsRCLikeNormedField, ↓reduceDIte, this]
313+
exact htarget.convex_isRCLikeNormedField
314+
nonempty_interior' := by
315+
have : range φ = φ.target := by rw [← φ.image_source_eq_target, hsource, image_univ.symm]
316+
simp [this, htarget, hint]
317+
318+
theorem convex_range [NormedSpace ℝ E] : Convex ℝ (range I) := by
319+
by_cases h : IsRCLikeNormedField 𝕜
320+
· letI : RCLike 𝕜 := h.rclike
321+
have W := I.convex_range'
322+
simp only [h, ↓reduceDIte, toPartialEquiv_coe] at W
323+
simp only [Convex, StarConvex] at W ⊢
324+
intro u hu v hv a b ha hb hab
325+
convert W hu hv ha hb hab using 2
326+
· rw [← @algebraMap_smul (R := ℝ) (A := 𝕜)]
327+
rfl
328+
· rw [← @algebraMap_smul (R := ℝ) (A := 𝕜)]
329+
rfl
330+
· simp [range_eq_univ_of_not_isRCLikeNormedField I h, convex_univ]
331+
332+
protected theorem uniqueDiffOn : UniqueDiffOn 𝕜 (range I) := by
333+
by_cases h : IsRCLikeNormedField 𝕜
334+
· letI := h.rclike 𝕜;
335+
letI := NormedSpace.restrictScalars ℝ 𝕜 E
336+
apply uniqueDiffOn_convex_of_isRCLikeNormedField _ I.nonempty_interior
337+
simpa [h] using I.convex_range
338+
· simp [range_eq_univ_of_not_isRCLikeNormedField I h, uniqueDiffOn_univ]
257339

258340
theorem range_subset_closure_interior : range I ⊆ closure (interior (range I)) := by
259-
rw [← I.target_eq]
260-
exact I.target_subset_closure_interior
341+
by_cases h : IsRCLikeNormedField 𝕜
342+
· letI := h.rclike 𝕜
343+
letI := NormedSpace.restrictScalars ℝ 𝕜 E
344+
rw [Convex.closure_interior_eq_closure_of_nonempty_interior (𝕜 := ℝ)]
345+
· apply subset_closure
346+
· apply I.convex_range
347+
· apply I.nonempty_interior
348+
· simp [range_eq_univ_of_not_isRCLikeNormedField I h]
261349

262350
@[simp, mfld_simps]
263351
protected theorem left_inv (x : H) : I.symm (I x) = x := by refine I.left_inv' ?_; simp
@@ -398,10 +486,17 @@ def ModelWithCorners.prod {𝕜 : Type u} [NontriviallyNormedField 𝕜] {E : Ty
398486
invFun := fun x => (I.symm x.1, I'.symm x.2)
399487
source := { x | x.1 ∈ I.source ∧ x.2 ∈ I'.source }
400488
source_eq := by simp only [setOf_true, mfld_simps]
401-
uniqueDiffOn' := I.uniqueDiffOn'.prod I'.uniqueDiffOn'
402-
target_subset_closure_interior := by
403-
simp only [PartialEquiv.prod_target, target_eq, interior_prod_eq, closure_prod_eq]
404-
exact Set.prod_mono I.range_subset_closure_interior I'.range_subset_closure_interior
489+
convex_range' := by
490+
have : range (fun (x : ModelProd H H') ↦ (I x.1, I' x.2)) = range (Prod.map I I') := rfl
491+
rw [this, Set.range_prodMap]
492+
split_ifs with h
493+
· letI := h.rclike;
494+
letI := NormedSpace.restrictScalars ℝ 𝕜 E; letI := NormedSpace.restrictScalars ℝ 𝕜 E'
495+
exact I.convex_range.prod I'.convex_range
496+
· simp [range_eq_univ_of_not_isRCLikeNormedField, h]
497+
nonempty_interior' := by
498+
have : range (fun (x : ModelProd H H') ↦ (I x.1, I' x.2)) = range (Prod.map I I') := rfl
499+
simp [this, interior_prod_eq, nonempty_interior]
405500
continuous_toFun := I.continuous_toFun.prodMap I'.continuous_toFun
406501
continuous_invFun := I.continuous_invFun.prodMap I'.continuous_invFun }
407502

@@ -414,10 +509,16 @@ def ModelWithCorners.pi {𝕜 : Type u} [NontriviallyNormedField 𝕜] {ι : Typ
414509
ModelWithCorners 𝕜 (∀ i, E i) (ModelPi H) where
415510
toPartialEquiv := PartialEquiv.pi fun i => (I i).toPartialEquiv
416511
source_eq := by simp only [pi_univ, mfld_simps]
417-
uniqueDiffOn' := UniqueDiffOn.pi ι E _ _ fun i _ => (I i).uniqueDiffOn'
418-
target_subset_closure_interior := by
419-
simp only [PartialEquiv.pi_target, target_eq, finite_univ, interior_pi_set, closure_pi_set]
420-
exact Set.pi_mono (fun i _ ↦ (I i).range_subset_closure_interior)
512+
convex_range' := by
513+
rw [PartialEquiv.pi_apply, Set.range_piMap]
514+
split_ifs with h
515+
· letI := h.rclike;
516+
letI := fun i ↦ NormedSpace.restrictScalars ℝ 𝕜 (E i);
517+
exact convex_pi fun i _hi ↦ (I i).convex_range
518+
· simp [range_eq_univ_of_not_isRCLikeNormedField, h]
519+
nonempty_interior' := by
520+
rw [PartialEquiv.pi_apply, Set.range_piMap]
521+
simp [interior_pi_set finite_univ, univ_pi_nonempty_iff, nonempty_interior]
421522
continuous_toFun := continuous_pi fun i => (I i).continuous.comp (continuous_apply i)
422523
continuous_invFun := continuous_pi fun i => (I i).continuous_symm.comp (continuous_apply i)
423524

0 commit comments

Comments
 (0)