Skip to content

Commit 78dc2d5

Browse files
committed
Modulize; adjust for current mathlib; adjust deprecations; minor adjustments
1 parent ceeb592 commit 78dc2d5

2 files changed

Lines changed: 45 additions & 40 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2076,6 +2076,7 @@ public import Mathlib.Analysis.NormedSpace.FunctionSeries
20762076
public import Mathlib.Analysis.NormedSpace.HahnBanach.Extension
20772077
public import Mathlib.Analysis.NormedSpace.HahnBanach.SeparatingDual
20782078
public import Mathlib.Analysis.NormedSpace.HahnBanach.Separation
2079+
public import Mathlib.Analysis.NormedSpace.HahnBanach.Splits
20792080
public import Mathlib.Analysis.NormedSpace.HomeomorphBall
20802081
public import Mathlib.Analysis.NormedSpace.IndicatorFunction
20812082
public import Mathlib.Analysis.NormedSpace.Int

Mathlib/Analysis/NormedSpace/HahnBanach/Splits.lean

Lines changed: 44 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ Copyright (c) 2025 Michael Rothgang. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Michael Rothgang
55
-/
6-
import Mathlib.Analysis.Normed.Module.Complemented
7-
import Mathlib.Analysis.NormedSpace.HahnBanach.Extension
6+
module
7+
8+
public import Mathlib.Analysis.Normed.Module.Complemented
9+
public import Mathlib.Analysis.Normed.Module.HahnBanach
810

911
/-! # Linear maps which split
1012
@@ -19,6 +21,8 @@ This concept is used to give a conceptual definition of immersions between Banac
1921
2022
-/
2123

24+
public section
25+
2226
open Function Set
2327

2428
variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E E' F F' G : Type*}
@@ -28,20 +32,11 @@ variable {𝕜 : Type*} [NontriviallyNormedField 𝕜] {E E' F F' G : Type*}
2832

2933
noncomputable section
3034

31-
namespace LinearMap
32-
33-
lemma range_prodMap {f : E →L[𝕜] F} {g : E' →L[𝕜] F'} :
34-
range (f.prodMap g) = (range f).prod (range g) := by
35-
ext x
36-
simp [Prod.ext_iff]
37-
38-
lemma _root_.Submodule.map_add {f : E →L[𝕜] F} {p q : Submodule 𝕜 E} :
39-
Submodule.map f p + Submodule.map f q = Submodule.map f (p + q) := by
35+
lemma Submodule.map_add {f : E →L[𝕜] F} {p q : Submodule 𝕜 E} :
36+
p.map (f : E →ₛₗ[.id _] F) + q.map (f : E →ₛₗ[.id _] F) = (p + q).map (f : E →ₛₗ[.id _] F) := by
4037
ext x
4138
simp
4239

43-
end LinearMap
44-
4540
section
4641

4742
variable {R M N : Type*} [Semiring R] [AddCommMonoid M] [Module R M] [AddCommMonoid N] [Module R N]
@@ -63,7 +58,7 @@ end
6358
/-- A continuous linear map `f : E → F` **splits** iff it is injective, has closed range and
6459
its image has a closed complement. -/
6560
protected def ContinuousLinearMap.Splits (f : E →L[𝕜] F) : Prop :=
66-
Injective f ∧ IsClosed (Set.range f) ∧ Submodule.ClosedComplemented (LinearMap.range f)
61+
Injective f ∧ IsClosed (Set.range f) ∧ Submodule.ClosedComplemented (f.range)
6762

6863
-- XXX: should this be about ContinuousLinearMapClass?
6964
namespace ContinuousLinearMap.Splits
@@ -74,7 +69,7 @@ lemma injective (h : f.Splits) : Injective f := h.1
7469

7570
lemma isClosed_range (h : f.Splits) : IsClosed (Set.range f) := h.2.1
7671

77-
lemma closedComplemented (h : f.Splits) : Submodule.ClosedComplemented (LinearMap.range f) :=
72+
lemma closedComplemented (h : f.Splits) : Submodule.ClosedComplemented (f.range) :=
7873
h.2.2
7974

8075
/-- Choice of a closed complement of `range f` -/
@@ -84,7 +79,7 @@ def complement (h : f.Splits) : Submodule 𝕜 F :=
8479
lemma complement_isClosed (h : f.Splits) : IsClosed (X := F) h.complement :=
8580
(Classical.choose_spec h.closedComplemented.exists_isClosed_isCompl).1
8681

87-
lemma complement_isCompl (h : f.Splits) : IsCompl (LinearMap.range f) h.complement :=
82+
lemma complement_isCompl (h : f.Splits) : IsCompl f.range h.complement :=
8883
(Classical.choose_spec h.closedComplemented.exists_isClosed_isCompl).2
8984

9085
lemma congr {g : E →L[𝕜] F} (hf : f.Splits) (hfg : g = f) : g.Splits :=
@@ -97,24 +92,19 @@ lemma _root_.ContinuousLinearEquiv.splits (f : E ≃L[𝕜] F) : f.toContinuousL
9792
apply EquivLike.injective
9893
· rw [f.coe_coe, EquivLike.range_eq_univ]
9994
exact isClosed_univ
100-
· erw [LinearMap.range_eq_top_of_surjective f (EquivLike.surjective f)]
95+
· erw [f.range_eq_top_of_surjective (EquivLike.surjective f)]
10196
exact Submodule.closedComplemented_top
10297

10398
/-- If `f` and `g` split, then so does `f × g`. -/
10499
lemma prodMap (hf : f.Splits) (hg : g.Splits) : (f.prodMap g).Splits := by
105100
refine ⟨hf.injective.prodMap hg.injective, ?_, ?_⟩
106-
· rw [coe_prodMap', range_prod_map]
101+
· rw [coe_prodMap', range_prodMap]
107102
exact (hf.isClosed_range).prod hg.isClosed_range
108-
· rw [LinearMap.range_prodMap]
109-
exact hf.closedComplemented.prod hg.closedComplemented
103+
· simpa using hf.closedComplemented.prod hg.closedComplemented
110104

111-
section RCLike
105+
section
112106

113-
variable {𝕜 : Type*} [RCLike 𝕜] {E E' F F' G : Type*}
114-
[NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E']
115-
[NormedAddCommGroup F] [NormedSpace 𝕜 F] [NormedAddCommGroup F'] [NormedSpace 𝕜 F']
116-
[NormedAddCommGroup G] [NormedSpace 𝕜 G]
117-
[CompleteSpace E] [CompleteSpace F] [CompleteSpace G] {f : E →L[𝕜] F} {g : E' →L[𝕜] F'}
107+
variable [CompleteSpace E] [CompleteSpace F] [CompleteSpace G]
118108

119109
/-- If `f : E → F` splits and `E`, `F` are real or complex Banach spaces, `f` is anti-Lipschitz.
120110
This result is unseful to prove that the composition of split maps is a split map. -/
@@ -131,9 +121,9 @@ lemma isClosedMap (hf : f.Splits) : IsClosedMap f :=
131121
(hf.antilipschitzWith.isClosedEmbedding f.uniformContinuous).isClosedMap
132122

133123
omit [CompleteSpace F] [CompleteSpace G] in
134-
lemma disjoint_aux {g : F →L[𝕜] G} {F₁ F₂ : Submodule 𝕜 F} {G' : Submodule 𝕜 G}
135-
(hF : Disjoint F₁ F₂) (hG' : Disjoint (LinearMap.range g) G') (hg : Injective g) :
136-
Disjoint (Submodule.map g F₁) (Submodule.map g F₂ + G') := by
124+
lemma disjoint_aux {g : F →L[𝕜] G} {F₁ F₂ : Submodule 𝕜 F} {G' : Submodule 𝕜 G}
125+
(hF : Disjoint F₁ F₂) (hG' : Disjoint g.range G') (hg : Injective g) :
126+
Disjoint (F₁.map (g : F →ₛₗ[.id _] G)) (F₂.map (g : F →ₛₗ[.id _] G) + G') := by
137127
rw [Submodule.disjoint_def] at hF hG' ⊢
138128
intro x h1 h2
139129
-- Write x = g (f x₀)
@@ -149,6 +139,7 @@ lemma disjoint_aux {g : F →L[𝕜] G} {F₁ F₂ : Submodule 𝕜 F} {G' : Su
149139
have : z ∈ range g := by
150140
rw [this, ← hgx₀, ← hgy₀, ← map_sub]
151141
use x₀ - y₀ -- Can or should this be a simproc?
142+
simp only [map_sub, coe_coe]
152143
have : z = 0 := hG' z this hz
153144
-- g y₀ = y = x = g x₀, thus x₀ = y₀.
154145
have hxy : x = y := by rw [← add_zero y, ← this, hxyz]
@@ -160,16 +151,27 @@ lemma disjoint_aux {g : F →L[𝕜] G} {F₁ F₂ : Submodule 𝕜 F} {G' : Su
160151
have : y₀ = 0 := hF y₀ ((hg aux) ▸ hx₀) hy₀
161152
simp [hxy, ← hgy₀, this]
162153

154+
end
155+
156+
section RCLike
157+
158+
variable {𝕜 : Type*} [RCLike 𝕜] {E E' F F' G : Type*}
159+
[NormedAddCommGroup E] [NormedSpace 𝕜 E] [NormedAddCommGroup E'] [NormedSpace 𝕜 E']
160+
[NormedAddCommGroup F] [NormedSpace 𝕜 F] [NormedAddCommGroup F'] [NormedSpace 𝕜 F']
161+
[NormedAddCommGroup G] [NormedSpace 𝕜 G]
162+
[CompleteSpace E] [CompleteSpace F] [CompleteSpace G] {f : E →L[𝕜] F} {g : E' →L[𝕜] F'}
163+
163164
/-- The composition of split continuous linear maps between real or complex Banach spaces splits. -/
164-
lemma comp {g : F →L[𝕜] G} (hg : g.Splits) (hf : f.Splits) : (g.comp f).Splits := by
165+
lemma comp {g : F →L[𝕜] G} (hg : g.Splits) (hf : f.Splits) : (g.comp f).Splits := by
165166
have h : IsClosed (range (g ∘ f)) := by
166167
rw [range_comp]
167168
apply hg.isClosedMap _ hf.isClosed_range
168169
refine ⟨hg.injective.comp hf.injective, h, ?_⟩
169170
· rw [Submodule.closedComplemented_iff_isClosed_exists_isClosed_isCompl]
170171
let F' := hf.complement
171-
refine ⟨h, (F'.map g) + hg.complement, ?_, ?_⟩
172-
· have : IsClosed (X := G) (F'.map g) := hg.isClosedMap _ hf.complement_isClosed
172+
refine ⟨h, (F'.map (g : F →ₛₗ[.id _] G)) + hg.complement, ?_, ?_⟩
173+
· have : IsClosed (X := G) (F'.map (g : F →ₛₗ[.id _] G)) :=
174+
hg.isClosedMap _ hf.complement_isClosed
173175
have : IsClosed (X := G) hg.complement := hg.complement_isClosed
174176
-- In general, the sum of closed subspaces need not be closed.
175177
-- In this case, however, this is true as F'.map G is a closed subspace of range g,
@@ -182,7 +184,7 @@ lemma comp {g : F →L[𝕜] G} (hg : g.Splits) (hf : f.Splits) : (g.comp f).Sp
182184
intro u u₀ hu hconv
183185
simp_rw [Submodule.add_eq_sup, SetLike.mem_coe, Submodule.mem_sup] at hu
184186
-- Write u_n = x_n + y_n, for x_n in g(F') and y_n in G'.
185-
let x : ℕ → Submodule.map g F' := by
187+
let x : ℕ → Submodule.map (g : F →ₛₗ[.id _] G) F' := by
186188
intro n
187189
choose y hy z hz hyz using hu n
188190
exact ⟨y, hy⟩
@@ -191,7 +193,7 @@ lemma comp {g : F →L[𝕜] G} (hg : g.Splits) (hf : f.Splits) : (g.comp f).Sp
191193
choose y hy z hz hyz using hu n
192194
exact ⟨z, hz⟩
193195
-- By construction, u_n = x_n + y_n.
194-
have (n) : u n = x n + y n := by
196+
have (n : ℕ) : u n = x n + y n := by
195197
simp [x, y]
196198
sorry -- need more API lemmas
197199
-- x equals the projection into g(F'); y equals the projection onto hg.complement.
@@ -203,15 +205,16 @@ lemma comp {g : F →L[𝕜] G} (hg : g.Splits) (hf : f.Splits) : (g.comp f).Sp
203205
-- Thus, by continuity, x_n converges to some point in g(F').
204206
-- By linearity, u_n converges to a point in g(F')+G', qed.
205207
sorry
206-
· have : LinearMap.range (g.comp f) = Submodule.map g (LinearMap.range f) := by aesop
208+
· have : LinearMap.range (g.comp f : E →ₛₗ[.id _] G) = f.range.map (g : F →ₛₗ[.id _] G) := by
209+
aesop
207210
-- some lemmas which could be useful for a manual proof:
208211
-- rw [LinearMap.range_comp]; rw [LinearMap.range_eq_map]; rw [Submodule.map_comp f g ⊤]
209212
-- rw [← LinearMap.range_eq_map f]
210213
constructor
211214
· exact this ▸ disjoint_aux hf.complement_isCompl.1 hg.complement_isCompl.1 hg.injective
212215
· rw [codisjoint_iff, this, ← Submodule.add_eq_sup, Submodule.sum_assoc, Submodule.map_add]
213216
rw [LinearMap.range_eq_map]
214-
trans Submodule.map g ⊤ + hg.complement
217+
trans Submodule.map (g : F →ₛₗ[.id _] G) ⊤ + hg.complement
215218
· congr
216219
rw [Submodule.add_eq_sup, ← codisjoint_iff]
217220
simpa using hf.complement_isCompl.2
@@ -230,15 +233,16 @@ omit [CompleteSpace E] [CompleteSpace F] [CompleteSpace G]
230233

231234
/-- If `f : E → F` is injective and `F` is finite-dimensional, then `f` splits. -/
232235
lemma of_injective_of_finiteDimensional [FiniteDimensional 𝕜 F] (hf : Injective f) : f.Splits := by
233-
have aux : IsClosed (X := F) (LinearMap.range f) := Submodule.closed_of_finiteDimensional _
234-
exact ⟨hf, aux, Submodule.ClosedComplemented.of_finiteDimensional (LinearMap.range f)
236+
have aux : IsClosed (X := F) f.range := Submodule.closed_of_finiteDimensional _
237+
exact ⟨hf, aux, Submodule.ClosedComplemented.of_finiteDimensional f.range⟩
235238

236239
/-- If `f : E → F` is injective and `E` is finite-dimensional, then `f` splits. -/
237240
lemma of_injective_of_finiteDimensional_of_completeSpace
238241
[FiniteDimensional 𝕜 E] (hf : Injective f) : f.Splits := by
239-
have aux : IsClosed (X := F) (LinearMap.range f) := Submodule.closed_of_finiteDimensional _
240-
exact ⟨hf, aux, Submodule.ClosedComplemented.of_finiteDimensional (LinearMap.range f)
242+
have aux : IsClosed (X := F) f.range := Submodule.closed_of_finiteDimensional _
243+
exact ⟨hf, aux, Submodule.ClosedComplemented.of_finiteDimensional f.range⟩
241244

245+
-- FUTURE (once mathlib has a notion of Fredholm operators):
242246
-- If `f : E → F` is injective, `E` and `F` are Banach and `f` is Fredholm, then `f` splits.
243247

244248
end RCLike

0 commit comments

Comments
 (0)