Skip to content

Commit 1620b76

Browse files
committed
feat(AlgebraicGeometry): preimmersions are stable under base change (#18915)
Co-authored-by: Andrew Yang <36414270+erdOne@users.noreply.github.com>
1 parent 2abe270 commit 1620b76

File tree

7 files changed

+264
-23
lines changed

7 files changed

+264
-23
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -962,6 +962,7 @@ import Mathlib.AlgebraicGeometry.Morphisms.QuasiSeparated
962962
import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties
963963
import Mathlib.AlgebraicGeometry.Morphisms.Separated
964964
import Mathlib.AlgebraicGeometry.Morphisms.Smooth
965+
import Mathlib.AlgebraicGeometry.Morphisms.SurjectiveOnStalks
965966
import Mathlib.AlgebraicGeometry.Morphisms.UnderlyingMap
966967
import Mathlib.AlgebraicGeometry.Morphisms.UniversallyClosed
967968
import Mathlib.AlgebraicGeometry.Morphisms.UniversallyInjective

Mathlib/AlgebraicGeometry/Cover/MorphismProperty.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ theorem Cover.iUnion_range {X : Scheme.{u}} (𝒰 : X.Cover P) :
7373
rw [Set.mem_iUnion]
7474
exact ⟨𝒰.f x, 𝒰.covers x⟩
7575

76+
lemma Cover.exists_eq (𝒰 : X.Cover P) (x : X) : ∃ i y, (𝒰.map i).base y = x :=
77+
⟨_, 𝒰.covers x⟩
78+
7679
/-- Given a family of schemes with morphisms to `X` satisfying `P` that jointly
7780
cover `X`, this an associated `P`-cover of `X`. -/
7881
@[simps]

Mathlib/AlgebraicGeometry/Morphisms/ClosedImmersion.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ lemma eq_inf : @IsClosedImmersion = (topologically IsClosedEmbedding) ⊓
6262

6363
lemma iff_isPreimmersion {X Y : Scheme} {f : X ⟶ Y} :
6464
IsClosedImmersion f ↔ IsPreimmersion f ∧ IsClosed (Set.range f.base) := by
65-
rw [and_comm, isClosedImmersion_iff, isPreimmersion_iff, ← and_assoc, isClosedEmbedding_iff,
66-
@and_comm (IsEmbedding _)]
65+
rw [isClosedImmersion_iff, isPreimmersion_iff, ← surjectiveOnStalks_iff, and_comm, and_assoc,
66+
isClosedEmbedding_iff]
6767

6868
lemma of_isPreimmersion {X Y : Scheme} (f : X ⟶ Y) [IsPreimmersion f]
6969
(hf : IsClosed (Set.range f.base)) : IsClosedImmersion f :=

Mathlib/AlgebraicGeometry/Morphisms/Preimmersion.lean

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Andrew Yang
55
-/
66
import Mathlib.AlgebraicGeometry.Morphisms.UnderlyingMap
7-
import Mathlib.RingTheory.RingHom.Surjective
8-
import Mathlib.RingTheory.SurjectiveOnStalks
7+
import Mathlib.AlgebraicGeometry.Morphisms.SurjectiveOnStalks
98

109
/-!
1110
@@ -33,22 +32,17 @@ namespace AlgebraicGeometry
3332
/-- A morphism of schemes `f : X ⟶ Y` is a preimmersion if the underlying map of
3433
topological spaces is an embedding and the induced morphisms of stalks are all surjective. -/
3534
@[mk_iff]
36-
class IsPreimmersion {X Y : Scheme} (f : X ⟶ Y) : Prop where
35+
class IsPreimmersion {X Y : Scheme} (f : X ⟶ Y) extends SurjectiveOnStalks f : Prop where
3736
base_embedding : IsEmbedding f.base
38-
surj_on_stalks : ∀ x, Function.Surjective (f.stalkMap x)
3937

4038
lemma Scheme.Hom.isEmbedding {X Y : Scheme} (f : Hom X Y) [IsPreimmersion f] : IsEmbedding f.base :=
4139
IsPreimmersion.base_embedding
4240

4341
@[deprecated (since := "2024-10-26")]
4442
alias Scheme.Hom.embedding := Scheme.Hom.isEmbedding
4543

46-
lemma Scheme.Hom.stalkMap_surjective {X Y : Scheme} (f : Hom X Y) [IsPreimmersion f] (x) :
47-
Function.Surjective (f.stalkMap x) :=
48-
IsPreimmersion.surj_on_stalks x
49-
5044
lemma isPreimmersion_eq_inf :
51-
@IsPreimmersion = topologically IsEmbedding ⊓ stalkwise (Function.Surjective ·) := by
45+
@IsPreimmersion = (@SurjectiveOnStalks ⊓ topologically IsEmbedding : MorphismProperty _) := by
5246
ext
5347
rw [isPreimmersion_iff]
5448
rfl
@@ -69,10 +63,7 @@ instance (priority := 900) {X Y : Scheme} (f : X ⟶ Y) [IsOpenImmersion f] : Is
6963

7064
instance : MorphismProperty.IsMultiplicative @IsPreimmersion where
7165
id_mem _ := inferInstance
72-
comp_mem {X Y Z} f g hf hg := by
73-
refine ⟨hg.base_embedding.comp hf.base_embedding, fun x ↦ ?_⟩
74-
rw [Scheme.stalkMap_comp]
75-
exact (hf.surj_on_stalks x).comp (hg.surj_on_stalks (f.base x))
66+
comp_mem f g _ _ := ⟨g.isEmbedding.comp f.isEmbedding⟩
7667

7768
instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [IsPreimmersion f]
7869
[IsPreimmersion g] : IsPreimmersion (f ≫ g) :=
@@ -104,14 +95,8 @@ lemma Spec_map_iff {R S : CommRingCat.{u}} (f : R ⟶ S) :
10495
haveI : (RingHom.toMorphismProperty <| fun f ↦ Function.Surjective f).RespectsIso := by
10596
rw [← RingHom.toMorphismProperty_respectsIso_iff]
10697
exact RingHom.surjective_respectsIso
107-
refine ⟨fun ⟨h₁, h₂⟩ ↦ ⟨h₁, ?_⟩, fun ⟨h₁, h₂⟩ ↦ ⟨h₁, fun (x : PrimeSpectrum S) ↦ ?_⟩⟩
108-
· intro p hp
109-
let e := Scheme.arrowStalkMapSpecIso f ⟨p, hp⟩
110-
apply ((RingHom.toMorphismProperty <| fun f ↦ Function.Surjective f).arrow_mk_iso_iff e).mp
111-
exact h₂ ⟨p, hp⟩
112-
· let e := Scheme.arrowStalkMapSpecIso f x
113-
apply ((RingHom.toMorphismProperty <| fun f ↦ Function.Surjective f).arrow_mk_iso_iff e).mpr
114-
exact h₂ x.asIdeal x.isPrime
98+
rw [← HasRingHomProperty.Spec_iff (P := @SurjectiveOnStalks), isPreimmersion_iff, and_comm]
99+
rfl
115100

116101
lemma mk_Spec_map {R S : CommRingCat.{u}} {f : R ⟶ S}
117102
(h₁ : IsEmbedding (PrimeSpectrum.comap f)) (h₂ : f.SurjectiveOnStalks) :
@@ -125,6 +110,19 @@ lemma of_isLocalization {R S : Type u} [CommRing R] (M : Submonoid R) [CommRing
125110
(PrimeSpectrum.localization_comap_isEmbedding (R := R) S M)
126111
(RingHom.surjectiveOnStalks_of_isLocalization (M := M) S)
127112

113+
open Limits MorphismProperty in
114+
instance : IsStableUnderBaseChange @IsPreimmersion := by
115+
refine .mk' fun X Y Z f g _ _ ↦ ?_
116+
have := pullback_fst (P := @SurjectiveOnStalks) f g inferInstance
117+
constructor
118+
let L (x : (pullback f g : _)) : { x : X × Y | f.base x.1 = g.base x.2 } :=
119+
⟨⟨(pullback.fst f g).base x, (pullback.snd f g).base x⟩,
120+
by simp only [Set.mem_setOf, ← Scheme.comp_base_apply, pullback.condition]⟩
121+
have : IsEmbedding L := IsEmbedding.of_comp (by fun_prop) continuous_subtype_val
122+
(SurjectiveOnStalks.isEmbedding_pullback f g)
123+
exact IsEmbedding.subtypeVal.comp ((TopCat.pullbackHomeoPreimage _ f.continuous _
124+
g.isEmbedding).isEmbedding.comp this)
125+
128126
end IsPreimmersion
129127

130128
end AlgebraicGeometry
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/-
2+
Copyright (c) 2024 Andrew Yang. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Andrew Yang
5+
-/
6+
import Mathlib.AlgebraicGeometry.Morphisms.RingHomProperties
7+
import Mathlib.AlgebraicGeometry.PrimeSpectrum.TensorProduct
8+
import Mathlib.Topology.LocalAtTarget
9+
10+
/-!
11+
# Morphisms surjective on stalks
12+
13+
We define the classe of morphisms between schemes that are surjective on stalks.
14+
We show that this class is stable under composition and base change.
15+
16+
We also show that (`AlgebraicGeometry.SurjectiveOnStalks.isEmbedding_pullback`)
17+
if `Y ⟶ S` is surjective on stalks, then for every `X ⟶ S`, `X ×ₛ Y` is a subset of
18+
`X × Y` (cartesian product as topological spaces) with the induced topology.
19+
-/
20+
21+
open CategoryTheory CategoryTheory.Limits Topology
22+
23+
namespace AlgebraicGeometry
24+
25+
universe u
26+
27+
variable {X Y Z : Scheme.{u}} (f : X ⟶ Y) (g : Y ⟶ Z)
28+
29+
/-- The class of morphisms `f : X ⟶ Y` between schemes such that
30+
`𝒪_{Y, f x} ⟶ 𝒪_{X, x}` is surjective for all `x : X`. -/
31+
@[mk_iff]
32+
class SurjectiveOnStalks : Prop where
33+
surj_on_stalks : ∀ x, Function.Surjective (f.stalkMap x)
34+
35+
theorem Scheme.Hom.stalkMap_surjective (f : X.Hom Y) [SurjectiveOnStalks f] (x) :
36+
Function.Surjective (f.stalkMap x) :=
37+
SurjectiveOnStalks.surj_on_stalks x
38+
39+
namespace SurjectiveOnStalks
40+
41+
instance (priority := 900) [IsOpenImmersion f] : SurjectiveOnStalks f :=
42+
fun _ ↦ (ConcreteCategory.bijective_of_isIso _).2
43+
44+
instance : MorphismProperty.IsMultiplicative @SurjectiveOnStalks where
45+
id_mem _ := inferInstance
46+
comp_mem {X Y Z} f g hf hg := by
47+
refine ⟨fun x ↦ ?_⟩
48+
rw [Scheme.stalkMap_comp]
49+
exact (hf.surj_on_stalks x).comp (hg.surj_on_stalks (f.base x))
50+
51+
instance comp {X Y Z : Scheme} (f : X ⟶ Y) (g : Y ⟶ Z) [SurjectiveOnStalks f]
52+
[SurjectiveOnStalks g] : SurjectiveOnStalks (f ≫ g) :=
53+
MorphismProperty.IsStableUnderComposition.comp_mem f g inferInstance inferInstance
54+
55+
lemma eq_stalkwise :
56+
@SurjectiveOnStalks = stalkwise (Function.Surjective ·) := by
57+
ext; exact surjectiveOnStalks_iff _
58+
59+
instance : IsLocalAtTarget @SurjectiveOnStalks :=
60+
eq_stalkwise ▸ stalkwiseIsLocalAtTarget_of_respectsIso RingHom.surjective_respectsIso
61+
62+
instance : IsLocalAtSource @SurjectiveOnStalks :=
63+
eq_stalkwise ▸ stalkwise_isLocalAtSource_of_respectsIso RingHom.surjective_respectsIso
64+
65+
lemma Spec_iff {R S : CommRingCat.{u}} {φ : R ⟶ S} :
66+
SurjectiveOnStalks (Spec.map φ) ↔ RingHom.SurjectiveOnStalks φ := by
67+
rw [eq_stalkwise, stalkwise_Spec_map_iff RingHom.surjective_respectsIso,
68+
RingHom.SurjectiveOnStalks]
69+
70+
instance : HasRingHomProperty @SurjectiveOnStalks RingHom.SurjectiveOnStalks :=
71+
eq_stalkwise ▸ .stalkwise RingHom.surjective_respectsIso
72+
73+
variable {f} in
74+
lemma iff_of_isAffine [IsAffine X] [IsAffine Y] :
75+
SurjectiveOnStalks f ↔ RingHom.SurjectiveOnStalks (f.app ⊤) := by
76+
rw [← Spec_iff, MorphismProperty.arrow_mk_iso_iff @SurjectiveOnStalks (arrowIsoSpecΓOfIsAffine f)]
77+
rfl
78+
79+
theorem of_comp [SurjectiveOnStalks (f ≫ g)] : SurjectiveOnStalks f := by
80+
refine ⟨fun x ↦ ?_⟩
81+
have := (f ≫ g).stalkMap_surjective x
82+
rw [Scheme.stalkMap_comp] at this
83+
exact Function.Surjective.of_comp this
84+
85+
instance stableUnderBaseChange :
86+
MorphismProperty.IsStableUnderBaseChange @SurjectiveOnStalks := by
87+
apply HasRingHomProperty.isStableUnderBaseChange
88+
apply RingHom.IsStableUnderBaseChange.mk
89+
· exact (HasRingHomProperty.isLocal_ringHomProperty @SurjectiveOnStalks).respectsIso
90+
intros R S T _ _ _ _ _ H
91+
exact H.baseChange
92+
93+
/-- If `Y ⟶ S` is surjective on stalks, then for every `X ⟶ S`, `X ×ₛ Y` is a subset of
94+
`X × Y` (cartesian product as topological spaces) with the induced topology. -/
95+
lemma isEmbedding_pullback {X Y S : Scheme.{u}} (f : X ⟶ S) (g : Y ⟶ S) [SurjectiveOnStalks g] :
96+
IsEmbedding (fun x ↦ ((pullback.fst f g).base x, (pullback.snd f g).base x)) := by
97+
let L := (fun x ↦ ((pullback.fst f g).base x, (pullback.snd f g).base x))
98+
have H : ∀ R A B (f' : Spec A ⟶ Spec R) (g' : Spec B ⟶ Spec R) (iX : Spec A ⟶ X)
99+
(iY : Spec B ⟶ Y) (iS : Spec R ⟶ S) (e₁ e₂), IsOpenImmersion iX → IsOpenImmersion iY →
100+
IsOpenImmersion iS → IsEmbedding (L ∘ (pullback.map f' g' f g iX iY iS e₁ e₂).base) := by
101+
intro R A B f' g' iX iY iS e₁ e₂ _ _ _
102+
have H : SurjectiveOnStalks g' :=
103+
have : SurjectiveOnStalks (g' ≫ iS) := e₂ ▸ inferInstance
104+
.of_comp _ iS
105+
obtain ⟨φ, rfl⟩ : ∃ φ, Spec.map φ = f' := ⟨_, Spec.map_preimage _⟩
106+
obtain ⟨ψ, rfl⟩ : ∃ ψ, Spec.map ψ = g' := ⟨_, Spec.map_preimage _⟩
107+
letI := φ.toAlgebra
108+
letI := ψ.toAlgebra
109+
rw [HasRingHomProperty.Spec_iff (P := @SurjectiveOnStalks)] at H
110+
convert ((iX.isOpenEmbedding.prodMap iY.isOpenEmbedding).isEmbedding.comp
111+
(PrimeSpectrum.isEmbedding_tensorProductTo_of_surjectiveOnStalks R A B H)).comp
112+
(Scheme.homeoOfIso (pullbackSpecIso R A B)).isEmbedding
113+
ext1 x
114+
obtain ⟨x, rfl⟩ := (Scheme.homeoOfIso (pullbackSpecIso R A B).symm).surjective x
115+
simp only [Scheme.homeoOfIso_apply, Function.comp_apply]
116+
ext
117+
· simp only [← Scheme.comp_base_apply, pullback.lift_fst, Iso.symm_hom, Iso.inv_hom_id]
118+
erw [← Scheme.comp_base_apply, pullbackSpecIso_inv_fst_assoc]
119+
rfl
120+
· simp only [← Scheme.comp_base_apply, pullback.lift_snd, Iso.symm_hom, Iso.inv_hom_id]
121+
erw [← Scheme.comp_base_apply, pullbackSpecIso_inv_snd_assoc]
122+
rfl
123+
let 𝒰 := S.affineOpenCover.openCover
124+
let 𝒱 (i) := ((𝒰.pullbackCover f).obj i).affineOpenCover.openCover
125+
let 𝒲 (i) := ((𝒰.pullbackCover g).obj i).affineOpenCover.openCover
126+
let U (ijk : Σ i, (𝒱 i).J × (𝒲 i).J) : TopologicalSpace.Opens (X.carrier × Y) :=
127+
⟨{ P | P.1 ∈ ((𝒱 ijk.1).map ijk.2.1 ≫ (𝒰.pullbackCover f).map ijk.1).opensRange ∧
128+
P.2 ∈ ((𝒲 ijk.1).map ijk.2.2 ≫ (𝒰.pullbackCover g).map ijk.1).opensRange },
129+
(continuous_fst.1 _ ((𝒱 ijk.1).map ijk.2.1
130+
(𝒰.pullbackCover f).map ijk.1).opensRange.2).inter (continuous_snd.1 _
131+
((𝒲 ijk.1).map ijk.2.2 ≫ (𝒰.pullbackCover g).map ijk.1).opensRange.2)⟩
132+
have : Set.range L ⊆ (iSup U : _) := by
133+
simp only [Scheme.Cover.pullbackCover_J, Scheme.Cover.pullbackCover_obj, Set.range_subset_iff]
134+
intro z
135+
simp only [SetLike.mem_coe, TopologicalSpace.Opens.mem_iSup, Sigma.exists, Prod.exists]
136+
obtain ⟨is, s, hsx⟩ := 𝒰.exists_eq (f.base ((pullback.fst f g).base z))
137+
have hsy : (𝒰.map is).base s = g.base ((pullback.snd f g).base z) := by
138+
rwa [← Scheme.comp_base_apply, ← pullback.condition, Scheme.comp_base_apply]
139+
obtain ⟨x : (𝒰.pullbackCover f).obj is, hx⟩ :=
140+
Scheme.IsJointlySurjectivePreserving.exists_preimage_fst_triplet_of_prop
141+
(P := @IsOpenImmersion) inferInstance _ _ hsx.symm
142+
obtain ⟨y : (𝒰.pullbackCover g).obj is, hy⟩ :=
143+
Scheme.IsJointlySurjectivePreserving.exists_preimage_fst_triplet_of_prop
144+
(P := @IsOpenImmersion) inferInstance _ _ hsy.symm
145+
obtain ⟨ix, x, rfl⟩ := (𝒱 is).exists_eq x
146+
obtain ⟨iy, y, rfl⟩ := (𝒲 is).exists_eq y
147+
refine ⟨is, ix, iy, ⟨x, hx⟩, ⟨y, hy⟩⟩
148+
let 𝓤 := (Scheme.Pullback.openCoverOfBase 𝒰 f g).bind
149+
(fun i ↦ Scheme.Pullback.openCoverOfLeftRight (𝒱 i) (𝒲 i) _ _)
150+
refine isEmbedding_of_iSup_eq_top_of_preimage_subset_range _ ?_ U this _ (fun i ↦ (𝓤.map i).base)
151+
(fun i ↦ (𝓤.map i).continuous) ?_ ?_
152+
· fun_prop
153+
· rintro i x ⟨⟨x₁, hx₁⟩, ⟨x₂, hx₂⟩⟩
154+
obtain ⟨x₁', hx₁'⟩ :=
155+
Scheme.IsJointlySurjectivePreserving.exists_preimage_fst_triplet_of_prop
156+
(P := @IsOpenImmersion) inferInstance _ _ hx₁.symm
157+
obtain ⟨x₂', hx₂'⟩ :=
158+
Scheme.IsJointlySurjectivePreserving.exists_preimage_fst_triplet_of_prop
159+
(P := @IsOpenImmersion) inferInstance _ _ hx₂.symm
160+
obtain ⟨z, hz⟩ :=
161+
Scheme.IsJointlySurjectivePreserving.exists_preimage_fst_triplet_of_prop
162+
(P := @IsOpenImmersion) inferInstance _ _ (hx₁'.trans hx₂'.symm)
163+
refine ⟨(pullbackFstFstIso _ _ _ _ _ _ (𝒰.map i.1) ?_ ?_).hom.base z, ?_⟩
164+
· simp [pullback.condition]
165+
· simp [pullback.condition]
166+
· dsimp only
167+
rw [← hx₁', ← hz, ← Scheme.comp_base_apply]
168+
erw [← Scheme.comp_base_apply]
169+
congr 4
170+
apply pullback.hom_ext <;> simp [𝓤, ← pullback.condition, ← pullback.condition_assoc]
171+
· intro i
172+
have := H (S.affineOpenCover.obj i.1) (((𝒰.pullbackCover f).obj i.1).affineOpenCover.obj i.2.1)
173+
(((𝒰.pullbackCover g).obj i.1).affineOpenCover.obj i.2.2)
174+
((𝒱 i.1).map i.2.1 ≫ 𝒰.pullbackHom f i.1)
175+
((𝒲 i.1).map i.2.2 ≫ 𝒰.pullbackHom g i.1)
176+
((𝒱 i.1).map i.2.1 ≫ (𝒰.pullbackCover f).map i.1)
177+
((𝒲 i.1).map i.2.2 ≫ (𝒰.pullbackCover g).map i.1)
178+
(𝒰.map i.1) (by simp [pullback.condition]) (by simp [pullback.condition])
179+
inferInstance inferInstance inferInstance
180+
convert this using 6
181+
apply pullback.hom_ext <;>
182+
simp [𝓤, ← pullback.condition, ← pullback.condition_assoc, Scheme.Cover.pullbackHom]
183+
184+
end SurjectiveOnStalks
185+
186+
end AlgebraicGeometry

Mathlib/AlgebraicGeometry/Scheme.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,13 +214,25 @@ def forgetToTop : Scheme ⥤ TopCat :=
214214
noncomputable def homeoOfIso {X Y : Scheme.{u}} (e : X ≅ Y) : X ≃ₜ Y :=
215215
TopCat.homeoOfIso (forgetToTop.mapIso e)
216216

217+
@[simp]
218+
lemma homeoOfIso_symm {X Y : Scheme} (e : X ≅ Y) :
219+
(homeoOfIso e).symm = homeoOfIso e.symm := rfl
220+
221+
@[simp]
222+
lemma homeoOfIso_apply {X Y : Scheme} (e : X ≅ Y) (x : X) :
223+
homeoOfIso e x = e.hom.base x := rfl
224+
217225
alias _root_.CategoryTheory.Iso.schemeIsoToHomeo := homeoOfIso
218226

219227
/-- An isomorphism of schemes induces a homeomorphism of the underlying topological spaces. -/
220228
noncomputable def Hom.homeomorph {X Y : Scheme.{u}} (f : X.Hom Y) [IsIso (C := Scheme) f] :
221229
X ≃ₜ Y :=
222230
(asIso f).schemeIsoToHomeo
223231

232+
@[simp]
233+
lemma Hom.homeomorph_apply {X Y : Scheme.{u}} (f : X.Hom Y) [IsIso (C := Scheme) f] (x) :
234+
f.homeomorph x = f.base x := rfl
235+
224236
-- Porting note: Lean seems not able to find this coercion any more
225237
instance hasCoeToTopCat : CoeOut Scheme TopCat where
226238
coe X := X.carrier

Mathlib/Topology/LocalAtTarget.lean

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,47 @@ theorem isEmbedding_iff_of_iSup_eq_top (h : Continuous f) :
185185
convert congr_arg SetLike.coe hU
186186
simp
187187

188+
omit hU in
189+
/--
190+
Given a continuous map `f : X → Y` between topological spaces.
191+
Suppose we have an open cover `V i` of the range of `f`, and an open cover `U i` of `X` that is
192+
coarser than the pullback of `V` under `f`.
193+
To check that `f` is an embedding it suffices to check that `U i → Y` is an embedding for all `i`.
194+
-/
195+
theorem isEmbedding_of_iSup_eq_top_of_preimage_subset_range
196+
{X Y} [TopologicalSpace X] [TopologicalSpace Y]
197+
(f : X → Y) (h : Continuous f) {ι : Type*}
198+
(U : ι → Opens Y) (hU : Set.range f ⊆ (iSup U : _))
199+
(V : ι → Type*) [∀ i, TopologicalSpace (V i)]
200+
(iV : ∀ i, V i → X) (hiV : ∀ i, Continuous (iV i)) (hV : ∀ i, f ⁻¹' U i ⊆ Set.range (iV i))
201+
(hV' : ∀ i, IsEmbedding (f ∘ iV i)) : IsEmbedding f := by
202+
wlog hU' : iSup U = ⊤
203+
· let f₀ : X → Set.range f := fun x ↦ ⟨f x, ⟨x, rfl⟩⟩
204+
suffices IsEmbedding f₀ from IsEmbedding.subtypeVal.comp this
205+
have hU'' : (⨆ i, (U i).comap ⟨Subtype.val, continuous_subtype_val⟩ :
206+
Opens (Set.range f)) = ⊤ := by
207+
rw [← top_le_iff]
208+
simpa [Set.range_subset_iff, SetLike.le_def] using hU
209+
refine this _ ?_ _ ?_ V iV hiV ?_ ?_ hU''
210+
· fun_prop
211+
· rw [hU'']; simp
212+
· exact hV
213+
· exact fun i ↦ IsEmbedding.of_comp (by fun_prop) continuous_subtype_val (hV' i)
214+
rw [isEmbedding_iff_of_iSup_eq_top hU' h]
215+
intro i
216+
let f' := (Subtype.val ∘ (f ⁻¹' U i).restrictPreimage (iV i))
217+
have : IsEmbedding f' :=
218+
IsEmbedding.subtypeVal.comp ((IsEmbedding.of_comp (hiV i) h (hV' _)).restrictPreimage _)
219+
have hf' : Set.range f' = f ⁻¹' U i := by
220+
simpa [f', Set.range_comp, Set.range_restrictPreimage] using hV i
221+
let e := (Homeomorph.ofIsEmbedding _ this).trans (Homeomorph.setCongr hf')
222+
refine IsEmbedding.of_comp (by fun_prop) continuous_subtype_val ?_
223+
convert ((hV' i).comp IsEmbedding.subtypeVal).comp e.symm.isEmbedding
224+
ext x
225+
obtain ⟨x, rfl⟩ := e.surjective x
226+
simp
227+
rfl
228+
188229
@[deprecated (since := "2024-10-26")]
189230
alias embedding_iff_embedding_of_iSup_eq_top := isEmbedding_iff_of_iSup_eq_top
190231

0 commit comments

Comments
 (0)