Zulip Chat Archive
Stream: new members
Topic: prove Multiset.map produces no duplicates under local inject
Nick_adfor (Oct 16 2025 at 15:04):
What's the standard approach in Mathlib to prove Nodup in this scenario? Specifically, how do I properly leverage the injectivity hypothesis that's only on the finite subset Fin n when working with multisets?
lemma range_n_nodup_of_fin_injective (n : ℕ) (f : ℕ → ℝ) (h : Function.Injective (fun (i : Fin n) => f i)) :
(Multiset.map f (Multiset.range n)).Nodup := by sorry
Aaron Liu (Oct 16 2025 at 15:32):
Nick_adfor (Oct 17 2025 at 01:54):
I've finished but found an interesting thing:
import Mathlib
open Real
lemma range_n_nodup_of_fin_injective (n : ℕ) (f : ℕ → ℝ) (h : Function.Injective (fun (i : Fin n) => f i)) :
(Multiset.map f (Multiset.range n)).Nodup := by
have h_range_nodup : (Multiset.range n).Nodup := by
simp [Multiset.nodup_range]
refine h_range_nodup.map_on fun x hx y hy hfxy => ?_
rw [Multiset.mem_range] at hx hy
let x' : Fin n := ⟨x, hx⟩
let y' : Fin n := ⟨y, hy⟩
exact?
Nick_adfor (Oct 17 2025 at 01:57):
This exact? show me:
found a proof, but the corresponding tactic failed:
(expose_names; exact Fin.mk.inj_iff.mp (h hfxy))
It may be possible to correct this proof by adding type annotations, explicitly specifying implicit arguments, or eliminating unnecessary function abstractions.
in the earlier version, it would show:
Try this: exact Fin.mk.inj_iff.mp (h hfxy)
but cannot run with error
don't know how to synthesize implicit argument 'a'
@Iff.mp (⟨x, ?m.22979⟩ = ⟨y, ?m.22980⟩) (x = y) Fin.mk.inj_iff (h hfxy)
Nick_adfor (Oct 17 2025 at 01:58):
I'm wondering how exact? works. Before that I always think exact? will conclude the proof but today my faith destroys.
Aaron Liu (Oct 17 2025 at 02:00):
You can probably repair this proof
Aaron Liu (Oct 17 2025 at 02:00):
probably what happened is that exact? found a working proof but the pretty printer was not able to preserve all of that information
Aaron Liu (Oct 17 2025 at 02:02):
yeah if you do
exact @Iff.mp (x' = y') (x = y) Fin.mk.inj_iff (h hfxy)
then it works
Nick_adfor (Oct 17 2025 at 03:45):
Aaron Liu said:
yeah if you do
exact @Iff.mp (x' = y') (x = y) Fin.mk.inj_iff (h hfxy)then it works
@Iff.mp (x' = y') (x = y) : ((x' = y') ↔ (x = y)) → (x' = y') → (x = y)
The exact? tactic can vaguely recognize this part, but cannot write it out accurately. On the contrary, it hides them.
Kevin Buzzard (Oct 17 2025 at 07:36):
Yes I have seen exact? do this expose_names thing before and it's usually due to some issue with variables. I use the same workaround that Aaron is suggesting (in fact sometimes just deleting the expose_names fixes it, but sometimes you have to engage your brain by looking at what exact? found).
Last updated: Dec 20 2025 at 21:32 UTC