l3lab/ntp-mathlib huggingface dataset:
theorem prod_lipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    LipschitzWith 1 (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le h).ne'
    rw [prod_edist_eq_add (zero_lt_one.trans_le h)]
    simp only [edist, forall_prop_of_true, one_mul, ENNReal.coe_one, ge_iff_le, sup_le_iff]
    constructor
    · calc
        edist x.fst y.fst ≤ (edist x.fst y.fst ^ p.toReal) ^ (1 / p.toReal) := by
          simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
        _ ≤ (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          gcongr
          simp only [self_le_add_right]
    · 

Proof state:
case inr.right
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ edist ((WithLp.equiv p (α × β)) x).2 ((WithLp.equiv p (α × β)) y).2 ≤
    (edist x.1 y.1 ^ ENNReal.toReal p + edist x.2 y.2 ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p)

Next tactic:
calc
        edist x.snd y.snd ≤ (edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
        _ ≤ (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          gcongr
          simp only [self_le_add_left]
theorem prod_lipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    LipschitzWith 1 (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le h).ne'
    rw [prod_edist_eq_add (zero_lt_one.trans_le h)]
    simp only [edist, forall_prop_of_true, one_mul, ENNReal.coe_one, ge_iff_le, sup_le_iff]
    constructor
    · calc
        edist x.fst y.fst ≤ (edist x.fst y.fst ^ p.toReal) ^ (1 / p.toReal) := by
          simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
        _ ≤ (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          gcongr
          simp only [self_le_add_right]
    · calc
        edist x.snd y.snd ≤ (edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ edist x.2 y.2 ≤ (edist x.2 y.2 ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p)

Next tactic:
simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
theorem prod_lipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    LipschitzWith 1 (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le h).ne'
    rw [prod_edist_eq_add (zero_lt_one.trans_le h)]
    simp only [edist, forall_prop_of_true, one_mul, ENNReal.coe_one, ge_iff_le, sup_le_iff]
    constructor
    · calc
        edist x.fst y.fst ≤ (edist x.fst y.fst ^ p.toReal) ^ (1 / p.toReal) := by
          simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
        _ ≤ (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          gcongr
          simp only [self_le_add_right]
    · calc
        edist x.snd y.snd ≤ (edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
        _ ≤ (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ (edist x.2 y.2 ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p) ≤
    (edist x.1 y.1 ^ ENNReal.toReal p + edist x.2 y.2 ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p)

Next tactic:
gcongr
theorem prod_lipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    LipschitzWith 1 (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (zero_lt_one.trans_le h).ne'
    rw [prod_edist_eq_add (zero_lt_one.trans_le h)]
    simp only [edist, forall_prop_of_true, one_mul, ENNReal.coe_one, ge_iff_le, sup_le_iff]
    constructor
    · calc
        edist x.fst y.fst ≤ (edist x.fst y.fst ^ p.toReal) ^ (1 / p.toReal) := by
          simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
        _ ≤ (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          gcongr
          simp only [self_le_add_right]
    · calc
        edist x.snd y.snd ≤ (edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          simp only [← ENNReal.rpow_mul, cancel, ENNReal.rpow_one, le_refl]
        _ ≤ (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) := by
          gcongr
          

Proof state:
case h₁
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ edist x.2 y.2 ^ ENNReal.toReal p ≤ edist x.1 y.1 ^ ENNReal.toReal p + edist x.2 y.2 ^ ENNReal.toReal p

Next tactic:
simp only [self_le_add_left]
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
⊢ AntilipschitzWith (2 ^ ENNReal.toReal (1 / p)) ⇑(WithLp.equiv p (α × β))

Next tactic:
intro x y
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
⊢ edist x y ≤ ↑(2 ^ ENNReal.toReal (1 / p)) * edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
rcases p.dichotomy with (rfl | h)
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · 

Proof state:
case inl
𝕜 : Type u_1
α : Type u_2
β : Type u_3
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
hp : Fact (1 ≤ ⊤)
x y : WithLp ⊤ (α × β)
⊢ edist x y ≤ ↑(2 ^ ENNReal.toReal (1 / ⊤)) * edist ((WithLp.equiv ⊤ (α × β)) x) ((WithLp.equiv ⊤ (α × β)) y)

Next tactic:
simp [edist]
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · 

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
⊢ edist x y ≤ ↑(2 ^ ENNReal.toReal (1 / p)) * edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
have pos : 0 < p.toReal := by positivity
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by 

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
⊢ 0 < ENNReal.toReal p

Next tactic:
positivity
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
⊢ edist x y ≤ ↑(2 ^ ENNReal.toReal (1 / p)) * edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
have nonneg : 0 ≤ 1 / p.toReal := by positivity
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by 

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
⊢ 0 ≤ 1 / ENNReal.toReal p

Next tactic:
positivity
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
⊢ edist x y ≤ ↑(2 ^ ENNReal.toReal (1 / p)) * edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
    

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ edist x y ≤ ↑(2 ^ ENNReal.toReal (1 / p)) * edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
rw [prod_edist_eq_add pos, ENNReal.toReal_div 1 p]
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
    rw [prod_edist_eq_add pos, ENNReal.toReal_div 1 p]
    

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ (edist x.1 y.1 ^ ENNReal.toReal p + edist x.2 y.2 ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p) ≤
    ↑(2 ^ (ENNReal.toReal 1 / ENNReal.toReal p)) * edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
simp only [edist, ← one_div, ENNReal.one_toReal]
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
    rw [prod_edist_eq_add pos, ENNReal.toReal_div 1 p]
    simp only [edist, ← one_div, ENNReal.one_toReal]
    

Proof state:
case inr
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ (edist x.1 y.1 ^ ENNReal.toReal p + edist x.2 y.2 ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p) ≤
    ↑(2 ^ (1 / ENNReal.toReal p)) *
      (edist ((WithLp.equiv p (α × β)) x).1 ((WithLp.equiv p (α × β)) y).1 ⊔
        edist ((WithLp.equiv p (α × β)) x).2 ((WithLp.equiv p (α × β)) y).2)

Next tactic:
calc
      (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) ≤
          (edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal +
          edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal) ^ (1 / p.toReal) := by
        gcongr <;> simp [edist]
      _ = (2 ^ (1 / p.toReal) : ℝ≥0) * edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) := by
        simp only [← two_mul, ENNReal.mul_rpow_of_nonneg _ _ nonneg, ← ENNReal.rpow_mul, cancel,
          ENNReal.rpow_one, ← ENNReal.coe_rpow_of_nonneg _ nonneg, coe_ofNat]
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
    rw [prod_edist_eq_add pos, ENNReal.toReal_div 1 p]
    simp only [edist, ← one_div, ENNReal.one_toReal]
    calc
      (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) ≤
          (edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal +
          edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal) ^ (1 / p.toReal) := by
        

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ (edist x.1 y.1 ^ ENNReal.toReal p + edist x.2 y.2 ^ ENNReal.toReal p) ^ (1 / ENNReal.toReal p) ≤
    (edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y) ^ ENNReal.toReal p +
        edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y) ^ ENNReal.toReal p) ^
      (1 / ENNReal.toReal p)

Next tactic:
gcongr
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
    rw [prod_edist_eq_add pos, ENNReal.toReal_div 1 p]
    simp only [edist, ← one_div, ENNReal.one_toReal]
    calc
      (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) ≤
          (edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal +
          edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal) ^ (1 / p.toReal) := by
        gcongr <;> 

Proof state:
case h₁.h₁.h₁
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ edist x.1 y.1 ≤ edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
simp [edist]
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
    rw [prod_edist_eq_add pos, ENNReal.toReal_div 1 p]
    simp only [edist, ← one_div, ENNReal.one_toReal]
    calc
      (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) ≤
          (edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal +
          edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal) ^ (1 / p.toReal) := by
        gcongr <;> 

Proof state:
case h₁.h₂.h₁
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ edist x.2 y.2 ≤ edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
simp [edist]
theorem prod_antilipschitzWith_equiv_aux [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    AntilipschitzWith ((2 : ℝ≥0) ^ (1 / p).toReal) (WithLp.equiv p (α × β)) := by
  intro x y
  rcases p.dichotomy with (rfl | h)
  · simp [edist]
  · have pos : 0 < p.toReal := by positivity
    have nonneg : 0 ≤ 1 / p.toReal := by positivity
    have cancel : p.toReal * (1 / p.toReal) = 1 := mul_div_cancel' 1 (ne_of_gt pos)
    rw [prod_edist_eq_add pos, ENNReal.toReal_div 1 p]
    simp only [edist, ← one_div, ENNReal.one_toReal]
    calc
      (edist x.fst y.fst ^ p.toReal + edist x.snd y.snd ^ p.toReal) ^ (1 / p.toReal) ≤
          (edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal +
          edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) ^ p.toReal) ^ (1 / p.toReal) := by
        gcongr <;> simp [edist]
      _ = (2 ^ (1 / p.toReal) : ℝ≥0) * edist (WithLp.equiv p _ x) (WithLp.equiv p _ y) := by
        

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
x y : WithLp p (α × β)
h : 1 ≤ ENNReal.toReal p
pos : 0 < ENNReal.toReal p
nonneg : 0 ≤ 1 / ENNReal.toReal p
cancel : ENNReal.toReal p * (1 / ENNReal.toReal p) = 1
⊢ (edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y) ^ ENNReal.toReal p +
        edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y) ^ ENNReal.toReal p) ^
      (1 / ENNReal.toReal p) =
    ↑(2 ^ (1 / ENNReal.toReal p)) * edist ((WithLp.equiv p (α × β)) x) ((WithLp.equiv p (α × β)) y)

Next tactic:
simp only [← two_mul, ENNReal.mul_rpow_of_nonneg _ _ nonneg, ← ENNReal.rpow_mul, cancel,
          ENNReal.rpow_one, ← ENNReal.coe_rpow_of_nonneg _ nonneg, coe_ofNat]
theorem prod_aux_uniformity_eq [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    𝓤 (WithLp p (α × β)) = 𝓤[instUniformSpaceProd] := by
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
⊢ 𝓤 (WithLp p (α × β)) = 𝓤 (α × β)

Next tactic:
have A : UniformInducing (WithLp.equiv p (α × β)) :=
    (prod_antilipschitzWith_equiv_aux p α β).uniformInducing
      (prod_lipschitzWith_equiv_aux p α β).uniformContinuous
theorem prod_aux_uniformity_eq [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    𝓤 (WithLp p (α × β)) = 𝓤[instUniformSpaceProd] := by
  have A : UniformInducing (WithLp.equiv p (α × β)) :=
    (prod_antilipschitzWith_equiv_aux p α β).uniformInducing
      (prod_lipschitzWith_equiv_aux p α β).uniformContinuous
  

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
A : UniformInducing ⇑(WithLp.equiv p (α × β))
⊢ 𝓤 (WithLp p (α × β)) = 𝓤 (α × β)

Next tactic:
have : (fun x : WithLp p (α × β) × WithLp p (α × β) =>
    ((WithLp.equiv p (α × β)) x.fst, (WithLp.equiv p (α × β)) x.snd)) = id :=
    by ext i <;> rfl
theorem prod_aux_uniformity_eq [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    𝓤 (WithLp p (α × β)) = 𝓤[instUniformSpaceProd] := by
  have A : UniformInducing (WithLp.equiv p (α × β)) :=
    (prod_antilipschitzWith_equiv_aux p α β).uniformInducing
      (prod_lipschitzWith_equiv_aux p α β).uniformContinuous
  have : (fun x : WithLp p (α × β) × WithLp p (α × β) =>
    ((WithLp.equiv p (α × β)) x.fst, (WithLp.equiv p (α × β)) x.snd)) = id :=
    by 

Proof state:
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
A : UniformInducing ⇑(WithLp.equiv p (α × β))
⊢ (fun x => ((WithLp.equiv p (α × β)) x.1, (WithLp.equiv p (α × β)) x.2)) = id

Next tactic:
ext i
theorem prod_aux_uniformity_eq [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    𝓤 (WithLp p (α × β)) = 𝓤[instUniformSpaceProd] := by
  have A : UniformInducing (WithLp.equiv p (α × β)) :=
    (prod_antilipschitzWith_equiv_aux p α β).uniformInducing
      (prod_lipschitzWith_equiv_aux p α β).uniformContinuous
  have : (fun x : WithLp p (α × β) × WithLp p (α × β) =>
    ((WithLp.equiv p (α × β)) x.fst, (WithLp.equiv p (α × β)) x.snd)) = id :=
    by ext i <;> 

Proof state:
case h.a.a
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
A : UniformInducing ⇑(WithLp.equiv p (α × β))
i : WithLp p (α × β) × WithLp p (α × β)
⊢ ((WithLp.equiv p (α × β)) i.1, (WithLp.equiv p (α × β)) i.2).1.1 = (id i).1.1

Next tactic:
rfl
theorem prod_aux_uniformity_eq [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    𝓤 (WithLp p (α × β)) = 𝓤[instUniformSpaceProd] := by
  have A : UniformInducing (WithLp.equiv p (α × β)) :=
    (prod_antilipschitzWith_equiv_aux p α β).uniformInducing
      (prod_lipschitzWith_equiv_aux p α β).uniformContinuous
  have : (fun x : WithLp p (α × β) × WithLp p (α × β) =>
    ((WithLp.equiv p (α × β)) x.fst, (WithLp.equiv p (α × β)) x.snd)) = id :=
    by ext i <;> 

Proof state:
case h.a.a
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
A : UniformInducing ⇑(WithLp.equiv p (α × β))
i : WithLp p (α × β) × WithLp p (α × β)
⊢ ((WithLp.equiv p (α × β)) i.1, (WithLp.equiv p (α × β)) i.2).1.2 = (id i).1.2

Next tactic:
rfl
theorem prod_aux_uniformity_eq [PseudoEMetricSpace α] [PseudoEMetricSpace β] :
    𝓤 (WithLp p (α × β)) = 𝓤[instUniformSpaceProd] := by
  have A : UniformInducing (WithLp.equiv p (α × β)) :=
    (prod_antilipschitzWith_equiv_aux p α β).uniformInducing
      (prod_lipschitzWith_equiv_aux p α β).uniformContinuous
  have : (fun x : WithLp p (α × β) × WithLp p (α × β) =>
    ((WithLp.equiv p (α × β)) x.fst, (WithLp.equiv p (α × β)) x.snd)) = id :=
    by ext i <;> 

Proof state:
case h.a.a
p : ℝ≥0∞
𝕜 : Type u_1
α : Type u_2
β : Type u_3
hp : Fact (1 ≤ p)
inst✝¹ : PseudoEMetricSpace α
inst✝ : PseudoEMetricSpace β
A : UniformInducing ⇑(WithLp.equiv p (α × β))
i : WithLp p (α × β) × WithLp p (α × β)
⊢ ((WithLp.equiv p (α × β)) i.1, (WithLp.equiv p (α × β)) i.2).2.1 = (id i).2.1

Next tactic:
rfl