|
1 | | -/- |
2 | | -Copyright (c) 2022 Julian Kuelshammer. All rights reserved. |
3 | | -Released under Apache 2.0 license as described in the file LICENSE. |
4 | | -Authors: Julian Kuelshammer |
5 | | --/ |
6 | 1 | module |
7 | 2 |
|
8 | | -public import Mathlib.Algebra.BigOperators.Group.Finset.Defs |
9 | | -public import Mathlib.Data.Finset.NatAntidiagonal |
10 | | -public import Mathlib.Data.Nat.Choose.Central |
| 3 | +public import Mathlib.Combinatorics.Enumerative.Catalan.Basic |
| 4 | +public import Mathlib.Combinatorics.Enumerative.Catalan.Tree |
11 | 5 |
|
12 | | -import Mathlib.Algebra.BigOperators.Fin |
13 | | -import Mathlib.Algebra.BigOperators.NatAntidiagonal |
14 | | -import Mathlib.Tactic.Field |
15 | | - |
16 | | -/-! |
17 | | -# Catalan numbers |
18 | | -
|
19 | | -The Catalan numbers (http://oeis.org/A000108) are probably the most ubiquitous sequence of integers |
20 | | -in mathematics. They enumerate several important objects like binary trees, Dyck paths, and |
21 | | -triangulations of convex polygons. |
22 | | -
|
23 | | -## Main definitions |
24 | | -
|
25 | | -* `catalan n`: the `n`th Catalan number, defined recursively as |
26 | | - `catalan (n + 1) = ∑ i : Fin n.succ, catalan i * catalan (n - i)`. |
27 | | -
|
28 | | -## Main results |
29 | | -
|
30 | | -* `catalan_eq_centralBinom_div`: The explicit formula for the Catalan number using the central |
31 | | - binomial coefficient, `catalan n = Nat.centralBinom n / (n + 1)`. |
32 | | -
|
33 | | -* `treesOfNumNodesEq_card_eq_catalan`: The number of binary trees with `n` internal nodes |
34 | | - is `catalan n` |
35 | | -
|
36 | | -## Implementation details |
37 | | -
|
38 | | -The proof of `catalan_eq_centralBinom_div` follows https://math.stackexchange.com/questions/3304415 |
39 | | -
|
40 | | -## TODO |
41 | | -
|
42 | | -* Prove that the Catalan numbers enumerate many interesting objects. |
43 | | -* Provide the many variants of Catalan numbers, e.g. associated to complex reflection groups, |
44 | | - Fuss-Catalan, etc. |
45 | | -
|
46 | | --/ |
47 | | - |
48 | | -@[expose] public section |
49 | | - |
50 | | - |
51 | | -open Finset |
52 | | - |
53 | | -open Finset.antidiagonal (fst_le snd_le) |
54 | | - |
55 | | -/-- The recursive definition of the sequence of Catalan numbers: |
56 | | -`catalan (n + 1) = ∑ i : Fin n.succ, catalan i * catalan (n - i)` -/ |
57 | | -def catalan : ℕ → ℕ |
58 | | - | 0 => 1 |
59 | | - | n + 1 => |
60 | | - ∑ i : Fin n.succ, |
61 | | - catalan i * catalan (n - i) |
62 | | - |
63 | | -@[simp] |
64 | | -theorem catalan_zero : catalan 0 = 1 := by rw [catalan] |
65 | | - |
66 | | -theorem catalan_succ (n : ℕ) : catalan (n + 1) = ∑ i : Fin n.succ, catalan i * catalan (n - i) := by |
67 | | - rw [catalan] |
68 | | - |
69 | | -theorem catalan_succ' (n : ℕ) : |
70 | | - catalan (n + 1) = ∑ ij ∈ antidiagonal n, catalan ij.1 * catalan ij.2 := by |
71 | | - rw [catalan_succ, Nat.sum_antidiagonal_eq_sum_range_succ (fun x y => catalan x * catalan y) n, |
72 | | - sum_range] |
73 | | - |
74 | | -@[simp] |
75 | | -theorem catalan_one : catalan 1 = 1 := by simp [catalan_succ] |
76 | | - |
77 | | -/-- A helper sequence that can be used to prove the equality of the recursive and the explicit |
78 | | -definition using a telescoping sum argument. -/ |
79 | | -private def gosperCatalan (n j : ℕ) : ℚ := |
80 | | - Nat.centralBinom j * Nat.centralBinom (n - j) * (2 * j - n) / (2 * n * (n + 1)) |
81 | | - |
82 | | -private theorem gosper_trick {n i : ℕ} (h : i ≤ n) : |
83 | | - gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i = |
84 | | - Nat.centralBinom i / (i + 1) * Nat.centralBinom (n - i) / (n - i + 1) := by |
85 | | - have l₁ : (i : ℚ) + 1 ≠ 0 := by norm_cast |
86 | | - have l₂ : (n : ℚ) - i + 1 ≠ 0 := by norm_cast |
87 | | - have h₁ := (mul_div_cancel_left₀ (↑(Nat.centralBinom (i + 1))) l₁).symm |
88 | | - have h₂ := (mul_div_cancel_left₀ (↑(Nat.centralBinom (n - i + 1))) l₂).symm |
89 | | - have h₃ : ((i : ℚ) + 1) * (i + 1).centralBinom = 2 * (2 * i + 1) * i.centralBinom := |
90 | | - mod_cast Nat.succ_mul_centralBinom_succ i |
91 | | - have h₄ : |
92 | | - ((n : ℚ) - i + 1) * (n - i + 1).centralBinom = 2 * (2 * (n - i) + 1) * (n - i).centralBinom := |
93 | | - mod_cast Nat.succ_mul_centralBinom_succ (n - i) |
94 | | - simp only [gosperCatalan] |
95 | | - push_cast |
96 | | - rw [show n + 1 - i = n - i + 1 by rw [Nat.add_comm (n - i) 1, ← (Nat.add_sub_assoc h 1), |
97 | | - add_comm]] |
98 | | - rw [h₁, h₂, h₃, h₄] |
99 | | - field |
100 | | - |
101 | | -private theorem gosper_catalan_sub_eq_central_binom_div (n : ℕ) : gosperCatalan (n + 1) (n + 1) - |
102 | | - gosperCatalan (n + 1) 0 = Nat.centralBinom (n + 1) / (n + 2) := by |
103 | | - simp only [gosperCatalan, tsub_self, Nat.centralBinom_zero, Nat.cast_one, Nat.cast_add, |
104 | | - Nat.cast_zero, tsub_zero] |
105 | | - field |
106 | | - |
107 | | -theorem catalan_eq_centralBinom_div (n : ℕ) : catalan n = n.centralBinom / (n + 1) := by |
108 | | - suffices (catalan n : ℚ) = Nat.centralBinom n / (n + 1) by |
109 | | - have h := Nat.succ_dvd_centralBinom n |
110 | | - exact mod_cast this |
111 | | - induction n using Nat.caseStrongRecOn with |
112 | | - | zero => simp |
113 | | - | ind d hd => |
114 | | - simp_rw [catalan_succ, Nat.cast_sum, Nat.cast_mul] |
115 | | - trans (∑ i : Fin d.succ, Nat.centralBinom i / (i + 1) * |
116 | | - (Nat.centralBinom (d - i) / (d - i + 1)) : ℚ) |
117 | | - · congr |
118 | | - ext1 x |
119 | | - have m_le_d : x.val ≤ d := by lia |
120 | | - have d_minus_x_le_d : (d - x.val) ≤ d := tsub_le_self |
121 | | - rw [hd _ m_le_d, hd _ d_minus_x_le_d] |
122 | | - norm_cast |
123 | | - · trans (∑ i : Fin d.succ, (gosperCatalan (d + 1) (i + 1) - gosperCatalan (d + 1) i)) |
124 | | - · refine sum_congr rfl fun i _ => ?_ |
125 | | - rw [gosper_trick i.is_le, mul_div] |
126 | | - · rw [← sum_range fun i => gosperCatalan (d + 1) (i + 1) - gosperCatalan (d + 1) i, |
127 | | - sum_range_sub, Nat.succ_eq_add_one] |
128 | | - rw [gosper_catalan_sub_eq_central_binom_div d] |
129 | | - norm_cast |
130 | | - |
131 | | -theorem succ_mul_catalan_eq_centralBinom (n : ℕ) : (n + 1) * catalan n = n.centralBinom := |
132 | | - (Nat.eq_mul_of_div_eq_right n.succ_dvd_centralBinom (catalan_eq_centralBinom_div n).symm).symm |
133 | | - |
134 | | -theorem catalan_two : catalan 2 = 2 := by |
135 | | - norm_num [catalan_eq_centralBinom_div, Nat.centralBinom, Nat.choose] |
136 | | - |
137 | | -theorem catalan_three : catalan 3 = 5 := by |
138 | | - norm_num [catalan_eq_centralBinom_div, Nat.centralBinom, Nat.choose] |
139 | | - |
140 | | -namespace Tree |
141 | | - |
142 | | -/-- Given two finsets, find all trees that can be formed with |
143 | | - left child in `a` and right child in `b` -/ |
144 | | -abbrev pairwiseNode (a b : Finset (Tree Unit)) : Finset (Tree Unit) := |
145 | | - (a ×ˢ b).map ⟨fun x => x.1 △ x.2, fun ⟨x₁, x₂⟩ ⟨y₁, y₂⟩ => fun h => by simpa using h⟩ |
146 | | - |
147 | | -/-- A Finset of all trees with `n` nodes. See `mem_treesOfNodesEq` -/ |
148 | | -def treesOfNumNodesEq : ℕ → Finset (Tree Unit) |
149 | | - | 0 => {nil} |
150 | | - | n + 1 => |
151 | | - (antidiagonal n).attach.biUnion fun ijh => |
152 | | - pairwiseNode (treesOfNumNodesEq ijh.1.1) (treesOfNumNodesEq ijh.1.2) |
153 | | - decreasing_by |
154 | | - · simp_wf; have := fst_le ijh.2; lia |
155 | | - · simp_wf; have := snd_le ijh.2; lia |
156 | | - |
157 | | -@[simp] |
158 | | -theorem treesOfNumNodesEq_zero : treesOfNumNodesEq 0 = {nil} := by rw [treesOfNumNodesEq] |
159 | | - |
160 | | -theorem treesOfNumNodesEq_succ (n : ℕ) : |
161 | | - treesOfNumNodesEq (n + 1) = |
162 | | - (antidiagonal n).biUnion fun ij => |
163 | | - pairwiseNode (treesOfNumNodesEq ij.1) (treesOfNumNodesEq ij.2) := by |
164 | | - rw [treesOfNumNodesEq] |
165 | | - ext |
166 | | - simp |
167 | | - |
168 | | -@[simp] |
169 | | -theorem mem_treesOfNumNodesEq {x : Tree Unit} {n : ℕ} : |
170 | | - x ∈ treesOfNumNodesEq n ↔ x.numNodes = n := by |
171 | | - induction x using Tree.unitRecOn generalizing n <;> cases n <;> |
172 | | - simp [treesOfNumNodesEq_succ, *] |
173 | | - |
174 | | -theorem mem_treesOfNumNodesEq_numNodes (x : Tree Unit) : x ∈ treesOfNumNodesEq x.numNodes := |
175 | | - mem_treesOfNumNodesEq.mpr rfl |
176 | | - |
177 | | -@[simp, norm_cast] |
178 | | -theorem coe_treesOfNumNodesEq (n : ℕ) : |
179 | | - ↑(treesOfNumNodesEq n) = { x : Tree Unit | x.numNodes = n } := |
180 | | - Set.ext (by simp) |
181 | | - |
182 | | -theorem treesOfNumNodesEq_card_eq_catalan (n : ℕ) : #(treesOfNumNodesEq n) = catalan n := by |
183 | | - induction n using Nat.case_strong_induction_on with |
184 | | - | hz => simp |
185 | | - | hi n ih => |
186 | | - rw [treesOfNumNodesEq_succ, card_biUnion, catalan_succ'] |
187 | | - · apply sum_congr rfl |
188 | | - rintro ⟨i, j⟩ H |
189 | | - rw [card_map, card_product, ih _ (fst_le H), ih _ (snd_le H)] |
190 | | - · simp_rw [Set.PairwiseDisjoint, Set.Pairwise, disjoint_left] |
191 | | - aesop |
192 | | - |
193 | | -end Tree |
| 6 | +deprecated_module (since := "2026-02-04") |
0 commit comments