New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(data/sym/card): Prove stars and bars (superseded by #11162) #10846
feat(data/sym/card): Prove stars and bars (superseded by #11162) #10846
Conversation
huynhtrankhanh
commented
Dec 16, 2021
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a pass at simplification
oh dear I accidentally tapped the request review button 😢 sorry for that mistake feel absolutely free to ignore the request |
|
||
def multichoose2 (n k : ℕ) := (n + k - 1).choose k | ||
|
||
def encode (n k : ℕ) (x : sym (fin n.succ) k.succ) : sym (fin n) k.succ ⊕ sym (fin n.succ) k := |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would make sense to generalize this to arbitrary types to have an Even More combinatorial proof:
def encode {k : ℕ} (v : α) (x : sym α k.succ) : sym {w // w ≠ v} k.succ ⊕ sym α k :=
if h : v ∈ x then
sum.inr ⟨x.val.erase v, by { rw [multiset.card_erase_of_mem h, x.property], refl }⟩
else begin
refine sum.inl ⟨x.val.attach.map (λ a, if h' : (a : α) = v then _ else _), _⟩,
{ rw ←h' at h,
exact (h a.property).elim, },
{ use a, },
{ rw [multiset.card_map, multiset.card_attach, x.property], }
end
def decode {k : ℕ} (v : α) : sym {w // w ≠ v} k.succ ⊕ sym α k → sym α k.succ
| (sum.inl x) := ⟨x.val.map subtype.val, by simpa [multiset.card_map] using x.property⟩
| (sum.inr x) := sym.cons v x
There are some dependent type issues when trying to prove equivalent
, though, because of attach
. Maybe someone wants to figure it out?
lemma equivalent {k : ℕ} (v : α) : sym α k.succ ≃ sym {w // w ≠ v} k.succ ⊕ sym α k :=
{ to_fun := encode v,
inv_fun := decode v,
left_inv := sorry,
right_inv := sorry }
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the point in this generalization that you no longer have to start with fintype α
? If so, I guess this does make sense.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@eric-wieser The point is to show it doesn't depend on any properties of fin
, and also that this might be a useful function beyond stars and bars. encode
is "remove or restrict". decode
might not need to exist on its own if there's sym.map
since there ought to be a function sum a b -> (a -> c) -> (b -> c) -> c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather write it like
def encode {k : ℕ} (x : sym (option α) k.succ) : sym α k.succ ⊕ sym (option α) k :=
and then use fintype.induction_empty_option
. Subtypes are nasty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@YaelDillies That seems good and more natural. (Mine was more like something in terms of nat.pred
, which no one really wants if they can help it.)
I will temporarily place all the new definitions in the data.sym.card file. When I push the new code, you can tell me where to move the new definitions to. |
if h : fin.last n ∈ x then | ||
sum.inr ⟨x.val.erase (fin.last n), by { rw [multiset.card_erase_of_mem h, x.property], refl }⟩ | ||
else begin | ||
refine sum.inl (x.map (λ a, ⟨if (a : ℕ) = n then 0 else a, _⟩)), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refine sum.inl (x.map (λ a, ⟨if (a : ℕ) = n then 0 else a, _⟩)), | |
refine sum.inl (x.map fin.cast_pred), |
| (n + 1) 0 := by simp [multichoose1, multichoose2] | ||
| (n + 1) (k + 1) := | ||
by simp only [multichoose1_rec, multichoose2_rec, multichoose1_eq_multichoose2 n k.succ, | ||
multichoose1_eq_multichoose2 n.succ k] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh what a nice short proof this was. Hopefully we can recover it somehow in the new version with some additional lemmas to help support manipulating equivalences and cardinalities.