From c9b5943f0fef8ed960b7ea62b9876ea31e72a205 Mon Sep 17 00:00:00 2001 From: Wilf Wilson Date: Thu, 22 Apr 2021 11:19:01 +0100 Subject: [PATCH] Unify argument checking for some free objects In particular, unify argument processing/error checking in * FreeSemigroup * FreeMonoid * FreeMagma * FreeMagmaWithOne Resolves #1385. --- lib/magma.gd | 19 +-- lib/mgmfree.gi | 221 ++++++++++++++++++++++--------- lib/monofree.gi | 65 +++------ lib/monoid.gd | 12 +- lib/semigrp.gd | 2 +- lib/smgrpfre.gi | 116 +++-------------- tst/testinstall/mgmfree.tst | 246 +++++++++++++++++++++++++++++++++++ tst/testinstall/monofree.tst | 118 +++++++++++++++++ tst/testinstall/smgrpfre.tst | 12 +- 9 files changed, 578 insertions(+), 233 deletions(-) create mode 100644 tst/testinstall/mgmfree.tst diff --git a/lib/magma.gd b/lib/magma.gd index a987a4ce2ea..a62e13cda7f 100644 --- a/lib/magma.gd +++ b/lib/magma.gd @@ -731,7 +731,7 @@ DeclareOperation( "SquareRoots", [ IsMagma, IsMultiplicativeElement ] ); #F FreeMagma( [, ] ) #F FreeMagma( , , ... ) #F FreeMagma( ) -#F FreeMagma( infinity, , ) +#F FreeMagma( infinity[, [, ]] ) ## ## <#GAPDoc Label="FreeMagma"> ## @@ -742,18 +742,19 @@ DeclareOperation( "SquareRoots", [ IsMagma, IsMultiplicativeElement ] ); ## Label="for various names"/> ## -## ## ## ## Called with a positive integer rank, ## returns ## a free magma on rank generators. -## If the optional argument name is given then the generators are +## If the optional argument name (a string) is given, +## then the generators are ## printed as name1, name2 etc., ## that is, each name is the concatenation of the string name and an -## integer from 1 to range. -## The default for name is the string "m". +## integer from 1 to rank. +## The default for name is the string "x". ##

## Called in the second form, ## returns @@ -783,7 +784,7 @@ DeclareGlobalFunction( "FreeMagma" ); #F FreeMagmaWithOne( [, ] ) #F FreeMagmaWithOne( , , ... ) #F FreeMagmaWithOne( ) -#F FreeMagmaWithOne( infinity, , ) +#F FreeMagmaWithOne( infinity[, [, ]] ) ## ## <#GAPDoc Label="FreeMagmaWithOne"> ## @@ -794,7 +795,7 @@ DeclareGlobalFunction( "FreeMagma" ); ## Label="for various names"/> ## -## ## ## @@ -804,8 +805,8 @@ DeclareGlobalFunction( "FreeMagma" ); ## If the optional argument name is given then the generators are ## printed as name1, name2 etc., ## that is, each name is the concatenation of the string name and an -## integer from 1 to range. -## The default for name is the string "m". +## integer from 1 to rank. +## The default for name is the string "x". ##

## Called in the second form, ## returns diff --git a/lib/mgmfree.gi b/lib/mgmfree.gi index 15e91b86ac1..17bfc37692a 100644 --- a/lib/mgmfree.gi +++ b/lib/mgmfree.gi @@ -273,43 +273,152 @@ InstallMethod( MagmaGeneratorsOfFamily, F -> List( [ 1 .. Length( F!.names ) ], i -> ObjByExtRep( F, i ) ) ); +# Currently used by FreeSemigroup, FreeMagma, FreeMonoid, FreeMagmaWithOne +FreeAlgebraCreatorArgumentProcessor := function(func, lesy, arg) + local rank, + name, + init, + bad_form, + err, # string; helpful error message + form, # string: assumed argument form of call to + names; # list of generators names + + + # Process and validate the argument list, constructing names if necessary + err := ""; + form := fail; + bad_form := false; + names := []; + + if Length( arg ) = 0 or arg[1] = 0 + or (Length( arg ) = 1 and IsList( arg[1] ) and IsEmpty( arg[1] )) then + # rank 0 + + # func( [, ] ) + elif IsPosInt( arg[1] ) and Length( arg ) <= 2 then + + # Get default and optional arguments + rank := arg[1]; + if Length( arg ) = 1 then + if func = "FreeSemigroup" then + name := "s"; + elif func = "FreeMagma" or func = "FreeMagmaWithOne" then + name := "x"; + else + name := "m"; + fi; + else + name := arg[2]; + fi; + + # Error checking + if not IsString( name ) then + form := ", "; + err := " must be a string"; + + # Construct names + else + names:= List( [ 1 .. rank ], i -> Concatenation( name, String(i) ) ); + MakeImmutable( names ); + fi; + + # func( [, , ...] ), or a list of such arguments + elif ForAll( arg, IsString ) or Length( arg ) = 1 and IsList( arg[1] ) then + if Length( arg ) = 1 and not IsString( arg[1] ) then + form := "[ , , ... ]"; + names:= arg[1]; + else + form := ", , ..."; + names:= arg; + fi; + if not ForAll( names, s -> IsString(s) and not IsEmpty(s) ) then + err := "the names must be nonempty strings"; + fi; + + # func( infinity[, [, ]] ) + elif arg[1] = infinity and Length( arg ) <= 3 then + + # Get default and optional arguments + name := "s"; + init := []; + if Length( arg ) = 3 then + form := "infinity, , "; + name := arg[2]; + init := arg[3]; + elif Length( arg ) = 2 then + form := "infinity, "; + name := arg[2]; + fi; + + # Error checking + if not IsString( name ) then + err := " must be a string"; + fi; + if not ( IsList( init ) and ForAll( init, s -> IsString(s) and not IsEmpty(s) ) ) then + if not IsEmpty(err) then + Append(err, " and "); + fi; + Append(err, " must be a list of nonempty strings"); + fi; + + # Construct names + if IsEmpty(err) then + names:= InfiniteListOfNames( name, init ); + fi; + + else + bad_form := true; + fi; + + if not IsEmpty(err) then + ErrorNoReturn(StringFormatted("{}( {} ): {}", func, form, err)); + fi; + + # deal with letter words family types + if lesy <> fail then + if lesy=IsLetterWordsFamily then + if Length(names)>127 then + lesy:=IsWLetterWordsFamily; + else + lesy:=IsBLetterWordsFamily; + fi; + elif lesy=IsBLetterWordsFamily and Length(names)>127 then + lesy:=IsWLetterWordsFamily; + fi; + fi; + + return rec( + names := names, + form := form, + lesy := lesy, + bad_form := bad_form, + ); +end; + + ############################################################################# ## -#F FreeMagma( ) -#F FreeMagma( , ) +#F FreeMagma( [, ] ) #F FreeMagma( , , ... ) #F FreeMagma( ) -#F FreeMagma( infinity, , ) -## -InstallGlobalFunction( FreeMagma, - function( arg ) - local names, # list of generators names - F, # family of free magma element objects - M; # free magma, result - - # Get and check the argument list, and construct names if necessary. - if Length( arg ) = 1 and arg[1] = infinity then - names:= InfiniteListOfNames( "x" ); - elif Length( arg ) = 2 and arg[1] = infinity then - names:= InfiniteListOfNames( arg[2] ); - elif Length( arg ) = 3 and arg[1] = infinity then - names:= InfiniteListOfNames( arg[2], arg[3] ); - elif Length( arg ) = 1 and IsInt( arg[1] ) and 0 < arg[1] then - names:= List( [ 1 .. arg[1] ], - i -> Concatenation( "x", String(i) ) ); - MakeImmutable( names ); - elif Length( arg ) = 2 and IsInt( arg[1] ) and 0 < arg[1] then - names:= List( [ 1 .. arg[1] ], - i -> Concatenation( arg[2], String(i) ) ); - MakeImmutable( names ); - elif 1 <= Length( arg ) and ForAll( arg, IsString ) then - names:= arg; - elif Length( arg ) = 1 and IsList( arg[1] ) - and not IsEmpty( arg[1] ) - and ForAll( arg[1], IsString ) then - names:= arg[1]; - else - Error("usage: FreeMagma(,..),FreeMagma()"); +#F FreeMagma( infinity[, [, ]] ) +## +InstallGlobalFunction( FreeMagma, function( arg ) + local names, # list of generators names + F, # family of free magma element objects + M, # free magma, result + processed; + + processed := FreeAlgebraCreatorArgumentProcessor("FreeMagma", fail, arg); + names := processed.names; + + if processed.bad_form then + ErrorNoReturn("""usage: FreeMagma( [, ] ) + FreeMagma( , , ... ) + FreeMagma( ) + FreeMagma( infinity[, [, ]] )"""); + elif IsEmpty(names) then + ErrorNoReturn("free magmas of rank zero are not supported"); fi; # Construct the family of element objects of our magma. @@ -334,42 +443,26 @@ end ); ############################################################################# ## -#F FreeMagmaWithOne( ) -#F FreeMagmaWithOne( , ) +#F FreeMagmaWithOne( [, ] ) #F FreeMagmaWithOne( , , ... ) #F FreeMagmaWithOne( ) -#F FreeMagmaWithOne( infinity, , ) +#F FreeMagmaWithOne( infinity[, [, ]] ) ## InstallGlobalFunction( FreeMagmaWithOne, function( arg ) - local names, # list of generators names - F, # family of free magma element objects - M; # free magma, result - - # Get and check the argument list, and construct names if necessary. - if Length( arg ) = 1 and arg[1] = infinity then - names:= InfiniteListOfNames( "x" ); - elif Length( arg ) = 2 and arg[1] = infinity then - names:= InfiniteListOfNames( arg[2] ); - elif Length( arg ) = 3 and arg[1] = infinity then - names:= InfiniteListOfNames( arg[2], arg[3] ); - elif Length( arg ) = 1 and IsInt( arg[1] ) and 0 < arg[1] then - names:= List( [ 1 .. arg[1] ], - i -> Concatenation( "x", String(i) ) ); - MakeImmutable( names ); - elif Length( arg ) = 2 and IsInt( arg[1] ) and 0 < arg[1] then - names:= List( [ 1 .. arg[1] ], - i -> Concatenation( arg[2], String(i) ) ); - MakeImmutable( names ); - elif 1 <= Length( arg ) and ForAll( arg, IsString ) then - names:= arg; - elif Length( arg ) = 1 and IsList( arg[1] ) - and not IsEmpty( arg[1]) - and ForAll( arg[1], IsString ) then - names:= arg[1]; - else - Error( "usage: FreeMagmaWithOne(,..),", - "FreeMagmaWithOne()" ); + local names, # list of generators names + F, # family of free magma element objects + M, # free magma, result + processed; + + processed := FreeAlgebraCreatorArgumentProcessor("FreeMagmaWithOne", fail, arg); + names := processed.names; + + if processed.bad_form then + ErrorNoReturn("""usage: FreeMagmaWithOne( [, ] ) + FreeMagmaWithOne( , , ... ) + FreeMagmaWithOne( ) + FreeMagmaWithOne( infinity[, [, ]] )"""); fi; # Handle the trivial case. diff --git a/lib/monofree.gi b/lib/monofree.gi index 05bca577757..5d9c359678d 100644 --- a/lib/monofree.gi +++ b/lib/monofree.gi @@ -176,69 +176,42 @@ InstallMethod( GeneratorsSmallest, ############################################################################# ## -#F FreeMonoid( ) -#F FreeMonoid( , ) -#F FreeMonoid( , , ... ) -#F FreeMonoid( ) -#F FreeMonoid( infinity, , ) +#F FreeMonoid( [, ][, [ ) +#F FreeMonoid( [, ], , ... ) +#F FreeMonoid( [, ] ) +#F FreeMonoid( [, ]infinity[, [, ]] ) ## InstallGlobalFunction( FreeMonoid, function( arg ) - local names, # list of generators names + local names, # list of generator names F, # family of free monoid element objects - zarg, + M, # free monoid, result lesy, # filter for letter or syllable words family - M; # free monoid, result + zarg, + processed; lesy:=IsLetterWordsFamily; # default - if IsFilter(arg[1]) then + if not IsEmpty(arg) and IsFilter(arg[1]) then lesy:=arg[1]; zarg:=arg{[2..Length(arg)]}; else zarg:=arg; fi; - # Get and check the argument list, and construct names if necessary. - if Length( zarg ) = 1 and zarg[1] = infinity then - names:= InfiniteListOfNames( "m" ); - elif Length( zarg ) = 2 and zarg[1] = infinity then - names:= InfiniteListOfNames( zarg[2] ); - elif Length( zarg ) = 3 and zarg[1] = infinity then - names:= InfiniteListOfNames( zarg[2], zarg[3] ); - elif Length( zarg ) = 1 and IsInt( zarg[1] ) and 0 <= zarg[1] then - names:= List( [ 1 .. zarg[1] ], - i -> Concatenation( "m", String(i) ) ); - MakeImmutable( names ); - 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 - names:= zarg; - elif Length( zarg ) = 1 and IsList( zarg[1] ) - and ForAll( zarg[1], IsString ) then - names:= zarg[1]; - else - Error("usage: FreeMonoid(,..) or FreeMonoid()"); - fi; + processed := FreeAlgebraCreatorArgumentProcessor("FreeMonoid", lesy, zarg); + names := processed.names; - # deal with letter words family types - if lesy=IsLetterWordsFamily then - if Length(names)>127 then - lesy:=IsWLetterWordsFamily; - else - lesy:=IsBLetterWordsFamily; - fi; - elif lesy=IsBLetterWordsFamily and Length(names)>127 then - lesy:=IsWLetterWordsFamily; - fi; + if processed.bad_form then + ErrorNoReturn("""usage: FreeMonoid( [, ][, ] ) + FreeMonoid( [, ], , ... ) + FreeMonoid( [, ] ) + FreeMonoid( [, ]infinity[, [, ]] )"""); + fi; # Construct the family of element objects of our monoid. F:= NewFamily( "FreeMonoidElementsFamily", IsAssocWordWithOne, CanEasilySortElements, # the free monoid can. CanEasilySortElements # the free monoid can. - and lesy); + and processed.lesy); # Install the data (names, no. of bits available for exponents, types). StoreInfoFreeMagma( F, names, IsAssocWordWithOne ); @@ -267,7 +240,7 @@ InstallGlobalFunction( FreeMonoid, function( arg ) SetIsFreeMonoid( M, true); SetIsWholeFamily( M, true ); - # store the whole monoid in the family + # store the whole monoid in the family FamilyObj(M)!.wholeMonoid:= M; F!.freeMonoid:=M; diff --git a/lib/monoid.gd b/lib/monoid.gd index 8d01a9613fd..0880890da03 100644 --- a/lib/monoid.gd +++ b/lib/monoid.gd @@ -184,11 +184,10 @@ DeclareSynonymAttr( "TrivialSubmonoid", TrivialSubmagmaWithOne ); ############################################################################# ## -#F FreeMonoid( [,] ) -#F FreeMonoid( [,], ) +#F FreeMonoid( [,][, ] ) #F FreeMonoid( [,], , ... ) #F FreeMonoid( [,] ) -#F FreeMonoid( [,]infinity, , ) +#F FreeMonoid( [,]infinity[, [, ]] ) ## ## <#GAPDoc Label="FreeMonoid"> ## @@ -199,17 +198,18 @@ DeclareSynonymAttr( "TrivialSubmonoid", TrivialSubmagmaWithOne ); ## Label="for various names"/> ## -## ## ## ## Called with a positive integer rank, ## returns ## a free monoid on rank generators. -## If the optional argument name is given then the generators are +## If the optional argument name (a string) is given, +## then the generators are ## printed as name1, name2 etc., ## that is, each name is the concatenation of the string name and an -## integer from 1 to range. +## integer from 1 to rank. ## The default for name is the string "m". ##

## Called in the second form, diff --git a/lib/semigrp.gd b/lib/semigrp.gd index 9cf4c9df753..a27e03714ec 100644 --- a/lib/semigrp.gd +++ b/lib/semigrp.gd @@ -278,7 +278,7 @@ DeclareAttribute("CayleyGraphDualSemigroup",IsSemigroup); ############################################################################# ## #F FreeSemigroup( [, ][, ] ) -#F FreeSemigroup( [, ][, , ...] ) +#F FreeSemigroup( [, ], , ... ) #F FreeSemigroup( [, ] ) #F FreeSemigroup( [, ]infinity[, [, ]] ) ## diff --git a/lib/smgrpfre.gi b/lib/smgrpfre.gi index 67369260d7a..d4037cc371f 100644 --- a/lib/smgrpfre.gi +++ b/lib/smgrpfre.gi @@ -378,23 +378,19 @@ InstallMethod( GeneratorsSmallest, ############################################################################# ## #F FreeSemigroup( [, ][, ] ) -#F FreeSemigroup( [, ][, , ...] ) +#F FreeSemigroup( [, ], , ... ) #F FreeSemigroup( [, ] ) #F FreeSemigroup( [, ]infinity[, [, ]] ) ## InstallGlobalFunction( FreeSemigroup, function( arg ) - local names, # list of generators names + local names, # list of generator names F, # family of free semigroup element objects - zarg, - lesy, # filter for letter or syllable words family S, # free semigroup, result - err, # string; helpful error message - form, # string: assumed argument form of call to FreeSemigroup - rank, - name, - init; + lesy, # filter for letter or syllable words family + zarg, + processed; - lesy:=IsLetterWordsFamily; # default: + lesy:=IsLetterWordsFamily; # default if not IsEmpty(arg) and IsFilter(arg[1]) then lesy:=arg[1]; zarg:=arg{[2..Length(arg)]}; @@ -402,106 +398,24 @@ InstallGlobalFunction( FreeSemigroup, function( arg ) zarg:=arg; fi; - # Process and validate the argument list, constructing names if necessary - err := ""; - - if Length( zarg ) = 0 or zarg[1] = 0 - or (Length(zarg) = 1 and IsList( zarg[1] ) and IsEmpty( zarg[1] )) then - Error("free semigroups of rank zero are not supported"); - - # FreeSemigroup( [, ] ) - elif IsPosInt( zarg[1] ) and Length( zarg ) <= 2 then - - # Get default and optional arguments - rank := zarg[1]; - if Length( zarg ) = 1 then - name := "s"; - else - name := zarg[2]; - fi; - - # Error checking - if not IsString( name ) then - form := ", "; - err := " must be a string"; - - # Construct names - else - names:= List( [ 1 .. rank ], i -> Concatenation( name, String(i) ) ); - MakeImmutable( names ); - fi; - - # FreeSemigroup( [, , ...] ), or a list of such arguments - elif ForAll( zarg, IsString ) or Length( zarg ) = 1 and IsList( zarg[1] ) then - if Length( zarg ) = 1 and not IsString( zarg[1] ) then - form := "[ , , ... ]"; - names:= zarg[1]; - else - form := ", , ..."; - names:= zarg; - fi; - if not ForAll( names, s -> IsString(s) and not IsEmpty(s) ) then - err := "the names must be nonempty strings"; - fi; + processed := FreeAlgebraCreatorArgumentProcessor("FreeSemigroup", lesy, zarg); + names := processed.names; - # FreeSemigroup( infinity[, [, ]] ) - elif zarg[1] = infinity and Length( zarg ) <= 3 then - - # Get default and optional arguments - name := "s"; - init := []; - if Length( zarg ) = 3 then - form := "infinity, , "; - name := zarg[2]; - init := zarg[3]; - elif Length( zarg ) = 2 then - form := "infinity, "; - name := zarg[2]; - fi; - - # Error checking - if not IsString( name ) then - err := " must be a string"; - fi; - if not ( IsList( init ) and ForAll( init, s -> IsString(s) and not IsEmpty(s) ) ) then - if not IsEmpty(err) then - Append(err, " and "); - fi; - Append(err, " must be a list of nonempty strings"); - fi; - - # Construct names - if IsEmpty(err) then - names:= InfiniteListOfNames( name, init ); - fi; - - else - ErrorNoReturn("""usage: FreeSemigroup( [, ][, ] ) - FreeSemigroup( [, ][, , ...] ) + if processed.bad_form then + ErrorNoReturn("""usage: FreeSemigroup( [, ][, ] ) + FreeSemigroup( [, ], , ... ) FreeSemigroup( [, ] ) FreeSemigroup( [, ]infinity[, [, ]] )"""); - fi; - - if not IsEmpty(err) then - ErrorNoReturn(StringFormatted("FreeSemigroup( {} ): {}", form, err)); - fi; + elif IsEmpty(names) then + ErrorNoReturn("free semigroups of rank zero are not supported"); + fi; - # deal with letter words family types - if lesy=IsLetterWordsFamily then - if Length(names)>127 then - lesy:=IsWLetterWordsFamily; - else - lesy:=IsBLetterWordsFamily; - fi; - elif lesy=IsBLetterWordsFamily and Length(names)>127 then - lesy:=IsWLetterWordsFamily; - fi; # Construct the family of element objects of our semigroup. F:= NewFamily( "FreeSemigroupElementsFamily", IsAssocWord, CanEasilySortElements, # the free group can. CanEasilySortElements # the free group can. - and lesy); + and processed.lesy); # Install the data (names, no. of bits available for exponents, types). StoreInfoFreeMagma( F, names, IsAssocWord ); diff --git a/tst/testinstall/mgmfree.tst b/tst/testinstall/mgmfree.tst new file mode 100644 index 00000000000..13ed4fc354e --- /dev/null +++ b/tst/testinstall/mgmfree.tst @@ -0,0 +1,246 @@ +#@local M +gap> START_TEST("mgmfree.tst"); + +# FreeMagma +gap> FreeMagma(fail); +Error, usage: FreeMagma( [, ] ) + FreeMagma( , , ... ) + FreeMagma( ) + FreeMagma( infinity[, [, ]] ) + +# FreeMagma: rank 0 +gap> FreeMagma(); +Error, free magmas of rank zero are not supported +gap> FreeMagma([]); +Error, free magmas of rank zero are not supported +gap> FreeMagma(""); +Error, free magmas of rank zero are not supported +gap> FreeMagma(0); +Error, free magmas of rank zero are not supported +gap> FreeMagma(0, "name"); +Error, free magmas of rank zero are not supported + +# FreeMagma(infinity[, name[, init]]) +gap> FreeMagma(infinity); + +gap> FreeMagma(infinity, fail); +Error, FreeMagma( infinity, ): must be a string +gap> FreeMagma(infinity, []); + +gap> FreeMagma(infinity, ""); + +gap> FreeMagma(infinity, "nicename"); + +gap> FreeMagma(infinity, fail, fail); +Error, FreeMagma( infinity, , ): must be a string and must be a list of nonempty strings +gap> FreeMagma(infinity, "nicename", fail); +Error, FreeMagma( infinity, , ): must be a list of nonempt\ +y strings +gap> FreeMagma(infinity, "gen", []); + +gap> FreeMagma(infinity, "gen", [""]); +Error, FreeMagma( infinity, , ): must be a list of nonempt\ +y strings +gap> FreeMagma(infinity, "gen", ["starter"]); + +gap> FreeMagma(infinity, "gen", ["starter", ""]); +Error, FreeMagma( infinity, , ): must be a list of nonempt\ +y strings +gap> M := FreeMagma(infinity, "gen", ["starter", "second", "third"]); + +gap> GeneratorsOfMagma(M){[1 .. 4]}; +[ starter, second, third, gen4 ] +gap> FreeMagma(infinity, "gen", ["starter"], fail); +Error, usage: FreeMagma( [, ] ) + FreeMagma( , , ... ) + FreeMagma( ) + FreeMagma( infinity[, [, ]] ) + +# FreeMagma(rank[, name]) +gap> M := FreeMagma(1); + +gap> HasIsTrivial(M) and not IsTrivial(M); +true +gap> M := FreeMagma(2); + +gap> HasIsTrivial(M) and not IsTrivial(M); +true +gap> M := FreeMagma(10); + +gap> M := FreeMagma(3, fail); +Error, FreeMagma( , ): must be a string +gap> M := FreeMagma(4, ""); + +gap> M := FreeMagma(5, []); + +gap> M := FreeMagma(4, "cheese"); + +gap> FreeMagma(3, "car", fail); +Error, usage: FreeMagma( [, ] ) + FreeMagma( , , ... ) + FreeMagma( ) + FreeMagma( infinity[, [, ]] ) + +# FreeMagma( [, , ...] ) +gap> FreeMagma("", "second"); +Error, FreeMagma( , , ... ): the names must be nonempty strings +gap> FreeMagma("first", ""); +Error, FreeMagma( , , ... ): the names must be nonempty strings +gap> FreeMagma("first", []); +Error, FreeMagma( , , ... ): the names must be nonempty strings +gap> FreeMagma([], []); +Error, FreeMagma( , , ... ): the names must be nonempty strings +gap> FreeMagma("bacon", "eggs", "beans"); + +gap> FreeMagma("shed"); + + +# FreeMagma( [ [, , ...] ] ) +gap> FreeMagma(["", "second"]); +Error, FreeMagma( [ , , ... ] ): the names must be nonempty stri\ +ngs +gap> FreeMagma(["first", ""]); +Error, FreeMagma( [ , , ... ] ): the names must be nonempty stri\ +ngs +gap> FreeMagma(["first", []]); +Error, FreeMagma( [ , , ... ] ): the names must be nonempty stri\ +ngs +gap> FreeMagma([[], []]); +Error, FreeMagma( [ , , ... ] ): the names must be nonempty stri\ +ngs +gap> FreeMagma(["bacon", "eggs", "beans"]); + +gap> FreeMagma(["grid"]); + +gap> FreeMagma(["grid"], fail); +Error, usage: FreeMagma( [, ] ) + FreeMagma( , , ... ) + FreeMagma( ) + FreeMagma( infinity[, [, ]] ) + +# FreeMagmaWithOne +gap> FreeMagmaWithOne(fail); +Error, usage: FreeMagmaWithOne( [, ] ) + FreeMagmaWithOne( , , ... ) + FreeMagmaWithOne( ) + FreeMagmaWithOne( infinity[, [, ]] ) + +# FreeMagmaWithOne: rank 0 +gap> FreeMagmaWithOne(); + +gap> FreeMagmaWithOne([]); + +gap> FreeMagmaWithOne(""); + +gap> FreeMagmaWithOne(0); + +gap> FreeMagmaWithOne(0, "name"); + + +# FreeMagmaWithOne(infinity[, name[, init]]) +gap> FreeMagmaWithOne(infinity); + +gap> FreeMagmaWithOne(infinity, fail); +Error, FreeMagmaWithOne( infinity, ): must be a string +gap> FreeMagmaWithOne(infinity, []); + +gap> FreeMagmaWithOne(infinity, ""); + +gap> FreeMagmaWithOne(infinity, "nicename"); + +gap> FreeMagmaWithOne(infinity, fail, fail); +Error, FreeMagmaWithOne( infinity, , ): must be a string a\ +nd must be a list of nonempty strings +gap> FreeMagmaWithOne(infinity, "nicename", fail); +Error, FreeMagmaWithOne( infinity, , ): must be a list of \ +nonempty strings +gap> FreeMagmaWithOne(infinity, "gen", []); + +gap> FreeMagmaWithOne(infinity, "gen", [""]); +Error, FreeMagmaWithOne( infinity, , ): must be a list of \ +nonempty strings +gap> FreeMagmaWithOne(infinity, "gen", ["starter"]); + +gap> FreeMagmaWithOne(infinity, "gen", ["starter", ""]); +Error, FreeMagmaWithOne( infinity, , ): must be a list of \ +nonempty strings +gap> M := FreeMagmaWithOne(infinity, "gen", ["starter", "second", "third"]); + +gap> GeneratorsOfMagmaWithOne(M){[1 .. 4]}; +[ starter, second, third, gen4 ] +gap> FreeMagmaWithOne(infinity, "gen", ["starter"], fail); +Error, usage: FreeMagmaWithOne( [, ] ) + FreeMagmaWithOne( , , ... ) + FreeMagmaWithOne( ) + FreeMagmaWithOne( infinity[, [, ]] ) + +# FreeMagmaWithOne(rank[, name]) +gap> M := FreeMagmaWithOne(1); + +gap> HasIsTrivial(M) and not IsTrivial(M); +true +gap> M := FreeMagmaWithOne(2); + +gap> HasIsTrivial(M) and not IsTrivial(M); +true +gap> M := FreeMagmaWithOne(10); + +gap> M := FreeMagmaWithOne(3, fail); +Error, FreeMagmaWithOne( , ): must be a string +gap> M := FreeMagmaWithOne(4, ""); + +gap> M := FreeMagmaWithOne(5, []); + +gap> M := FreeMagmaWithOne(4, "cheese"); + +gap> FreeMagmaWithOne(3, "car", fail); +Error, usage: FreeMagmaWithOne( [, ] ) + FreeMagmaWithOne( , , ... ) + FreeMagmaWithOne( ) + FreeMagmaWithOne( infinity[, [, ]] ) + +# FreeMagmaWithOne( [, , ...] ) +gap> FreeMagmaWithOne("", "second"); +Error, FreeMagmaWithOne( , , ... ): the names must be nonempty s\ +trings +gap> FreeMagmaWithOne("first", ""); +Error, FreeMagmaWithOne( , , ... ): the names must be nonempty s\ +trings +gap> FreeMagmaWithOne("first", []); +Error, FreeMagmaWithOne( , , ... ): the names must be nonempty s\ +trings +gap> FreeMagmaWithOne([], []); +Error, FreeMagmaWithOne( , , ... ): the names must be nonempty s\ +trings +gap> FreeMagmaWithOne("bacon", "eggs", "beans"); + +gap> FreeMagmaWithOne("shed"); + + +# FreeMagmaWithOne( [ [, , ...] ] ) +gap> FreeMagmaWithOne(["", "second"]); +Error, FreeMagmaWithOne( [ , , ... ] ): the names must be nonemp\ +ty strings +gap> FreeMagmaWithOne(["first", ""]); +Error, FreeMagmaWithOne( [ , , ... ] ): the names must be nonemp\ +ty strings +gap> FreeMagmaWithOne(["first", []]); +Error, FreeMagmaWithOne( [ , , ... ] ): the names must be nonemp\ +ty strings +gap> FreeMagmaWithOne([[], []]); +Error, FreeMagmaWithOne( [ , , ... ] ): the names must be nonemp\ +ty strings +gap> FreeMagmaWithOne(["bacon", "eggs", "beans"]); + +gap> FreeMagmaWithOne(["grid"]); + +gap> FreeMagmaWithOne(["grid"], fail); +Error, usage: FreeMagmaWithOne( [, ] ) + FreeMagmaWithOne( , , ... ) + FreeMagmaWithOne( ) + FreeMagmaWithOne( infinity[, [, ]] ) + +# +gap> STOP_TEST( "mgmfree.tst", 1); diff --git a/tst/testinstall/monofree.tst b/tst/testinstall/monofree.tst index aed6642167e..65578331f23 100644 --- a/tst/testinstall/monofree.tst +++ b/tst/testinstall/monofree.tst @@ -41,5 +41,123 @@ true gap> ForAll([0,1,2,3,infinity], n -> (n < 2) = IsCommutative(FreeMonoid(n))); true +# FreeMonoid +gap> FreeMonoid(fail); +Error, usage: FreeMonoid( [, ][, ] ) + FreeMonoid( [, ], , ... ) + FreeMonoid( [, ] ) + FreeMonoid( [, ]infinity[, [, ]] ) + +# FreeMonoid: rank 0 +gap> FreeMonoid(); + +gap> FreeMonoid([]); + +gap> FreeMonoid(""); + +gap> FreeMonoid(0); + +gap> FreeMonoid(0, "name"); + + +# FreeMonoid(infinity[, name[, init]]) +gap> FreeMonoid(infinity); + +gap> FreeMonoid(infinity, fail); +Error, FreeMonoid( infinity, ): must be a string +gap> FreeMonoid(infinity, []); + +gap> FreeMonoid(infinity, ""); + +gap> FreeMonoid(infinity, "nicename"); + +gap> FreeMonoid(infinity, fail, fail); +Error, FreeMonoid( infinity, , ): must be a string and must be a list of nonempty strings +gap> FreeMonoid(infinity, "nicename", fail); +Error, FreeMonoid( infinity, , ): must be a list of nonemp\ +ty strings +gap> FreeMonoid(infinity, "gen", []); + +gap> FreeMonoid(infinity, "gen", [""]); +Error, FreeMonoid( infinity, , ): must be a list of nonemp\ +ty strings +gap> FreeMonoid(infinity, "gen", ["starter"]); + +gap> FreeMonoid(infinity, "gen", ["starter", ""]); +Error, FreeMonoid( infinity, , ): must be a list of nonemp\ +ty strings +gap> F := FreeMonoid(infinity, "gen", ["starter", "second", "third"]); + +gap> GeneratorsOfMonoid(F){[1 .. 4]}; +[ starter, second, third, gen4 ] +gap> FreeMonoid(infinity, "gen", ["starter"], fail); +Error, usage: FreeMonoid( [, ][, ] ) + FreeMonoid( [, ], , ... ) + FreeMonoid( [, ] ) + FreeMonoid( [, ]infinity[, [, ]] ) + +# FreeMonoid(rank[, name]) +gap> F := FreeMonoid(1); + +gap> HasIsCommutative(F) and IsCommutative(F); +true +gap> F := FreeMonoid(2); + +gap> HasIsCommutative(F) and not IsCommutative(F); +true +gap> F := FreeMonoid(10); + +gap> F := FreeMonoid(3, fail); +Error, FreeMonoid( , ): must be a string +gap> F := FreeMonoid(4, ""); + +gap> F := FreeMonoid(5, []); + +gap> F := FreeMonoid(4, "cheese"); + +gap> FreeMonoid(3, "car", fail); +Error, usage: FreeMonoid( [, ][, ] ) + FreeMonoid( [, ], , ... ) + FreeMonoid( [, ] ) + FreeMonoid( [, ]infinity[, [, ]] ) + +# FreeMonoid( , , ... ) +gap> FreeMonoid("", "second"); +Error, FreeMonoid( , , ... ): the names must be nonempty strings +gap> FreeMonoid("first", ""); +Error, FreeMonoid( , , ... ): the names must be nonempty strings +gap> FreeMonoid("first", []); +Error, FreeMonoid( , , ... ): the names must be nonempty strings +gap> FreeMonoid([], []); +Error, FreeMonoid( , , ... ): the names must be nonempty strings +gap> FreeMonoid("bacon", "eggs", "beans"); + +gap> FreeMonoid("shed"); + + +# FreeMonoid( [ , , ... ] ) +gap> FreeMonoid(["", "second"]); +Error, FreeMonoid( [ , , ... ] ): the names must be nonempty str\ +ings +gap> FreeMonoid(["first", ""]); +Error, FreeMonoid( [ , , ... ] ): the names must be nonempty str\ +ings +gap> FreeMonoid(["first", []]); +Error, FreeMonoid( [ , , ... ] ): the names must be nonempty str\ +ings +gap> FreeMonoid([[], []]); +Error, FreeMonoid( [ , , ... ] ): the names must be nonempty str\ +ings +gap> FreeMonoid(["bacon", "eggs", "beans"]); + +gap> FreeMonoid(["grid"]); + +gap> FreeMonoid(["grid"], fail); +Error, usage: FreeMonoid( [, ][, ] ) + FreeMonoid( [, ], , ... ) + FreeMonoid( [, ] ) + FreeMonoid( [, ]infinity[, [, ]] ) + # gap> STOP_TEST( "grpfree.tst", 1); diff --git a/tst/testinstall/smgrpfre.tst b/tst/testinstall/smgrpfre.tst index 668e2eaf97e..2c0c83d4f41 100644 --- a/tst/testinstall/smgrpfre.tst +++ b/tst/testinstall/smgrpfre.tst @@ -4,7 +4,7 @@ gap> START_TEST("smgrpfre.tst"); # FreeSemigroup gap> FreeSemigroup(fail); Error, usage: FreeSemigroup( [, ][, ] ) - FreeSemigroup( [, ][, , ...] ) + FreeSemigroup( [, ], , ... ) FreeSemigroup( [, ] ) FreeSemigroup( [, ]infinity[, [, ]] ) @@ -53,7 +53,7 @@ gap> GeneratorsOfSemigroup(F){[1 .. 4]}; [ starter, second, third, gen4 ] gap> FreeSemigroup(infinity, "gen", ["starter"], fail); Error, usage: FreeSemigroup( [, ][, ] ) - FreeSemigroup( [, ][, , ...] ) + FreeSemigroup( [, ], , ... ) FreeSemigroup( [, ] ) FreeSemigroup( [, ]infinity[, [, ]] ) @@ -78,11 +78,11 @@ gap> F := FreeSemigroup(4, "cheese"); gap> FreeSemigroup(3, "car", fail); Error, usage: FreeSemigroup( [, ][, ] ) - FreeSemigroup( [, ][, , ...] ) + FreeSemigroup( [, ], , ... ) FreeSemigroup( [, ] ) FreeSemigroup( [, ]infinity[, [, ]] ) -# FreeSemigroup( [, , ...] ) +# FreeSemigroup( , , ... ) gap> FreeSemigroup("", "second"); Error, FreeSemigroup( , , ... ): the names must be nonempty stri\ ngs @@ -100,7 +100,7 @@ gap> FreeSemigroup("bacon", "eggs", "beans"); gap> FreeSemigroup("shed"); -# FreeSemigroup( [ [, , ...] ] ) +# FreeSemigroup( [ , , ... ] ) gap> FreeSemigroup(["", "second"]); Error, FreeSemigroup( [ , , ... ] ): the names must be nonempty \ strings @@ -119,7 +119,7 @@ gap> FreeSemigroup(["grid"]); gap> FreeSemigroup(["grid"], fail); Error, usage: FreeSemigroup( [, ][, ] ) - FreeSemigroup( [, ][, , ...] ) + FreeSemigroup( [, ], , ... ) FreeSemigroup( [, ] ) FreeSemigroup( [, ]infinity[, [, ]] )