Dyck words #
A Dyck word is a sequence consisting of an equal number n
of symbols of two types such that
for all prefixes one symbol occurs at least as many times as the other.
If the symbols are (
and )
the latter restriction is equivalent to balanced brackets;
if they are U = (1, 1)
and D = (1, -1)
the sequence is a lattice path from (0, 0)
to (0, 2n)
and the restriction requires the path to never go below the x-axis.
This file defines Dyck words and constructs their bijection with rooted binary trees,
one consequence being that the number of Dyck words with length 2 * n
is catalan n
.
Main definitions #
DyckWord
: a list ofU
s andD
s with as manyU
s asD
s and with every prefix having at least as manyU
s asD
s.DyckWord.semilength
: semilength (half the length) of a Dyck word.DyckWord.firstReturn
: for a nonempty word, the index of theD
matching the initialU
.
Main results #
DyckWord.equivTree
: equivalence between Dyck words and rooted binary trees. See the docstrings ofDyckWord.equivTreeToFun
andDyckWord.equivTreeInvFun
for details.DyckWord.equivTreesOfNumNodesEq
: equivalence between Dyck words of length2 * n
and rooted binary trees withn
internal nodes.DyckWord.card_dyckWord_semilength_eq_catalan
: there arecatalan n
Dyck words of length2 * n
or semilengthn
.
Implementation notes #
While any two-valued type could have been used for DyckStep
, a new enumerated type is used here
to emphasise that the definition of a Dyck word does not depend on that underlying type.
Equations
- instInhabitedDyckStep = { default := DyckStep.U }
Equations
- instDecidableEqDyckStep x✝ y✝ = if h : x✝.toCtorIdx = y✝.toCtorIdx then isTrue ⋯ else isFalse ⋯
Named in analogy to Bool.dichotomy
.
A Dyck word is a list of DyckStep
s with as many U
s as D
s and with every prefix having
at least as many U
s as D
s.
The underlying list
- count_U_eq_count_D : List.count DyckStep.U ↑self = List.count DyckStep.D ↑self
- count_D_le_count_U (i : ℕ) : List.count DyckStep.D (List.take i ↑self) ≤ List.count DyckStep.U (List.take i ↑self)
Instances For
Equations
Equations
- instCoeDyckWordListDyckStep = { coe := DyckWord.toList }
Equations
- instAddDyckWord = { add := fun (p q : DyckWord) => { toList := ↑p ++ ↑q, count_U_eq_count_D := ⋯, count_D_le_count_U := ⋯ } }
Equations
- instZeroDyckWord = { zero := { toList := [], count_U_eq_count_D := instZeroDyckWord.proof_1, count_D_le_count_U := instZeroDyckWord.proof_2 } }
Dyck words form an additive cancellative monoid under concatenation, with the empty word as 0.
The only Dyck word that is an additive unit is the empty word.
Equations
- DyckWord.instUniqueAddUnits = { toInhabited := AddUnits.instInhabited, uniq := DyckWord.instUniqueAddUnits.proof_1 }
The first element of a nonempty Dyck word is U
.
The last element of a nonempty Dyck word is D
.
Prefix of a Dyck word as a Dyck word, given that the count of U
s and D
s in it are equal.
Equations
Instances For
Suffix of a Dyck word as a Dyck word, given that the count of U
s and D
s in the prefix
are equal.
Equations
Instances For
Nest p
in one pair of brackets, i.e. x
becomes (x)
.
Equations
- p.nest = { toList := [DyckStep.U] ++ ↑p ++ [DyckStep.D], count_U_eq_count_D := ⋯, count_D_le_count_U := ⋯ }
Instances For
A property stating that p
is nonempty and strictly positive in its interior,
i.e. is of the form (x)
with x
a Dyck word.
Equations
- p.IsNested = (p ≠ 0 ∧ ∀ ⦃i : ℕ⦄, 0 < i → i < (↑p).length → List.count DyckStep.D (List.take i ↑p) < List.count DyckStep.U (List.take i ↑p))
Instances For
The semilength of a Dyck word is half of the number of DyckStep
s in it, or equivalently
its number of U
s.
Equations
- p.semilength = List.count DyckStep.U ↑p
Instances For
p.firstReturn
is 0 if p = 0
and the index of the D
matching the initial U
otherwise.
Equations
- p.firstReturn = List.findIdx (fun (i : ℕ) => decide (List.count DyckStep.U (List.take (i + 1) ↑p) = List.count DyckStep.D (List.take (i + 1) ↑p))) (List.range (↑p).length)
Instances For
The left part of the Dyck word decomposition,
inside the U, D
pair that firstReturn
refers to. insidePart 0 = 0
.
Instances For
The right part of the Dyck word decomposition,
outside the U, D
pair that firstReturn
refers to. outsidePart 0 = 0
.
Instances For
Partial order on Dyck words: p ≤ q
if a (possibly empty) sequence of
insidePart
and outsidePart
operations can turn q
into p
.
Equivalence between Dyck words and rooted binary trees.
Equations
- DyckWord.equivTree = { toFun := DyckWord.equivTreeToFun✝, invFun := DyckWord.equivTreeInvFun✝, left_inv := DyckWord.equivTree_left_inv✝, right_inv := DyckWord.equivTree_right_inv✝ }
Instances For
Equivalence between Dyck words of semilength n
and rooted binary trees with
n
internal nodes.
Equations
- One or more equations did not get rendered due to their size.
Instances For
Equations
- DyckWord.instFintypeSubtypeEqNatSemilength = Fintype.ofEquiv { x : Tree Unit // x ∈ Tree.treesOfNumNodesEq n } (DyckWord.equivTreesOfNumNodesEq n).symm
There are catalan n
Dyck words of semilength n
(or length 2 * n
).
Extension for the positivity
tactic: p.firstReturn
is positive if p
is nonzero.