Skip to content

Commit a18da25

Browse files
committed
chore(Combinatorics/Enumerative/Catalan): split into Basic & Tree
1 parent ea9c914 commit a18da25

File tree

6 files changed

+227
-194
lines changed

6 files changed

+227
-194
lines changed

Mathlib.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3373,6 +3373,8 @@ public import Mathlib.Combinatorics.Digraph.Basic
33733373
public import Mathlib.Combinatorics.Digraph.Orientation
33743374
public import Mathlib.Combinatorics.Enumerative.Bell
33753375
public import Mathlib.Combinatorics.Enumerative.Catalan
3376+
public import Mathlib.Combinatorics.Enumerative.Catalan.Basic
3377+
public import Mathlib.Combinatorics.Enumerative.Catalan.Tree
33763378
public import Mathlib.Combinatorics.Enumerative.Composition
33773379
public import Mathlib.Combinatorics.Enumerative.DoubleCounting
33783380
public import Mathlib.Combinatorics.Enumerative.DyckWord
Lines changed: 4 additions & 192 deletions
Original file line numberDiff line numberDiff line change
@@ -1,193 +1,5 @@
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-
module
1+
module -- shake: keep-all
2+
public import Mathlib.Combinatorics.Enumerative.Catalan.Basic
3+
public import Mathlib.Combinatorics.Enumerative.Catalan.Tree
74

8-
public import Mathlib.Algebra.BigOperators.Group.Finset.Defs
9-
public import Mathlib.Data.Finset.NatAntidiagonal
10-
public import Mathlib.Data.Nat.Choose.Central
11-
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 : ℚ) + 10 := by norm_cast
86-
have l₂ : (n : ℚ) - i + 10 := 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, mul_one, Nat.cast_add,
104-
Nat.sub_zero, one_mul, Nat.cast_zero, mul_zero, zero_sub, neg_add_rev]
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
5+
deprecated_module (since := "2026-02-04")
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
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+
module
7+
8+
public import Mathlib.Algebra.BigOperators.Group.Finset.Defs
9+
public import Mathlib.Data.Finset.NatAntidiagonal
10+
public import Mathlib.Data.Nat.Choose.Central
11+
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+
## Implementation details
34+
35+
The proof of `catalan_eq_centralBinom_div` follows https://math.stackexchange.com/questions/3304415
36+
37+
## TODO
38+
39+
* Prove that the Catalan numbers enumerate many interesting objects.
40+
* Provide the many variants of Catalan numbers, e.g. associated to complex reflection groups,
41+
Fuss-Catalan, etc.
42+
43+
-/
44+
45+
@[expose] public section
46+
47+
48+
open Finset
49+
50+
/-- The recursive definition of the sequence of Catalan numbers:
51+
`catalan (n + 1) = ∑ i : Fin n.succ, catalan i * catalan (n - i)` -/
52+
def catalan : ℕ → ℕ
53+
| 0 => 1
54+
| n + 1 =>
55+
∑ i : Fin n.succ,
56+
catalan i * catalan (n - i)
57+
58+
@[simp]
59+
theorem catalan_zero : catalan 0 = 1 := by rw [catalan]
60+
61+
theorem catalan_succ (n : ℕ) : catalan (n + 1) = ∑ i : Fin n.succ, catalan i * catalan (n - i) := by
62+
rw [catalan]
63+
64+
theorem catalan_succ' (n : ℕ) :
65+
catalan (n + 1) = ∑ ij ∈ antidiagonal n, catalan ij.1 * catalan ij.2 := by
66+
rw [catalan_succ, Nat.sum_antidiagonal_eq_sum_range_succ (fun x y => catalan x * catalan y) n,
67+
sum_range]
68+
69+
@[simp]
70+
theorem catalan_one : catalan 1 = 1 := by simp [catalan_succ]
71+
72+
/-- A helper sequence that can be used to prove the equality of the recursive and the explicit
73+
definition using a telescoping sum argument. -/
74+
private def gosperCatalan (n j : ℕ) : ℚ :=
75+
Nat.centralBinom j * Nat.centralBinom (n - j) * (2 * j - n) / (2 * n * (n + 1))
76+
77+
private theorem gosper_trick {n i : ℕ} (h : i ≤ n) :
78+
gosperCatalan (n + 1) (i + 1) - gosperCatalan (n + 1) i =
79+
Nat.centralBinom i / (i + 1) * Nat.centralBinom (n - i) / (n - i + 1) := by
80+
have l₁ : (i : ℚ) + 10 := by norm_cast
81+
have l₂ : (n : ℚ) - i + 10 := by norm_cast
82+
have h₁ := (mul_div_cancel_left₀ (↑(Nat.centralBinom (i + 1))) l₁).symm
83+
have h₂ := (mul_div_cancel_left₀ (↑(Nat.centralBinom (n - i + 1))) l₂).symm
84+
have h₃ : ((i : ℚ) + 1) * (i + 1).centralBinom = 2 * (2 * i + 1) * i.centralBinom :=
85+
mod_cast Nat.succ_mul_centralBinom_succ i
86+
have h₄ :
87+
((n : ℚ) - i + 1) * (n - i + 1).centralBinom = 2 * (2 * (n - i) + 1) * (n - i).centralBinom :=
88+
mod_cast Nat.succ_mul_centralBinom_succ (n - i)
89+
simp only [gosperCatalan]
90+
push_cast
91+
rw [show n + 1 - i = n - i + 1 by rw [Nat.add_comm (n - i) 1, ← (Nat.add_sub_assoc h 1),
92+
add_comm]]
93+
rw [h₁, h₂, h₃, h₄]
94+
field
95+
96+
private theorem gosper_catalan_sub_eq_central_binom_div (n : ℕ) : gosperCatalan (n + 1) (n + 1) -
97+
gosperCatalan (n + 1) 0 = Nat.centralBinom (n + 1) / (n + 2) := by
98+
simp only [gosperCatalan, tsub_self, Nat.centralBinom_zero, Nat.cast_one, mul_one, Nat.cast_add,
99+
Nat.sub_zero, one_mul, Nat.cast_zero, mul_zero, zero_sub, neg_add_rev]
100+
field
101+
102+
theorem catalan_eq_centralBinom_div (n : ℕ) : catalan n = n.centralBinom / (n + 1) := by
103+
suffices (catalan n : ℚ) = Nat.centralBinom n / (n + 1) by
104+
have h := Nat.succ_dvd_centralBinom n
105+
exact mod_cast this
106+
induction n using Nat.caseStrongRecOn with
107+
| zero => simp
108+
| ind d hd =>
109+
simp_rw [catalan_succ, Nat.cast_sum, Nat.cast_mul]
110+
trans (∑ i : Fin d.succ, Nat.centralBinom i / (i + 1) *
111+
(Nat.centralBinom (d - i) / (d - i + 1)) : ℚ)
112+
· congr
113+
ext1 x
114+
have m_le_d : x.val ≤ d := by lia
115+
have d_minus_x_le_d : (d - x.val) ≤ d := tsub_le_self
116+
rw [hd _ m_le_d, hd _ d_minus_x_le_d]
117+
norm_cast
118+
· trans (∑ i : Fin d.succ, (gosperCatalan (d + 1) (i + 1) - gosperCatalan (d + 1) i))
119+
· refine sum_congr rfl fun i _ => ?_
120+
rw [gosper_trick i.is_le, mul_div]
121+
· rw [← sum_range fun i => gosperCatalan (d + 1) (i + 1) - gosperCatalan (d + 1) i,
122+
sum_range_sub, Nat.succ_eq_add_one]
123+
rw [gosper_catalan_sub_eq_central_binom_div d]
124+
norm_cast
125+
126+
theorem succ_mul_catalan_eq_centralBinom (n : ℕ) : (n + 1) * catalan n = n.centralBinom :=
127+
(Nat.eq_mul_of_div_eq_right n.succ_dvd_centralBinom (catalan_eq_centralBinom_div n).symm).symm
128+
129+
theorem catalan_two : catalan 2 = 2 := by
130+
norm_num [catalan_eq_centralBinom_div, Nat.centralBinom, Nat.choose]
131+
132+
theorem catalan_three : catalan 3 = 5 := by
133+
norm_num [catalan_eq_centralBinom_div, Nat.centralBinom, Nat.choose]

0 commit comments

Comments
 (0)