35.3. Subgroups and cosets
Two groups can have different generators and the same elements.
Hex.PermGroup.Group.sameGroup decides whether they do, by testing each
generator of each group for membership in the other. The rotation and its inverse
generate the same cyclic group of order 4:
def cyclicA : Group 4 := Group.ofGenerators #[rotation]
def cyclicB : Group 4 := Group.ofGenerators #[rotation.inv]
#guard cyclicA.sameGroup cyclicB
In particular, if p₁, …, pᵣ are automorphisms of a graph,
Group.ofGenerators #[p₁, …, pᵣ] is the subgroup they generate, which may be
smaller than the automorphism group of the graph. Showing that it is all of
the automorphism group is a theorem about the graph, which the
HexGraphIso chapter discusses. The section
Graph automorphisms below works
through an example.
For a subgroup H of G, Hex.PermGroup.Group.leftCosetsCapped returns
one representative g of each left coset g H. It takes a bound on the index
and returns an error, carrying the index, when the index exceeds the bound;
this lets a caller refuse to allocate a large transversal. It also needs a
proof that H is a subgroup of G, which here comes from the description of
the stabilizer. When H is not normal the left and right cosets differ;
Hex.PermGroup.LeftTransversal.inverse turns representatives of the left
cosets into representatives of the right cosets.
def swap3 : Perm 3 := Perm.mk #v[1, 0, 2]
def cycle3 : Perm 3 := Perm.mk #v[1, 2, 0]
def symmetric3 : Group 3 :=
Group.ofGenerators #[swap3, cycle3]
def pointFixer : Group 3 := symmetric3.stabilizer 2
theorem pointFixer_le :
pointFixer.IsSubgroup symmetric3 := ⊢ pointFixer.IsSubgroup symmetric3
p:Perm 3hp:Generated pointFixer.generators p⊢ Generated symmetric3.generators p
All goals completed! 🐙
#guard (symmetric3.leftCosetsCapped 3 pointFixer
pointFixer_le).isOk