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

Commit 2543b68

Browse files
urkudPatrickMassotsgouezel
committed
refactor(*): migrate to dense API (#4447)
@PatrickMassot introduced `dense` in #4399. In this PR I review the API and migrate many definitions and lemmas to use `dense s` instead of `closure s = univ`. I also generalize `second_countable_of_separable` to a `uniform_space` with a countably generated uniformity filter. ## API changes ### Use `dense` or `dense_range` instead of `closure _ = univ` #### Lemmas - `has_fderiv_within_at.unique_diff_within_at`; - `exists_dense_seq`; - `dense_Inter_of_open_nat`; - `dense_sInter_of_open`; - `dense_bInter_of_open`; - `dense_Inter_of_open`; - `dense_sInter_of_Gδ`; - `dense_bInter_of_Gδ`; - `eventually_residual`; - `mem_residual`; - `dense_bUnion_interior_of_closed`; - `dense_sUnion_interior_of_closed`; - `dense_Union_interior_of_closed`; - `Kuratowski_embeddinng.embedding_of_subset_isometry`; - `continuous_extend_from`; #### Definitions - `unique_diff_within_at`; - `residual`; ### Rename - `submodule.linear_eq_on` → `linear_map.eq_on_span`, `linear_map.eq_on_span'`; - `submodule.linear_map.ext_on` → `linear_map.ext_on_range`; - `filter.is_countably_generated.has_antimono_basis` → `filter.is_countably_generated.exists_antimono_basis`; - `exists_countable_closure_eq_univ` → `exists_countable_dense`, use `dense`; - `dense_seq_dense` → `dense_range_dense_seq`, use `dense`; - `dense_range.separable_space` is now `protected`; - `dense_of_subset_dense` → `dense.mono`; - `dense_inter_of_open_left` → `dense.inter_of_open_left`; - `dense_inter_of_open_right` → `dense.inter_of_open_right`; - `continuous.dense_image_of_dense_range` → `dense_range.dense_image`; - `dense_range.inhabited`, `dense_range.nonempty`: changed API, TODO; - `quotient_dense_of_dense` → `dense.quotient`, use `dense`; - `dense_inducing.separable` → `dense_inducing.separable_space`, add `protected`; - `dense_embedding.separable` → `dense_embedding.separable_space`, add `protected`; - `dense_inter_of_Gδ` → `dense.inter_of_Gδ`; - `stone_cech_unit_dense` → `dense_range_stone_cech_unit`; - `abstract_completion.dense'` → `abstract_completion.closure_range`; - `Cauchy.pure_cauchy_dense` → `Cauchy.dense_range_pure_cauchy`; - `completion.dense` → `completion.dense_range_coe`; - `completion.dense₂` → `completion.dense_range_coe₂`; - `completion.dense₃` → `completion.dense_range_coe₃`; ### New - `has_fderiv_within_at.unique_on` : if `f'` and `f₁'` are two derivatives of `f` within `s` at `x`, then they are equal on the tangent cone to `s` at `x`; - `local_homeomorph.mdifferentiable.mfderiv_bijective`, `local_homeomorph.mdifferentiable.mfderiv_surjective` - `continuous_linear_map.eq_on_closure_span`: if two continuous linear maps are equal on `s`, then they are equal on `closure (submodule.span s)`; - `continuous_linear_map.ext_on`: if two continuous linear maps are equal on a set `s` such that `submodule.span s` is dense, then they are equal; - `dense_closure`: `closure s` is dense iff `s` is dense; - `dense.of_closure`, `dense.closure`: aliases for `dense_closure.mp` and `dense_closure.mpr`; - `dense_univ`: `univ` is dense; - `dense.inter_open_nonempty`: alias for `dense_iff_inter_open.mp`; - `dense.nonempty_iff`: if `s : set α` is a dense set, then `s` is nonempty iff `α` is nonempty; - `dense.nonempty`: a dense set in a nonempty type is nonempty; - `dense_range.some`: given a function with `dense_range` and a point in the codomain, returns a point in the domain; - `function.surjective.dense_range`: a surjective function has dense range; - `continuous.range_subset_closure_image_dense`: closure of the image of a dense set under a continuous function includes the range of this function; - `dense_range.dense_of_maps_to`: if a function with dense range maps a dense set `s` to `t`, then `t` is dense in the codomain; - `dense_range.quotient`; - `dense.prod`: product of two dense sets is dense in the product; - `set.eq_on.closure`; - `continuous.ext_on`; - `linear_map.ext_on` Co-authored-by: Patrick Massot <patrickmassot@free.fr> Co-authored-by: sgouezel <sebastien.gouezel@univ-rennes1.fr>
1 parent fde3d78 commit 2543b68

23 files changed

+347
-313
lines changed

src/analysis/calculus/fderiv.lean

Lines changed: 19 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -240,36 +240,22 @@ begin
240240
rwa [this, zero_add] at L3
241241
end
242242

243+
/-- If `f'` and `f₁'` are two derivatives of `f` within `s` at `x`, then they are equal on the
244+
tangent cone to `s` at `x` -/
245+
theorem has_fderiv_within_at.unique_on (hf : has_fderiv_within_at f f' s x)
246+
(hg : has_fderiv_within_at f f₁' s x) :
247+
eq_on f' f₁' (tangent_cone_at 𝕜 s x) :=
248+
λ y ⟨c, d, dtop, clim, cdlim⟩,
249+
tendsto_nhds_unique (hf.lim at_top dtop clim cdlim) (hg.lim at_top dtop clim cdlim)
250+
243251
/-- `unique_diff_within_at` achieves its goal: it implies the uniqueness of the derivative. -/
244252
theorem unique_diff_within_at.eq (H : unique_diff_within_at 𝕜 s x)
245-
(h : has_fderiv_within_at f f' s x) (h₁ : has_fderiv_within_at f f₁' s x) : f' = f₁' :=
246-
begin
247-
have A : ∀y ∈ tangent_cone_at 𝕜 s x, f' y = f₁' y,
248-
{ rintros y ⟨c, d, dtop, clim, cdlim⟩,
249-
exact tendsto_nhds_unique (h.lim at_top dtop clim cdlim) (h₁.lim at_top dtop clim cdlim) },
250-
have B : ∀y ∈ submodule.span 𝕜 (tangent_cone_at 𝕜 s x), f' y = f₁' y,
251-
{ assume y hy,
252-
apply submodule.span_induction hy,
253-
{ exact λy hy, A y hy },
254-
{ simp only [continuous_linear_map.map_zero] },
255-
{ simp {contextual := tt} },
256-
{ simp {contextual := tt} } },
257-
have C : ∀y ∈ closure ((submodule.span 𝕜 (tangent_cone_at 𝕜 s x)) : set E), f' y = f₁' y,
258-
{ assume y hy,
259-
let K := {y | f' y = f₁' y},
260-
have : (submodule.span 𝕜 (tangent_cone_at 𝕜 s x) : set E) ⊆ K := B,
261-
have : closure (submodule.span 𝕜 (tangent_cone_at 𝕜 s x) : set E) ⊆ closure K :=
262-
closure_mono this,
263-
have : y ∈ closure K := this hy,
264-
rwa (is_closed_eq f'.continuous f₁'.continuous).closure_eq at this },
265-
rw H.1 at C,
266-
ext y,
267-
exact C y (mem_univ _)
268-
end
253+
(hf : has_fderiv_within_at f f' s x) (hg : has_fderiv_within_at f f₁' s x) : f' = f₁' :=
254+
continuous_linear_map.ext_on H.1 (hf.unique_on hg)
269255

270256
theorem unique_diff_on.eq (H : unique_diff_on 𝕜 s) (hx : x ∈ s)
271257
(h : has_fderiv_within_at f f' s x) (h₁ : has_fderiv_within_at f f₁' s x) : f' = f₁' :=
272-
unique_diff_within_at.eq (H x hx) h h₁
258+
(H x hx).eq h h₁
273259

274260
end derivative_uniqueness
275261

@@ -2458,44 +2444,22 @@ end
24582444
under a map with onto derivative has also the unique differentiability property at the image point.
24592445
-/
24602446
lemma has_fderiv_within_at.unique_diff_within_at {x : E} (h : has_fderiv_within_at f f' s x)
2461-
(hs : unique_diff_within_at 𝕜 s x) (h' : closure (range f') = univ) :
2447+
(hs : unique_diff_within_at 𝕜 s x) (h' : dense_range f') :
24622448
unique_diff_within_at 𝕜 (f '' s) (f x) :=
24632449
begin
2464-
have B : ∀v ∈ (submodule.span 𝕜 (tangent_cone_at 𝕜 s x) : set E),
2465-
f' v ∈ (submodule.span 𝕜 (tangent_cone_at 𝕜 (f '' s) (f x)) : set F),
2466-
{ assume v hv,
2467-
apply submodule.span_induction hv,
2468-
{ exact λ w hw, submodule.subset_span (h.maps_to_tangent_cone hw) },
2469-
{ simp },
2470-
{ assume w₁ w₂ hw₁ hw₂,
2471-
rw continuous_linear_map.map_add,
2472-
exact submodule.add_mem (submodule.span 𝕜 (tangent_cone_at 𝕜 (f '' s) (f x))) hw₁ hw₂ },
2473-
{ assume a w hw,
2474-
rw continuous_linear_map.map_smul,
2475-
exact submodule.smul_mem (submodule.span 𝕜 (tangent_cone_at 𝕜 (f '' s) (f x))) _ hw } },
2476-
rw [unique_diff_within_at, ← univ_subset_iff],
2477-
split,
2478-
show f x ∈ closure (f '' s), from h.continuous_within_at.mem_closure_image hs.2,
2479-
show univ ⊆ closure ↑(submodule.span 𝕜 (tangent_cone_at 𝕜 (f '' s) (f x))), from calc
2480-
univ ⊆ closure (range f') : univ_subset_iff.2 h'
2481-
... = closure (f' '' univ) : by rw image_univ
2482-
... = closure (f' '' (closure (submodule.span 𝕜 (tangent_cone_at 𝕜 s x) : set E))) : by rw hs.1
2483-
... ⊆ closure (closure (f' '' (submodule.span 𝕜 (tangent_cone_at 𝕜 s x) : set E))) :
2484-
closure_mono (image_closure_subset_closure_image f'.cont)
2485-
... = closure (f' '' (submodule.span 𝕜 (tangent_cone_at 𝕜 s x) : set E)) : closure_closure
2486-
... ⊆ closure (submodule.span 𝕜 (tangent_cone_at 𝕜 (f '' s) (f x)) : set F) :
2487-
closure_mono (image_subset_iff.mpr B)
2450+
refine ⟨h'.dense_of_maps_to f'.continuous hs.1 _,
2451+
h.continuous_within_at.mem_closure_image hs.2⟩,
2452+
show submodule.span 𝕜 (tangent_cone_at 𝕜 s x) ≤
2453+
(submodule.span 𝕜 (tangent_cone_at 𝕜 (f '' s) (f x))).comap f',
2454+
rw [submodule.span_le],
2455+
exact h.maps_to_tangent_cone.mono (subset.refl _) submodule.subset_span
24882456
end
24892457

24902458
lemma has_fderiv_within_at.unique_diff_within_at_of_continuous_linear_equiv
24912459
{x : E} (e' : E ≃L[𝕜] F) (h : has_fderiv_within_at f (e' : E →L[𝕜] F) s x)
24922460
(hs : unique_diff_within_at 𝕜 s x) :
24932461
unique_diff_within_at 𝕜 (f '' s) (f x) :=
2494-
begin
2495-
apply h.unique_diff_within_at hs,
2496-
have : set.range (e' : E →L[𝕜] F) = univ := e'.to_linear_equiv.to_equiv.range_eq_univ,
2497-
rw [this, closure_univ]
2498-
end
2462+
h.unique_diff_within_at hs e'.surjective.dense_range
24992463

25002464
lemma continuous_linear_equiv.unique_diff_on_preimage_iff (e : F ≃L[𝕜] E) :
25012465
unique_diff_on 𝕜 (e ⁻¹' s) ↔ unique_diff_on 𝕜 s :=

src/analysis/calculus/tangent_cone.lean

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ To avoid pathologies in dimension 0, we also require that `x` belongs to the clo
5050
is automatic when `E` is not `0`-dimensional).
5151
-/
5252
def unique_diff_within_at (s : set E) (x : E) : Prop :=
53-
closure ((submodule.span 𝕜 (tangent_cone_at 𝕜 s x)) : set E) = univ ∧ x ∈ closure s
53+
dense ((submodule.span 𝕜 (tangent_cone_at 𝕜 s x)) : set E) ∧ x ∈ closure s
5454

5555
/-- A property ensuring that the tangent cone to `s` at any of its points spans a dense subset of
5656
the whole space. The main role of this property is to ensure that the differential along `s` is
@@ -268,10 +268,9 @@ lemma unique_diff_within_at.mono_nhds (h : unique_diff_within_at 𝕜 s x)
268268
unique_diff_within_at 𝕜 t x :=
269269
begin
270270
unfold unique_diff_within_at at *,
271-
rw [← univ_subset_iff, ← h.1],
272271
rw [mem_closure_iff_nhds_within_ne_bot] at h ⊢,
273-
exact ⟨closure_mono (submodule.span_mono (tangent_cone_mono_nhds st)),
274-
ne_bot_of_le_ne_bot h.2 st⟩
272+
exact ⟨h.1.mono $ submodule.span_mono $ tangent_cone_mono_nhds st,
273+
h.2.mono st⟩
275274
end
276275

277276
lemma unique_diff_within_at.mono (h : unique_diff_within_at 𝕜 s x) (st : s ⊆ t) :
@@ -317,13 +316,13 @@ lemma unique_diff_within_at.prod {t : set F} {y : F}
317316
unique_diff_within_at 𝕜 (set.prod s t) (x, y) :=
318317
begin
319318
rw [unique_diff_within_at] at ⊢ hs ht,
320-
rw [← univ_subset_iff, closure_prod_eq],
319+
rw [closure_prod_eq],
321320
refine ⟨_, hs.2, ht.2⟩,
322-
have : _ tangent_cone_at 𝕜 (s.prod t) (x, y) :=
323-
union_subset (subset_tangent_cone_prod_left ht.2) (subset_tangent_cone_prod_right hs.2),
324-
refine subset.trans _ (closure_mono $ submodule.span_mono this),
325-
erw [linear_map.span_inl_union_inr, submodule.prod_coe, closure_prod_eq,
326-
hs.1, ht.1, univ_prod_univ]
321+
have : _ ≤ submodule.span 𝕜 (tangent_cone_at 𝕜 (s.prod t) (x, y)) :=
322+
submodule.span_mono (union_subset (subset_tangent_cone_prod_left ht.2)
323+
(subset_tangent_cone_prod_right hs.2)),
324+
rw [linear_map.span_inl_union_inr, submodule.le_def, submodule.prod_coe] at this,
325+
exact (hs.1.prod ht.1).mono this
327326
end
328327

329328
/-- The product of two sets of unique differentiability is a set of unique differentiability. -/
@@ -339,9 +338,9 @@ begin
339338
assume x xs,
340339
rcases hs with ⟨y, hy⟩,
341340
suffices : y - x ∈ interior (tangent_cone_at ℝ s x),
342-
{ refine ⟨_, subset_closure xs⟩,
343-
rw [submodule.eq_top_of_nonempty_interior' _ ⟨y - x, interior_mono submodule.subset_span this⟩,
344-
submodule.top_coe, closure_univ]; apply_instance },
341+
{ refine ⟨dense.of_closure _, subset_closure xs⟩,
342+
simp [(submodule.span ℝ (tangent_cone_at ℝ s x)).eq_top_of_nonempty_interior'
343+
⟨y - x, interior_mono submodule.subset_span this⟩] },
345344
rw [mem_interior_iff_mem_nhds] at hy ⊢,
346345
apply mem_sets_of_superset ((is_open_map_add_right (-x)).image_mem_nhds hy),
347346
rintros _ ⟨z, zs, rfl⟩,

src/analysis/normed_space/finite_dimension.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ begin
258258
from metric.second_countable_of_countable_discretization
259259
(λ ε ε_pos, ⟨fin d → ℕ, by apply_instance, this ε ε_pos⟩),
260260
intros ε ε_pos,
261-
obtain ⟨u : ℕ → F, hu : closure (range u) = univ⟩ := exists_dense_seq F,
261+
obtain ⟨u : ℕ → F, hu : dense_range u⟩ := exists_dense_seq F,
262262
obtain ⟨v : fin d → E, hv : is_basis 𝕜 v⟩ := finite_dimensional.fin_basis 𝕜 E,
263263
obtain ⟨C : ℝ, C_pos : 0 < C,
264264
hC : ∀ {φ : E →L[𝕜] F} {M : ℝ}, 0 ≤ M → (∀ i, ∥φ (v i)∥ ≤ M) → ∥φ∥ ≤ C * M⟩ := hv.op_norm_le,
@@ -269,7 +269,7 @@ begin
269269
have : ∀ i, ∃ n, ∥φ (v i) - u n∥ ≤ ε/(2*C),
270270
{ simp only [norm_sub_rev],
271271
intro i,
272-
have : φ (v i) ∈ closure (range u), by simp [hu],
272+
have : φ (v i) ∈ closure (range u) := hu _,
273273
obtain ⟨n, hn⟩ : ∃ n, ∥u n - φ (v i)∥ < ε / (2 * C),
274274
{ rw mem_closure_iff_nhds_basis metric.nhds_basis_ball at this,
275275
specialize this (ε/(2*C)) hε2C,

src/geometry/manifold/mfderiv.lean

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,10 +1230,17 @@ protected def mfderiv {x : M} (hx : x ∈ e.source) :
12301230
end,
12311231
.. mfderiv I I' e x }
12321232

1233+
lemma mfderiv_bijective {x : M} (hx : x ∈ e.source) :
1234+
function.bijective (mfderiv I I' e x) :=
1235+
(he.mfderiv hx).bijective
1236+
1237+
lemma mfderiv_surjective {x : M} (hx : x ∈ e.source) :
1238+
function.surjective (mfderiv I I' e x) :=
1239+
(he.mfderiv hx).surjective
12331240

12341241
lemma range_mfderiv_eq_univ {x : M} (hx : x ∈ e.source) :
12351242
range (mfderiv I I' e x) = univ :=
1236-
(he.mfderiv hx).to_linear_equiv.to_equiv.range_eq_univ
1243+
(he.mfderiv_surjective hx).range_eq
12371244

12381245
lemma trans (he': e'.mdifferentiable I' I'') : (e.trans e').mdifferentiable I I'' :=
12391246
begin
@@ -1313,16 +1320,15 @@ begin
13131320
D₁.mono (by mfld_set_tac),
13141321
-- The derivative `G'` is onto, as it is the derivative of a local diffeomorphism, the composition
13151322
-- of the two charts and of `e`.
1316-
have C : range (G' : E → E') = univ,
1323+
have C : dense_range (G' : E → E'),
13171324
{ have : G' = mfderiv I I' ((chart_at H z).symm ≫ₕ e ≫ₕ (chart_at H' x)) ((chart_at H z : M → H) z),
13181325
by { rw (Diff.mdifferentiable_at Mmem).mfderiv, refl },
13191326
rw this,
1320-
exact Diff.range_mfderiv_eq_univ Mmem },
1321-
have C₂ : closure (range (G' : E → E')) = univ, by rw [C₁, closure_univ],
1327+
exact (Diff.mfderiv_surjective Mmem).dense_range },
13221328
-- key step: thanks to what we have proved about it, `G` preserves the unique derivative property
13231329
have key : unique_diff_within_at 𝕜
13241330
(G '' (F.symm ⁻¹' (s ∩ (e.source ∩ e ⁻¹' ((ext_chart_at I' x).source))) ∩ F.target))
1325-
(G (F z)) := D₂.unique_diff_within_at B C,
1331+
(G (F z)) := D₂.unique_diff_within_at B C,
13261332
have : G (F z) = (ext_chart_at I' x) x, by { dsimp [G, F], simp only [hx.1] with mfld_simps },
13271333
rw this at key,
13281334
apply key.mono,

src/linear_algebra/basic.lean

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -924,17 +924,6 @@ span_eq_bot.trans $ by simp
924924
span_eq_of_le _ (image_subset _ subset_span) $ map_le_iff_le_comap.2 $
925925
span_le.2 $ image_subset_iff.1 subset_span
926926

927-
lemma linear_eq_on (s : set M) {f g : M →ₗ[R] M₂} (H : ∀x∈s, f x = g x) {x} (h : x ∈ span R s) :
928-
f x = g x :=
929-
by apply span_induction h H; simp {contextual := tt}
930-
931-
lemma linear_map.ext_on {v : ι → M} {f g : M →ₗ[R] M₂} (hv : span R (range v) = ⊤)
932-
(h : ∀i, f (v i) = g (v i)) : f = g :=
933-
begin
934-
apply linear_map.ext (λ x, linear_eq_on (range v) _ (eq_top_iff'.1 hv _)),
935-
exact (λ y hy, exists.elim (set.mem_range.1 hy) (λ i hi, by rw ←hi; exact h i))
936-
end
937-
938927
lemma supr_eq_span {ι : Sort w} (p : ι → submodule R M) :
939928
(⨆ (i : ι), p i) = submodule.span R (⋃ (i : ι), ↑(p i)) :=
940929
le_antisymm
@@ -1140,6 +1129,33 @@ variables [semimodule R M] [semimodule R M₂] [semimodule R M₃]
11401129
include R
11411130
open submodule
11421131

1132+
/-- If two linear maps are equal on a set `s`, then they are equal on `submodule.span s`.
1133+
1134+
See also `linear_map.eq_on_span'` for a version using `set.eq_on`. -/
1135+
lemma eq_on_span {s : set M} {f g : M →ₗ[R] M₂} (H : set.eq_on f g s) ⦃x⦄ (h : x ∈ span R s) :
1136+
f x = g x :=
1137+
by apply span_induction h H; simp {contextual := tt}
1138+
1139+
/-- If two linear maps are equal on a set `s`, then they are equal on `submodule.span s`.
1140+
1141+
This version uses `set.eq_on`, and the hidden argument will expand to `h : x ∈ (span R s : set M)`.
1142+
See `linear_map.eq_on_span` for a version that takes `h : x ∈ span R s` as an argument. -/
1143+
lemma eq_on_span' {s : set M} {f g : M →ₗ[R] M₂} (H : set.eq_on f g s) :
1144+
set.eq_on f g (span R s : set M) :=
1145+
eq_on_span H
1146+
1147+
/-- If `s` generates the whole semimodule and linear maps `f`, `g` are equal on `s`, then they are
1148+
equal. -/
1149+
lemma ext_on {s : set M} {f g : M →ₗ[R] M₂} (hv : span R s = ⊤) (h : set.eq_on f g s) :
1150+
f = g :=
1151+
linear_map.ext (λ x, eq_on_span h (eq_top_iff'.1 hv _))
1152+
1153+
/-- If the range of `v : ι → M` generates the whole semimodule and linear maps `f`, `g` are equal at
1154+
each `v i`, then they are equal. -/
1155+
lemma ext_on_range {v : ι → M} {f g : M →ₗ[R] M₂} (hv : span R (set.range v) = ⊤)
1156+
(h : ∀i, f (v i) = g (v i)) : f = g :=
1157+
ext_on hv (set.forall_range_iff.2 h)
1158+
11431159
@[simp] lemma finsupp_sum {γ} [has_zero γ]
11441160
(f : M →ₗ[R] M₂) {t : ι →₀ γ} {g : ι → γ → M} :
11451161
f (t.sum g) = t.sum (λi d, f (g i d)) := f.map_sum

src/linear_algebra/basis.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ lemma is_basis.total_comp_repr : (finsupp.total ι M R v).comp hv.repr = linear_
104104
linear_map.ext hv.total_repr
105105

106106
lemma is_basis.ext {f g : M →ₗ[R] M'} (hv : is_basis R v) (h : ∀i, f (v i) = g (v i)) : f = g :=
107-
linear_map.ext_on hv.2 h
107+
linear_map.ext_on_range hv.2 h
108108

109109
lemma is_basis.repr_ker : hv.repr.ker = ⊥ :=
110110
linear_map.ker_eq_bot.2 $ left_inverse.injective hv.total_repr

src/measure_theory/simple_func_dense.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ lemma tendsto_approx_on {f : β → α} (hf : measurable f) {s : set α} {y₀ :
134134
tendsto (λ n, approx_on f hf s y₀ h₀ n x) at_top (𝓝 $ f x) :=
135135
begin
136136
haveI : nonempty s := ⟨⟨y₀, h₀⟩⟩,
137-
rw [← @subtype.range_coe _ s, ← image_univ, ← dense_seq_dense s] at hx,
137+
rw [← @subtype.range_coe _ s, ← image_univ, ← (dense_range_dense_seq s).closure_eq] at hx,
138138
simp only [approx_on, coe_comp],
139139
refine tendsto_nearest_pt (closure_minimal _ is_closed_closure hx),
140140
simp only [nat.range_cases_on, closure_union, range_comp coe],

src/topology/algebra/module.lean

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,19 @@ lemma map_sum {ι : Type*} (s : finset ι) (g : ι → M) :
238238

239239
@[simp, norm_cast] lemma coe_coe : ((f : M →ₗ[R] M₂) : (M → M₂)) = (f : M → M₂) := rfl
240240

241+
/-- If two continuous linear maps are equal on a set `s`, then they are equal on the closure
242+
of the `submodule.span` of this set. -/
243+
lemma eq_on_closure_span [t2_space M₂] {s : set M} {f g : M →L[R] M₂} (h : set.eq_on f g s) :
244+
set.eq_on f g (closure (submodule.span R s : set M)) :=
245+
(linear_map.eq_on_span' h).closure f.continuous g.continuous
246+
247+
/-- If the submodule generated by a set `s` is dense in the ambient semimodule, then two continuous
248+
linear maps equal on `s` are equal. -/
249+
lemma ext_on [t2_space M₂] {s : set M} (hs : dense (submodule.span R s : set M)) {f g : M →L[R] M₂}
250+
(h : set.eq_on f g s) :
251+
f = g :=
252+
ext $ λ x, eq_on_closure_span h (hs x)
253+
241254
/-- The continuous map that is constantly zero. -/
242255
instance: has_zero (M →L[R] M₂) := ⟨⟨0, continuous_const⟩⟩
243256
instance : inhabited (M →L[R] M₂) := ⟨0

src/topology/bases.lean

Lines changed: 34 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -108,42 +108,55 @@ let ⟨S, sb, su⟩ := sUnion_basis_of_is_open hB ou in
108108

109109
variables (α)
110110

111-
/-- A separable space is one with a countable dense subset. -/
111+
/-- A separable space is one with a countable dense subset, available through
112+
`topological_space.exists_countable_dense`. If `α` is also known to be nonempty, then
113+
`topological_space.dense_seq` provides a sequence `ℕ → α` with dense range, see
114+
`topological_space.dense_range_dense_seq`.
115+
116+
If `α` is a uniform space with countably generated uniformity filter (e.g., an `emetric_space`),
117+
then this condition is equivalent to `topological_space.second_countable_topology α`. In this case
118+
the latter should be used as a typeclass argument in theorems because Lean can automatically deduce
119+
`separable_space` from `second_countable_topology` but it can't deduce `second_countable_topology`
120+
and `emetric_space`. -/
112121
class separable_space : Prop :=
113-
(exists_countable_closure_eq_univ : ∃s:set α, countable s ∧ closure s = univ)
114-
115-
lemma exists_countable_closure_eq_univ [separable_space α] :
116-
∃ s : set α, countable s ∧ closure s = univ :=
117-
separable_space.exists_countable_closure_eq_univ
122+
(exists_countable_dense : ∃s:set α, countable s ∧ dense s)
118123

119124
lemma exists_countable_dense [separable_space α] :
120125
∃ s : set α, countable s ∧ dense s :=
121-
let ⟨s, hsc, hsd⟩ := exists_countable_closure_eq_univ α
122-
in ⟨s, hsc, dense_iff_closure_eq.2 hsd⟩
126+
separable_space.exists_countable_dense
127+
128+
/-- A nonempty separable space admits a sequence with dense range. Instead of running `cases` on the
129+
conclusion of this lemma, you might want to use `topological_space.dense_seq` and
130+
`topological_space.dense_range_dense_seq`.
123131
124-
lemma exists_dense_seq [separable_space α] [nonempty α] : ∃ u : ℕ → α, closure (range u) = univ :=
132+
If `α` might be empty, then `exists_countable_dense` is the main way to use separability of `α`. -/
133+
lemma exists_dense_seq [separable_space α] [nonempty α] : ∃ u : ℕ → α, dense_range u :=
125134
begin
126-
obtain ⟨s : set α, hs, s_dense⟩ := @separable_space.exists_countable_closure_eq_univ α _ _,
135+
obtain ⟨s : set α, hs, s_dense⟩ := exists_countable_dense α,
127136
cases countable_iff_exists_surjective.mp hs with u hu,
128-
use u,
129-
apply eq_univ_of_univ_subset,
130-
simpa [s_dense] using closure_mono hu
137+
exact ⟨u, s_dense.mono hu⟩,
131138
end
132139

133-
/-- A sequence dense in a non-empty separable topological space. -/
140+
/-- A sequence dense in a non-empty separable topological space.
141+
142+
If `α` might be empty, then `exists_countable_dense` is the main way to use separability of `α`. -/
134143
def dense_seq [separable_space α] [nonempty α] : ℕ → α := classical.some (exists_dense_seq α)
135144

136-
@[simp] lemma dense_seq_dense [separable_space α] [nonempty α] :
137-
closure (range $ dense_seq α) = univ := classical.some_spec (exists_dense_seq α)
145+
/-- The sequence `dense_seq α` has dense range. -/
146+
@[simp] lemma dense_range_dense_seq [separable_space α] [nonempty α] :
147+
dense_range (dense_seq α) := classical.some_spec (exists_dense_seq α)
138148

139149
end topological_space
140150

141151
open topological_space
142152

143-
lemma dense_range.separable_space {α β : Type*} [topological_space α] [separable_space α]
144-
[topological_space β] {f : α → β} (h : dense_range f) (h' : continuous f) : separable_space β :=
145-
let ⟨s, s_cnt, s_cl⟩ := exists_countable_closure_eq_univ α in
146-
⟨⟨f '' s, countable.image s_cnt f, h'.dense_image_of_dense_range h (dense_iff_closure_eq.mpr s_cl)⟩⟩
153+
/-- If `α` is a separable space and `f : α → β` is a continuous map with dense range, then `β` is
154+
a separable space as well. E.g., the completion of a separable uniform space is separable. -/
155+
protected lemma dense_range.separable_space {α β : Type*} [topological_space α] [separable_space α]
156+
[topological_space β] {f : α → β} (h : dense_range f) (h' : continuous f) :
157+
separable_space β :=
158+
let ⟨s, s_cnt, s_dense⟩ := exists_countable_dense α in
159+
⟨⟨f '' s, countable.image s_cnt f, h.dense_image h' s_dense⟩⟩
147160

148161
namespace topological_space
149162
universe u
@@ -253,8 +266,7 @@ begin
253266
have : ∀ s ∈ b, set.nonempty s :=
254267
assume s hs, ne_empty_iff_nonempty.1 $ λ eq, absurd hs (eq.symm ▸ hbne),
255268
choose f hf,
256-
refine ⟨⟨⋃ s ∈ b, {f s ‹_›}, hbc.bUnion (λ _ _, countable_singleton _), _⟩⟩,
257-
refine eq_univ_of_forall (λ a, _),
269+
refine ⟨⟨⋃ s ∈ b, {f s ‹_›}, hbc.bUnion (λ _ _, countable_singleton _), λ a, _⟩⟩,
258270
suffices : (⨅ s ∈ S a, 𝓟 (s ∩ ⋃ t ∈ b, {f t ‹_›})).ne_bot,
259271
{ obtain ⟨t, htb, hta⟩ : a ∈ ⋃₀ b, { simp only [hbU] },
260272
have A : ∃ s, s ∈ S a := ⟨t, hta, htb⟩,

0 commit comments

Comments
 (0)