diff --git a/doc/ref/grplib.xml b/doc/ref/grplib.xml
index 596cbef1bb..ed4f588110 100644
--- a/doc/ref/grplib.xml
+++ b/doc/ref/grplib.xml
@@ -99,6 +99,31 @@ calculations.
<#Include Label="SuzukiGroup">
<#Include Label="ReeGroup">
+
+Generator Names
+For groups created as finitely presented groups, including polycyclic groups, the
+generators are labelled, by default, with a letter and a number. Using the
+option generatorNames it is possible to influcence this naming. If
+this option holds a string, the generators are named with this string and
+numbers, if a list of strings of sufficient length is given, the generator
+names are taken from this list of strings.
+
+ GeneratorsOfGroup(AbelianGroup([5,7]));
+[ f1, f2 ]
+gap> GeneratorsOfGroup(AbelianGroup([5,7]:generatorNames:="a"));
+[ a1, a2 ]
+gap> GeneratorsOfGroup(AbelianGroup([5,7]:generatorNames:=["u","v","w"]));
+[ u, v ]
+gap> AsSSortedList(DihedralGroup(12:generatorNames:="a"));
+[ of ..., a1, a2, a3, a1*a2, a1*a3, a2*a3, a3^2, a1*a2*a3,
+ a1*a3^2, a2*a3^2, a1*a2*a3^2 ]
+gap> AsSSortedList(DihedralGroup(12:generatorNames:=["a","b","c"]));
+[ of ..., a, b, c, a*b, a*c, b*c, c^2, a*b*c, a*c^2, b*c^2,
+ a*b*c^2 ]
+]]>
+
+
diff --git a/doc/tut/domain.xml b/doc/tut/domain.xml
index ffb7d58430..bdf5429153 100644
--- a/doc/tut/domain.xml
+++ b/doc/tut/domain.xml
@@ -274,7 +274,8 @@ The functions and
mentioned above do not return
domains, but they fit into the general pattern in the sense that they
forget all the structure of the argument, including the fact that it is
-a domain, and return a list with the same elements as the argument has.
+a domain, and return an immutable list with the same elements as the
+argument has.
@@ -311,7 +312,8 @@ true
]]>
Many functions return subdomains of their arguments, for example
-the result of SylowSubgroup( G ) is a group with parent group
+the result of SylowSubgroup( G, prime )
+is a group with parent group
G.
If you are sure that the domain Something( gens ) is contained
diff --git a/doc/tut/group.xml b/doc/tut/group.xml
index fd936133e9..cb23f4e9d5 100644
--- a/doc/tut/group.xml
+++ b/doc/tut/group.xml
@@ -162,7 +162,7 @@ gap> Size( f );
]]>
The factor group is again represented as a permutation group
-(its first three generators are trivial, meaning that the first three
+(its last three generators are trivial, meaning that the last three
generators of the preimage are in the kernel of hom). However,
the action domain of this factor group has nothing to do with the
action domain of norm. (It only happens that both are subsets of the
@@ -197,8 +197,9 @@ gap> x * rep^-1 in ker;
true
]]>
-The factor group f is a simple group, i.e., it has no non-trivial
-normal subgroups. &GAP; can detect this fact, and it can then also find
+The factor group f is a simple group, i.e., it is a non-trivial
+group whose only normal subgroups are its trivial subgroup and itself.
+&GAP; can detect this fact, and it can then also find
the name by which this simple group is known among group theorists. (Such
names are of course not available for non-simple groups.)
@@ -316,7 +317,7 @@ group), but it also denotes the natural action of permutations on
positive integers (and exponentiation of integers as well, of course).
It is in fact the default action and will be supplied by the system if not
given. Another common action is for example
-always assumes , which means right
+, which means right
multiplication, defined as d * g.
(Group actions in &GAP; are always from the right.)
@@ -340,7 +341,8 @@ for example would the default domain of Group( (2,3,4) ) be
To avoid confusion, all action functions require that you
specify the domain of action.
If we had specified [ 1 .. 113 ] in the
-primitivity test above, point 113 would have been a fixpoint (and the
+primitivity test above, point 113 would have been a fixed point
+(and the
action would not even have been transitive).
Now blocks is a list of blocks (i.e., a list of lists), which we do not
@@ -362,7 +364,7 @@ true
Note that we give a third argument (the action function
) to
indicate that the action is not the default action on points but an
-action on sets of elements given as sorted lists.
+action on sets of elements given as strictly sorted lists.
(Section lists all
actions that are pre-defined by &GAP;.)
@@ -553,7 +555,7 @@ a subgroup.
Subgroups as Stabilizers
-Action functions can also be used without constructing external sets.
+Action functions can also be used to construct subgroups.
We will try to find several subgroups in a8 as stabilizers of such
actions. One subgroup is immediately available, namely the stabilizer
of one point. The index of the stabilizer must of course be equal to the
@@ -831,6 +833,7 @@ stabilizer using the centralizer algorithm for permutation groups. In the
usual way we now look for the subgroups above u105.
orb:=Set(orb);;
gap> blocks := Blocks( a8, orb );; Length( blocks );
15
gap> Set(blocks[1]);
@@ -847,9 +850,9 @@ the points of the orbit and the cosets of u105. The point
To get the subgroup above u105 that has index 15 in a8,
we must form the closure of u105 with an element of the coset that
corresponds to any other point in the first block.
-If we choose the point (1,3)(2,4)(5,8)(6,7),
+If we choose the point (1,3)(2,4)(5,7)(6,8),
we must use an element of a8 that maps (1,2)(3,4)(5,6)(7,8) to
-(1,3)(2,4)(5,8)(6,7).
+(1,3)(2,4)(5,7)(6,8).
The function does
what we need.
It takes a group and two points and returns an element of the group
@@ -862,18 +865,18 @@ lie in one orbit under the group,
rep := RepresentativeAction( a8, (1,2)(3,4)(5,6)(7,8),
-> (1,3)(2,4)(5,8)(6,7) );
-(1,5,7,2,8,4,3)
+> (1,3)(2,4)(5,7)(6,8) );
+(2,3)(6,7)
gap> u15 := ClosureGroup( u105, rep );; Index( a8, u15 );
15
]]>
u15 is of course a maximal subgroup, because a8 has no subgroups of
index 3 or 5. There is in fact another class of subgroups of index 15
-above u105 that we get by adding (2,3)(6,7) to u105.
+above u105 that we get by adding (2,3)(6,8) to u105.
u15b := ClosureGroup( u105, (2,3)(6,7) );; Index( a8, u15b );
+gap> u15b := ClosureGroup( u105, (2,3)(6,8) );; Index( a8, u15b );
15
gap> RepresentativeAction( a8, u15, u15b );
fail
@@ -1094,7 +1097,8 @@ the mapping was surjective).
Nice Monomorphisms
-For some types of groups, the best method to calculate in an isomorphic
+For some types of groups, the best method for calculations in it is to use
+instead an isomorphic
group in a better
representation (say, a permutation group).
We call an injective homomorphism,
that will give such an isomorphic image a nice monomorphism
.
diff --git a/lib/grpfree.gi b/lib/grpfree.gi
index beb380d8ca..0d26087406 100644
--- a/lib/grpfree.gi
+++ b/lib/grpfree.gi
@@ -424,6 +424,7 @@ InstallMethod( GeneratorsSmallest,
##
InstallGlobalFunction( FreeGroup, function ( arg )
local names, # list of generators names
+ opt,
zarg,
lesy, # filter for letter or syllable words family
F, # family of free group element objects
@@ -455,7 +456,6 @@ InstallGlobalFunction( FreeGroup, function ( arg )
elif Length( zarg ) = 2 and IsInt( zarg[1] ) and 0 <= zarg[1] then
names:= List( [ 1 .. zarg[1] ],
i -> Concatenation( zarg[2], String(i) ) );
- MakeImmutable( names );
elif Length( zarg ) = 1 and IsList( zarg[1] ) and IsEmpty( zarg[1] ) then
names:= zarg[1];
elif 1 <= Length( zarg ) and ForAll( zarg, IsString ) then
@@ -467,6 +467,20 @@ InstallGlobalFunction( FreeGroup, function ( arg )
Error("usage: FreeGroup(,..) or FreeGroup()");
fi;
+ opt:=ValueOption("generatorNames");
+ if opt<>fail then
+ if IsString(opt) then
+ names:= List( [ 1 .. Length(names) ],
+ i -> Concatenation( opt, String(i) ) );
+ elif IsList(opt) and ForAll(opt,IsString)
+ and Length(names)<=Length(opt) then
+ names:=opt{[1..Length(names)]};
+ MakeImmutable( names );
+ else
+ Error("Cannot process `generatorNames` option");
+ fi;
+ fi;
+
# deal with letter words family types
if lesy=IsLetterWordsFamily then
if Length(names)>127 then