Zulip Chat Archive
Stream: new members
Topic: How to prove some simple combinatoric identities
Ching-Tsun Chou (Jan 10 2025 at 01:56):
I wish to prove the following simple combinatoric identities:
variable {α : Type*} [Fintype α] [DecidableEq α]
def Perm α := {l : List α // l.Nodup ∧ ∀ a, a ∈ l}
instance fintype_perm : Fintype (Perm α) := by
sorry
theorem num_perms_all : Fintype.card (Perm α) = (Fintype.card α).factorial := by
sorry
def hasSetPrefix (s : Finset α) : Finset (Perm α) :=
{l : Perm α | (List.take s.card l.val).toFinset = s}
theorem num_perms_set_prefix (s : Finset α) :
(hasSetPrefix s).card = s.card.factorial * (Fintype.card α - s.card).factorial := by
sorry
My first thought was that such simple facts must be in Mathlib already. But I seemed to be wrong. Any advice about how I should go about proving such results? I am completely open to changing the definitions if that makes it easier to use existing results in Mathlib.
Another question I have is that I also tried an alternative definition of the type Perm:
def Perm α := {l : List α // l.length = Fintype.card α ∧ ∀ a, a ∈ l}
But Lean claims it fails to synthesize Fintype α, even though this has been explicitly declared. Why?
Matt Diamond (Jan 10 2025 at 03:03):
To answer your second question, it's because the α in your definition isn't the same α as the one in your variable declaration. When you write Perm α := ..., you're declaring an entirely new variable which also happens to be called α. If you want to reference the α from the variable statement, you'll need to remove the α from Perm's parameter list:
def Perm := {l : List α // l.length = Fintype.card α ∧ ∀ a, a ∈ l}
Matt Diamond (Jan 10 2025 at 03:10):
If you do that, you'll notice a bunch of errors in the rest of your code because your variable declaration defines α as an implicit variable. You can fix this easily by changing α to be explicit (i.e. (α : Type*) instead of {α : Type*}).
Ching-Tsun Chou (Jan 10 2025 at 03:20):
Thanks! That's very helpful.
Matt Diamond (Jan 10 2025 at 03:24):
Are you familiar with docs#Equiv.Perm ? it's a different way of representing permutations
Matt Diamond (Jan 10 2025 at 03:25):
docs#Fintype.card_perm is the cardinality result
Matt Diamond (Jan 10 2025 at 03:26):
and docs#fintypePerm is the Fintype instance
Matt Diamond (Jan 10 2025 at 03:28):
however, it represents permutations as automorphisms, rather than explicit orderings, so I'm not sure if that's useful
Daniel Weber (Jan 10 2025 at 04:06):
You can show an equivalence (Fin (Fintype.card α) ≃ α) ≃ Perm α to be able to use the results on Equiv.Perm (You can use docs#Fintype.truncEquivFin to convert Fin (Fintype.card α) to α)
Ching-Tsun Chou (Jan 11 2025 at 01:04):
Thanks for the suggestions! I'll look into them.
Ching-Tsun Chou (Jan 11 2025 at 02:31):
I don't understand the Trunc thing in docs#Fintype.truncEquivFin and other similar results. What is it for?
Ching-Tsun Chou (Jan 11 2025 at 03:35):
Using the suggestions from Matt and Daniel, I modified my definitions to make them easier to work with:
noncomputable section
variable (α : Type*) [Fintype α] [DecidableEq α]
def Perm := α ≃ Fin (Fintype.card α)
instance fintype_perm : Fintype (Perm α) := Equiv.instFintype
theorem num_perms_all : Fintype.card (Perm α) = (Fintype.card α).factorial := by
refine Fintype.card_equiv ?_
exact Fintype.equivFinOfCardEq rfl
def hasSetPrefix (s : Finset α) : Finset (Perm α) :=
{ f : Perm α | ∀ a ∈ s, f.toFun a ≤ s.card }
theorem num_perms_set_prefix (s : Finset α) :
(hasSetPrefix α s).card = s.card.factorial * (Fintype.card α - s.card).factorial := by
sorry
Last updated: May 02 2025 at 03:31 UTC