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