hex

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