diff --git a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean index cc31a4c1053e2d..39075d78ecd526 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/ExtChartAt.lean @@ -370,6 +370,61 @@ theorem contDiffWithinAt_extend_coord_change' [ChartedSpace H M] (hf : f โˆˆ max end OpenPartialHomeomorph +namespace ModelWithCorners + +/-- The change of charts from `e` to `e'` in the model vector space `E`. -/ +@[simps!] +def extCoordChange (e e' : OpenPartialHomeomorph M H) : PartialEquiv E E := + (e.extend I).symm.trans (e'.extend I) + +variable {e e' : OpenPartialHomeomorph M H} + +lemma extCoordChange_symm : (I.extCoordChange e e').symm = I.extCoordChange e' e := by + rfl + +lemma uniqueDiffOn_extCoordChange_source : UniqueDiffOn ๐•œ (I.extCoordChange e e').source := by + rw [extCoordChange_source, inter_assoc, inter_comm, preimage_comp, โ† preimage_inter] + exact I.uniqueDiffOn_preimage <| e.isOpen_inter_preimage_symm e'.open_source + +lemma uniqueDiffOn_extCoordChange_target : UniqueDiffOn ๐•œ (I.extCoordChange e e').target := by + rw [โ† extCoordChange_symm, PartialEquiv.symm_target] + exact uniqueDiffOn_extCoordChange_source + +variable [ChartedSpace H M] {n : WithTop โ„•โˆž} + +lemma contDiffOn_extCoordChange (he : e โˆˆ IsManifold.maximalAtlas I n M) + (he' : e' โˆˆ IsManifold.maximalAtlas I n M) : + ContDiffOn ๐•œ n (I.extCoordChange e e') (I.extCoordChange e e').source := + e'.contDiffOn_extend_coord_change he' he + +lemma contDiffOn_extCoordChange_symm (he : e โˆˆ IsManifold.maximalAtlas I n M) + (he' : e' โˆˆ IsManifold.maximalAtlas I n M) : + ContDiffOn ๐•œ n (I.extCoordChange e e').symm (I.extCoordChange e e').target := + e.contDiffOn_extend_coord_change he he' + +lemma isInvertible_fderivWithin_extCoordChange (hn : n โ‰  0) (he : e โˆˆ IsManifold.maximalAtlas I n M) + (he' : e' โˆˆ IsManifold.maximalAtlas I n M) {x : E} (hx : x โˆˆ (I.extCoordChange e e').source) : + (fderivWithin ๐•œ (I.extCoordChange e e') (I.extCoordChange e e').source x).IsInvertible := by + set ฯ† := I.extCoordChange e e' + have hฯ† : ContDiffOn ๐•œ n ฯ† ฯ†.source := I.contDiffOn_extCoordChange he he' + have hฯ†' : ContDiffOn ๐•œ n ฯ†.symm ฯ†.target := I.contDiffOn_extCoordChange_symm he he' + refine .of_inverse (g := (fderivWithin ๐•œ ฯ†.symm ฯ†.target (ฯ† x))) ?_ ?_ + ยท rw [โ† ฯ†.left_inv hx, ฯ†.right_inv (ฯ†.map_source hx), โ† fderivWithin_comp, + fderivWithin_congr' ฯ†.rightInvOn.eqOn (ฯ†.map_source hx), fderivWithin_id] + ยท exact I.uniqueDiffOn_extCoordChange_source _ (ฯ†.map_source hx) + ยท exact (ฯ†.left_inv hx โ–ธ ((hฯ† _ hx).differentiableWithinAt hn):) + ยท exact (hฯ†' _ (ฯ†.map_source hx)).differentiableWithinAt hn + ยท exact ฯ†.symm_mapsTo + ยท exact I.uniqueDiffOn_extCoordChange_source _ (ฯ†.map_source hx) + ยท rw [โ† fderivWithin_comp, fderivWithin_congr' ฯ†.leftInvOn.eqOn hx, fderivWithin_id] + ยท exact I.uniqueDiffOn_extCoordChange_source _ hx + ยท exact (hฯ†' _ (ฯ†.map_source hx)).differentiableWithinAt hn + ยท exact (hฯ† _ hx).differentiableWithinAt hn + ยท exact ฯ†.mapsTo + ยท exact I.uniqueDiffOn_extCoordChange_source _ hx + +end ModelWithCorners + open OpenPartialHomeomorph variable [ChartedSpace H M] [ChartedSpace H' M'] diff --git a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean index 791ab7b7cbcfd7..f13142de6c229f 100644 --- a/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean +++ b/Mathlib/Geometry/Manifold/IsManifold/InteriorBoundary.lean @@ -1,12 +1,15 @@ /- Copyright (c) 2023 Michael Rothgang. All rights reserved. Released under Apache 2.0 license as described in the file LICENSE. -Authors: Michael Rothgang +Authors: Michael Rothgang, Ben Eltschig -/ module public import Mathlib.Geometry.Manifold.IsManifold.ExtChartAt +import Mathlib.Analysis.Calculus.LocalExtr.Basic +import Mathlib.Analysis.LocallyConvex.Separation + /-! # Interior and boundary of a manifold Define the interior and boundary of a manifold. @@ -25,6 +28,12 @@ Define the interior and boundary of a manifold. - `ModelWithCorners.Boundaryless.boundary_eq_empty` and `of_boundary_eq_empty`: `M` is boundaryless if and only if its boundary is empty +- `isInteriorPoint_iff_of_mem_atlas`: a point is an interior point iff any given chart around it + sends it to the interior of the model; that is, the notion of interior is independent of choices + of charts +- `ModelWithCorners.isOpen_interior`, `ModelWithCorners.isClosed_boundary`: the interior is open and + and the boundary is closed. This is currently only proven for Cยน manifolds. + - `ModelWithCorners.interior_open`: the interior of `u : Opens M` is the preimage of the interior of `M` under the inclusion - `ModelWithCorners.boundary_open`: the boundary of `u : Opens M` is the preimage of the boundary @@ -47,15 +56,14 @@ of `M` and `N`. manifold, interior, boundary ## TODO -- `x` is an interior point iff *any* chart around `x` maps it to `interior (range I)`; -similarly for the boundary. -- the interior of `M` is open, hence the boundary is closed (and nowhere dense) - In finite dimensions, this requires e.g. the homology of spheres. -- the interior of `M` is a manifold without boundary +- the interior of `M` is dense, the boundary nowhere dense +- the interior of `M` is a boundaryless manifold - `boundary M` is a submanifold (possibly with boundary and corners): -follows from the corresponding statement for the model with corners `I`; -this requires a definition of submanifolds + follows from the corresponding statement for the model with corners `I`; + this requires a definition of submanifolds - if `M` is finite-dimensional, its boundary has measure zero +- generalise lemmas about Cยน manifolds with boundary to also hold for finite-dimensional topological + manifolds; this will require e.g. the homology of spheres. -/ @@ -73,12 +81,12 @@ variable {๐•œ : Type*} [NontriviallyNormedField ๐•œ] namespace ModelWithCorners variable (I) in -/-- `p โˆˆ M` is an interior point of a manifold `M` iff its image in the extended chart +/-- `p โˆˆ M` is an interior point of a manifold `M` if and only if its image in the extended chart lies in the interior of the model space. -/ def IsInteriorPoint (x : M) := extChartAt I x x โˆˆ interior (range I) variable (I) in -/-- `p โˆˆ M` is a boundary point of a manifold `M` iff its image in the extended chart +/-- `p โˆˆ M` is a boundary point of a manifold `M` if and only if its image in the extended chart lies on the boundary of the model space. -/ def IsBoundaryPoint (x : M) := extChartAt I x x โˆˆ frontier (range I) @@ -182,7 +190,7 @@ lemma Boundaryless.boundary_eq_empty [BoundarylessManifold I M] : I.boundary M = instance [BoundarylessManifold I M] : IsEmpty (I.boundary M) := isEmpty_coe_sort.mpr Boundaryless.boundary_eq_empty -/-- `M` is boundaryless iff its boundary is empty. -/ +/-- `M` is boundaryless if and only if its boundary is empty. -/ lemma Boundaryless.iff_boundary_eq_empty : I.boundary M = โˆ… โ†” BoundarylessManifold I M := by refine โŸจfun h โ†ฆ { isInteriorPoint' := ?_ }, fun a โ†ฆ boundary_eq_emptyโŸฉ intro x @@ -197,6 +205,116 @@ lemma Boundaryless.of_boundary_eq_empty (h : I.boundary M = โˆ…) : BoundarylessM end BoundarylessManifold +section ChartIndependence + +/-- If a function `f : E โ†’ H` is differentiable at `x`, sends a neighbourhood `u` of `x` to a +closed convex set `s` with nonempty interior and has surjective differential at `x`, it must send +`x` to the interior of `s`. -/ +lemma _root_.DifferentiableAt.mem_interior_convex_of_surjective_fderiv + {E H : Type*} [NormedAddCommGroup E] [NormedSpace โ„ E] [NormedAddCommGroup H] [NormedSpace โ„ H] + {f : E โ†’ H} {x : E} (hf : DifferentiableAt โ„ f x) {u : Set E} (hu : u โˆˆ ๐“ x) {s : Set H} + (hs : Convex โ„ s) (hs' : IsClosed s) (hs'' : (interior s).Nonempty) (hfus : Set.MapsTo f u s) + (hfx : Function.Surjective (fderiv โ„ f x)) : f x โˆˆ interior s := by + contrapose hfx + have โŸจF, hFโŸฉ := geometric_hahn_banach_open_point hs.interior isOpen_interior hfx + -- It suffices to show that `fderiv โ„ f x` sends everything to the kernel of `F`. + suffices h : โˆ€ y, F (fderiv โ„ f x y) = 0 by + have โŸจy, hyโŸฉ := hs'' + unfold Function.Surjective; push_neg + refine โŸจf x - y, fun z โ†ฆ ne_of_apply_ne F ?_โŸฉ + rw [h z, F.map_sub] + exact (sub_pos.2 <| hF _ hy).ne + -- This follows from `F โˆ˜ f` taking on a local maximum at `e.extend I x`. + have hF' : MapsTo F s (Iic (F (f x))) := by + rw [โ† hs'.closure_eq, โ† closure_Iio, โ† hs.closure_interior_eq_closure_of_nonempty_interior hs''] + exact .closure hF F.continuous + have hFฯ† : IsLocalMax (F โˆ˜ f) x := Filter.eventually_of_mem hu fun y hy โ†ฆ hF' <| hfus hy + have h := hFฯ†.fderiv_eq_zero + rw [fderiv_comp _ (by fun_prop) hf, ContinuousLinearMap.fderiv] at h + exact DFunLike.congr_fun h + +/-- A point `x` in a Cยน manifold is an interior point if and only if it gets mapped to the interior +of the model space by any given chart - in other words, the notion of interior points does not +depend on any choice of charts. + +Note that in general, this is actually quite nontrivial; that is why are focusing only on Cยน +manifolds here. For merely topological finite-dimensional manifolds the proof involves singular +homology, and for infinite-dimensional topological manifolds I don't even know if this lemma holds. +-/ +lemma isInteriorPoint_iff_of_mem_atlas {n : WithTop โ„•โˆž} [IsManifold I n M] (hn : n โ‰  0) + {e : OpenPartialHomeomorph M H} (he : e โˆˆ atlas H M) {x : M} (hx : x โˆˆ e.source) : + I.IsInteriorPoint x โ†” e.extend I x โˆˆ interior (e.extend I).target := by + -- it suffices to show that if `x` is interior in one chart `e` it also is in any other chart `e'` + revert e + suffices h : โˆ€ e โˆˆ atlas H M, x โˆˆ e.source โ†’ โˆ€ e' โˆˆ atlas H M, x โˆˆ e'.source โ†’ + e.extend I x โˆˆ interior (e.extend I).target โ†’ e'.extend I x โˆˆ interior (e'.extend I).target by + rw [isInteriorPoint_iff] + exact fun e he hx โ†ฆ โŸจh _ (chart_mem_atlas H x) (mem_chart_source H x) _ he hx, + h _ he hx _ (chart_mem_atlas H x) (mem_chart_source H x)โŸฉ + intro e he hex e' he' hex' hx + /- Since transition maps are diffeomorphisms, it suffices to show that if `e'` were to send `x` + to the boundary of `range I`, the differential of the transition map `ฯ†` from `e` to `e'` at `x` + could not be surjective. -/ + let ฯ† := I.extCoordChange e e' + have hฯ† : ContDiffOn ๐•œ n ฯ† ฯ†.source := contDiffOn_extCoordChange + (IsManifold.subset_maximalAtlas he) (IsManifold.subset_maximalAtlas he') + suffices h : Function.Surjective (fderivWithin ๐•œ ฯ† ฯ†.source (e.extend I x)) โ†’ + e'.extend I x โˆˆ interior (range I) by + refine e'.mem_interior_extend_target (by simp [hex']) <| h ?_ + exact (isInvertible_fderivWithin_extCoordChange hn (IsManifold.subset_maximalAtlas he) + (IsManifold.subset_maximalAtlas he') <| by simp [hex, hex']).surjective + intro hฯ†x' + /- Reduce the situation to the real case, then apply + `DifferentiableAt.mem_interior_convex_of_surjective_fderiv`. -/ + wlog _ : IsRCLikeNormedField ๐•œ + ยท simp [I.range_eq_univ_of_not_isRCLikeNormedField โ€น_โ€บ] + let _ := IsRCLikeNormedField.rclike ๐•œ + let _ : NormedSpace โ„ E := NormedSpace.restrictScalars โ„ ๐•œ E + have hฯ†x : ฯ†.source โˆˆ ๐“ (e.extend I x) := by + simp_rw [ฯ†, extCoordChange, PartialEquiv.trans_source, PartialEquiv.symm_source, + Filter.inter_mem_iff, mem_interior_iff_mem_nhds.1 hx, true_and, e'.extend_source] + exact e.extend_preimage_mem_nhds hex <| e'.open_source.mem_nhds hex' + rw [โ† ContinuousLinearMap.coe_restrictScalars' (R := โ„), + (hฯ†.differentiableOn hn _ (by simp [ฯ†, hex, hex'])).restrictScalars_fderivWithin (๐•œ := โ„) + (uniqueDiffWithinAt_of_mem_nhds hฯ†x), fderivWithin_of_mem_nhds <| hฯ†x] at hฯ†x' + rw [show e'.extend I x = ฯ† (e.extend I x) by simp [ฯ†, hex]] + replace hฯ† := ((hฯ†.restrict_scalars โ„).differentiableOn hn).differentiableAt hฯ†x + exact hฯ†.mem_interior_convex_of_surjective_fderiv hฯ†x I.convex_range I.isClosed_range + I.nonempty_interior (ฯ†.mapsTo.mono_right <| by simp [ฯ†, inter_assoc]) hฯ†x' + +/-- A point `x` in a Cยน manifold is a boundary point if and only if it gets mapped to the boundary +of the model space by any given chart - in other words, the notion of boundary points does not +depend on any choice of charts. + +Also see `ModelWithCorners.isInteriorPoint_iff_of_mem_atlas`. -/ +lemma isBoundaryPoint_iff_of_mem_atlas {n : WithTop โ„•โˆž} [IsManifold I n M] (hn : n โ‰  0) + {e : OpenPartialHomeomorph M H} (he : e โˆˆ atlas H M) {x : M} (hx : x โˆˆ e.source) : + I.IsBoundaryPoint x โ†” e.extend I x โˆˆ frontier (e.extend I).target := by + rw [โ† not_iff_not, โ† I.isInteriorPoint_iff_not_isBoundaryPoint, + I.isInteriorPoint_iff_of_mem_atlas hn he hx, mem_interior_iff_notMem_frontier] + exact (e.extend I).mapsTo <| e.extend_source (I := I) โ–ธ hx + +/-- The interior of any Cยน manifold is open. + +This is currently only proven for Cยน manifolds, but holds at least for finite-dimensional +topological manifolds too; see `ModelWithCorners.isInteriorPoint_iff_of_mem_atlas`. -/ +protected lemma isOpen_interior {n : WithTop โ„•โˆž} [IsManifold I n M] (hn : n โ‰  0) : + IsOpen (I.interior M) := by + refine isOpen_iff_forall_mem_open.2 fun x hx โ†ฆ โŸจ_, ?_, isOpen_extChartAt_preimage (I := I) x + isOpen_interior, mem_chart_source H x, isInteriorPoint_iff.1 hxโŸฉ + exact fun y hy โ†ฆ (I.isInteriorPoint_iff_of_mem_atlas hn (chart_mem_atlas H x) hy.1).2 hy.2 + +/-- The boundary of any Cยน manifold is closed. + +This is currently only proven for Cยน manifolds, but holds at least for finite-dimensional +topological manifolds too; see `ModelWithCorners.isInteriorPoint_iff_of_mem_atlas`. -/ +protected lemma isClosed_boundary {n : WithTop โ„•โˆž} [IsManifold I n M] (hn : n โ‰  0) : + IsClosed (I.boundary M) := by + rw [โ† I.compl_interior, isClosed_compl_iff] + exact I.isOpen_interior hn + +end ChartIndependence + /-! Interior and boundary of open subsets of a manifold. -/ section opens diff --git a/Mathlib/Topology/Closure.lean b/Mathlib/Topology/Closure.lean index 9fce1bcde43b43..2c498c2afa91c4 100644 --- a/Mathlib/Topology/Closure.lean +++ b/Mathlib/Topology/Closure.lean @@ -489,6 +489,14 @@ theorem self_diff_frontier (s : Set X) : s \ frontier s = interior s := by rw [frontier, diff_diff_right, diff_eq_empty.2 subset_closure, inter_eq_self_of_subset_right interior_subset, empty_union] +lemma mem_interior_iff_notMem_frontier {s : Set X} {x : X} (hx : x โˆˆ s) : + x โˆˆ interior s โ†” x โˆ‰ frontier s := by + simp [โ† self_diff_frontier, hx] + +lemma mem_frontier_iff_notMem_interior {s : Set X} {x : X} (hx : x โˆˆ s) : + x โˆˆ frontier s โ†” x โˆ‰ interior s := by + simp [โ† self_diff_frontier, hx] + theorem frontier_eq_closure_inter_closure : frontier s = closure s โˆฉ closure sแถœ := by rw [closure_compl, frontier, diff_eq]