Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - feat: Add a few continuity lemmas for products #10820

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions Mathlib/Analysis/Analytic/Constructions.lean
Original file line number Diff line number Diff line change
Expand Up @@ -117,24 +117,28 @@ theorem AnalyticOn.comp₂ {h : F × G → H} {f : E → F} {g : E → G} {s : S
fun _ xt ↦ (ha _ (m _ xt)).comp₂ (fa _ xt) (ga _ xt)

/-- Analytic functions on products are analytic in the first coordinate -/
theorem AnalyticAt.along_fst {f : E × F → G} {p : E × F} (fa : AnalyticAt 𝕜 f p) :
theorem AnalyticAt.curry_left {f : E × F → G} {p : E × F} (fa : AnalyticAt 𝕜 f p) :
AnalyticAt 𝕜 (fun x ↦ f (x, p.2)) p.1 :=
AnalyticAt.comp₂ fa (analyticAt_id _ _) analyticAt_const
alias AnalyticAt.along_fst := AnalyticAt.curry_left

/-- Analytic functions on products are analytic in the second coordinate -/
theorem AnalyticAt.along_snd {f : E × F → G} {p : E × F} (fa : AnalyticAt 𝕜 f p) :
theorem AnalyticAt.curry_right {f : E × F → G} {p : E × F} (fa : AnalyticAt 𝕜 f p) :
AnalyticAt 𝕜 (fun y ↦ f (p.1, y)) p.2 :=
AnalyticAt.comp₂ fa analyticAt_const (analyticAt_id _ _)
alias AnalyticAt.along_snd := AnalyticAt.curry_right

/-- Analytic functions on products are analytic in the first coordinate -/
theorem AnalyticOn.along_fst {f : E × F → G} {s : Set (E × F)} {y : F} (fa : AnalyticOn 𝕜 f s) :
theorem AnalyticOn.curry_left {f : E × F → G} {s : Set (E × F)} {y : F} (fa : AnalyticOn 𝕜 f s) :
AnalyticOn 𝕜 (fun x ↦ f (x, y)) {x | (x, y) ∈ s} :=
fun x m ↦ (fa (x, y) m).along_fst
alias AnalyticOn.along_fst := AnalyticOn.curry_left

/-- Analytic functions on products are analytic in the second coordinate -/
theorem AnalyticOn.along_snd {f : E × F → G} {x : E} {s : Set (E × F)} (fa : AnalyticOn 𝕜 f s) :
theorem AnalyticOn.curry_right {f : E × F → G} {x : E} {s : Set (E × F)} (fa : AnalyticOn 𝕜 f s) :
AnalyticOn 𝕜 (fun y ↦ f (x, y)) {y | (x, y) ∈ s} :=
fun y m ↦ (fa (x, y) m).along_snd
alias AnalyticOn.along_snd := AnalyticOn.curry_right

/-!
### Arithmetic on analytic functions
Expand Down
2 changes: 1 addition & 1 deletion Mathlib/Analysis/Calculus/FDeriv/Measurable.lean
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ lemma isOpen_A_with_param {r s : ℝ} (hf : Continuous f.uncurry) (L : E →L[
simp only [A, half_lt_self_iff, not_lt, mem_Ioc, mem_ball, map_sub, mem_setOf_eq]
apply isOpen_iff_mem_nhds.2
rintro ⟨a, x⟩ ⟨r', ⟨Irr', Ir'r⟩, hr⟩
have ha : Continuous (f a) := continuous_uncurry_left a hf
have ha : Continuous (f a) := hf.uncurry_left a
rcases exists_between Irr' with ⟨t, hrt, htr'⟩
rcases exists_between hrt with ⟨t', hrt', ht't⟩
obtain ⟨b, b_lt, hb⟩ : ∃ b, b < s * r ∧ ∀ y ∈ closedBall x t, ∀ z ∈ closedBall x t,
Expand Down
37 changes: 32 additions & 5 deletions Mathlib/Topology/Constructions.lean
Original file line number Diff line number Diff line change
Expand Up @@ -507,18 +507,22 @@ lemma isClosedMap_swap : IsClosedMap (Prod.swap : X × Y → Y × X) := fun s hs
rw [image_swap_eq_preimage_swap]
exact hs.preimage continuous_swap

theorem continuous_uncurry_left {f : X → Y → Z} (x : X) (h : Continuous (uncurry f)) :
theorem Continuous.uncurry_left {f : X → Y → Z} (x : X) (h : Continuous (uncurry f)) :
Continuous (f x) :=
h.comp (Continuous.Prod.mk _)
#align continuous_uncurry_left continuous_uncurry_left
#align continuous_uncurry_left Continuous.uncurry_left

theorem continuous_uncurry_right {f : X → Y → Z} (y : Y) (h : Continuous (uncurry f)) :
theorem Continuous.uncurry_right {f : X → Y → Z} (y : Y) (h : Continuous (uncurry f)) :
Continuous fun a => f a y :=
h.comp (Continuous.Prod.mk_left _)
#align continuous_uncurry_right continuous_uncurry_right
#align continuous_uncurry_right Continuous.uncurry_right

-- 2024-03-09
@[deprecated] alias continuous_uncurry_left := Continuous.uncurry_left
girving marked this conversation as resolved.
Show resolved Hide resolved
@[deprecated] alias continuous_uncurry_right := Continuous.uncurry_right

theorem continuous_curry {g : X × Y → Z} (x : X) (h : Continuous g) : Continuous (curry g x) :=
continuous_uncurry_left x h
Continuous.uncurry_left x h
#align continuous_curry continuous_curry

theorem IsOpen.prod {s : Set X} {t : Set Y} (hs : IsOpen s) (ht : IsOpen t) : IsOpen (s ×ˢ t) :=
Expand Down Expand Up @@ -635,6 +639,29 @@ theorem ContinuousAt.prod_map' {f : X → Z} {g : Y → W} {x : X} {y : Y} (hf :
hf.fst'.prod hg.snd'
#align continuous_at.prod_map' ContinuousAt.prod_map'

theorem ContinuousAt.comp₂ {f : Y × Z → W} {g : X → Y} {h : X → Z} {x : X}
(hf : ContinuousAt f (g x, h x)) (hg : ContinuousAt g x) (hh : ContinuousAt h x) :
ContinuousAt (fun x ↦ f (g x, h x)) x :=
ContinuousAt.comp hf (hg.prod hh)

theorem ContinuousAt.comp₂_of_eq {f : Y × Z → W} {g : X → Y} {h : X → Z} {x : X} {y : Y × Z}
(hf : ContinuousAt f y) (hg : ContinuousAt g x) (hh : ContinuousAt h x) (e : (g x, h x) = y) :
ContinuousAt (fun x ↦ f (g x, h x)) x := by
rw [← e] at hf
exact hf.comp₂ hg hh

/-- Continuous functions on products are continuous in their first argument -/
theorem Continuous.curry_left {f : X × Y → Z} (hf : Continuous f) {y : Y} :
Continuous fun x ↦ f (x, y) :=
hf.comp (continuous_id.prod_mk continuous_const)
alias Continuous.along_fst := Continuous.curry_left

/-- Continuous functions on products are continuous in their second argument -/
theorem Continuous.curry_right {f : X × Y → Z} (hf : Continuous f) {x : X} :
Continuous fun y ↦ f (x, y) :=
hf.comp (continuous_const.prod_mk continuous_id)
alias Continuous.along_snd := Continuous.curry_right

-- todo: reformulate using `Set.image2`
-- todo: prove a version of `generateFrom_union` with `image2 (∩) s t` in the LHS and use it here
theorem prod_generateFrom_generateFrom_eq {X Y : Type*} {s : Set (Set X)} {t : Set (Set Y)}
Expand Down
13 changes: 13 additions & 0 deletions Mathlib/Topology/ContinuousOn.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1145,6 +1145,19 @@ theorem ContinuousOn.prod {f : α → β} {g : α → γ} {s : Set α} (hf : Con
ContinuousWithinAt.prod (hf x hx) (hg x hx)
#align continuous_on.prod ContinuousOn.prod

theorem ContinuousAt.comp₂_continuousWithinAt {f : β × γ → δ} {g : α → β} {h : α → γ} {x : α}
{s : Set α} (hf : ContinuousAt f (g x, h x)) (hg : ContinuousWithinAt g s x)
(hh : ContinuousWithinAt h s x) :
ContinuousWithinAt (fun x ↦ f (g x, h x)) s x :=
ContinuousAt.comp_continuousWithinAt hf (hg.prod hh)

theorem ContinuousAt.comp₂_continuousWithinAt_of_eq {f : β × γ → δ} {g : α → β}
{h : α → γ} {x : α} {s : Set α} {y : β × γ} (hf : ContinuousAt f y)
(hg : ContinuousWithinAt g s x) (hh : ContinuousWithinAt h s x) (e : (g x, h x) = y) :
ContinuousWithinAt (fun x ↦ f (g x, h x)) s x := by
rw [← e] at hf
exact hf.comp₂_continuousWithinAt hg hh

theorem Inducing.continuousWithinAt_iff {f : α → β} {g : β → γ} (hg : Inducing g) {s : Set α}
{x : α} : ContinuousWithinAt f s x ↔ ContinuousWithinAt (g ∘ f) s x := by
simp_rw [ContinuousWithinAt, Inducing.tendsto_nhds_iff hg]; rfl
Expand Down
3 changes: 1 addition & 2 deletions Mathlib/Topology/Separation.lean
Original file line number Diff line number Diff line change
Expand Up @@ -1594,8 +1594,7 @@ theorem eqOn_closure₂' [T2Space Z] {s : Set X} {t : Set Y} {f g : X → Y →
theorem eqOn_closure₂ [T2Space Z] {s : Set X} {t : Set Y} {f g : X → Y → Z}
(h : ∀ x ∈ s, ∀ y ∈ t, f x y = g x y) (hf : Continuous (uncurry f))
(hg : Continuous (uncurry g)) : ∀ x ∈ closure s, ∀ y ∈ closure t, f x y = g x y :=
eqOn_closure₂' h (fun x => continuous_uncurry_left x hf) (fun x => continuous_uncurry_right x hf)
(fun y => continuous_uncurry_left y hg) fun y => continuous_uncurry_right y hg
eqOn_closure₂' h hf.uncurry_left hf.uncurry_right hg.uncurry_left hg.uncurry_right
#align eq_on_closure₂ eqOn_closure₂

/-- If `f x = g x` for all `x ∈ s` and `f`, `g` are continuous on `t`, `s ⊆ t ⊆ closure s`, then
Expand Down
Loading