Zulip Chat Archive
Stream: mathlib4
Topic: NormedAddCommGroup (WithLp p α × β)
Christopher Hoskin (Jan 01 2025 at 14:12):
Please can someone advise why the following mwe doesn't work:
import Mathlib.Analysis.Normed.Lp.ProdLp
import Mathlib.Analysis.NormedSpace.MStructure
noncomputable section WithL1
open Real Set Filter RCLike Bornology Uniformity Topology NNReal ENNReal
variable (p : ℝ≥0∞) (𝕜 α β : Type*)
variable {p 𝕜 α β}
variable [NormedAddCommGroup α] [NormedAddCommGroup β]
def P1 : AddMonoid.End (WithLp p α × β) := (AddMonoidHom.inl α β).comp (AddMonoidHom.fst α β)
def P2 : AddMonoid.End (WithLp p α × β) := (AddMonoidHom.inr α β).comp (AddMonoidHom.snd α β)
variable (x : WithLp p α × β)
#check P1 x
lemma P1_idempotent : IsIdempotentElem (M := (AddMonoid.End (WithLp p α × β))) P1 := by
rw [IsIdempotentElem, P1]
rfl
variable [hp : Fact (1 ≤ p)]
noncomputable instance instProdNormedAddCommGroup :
NormedAddCommGroup (WithLp p (α × β)) := {
WithLp.instProdNormedAddCommGroup p α β with
}
lemma P1_Lprojection :
IsLprojection (WithLp p α × β) (M := (AddMonoid.End (WithLp p α × β))) P1 := sorry
end WithL1
Lemma P1_Lprojection
(which I know is only true with the current def with p=1) produces the error message:
failed to synthesize
NormedAddCommGroup (WithLp p α × β)
What am missing?
Thanks and Happy New Year!
Christopher
Edward van de Meent (Jan 01 2025 at 14:16):
i think you're looking for this:
lemma P1_Lprojection :
IsLprojection (WithLp p (α × β)) (M := (AddMonoid.End (WithLp p (α × β)))) (P1 (p := p)) := sorry
Christopher Hoskin (Jan 01 2025 at 14:17):
This works as a statement:
lemma P1lproj :
letI := WithLp.instProdNormedAddCommGroup 1 α β
@IsLprojection (WithLp 1 α × β) (WithLp.instProdNormedAddCommGroup 1 α β)
(AddMonoid.End (WithLp 1 α × β)) _ _ P1 := sorry
But then I get the same failed to synthesize NormedAddCommGroup (WithLp p α × β)
message when trying to fill in the proof.
Edward van de Meent (Jan 01 2025 at 14:18):
i'm not sure why you're using WithLp p
without the brackets... you do realise that it only does things when the argument is a pi type or product?
Christopher Hoskin (Jan 01 2025 at 14:20):
Edward van de Meent said:
i think you're looking for this:
lemma P1_Lprojection : IsLprojection (WithLp p (α × β)) (M := (AddMonoid.End (WithLp p (α × β)))) (P1 (p := p)) := sorry
Thanks - thought I'd tried that, but obviously not. It looks like it works!
Edward van de Meent (Jan 01 2025 at 14:21):
i.e. WithLp p α × β
(which gets bracketed as (WithLp p α) × β
) means "put the Lp norm on α
, then use the maximum of the norms on the product", which i'm guessing doesn't respect addition?
Christopher Hoskin (Jan 01 2025 at 14:22):
Ah, it should be WithLp p (α × β)
not WithLp p α × β
- that was my typo.
Christopher Hoskin (Jan 01 2025 at 18:24):
I've drafted a PR #20380 - needs work though. Showing:
‖x.1‖ = ‖(x.1, 0)‖
for (x : WithLp p (α × β))
0 < p < ∞
seems surprisingly difficult.
Edward van de Meent (Jan 01 2025 at 18:45):
do you mean ‖(WithLp.equiv p (α × β)).symm (x.1,0)‖
, btw?
Edward van de Meent (Jan 01 2025 at 18:45):
otherwise lean might think you mean the maximum norm of α × β
Christopher Hoskin (Jan 01 2025 at 18:57):
@Edward van de Meent it's here: https://github.com/leanprover-community/mathlib4/pull/20380/files#diff-cb790f5ea1d9fce79724cd8acc3c53dab6d56b3c3e5f1d3b8844a0f9ad8ec162R356
on the left, @norm α NormedAddCommGroup.toNorm x.1 : ℝ
and on the right @norm (WithLp p (α × β)) (WithLp.instProdNorm p α β) (x.1, 0) : ℝ
.
Edward van de Meent (Jan 01 2025 at 19:00):
right.... my main concern here is that(from the snippets you send) you are abusing the fact that WithLp p
is the identity. this is bad from a lemma application pov
Edward van de Meent (Jan 01 2025 at 20:05):
i think this file might benefit from the following:
protected def fst : α := (WithLp.equiv p (α × β) x).fst
protected def snd : β := (WithLp.equiv p (α × β) x).snd
@[simp]
theorem prod_fst {α β : Type*} (x : WithLp p (α × β)) : Prod.fst x = x.fst := rfl
@[simp]
theorem prod_snd {α β : Type*} (x : WithLp p (α × β)) : Prod.snd x = x.snd := rfl
with this, the simp normal form at least is immediately type correct.
Christopher Hoskin (Jan 01 2025 at 20:57):
@Edward van de Meent isn't that essentially what WithLp.equiv_fst
and WithLp.equiv_snd
do?
Did you mean for this to be added to Analysis/Normed/Lp/ProdLp
?
Edward van de Meent (Jan 01 2025 at 20:58):
no. currently, the normal form uses Prod.fst
and Prod.snd
, which forces defeq abuse
Edward van de Meent (Jan 01 2025 at 20:59):
making WithLp.fst
and -snd
available in the file makes it automagically use this version tho, so the fix is very light
Edward van de Meent (Jan 01 2025 at 20:59):
aamof, the change really only needs 3 lines of code on all of mathlib, imma PR this in a minute
Eric Wieser (Jan 01 2025 at 21:00):
I'm not sure this is actually a good idea
Edward van de Meent (Jan 01 2025 at 21:00):
how so? this removes defeq abuse?
Eric Wieser (Jan 01 2025 at 21:00):
Certainly I don't like the strategy of having simp lemmas that use defeq abuse to try and avoid later defeq abuse
Edward van de Meent (Jan 01 2025 at 21:01):
those simp lemmas i posted actually aren't necessary, i think...
Edward van de Meent (Jan 01 2025 at 21:01):
i compiled mathlib without them
Christopher Hoskin (Jan 01 2025 at 21:02):
From my perspective, the main difficulty I was having was showing that:
a^ (p.toReal) ^ (1 / p.toReal) = a
This is almost NNReal.rpow_inv_rpow_self
but not quite.
Eric Wieser (Jan 01 2025 at 21:03):
As for x.1
vs (WithLp.equiv p (α × β) x).fst
when x : WithLp p (α × β)
, I think the latter is indeed the more principled, but in practice I think it just creates boilerplate. We already have something similar with x : WithLp p (α →β)
and x i
, and seem to largely get away with it
Eric Wieser (Jan 01 2025 at 21:03):
Christopher Hoskin said:
This is almost
NNReal.rpow_inv_rpow_self
but not quite.
It would certainly help if we were consistent in choosing between x ^ (1 / p)
and x ^ (p⁻¹)
. My preference would be for the latter...
Edward van de Meent (Jan 01 2025 at 21:04):
Eric Wieser said:
but in practice I think it just creates boilerplate
from my local build run, it looks like the boilerplate already exists, but just using the wrong function :upside_down:
Edward van de Meent (Jan 01 2025 at 21:06):
no added simp lemmas needed, sheer existance of these functions seems to make all defeq abuse fly away
Eric Wieser (Jan 01 2025 at 21:07):
A little more precisely, I think the issue with #20380 is not defeq abuse of fst
and snd
, but defeq abuse of Prod.mk
Edward van de Meent (Jan 01 2025 at 21:09):
all that aside, i am of the opinion that WithLp.equiv
is the wrong way around (or should come in the opposite flavour too)
Eric Wieser (Jan 01 2025 at 21:21):
Regarding the original topic, does docs#WihLp.norm_equiv_symm_fst make the proof any easier?
Edward van de Meent (Jan 01 2025 at 21:24):
Eric Wieser (Jan 01 2025 at 21:25):
Indeed,
lemma prod_norm_eq_add_P1 [Fact (1 ≤ p)] (hp : 0 < p.toReal) (x : WithLp p (α × β)) :
‖x‖ = (‖P1 x‖ ^ p.toReal + ‖(1 - P1) x‖ ^ p.toReal) ^ (1 / p.toReal) := by
rw [WithLp.prod_norm_eq_add hp]
rw [← WithLp.norm_equiv_symm_fst p α β x.1, ← WithLp.norm_equiv_symm_snd p α β x.2, P1_compl]
rfl
works
Eric Wieser (Jan 01 2025 at 21:25):
Generally much of the LP library unecessarily assumes [Fact (1 ≤ p)]
when it doesn't need it; I tried to fix this last year in #20389 (which I just promoted from a branch to a draft PR)
Christopher Hoskin (Jan 02 2025 at 08:37):
@Edward van de Meent @Eric Wieser thanks very much for your help. I've updated #20380 to use WithLp.norm_equiv_symm_fst
and WithLp.norm_equiv_symm_snd
with [Fact (1 ≤ p)]
for now.
Last updated: May 02 2025 at 03:31 UTC