Zulip Chat Archive
Stream: Is there code for X?
Topic: rw inside sum
Nick Andersen (May 29 2024 at 19:24):
Is there a way to perform a rewrite inside a sum (or other big operator)?
This is the shortest way I've found.
example {a b : ℕ → ℚ} : ∑ k ∈ range m, a k * b k = ∑ k ∈ range m, b k * a k := by
apply Finset.sum_congr rfl;
intro _ _
rw [mul_comm]
Damiano Testa (May 29 2024 at 19:25):
simp_rw
?
Nick Andersen (May 29 2024 at 19:29):
Thanks, looks like that works.
simp_rw [mul_comm]
Martin Dvořák (May 29 2024 at 19:31):
Specifically _comm
theorems often cause looping inside simp
(_rw
). If it happens to you (which can easily happen if you try to do the same thing without the auxiliary lemma), conv
is your friend!
Kevin Buzzard (May 29 2024 at 19:40):
Can you give an example of looping Martin? I thought that this sometimes happened in Lean 3 but not in Lean 4.
Kevin Buzzard (May 29 2024 at 19:46):
@Nick Andersen here's what a conv
mode proof would look like:
import Mathlib.Tactic
open Finset
variable (m : ℕ)
example {a b : ℕ → ℚ} : ∑ k ∈ range m, a k * b k = ∑ k ∈ range m, b k * a k := by
conv =>
lhs
congr
rfl
intro x
rw [mul_comm]
See https://lean-lang.org/theorem_proving_in_lean4/conv.html for more details.
Martin Dvořák (May 29 2024 at 19:47):
Kevin Buzzard said:
Can you give an example of looping Martin? I thought that this sometimes happened in Lean 3 but not in Lean 4.
import Mathlib
open BigOperators
example {a b : Fin 5 → Fin 4 → ℚ} (hab : a = b) :
∑ i : Fin 5, ∑ j : Fin 4, a i j = ∑ j : Fin 4, ∑ i : Fin 5, b i j := by
rw [Finset.sum_comm, hab]
example {a b : Fin 5 → Fin 4 → ℚ} (hab : a = b) :
∑ i : Fin 5, ∑ j : Fin 4, a i j = ∑ j : Fin 4, ∑ i : Fin 5, b i j := by
simp_rw [Finset.sum_comm]
The first proof succeeds. The second proof times out.
Martin Dvořák (May 29 2024 at 19:50):
Perhaps a better example:
import Mathlib
open BigOperators
example {a b : Fin 5 → Fin 4 → Fin 3 → ℚ} (hab : a = b) :
∑ i : Fin 5, ∑ j : Fin 4, ∑ k : Fin 3, a i j k =
∑ i : Fin 5, ∑ k : Fin 3, ∑ j : Fin 4, b i j k := by
congr
ext
rw [Finset.sum_comm, hab]
example {a b : Fin 5 → Fin 4 → Fin 3 → ℚ} (hab : a = b) :
∑ i : Fin 5, ∑ j : Fin 4, ∑ k : Fin 3, a i j k =
∑ i : Fin 5, ∑ k : Fin 3, ∑ j : Fin 4, b i j k := by
simp_rw [Finset.sum_comm]
example {a b : Fin 5 → Fin 4 → Fin 3 → ℚ} (hab : a = b) :
∑ i : Fin 5, ∑ j : Fin 4, ∑ k : Fin 3, a i j k =
∑ i : Fin 5, ∑ k : Fin 3, ∑ j : Fin 4, b i j k := by
simp [Finset.sum_comm, hab]
The first proof succeeds. The second proof times out. The third proof times out, too.
Kevin Buzzard (May 29 2024 at 19:58):
FWIW here's a more golfed conv proof:
import Mathlib.Tactic
open Finset
variable (m : ℕ)
example {a b : ℕ → ℚ} : ∑ k ∈ range m, a k * b k = ∑ k ∈ range m, b k * a k := by
conv_lhs =>
enter [2, x]
rw [mul_comm]
Martin Dvořák (May 29 2024 at 19:58):
Martin Dvořák (May 29 2024 at 19:59):
Does anybody know if those _comm
theorems that "stay on the same level" never loop?
Martin Dvořák (May 29 2024 at 20:13):
Kevin Buzzard said:
Can you give an example of looping Martin? I thought that this sometimes happened in Lean 3 but not in Lean 4.
Maybe they are only theorems that swap big operators that loop, I don't know...
It sometimes happens to me when I have a serie of transformation inside double sum, which I use simp_rw
for, then I want to do the "main swap" but I am too lazy to close simp_rw
and open rw
instead, so I just add , Finset.sum_comm
inside the simp_rw
and VS Code freezes...
Junyan Xu (May 29 2024 at 20:46):
You can also specify (implicit) arguments:
example {a b : Fin 5 → Fin 4 → Fin 3 → ℚ} (hab : a = b) :
∑ i : Fin 5, ∑ j : Fin 4, ∑ k : Fin 3, a i j k =
∑ i : Fin 5, ∑ k : Fin 3, ∑ j : Fin 4, b i j k := by
simp_rw [Finset.sum_comm (f := a _), hab]
-- or simp_rw [Finset.sum_comm (γ := Fin 4), hab]
Yaël Dillies (May 29 2024 at 20:54):
Martin Dvořák said:
The first proof succeeds. The second proof times out.
I actually think this is partly a regression over Lean 3. Heuristically, it seems that some cases that looped in Lean 3 don't loop in Lean 4, and vice-versa.
Kevin Buzzard (May 29 2024 at 20:58):
I had thought that Lean had some kind of internal total ordering of "things" and simp
only applied mul_comm
when it was putting things in order. But now I realise that I don't really know how this can work, so maybe I'm mistaken (e.g. if some lemma is of the form a * b = c
and we're faced with b * a = c
one would hope simp [mul_comm, the lemma]
would work regardless of whether a < b or not).
Richard Osborn (May 29 2024 at 21:06):
The regular simp
tactic does this. In my experience, simp_rw
doesn't protect against "infinite loops".
Ralf Stephan (May 30 2024 at 07:26):
For rewrite inside BigOperators, see also this thread.
Martin Dvořák (May 30 2024 at 09:19):
Martin Dvořák said:
It sometimes happens to me when I have a serie of transformation inside double sum, which I use
simp_rw
for, then I want to do the "main swap" but I am too lazy to closesimp_rw
and openrw
instead, so I just add, Finset.sum_comm
inside thesimp_rw
and VS Code freezes...
As a result, I learnt not to be lazy to close simp_rw
and open rw
whenever rw
is sufficient.
Sometimes it leads to funny code:
https://github.com/madvorak/vcsp/blob/057db7f3dc735d6a90cabe4bddeea8d665fc4f96/VCSP/FarkasBartl.lean#L182
Yaël Dillies (May 30 2024 at 09:32):
You should probably be using calc
more
Last updated: May 02 2025 at 03:31 UTC