Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
248 changes: 248 additions & 0 deletions doc/example/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
---
title: Rubik's Cube Example
layout: default_with_title
parent: Documentation
---

This is an updated GAP 4 version of a GAP 3 example by [Martin Schönert](https://www.math.rwth-aachen.de/~Martin.Schoenert/), 1993. An almost classical permutation group of small degree is examined with some elementary GAP commands.
The output given here has been produced by GAP 4.16.0, the input is available in form of a plain GAP 4 [input file](rubik.in).<!-- TODO -->

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the TODO comment


<p style="text-align: right"><i>
Ideal Toy Company stated on the package of<br />
the original Rubik cube that there were more than<br />
three billion possible states the cube could attain.<br />
It's analogous to Mac Donald's proudly announcing<br />
that they've sold more than 120 hamburgers.</i><br />
(J. A. Paulos, Innumeracy)</p>
Comment on lines +10 to +16

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand you are "backporting" this existing example, but I'd say if we do that, should also bring it to the 21st century and use CSS to format a quote like this. I.e., instead of manually inserting line breaks, and using <p> block, I think this should be in a div or maybe a quote and then the formatting should be CSS -- so the wrapping could presumably be achieved via width or max-width or so?


We consider the group of transformations of Rubik's magic cube. If we number the faces of this cube as follows
```
+--------------+
| 1 2 3 |
| 4 top 5 |
| 6 7 8 |
+--------------+--------------+--------------+--------------+
| 9 10 11 | 17 18 19 | 25 26 27 | 33 34 35 |
| 12 left 13 | 20 front 21 | 28 right 29 | 36 rear 37 |
| 14 15 16 | 22 23 24 | 30 31 32 | 38 39 40 |
+--------------+--------------+--------------+--------------+
| 41 42 43 |
| 44 bottom 45 |
| 46 47 48 |
+--------------+
```
Comment on lines +19 to +33

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While ASCII art is fun, I wonder if we can't improve on this via some SVG or so. Ah well, not important.

then the group is generated by the following generators, corresponding to the six faces of the cube.
```

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
```
```gap-repl

gap> cube := Group(
> ( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19),
> ( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35),
> (17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11),
> (25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24),
> (33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27),
> (41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40) );
<permutation group with 6 generators>
```
First we want to know the size of this group.
```
gap> Size( cube );
43252003274489856000
```
Since this is a little bit unhandy, let us factorize this number.
```
gap> Collected( Factors( last ) );
[ [ 2, 27 ], [ 3, 14 ], [ 5, 3 ], [ 7, 2 ], [ 11, 1 ] ]
```
(The result tells us that the size is 2^27 3^14 5^3 7^2 11.)

Next let us investigate the operation of the group on the 48 points (we reduce the line length to get a more appropriate output format).
```
gap> SizeScreen( [71, ] );;
Comment on lines +57 to +59

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reducing the line length here seems questionable to me -- it is very technical and distracts from the content; at the same time, clearly a line length limit was already in place above (perhaps 80) ? I think are free to format example output as we deem fit, there is no requirement to make this precisely reproducible?

Suggested change
Next let us investigate the operation of the group on the 48 points (we reduce the line length to get a more appropriate output format).
```
gap> SizeScreen( [71, ] );;
Next let us investigate the operation of the group on the 48 points,
```

gap> orbits := Orbits( cube, [1..48] );
[ [ 1, 3, 17, 14, 8, 38, 9, 41, 19, 48, 22, 6, 30, 33, 43, 11, 46,
40, 24, 27, 25, 35, 16, 32 ],
[ 2, 5, 12, 7, 36, 10, 47, 4, 28, 45, 34, 13, 29, 44, 20, 42, 26,
21, 37, 15, 31, 18, 23, 39 ] ]
```
The first orbit contains the points at the corners, the second those at the edges; clearly the group cannot move a point at a corner onto a point at an edge.

So to investigate the cube group we first investigate the operation on the corner points. Note that the constructed group that describes this operation will operate on the set `[1..24]`, not on the original set `[1,3,17,14,8,38,9,41,19,48,22,6,30,33,43,11,46,40,24,27,25,35,16,32]`.
```
gap> cube1 := Action( cube, orbits[1] );
<permutation group with 6 generators>
gap> NrMovedPoints( cube1 );
24
gap> Size( cube1 );
88179840
```
Now this group obviously operates transitively, but let us test whether it is also primitive.
```
gap> corners := Blocks( cube1, MovedPoints( cube1 ) );
[ [ 1, 7, 22 ], [ 2, 14, 20 ], [ 3, 12, 16 ], [ 4, 17, 18 ],
[ 5, 9, 21 ], [ 6, 10, 24 ], [ 8, 11, 23 ], [ 13, 15, 19 ] ]
```
Those eight blocks correspond to the eight corners of the cube; on the one hand the group permutes those and on the other hand it permutes the three points at each corner cyclically.

So the obvious thing to do is to investigate the operation of the group on the eight corners. The action gives a homomorphism to a permutation group on the corners:
```
gap> blockhom1 := ActionHomomorphism( cube1, corners, OnSets );
<action homomorphism>
gap> cube1b := Image( blockhom1 );
Group([ (1,2,4,3), (1,3,6,5), (1,5,8,2), (3,4,7,6), (5,6,7,8),
(2,8,7,4) ])
gap> Size( cube1b );
40320
```
Now a permutation group of degree 8 that has order 40320 must be the full symmetric group S(8) on eight points.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, S(8) seems like unusual notation. How about e.g. this?

Suggested change
Now a permutation group of degree 8 that has order 40320 must be the full symmetric group S(8) on eight points.
Now a permutation group of degree 8 that has order 40320 must be the full symmetric group $S_8$ on eight points.

Actually we could also show how GAP can verify this:

Suggested change
Now a permutation group of degree 8 that has order 40320 must be the full symmetric group S(8) on eight points.
Now a permutation group of degree 8 that has order 40320 must be the full symmetric group $S_8$ on eight points.
Indeed, GAP agrees:
```gap-repl
gap> IsNaturalSymmetricGroup(cube1b);
true
```


The next thing then is to investigate the kernel of this operation on blocks, i.e., the subgroup of `cube1` of those elements that fix the blocks setwise.
```
gap> Factors( Size( Kernel( blockhom1 ) ) );
[ 3, 3, 3, 3, 3, 3, 3 ]
gap> IsElementaryAbelian( Kernel( blockhom1 ) );
true
```
We can show that the product of this elementary abelian group 3^7 with the S(8) is semidirect by finding a complement, i.e., a subgroup that has trivial intersection with the kernel and that generates `cube1` together with the kernel.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
We can show that the product of this elementary abelian group 3^7 with the S(8) is semidirect by finding a complement, i.e., a subgroup that has trivial intersection with the kernel and that generates `cube1` together with the kernel.
We can show that the product of this elementary abelian group $3^7$ with the $S_8$ is semidirect by finding a complement, i.e., a subgroup that has trivial intersection with the kernel and that generates `cube1` together with the kernel.

```
gap> cmpl1 := ComplementClassesRepresentatives( cube1, Kernel( blockhom1 ) );
[ <permutation group of size 40320 with 7 generators> ]
```
We verify the complement properties:
```
gap> cmpl1 := cmpl1[1];;
gap> Size( Intersection( cmpl1, Kernel( blockhom1 ) ) );
1
gap> ClosureGroup( cmpl1, Kernel( blockhom1 ) ) = cube1;
true
```
There is even a more elegant way to show that `cmpl1` is a complement.
```
gap> IsBijective( RestrictedMapping( blockhom1, cmpl1 ) );
true
```
Of course, theoretically it is clear that `cmpl1` must indeed be a complement.

In fact we know that `cube1` is a subgroup of index 3 in the wreath product of a cyclic 3 with S(8). This missing index 3 tells us that we do not have total freedom in turning the corners. The following tests show that whenever we turn one corner clockwise we must turn another corner counterclockwise.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again S(8). Also maybe avoid super long lines?

Suggested change
In fact we know that `cube1` is a subgroup of index 3 in the wreath product of a cyclic 3 with S(8). This missing index 3 tells us that we do not have total freedom in turning the corners. The following tests show that whenever we turn one corner clockwise we must turn another corner counterclockwise.
In fact we know that `cube1` is a subgroup of index 3 in the wreath product of a cyclic 3 with $S_8$.
This missing index 3 tells us that we do not have total freedom in turning the corners.
The following tests show that whenever we turn one corner clockwise we must turn another corner counterclockwise.

```
gap> (1,7,22) in cube1;
false
gap> (1,7,22)(2,20,14) in cube1;
true
```
More or less the same things happen when we consider the operation of the cube group on the edges.
```
gap> cube2 := Action( cube, orbits[2] );;
gap> Size( cube2 );
980995276800
gap> edges := Blocks( cube2, MovedPoints( cube2 ) );
[ [ 1, 11 ], [ 2, 17 ], [ 3, 19 ], [ 4, 22 ], [ 5, 13 ], [ 6, 8 ],
[ 7, 24 ], [ 9, 18 ], [ 10, 21 ], [ 12, 15 ], [ 14, 20 ],
[ 16, 23 ] ]
gap> blockhom2 := ActionHomomorphism( cube2, edges, OnSets );;
gap> cube2b := Image( blockhom2 );;
gap> Size( cube2b );
479001600
gap> Factors( Size( Kernel( blockhom2 ) ) );
[ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 ]
gap> IsElementaryAbelian( Kernel( blockhom2 ) );
true
gap> cmpl2 := ComplementClassesRepresentatives( cube2, Kernel( blockhom2 ) );
[ <permutation group of size 479001600 with 11 generators>,
<permutation group of size 479001600 with 11 generators>,
<permutation group of size 479001600 with 11 generators>,
<permutation group of size 479001600 with 11 generators> ]
```
So there are even 4 classes of complements here. This time we get a semidirect product of a 2^11 with an S(12), namely a subgroup of index 2 of the wreath product of a cyclic 2 with S(12). Here the missing index 2 tells us again that we do not have total freedom in turning the edges. The following tests show that whenever we flip one edge we must also flip another edge.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

math mode, S(12), overlong lines

```
gap> (1,11) in cube2;
false
gap> (1,11)(2,17) in cube2;
true
```
Since `cube1` and `cube2` are the groups describing the actions on the two orbits of `cube`, it is clear that `cube` is a subdirect product of those groups, i.e., a subgroup of the direct product. Comparing the sizes of `cube1`, `cube2`, and `cube` we see that `cube` must be a subgroup of index 2 in the direct product of those two groups.

```
gap> Size( cube );
43252003274489856000
gap> Size( cube1 ) * Size( cube2 );
86504006548979712000
```
This final missing index 2 tells us that we cannot operate on corners and edges totally independently. The following tests show that whenever we exchange a pair of corners we must also exchange a pair of edges (and vice versa).
```
gap> (17,19)(11,8)(6,25) in cube;
false
gap> (7,28)(18,21) in cube;
false
gap> (17,19)(11,8)(6,25)(7,28)(18,21) in cube;
true
```
As a last part of the structure analysis of the cube group let us compute the centre of the cube group, i.e., the subgroup of those operations that can be performed either before or after any other operation with the same result.
```
gap> z := Centre( cube );
Group([ (2,34)(4,10)(5,26)(7,18)(12,37)(13,20)(15,44)(21,28)(23,42)
(29,36)(31,45)(39,47) ])
```
We see that the centre contains one nontrivial element, namely the operation that flips all 12 edges simultaneously.

Finally we turn to the original idea connected with the cube, namely to find a sequence of turns of the faces that will transform the cube back into its original state. This amounts to a decomposition of a given element of the cube group into a product of the generators. For this purpose we introduce a free group and a homomorphism of it onto the cube group.
```
gap> f := FreeGroup("t","l","f","r","e","b");
<free group on the generators [ t, l, f, r, e, b ]>
gap> hom := GroupHomomorphismByImages( f, cube, GeneratorsOfGroup(f),
> GeneratorsOfGroup(cube) );
[ t, l, f, r, e, b ] ->
[ (1,3,8,6)(2,5,7,4)(9,33,25,17)(10,34,26,18)(11,35,27,19),
(1,17,41,40)(4,20,44,37)(6,22,46,35)(9,11,16,14)(10,13,15,12),
(6,25,43,16)(7,28,42,13)(8,30,41,11)(17,19,24,22)(18,21,23,20),
(3,38,43,19)(5,36,45,21)(8,33,48,24)(25,27,32,30)(26,29,31,28),
(1,14,48,27)(2,12,47,29)(3,9,46,32)(33,35,40,38)(34,37,39,36),
(14,22,30,38)(15,23,31,39)(16,24,32,40)(41,43,48,46)(42,45,47,44) ]
```
Using this homomorphism, we can now decompose elements into generators. The method used utilizes a stabilizer chain and does not enumerate all group elements, therefore the words obtained are not the shortest possible, though they are short enough for hand solutions.

First we decompose the centre element:
```
gap> PreImagesRepresentative( hom, z.1 );
l^-1*e^-1*t^-1*e*t*l*t*f*t*r*t^-1*r^-1*f^-1*t^-1*f*t*l*t*l^-1*f^-1*l*\
t^-1*l^-1*f*r*t^-1*r^-1*f^-1*l*t*f*t^-1*f^-1*l^-2*t^-1*l^-1*e*l*e^-1*\
t*l*t^-1*l*t*f*t^-1*f^-1*l^-1*t^-1*f*t*f^-1*t^-1*l^-1*t^-1*l*t*l^-1*f\
^-1*l^-1*f*(l*t^-1)^2*f*t^-1*f^-1*l^-3*t^-2*f*l*f*l^-1*f^-1*t^-2*f^-1\
*t*l^-1*f^-1*t^-2*b^-1*e^-1*b*l^-1*e^-1*r*e*f*b*r^-1*b^-1*r^-2*t^-2*l\
^-1*b^-1*r^-1*e^-1
gap> Length( last );
106
```
Next we decompose some element arbitrarily chosen by us:
```
gap> PreImagesRepresentative( hom, (17,19)(11,8)(6,25)(7,28)(18,21) );
l^-1*t^-1*l*f*r*t*r^-1*f^-1*l*t*f*t^-1*f^-1*l^-1*t^2*f*t*l*t*l^-1*f^-\
1*l*t^-1*l^-1*f*t^-1*f^-1*l*t*l^-1*t*l*t^-2*l^-1*f*(t*r*t^-1*r^-1)^2*\
f^-1*t*l*f^-1*l^-1*f*l^-1*t^-1*l*t^-2*f*t*(f^-1*l^-1)^2*l^-1*f*l*e^-1\
*t*e*l*t^-1*e^-1*t^-1*e*l*b*f^-1*b^-1
gap> Length( last );
77
```
Last we let GAP choose a random element ...
```
gap> r := Random( cube );
(1,43,6,27,32,46)(2,4,13,34,10,20)(3,38,40,9,24,17)(5,15,45,23,29,47,
26,44,31,42,36,39)(7,18)(8,22)(11,33,48,14,35,30)(12,21,37,28)(16,
19)(25,41)
gap> pre := PreImagesRepresentative( hom, r );
e^-1*r*f^-1*t^-1*r*l*e*b^-1*e^-1*t^-1*b^-1*e^-1*b*l^-1*(f^-1*l)^2*t^-\
1*f*b*f^2*b^-1*t*f^-1*l*f*l*t*l^-1*t^2*l^-1*f^-1*(l*f)^2*t^-1*f^-1*l^\
-1*t^-1*l*t^2*l^-1*t*l*f^-1*l*f*l^-1*t^-1*(t^-1*l^-1)^2*e*l*e^-1*t*l*\
t^-3*l*t*f*t^-1*f^-2*l^-1*f*t*f*t^-1*f^2*l*f*l^-1*t^-1*l^-1*t*l*t*f*r\
*t*r^-1*t^-1*f^-1*t^-1*l^-1*t^-1*e^-1*t*e*l
gap> Length( last );
100
```
... and we verify that the decomposition is correct:
```
gap> Image( hom, pre );
(1,43,6,27,32,46)(2,4,13,34,10,20)(3,38,40,9,24,17)(5,15,45,23,29,47,
26,44,31,42,36,39)(7,18)(8,22)(11,33,48,14,35,30)(12,21,37,28)(16,
19)(25,41)
gap> last = r;
true
```
This concludes our example. Of course, GAP can do much more, but demonstrating them all would take too much room.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"them" is grammatically incorrect, and "too much room" is a German-ism.

Some alternative suggestions:

Suggested change
This concludes our example. Of course, GAP can do much more, but demonstrating them all would take too much room.
This concludes our example. Of course, GAP can do much more, but demonstrating everything it can do would take too much space.
Suggested change
This concludes our example. Of course, GAP can do much more, but demonstrating them all would take too much room.
This concludes our example. Of course, GAP offers many more features, but demonstrating all of them would take too much space.
Suggested change
This concludes our example. Of course, GAP can do much more, but demonstrating them all would take too much room.
This concludes our example. Of course, GAP can do much more, but covering all of its capabilities would take too much space.
Suggested change
This concludes our example. Of course, GAP can do much more, but demonstrating them all would take too much room.
This concludes our example. Of course, GAP can do much more, but illustrating all its functionality would take too much space.

57 changes: 57 additions & 0 deletions doc/example/rubik.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
cube := Group(
( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19),
( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35),
(17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11),
(25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24),
(33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27),
(41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40) );
Size( cube );
Collected( Factors( Size( cube ) ) );
SizeScreen( [71, ] );;
orbits := Orbits( cube, [1..48] );
cube1 := Action( cube, orbits[1] );
NrMovedPoints( cube1 );
Size( cube1 );
corners := Blocks( cube1, MovedPoints( cube1 ) );
blockhom1 := ActionHomomorphism( cube1, corners, OnSets );
cube1b := Image( blockhom1 );
Size( cube1b );
Factors( Size( Kernel( blockhom1 ) ) );
IsElementaryAbelian( Kernel( blockhom1 ) );
cmpl1 := ComplementClassesRepresentatives( cube1, Kernel( blockhom1 ) );
cmpl1 := cmpl1[1];;
Size( Intersection( cmpl1, Kernel( blockhom1 ) ) );
ClosureGroup( cmpl1, Kernel( blockhom1 ) ) = cube1;
IsBijective( RestrictedMapping( blockhom1, cmpl1 ) );
(1,7,22) in cube1;
(1,7,22)(2,20,14) in cube1;
cube2 := Action( cube, orbits[2] );;
Size( cube2 );
edges := Blocks( cube2, MovedPoints( cube2 ) );
blockhom2 := ActionHomomorphism( cube2, edges, OnSets );;
cube2b := Image( blockhom2 );;
Size( cube2b );
Factors( Size( Kernel( blockhom2 ) ) );
IsElementaryAbelian( Kernel( blockhom2 ) );
cmpl2 := ComplementClassesRepresentatives( cube2, Kernel( blockhom2 ) );
(1,11) in cube2;
(1,11)(2,17) in cube2;
Size( cube );
Size( cube1 ) * Size( cube2 );
(17,19)(11,8)(6,25) in cube;
(7,28)(18,21) in cube;
(17,19)(11,8)(6,25)(7,28)(18,21) in cube;
z := Centre( cube );
f := FreeGroup("t","l","f","r","e","b");
hom := GroupHomomorphismByImages( f, cube, GeneratorsOfGroup(f),
GeneratorsOfGroup(cube) );
pre := PreImagesRepresentative( hom, z.1 );
Length( pre );
pre := PreImagesRepresentative( hom, (17,19)(11,8)(6,25)(7,28)(18,21) );
Length( pre );
r := Random( cube );
pre := PreImagesRepresentative( hom, r );
Length( pre );
im:=Image( hom, pre );
im=r;
quit;