Theorem: continuousOn_prod_of_continuousOn_lipschitz_on
File: Mathlib/Topology/MetricSpace/Lipschitz.lean

tactic: rintro ⟨x, y⟩ ⟨hx : x ∈ s, hy : y ∈ t⟩
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
⊢ ContinuousOn f (s ×ˢ t)

tactic: refine' EMetric.tendsto_nhds.2 fun ε (ε0 : 0 < ε) => _
state_before: case mk.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
⊢ ContinuousWithinAt f (s ×ˢ t) (x, y)

tactic: replace ε0 : 0 < ε / 2 := ENNReal.half_pos (ne_of_gt ε0)
state_before: case mk.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
ε : ℝ≥0∞
ε0 : 0 < ε
⊢ ∀ᶠ (x_1 : α × β) in 𝓝[s ×ˢ t] (x, y), edist (f x_1) (f (x, y)) < ε

tactic: have εK : 0 < ε / 2 / K := ENNReal.div_pos_iff.2 ⟨ε0.ne', ENNReal.coe_ne_top⟩
state_before: case mk.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
ε : ℝ≥0∞
ε0 : 0 < ε / 2
⊢ ∀ᶠ (x_1 : α × β) in 𝓝[s ×ˢ t] (x, y), edist (f x_1) (f (x, y)) < ε

tactic: have A : s ∩ EMetric.ball x (ε / 2 / K) ∈ 𝓝[s] x :=
  inter_mem_nhdsWithin _ (EMetric.ball_mem_nhds _ εK)
state_before: case mk.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
ε : ℝ≥0∞
ε0 : 0 < ε / 2
εK : 0 < ε / 2 / ↑K
⊢ ∀ᶠ (x_1 : α × β) in 𝓝[s ×ˢ t] (x, y), edist (f x_1) (f (x, y)) < ε

tactic: have B : { b : β | b ∈ t ∧ edist (f (x, b)) (f (x, y)) < ε / 2 } ∈ 𝓝[t] y :=
  inter_mem self_mem_nhdsWithin (ha x hx y hy (EMetric.ball_mem_nhds _ ε0))
state_before: case mk.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
ε : ℝ≥0∞
ε0 : 0 < ε / 2
εK : 0 < ε / 2 / ↑K
A : s ∩ EMetric.ball x (ε / 2 / ↑K) ∈ 𝓝[s] x
⊢ ∀ᶠ (x_1 : α × β) in 𝓝[s ×ˢ t] (x, y), edist (f x_1) (f (x, y)) < ε

tactic: filter_upwards [nhdsWithin_prod A B]
state_before: case mk.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
ε : ℝ≥0∞
ε0 : 0 < ε / 2
εK : 0 < ε / 2 / ↑K
A : s ∩ EMetric.ball x (ε / 2 / ↑K) ∈ 𝓝[s] x
B : {b | b ∈ t ∧ edist (f (x, b)) (f (x, y)) < ε / 2} ∈ 𝓝[t] y
⊢ ∀ᶠ (x_1 : α × β) in 𝓝[s ×ˢ t] (x, y), edist (f x_1) (f (x, y)) < ε

tactic: rintro ⟨a, b⟩ ⟨⟨has : a ∈ s, hax : edist a x < ε / 2 / K⟩, hbt : b ∈ t,
  hby : edist (f (x, b)) (f (x, y)) < ε / 2⟩
state_before: case h
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
ε : ℝ≥0∞
ε0 : 0 < ε / 2
εK : 0 < ε / 2 / ↑K
A : s ∩ EMetric.ball x (ε / 2 / ↑K) ∈ 𝓝[s] x
B : {b | b ∈ t ∧ edist (f (x, b)) (f (x, y)) < ε / 2} ∈ 𝓝[t] y
⊢ ∀ (a : α × β),
    a ∈ (s ∩ EMetric.ball x (ε / 2 / ↑K)) ×ˢ {b | b ∈ t ∧ edist (f (x, b)) (f (x, y)) < ε / 2} →
      edist (f a) (f (x, y)) < ε

tactic: calc
  edist (f (a, b)) (f (x, y)) ≤ edist (f (a, b)) (f (x, b)) + edist (f (x, b)) (f (x, y)) :=
    edist_triangle _ _ _
  _ < ε / 2 + ε / 2 := (ENNReal.add_lt_add ((hb _ hbt).edist_lt_of_edist_lt_div has hx hax) hby)
  _ = ε := ENNReal.add_halves ε
state_before: case h.mk.intro.intro.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝² : PseudoEMetricSpace α
inst✝¹ : TopologicalSpace β
inst✝ : PseudoEMetricSpace γ
f : α × β → γ
s : Set α
t : Set β
K : ℝ≥0
ha : ∀ (a : α), a ∈ s → ContinuousOn (fun y => f (a, y)) t
hb : ∀ (b : β), b ∈ t → LipschitzOnWith K (fun x => f (x, b)) s
x : α
y : β
hx : x ∈ s
hy : y ∈ t
ε : ℝ≥0∞
ε0 : 0 < ε / 2
εK : 0 < ε / 2 / ↑K
A : s ∩ EMetric.ball x (ε / 2 / ↑K) ∈ 𝓝[s] x
B : {b | b ∈ t ∧ edist (f (x, b)) (f (x, y)) < ε / 2} ∈ 𝓝[t] y
a : α
b : β
has : a ∈ s
hax : edist a x < ε / 2 / ↑K
hbt : b ∈ t
hby : edist (f (x, b)) (f (x, y)) < ε / 2
⊢ edist (f (a, b)) (f (x, y)) < ε