Zulip Chat Archive
Stream: Is there code for X?
Topic: finset.to_list sum
Joseph Hua (Dec 16 2021 at 10:34):
Hi, is there code for
import data.finset
lemma help {A B : Type*}
[decidable_eq A] [add_comm_monoid B] (s : finset A)
(f : A → B)
:
finset.sum s f = (list.map f s.to_list).sum
:=
begin
apply finset.induction_on s,
{simp},
{
intros a s has hind,
rw [finset.sum_insert has, hind],
sorry -- f a + (list.map f s.to_list).sum = (list.map f (insert a s).to_list).sum
},
end
Kevin Buzzard (Dec 16 2021 at 10:39):
My instinct is to show that (insert a s).to_list bijects with a :: s.to_list in the sense of list.perm and then to show that list.map reflects equiv.perm and list.sum sends equivalent lists to equal sums.
Kevin Buzzard (Dec 16 2021 at 10:39):
Do we have any of that?
Yaël Dillies (Dec 16 2021 at 10:40):
Of course. That's basically how finset.sum is defined in the first place.
Kevin Buzzard (Dec 16 2021 at 10:41):
Right! I just don't know my way around
Kevin Buzzard (Dec 16 2021 at 10:44):
OK we've reduced it to a :: s.to_list ~ (insert a s).to_list
Yaël Dillies (Dec 16 2021 at 10:44):
Okay, that sounds actually hard to prove
Johan Commelin (Dec 16 2021 at 10:45):
Hmmz, it seems that finset.sum uses a list.foldr under the hood. Whereas list.sum is using a foldl. That's surprising.
Johan Commelin (Dec 16 2021 at 10:46):
delta finset.sum multiset.sum list.sum multiset.foldr
multiset.map finset.to_list
-- quot.lift_on (quot.lift_on s.val
-- (λ (l : list A), ↑(list.map f l)) _) (λ (l : list B), list.foldr has_add.add 0 l) _ =
-- list.foldl has_add.add 0 (list.map f s.val.to_list)
Kevin Buzzard (Dec 16 2021 at 10:46):
import data.finset
lemma help {A B : Type*}
[decidable_eq A] [add_comm_monoid B] (s : finset A)
(f : A → B)
:
finset.sum s f = (list.map f s.to_list).sum
:=
begin
apply finset.induction_on s,
{simp},
{
intros a s has hind,
rw [finset.sum_insert has, hind],
rw ← list.sum_cons,
apply list.perm.sum_eq,
rw ← list.map_cons,
apply list.perm.map,
-- a :: s.to_list ~ (insert a s).to_list
sorry,
},
end
Yaël Dillies (Dec 16 2021 at 10:46):
Oh actually this is fine because we're talking about finsets, not multisets.
Kevin Buzzard (Dec 16 2021 at 10:46):
(deleted)
Yaël Dillies (Dec 16 2021 at 10:46):
Extensionality is enough.
Kevin Buzzard (Dec 16 2021 at 10:47):
Aah!
Yaël Dillies (Dec 16 2021 at 10:48):
But I don't know how to prove the corresponding statement with docs#multiset.to_list
Kevin Buzzard (Dec 16 2021 at 10:48):
lol list.perm.mem_iff isn't an iff
Kevin Buzzard (Dec 16 2021 at 10:50):
oh because it's not true because of repeats :-/
Ruben Van de Velde (Dec 16 2021 at 10:52):
lemma help {A B : Type*}
[decidable_eq A] [add_comm_monoid B] (s : finset A)
(f : A → B)
:
finset.sum s f = (list.map f s.to_list).sum
:=
begin
apply finset.induction_on s,
{simp},
{ intros a s has hind,
rw [finset.sum_insert has, hind],
rw ← list.sum_cons,
apply list.perm.sum_eq,
rw ← list.map_cons,
apply list.perm.map,
rw list.perm_ext,
{ intros x,
simp only [list.mem_cons_iff, iff_self, finset.mem_to_list, finset.mem_insert] },
{ simp [has, finset.nodup_to_list s] },
{ apply finset.nodup_to_list } },
end
Johan Commelin (Dec 16 2021 at 10:53):
docs#multiset.sum_to_list exists
Joseph Hua (Dec 16 2021 at 10:57):
should this be called finset.sum_to_list? or maybe finset.to_list_sum? whats the convension on the ordering
Anne Baanen (Dec 16 2021 at 10:58):
I'd copy the multiset version and call it finset.sum_to_list. In general we put the "outermost" operator first, in this case sum.
Yaël Dillies (Dec 16 2021 at 10:58):
Given the multiset precedent, finset.sum_to_list. Please make finset.insert_to_list as separate lemma
Anne Baanen (Dec 16 2021 at 10:59):
Even better would be to call it finset.prod_to_list (and prove it for Π of course!): we have a magical translation from products to sums called @[to_additive].
Kevin Buzzard (Dec 16 2021 at 11:00):
Can someone give Joseph push access to non-master branches of mathlib? His github userid is Jlh18
Johan Commelin (Dec 16 2021 at 11:01):
lemma help {A B : Type*} [decidable_eq A] [add_comm_monoid B]
(s : finset A) (f : A → B) :
finset.sum s f = (list.map f s.to_list).sum :=
begin
delta finset.sum,
rw [← multiset.coe_sum, ← multiset.coe_map, finset.coe_to_list],
end
Ruben Van de Velde (Dec 16 2021 at 11:04):
Do we want
lemma finset.sum_def {A B : Type*} [add_comm_monoid B] (s : finset A) (f : A → B) :
finset.sum s f = (s.1.map f).sum :=
rfl
?
Johan Commelin (Dec 16 2021 at 11:05):
@Joseph Hua https://github.com/leanprover-community/mathlib/invitations
Joseph Hua (Dec 16 2021 at 11:05):
thank you!
Johan Commelin (Dec 16 2021 at 11:06):
Golfed:
by { rw [← multiset.coe_sum, ← multiset.coe_map, finset.coe_to_list], refl, }
Anne Baanen (Dec 16 2021 at 11:07):
Ruben Van de Velde said:
Do we want
lemma finset.sum_def {A B : Type*} [add_comm_monoid B] (s : finset A) (f : A → B) : finset.sum s f = (s.1.map f).sum := rfl?
I'd see this as a simp lemma in the opposite direction named something like sum_to_multiset. (More precisely, as@[to_additive] prod_to_multiset.)
Eric Wieser (Dec 16 2021 at 12:22):
We don't need finset.sum_def, because we already have it as an equation lemma for finset.sum; rw finset.sum does the same thing as that lemma.
Eric Wieser (Dec 16 2021 at 12:23):
Johan Commelin said:
Hmmz, it seems that
finset.sumuses alist.foldrunder the hood. Whereaslist.sumis using afoldl. That's surprising.
There's an open issue about changing list.sum to go in the other direction, which definitionally is more convenient but computationally is slower.
Eric Wieser (Dec 16 2021 at 12:28):
The Zulip thread is here, I can't find the github issue any more
Ruben Van de Velde (Dec 17 2021 at 09:54):
#10842 is ready to land if someone wants to tell bors
Last updated: May 02 2025 at 03:31 UTC