Zulip Chat Archive
Stream: Is there code for X?
Topic: involutive f ↔ f ∘ f = id
Eric Wieser (Sep 23 2020 at 09:19):
I have a goal of the form map (reverse ∘ reverse) l = l for some nested list l, and would like it to simplify. Unfortunately, docs#list.reverse_reverse doesn't apply here, as there is no direct application.
I can write
lemma involutive_comp_self {f : α → α} (h : function.involutive f) : f ∘ f = id :=
by {funext, simp [h x]}
and then use involutive_comp_self reverse_reverse but this isn't suitable as a simp lemma due to the h. Can I make h be inferred by simp too?
Should involutive_comp_self be in mathlib?
Kyle Miller (Sep 23 2020 at 09:23):
(I have no comment about mathlib, but you can simplify the proof to the term funext h.)
Johan Commelin (Sep 23 2020 at 09:25):
@Eric Wieser I would call the lemma involutive.comp_self (with a .).
Does reverse_involutive exist? If not, it should.
Johan Commelin (Sep 23 2020 at 09:25):
You would then be able to use reverse_involutive.comp_self
Eric Wieser (Sep 23 2020 at 09:26):
Does it make sense to change the definition of reverse_reverse to be involutive reverse instead of reverse reverse l = l?
Johan Commelin (Sep 23 2020 at 09:26):
No, I think we want both names
Eric Wieser (Sep 23 2020 at 09:27):
Can we make involutive.comp_self be simp somehow, where the proof of involutiveness is found automatically?
Johan Commelin (Sep 23 2020 at 09:28):
Yes, you can make it simp, but you will need to feed reverse_involutive into the simp set, for it to work.
Johan Commelin (Sep 23 2020 at 09:28):
I'm not sure if reverse_involutive should be @[simp] by default.
Eric Wieser (Sep 23 2020 at 09:28):
If we did that, presumably reverse_reverse could be removed from the simp set?
Eric Wieser (Sep 23 2020 at 10:38):
Added as part of #4222
Reid Barton (Sep 23 2020 at 12:50):
Eric Wieser said:
If we did that, presumably
reverse_reversecould be removed from the simp set?
I'm skeptical--I don't think there is any way simp could then look at reverse (reverse l) and think, "gee, I wish I knew reverse was involutive, so I could apply the definition of involutive"--the reason being that a lemma (h : involutive f) : f (f x) = x isn't a valid form for a simp lemma.
Similarly, I think changing the statement of reverse_reverse to be involutive reverse will prevent it from being used conveniently with both simp and rw.
Gabriel Ebner (Sep 23 2020 at 13:24):
I think the canonical solution is to have two lemmas here:
@[simp] lemma reverse_reverse {x : list α} : x.reverse.reverse = x := ...
@[simp] lemma reverse_comp_reverse : (reverse ∘ reverse) = @id (list α) := by ext; simp
Similar to docs#deriv_pow and docs#deriv_pow', etc. (∘ is a bit of a pain in simp lemmas sometimes, but it should be fine here. We should really make it semireducible one day.)
Eric Wieser (Sep 23 2020 at 13:29):
Presumably we still want a third lemma, involutive reverse?
Gabriel Ebner (Sep 23 2020 at 13:37):
Sure, seems reasonable enough.
Gabriel Ebner (Sep 23 2020 at 13:38):
Johan Commelin said:
I'm not sure if
reverse_involutiveshould be@[simp]by default.
IMHO it should definitely be simp, there's no real downside.
Eric Wieser (Sep 23 2020 at 13:39):
So now every single involutive def needs two obvious lemmas on top of the original lemma (+ the standard func_inj one). Is there any way to avoid all this repetition?
Eric Wieser (Sep 23 2020 at 13:40):
Making involutive a class might solve that problem. Would that be sane?
Johan Commelin (Sep 23 2020 at 13:44):
Well, we tried that with semi-bundled homs, but simp didn't fire in many cases.
Johan Commelin (Sep 23 2020 at 13:44):
Hence we started the bundled hom story. But I don't think we want bundled involutions.
Gabriel Ebner (Sep 23 2020 at 13:59):
Eric Wieser said:
So now every single involutive
defneeds two obvious lemmas on top of the original lemma (+ the standardfunc_injone). Is there any way to avoid all this repetition?
If you make both involutive.comp_self and involutive_reverse simp, then you don't need reverse_comp_reverse. But yeah, it's still two lemmas.
Eric Wieser (Sep 23 2020 at 14:02):
You're right, I overcounter. For reverse, in my PR #4222 and master we have
reverse_reversereverse_involutive := reverse_reverse(new in my PR)reverse_injective := reverse_involutive.injectivereverse_inj : = reverse_injective.eq_iff
Perhaps we can remove some of these
Reid Barton (Sep 23 2020 at 14:05):
In your original goal, I think you should also just be able to add function.comp to the list of simp lemmas, and that should enable reverse_reverse to fire
Eric Wieser (Sep 23 2020 at 14:17):
Reid Barton said:
In your original goal, I think you should also just be able to add
function.compto the list of simp lemmas, and that should enablereverse_reverseto fire
That doesn't work, the goal reduces to l = map (λ (x : list α), x) l, which doesn't match the map_id simp lemma
Gabriel Ebner (Sep 23 2020 at 15:00):
So we need map_id' : xs.map (λ x, x) = xs!
Eric Wieser (Sep 23 2020 at 15:40):
And the same for every other lemma that currently involves id?
Gabriel Ebner (Sep 23 2020 at 15:50):
We already do, see docs#deriv_id, docs#deriv_id', docs#deriv_id'', etc.
Eric Wieser (Sep 23 2020 at 15:53):
Is a simp lemma from id to (λ x, x) sensible to eliminate the duplication?
Eric Wieser (Sep 23 2020 at 15:54):
(Also, does your suggestion go against or complement the new lemma in my PR?)
Johan Commelin (Sep 23 2020 at 16:59):
Gabriel Ebner said:
We already do, see docs#deriv_id, docs#deriv_id', docs#deriv_id'', etc.
I feel like this is a bit of a symptom. It would be good if we could find a way to avoid these repetitive statements.
Eric Wieser (Sep 24 2020 at 13:21):
Gabriel Ebner said:
If you make ...
involutive_reversesimp, then ...
It seems that while marking involutive reverse with simp is fine, marking injective reverse fails with:
/- The `simp_var_head` linter reports: -/
/- LEFT-HAND SIDE HAS VARIABLE AS HEAD SYMBOL.
Some simp lemmas have a variable as head symbol of the left-hand side: -/
-- data/list/basic.lean
#print list.reverse_injective /- Left-hand side has variable as head symbol: a₁ -/
I don't understand this error @Gabriel Ebner, but I assume I should just ignore your request in https://github.com/leanprover-community/mathlib/pull/4222#discussion_r494285415 to make injective reverse simp?
Gabriel Ebner (Sep 24 2020 at 14:10):
Last updated: May 02 2025 at 03:31 UTC