The binary tree, its automorphisms, and the Grigorchuk group
DefinitionGarrido_GrigorchukThe rooted binary tree, its automorphisms, and the (first) Grigorchuk group .
The tree. p. 13 (Definition 4.6): “Denote by the infinite rooted binary tree. We will
generally identify the vertices of with finite words in the alphabet .” p. 14: “For
any vertex of , there is a unique path to the root. The level of is the number of
edges in this unique path to the root.” The vertices are these words, as List Bool (with
false and true ); the root is the empty word, the level of a vertex is its length,
and lies below when is a prefix of .
BinaryTreeAut. The source uses the automorphisms of without defining them (Definition 4.6, p. 13). Here they are the permutations of the vertices that preserve length and the prefix order in both directions. They form a group under composition.
The generators. p. 13 (Definition 4.6): “The automorphism rigidly swaps the two subtrees rooted at the first level of , while and leave the first level intact and are defined recursively by . This notation means that, for instance, acts on (the subtree rooted at the leftmost vertex of the first level) like acts on , while acting on like does on .” Here changes the first letter of every nonempty word, and , , fix the first letter and act on what follows by this recursion: on and ,
Each is shown to be an involutive automorphism of .
GrigorchukGroup. p. 13 (Definition 4.6): “The (first) Grigorchuk group is a group
of automorphisms of generated by four automorphisms denoted .” Here is
the subgroup of the automorphisms of generated by ; GrigorchukGroup.a, …,
GrigorchukGroup.d are the generators as elements of , and GrigorchukGroup.generators
is the set .
levelStabilizer . p. 14: “The stabilizer of is denoted by and the th level stabilizer is the intersection of the stabilizers of all vertices of level .” Here is the set of elements of fixing every vertex of level .
treeSection . The source has no defining sentence for the section of an arbitrary automorphism at an arbitrary vertex; it reaches sections only through the maps of the Remark, p. 14: “To see this, define by , .” The section of an automorphism at a vertex is the automorphism of describing how acts below , defined by ; at the two first-level vertices these are the components that pick out. p. 14 (Lemma 4.8): “For each we have , where is the element obtained by reducing .” The section at the level-3 vertex is this .
stOnePair. p. 14: “Writing any element as , it is easy to see
that conjugation by , induces a ‘swapped’ action: .” p. 14 (Remark): “This
also shows that the map , is a
monomorphism.” Here and are the sections of at the two first-level vertices; that
notation, , is stOnePair, defined, as in the notes, on only. Its values are
pairs of automorphisms of (as the sections in treeSection are automorphisms of , where the
source's land in ); that they lie in and that the map is multiplicative is a
statement of the mission.
wordLength. p. 14 (§4.2.1): “Throughout, we will abuse notation and write to mean both
the length of a shortest word representing and for the length of as a word.” Here
for is the least such that is a product of at most elements of
(the imported Chou.wordBall). It is defined as an infimum, which would be
for an element in no ball; that does not arise, because generate and so
every element lies in some ball.
import Mathlib
import Definitions.Def_Chou_Growth
namespace Garrido
/-- The automorphisms of the rooted binary tree: permutations of the finite words in `{0, 1}`
(`false` = 0, `true` = 1) that preserve length and the prefix order in both directions. -/
def BinaryTreeAut : Subgroup (Equiv.Perm (List Bool)) where
carrier := {σ | (∀ v : List Bool, (σ v).length = v.length) ∧
∀ v w : List Bool, v <+: w ↔ σ v <+: σ w}
mul_mem' := by
rintro σ τ ⟨hσl, hσ⟩ ⟨hτl, hτ⟩
refine ⟨fun v => ?_, fun v w => ?_⟩
· simp [hσl, hτl]
· simp only [Equiv.Perm.coe_mul, Function.comp_apply]
rw [hτ v w, hσ]
one_mem' := ⟨fun v => rfl, fun v w => Iff.rfl⟩
inv_mem' := by
rintro σ ⟨hσl, hσ⟩
refine ⟨fun v => ?_, fun v w => ?_⟩
· have := hσl (σ⁻¹ v); simp at this; exact this.symm
· rw [hσ (σ⁻¹ v) (σ⁻¹ w)]; simp
/-- `a` exchanges the two subtrees below the root: it changes the first letter. -/
def grigAFun : List Bool → List Bool
| [] => []
| x :: w => (!x) :: w
mutual
/-- `b = (a, c)`. -/
def grigBFun : List Bool → List Bool
| [] => []
| false :: w => false :: grigAFun w
| true :: w => true :: grigCFun w
/-- `c = (a, d)`. -/
def grigCFun : List Bool → List Bool
| [] => []
| false :: w => false :: grigAFun w
| true :: w => true :: grigDFun w
/-- `d = (1, b)`. -/
def grigDFun : List Bool → List Bool
| [] => []
| false :: w => false :: w
| true :: w => true :: grigBFun w
end
theorem grigAFun_involutive : Function.Involutive grigAFun := by
intro w; cases w <;> simp [grigAFun]
theorem grigBCD_involutive (w : List Bool) :
grigBFun (grigBFun w) = w ∧ grigCFun (grigCFun w) = w ∧ grigDFun (grigDFun w) = w := by
induction w with
| nil => simp [grigBFun, grigCFun, grigDFun]
| cons x w ih =>
cases x <;> simp [grigBFun, grigCFun, grigDFun, grigAFun_involutive w, ih.1, ih.2.1, ih.2.2]
theorem grigAFun_length (w : List Bool) : (grigAFun w).length = w.length := by
cases w <;> simp [grigAFun]
theorem grigBCD_length (w : List Bool) : (grigBFun w).length = w.length ∧
(grigCFun w).length = w.length ∧ (grigDFun w).length = w.length := by
induction w with
| nil => simp [grigBFun, grigCFun, grigDFun]
| cons x w ih => cases x <;> simp [grigBFun, grigCFun, grigDFun, grigAFun_length, ih.1, ih.2.1, ih.2.2]
theorem grigAFun_prefix {v w : List Bool} (h : v <+: w) : grigAFun v <+: grigAFun w := by
obtain ⟨t, rfl⟩ := h
cases v with
| nil => simp [grigAFun]
| cons x v => exact ⟨t, by simp [grigAFun]⟩
theorem grigBCD_prefix (v : List Bool) : ∀ w, v <+: w →
grigBFun v <+: grigBFun w ∧ grigCFun v <+: grigCFun w ∧ grigDFun v <+: grigDFun w := by
induction v with
| nil => intro w _; simp [grigBFun, grigCFun, grigDFun]
| cons x v ih =>
intro w h
obtain ⟨t, rfl⟩ := h
have ih' := ih (v ++ t) ⟨t, rfl⟩
cases x <;> simp only [List.cons_append, grigBFun, grigCFun, grigDFun, List.cons_prefix_cons,
true_and] <;> exact ⟨by first | exact grigAFun_prefix ⟨t, rfl⟩ | exact ih'.2.1,
by first | exact grigAFun_prefix ⟨t, rfl⟩ | exact ih'.2.2,
by first | exact ⟨t, rfl⟩ | exact ih'.1⟩
theorem grigAFun_prefix_iff (v w : List Bool) : v <+: w ↔ grigAFun v <+: grigAFun w :=
⟨grigAFun_prefix, fun h => by
simpa [grigAFun_involutive v, grigAFun_involutive w] using grigAFun_prefix h⟩
theorem grigBCD_prefix_iff (v w : List Bool) : (v <+: w ↔ grigBFun v <+: grigBFun w) ∧
(v <+: w ↔ grigCFun v <+: grigCFun w) ∧ (v <+: w ↔ grigDFun v <+: grigDFun w) := by
refine ⟨⟨fun h => (grigBCD_prefix v w h).1, fun h => ?_⟩,
⟨fun h => (grigBCD_prefix v w h).2.1, fun h => ?_⟩,
⟨fun h => (grigBCD_prefix v w h).2.2, fun h => ?_⟩⟩
· simpa [(grigBCD_involutive v).1, (grigBCD_involutive w).1] using (grigBCD_prefix _ _ h).1
· simpa [(grigBCD_involutive v).2.1, (grigBCD_involutive w).2.1] using (grigBCD_prefix _ _ h).2.1
· simpa [(grigBCD_involutive v).2.2, (grigBCD_involutive w).2.2] using (grigBCD_prefix _ _ h).2.2
/-- The generator `a` of the Grigorchuk group, as a tree automorphism. -/
def grigA : BinaryTreeAut :=
⟨grigAFun_involutive.toPerm _, grigAFun_length, grigAFun_prefix_iff⟩
/-- The generator `b = (a, c)`. -/
def grigB : BinaryTreeAut :=
⟨Function.Involutive.toPerm grigBFun (fun w => (grigBCD_involutive w).1),
fun w => (grigBCD_length w).1, fun v w => (grigBCD_prefix_iff v w).1⟩
/-- The generator `c = (a, d)`. -/
def grigC : BinaryTreeAut :=
⟨Function.Involutive.toPerm grigCFun (fun w => (grigBCD_involutive w).2.1),
fun w => (grigBCD_length w).2.1, fun v w => (grigBCD_prefix_iff v w).2.1⟩
/-- The generator `d = (1, b)`. -/
def grigD : BinaryTreeAut :=
⟨Function.Involutive.toPerm grigDFun (fun w => (grigBCD_involutive w).2.2),
fun w => (grigBCD_length w).2.2, fun v w => (grigBCD_prefix_iff v w).2.2⟩
/-- The (first) Grigorchuk group `Γ`: the subgroup of the automorphisms of the binary tree
generated by `a, b, c, d` (Definition 4.6). -/
def GrigorchukGroup : Subgroup BinaryTreeAut :=
Subgroup.closure {grigA, grigB, grigC, grigD}
namespace GrigorchukGroup
/-- `a` as an element of `Γ`. -/
def a : GrigorchukGroup := ⟨grigA, Subgroup.subset_closure (by simp)⟩
/-- `b` as an element of `Γ`. -/
def b : GrigorchukGroup := ⟨grigB, Subgroup.subset_closure (by simp)⟩
/-- `c` as an element of `Γ`. -/
def c : GrigorchukGroup := ⟨grigC, Subgroup.subset_closure (by simp)⟩
/-- `d` as an element of `Γ`. -/
def d : GrigorchukGroup := ⟨grigD, Subgroup.subset_closure (by simp)⟩
/-- The generating set `S = {a, b, c, d}` of `Γ`. -/
def generators : Set GrigorchukGroup := {a, b, c, d}
end GrigorchukGroup
/-- The `n`-th level stabilizer `St(n)` of `Γ`: the elements fixing every vertex of level `n`,
i.e. every word of length `n`. -/
def levelStabilizer (n : ℕ) : Subgroup GrigorchukGroup where
carrier := {g | ∀ v : List Bool, v.length = n →
((g : BinaryTreeAut) : Equiv.Perm (List Bool)) v = v}
mul_mem' := by
intro g h hg hh v hv
simp only [Subgroup.coe_mul, Equiv.Perm.coe_mul, Function.comp_apply]
rw [hh v hv, hg v hv]
one_mem' := by intro v _; rfl
inv_mem' := by
intro g hg v hv
have := hg v hv
simp only [InvMemClass.coe_inv]
conv_lhs => rw [← this]
simp
theorem BinaryTreeAut.append_drop (g : BinaryTreeAut) (v w : List Bool) :
(g : Equiv.Perm (List Bool)) v ++ ((g : Equiv.Perm (List Bool)) (v ++ w)).drop v.length =
(g : Equiv.Perm (List Bool)) (v ++ w) := by
have hp : (g : Equiv.Perm (List Bool)) v <+: (g : Equiv.Perm (List Bool)) (v ++ w) :=
(g.2.2 v (v ++ w)).1 (List.prefix_append v w)
have hl := g.2.1 v
rw [← hl]
exact List.prefix_iff_eq_append.mp hp
/-- The section `g|_v` of a tree automorphism `g` at a vertex `v`: how `g` acts below `v`,
read as an automorphism of the whole tree. It sends `w` to the word `u` with
`g (v ++ w) = g v ++ u`. For `v = [i]` this is Garrido's `φᵢ(g)`, and `g|_{[i, j, k]}` is
`φₖ(φⱼ(φᵢ(g)))`. -/
def treeSection (g : BinaryTreeAut) (v : List Bool) : BinaryTreeAut :=
⟨{ toFun := fun w => ((g : Equiv.Perm (List Bool)) (v ++ w)).drop v.length
invFun := fun w => (((g⁻¹ : BinaryTreeAut) : Equiv.Perm (List Bool))
((g : Equiv.Perm (List Bool)) v ++ w)).drop v.length
left_inv := by
intro w
simp only
rw [BinaryTreeAut.append_drop g v w]
simp
right_inv := by
intro w
simp only
have h1 := BinaryTreeAut.append_drop g⁻¹ ((g : Equiv.Perm (List Bool)) v) w
have hv : ((g⁻¹ : BinaryTreeAut) : Equiv.Perm (List Bool))
((g : Equiv.Perm (List Bool)) v) = v := by simp
rw [hv, g.2.1 v] at h1
rw [h1]
simp only [InvMemClass.coe_inv, Equiv.Perm.mul_apply]
rw [show (g : Equiv.Perm (List Bool)) ((g : Equiv.Perm (List Bool))⁻¹ ((g : Equiv.Perm (List Bool)) v ++ w)) = (g : Equiv.Perm (List Bool)) v ++ w by simp]
rw [← g.2.1 v]
simp },
by
refine ⟨fun w => ?_, fun w₁ w₂ => ?_⟩
· simp only [Equiv.coe_fn_mk, List.length_drop, g.2.1, List.length_append]
omega
· simp only [Equiv.coe_fn_mk]
have e1 := BinaryTreeAut.append_drop g v w₁
have e2 := BinaryTreeAut.append_drop g v w₂
calc w₁ <+: w₂ ↔ v ++ w₁ <+: v ++ w₂ := (List.prefix_append_right_inj v).symm
_ ↔ (g : Equiv.Perm (List Bool)) (v ++ w₁) <+: (g : Equiv.Perm (List Bool)) (v ++ w₂) :=
g.2.2 _ _
_ ↔ _ := by rw [e1, e2]
_ ↔ _ := List.prefix_append_right_inj _⟩
/-- Garrido's notation `u = (u₀, u₁)` for `u ∈ St(1)` (p. 14): the sections of `u` at the two
first-level vertices, `0` then `1`. It is defined on `St(1)` only. -/
def stOnePair (u : levelStabilizer 1) : BinaryTreeAut × BinaryTreeAut :=
(treeSection ((u : GrigorchukGroup) : BinaryTreeAut) [false],
treeSection ((u : GrigorchukGroup) : BinaryTreeAut) [true])
/-- The word length `l(g)` of `g ∈ Γ` with respect to `{a, b, c, d}`: the least `n` such that
`g` is a product of at most `n` generators and their inverses. -/
noncomputable def wordLength (g : GrigorchukGroup) : ℕ :=
sInf {n | g ∈ Chou.wordBall GrigorchukGroup.generators n}
end Garrido
Read-back
What the Lean code literally says, in plain math · claude-opus-5-5
Read-back: the Grigorchuk group and associated definitions
This item is a bundle of definitions (with a few supporting lemmas that are proved in the file). They share the vocabulary set up in the first two sections.
Words and prefixes
Throughout, a word is a finite sequence of letters from (the two Boolean values; below, "false" is written and "true" is written ). The empty word is allowed, and denotes the length of . Words are read left to right: is the first letter, and concatenation means followed by . Write for the set of all words (of every finite length, including ).
A word is a prefix of , written , when there exists a word with . (Every word is a prefix of itself, and is a prefix of every word.)
Permutations of are composed as functions: , i.e. is applied first. The identity is the identity map and is the inverse bijection.
1. The group of tree automorphisms,
is the subgroup of the group of all bijections consisting of those bijections such that
- preserves length: for every word ; and
- preserves and reflects the prefix relation: for all words ,
(The file proves this set contains the identity and is closed under composition and inverses.) An element of is formally such a bijection bundled with the proof of the two properties; it acts on words by applying the underlying bijection. The group operation is composition as above.
2. The four generating maps
Four functions are defined by recursion on the word:
-
, and , where is the other letter. That is, flips the first letter and leaves the rest unchanged.
-
, , are defined simultaneously: each fixes , and for every word
So never change the first letter; after a first letter , and apply to the remainder while does nothing; after a first letter , the remainder is acted on by , , respectively. (For example, , , .)
Supporting lemmas proved in the file: each of is an involution ( for all ), preserves length, and satisfies for all (with the forward implication also recorded separately for each). Consequently each of is a bijection of that is its own inverse, and lies in . The elements of so obtained are also called .
3. The Grigorchuk group
the smallest subgroup of containing the four elements (the intersection of all subgroups containing them). is regarded as a group in its own right, whose elements are elements of lying in this subgroup.
The same four elements, now viewed as elements of , are again called , and the generating set of is the set .
4. Level stabilizers
For each natural number , is the subgroup of (not of ) consisting of the elements that fix every word of length exactly :
(The file proves this is a subgroup.) Edge case: for the only word of length is , and every element of preserves length and so fixes ; hence .
A supporting lemma proved in the file: for every and all words , the word equals followed by the word obtained from by deleting its first letters. In other words, begins with .
5. Sections
For and a word , the section is the map
By the lemma just stated, this is the unique word with . Its inverse bijection is (delete the first letters of ). The file proves this is a bijection of satisfying the two conditions of Section 1, so . Note that is defined for every and every word (including , where as maps) and lands in , not necessarily in .
6. The pair of first-level sections
For (so fixes both one-letter words and ), define
the sections of (as an element of ) at the words and , in that order. This is only a function; nothing in the definition asserts it is a homomorphism, injective, or lands in .
7. Word length in
For , the ball of radius with respect to a subset of a group is the set of all group elements for which there is a finite list of group elements with
- (the empty list, , is allowed and has product the identity),
- each satisfies or , and
- (product in list order).
The word length of is
where is the ball of radius with respect to the generating set of Section 3. Junk-value convention: if lay in no ball , the set would be empty and would be defined to be . In particular (via the empty list). Since the balls are nested ( follows from ""), is the least number of factors from needed to write , whenever can be so written.
Confirmed by the mission captain (proposal self-audit).
Confirmed by the moderator at approval.