Skip to content

Commit

Permalink
feat(order/topology/**/uniform*): Lemmas about uniform convergence (#…
Browse files Browse the repository at this point in the history
…14587)

To prove facts about uniform convergence, it is often useful to manipulate the various functions without dealing with the ε's and δ's. To do so, you need auxiliary lemmas about adding/muliplying/etc Cauchy sequences.

This commit adds several such lemmas. It supports #14090, which we're slowly transforming to use these lemmas instead of doing direct ε/δ manipulation.





Co-authored-by: Floris van Doorn <fpvdoorn@gmail.com>
  • Loading branch information
khwilson and fpvandoorn committed Jun 17, 2022
1 parent 545f0fb commit 260d472
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 36 deletions.
10 changes: 0 additions & 10 deletions src/order/filter/bases.lean
Expand Up @@ -721,16 +721,6 @@ lemma has_basis.coprod {ι ι' : Type*} {pa : ι → Prop} {sa : ι → set α}

end two_types

open equiv

lemma prod_assoc (f : filter α) (g : filter β) (h : filter γ) :
map (prod_assoc α β γ) ((f ×ᶠ g) ×ᶠ h) = f ×ᶠ (g ×ᶠ h) :=
begin
apply ((((basis_sets f).prod $ basis_sets g).prod $ basis_sets h).map _).eq_of_same_basis,
simpa only [prod_assoc_image, function.comp, and_assoc] using
((basis_sets f).prod $ (basis_sets g).prod $ basis_sets h).comp_equiv (prod_assoc _ _ _)
end

end filter

end sort
Expand Down
54 changes: 52 additions & 2 deletions src/order/filter/basic.lean
Expand Up @@ -233,7 +233,7 @@ add_tactic_doc
end tactic.interactive

namespace filter
variables {α : Type u} {β : Type v} {γ : Type w} {ι : Sort x}
variables {α : Type u} {β : Type v} {γ : Type w} {δ : Type*} {ι : Sort x}

section principal

Expand Down Expand Up @@ -1647,7 +1647,6 @@ lemma comap_comap {m : γ → β} {n : β → α} : comap m (comap n f) = comap
filter.coext $ λ s, by simp only [compl_mem_comap, image_image]

section comm
variables {δ : Type*}

/-!
The variables in the following lemmas are used as in this diagram:
Expand Down Expand Up @@ -2001,6 +2000,12 @@ lemma comap_equiv_symm (e : α ≃ β) (f : filter α) :
lemma map_swap_eq_comap_swap {f : filter (α × β)} : prod.swap <$> f = comap prod.swap f :=
map_eq_comap_of_inverse prod.swap_swap_eq prod.swap_swap_eq

/-- A useful lemma when dealing with uniformities. -/
lemma map_swap4_eq_comap {f : filter ((α × β) × (γ × δ))} :
map (λ p : (α × β) × (γ × δ), ((p.1.1, p.2.1), (p.1.2, p.2.2))) f =
comap (λ p : (α × γ) × (β × δ), ((p.1.1, p.2.1), (p.1.2, p.2.2))) f :=
map_eq_comap_of_inverse (funext $ λ ⟨⟨_, _⟩, ⟨_, _⟩⟩, rfl) (funext $ λ ⟨⟨_, _⟩, ⟨_, _⟩⟩, rfl)

lemma le_map {f : filter α} {m : α → β} {g : filter β} (h : ∀ s ∈ f, m '' s ∈ g) :
g ≤ f.map m :=
λ s hs, mem_of_superset (h _ hs) $ image_preimage_subset _ _
Expand Down Expand Up @@ -2559,6 +2564,10 @@ lemma tendsto.prod_mk {f : filter α} {g : filter β} {h : filter γ} {m₁ : α
(h₁ : tendsto m₁ f g) (h₂ : tendsto m₂ f h) : tendsto (λ x, (m₁ x, m₂ x)) f (g ×ᶠ h) :=
tendsto_inf.2 ⟨tendsto_comap_iff.2 h₁, tendsto_comap_iff.2 h₂⟩

lemma tendsto_prod_swap1 α2 : Type*} {a1 : filter α1} {a2 : filter α2} :
tendsto (prod.swap : α1 × α2 → α2 × α1) (a1 ×ᶠ a2) (a2 ×ᶠ a1) :=
tendsto_snd.prod_mk tendsto_fst

lemma eventually.prod_inl {la : filter α} {p : α → Prop} (h : ∀ᶠ x in la, p x) (lb : filter β) :
∀ᶠ x in la ×ᶠ lb, p (x : α × β).1 :=
tendsto_fst.eventually h
Expand Down Expand Up @@ -2590,6 +2599,18 @@ begin
exact ha.mono (λ a ha, hb.mono $ λ b hb, h ha hb)
end

/-- A fact that is eventually true about all pairs `l ×ᶠ l` is eventually true about
all diagonal pairs `(i, i)` -/
lemma eventually.diag_of_prod {f : filter α} {p : α × α → Prop}
(h : ∀ᶠ i in f ×ᶠ f, p i) : (∀ᶠ i in f, p (i, i)) :=
begin
obtain ⟨t, ht, s, hs, hst⟩ := eventually_prod_iff.1 h,
apply (ht.and hs).mono (λ x hx, hst hx.1 hx.2),
end

lemma tendsto_diag : tendsto (λ i, (i, i)) f (f ×ᶠ f) :=
tendsto_iff_eventually.mpr (λ _ hpr, hpr.diag_of_prod)

lemma prod_infi_left [nonempty ι] {f : ι → filter α} {g : filter β}:
(⨅ i, f i) ×ᶠ g = (⨅ i, (f i) ×ᶠ g) :=
by { rw [filter.prod, comap_infi, infi_inf], simp only [filter.prod, eq_self_iff_true] }
Expand All @@ -2614,6 +2635,35 @@ by simp only [filter.prod, comap_comap, (∘), inf_comm, prod.fst_swap,
lemma prod_comm : f ×ᶠ g = map (λ p : β×α, (p.2, p.1)) (g ×ᶠ f) :=
by { rw [prod_comm', ← map_swap_eq_comap_swap], refl }

lemma prod_assoc (f : filter α) (g : filter β) (h : filter γ) :
map (equiv.prod_assoc α β γ) ((f ×ᶠ g) ×ᶠ h) = f ×ᶠ (g ×ᶠ h) :=
by simp_rw [← comap_equiv_symm, filter.prod, comap_inf, comap_comap, inf_assoc, function.comp,
equiv.prod_assoc_symm_apply]

theorem prod_assoc_symm (f : filter α) (g : filter β) (h : filter γ) :
map (equiv.prod_assoc α β γ).symm (f ×ᶠ (g ×ᶠ h)) = (f ×ᶠ g) ×ᶠ h :=
by simp_rw [map_equiv_symm, filter.prod, comap_inf, comap_comap, inf_assoc, function.comp,
equiv.prod_assoc_apply]

lemma tendsto_prod_assoc {f : filter α} {g : filter β} {h : filter γ} :
tendsto (equiv.prod_assoc α β γ) (f ×ᶠ g ×ᶠ h) (f ×ᶠ (g ×ᶠ h)) :=
(prod_assoc f g h).le

lemma tendsto_prod_assoc_symm {f : filter α} {g : filter β} {h : filter γ} :
tendsto (equiv.prod_assoc α β γ).symm (f ×ᶠ (g ×ᶠ h)) (f ×ᶠ g ×ᶠ h) :=
(prod_assoc_symm f g h).le

/-- A useful lemma when dealing with uniformities. -/
lemma map_swap4_prod {f : filter α} {g : filter β} {h : filter γ} {k : filter δ} :
map (λ p : (α × β) × (γ × δ), ((p.1.1, p.2.1), (p.1.2, p.2.2))) ((f ×ᶠ g) ×ᶠ (h ×ᶠ k)) =
(f ×ᶠ h) ×ᶠ (g ×ᶠ k) :=
by simp_rw [map_swap4_eq_comap, filter.prod, comap_inf, comap_comap, inf_assoc, inf_left_comm]

lemma tendsto_swap4_prod {f : filter α} {g : filter β} {h : filter γ} {k : filter δ} :
tendsto (λ p : (α × β) × (γ × δ), ((p.1.1, p.2.1), (p.1.2, p.2.2)))
((f ×ᶠ g) ×ᶠ (h ×ᶠ k)) ((f ×ᶠ h) ×ᶠ (g ×ᶠ k)) :=
map_swap4_prod.le

lemma prod_map_map_eq {α₁ : Type u} {α₂ : Type v} {β₁ : Type w} {β₂ : Type x}
{f₁ : filter α₁} {f₂ : filter α₂} {m₁ : α₁ → β₁} {m₂ : α₂ → β₂} :
(map m₁ f₁) ×ᶠ (map m₂ f₂) = map (λ p : α₁×α₂, (m₁ p.1, m₂ p.2)) (f₁ ×ᶠ f₂) :=
Expand Down
20 changes: 20 additions & 0 deletions src/topology/algebra/uniform_group.lean
Expand Up @@ -266,6 +266,26 @@ uniform_continuous_inv.comp_cauchy_seq h
(𝓝 (1 : α)).basis_sets.uniformity_of_nhds_one_inv_mul_swapped.totally_bounded_iff.trans $
by simp [← preimage_smul_inv, preimage]

section uniform_convergence
variables {ι : Type*} {l : filter ι} {f f' : ι → β → α} {g g' : β → α} {s : set β}

@[to_additive] lemma tendsto_uniformly_on.mul (hf : tendsto_uniformly_on f g l s)
(hf' : tendsto_uniformly_on f' g' l s) : tendsto_uniformly_on (f * f') (g * g') l s :=
λ u hu, ((uniform_continuous_mul.comp_tendsto_uniformly_on (hf.prod hf')) u hu).diag_of_prod

@[to_additive] lemma tendsto_uniformly_on.div (hf : tendsto_uniformly_on f g l s)
(hf' : tendsto_uniformly_on f' g' l s) : tendsto_uniformly_on (f / f') (g / g') l s :=
λ u hu, ((uniform_continuous_div.comp_tendsto_uniformly_on (hf.prod hf')) u hu).diag_of_prod

@[to_additive] lemma uniform_cauchy_seq_on.mul (hf : uniform_cauchy_seq_on f l s)
(hf' : uniform_cauchy_seq_on f' l s) : uniform_cauchy_seq_on (f * f') l s :=
λ u hu, by simpa using ((uniform_continuous_mul.comp_uniform_cauchy_seq_on (hf.prod' hf')) u hu)

@[to_additive] lemma uniform_cauchy_seq_on.div (hf : uniform_cauchy_seq_on f l s)
(hf' : uniform_cauchy_seq_on f' l s) : uniform_cauchy_seq_on (f / f') l s :=
λ u hu, by simpa using ((uniform_continuous_div.comp_uniform_cauchy_seq_on (hf.prod' hf')) u hu)

end uniform_convergence
end uniform_group

section topological_comm_group
Expand Down
10 changes: 5 additions & 5 deletions src/topology/continuous_function/algebra.lean
Expand Up @@ -280,17 +280,17 @@ coe_injective.comm_group _ coe_one coe_mul coe_inv coe_div coe_pow coe_zpow
rw continuous_iff_continuous_at,
rintros ⟨f, g⟩,
rw [continuous_at, tendsto_iff_forall_compact_tendsto_uniformly_on, nhds_prod_eq],
exactI λ K hK, ((tendsto_iff_forall_compact_tendsto_uniformly_on.mp filter.tendsto_id K hK).prod
(tendsto_iff_forall_compact_tendsto_uniformly_on.mp filter.tendsto_id K hK)).comp'
uniform_continuous_mul },
exactI λ K hK, uniform_continuous_mul.comp_tendsto_uniformly_on
((tendsto_iff_forall_compact_tendsto_uniformly_on.mp filter.tendsto_id K hK).prod
(tendsto_iff_forall_compact_tendsto_uniformly_on.mp filter.tendsto_id K hK)), },
continuous_inv := by
{ letI : uniform_space β := topological_group.to_uniform_space β,
have : uniform_group β := topological_group_is_uniform,
rw continuous_iff_continuous_at,
intro f,
rw [continuous_at, tendsto_iff_forall_compact_tendsto_uniformly_on],
exactI λ K hK, (tendsto_iff_forall_compact_tendsto_uniformly_on.mp filter.tendsto_id K hK).comp'
uniform_continuous_inv } }
exactI λ K hK, uniform_continuous_inv.comp_tendsto_uniformly_on
(tendsto_iff_forall_compact_tendsto_uniformly_on.mp filter.tendsto_id K hK), } }

end continuous_map

Expand Down
9 changes: 2 additions & 7 deletions src/topology/uniform_space/basic.lean
Expand Up @@ -1319,13 +1319,8 @@ theorem uniformity_prod [uniform_space α] [uniform_space β] : 𝓤 (α × β)
inf_uniformity

lemma uniformity_prod_eq_prod [uniform_space α] [uniform_space β] :
𝓤 (α×β) =
map (λp:(α×α)×(β×β), ((p.1.1, p.2.1), (p.1.2, p.2.2))) (𝓤 α ×ᶠ 𝓤 β) :=
have map (λp:(α×α)×(β×β), ((p.1.1, p.2.1), (p.1.2, p.2.2))) =
comap (λp:(α×β)×(α×β), ((p.1.1, p.2.1), (p.1.2, p.2.2))),
from funext $ assume f, map_eq_comap_of_inverse
(funext $ assume ⟨⟨_, _⟩, ⟨_, _⟩⟩, rfl) (funext $ assume ⟨⟨_, _⟩, ⟨_, _⟩⟩, rfl),
by rw [this, uniformity_prod, filter.prod, comap_inf, comap_comap, comap_comap]
𝓤 (α × β) = map (λ p : (α × α) × (β × β), ((p.1.1, p.2.1), (p.1.2, p.2.2))) (𝓤 α ×ᶠ 𝓤 β) :=
by rw [map_swap4_eq_comap, uniformity_prod, filter.prod, comap_inf, comap_comap, comap_comap]

lemma mem_map_iff_exists_image' {α : Type*} {β : Type*} {f : filter α} {m : α → β} {t : set β} :
t ∈ (map m f).sets ↔ (∃s∈f, m '' s ⊆ t) :=
Expand Down
105 changes: 93 additions & 12 deletions src/topology/uniform_space/uniform_convergence.lean
Expand Up @@ -112,6 +112,15 @@ lemma tendsto_uniformly_on.mono {s' : set α}
(h : tendsto_uniformly_on F f p s) (h' : s' ⊆ s) : tendsto_uniformly_on F f p s' :=
λ u hu, (h u hu).mono (λ n hn x hx, hn x (h' hx))

lemma tendsto_uniformly_on.congr {F' : ι → α → β}
(hf : tendsto_uniformly_on F f p s) (hff' : ∀ᶠ n in p, set.eq_on (F n) (F' n) s) :
tendsto_uniformly_on F' f p s :=
begin
refine (λ u hu, ((hf u hu).and hff').mono (λ n h x hx, _)),
rw ← h.right hx,
exact h.left x hx,
end

protected lemma tendsto_uniformly.tendsto_uniformly_on
(h : tendsto_uniformly F f p) : tendsto_uniformly_on F f p s :=
(tendsto_uniformly_on_univ.2 h).mono (subset_univ s)
Expand All @@ -128,13 +137,15 @@ lemma tendsto_uniformly.comp (h : tendsto_uniformly F f p) (g : γ → α) :

/-- Composing on the left by a uniformly continuous function preserves
uniform convergence on a set -/
lemma tendsto_uniformly_on.comp' [uniform_space γ] {g : β → γ} (h : tendsto_uniformly_on F f p s)
(hg : uniform_continuous g) : tendsto_uniformly_on (λ i, g ∘ (F i)) (g ∘ f) p s :=
lemma uniform_continuous.comp_tendsto_uniformly_on [uniform_space γ] {g : β → γ}
(hg : uniform_continuous g) (h : tendsto_uniformly_on F f p s) :
tendsto_uniformly_on (λ i, g ∘ (F i)) (g ∘ f) p s :=
λ u hu, h _ (hg hu)

/-- Composing on the left by a uniformly continuous function preserves uniform convergence -/
lemma tendsto_uniformly.comp' [uniform_space γ] {g : β → γ} (h : tendsto_uniformly F f p)
(hg : uniform_continuous g) : tendsto_uniformly (λ i, g ∘ (F i)) (g ∘ f) p :=
lemma uniform_continuous.comp_tendsto_uniformly [uniform_space γ] {g : β → γ}
(hg : uniform_continuous g) (h : tendsto_uniformly F f p) :
tendsto_uniformly (λ i, g ∘ (F i)) (g ∘ f) p :=
λ u hu, h _ (hg hu)

lemma tendsto_uniformly_on.prod_map {ι' α' β' : Type*} [uniform_space β']
Expand Down Expand Up @@ -168,16 +179,39 @@ lemma tendsto_uniformly.prod {ι' β' : Type*} [uniform_space β'] {F' : ι' →
tendsto_uniformly (λ (i : ι × ι') a, (F i.1 a, F' i.2 a)) (λ a, (f a, f' a)) (p.prod p') :=
(h.prod_map h').comp (λ a, (a, a))

/-- Uniform convergence on a set `s` to a constant function is equivalent to convergence in
`p ×ᶠ 𝓟 s`. -/
lemma tendsto_prod_principal_iff {c : β} :
tendsto ↿F (p ×ᶠ 𝓟 s) (𝓝 c) ↔ tendsto_uniformly_on F (λ _, c) p s :=
begin
unfold tendsto,
simp_rw [nhds_eq_comap_uniformity, map_le_iff_le_comap.symm, map_map, le_def, mem_map,
mem_prod_principal],
simpa,
end

/-- Uniform convergence to a constant function is equivalent to convergence in `p ×ᶠ ⊤`. -/
lemma tendsto_prod_top_iff {c : β} : tendsto ↿F (p ×ᶠ ⊤) (𝓝 c) ↔ tendsto_uniformly F (λ _, c) p :=
let j : β → β × β := prod.mk c in
calc tendsto ↿F (p ×ᶠ ⊤) (𝓝 c)
↔ map ↿F (p ×ᶠ ⊤) ≤ (𝓝 c) : iff.rfl
... ↔ map ↿F (p ×ᶠ ⊤) ≤ comap j (𝓤 β) : by rw nhds_eq_comap_uniformity
... ↔ map j (map ↿F (p ×ᶠ ⊤)) ≤ 𝓤 β : map_le_iff_le_comap.symm
... ↔ map (j ∘ ↿F) (p ×ᶠ ⊤) ≤ 𝓤 β : by rw map_map
... ↔ ∀ V ∈ 𝓤 β, {x | (c, ↿F x) ∈ V} ∈ p ×ᶠ (⊤ : filter α) : iff.rfl
... ↔ ∀ V ∈ 𝓤 β, {i | ∀ a, (c, F i a) ∈ V} ∈ p : by simpa [mem_prod_top]
by rw [←principal_univ, ←tendsto_uniformly_on_univ, ←tendsto_prod_principal_iff]

/-- Uniform convergence on the empty set is vacuously true -/
lemma tendsto_uniformly_on_empty :
tendsto_uniformly_on F f p ∅ :=
λ u hu, by simp

/-- Uniform convergence on a singleton is equivalent to regular convergence -/
lemma tendsto_uniformly_on_singleton_iff_tendsto :
tendsto_uniformly_on F f p {x} ↔ tendsto (λ n : ι, F n x) p (𝓝 (f x)) :=
by simp_rw [uniform.tendsto_nhds_right, tendsto_uniformly_on, mem_singleton_iff, forall_eq,
tendsto_def, preimage, filter.eventually]

/-- If a sequence `g` converges to some `b`, then the sequence of constant functions
`λ n, λ a, g n` converges to the constant function `λ a, b` on any set `s` -/
lemma filter.tendsto.tendsto_uniformly_on_const
{g : ι → β} {b : β} (hg : tendsto g p (𝓝 b)) (s : set α) :
tendsto_uniformly_on (λ n : ι, λ a : α, g n) (λ a : α, b) p s :=
λ u hu, hg.eventually
(eventually_of_mem (mem_nhds_left b hu) (λ x hx y hy, hx) : ∀ᶠ x in 𝓝 b, ∀ y ∈ s, (b, x) ∈ u)

lemma uniform_continuous_on.tendsto_uniformly [uniform_space α] [uniform_space γ]
{x : α} {U : set α} (hU : U ∈ 𝓝 x)
Expand Down Expand Up @@ -251,6 +285,53 @@ begin
exact ⟨F m x, ⟨hm', htsymm (hm x hx)⟩⟩,
end

lemma uniform_cauchy_seq_on.mono {s' : set α} (hf : uniform_cauchy_seq_on F p s) (hss' : s' ⊆ s) :
uniform_cauchy_seq_on F p s' :=
λ u hu, (hf u hu).mono (λ x hx y hy, hx y (hss' hy))

/-- Composing on the right by a function preserves uniform Cauchy sequences -/
lemma uniform_cauchy_seq_on.comp {γ : Type*} (hf : uniform_cauchy_seq_on F p s) (g : γ → α) :
uniform_cauchy_seq_on (λ n, F n ∘ g) p (g ⁻¹' s) :=
λ u hu, (hf u hu).mono (λ x hx y hy, hx (g y) hy)

/-- Composing on the left by a uniformly continuous function preserves
uniform Cauchy sequences -/
lemma uniform_continuous.comp_uniform_cauchy_seq_on [uniform_space γ] {g : β → γ}
(hg : uniform_continuous g) (hf : uniform_cauchy_seq_on F p s) :
uniform_cauchy_seq_on (λ n, g ∘ (F n)) p s :=
λ u hu, hf _ (hg hu)

lemma uniform_cauchy_seq_on.prod_map {ι' α' β' : Type*} [uniform_space β']
{F' : ι' → α' → β'} {p' : filter ι'} {s' : set α'}
(h : uniform_cauchy_seq_on F p s) (h' : uniform_cauchy_seq_on F' p' s') :
uniform_cauchy_seq_on (λ (i : ι × ι'), prod.map (F i.1) (F' i.2))
(p.prod p') (s ×ˢ s') :=
begin
intros u hu,
rw [uniformity_prod_eq_prod, mem_map, mem_prod_iff] at hu,
obtain ⟨v, hv, w, hw, hvw⟩ := hu,
simp_rw [mem_prod, prod_map, and_imp, prod.forall],
rw [← set.image_subset_iff] at hvw,
apply (tendsto_swap4_prod.eventually ((h v hv).prod_mk (h' w hw))).mono,
intros x hx a b ha hb,
refine hvw ⟨_, mk_mem_prod (hx.1 a ha) (hx.2 b hb), rfl⟩,
end

lemma uniform_cauchy_seq_on.prod {ι' β' : Type*} [uniform_space β'] {F' : ι' → α → β'}
{p' : filter ι'}
(h : uniform_cauchy_seq_on F p s) (h' : uniform_cauchy_seq_on F' p' s) :
uniform_cauchy_seq_on (λ (i : ι × ι') a, (F i.fst a, F' i.snd a)) (p ×ᶠ p') s :=
(congr_arg _ s.inter_self).mp ((h.prod_map h').comp (λ a, (a, a)))

lemma uniform_cauchy_seq_on.prod' {β' : Type*} [uniform_space β'] {F' : ι → α → β'}
(h : uniform_cauchy_seq_on F p s) (h' : uniform_cauchy_seq_on F' p s) :
uniform_cauchy_seq_on (λ (i : ι) a, (F i a, F' i a)) p s :=
begin
intros u hu,
have hh : tendsto (λ x : ι, (x, x)) p (p ×ᶠ p), { exact tendsto_diag, },
exact (hh.prod_map hh).eventually ((h.prod h') u hu),
end

section seq_tendsto

lemma tendsto_uniformly_on_of_seq_tendsto_uniformly_on {l : filter ι} [l.is_countably_generated]
Expand Down

0 comments on commit 260d472

Please sign in to comment.