Skip to content

Commit 2c4e63c

Browse files
committed
feat: add IsEmbedding.sumElim_of_separatingNhds (leanprover-community#26099)
Characterise when the Sum.elim of two inducing maps resp. embeddings is an embedding, and deduce that the ranges of the two maps lying in separated neighbourhoods suffices. This is used in my bordism theory project. Co-authored by: @plp127
1 parent f4542b3 commit 2c4e63c

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

Mathlib/Data/Sum/Basic.lean

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,14 @@ lemma not_isLeft_and_isRight {x : α ⊕ β} : ¬(x.isLeft ∧ x.isRight) := by
2121

2222
namespace Sum
2323

24+
@[simp]
25+
theorem elim_swap {α β γ : Type*} {f : α → γ} {g : β → γ} :
26+
Sum.elim f g ∘ Sum.swap = Sum.elim g f := by
27+
ext x
28+
cases x with
29+
| inl x => simp
30+
| inr x => simp
31+
2432
-- Lean has removed the `@[simp]` attribute on these. For now Mathlib adds it back.
2533
attribute [simp] Sum.forall Sum.exists
2634

Mathlib/Topology/Constructions/SumProd.lean

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Johannes Hölzl, Mario Carneiro, Patrick Massot
55
-/
66
import Mathlib.Topology.Homeomorph.Defs
77
import Mathlib.Topology.Maps.Basic
8+
import Mathlib.Topology.Separation.SeparatedNhds
89

910
/-!
1011
# Disjoint unions and products of topological spaces
@@ -993,4 +994,97 @@ def prodSumDistrib : X × (Y ⊕ Z) ≃ₜ (X × Y) ⊕ (X × Z) :=
993994

994995
end Homeomorph
995996

997+
section IsInducing
998+
999+
variable {f : X → Z} {g : Y → Z}
1000+
1001+
/-- If `Sum.elim f g` is an inducing map, then so is `f`. -/
1002+
lemma Topology.IsInducing.sumElim_left (h : IsInducing (Sum.elim f g)) : IsInducing f :=
1003+
elim_comp_inl f g ▸ h.comp IsEmbedding.inl.isInducing
1004+
1005+
/-- If `Sum.elim f g` is an inducing map, then so is `g`. -/
1006+
lemma Topology.IsInducing.sumElim_right (h : IsInducing (Sum.elim f g)) : IsInducing g :=
1007+
elim_comp_inr f g ▸ h.comp IsEmbedding.inr.isInducing
1008+
1009+
/-- If `f` and `g` are inducing maps whose ranges are separated, then `Sum.elim f g` is inducing. -/
1010+
theorem Topology.IsInducing.sumElim (hf : IsInducing f) (hg : IsInducing g)
1011+
(hFg : Disjoint (closure (range f)) (range g)) (hfG : Disjoint (range f) (closure (range g))) :
1012+
IsInducing (Sum.elim f g) := by
1013+
rw [← disjoint_principal_nhdsSet] at hFg
1014+
rw [← disjoint_nhdsSet_principal] at hfG
1015+
rw [isInducing_iff_nhds]
1016+
intro x
1017+
apply le_antisymm ((hf.continuous.sumElim hg.continuous).tendsto x).le_comap
1018+
obtain x | x := x <;>
1019+
simp only [comap_sumElim_eq, nhds_inl, nhds_inr, elim_inl, elim_inr, ← hf.nhds_eq_comap,
1020+
← hg.nhds_eq_comap, sup_le_iff, le_rfl, true_and, and_true] <;>
1021+
convert bot_le (α := Filter (X ⊕ Y)) <;>
1022+
rw [map_eq_bot_iff, comap_eq_bot_iff_compl_range]
1023+
· rw [← disjoint_principal_right]
1024+
exact hfG.mono_left (nhds_le_nhdsSet (mem_range_self x))
1025+
· rw [← disjoint_principal_left]
1026+
exact hFg.mono_right (nhds_le_nhdsSet (mem_range_self x))
1027+
1028+
/-- If `Sum.elim f g` is inducing, `closure (range f)` and `range g` must be disjoint.
1029+
This is an auxiliary result towards proving `isInducing_sumElim`. -/
1030+
theorem Topology.IsInducing.disjoint_of_sumElim_aux (h : IsInducing (Sum.elim f g)) :
1031+
Disjoint (closure (range f)) (range g) := by
1032+
rcases h.isClosed_iff.mp isClosed_range_inl with ⟨C, C_closed, hC⟩
1033+
have A : closure (range f) ⊆ C := by
1034+
rw [C_closed.closure_subset_iff, ← elim_comp_inl f g, range_comp, image_subset_iff, hC]
1035+
have B : Disjoint C (range g) := by
1036+
rw [← image_univ, disjoint_image_right, ← elim_comp_inr f g, preimage_comp, hC,
1037+
← disjoint_image_right, ← image_univ]
1038+
exact disjoint_image_inl_image_inr
1039+
exact B.mono_left A
1040+
1041+
theorem IsOpenEmbedding.sumSwap : IsOpenEmbedding (@Sum.swap X Y) :=
1042+
(Homeomorph.sumComm X Y).isOpenEmbedding
1043+
1044+
theorem IsInducing.sumSwap : IsInducing (@Sum.swap X Y) := IsOpenEmbedding.sumSwap.isInducing
1045+
1046+
theorem isInducing_sumElim :
1047+
IsInducing (Sum.elim f g) ↔ IsInducing f ∧ IsInducing g ∧
1048+
Disjoint (closure (range f)) (range g) ∧ Disjoint (range f) (closure (range g)) :=
1049+
fun h ↦ ⟨h.sumElim_left, h.sumElim_right, h.disjoint_of_sumElim_aux,
1050+
((Sum.elim_swap ▸ h.comp IsInducing.sumSwap).disjoint_of_sumElim_aux ).symm⟩,
1051+
fun ⟨hf, hg, hFg, hfG⟩ ↦ hf.sumElim hg hFg hfG⟩
1052+
1053+
lemma Topology.IsInducing.sumElim_of_separatedNhds
1054+
(hf : IsInducing f) (hg : IsInducing g) (hsep : SeparatedNhds (range f) (range g)) :
1055+
IsInducing (Sum.elim f g) :=
1056+
hf.sumElim hg hsep.disjoint_closure_left hsep.disjoint_closure_right
1057+
1058+
/-- If `Sum.elim f g` is an embedding, then so is `f`. -/
1059+
lemma Topology.IsEmbedding.sumElim_left (h : IsEmbedding (Sum.elim f g)) : IsEmbedding f :=
1060+
elim_comp_inl f g ▸ h.comp IsEmbedding.inl
1061+
1062+
/-- If `Sum.elim f g` is an embedding, then so is `g`. -/
1063+
lemma Topology.IsEmbedding.sumElim_right (h : IsEmbedding (Sum.elim f g)) : IsEmbedding g :=
1064+
elim_comp_inr f g ▸ h.comp IsEmbedding.inr
1065+
1066+
theorem isEmbedding_sumElim :
1067+
IsEmbedding (Sum.elim f g) ↔ IsEmbedding f ∧ IsEmbedding g ∧
1068+
Disjoint (closure (range f)) (range g) ∧ Disjoint (range f) (closure (range g)) := by
1069+
simp_rw [isEmbedding_iff, isInducing_sumElim, Sum.elim_injective]
1070+
constructor
1071+
· intro ⟨⟨hf₁, hg₁, hFg, hfG⟩, ⟨hf₂, hg₂, f_ne_g⟩⟩
1072+
exact ⟨⟨hf₁, hf₂⟩, ⟨hg₁, hg₂⟩, hFg, hfG⟩
1073+
· intro ⟨⟨hf₁, hf₂⟩, ⟨hg₁, hg₂⟩, hFg, hfG⟩
1074+
refine ⟨⟨hf₁, hg₁, hFg, hfG⟩, ⟨hf₂, hg₂, ?_⟩⟩
1075+
exact fun a b ↦ hfG.ne_of_mem (mem_range_self a) (subset_closure (mem_range_self b))
1076+
1077+
/-- If `f` and `g` are embeddings whose ranges are separated, `Sum.elim f g` is an embedding. -/
1078+
theorem Topology.IsEmbedding.sumElim (hf : IsEmbedding f) (hg : IsEmbedding g)
1079+
(hFg : Disjoint (closure (range f)) (range g)) (hfG : Disjoint (range f) (closure (range g))) :
1080+
IsEmbedding (Sum.elim f g) :=
1081+
isEmbedding_sumElim.mpr ⟨hf, hg, hFg, hfG⟩
1082+
1083+
lemma Topology.IsEmbedding.sumElim_of_separatedNhds
1084+
(hf : IsEmbedding f) (hg : IsEmbedding g) (hsep : SeparatedNhds (range f) (range g)) :
1085+
IsEmbedding (Sum.elim f g) :=
1086+
hf.sumElim hg hsep.disjoint_closure_left hsep.disjoint_closure_right
1087+
1088+
end IsInducing
1089+
9961090
end Sum

0 commit comments

Comments
 (0)