Skip to content

Commit bf81df9

Browse files
committed
feat: an explicit criterion for membership in the maximal atlas of a C^n manifold (leanprover-community#40632)
Add an explicit characterisation, that an `OpenPartialHomeomorph` phi lies in the maximal atlas of a C^n manifold if both phi and phi.symm are C^n on their source. This can be useful to prove that certain explicit maps are in the maximal atlas, so prove some maps are immersions. Motivating examples are leanprover-community#29077 (for the inclusion of a closed interval [a, b] into the real numbers) and for a manual proof that diffeomorphisms are immersions. Along the way, rename `contMDiff_model` and its inverse cousin `contMDiffOn_model_symm` to match the naming convention, and golf their proofs.
1 parent 2c3e688 commit bf81df9

2 files changed

Lines changed: 32 additions & 13 deletions

File tree

Mathlib/Geometry/Manifold/ContMDiff/Atlas.lean

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,19 +45,20 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜]
4545

4646
section Atlas
4747

48-
theorem contMDiff_model : ContMDiff I 𝓘(𝕜, E) n I := by
48+
variable (I) in
49+
theorem ModelWithCorners.contMDiff : ContMDiff I 𝓘(𝕜, E) n I := by
4950
intro x
5051
refine contMDiffAt_iff.mpr ⟨I.continuousAt, ?_⟩
51-
simp only [mfld_simps]
52-
refine contDiffWithinAt_id.congr_of_eventuallyEq ?_ ?_
53-
· exact Filter.eventuallyEq_of_mem self_mem_nhdsWithin fun x₂ => I.right_inv
54-
simp_rw [Function.comp_apply, I.left_inv, Function.id_def]
52+
simpa using contDiffWithinAt_id.congr (fun y hy ↦ by simp [hy]) (by simp)
53+
@[deprecated (since := "2026-06-16")] alias contMDiff_model := ModelWithCorners.contMDiff
5554

56-
theorem contMDiffOn_model_symm : ContMDiffOn 𝓘(𝕜, E) I n I.symm (range I) := by
57-
rw [contMDiffOn_iff]
58-
refine ⟨I.continuousOn_symm, fun x y => ?_⟩
59-
simp only [mfld_simps]
60-
exact contDiffOn_id.congr fun x' => I.right_inv
55+
variable (I) in
56+
theorem ModelWithCorners.contMDiffOn_symm : ContMDiffOn 𝓘(𝕜, E) I n I.symm (range I) := by
57+
intro x hx
58+
apply contMDiffWithinAt_iff.mpr ⟨by fun_prop, ?_⟩
59+
simpa using contDiffWithinAt_id.congr (fun y hy ↦ by simp [hy]) (by simp [hx])
60+
@[deprecated (since := "2026-06-16")]
61+
alias contMDiffOn_model_symm := ModelWithCorners.contMDiffOn_symm
6162

6263
/-- An atlas member is `C^n` for any `n`. -/
6364
theorem contMDiffOn_of_mem_maximalAtlas (h : e ∈ maximalAtlas I n M) :
@@ -89,7 +90,7 @@ theorem contMDiffOn_chart_symm [IsManifold I n M] :
8990

9091
theorem contMDiffAt_extend {x : M} (he : e ∈ maximalAtlas I n M) (hx : x ∈ e.source) :
9192
ContMDiffAt I 𝓘(𝕜, E) n (e.extend I) x :=
92-
(contMDiff_model _).comp x <| contMDiffAt_of_mem_maximalAtlas he hx
93+
(I.contMDiff _).comp x <| contMDiffAt_of_mem_maximalAtlas he hx
9394

9495
theorem contMDiffOn_extend (he : e ∈ maximalAtlas I n M) :
9596
ContMDiffOn I 𝓘(𝕜, E) n (e.extend I) e.source :=
@@ -112,7 +113,7 @@ theorem contMDiffOn_extChartAt [IsManifold I n M] :
112113
theorem contMDiffOn_extend_symm (he : e ∈ maximalAtlas I n M) :
113114
ContMDiffOn 𝓘(𝕜, E) I n (e.extend I).symm (I '' e.target) := by
114115
refine (contMDiffOn_symm_of_mem_maximalAtlas he).comp
115-
(contMDiffOn_model_symm.mono <| image_subset_range _ _) ?_
116+
(I.contMDiffOn_symm.mono <| image_subset_range _ _) ?_
116117
simp_rw [image_subset_iff, PartialEquiv.restr_coe_symm, I.toPartialEquiv_coe_symm,
117118
preimage_preimage, I.left_inv, preimage_id']; rfl
118119

@@ -155,6 +156,24 @@ theorem contMDiffOn_of_mem_contDiffGroupoid {e' : OpenPartialHomeomorph H H}
155156
(h : e' ∈ contDiffGroupoid n I) : ContMDiffOn I I n e' e'.source :=
156157
(contDiffWithinAt_localInvariantProp n).liftPropOn_of_mem_groupoid contDiffWithinAtProp_id h
157158

159+
lemma OpenPartialHomeomorph.mem_maximalAtlas_of_contMDiffOn (φ : OpenPartialHomeomorph H H)
160+
(hφ : ContMDiffOn I I n φ φ.source) (hφ' : ContMDiffOn I I n φ.symm φ.target) :
161+
φ ∈ maximalAtlas I n H := by
162+
simp only [mfld_simps, IsManifold.mem_maximalAtlas_iff, StructureGroupoid.maximalAtlas, forall_eq,
163+
contDiffGroupoid, mem_groupoid_of_pregroupoid, contDiffPregroupoid,
164+
← contMDiffOn_iff_contDiffOn]
165+
refine ⟨⟨?_, ?_⟩, ?_, ?_⟩
166+
all_goals apply I.contMDiff.comp_contMDiffOn
167+
· exact hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by simp)
168+
· exact hφ.comp (I.contMDiffOn_symm.mono (by simp)) (by simp)
169+
· exact hφ.comp (I.contMDiffOn_symm.mono (by simp)) (by simp)
170+
· exact hφ'.comp (I.contMDiffOn_symm.mono (by simp)) (by simp)
171+
172+
lemma IsManifold.mem_maximalAtlas_iff_contMDiffOn (φ : OpenPartialHomeomorph H H) :
173+
φ ∈ maximalAtlas I n H ↔ ContMDiffOn I I n φ φ.source ∧ ContMDiffOn I I n φ.symm φ.target :=
174+
fun h ↦ ⟨contMDiffOn_of_mem_maximalAtlas h, contMDiffOn_symm_of_mem_maximalAtlas h⟩,
175+
fun ⟨hφ, hφ'⟩ ↦ φ.mem_maximalAtlas_of_contMDiffOn hφ hφ'⟩
176+
158177
end Atlas
159178

160179
/-! ### (local) structomorphisms are `C^n` -/

Mathlib/Geometry/Manifold/PartitionOfUnity.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ lemma IsOpen.exists_contMDiff_support_eq_aux {s : Set H} (hs : IsOpen s) :
736736
refine ⟨f ∘ I, ?_, ?_, ?_⟩
737737
· rw [support_comp_eq_preimage, f_supp, ← preimage_comp]
738738
simp only [ModelWithCorners.symm_comp_self, preimage_id_eq, id_eq]
739-
· exact f_diff.comp_contMDiff contMDiff_model
739+
· exact f_diff.comp_contMDiff I.contMDiff
740740
· exact Subset.trans (range_comp_subset_range _ _) f_range
741741

742742
@[deprecated (since := "2025-12-17")]

0 commit comments

Comments
 (0)