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

Commit 953ab3a

Browse files
committed
feat(geometry/manifold/charted_space): open subset of a manifold is a manifold (#3442)
An open subset of a charted space is naturally a charted space. If the charted space has structure groupoid `G` (with `G` closed under restriction), then the open subset does also. Most of the work is in `topology/local_homeomorph`, where it is proved that a local homeomorphism whose source is `univ` is an open embedding, and conversely.
1 parent bc278b7 commit 953ab3a

File tree

2 files changed

+180
-1
lines changed

2 files changed

+180
-1
lines changed

src/geometry/manifold/charted_space.lean

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,8 @@ variables (e : local_homeomorph α H)
756756

757757
/-- If a single local homeomorphism `e` from a space `α` into `H` has source covering the whole
758758
space `α`, then that local homeomorphism induces an `H`-charted space structure on `α`.
759-
(This condition is equivalent to `e` being an open embedding of `α` into `H`.) -/
759+
(This condition is equivalent to `e` being an open embedding of `α` into `H`; see
760+
`local_homeomorph.to_open_embedding` and `open_embedding.to_local_homeomorph`.) -/
760761
def singleton_charted_space (h : e.source = set.univ) : charted_space H α :=
761762
{ atlas := {e},
762763
chart_at := λ _, e,
@@ -782,6 +783,36 @@ lemma singleton_has_groupoid (h : e.source = set.univ) (G : structure_groupoid H
782783

783784
end singleton
784785

786+
namespace topological_space.opens
787+
788+
open topological_space
789+
variables (G : structure_groupoid H) [has_groupoid M G]
790+
variables (s : opens M)
791+
792+
/-- An open subset of a charted space is naturally a charted space. -/
793+
instance : charted_space H s :=
794+
{ atlas := ⋃ (x : s), {@local_homeomorph.subtype_restr _ _ _ _ (chart_at H x.1) s ⟨x⟩},
795+
chart_at := λ x, @local_homeomorph.subtype_restr _ _ _ _ (chart_at H x.1) s ⟨x⟩,
796+
mem_chart_source := λ x, by { simp only with mfld_simps, exact (mem_chart_source H x.1) },
797+
chart_mem_atlas := λ x, by { simp only [mem_Union, mem_singleton_iff], use x } }
798+
799+
/-- If a groupoid `G` is `closed_under_restriction`, then an open subset of a space which is
800+
`has_groupoid G` is naturally `has_groupoid G`. -/
801+
instance [closed_under_restriction G] : has_groupoid s G :=
802+
{ compatible := begin
803+
rintros e e' ⟨_, ⟨x, hc⟩, he⟩ ⟨_, ⟨x', hc'⟩, he'⟩,
804+
haveI : nonempty s := ⟨x⟩,
805+
simp only [hc.symm, mem_singleton_iff, subtype.val_eq_coe] at he,
806+
simp only [hc'.symm, mem_singleton_iff, subtype.val_eq_coe] at he',
807+
rw [he, he'],
808+
convert G.eq_on_source _ (subtype_restr_symm_trans_subtype_restr s (chart_at H x) (chart_at H x')),
809+
apply closed_under_restriction',
810+
{ exact G.compatible (chart_mem_atlas H x) (chart_mem_atlas H x') },
811+
{ exact preimage_open_of_open_symm (chart_at H x) s.2 },
812+
end }
813+
814+
end topological_space.opens
815+
785816
/-! ### Structomorphisms -/
786817

787818
/-- A `G`-diffeomorphism between two charted spaces is a homeomorphism which, when read in the

src/topology/local_homeomorph.lean

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Sébastien Gouëzel
55
-/
66
import data.equiv.local_equiv
77
import topology.homeomorph
8+
import topology.opens
89

910
/-!
1011
# Local homeomorphisms
@@ -108,6 +109,8 @@ e.left_inv' h
108109
@[simp, mfld_simps] lemma right_inv {x : β} (h : x ∈ e.target) : e (e.symm x) = x :=
109110
e.right_inv' h
110111

112+
lemma source_preimage_target : e.source ⊆ e ⁻¹' e.target := λ _ h, map_source e h
113+
111114
lemma eq_of_local_equiv_eq {e e' : local_homeomorph α β}
112115
(h : e.to_local_equiv = e'.to_local_equiv) : e = e' :=
113116
begin
@@ -225,6 +228,13 @@ begin
225228
exact e.continuous_on_symm.preimage_open_of_open e.open_target hs
226229
end
227230

231+
/-- The image of the restriction of an open set to the source is open. -/
232+
lemma image_open_of_open' {s : set α} (hs : is_open s) : is_open (e '' (s ∩ e.source)) :=
233+
begin
234+
refine image_open_of_open _ (is_open_inter hs e.open_source) _,
235+
simp,
236+
end
237+
228238
/-- Restricting a local homeomorphism `e` to `e.source ∩ s` when `s` is open. This is sometimes hard
229239
to use because of the openness assumption, but it has the advantage that when it can
230240
be used then its local_equiv is defeq to local_equiv.restr -/
@@ -661,6 +671,21 @@ def to_homeomorph_of_source_eq_univ_target_eq_univ (h : e.source = (univ : set
661671
(h : e.source = (univ : set α)) (h' : e.target = univ) :
662672
((e.to_homeomorph_of_source_eq_univ_target_eq_univ h h').symm : β → α) = e.symm := rfl
663673

674+
/-- A local homeomorphism whose source is all of `α` defines an open embedding of `α` into `β`. The
675+
converse is also true; see `open_embedding.to_local_homeomorph`. -/
676+
lemma to_open_embedding (h : e.source = set.univ) : open_embedding e.to_fun :=
677+
begin
678+
apply open_embedding_of_continuous_injective_open,
679+
{ apply continuous_iff_continuous_on_univ.mpr,
680+
rw ← h,
681+
exact e.continuous_to_fun },
682+
{ apply set.injective_iff_inj_on_univ.mpr,
683+
rw ← h,
684+
exact e.to_local_equiv.bij_on_source.inj_on },
685+
{ intros U hU,
686+
simpa only [h, subset_univ] with mfld_simps using e.image_open_of_open hU}
687+
end
688+
664689
end local_homeomorph
665690

666691
namespace homeomorph
@@ -682,3 +707,126 @@ correspond to the fields of the original homeomorphism. -/
682707
local_homeomorph.eq_of_local_equiv_eq $ equiv.trans_to_local_equiv _ _
683708

684709
end homeomorph
710+
711+
namespace open_embedding
712+
variables [nonempty α]
713+
variables {f : α → β} (h : open_embedding f)
714+
include f h
715+
716+
/-- An open embedding of `α` into `β`, with `α` nonempty, defines a local equivalence whose source
717+
is all of `α`. This is mainly an auxiliary lemma for the stronger result `to_local_homeomorph`. -/
718+
noncomputable def to_local_equiv : local_equiv α β :=
719+
set.inj_on.to_local_equiv f set.univ (set.injective_iff_inj_on_univ.mp h.to_embedding.inj)
720+
721+
@[simp, mfld_simps] lemma to_local_equiv_coe : (h.to_local_equiv : α → β) = f := rfl
722+
@[simp, mfld_simps] lemma to_local_equiv_source : h.to_local_equiv.source = set.univ := rfl
723+
724+
@[simp, mfld_simps] lemma to_local_equiv_target : h.to_local_equiv.target = set.range f :=
725+
begin
726+
rw ←local_equiv.image_source_eq_target,
727+
ext,
728+
split,
729+
{ exact λ ⟨a, _, h'⟩, ⟨a, h'⟩ },
730+
{ exact λ ⟨a, h'⟩, ⟨a, by trivial, h'⟩ }
731+
end
732+
733+
lemma open_target : is_open h.to_local_equiv.target :=
734+
by simpa only with mfld_simps using h.open_range
735+
736+
lemma continuous_inv_fun : continuous_on h.to_local_equiv.inv_fun h.to_local_equiv.target :=
737+
begin
738+
apply (continuous_on_open_iff h.open_target).mpr,
739+
intros t ht,
740+
simp only with mfld_simps,
741+
convert h.open_iff_image_open.mp ht,
742+
ext y,
743+
have hinv : ∀ x : α, (f x = y) → h.to_local_equiv.symm y = x :=
744+
λ x hxy, by { simpa only [hxy.symm] with mfld_simps using h.to_local_equiv.left_inv },
745+
simp only [mem_image, mem_range] with mfld_simps,
746+
split,
747+
{ rintros ⟨⟨x, hxy⟩, hy⟩,
748+
refine ⟨x, _, hxy⟩,
749+
rwa (hinv x hxy) at hy },
750+
{ rintros ⟨x, hx, hxy⟩,
751+
refine ⟨⟨x, hxy⟩, _⟩,
752+
rwa ← (hinv x hxy) at hx }
753+
end
754+
755+
/-- An open embedding of `α` into `β`, with `α` nonempty, defines a local homeomorphism whose source
756+
is all of `α`. The converse is also true; see `local_homeomorph.to_open_embedding`. -/
757+
noncomputable def to_local_homeomorph : local_homeomorph α β :=
758+
{ to_local_equiv := h.to_local_equiv,
759+
open_source := is_open_univ,
760+
open_target := h.open_target,
761+
continuous_to_fun := by simpa only with mfld_simps using h.continuous.continuous_on,
762+
continuous_inv_fun := h.continuous_inv_fun }
763+
764+
@[simp, mfld_simps] lemma to_local_homeomorph_coe : (h.to_local_homeomorph : α → β) = f := rfl
765+
@[simp, mfld_simps] lemma source : h.to_local_homeomorph.source = set.univ := rfl
766+
@[simp, mfld_simps] lemma target : h.to_local_homeomorph.target = set.range f :=
767+
h.to_local_equiv_target
768+
769+
end open_embedding
770+
771+
namespace topological_space.opens
772+
773+
open topological_space
774+
variables (s : opens α) [nonempty s]
775+
776+
/-- The inclusion of an open subset `s` of a space `α` into `α` is a local homeomorphism from the
777+
subtype `s` to `α`. -/
778+
noncomputable def local_homeomorph_subtype_coe : local_homeomorph s α :=
779+
open_embedding.to_local_homeomorph (s.2.open_embedding_subtype_coe)
780+
781+
@[simp, mfld_simps] lemma local_homeomorph_subtype_coe_coe :
782+
(s.local_homeomorph_subtype_coe : s → α) = coe := rfl
783+
784+
@[simp, mfld_simps] lemma local_homeomorph_subtype_coe_source :
785+
s.local_homeomorph_subtype_coe.source = set.univ := rfl
786+
787+
@[simp, mfld_simps] lemma local_homeomorph_subtype_coe_target :
788+
s.local_homeomorph_subtype_coe.target = s :=
789+
by { simp only [local_homeomorph_subtype_coe, subtype.range_coe_subtype] with mfld_simps, refl }
790+
791+
end topological_space.opens
792+
793+
namespace local_homeomorph
794+
795+
open topological_space
796+
variables (e : local_homeomorph α β)
797+
variables (s : opens α) [nonempty s]
798+
799+
/-- The restriction of a local homeomorphism `e` to an open subset `s` of the domain type produces a
800+
local homeomorphism whose domain is the subtype `s`.-/
801+
noncomputable def subtype_restr : local_homeomorph s β := s.local_homeomorph_subtype_coe.trans e
802+
803+
lemma subtype_restr_def : e.subtype_restr s = s.local_homeomorph_subtype_coe.trans e := rfl
804+
805+
@[simp, mfld_simps] lemma subtype_restr_coe : ((e.subtype_restr s : local_homeomorph s β) : s → β)
806+
= set.restrict (e : α → β) s := rfl
807+
808+
@[simp, mfld_simps] lemma subtype_restr_source : (e.subtype_restr s).source = coe ⁻¹' e.source :=
809+
by simp only [subtype_restr_def] with mfld_simps
810+
811+
/- This lemma characterizes the transition functions of an open subset in terms of the transition
812+
functions of the original space. -/
813+
lemma subtype_restr_symm_trans_subtype_restr (f f' : local_homeomorph α β) :
814+
(f.subtype_restr s).symm.trans (f'.subtype_restr s)
815+
≈ (f.symm.trans f').restr (f.target ∩ (f.symm) ⁻¹' s) :=
816+
begin
817+
simp only [subtype_restr_def, trans_symm_eq_symm_trans_symm],
818+
have openness₁ : is_open (f.target ∩ f.symm ⁻¹' s) := f.preimage_open_of_open_symm s.2,
819+
rw [← of_set_trans _ openness₁, ← trans_assoc, ← trans_assoc],
820+
refine eq_on_source.trans' _ (eq_on_source_refl _),
821+
-- f' has been eliminated !!!
822+
have sets_identity : f.symm.source ∩ (f.target ∩ (f.symm) ⁻¹' s) = f.symm.source ∩ f.symm ⁻¹' s,
823+
{ mfld_set_tac },
824+
have openness₂ : is_open (s : set α) := s.2,
825+
rw [of_set_trans', sets_identity, ← trans_of_set' _ openness₂, trans_assoc],
826+
refine eq_on_source.trans' (eq_on_source_refl _) _,
827+
-- f has been eliminated !!!
828+
refine setoid.trans (trans_symm_self s.local_homeomorph_subtype_coe) _,
829+
simp only with mfld_simps,
830+
end
831+
832+
end local_homeomorph

0 commit comments

Comments
 (0)