Skip to content
Draft
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
2 changes: 1 addition & 1 deletion doc/ref/grplib.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ It is possible to influence this naming with the option <C>generatorNames</C>,
see Section&nbsp;<Ref Sect="Function Call With Options"/>.
If this option holds a string, then the generators are named with this
string and sequential numbers starting with <C>1</C>.
If this option holds a list of sufficient length consisting of
If this option holds a list of sufficient length consisting of distinct
nonempty strings, then the generator names are taken from this list, in order.
<P/>
<Example><![CDATA[
Expand Down
12 changes: 8 additions & 4 deletions lib/algebra.gd
Original file line number Diff line number Diff line change
Expand Up @@ -1491,7 +1491,8 @@ DeclareOperation( "AsLieAlgebra", [ IsDivisionRing, IsCollection ] );
## <Description>
## is a free (nonassociative) algebra of rank <A>rank</A>
## over the division ring <A>R</A>.
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional strings
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional
## distinct nonempty strings
## that can be used to provide names for the generators.
## <Example><![CDATA[
## gap> A:= FreeAlgebra( Rationals, "a", "b" );
Expand Down Expand Up @@ -1523,7 +1524,8 @@ DeclareGlobalFunction( "FreeAlgebra" );
## <Description>
## is a free (nonassociative) algebra-with-one of rank <A>rank</A>
## over the division ring <A>R</A>.
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional strings
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional
## distinct nonempty strings
## that can be used to provide names for the generators.
## <Example><![CDATA[
## gap> A:= FreeAlgebraWithOne( Rationals, 4, "q" );
Expand Down Expand Up @@ -1555,7 +1557,8 @@ DeclareGlobalFunction( "FreeAlgebraWithOne" );
## <Description>
## is a free associative algebra of rank <A>rank</A> over the
## division ring <A>R</A>.
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional strings
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional
## distinct nonempty strings
## that can be used to provide names for the generators.
## <Example><![CDATA[
## gap> A:= FreeAssociativeAlgebra( GF( 5 ), 4, "a" );
Expand Down Expand Up @@ -1583,7 +1586,8 @@ DeclareGlobalFunction( "FreeAssociativeAlgebra" );
## <Description>
## is a free associative algebra-with-one of rank <A>rank</A> over the
## division ring <A>R</A>.
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional strings
## Here <A>name</A>, and <A>name1</A>, <A>name2</A>, ... are optional
## distinct nonempty strings
## that can be used to provide names for the generators.
## <Example><![CDATA[
## gap> A:= FreeAssociativeAlgebraWithOne( Rationals, "a", "b", "c" );
Expand Down
4 changes: 4 additions & 0 deletions lib/algebra.gi
Original file line number Diff line number Diff line change
Expand Up @@ -3322,6 +3322,10 @@ BindGlobal( "FreeAlgebraConstructor", function( name, magma )
"or ", name, "( <R>, <name1>, ... )" );
fi;

if not IsDuplicateFreeList(names) then
Error( "the given generator names must be distinct" );
fi;

M := magma( names );

# Construct the algebra as free magma algebra of a free magma over `R'.
Expand Down
1 change: 1 addition & 0 deletions lib/alglie.gd
Original file line number Diff line number Diff line change
Expand Up @@ -1253,6 +1253,7 @@ DeclareAttribute(
## <C>FreeLieAlgebra( <A>R</A>, <A>name1</A>, <A>name2</A>,...)</C> returns
## a free Lie algebra over <A>R</A> with generators named <A>name1</A>,
## <A>name2</A>, and so on.
## Note that any provided generator names must be distinct.
## The elements of a free Lie algebra are written on the Hall-Lyndon
## basis.
## <Example><![CDATA[
Expand Down
9 changes: 5 additions & 4 deletions lib/grpfree.gd
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ DeclareSynonym( "IsElementOfFreeGroupFamily",IsAssocWordWithInverseFamily );
## </Item>
## <Mark>2: For given generator names</Mark>
## <Item>
## Called with various nonempty strings,
## Called with various distinct nonempty strings,
## <Ref Func="FreeGroup" Label="for various names"/> returns
## a free group on as many generators as arguments, which are labelled
## <A>name1</A>, <A>name2</A>, etc.
## </Item>
## <Mark>3: For a given list of generator names</Mark>
## <Item>
## Called with a finite list <A>names</A> of
## Called with a finite duplicate-free list <A>names</A> of
## nonempty strings,
## <Ref Func="FreeGroup" Label="for a list of names"/> returns
## a free group on <C>Length(<A>names</A>)</C> generators, whose
Expand All @@ -104,11 +104,12 @@ DeclareSynonym( "IsElementOfFreeGroupFamily",IsAssocWordWithInverseFamily );
## The optional argument <A>name</A> must be a string; its default value is
## <C>"f"</C>,
## and the optional argument <A>init</A> must be a finite list of
## nonempty strings; its default value is an empty list.
## distinct nonempty strings; its default value is an empty list.
## The generators are initially labelled according to the list <A>init</A>,
## followed by
## <A>name</A><C>i</C> for each <C>i</C> in the range from
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>.
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>; such a label is not
## allowed to appear in <A>init</A>.
## </Item>
## </List>
## If the optional first argument <A>wfilt</A> is given, then it must be either
Expand Down
18 changes: 10 additions & 8 deletions lib/magma.gd
Original file line number Diff line number Diff line change
Expand Up @@ -818,15 +818,15 @@ DeclareGlobalFunction("FreeXArgumentProcessor");
## </Item>
## <Mark>2: For given generator names</Mark>
## <Item>
## Called with various (at least one) nonempty strings,
## Called with various (one or more) distinct nonempty strings,
## <Ref Func="FreeMagma" Label="for various names"/> returns
## a free magma on as many generators as arguments, which are labelled
## <A>name1</A>, <A>name2</A>, etc.
## </Item>
## <Mark>3: For a given list of generator names</Mark>
## <Item>
## Called with a finite nonempty list <A>names</A> of
## nonempty strings,
## distinct nonempty strings,
## <Ref Func="FreeMagma" Label="for a list of names"/> returns
## a free magma on <C>Length(<A>names</A>)</C> generators, whose
## <C>i</C>-th generator is labelled <A>names</A><C>[i]</C>.
Expand All @@ -843,11 +843,12 @@ DeclareGlobalFunction("FreeXArgumentProcessor");
## The optional argument <A>name</A> must be a string; its default value is
## <C>"x"</C>,
## and the optional argument <A>init</A> must be a finite list of
## nonempty strings; its default value is an empty list.
## distinct nonempty strings; its default value is an empty list.
## The generators are initially labelled according to the list <A>init</A>,
## followed by
## <A>name</A><C>i</C> for each <C>i</C> in the range from
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>.
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>; such a label is not
## allowed to appear in <A>init</A>.
## </Item>
## </List>
## <Example><![CDATA[
Expand Down Expand Up @@ -931,15 +932,15 @@ DeclareGlobalFunction( "FreeMagma" );
## </Item>
## <Mark>2: For given generator names</Mark>
## <Item>
## Called with various nonempty strings,
## Called with various (one or more) distinct nonempty strings,
## <Ref Func="FreeMagmaWithOne" Label="for various names"/> returns
## a free magma-with-one on as many generators as arguments, which are
## labelled <A>name1</A>, <A>name2</A>, etc.
## </Item>
## <Mark>3: For a given list of generator names</Mark>
## <Item>
## Called with a finite list <A>names</A> of
## nonempty strings,
## distinct nonempty strings,
## <Ref Func="FreeMagmaWithOne" Label="for a list of names"/> returns
## a free magma-with-one on <C>Length(<A>names</A>)</C> generators, whose
## <C>i</C>-th generator is labelled <A>names</A><C>[i]</C>.
Expand All @@ -956,11 +957,12 @@ DeclareGlobalFunction( "FreeMagma" );
## The optional argument <A>name</A> must be a string; its default value is
## <C>"x"</C>,
## and the optional argument <A>init</A> must be a finite list of
## nonempty strings; its default value is an empty list.
## distinct nonempty strings; its default value is an empty list.
## The generators are initially labelled according to the list <A>init</A>,
## followed by
## <A>name</A><C>i</C> for each <C>i</C> in the range from
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>.
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>; such a label is not
## allowed to appear in <A>init</A>.
## </Item>
## </List>
## <Example><![CDATA[
Expand Down
22 changes: 20 additions & 2 deletions lib/mgmfree.gi
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ function(
rank, # Length( names )
opt,
init,
word,
x, y1, y2;

# Set up defaults.
Expand Down Expand Up @@ -339,13 +340,14 @@ function(
MakeImmutable( names );
elif ( IsList and IsFinite )( opt ) and rank <= Length( opt )
and ForAll( [ 1 .. rank ],
s -> IsString( opt[s] ) and not IsEmpty( opt[s] ) ) then
s -> IsString( opt[s] ) and not IsEmpty( opt[s] ) )
and IsDuplicateFreeList( opt{[ 1 .. rank ]} ) then
names := MakeImmutable( opt{[ 1 .. rank ]} );
else
ErrorNoReturn( Concatenation(
"Cannot process the `generatorNames` option: ",
"the value must be either a single string, or a list ",
"of sufficiently many nonempty strings ",
"of sufficiently many distinct nonempty strings ",
"(at least ", String( rank ), ", in this case)" ) );
fi;

Expand Down Expand Up @@ -378,6 +380,8 @@ function(
err := "there must be only finitely many names";
elif not ForAll( names, s -> IsString( s ) and not IsEmpty( s ) ) then
err := "the names must be nonempty strings";
elif not IsDuplicateFreeList( names ) then
err := "the names must be distinct";
fi;

# Validate call of form: func( infinity[, <name>][, <init>] ).
Expand All @@ -404,8 +408,22 @@ function(
err := "<name> must be a string";
elif not ( IsList( init ) and IsFinite( init ) ) then
err := "<init> must be a finite list";
elif not IsDuplicateFreeList( init ) then
err := "<init> must be duplicate-free";
elif not ForAll( init, s -> IsString( s ) and not IsEmpty( s ) ) then
err := "<init> must consist of nonempty strings";
else
for word in init do
if StartsWith( word, name ) then
x := word{[ Length( name ) + 1 .. Length( word ) ]};
if not IsEmpty( x ) and ForAll( x, IsDigitChar )
and Int( x ) > Length( init ) then
err := "no member of <init> may repeat any of the infinitely many ";
Append( err, "generators that begin with <name>" );
break;
fi;
fi;
od;
fi;
if IsEmpty( err ) then
names := InfiniteListOfNames( name, init );
Expand Down
9 changes: 5 additions & 4 deletions lib/monoid.gd
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,15 @@ DeclareSynonymAttr( "TrivialSubmonoid", TrivialSubmagmaWithOne );
## </Item>
## <Mark>2: For given generator names</Mark>
## <Item>
## Called with various nonempty strings,
## Called with various (one or more) distinct nonempty strings,
## <Ref Func="FreeMonoid" Label="for various names"/> returns
## a free monoid on as many generators as arguments, which are labelled
## <A>name1</A>, <A>name2</A>, etc.
## </Item>
## <Mark>3: For a given list of generator names</Mark>
## <Item>
## Called with a finite list <A>names</A> of
## nonempty strings,
## distinct nonempty strings,
## <Ref Func="FreeMonoid" Label="for a list of names"/> returns
## a free monoid on <C>Length(<A>names</A>)</C> generators, whose
## <C>i</C>-th generator is labelled <A>names</A><C>[i]</C>.
Expand All @@ -256,11 +256,12 @@ DeclareSynonymAttr( "TrivialSubmonoid", TrivialSubmagmaWithOne );
## The optional argument <A>name</A> must be a string; its default value is
## <C>"m"</C>,
## and the optional argument <A>init</A> must be a finite list of
## nonempty strings; its default value is an empty list.
## distinct nonempty strings; its default value is an empty list.
## The generators are initially labelled according to the list <A>init</A>,
## followed by
## <A>name</A><C>i</C> for each <C>i</C> in the range from
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>.
## <C>Length(<A>init</A>)+1</C> to <K>infinity</K>; such a label is not
## allowed to appear in <A>init</A>.
## </Item>
## </List>
##
Expand Down
8 changes: 5 additions & 3 deletions lib/semigrp.gd
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ DeclareAttribute("CayleyGraphDualSemigroup",IsSemigroup);
## generators, and the labels given to the generators, can be specified in
## several different ways.
## Warning: the labels of generators are only an aid for printing,
## and do not necessarily distinguish generators;
## and do not necessarily distinguish elements of the semigroup;
## see the examples at the end for more information.
## <List>
## <Mark>
Expand All @@ -323,15 +323,15 @@ DeclareAttribute("CayleyGraphDualSemigroup",IsSemigroup);
## </Item>
## <Mark>2: For given generator names</Mark>
## <Item>
## Called with various (at least one) nonempty strings,
## Called with various (one or more) distinct nonempty strings,
## <Ref Func="FreeSemigroup" Label="for various names"/> returns
## a free semigroup on as many generators as arguments, which are labelled
## <A>name1</A>, <A>name2</A>, etc.
## </Item>
## <Mark>3: For a given list of generator names</Mark>
## <Item>
## Called with a nonempty finite list <A>names</A> of
## nonempty strings,
## distinct nonempty strings,
## <Ref Func="FreeSemigroup" Label="for a list of names"/> returns
## a free semigroup on <C>Length(<A>names</A>)</C> generators, whose
## <C>i</C>-th generator is labelled <A>names</A><C>[i]</C>.
Expand Down Expand Up @@ -417,6 +417,8 @@ DeclareAttribute("CayleyGraphDualSemigroup",IsSemigroup);
## distinguish letters.
## It is possible to create arbitrarily weird situations by choosing strange
## names for the letters.
## However, as a small step to avoiding confusion, it is disallowed to choose
## duplicate generator names.
## <P/>
## <Example><![CDATA[
## gap> f := FreeGroup( "x", "x" );
Expand Down
4 changes: 4 additions & 0 deletions tst/testinstall/grpfree.tst
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ gap> FreeGroup("bacon", "eggs", "beans");
<free group on the generators [ bacon, eggs, beans ]>
gap> FreeGroup("shed");
<free group on the generators [ shed ]>
gap> FreeGroup("shed", "shed");
Error, FreeGroup( <name1>, <name2>, ... ): the names must be distinct
gap> FreeGroup("a", "b", "c", "d", "b", "e", "f");
Error, FreeGroup( <name1>, <name2>, ... ): the names must be distinct

# FreeGroup( [ <name1>, <name2>, ... ] )
gap> FreeGroup(InfiniteListOfNames("a"));
Expand Down
8 changes: 8 additions & 0 deletions tst/testinstall/mgmfree.tst
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ gap> FreeMagma("bacon", "eggs", "beans");
<free magma on the generators [ bacon, eggs, beans ]>
gap> FreeMagma("shed");
<free magma on the generators [ shed ]>
gap> FreeMagma("shed", "shed");
Error, FreeMagma( <name1>, <name2>, ... ): the names must be distinct
gap> FreeMagma("a", "b", "c", "d", "b", "e", "f");
Error, FreeMagma( <name1>, <name2>, ... ): the names must be distinct

# FreeMagma( [ <name1>[, <name2>, ...] ] )
gap> FreeMagma(InfiniteListOfNames("a"));
Expand Down Expand Up @@ -238,6 +242,10 @@ gap> FreeMagmaWithOne("bacon", "eggs", "beans");
<free magma-with-one on the generators [ bacon, eggs, beans ]>
gap> FreeMagmaWithOne("shed");
<free magma-with-one on the generators [ shed ]>
gap> FreeMagmaWithOne("shed", "shed");
Error, FreeMagmaWithOne( <name1>, <name2>, ... ): the names must be distinct
gap> FreeMagmaWithOne("a", "b", "c", "d", "b", "e", "f");
Error, FreeMagmaWithOne( <name1>, <name2>, ... ): the names must be distinct

# FreeMagmaWithOne( [ <name1>[, <name2>, ...] ] )
gap> FreeMagmaWithOne(InfiniteListOfNames("a"));
Expand Down
4 changes: 4 additions & 0 deletions tst/testinstall/monofree.tst
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ gap> FreeMonoid("bacon", "eggs", "beans");
<free monoid on the generators [ bacon, eggs, beans ]>
gap> FreeMonoid("shed");
<free monoid on the generators [ shed ]>
gap> FreeMonoid("shed", "shed");
Error, FreeMonoid( <name1>, <name2>, ... ): the names must be distinct
gap> FreeMonoid("a", "b", "c", "d", "b", "e", "f");
Error, FreeMonoid( <name1>, <name2>, ... ): the names must be distinct

# FreeMonoid( [ <name1>, <name2>, ... ] )
gap> FreeMonoid(InfiniteListOfNames("a"));
Expand Down
8 changes: 4 additions & 4 deletions tst/testinstall/smgrpfre.tst
Original file line number Diff line number Diff line change
Expand Up @@ -147,17 +147,17 @@ Error, usage: FreeSemigroup( [<wfilt>, ]<rank>[, <name>] )
# generatorNames
gap> FreeSemigroup(5 : generatorNames := false);
Error, Cannot process the `generatorNames` option: the value must be either a \
single string, or a list of sufficiently many nonempty strings (at least 5, in\
this case)
single string, or a list of sufficiently many distinct nonempty strings (at le\
ast 5, in this case)
gap> PushOptions( rec( generatorNames := fail ) );
gap> FreeSemigroup(3 : generatorNames := "");
<free semigroup on the generators [ 1, 2, 3 ]>
gap> FreeSemigroup(2 : generatorNames := "cool");
<free semigroup on the generators [ cool1, cool2 ]>
gap> FreeSemigroup(2 : generatorNames := ["red"]);
Error, Cannot process the `generatorNames` option: the value must be either a \
single string, or a list of sufficiently many nonempty strings (at least 2, in\
this case)
single string, or a list of sufficiently many distinct nonempty strings (at le\
ast 2, in this case)
gap> PushOptions( rec( generatorNames := fail ) );
gap> FreeSemigroup(2 : generatorNames := ["red", "yellow"]);
<free semigroup on the generators [ red, yellow ]>
Expand Down
Loading