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: May 02 2025 at 03:31 UTC