Zulip Chat Archive

Stream: Is there code for X?

Topic: Multiset functor map with erase_dup


Yaël Dillies (Dec 31 2021 at 15:39):

This should be pretty obvious, but I can't do it. Any idea?

import data.finset.basic
import data.multiset.functor

universes u

open multiset

variables {α β : Type u} [decidable_eq α] [decidable_eq β] {F : Type u  Type u} [applicative F]
  [is_comm_applicative F]

lemma multiset.to_finset_fmap_traverse_erase_dup (f : α  F β) (m : multiset α) :
  to_finset <$> traverse f m.erase_dup = to_finset <$> traverse f m :=
sorry

Yaël Dillies (Dec 31 2021 at 15:39):

cc @Eric Wieser because that's for #10980

Yakov Pechersky (Dec 31 2021 at 15:49):

Do you have this for lists? You can just lift it across the quotient then.

Yaël Dillies (Dec 31 2021 at 15:50):

What for lists? We have docs#list.traversable if it's what you mean.

Yakov Pechersky (Dec 31 2021 at 15:52):

Can you prove

lemma list.to_finset_fmap_traverse_erase_dup (f : α  F β) (l : list α) :
  list.to_finset <$> traverse f l.erase_dup = list.to_finset <$> traverse f l :=

Yaël Dillies (Dec 31 2021 at 15:53):

I have no idea. This is out of my comfort zone.

Reid Barton (Dec 31 2021 at 15:55):

This looks false, the right hand side will have the effects of f on repeated elements of m multiple times, but the left hand side won't

Yakov Pechersky (Dec 31 2021 at 15:56):

Right, I think you need an "injectivity" of f assumption.

Yakov Pechersky (Dec 31 2021 at 15:57):

lemma list.to_finset_fmap_traverse_erase_dup (f : α  F β) (l : list α) :
  list.to_finset <$> traverse f l.erase_dup = list.to_finset <$> traverse f l :=
begin
  induction l with hd tl IH,
  { simp },
  { by_cases h : hd  tl,
    { simp only [h, list.erase_dup_cons_of_mem, list.traverse_cons],
      -- list.to_finset <$> traverse f tl.erase_dup =
      --   list.to_finset <$> (list.cons <$> f hd <*> traverse f tl)
      sorry },
    { sorry } }
end

Yakov Pechersky (Dec 31 2021 at 15:58):

That shows the issue of trying to erase_dup over f hd.

Yaël Dillies (Dec 31 2021 at 15:59):

Arf. I was trying to get away without injectivity :sad:

Reid Barton (Dec 31 2021 at 16:00):

I don't understand what you mean by "injectivity". You need something like f x is idempotent for each x.

Yaël Dillies (Dec 31 2021 at 16:03):

My idea was that the to_finset would squish whatever effect we had duplicated.

Reid Barton (Dec 31 2021 at 16:04):

e.g. in pseudo-math/Lean/Haskell, if m = {x, x}, then the left hand side is
do { y <- f x; return (to_finset [y]) }
but the right hand side is
do { y <- f x; y' <- f x; return (to_finset [y, y']) }
and there's no reason that these should be the same even if you ignore the return value, because f ran twice on the right hand side but only once on the left

Reid Barton (Dec 31 2021 at 16:06):

For example, F could be a monad which is counting the number of executions of f

Yaël Dillies (Dec 31 2021 at 16:21):

Welp, I'm giving up. #10980 is now ready for review.

Yakov Pechersky (Dec 31 2021 at 16:22):

Reid, you're right, I hand-waved "injectivity" to mean what you said clearer as idempotency.


Last updated: Dec 20 2023 at 11:08 UTC