Skip to content
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

[Merged by Bors] - feat(combinatorics/catalan): Connection between Catalan numbers and number of trees #16583

Closed
wants to merge 52 commits into from
Closed
Changes from 51 commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
4c26295
Initial commit
prakol16 Sep 7, 2022
b360476
Pull out nat decoding into function
prakol16 Sep 7, 2022
e895515
Fix lint
prakol16 Sep 7, 2022
0b546fb
Fix duplicate instance arg
prakol16 Sep 7, 2022
4af6fbd
Add docstrings
prakol16 Sep 7, 2022
d1de5f2
Add missing docstrings
prakol16 Sep 8, 2022
baa7fff
Use unit_tree instead of tree
prakol16 Sep 9, 2022
d7e7a97
Fix tencodable
prakol16 Sep 9, 2022
0aa93cb
Add inhabited instance
prakol16 Sep 10, 2022
7f540ef
Fix TODO
prakol16 Sep 20, 2022
309a7cd
Change names
prakol16 Sep 21, 2022
35926e5
Add definition of height
prakol16 Sep 21, 2022
fe04240
Merge branch 'tree_encoding' of https://github.com/leanprover-communi…
prakol16 Sep 21, 2022
ea5be3a
Add height le nodes
prakol16 Sep 21, 2022
457d6af
Clarify definition
prakol16 Sep 21, 2022
87463da
Merge branch 'tree_encoding' of https://github.com/leanprover-communi…
prakol16 Sep 21, 2022
d6f6206
Prove theorem
prakol16 Sep 21, 2022
73a5a2c
Move sum lemma to big_operators
prakol16 Sep 21, 2022
0acbe8b
Move part of #16415 into its own branch
prakol16 Sep 29, 2022
52657ea
Remove encodable definitions (unnecessary for catalan)
prakol16 Sep 29, 2022
1285902
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Sep 29, 2022
92e9908
Fix a comment
prakol16 Sep 29, 2022
cdb34cf
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Sep 29, 2022
3738f71
Remove unit_tree, replace with tree
prakol16 Oct 18, 2022
39ef81c
Add pattern for unit node
prakol16 Oct 18, 2022
e8ff7ea
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Oct 19, 2022
f8891fb
Add unit-specific lemmas
prakol16 Oct 19, 2022
1ecb82a
Add docstring to recursor
prakol16 Oct 19, 2022
3a838c8
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Oct 19, 2022
cbd29d9
Update to not use unit_tree
prakol16 Oct 19, 2022
7ec1993
Remove usage of new sum operators
prakol16 Oct 19, 2022
12f5cb2
Minor; change name of `leaves`, clean up comments
prakol16 Oct 19, 2022
acf8b38
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Oct 19, 2022
1ea625a
Change name of `nodes`
prakol16 Oct 22, 2022
278691d
Remove non_nil
prakol16 Oct 22, 2022
e6cd603
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Oct 22, 2022
1722d98
Update for name change of `nodes`
prakol16 Oct 22, 2022
79664c0
Fix naming of lemmas
prakol16 Oct 22, 2022
be8cb91
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Oct 22, 2022
a552716
Add notation for tree unit instead of custom constructor
prakol16 Nov 14, 2022
aeaf435
Merge branch 'unit_tree' of https://github.com/leanprover-community/m…
prakol16 Nov 14, 2022
910bde5
Use new tree notation
prakol16 Nov 14, 2022
e524bb0
Merge branch 'master' of https://github.com/leanprover-community/math…
prakol16 Jan 27, 2023
405277f
Fixes to disjoint change; add import
prakol16 Jan 27, 2023
556d70d
Minor
prakol16 Jan 28, 2023
ad76105
Add coe_trees_of_nodes_eq
prakol16 Jan 28, 2023
01e9205
Add norm cast attribute
prakol16 Jan 29, 2023
dca3313
Shorten type declaration
prakol16 Feb 2, 2023
a044a85
Change simp to reducible
prakol16 Feb 3, 2023
884a197
Oops, forgot to pull
prakol16 Feb 3, 2023
3f879d6
golf
eric-wieser Feb 7, 2023
e73ec61
wrap lines
eric-wieser Feb 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 65 additions & 2 deletions src/combinatorics/catalan.lean
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ Copyright (c) 2022 Julian Kuelshammer. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Julian Kuelshammer
-/
import data.nat.choose.central
import algebra.big_operators.fin
import algebra.big_operators.nat_antidiagonal
import algebra.char_zero.lemmas
import data.finset.nat_antidiagonal
import data.nat.choose.central
import data.tree
import tactic.field_simp
import tactic.linear_combination

Expand All @@ -26,6 +29,9 @@ triangulations of convex polygons.
* `catalan_eq_central_binom_div `: The explicit formula for the Catalan number using the central
binomial coefficient, `catalan n = nat.central_binom n / (n + 1)`.

* `trees_of_nodes_eq_card_eq_catalan`: The number of binary trees with `n` internal nodes
is `catalan n`

## Implementation details

The proof of `catalan_eq_central_binom_div` follows
Expand All @@ -40,7 +46,8 @@ https://math.stackexchange.com/questions/3304415/catalan-numbers-algebraic-proof
-/

open_locale big_operators
open finset

open finset finset.nat.antidiagonal (fst_le snd_le)

/-- The recursive definition of the sequence of Catalan numbers:
`catalan (n + 1) = ∑ i : fin n.succ, catalan i * catalan (n - i)` -/
Expand All @@ -54,6 +61,11 @@ def catalan : ℕ → ℕ
lemma catalan_succ (n : ℕ) : catalan (n + 1) = ∑ i : fin n.succ, catalan i * catalan (n - i) :=
by rw catalan

lemma catalan_succ' (n : ℕ) :
catalan (n + 1) = ∑ ij in nat.antidiagonal n, catalan ij.1 * catalan ij.2 :=
by rw [catalan_succ, nat.sum_antidiagonal_eq_sum_range_succ (λ x y, catalan x * catalan y) n,
sum_range]

@[simp] lemma catalan_one : catalan 1 = 1 := by simp [catalan_succ]

/-- A helper sequence that can be used to prove the equality of the recursive and the explicit
Expand Down Expand Up @@ -129,3 +141,54 @@ by norm_num [catalan_eq_central_binom_div, nat.central_binom, nat.choose]

lemma catalan_three : catalan 3 = 5 :=
by norm_num [catalan_eq_central_binom_div, nat.central_binom, nat.choose]

namespace tree
open_locale tree

/-- Given two finsets, find all trees that can be formed with
left child in `a` and right child in `b` -/
@[reducible] def pairwise_node (a b : finset (tree unit)) : finset (tree unit) :=
(a ×ˢ b).map ⟨λ x, x.1 △ x.2, λ ⟨x₁, x₂⟩ ⟨y₁, y₂⟩, λ h, by simpa using h⟩

/-- A finset of all trees with `n` nodes. See `mem_trees_of_nodes_eq` -/
def trees_of_num_nodes_eq : ℕ → finset (tree unit)
prakol16 marked this conversation as resolved.
Show resolved Hide resolved
| 0 := {nil}
| (n+1) := (finset.nat.antidiagonal n).attach.bUnion $ λ ijh,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@YaelDillies, can you see a way to use disj_Union here instead?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nevermind, this can wait till a follow-up

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it but it doesn't seem obvious at all.

have _ := nat.lt_succ_of_le (fst_le ijh.2),
have _ := nat.lt_succ_of_le (snd_le ijh.2),
pairwise_node (trees_of_num_nodes_eq ijh.1.1) (trees_of_num_nodes_eq ijh.1.2)

@[simp] lemma trees_of_nodes_eq_zero : trees_of_num_nodes_eq 0 = {nil} :=
by rw [trees_of_num_nodes_eq]

lemma trees_of_nodes_eq_succ (n : ℕ) : trees_of_num_nodes_eq (n + 1) =
(nat.antidiagonal n).bUnion (λ ij, pairwise_node (trees_of_num_nodes_eq ij.1)
(trees_of_num_nodes_eq ij.2)) :=
by { rw trees_of_num_nodes_eq, ext, simp, }

@[simp] theorem mem_trees_of_nodes_eq {x : tree unit} {n : ℕ} :
x ∈ trees_of_num_nodes_eq n ↔ x.num_nodes = n :=
prakol16 marked this conversation as resolved.
Show resolved Hide resolved
begin
induction x using tree.unit_rec_on generalizing n;
cases n;
simp [trees_of_nodes_eq_succ, nat.succ_eq_add_one, *],
trivial,
end

lemma mem_trees_of_nodes_eq_num_nodes (x : tree unit) :
x ∈ trees_of_num_nodes_eq x.num_nodes := mem_trees_of_nodes_eq.mpr rfl

@[simp, norm_cast] lemma coe_trees_of_nodes_eq (n : ℕ) :
↑(trees_of_num_nodes_eq n) = {x : tree unit | x.num_nodes = n} := set.ext (by simp)

lemma trees_of_nodes_eq_card_eq_catalan (n : ℕ) :
(trees_of_num_nodes_eq n).card = catalan n :=
begin
induction n using nat.case_strong_induction_on with n ih,
{ simp, },
rw [trees_of_nodes_eq_succ, card_bUnion, catalan_succ'],
{ apply sum_congr rfl, rintro ⟨i, j⟩ H, simp [ih _ (fst_le H), ih _ (snd_le H)], },
{ simp_rw disjoint_left, rintros ⟨i, j⟩ _ ⟨i', j'⟩ _, clear_except, tidy, },
end

end tree