Most of the details in this chapter are of a technical nature; the user need only skim over this chapter on a first reading. Mostly, it is enough to know that
you must do a LoadPackage("anupq");
before you can expect to use a command defined by the ANUPQ package (details are in Section Loading the ANUPQ Package);
partial results of ANUPQ commands and some other data are stored in the ANUPQData
global variable (details are in Section The ANUPQData Record);
doing SetInfoLevel(InfoANUPQ, n);
for n greater than the default value 1 will give progressively more information of what is going on behind the scenes
(details are in Section Setting the Verbosity of ANUPQ via Info and InfoANUPQ);
in Section Utility Functions we describe some utility functions and functions that run examples from the collection of examples of this package;
in Section Attributes and a Property for fp and pc p-groups we describe the attributes and property NuclearRank
, MultiplicatorRank
and IsCapable
; and
in Section Hints and Warnings regarding the use of Options we describe some troubleshooting strategies. Also this section explains the utility of setting ANUPQWarnOfOtherOptions := true;
(particularly for novice users) for detecting misspelt options and diagnosing other option usage problems.
To use the ANUPQ package, as with any GAP package, it must be requested explicitly. This is done by calling
gap> LoadPackage( "anupq" ); --------------------------------------------------------------------------- Loading ANUPQ 3.3.1 (ANU p-Quotient) by Greg Gamble (GAP code, Greg.Gamble@uwa.edu.au), Werner Nickel (GAP code), and Eamonn O'Brien (C code, https://www.math.auckland.ac.nz/~obrien). maintained by: Max Horn (https://www.quendi.de/math). uses ANU pq binary (C code program) version: 1.9 Homepage: https://gap-packages.github.io/anupq/ Report issues at https://github.com/gap-packages/anupq/issues --------------------------------------------------------------------------- true
Note that since the ANUPQ package uses the AutomorphimGroupPGroup
function of the AutPGrp package and, in any case, often needs other AutPGrp functions when computing descendants, the user must ensure that the AutPGrp package is also installed, at least version 1.5. If the AutPGrp package is not installed, the ANUPQ package will fail
to load.
Also, if GAP cannot find a working pq
binary, the call to LoadPackage
will return fail
.
If you want to load the ANUPQ package by default, you can put the LoadPackage
command into your gap.ini
file (see Section Reference: The gap.ini and gaprc files in the GAP Reference Manual). By the way, the novice user of the ANUPQ package should probably also append the line
ANUPQWarnOfOtherOptions := true;
to their gap.ini
file, somewhere after the LoadPackage( "anupq" );
command (see ANUPQWarnOfOtherOptions
(3.6-1)).
This section contains fairly technical details which may be skipped on an initial reading.
‣ ANUPQData | ( global variable ) |
is a GAP record in which the essential data for an ANUPQ session within GAP is stored; its fields are:
binary
the path of the pq
binary;
tmpdir
the path of the temporary directory used by the pq
binary and GAP (i.e. the directory in which all the pq
's temporary files are created) (also see ANUPQDirectoryTemporary
(3.2-2) below);
outfile
the full path of the default pq
output file;
SPimages
the full path of the file GAP_library
to which the pq
program writes its Standard Presentation images;
version
the version of the current pq
binary;
ni
a data record used by non-interactive functions (see below and Chapter Non-interactive ANUPQ functions);
io
list of data records for PqStart
(see below and PqStart
(5.1-1)) processes;
topqlogfile
name of file logged to by ToPQLog
(see ToPQLog
(3.4-7)); and
logstream
stream of file logged to by ToPQLog
(see ToPQLog
(3.4-7)).
Each time an interactive ANUPQ process is initiated via PqStart
(see PqStart
(5.1-1)), an identifying number ioIndex is generated for the interactive process and a record ANUPQData.io[ioIndex]
with some or all of the fields listed below is created. Whenever a non-interactive function is called (see Chapter Non-interactive ANUPQ functions), the record ANUPQData.ni
is updated with fields that, if bound, have exactly the same purpose as for a ANUPQData.io[ioIndex]
record.
stream
the IOStream opened for interactive ANUPQ process ioIndex or non-interactive ANUPQ function;
group
the group given as first argument to PqStart
, Pq
, PqEpimorphism
, PqDescendants
or PqStandardPresentation
(or any synonymous methods);
haspcp
is bound and set to true
when a pc presentation is first set inside the pq
program (e.g. by PqPcPresentation
or PqRestorePcPresentation
or a higher order function like Pq
, PqEpimorphism
, PqPCover
, PqDescendants
or PqStandardPresentation
that does a PqPcPresentation
operation, but not PqStart
which only starts up an interactive ANUPQ process);
gens
a list of the generators of the group group
as strings (the same as those passed to the pq
program);
rels
a list of the relators of the group group
as strings (the same as those passed to the pq
program);
name
the name of the group whose pc presentation is defined by a call to the pq
program (according to the pq
program -- unless you have used the GroupName
option (see e.g. Pq
(4.1-1)) or applied the function SetName
(see SetName
(Reference: Name)) to the group, the generic
name "[grp]"
is set as a default);
gpnum
if not a null string, the number
(i.e. the unique label assigned by the pq
program) of the last descendant processed;
class
the largest lower exponent-\(p\) central class of a quotient group of the group (usually group
) found by a call to the pq
program;
forder
the factored order of the quotient group of largest lower exponent-\(p\) central class found for the group (usually group
) by a call to the pq
program (this factored order is given as a list [p,n]
, indicating an order of \(p^n\));
pcoverclass
the lower exponent-\(p\) central class of the \(p\)-covering group of a \(p\)-quotient of the group (usually group
) found by a call to the pq
program;
workspace
the workspace set for the pq
process (either given as a second argument to PqStart
, or set by default to 10000000);
menu
the current menu of the pq
process (the pq
program is managed by various menus, the details of which the user shouldn't normally need to know about -- the menu
field remembers which menu the pq
process is currently in
);
outfname
is the file to which pq
output is directed, which is always ANUPQData.outfile
, except when option SetupFile
is used with a non-interactive function, in which case outfname
is set to "PQ_OUTPUT"
;
pQuotient
is set to the value returned by Pq
(see Pq
(4.1-1)) (the field pQepi
is also set at the same time);
pQepi
is set to the value returned by PqEpimorphism
(see PqEpimorphism
(4.1-2)) (the field pQuotient
is also set at the same time);
pCover
is set to the value returned by PqPCover
(see PqPCover
(4.1-3));
SP
is set to the value returned by PqStandardPresentation
or StandardPresentation
(see PqStandardPresentation
(5.3-4)) when called interactively, for process i (the field SPepi
is also set at the same time);
SPepi
is set to the value returned by EpimorphismPqStandardPresentation
or EpimorphismStandardPresentation
(see EpimorphismPqStandardPresentation
(5.3-5)) when called interactively, for process i (the field SP
is also set at the same time);
descendants
is set to the value returned by PqDescendants
(see PqDescendants
(4.4-1));
treepos
if set by a call to PqDescendantsTreeCoclassOne
(see PqDescendantsTreeCoclassOne
(A.4-1)), it contains a record with fields class
, node
and ndes
being the information that determines the last descendant with a non-zero number of descendants processed;
xgapsheet
if set by a call to PqDescendantsTreeCoclassOne
(see PqDescendantsTreeCoclassOne
(A.4-1)) during an XGAP session, it contains the XGAP Sheet
on which the descendants tree is displayed; and
nextX
if set by a call to PqDescendantsTreeCoclassOne
(see PqDescendantsTreeCoclassOne
(A.4-1)) during an XGAP session, it contains a list of integers, the ith entry of which is the x-coordinate of the next node (representing a descendant) for the ith class.
‣ ANUPQDirectoryTemporary ( dir ) | ( function ) |
calls the UNIX command mkdir
to create dir, which must be a string, and if successful a directory object for dir is both assigned to ANUPQData.tmpdir
and returned. The field ANUPQData.outfile
is also set to be a file in ANUPQData.tmpdir
, and on exit from GAP dir is removed. Most users will never need this command; by default, GAP typically chooses a random
subdirectory of /tmp
for ANUPQData.tmpdir
which may occasionally have limits on what may be written there. ANUPQDirectoryTemporary
permits the user to choose a directory (object) where one is not so limited.
‣ InfoANUPQ | ( info class ) |
The input to and the output from the pq
program is, by default, not displayed. However the user may choose to see some, or all, of this input/output. This is done via the Info
mechanism (see Section Reference: Info Functions in the GAP Reference Manual). For this purpose, there is the InfoClass InfoANUPQ
. If the InfoLevel
of InfoANUPQ
is high enough each line of pq
input/output is directed to a call to Info
and will be displayed for the user to see. By default, the InfoLevel
of InfoANUPQ
is 1, and it is recommended that you leave it at this level, or higher. Messages that the user should presumably want to see and output from the pq
program influenced by the value of the option OutputLevel
(see the options listed in Section Pq
(4.1-1)), other than timing and memory usage are directed to Info
at InfoANUPQ
level 1.
To turn off all InfoANUPQ
messaging, set the InfoANUPQ
level to 0.
There are five other user-intended InfoANUPQ
levels: 2, 3, 4, 5 and 6.
gap> SetInfoLevel(InfoANUPQ, 2);
enables the display of most timing and memory usage data from the pq
program, and also the number of identity instances when the Identities
option is used. (Some timing and memory usage data, particularly when profuse in quantity, is Info
-ed at InfoANUPQ
level 3 instead.) Note that the the GAP functions time
and Runtime
(see Runtime
(Reference: Runtime) in the GAP Reference Manual) count the time spent by GAP and not the time spent by the (external) pq
program.
gap> SetInfoLevel(InfoANUPQ, 3);
enables the display of output of the nature of the first two InfoANUPQ
that was not directly invoked by the user (e.g. some commands require GAP to discover something about the current state known to the pq
program). The identity instances processed under the Identities
option are also displayed at this level. In some cases, the pq
program produces a lot of output despite the fact that the OutputLevel
(see 6.2) is unset or is set to 0; such output is also Info
-ed at InfoANUPQ
level 3.
gap> SetInfoLevel(InfoANUPQ, 4);
enables the display of all the commands directed to the pq
program, behind a
prompt (so that you can distinguish it from the output from the ToPQ>
pq
program). See Section Hints and Warnings regarding the use of Options for an example of how this can be a useful troubleshooting tool.
gap> SetInfoLevel(InfoANUPQ, 5);
enables the display of the pq
program's prompts for input. Finally,
gap> SetInfoLevel(InfoANUPQ, 6);
enables the display of all other output from the pq
program, namely the banner and menus. However, the timing data printed when the pq
program exits can never be observed.
‣ PqLeftNormComm ( elts ) | ( function ) |
returns for a list of elements of some group (e.g. elts may be a list of words in the generators of a free or fp group) the left normed commutator of elts, e.g. if w1, w2, w3 are such elements then PqLeftNormComm( [w1, w2, w3] );
is equivalent to Comm( Comm( w1, w2 ), w3 );
.
Note: elts must contain at least two elements.
‣ PqGAPRelators ( group, rels ) | ( function ) |
returns a list of words that GAP understands, given a list rels of strings in the string representations of the generators of the fp group group prepared as a list of relators for the pq
program.
Note: The pq
program does not use /
to indicate multiplication by an inverse and uses square brackets to represent (left normed) commutators. Also, even though the pq
program accepts relations, all elements of rels must be in relator form, i.e. a relation of form w1 = w2
must be written as w1*(w2)^-1
.
Here is an example:
gap> F := FreeGroup("a", "b"); <free group on the generators [ a, b ]> gap> PqGAPRelators(F, [ "a*b^2", "[a,b]^2*a", "([a,b,a,b,b]*a*b)^2*a" ]); [ a*b^2, a^-1*b^-1*a*b*a^-1*b^-1*a*b*a, b^-1*a^-1*b^-1*a^-1*b*a*b^-1*a*b*a^ -1*b*a^-1*b^-1*a*b*a*b^-1*a^-1*b^-1*a^-1*b*a*b^-1*a*b^-1*a^-1*b*a^-1*b^ -1*a*b*a*b*a^-1*b*a*b^-1*a*b*a^-1*b*a^-1*b^-1*a*b*a*b^-1*a^-1*b^-1*a^ -1*b*a*b^-1*a*b^-1*a^-1*b*a^-1*b^-1*a*b*a*b^2*a*b*a ]
‣ PqParseWord ( word, n ) | ( function ) |
parses a word, a string representing a word in the pc generators x1,...,xn
, through GAP. This function is provided as a rough-and-ready check of word for syntax errors. A syntax error will cause the entering of a break
-loop, in which the error message may or may not be meaningful (depending on whether the syntax error gets caught at the GAP or kernel level).
Note: The reason the generators must be x1,...,xn
is that these are the pc generator names used by the pq
program (as distinct from the generator names for the group provided by the user to a function like Pq
that invokes the pq
program).
‣ PqExample ( ) | ( function ) |
‣ PqExample ( example[, PqStart][, Display] ) | ( function ) |
‣ PqExample ( example[, PqStart][, filename] ) | ( function ) |
With no arguments, or with single argument "index"
, or a string example that is not the name of a file in the examples
directory, an index of available examples is displayed.
With just the one argument example that is the name of a file in the examples
directory, the example contained in that file is executed in its simplest form. Some examples accept options which you may use to modify some of the options used in the commands of the example. To find out which options an example accepts, use one of the mechanisms for displaying the example described below.
Some examples have both non-interactive and interactive forms; those that are non-interactive only have a name ending in -ni
; those that are interactive only have a name ending in -i
; examples with names ending in .g
also have only one form; all other examples have both non-interactive and interactive forms and for these giving PqStart
as second argument invokes PqStart
initially and makes the appropriate adjustments so that the example is executed or displayed using interactive functions.
If PqExample
is called with last (second or third) argument Display
then the example is displayed without being executed. If the last argument is a non-empty string filename then the example is also displayed without being executed but is also written to a file with that name. Passing an empty string as last argument has the same effect as passing Display
.
Note: The variables used in PqExample
are local to the running of PqExample
, so there's no danger of having some of your variables over-written. However, they are not completely lost either. They are saved to a record ANUPQData.examples.vars
, i.e. if F
is a variable used in the example then you will be able to access it after PqExample
has finished as ANUPQData.examples.vars.F
.
‣ AllPqExamples ( ) | ( function ) |
returns a list of all currently available examples in default UNIX-listing (i.e. alphabetic) order.
‣ GrepPqExamples ( string ) | ( function ) |
runs the UNIX command grep string
over the ANUPQ examples and returns the list of examples for which there is a match. The actual matches are Info
-ed at InfoANUPQ
level 2.
‣ ToPQLog ( [filename] ) | ( function ) |
With string argument filename, ToPQLog
opens the file with name filename for logging; all commands written to the pq
binary (that are Info
-ed behind a
prompt at ToPQ>
InfoANUPQ
level 4) are then also written to that file (but without prompts). With no argument, ToPQLog
stops logging to whatever file was being logged to. If a file was already being logged to, that file is closed and the file with name filename is opened for logging.
‣ NuclearRank ( G ) | ( attribute ) |
‣ MultiplicatorRank ( G ) | ( attribute ) |
‣ IsCapable ( G ) | ( property ) |
return the nuclear rank of G, \(p\)-multiplicator rank of G, and whether G is capable (i.e. true
if it is, or false
if it is not), respectively.
These attributes and property are set automatically if G is one of the following:
an fp group returned by PqStandardPresentation
or StandardPresentation
(see PqStandardPresentation
(4.2-1));
the image (fp group) of the epimorphism returned by an EpimorphismPqStandardPresentation
or EpimorphismStandardPresentation
call (see EpimorphismPqStandardPresentation
(4.2-2)); or
one of the pc groups of the list of descendants returned by PqDescendants
(see PqDescendants
(4.4-1)).
If G is an fp group or a pc \(p\)-group and not one of the above and the attribute or property has not otherwise been set for G, then PqStandardPresentation
is called to set all three of NuclearRank
, MultiplicatorRank
and IsCapable
, before returning the value of the attribute or property actually called. Such a group G must know in advance that it is a \(p\)-group; this is the case for the groups returned by the functions Pq
and PqPCover
, and the image group of the epimorphism returned by PqEpimorphism
. Otherwise, if you know the group to be a \(p\)-group, then this can be set by typing
SetIsPGroup( G, true );
or by invoking IsPGroup( G )
. Note that for an fp group G, the latter may result in a coset enumeration which might not terminate in a reasonable time.
Note: For G such that HasNuclearRank(G) = true
, IsCapable(G)
is equivalent to (the truth or falsity of) NuclearRank( G ) = 0
.
On a first reading we recommend you skip this section and come back to it if and when you run into trouble.
Note: By options
we refer to GAP options. The pq
program also uses the term option
; to distinguish the two usages of option
, in this manual we use the term menu item to refer to what the pq
program refers to as an option
.
Options are passed to the ANUPQ interface functions in either of the two usual mechanisms provided by GAP, namely:
options may be set globally using the function PushOptions
(see Chapter Reference: Options Stack in the GAP Reference Manual); or
options may be appended to the argument list of any function call, separated by a colon from the argument list (see Chapter Reference: Function Calls in the GAP Reference Manual), in which case they are then passed on recursively to any subsequent inner function call, which may in turn have options of their own.
Particularly, when one is using the interactive functions of Chapter Interactive ANUPQ functions, one should, in general, avoid using the global method of passing options. In fact, it is recommended that prior to calling PqStart
the OptionsStack
be empty. The essential problem with setting options globally using the function PushOptions
is that options pushed onto OptionsStack
, in this way, (generally) remain there until an explicit PopOptions()
call is made.
In contrast, options passed in the usual way behind a colon following a function's arguments (see Reference: Function Call With Options in the GAP Reference Manual) are local, and disappear from OptionsStack
after the function has executed successfully. If the function does not execute successfully, i.e. it runs into error and the user quit
s the resulting break
loop (see Section Reference: Break Loops in the Reference Manual) rather than attempting to repair the problem and typing return;
then, unless the error at the kernel level, the OptionsStack
is reset. If an error is detected inside the kernel (hopefully, this should occur only rarely, if at all) then the options of that function will not be cleared from OptionsStack
; in such cases:
gap> ResetOptionsStack(); #I Options stack is already empty
is usually necessary (see Chapter ResetOptionsStack
(Reference: ResetOptionsStack) in the GAP Reference Manual), which recursively calls PopOptions()
until OptionsStack
is empty, or as in the above case warns you that the OptionsStack
is already empty.
Note that a function, that is passed options after the colon, will also see any global options or any options passed down recursively from functions calling that function, unless those options are over-ridden by options passed via the function. Also, note that duplication of option names for different programs may lead to misinterpretations, and mis-spelled options will not be seen
.
The non-interactive functions of Chapter Non-interactive ANUPQ functions that have Pq
somewhere in their name provide an alternative method of passing options as additional arguments. This has the advantages that options can be abbreviated and mis-spelled options will be trapped.
‣ ANUPQWarnOfOtherOptions | ( global variable ) |
is a global variable that is by default false
. If it is set to true
then any function provided by the ANUPQ function that recognises at least one option, will warn you of other
options, i.e. options that the function does not recognise. These warnings are emitted at InfoWarning
or InfoANUPQ
level 1. This is useful for detecting mis-spelled options. Here is an example using the function Pq
(first described in Chapter Non-interactive ANUPQ functions):
gap> SetInfoLevel(InfoANUPQ, 1); # Set InfoANUPQ to default level gap> ANUPQWarnOfOtherOptions := true;; gap> # The following makes entry into break loops very ``quiet'' ... gap> OnBreak := function() Where(0); end;; gap> F := FreeGroup( "a", "b" ); <free group on the generators [ a, b ]> gap> Pq( F : Prime := 2, Classbound := 1 ); #I ANUPQ Warning: Options: [ "Classbound" ] ignored #I (invalid for generic function: `Pq'). user interrupt at moreOfline := ReadLine( iostream ); Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue
Here we mistyped ClassBound
as Classbound
, and after seeing the Info
-ed warning that Classbound
was ignored, we typed a control-C (that's the
message) which took us into a break loop. Since the user interrupt at
Pq
command was not able to finish, the options Prime
and Classbound
, in particular, will still be on the OptionsStack
:
brk> OptionsStack; [ rec( Prime := 2, Classbound := 1 ), rec( Prime := 2, Classbound := 1, PqEpiOrPCover := "pQuotient" ) ]
The option PqEpiOrPCover
is a behind-the-scenes option that need not concern the user. On quit
ting the break
-loop the OptionsStack
is reset and a warning telling you this is emitted:
brk> quit; # to get back to the `gap>' prompt #I Options stack has been reset
Above, we altered OnBreak
(see OnBreak
(Reference: OnBreak) in the Reference manual) to reduce the back-tracing on entry into a break loop. We now restore OnBreak
to its usual value.
gap> OnBreak := Where;;
Notes
In cases where functions recursively call others with options (e.g. when using PqExample
with options), setting ANUPQWarnOfOtherOptions := true
may give rise to spurious other
option detections.
It is recommended that the novice user set ANUPQWarnOfOtherOptions
to true
in their gap.ini
file (see Section Loading the ANUPQ Package).
Other Troubleshooting Strategies
There are some other strategies which may have helped us to see our error above. The function Pq
recognises the option OutputLevel
(see 6.2); if this option is set to at least 1, the pq
program provides information on each class quotient as it is generated:
gap> ANUPQWarnOfOtherOptions := false;; # Set back to normal gap> F := FreeGroup( "a", "b" );; gap> Pq( F : Prime := 2, Classbound := 1, OutputLevel := 1 ); #I Lower exponent-2 central series for [grp] #I Group: [grp] to lower exponent-2 central class 1 has order 2^2 #I Group: [grp] to lower exponent-2 central class 2 has order 2^5 #I Group: [grp] to lower exponent-2 central class 3 has order 2^10 #I Group: [grp] to lower exponent-2 central class 4 has order 2^18 #I Group: [grp] to lower exponent-2 central class 5 has order 2^32 #I Group: [grp] to lower exponent-2 central class 6 has order 2^55 #I Group: [grp] to lower exponent-2 central class 7 has order 2^96 #I Group: [grp] to lower exponent-2 central class 8 has order 2^167 #I Group: [grp] to lower exponent-2 central class 9 has order 2^294 #I Group: [grp] to lower exponent-2 central class 10 has order 2^520 #I Group: [grp] to lower exponent-2 central class 11 has order 2^932 #I Group: [grp] to lower exponent-2 central class 12 has order 2^1679 [... output truncated ...]
After seeing the information for the class 2 quotient we may have got the idea that the Classbound
option was not recognised and may have realised that this was due to a mis-spelling. The above will ordinarily cause the available space to be exhausted, necessitating user-intervention by typing control-C and quit;
(to escape the break loop); otherwise Pq
terminates when the class reaches 63 (the default value of ClassBound
).
If you have some familiarity with keyword
command input to the pq
binary, then setting the level of InfoANUPQ
to 4 would also have indicated a problem:
gap> ResetOptionsStack(); # Necessary, if a break-loop was entered above gap> SetInfoLevel(InfoANUPQ, 4); gap> Pq( F : Prime := 2, Classbound := 1 ); #I ToPQ> 7 #to (Main) p-Quotient Menu #I ToPQ> 1 #define group #I ToPQ> name [grp] #I ToPQ> prime 2 #I ToPQ> class 63 #I ToPQ> exponent 0 #I ToPQ> output 0 #I ToPQ> generators { a,b } #I ToPQ> relators { }; [... output truncated ...]
Here the line
indicates that a directive to set the classbound to 63 was sent to the #I ToPQ> class 63
pq
program.
generated by GAPDoc2HTML