%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %W interact.tex ACE documentation - interactive fns Joachim Neub"user %W Greg Gamble %% %H $Id: interact.tex,v 1.29 2006/01/26 16:15:05 gap Exp $ %% %Y Copyright (C) 2000 Centre for Discrete Mathematics and Computing %Y Department of Information Tech. & Electrical Eng. %Y University of Queensland, Australia. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Chapter{Functions for Using ACE Interactively} The user will probably benefit most from interactive use of {\ACE} by setting the `InfoLevel' of `InfoACE' to at least 3 (see~"SetInfoACELevel"), particularly if she uses the `messages' option with a non-zero value. Have you read the various options warnings yet? If not, please take the time to read Section~"General Warnings regarding the Use of Options" which directs you to various important sections of Chapter~"Options for ACE". We describe in this chapter the functions that manipulate and initiate interactive {\ACE} processes. An interactive {\ACE} process is initiated by `ACEStart' and terminated via `ACEQuit'; these functions are described in Section~"Starting and Stopping Interactive ACE Processes". `ACEStart' also has forms that manipulate an already started interactive {\ACE} process. `ACEStart' always returns a positive integer <i>, which identifies the interactive {\ACE} process that was initiated or manipulated. Most functions (there is one `ACEStart' exception), that manipulate an already started interactive {\ACE} process, have a form where the first argument is the integer <i> returned by the initiating `ACEStart' command, and a second form with one argument fewer (where the integer <i> is discovered by a default mechanism, namely by determining the least integer <i> for which there is a currently active interactive {\ACE} process). We will thus commonly say that ``for the <i>th (or default) interactive {ACE} process'' a certain function performs a given action. In each case, it is an error, if <i> is not the index of an active interactive process, or there are no current active interactive processes. *Notes*: The global method of passing options (via `PushOptions'), should not be used with any of the interactive functions. In fact, the `OptionsStack' should be empty at the time any of the interactive functions is called. On `quit'ting {\GAP}, `ACEQuitAll();' is executed, which terminates all active interactive {\ACE} processes. If {\GAP} is killed without `quit'ting, before all interactive {\ACE} processes are terminated, *zombie* processes (still living *child* processes whose *parents* have died), will result. Since zombie processes do consume resources, in such an event, the responsible computer user should seek out and kill the still living `ace' children (e.g.~by piping the output of a `ps' with appropriate options, usually `aux' or `ef', to `grep ace', to find the process ids, and then using `kill'; try `man ps' and `man kill' if these hints are unhelpful). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Starting and Stopping Interactive ACE Processes} \>ACEStart( <fgens>, <rels>, <sgens> [:<options>] )!{details} F \>ACEStart( <i> [:<options>] ) F \>ACEStart( [:<options>] ) F \>ACEStart( <i>, <fgens>, <rels>, <sgens> [:<options>] ) F \>ACEStart( 0 [:<options>] ) F \>ACEStart( 0, <fgens>, <rels>, <sgens> [:<options>] ) F \>ACEStart( 0, <i> [:<options>] ) F \>ACEStart( 0, <i>, <fgens>, <rels>, <sgens> [:<options>] ) F The variables are: <i>, a positive integer numbering from 1 that represents (indexes) an already running interactive {\ACE} process; <fgens>, a list of free generators; <rels>, a list of words in the generators <fgens> giving relators for a finitely presented group; and <sgens>, a list of subgroup generators, again expressed as words in the free generators <fgens>. Each of <fgens>, <rels> and <sgens> are given in the standard {\GAP} format for finitely presented groups (See Chapter~"ref:Finitely Presented Groups" of the {\GAP} Reference Manual). All forms of `ACEStart' accept options described in Chapters~"Options for ACE" and~"Strategy Options for ACE", and Appendix~"Other ACE Options", which are listed behind a colon in the usual way (see "ref:Function Calls" in the {\GAP} Reference Manual). The reader is strongly encouraged to read the introductory sections of Chapter~"Options for ACE", with regard to options. The global mechanism (via `PushOptions') of passing options is *not* recommended for use with the interactive {\ACE} interface functions; please ensure the `OptionsStack' is empty before calling an interactive {\ACE} interface function. The return value (for all forms of `ACEStart') is an integer (numbering from 1) which represents the running process. It is possible to have more than one interactive process running at once. The integer returned may be used to index which of these processes an interactive {\ACE} interface function should be applied to. The first four forms of `ACEStart' insert a `start' (see~"option start") directive after the user's options to invoke an enumeration. The last four forms, with `0' as first argument, do not insert a `start' directive. Moreover, the last 3 forms of `ACEStart', with `0' as first argument only differ from the corresponding forms of `ACEStart' without the `0' argument, in that they do not insert a `start' directive. `ACEStart(0)', however, is special; unlike the no-argument form of `ACEStart' it invokes a new interactive {\ACE} process. We will now further describe each form of `ACEStart', in the order they appear above. The first form of `ACEStart' (on three arguments) is the usual way to start an interactive {\ACE} process. When `ACEStart' is called with one positive integer argument <i> it starts a new enumeration on the <i>th running process, i.e.~it scrubs a previously generated table and starts from scratch with the same parameters (i.e.~the same arguments and options); except that if new options are included these will modify those given previously. The only reason for doing such a thing, without new options, is to perhaps compare timings of runs (a second run is quicker because memory has already been allocated). If you are interested in this sort of information, however, you may be better off dealing directly with the standalone. When `ACEStart' is called with no arguments it finds the least positive integer <i> for which an interactive process is running and applies `ACEStart(<i>)'. (Most users will only run one interactive process at a time. Hence, `ACEStart()' will be a useful shortcut for `ACEStart(1)'.) The fourth form of `ACEStart' on four arguments, invokes a new enumeration on the <i>th running process, with new generators <fgens>, relators <rels> and subgroup generators <sgens>. This is provided so a user can re-use an already running process, rather than start a new process. This may be useful when pseudo-ttys are a scarce resource. See the notes for the non-interactive `ACECosetTable' ("ACECosetTableFromGensAndRels") which demonstrates an application of a usage of this and the following form of `ACEStart' in a loop. The fifth form of `ACEStart' (on the one argument: `0') initiates an interactive {\ACE} process, processes any user options, but does not insert a `start' (see~"option start") directive. This form is mainly for gurus who are familiar with the {\ACE} standalone and who wish, at least initially, to communicate with {\ACE} using the primitive read/write tools of Section~"Primitive ACE Read/Write Functions". In this case, after the group generators, relators, and subgroup generators have been set in the {\ACE} process, invocations of any of `ACEGroupGenerators' (see~"ACEGroupGenerators"), `ACERelators' (see~"ACERelators"), `ACESubgroupGenerators' (see~"ACESubgroupGenerators"), or `ACEParameters' (see~"ACEParameters") will establish the corresponding {\GAP} values. Be warned, though, that unless one of the general {\ACE} modes (see Section~"General ACE modes"): `ACEStart' (without a zero argument), `ACERedo' (see~"ACERedo") or `ACEContinue' (see~"ACEContinue"), or one of the mode options: `start' (see~"option start"), `redo' (see~"option redo") or `continu' (see~"option continu"), has been invoked since the last change of any parameter options (see~"ACEParameterOptions"), some of the values reported by `ACEParameters' may well be *incorrect*. The sixth form of `ACEStart' (on four arguments), is like the first form of `ACEStart' (on three arguments), except that it does not insert a `start' (see~"option start") directive. It initiates an interactive {\ACE} process, with a presentation defined by its last 3 arguments. The seventh form of `ACEStart' (on two arguments), is like the second form of `ACEStart' (on one argument), except that it does not insert a `start' (see~"option start") directive. It processes any new options for the <i>th interactive {\ACE} process. `ACEStart(0, <i> [: <options> ] )', is similar to `SetACEOptions(<i> [: <options> ] )' (see~"SetACEOptions"), but unlike the latter does not invoke a general mode (see Section~"General ACE Modes"). The last form of `ACEStart' (on five arguments), is like the fourth form of `ACEStart' (on four arguments), except that it does not insert a `start' (see~"option start") directive. It re-uses an existing interactive {\ACE} process, with a new presentation. There is no form of `ACEStart' with the same functionality as this form, where the <i> argument is omitted. *Note:* When an interactive {\ACE} process is initiated by `ACEStart' a process number <i> is assigned to it (the integer <i> returned by the `ACEStart' command), an {\ACE} (binary) process (in the UNIX sense) is started up, a {\GAP} iostream is assigned to communicate with the {\ACE} (binary) process, and the essential ``defining'' data associated with the interactive {\ACE} process is saved in `ACEData.io[<i>]' (see~"ACEData" for precisely what is saved). \>ACEQuit( <i> )!{details} F \>ACEQuit() F terminate an interactive {\ACE} process, where <i> is the integer returned by `ACEStart' when the process was started. If the second form is used (i.e.~without arguments) then the interactive process of least index that is still running is terminated. *Note:* `ACEQuit(<i>)' terminates the {\ACE} (binary) process of interactive {\ACE} process <i>, and closes its {\GAP} iostream, and unbinds the record `ACEData.io[<i>]' (see~"ACEStart" note). It can happen that the {\ACE} (binary) process, and hence the {\GAP} iostream assigned to communicate with it, can die, e.g.~by the user typing a `Ctrl-C' while the {\ACE} (binary) process is engaged in a long calculation. `IsACEProcessAlive' (see~"IsACEProcessAlive") is provided to check the status of the {\GAP} iostream (and hence the status of the {\ACE} (binary) process it was communicating with); in the case that it is indeed dead, `ACEResurrectProcess' (see~"ACEResurrectProcess") may be used to start a new {\ACE} (binary) process and assign a new {\GAP} iostream to communicate with it, by using the ``defining'' data of the interactive {\ACE} process saved in `ACEData.io[<i>]'. \>ACEQuitAll() F is provided as a convenience, to terminate all active interactive {\ACE} processes with a single command. It is equivalent to executing `ACEQuit(<i>)' for all active interactive {\ACE} processes <i> (see~"ACEQuit"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{General ACE Modes} For our purposes, we define an interactive {\ACE} interface command to be an {\ACE} mode, if it delivers an enumeration result (see Section~"Results messages"). Thus, `ACEStart' (see~"ACEStart"), except when called with the argument 0, and the commands `ACERedo' and `ACEContinue' which we describe below are {\ACE} modes; we call these *general {\ACE} modes*. Additionally, there are two other commands which deliver enumeration results: `ACEAllEquivPresentations' (see~"ACEAllEquivPresentations") and `ACERandomEquivPresentations' (see~"ACERandomEquivPresentations"); we call these ``experimentation'' {\ACE} modes and describe them in Section~"Experimentation ACE Modes". *Guru Note:* The {\ACE} standalone uses the term `mode' in a slightly different sense. There, the commands: `start', `redo' or `continue', put the {\ACE} enumerator in `start mode', `redo mode' or `continue mode'. In this manual, we have used the term to mean the command itself, and generalised it to include any command that produces enumeration results. After changing any of {\ACE}'s parameters, one of three *general modes* is possible: one may be able to ``continue'' via `ACEContinue' (see~"ACEContinue"), or ``redo'' via `ACERedo' (see~"ACERedo"), or if neither of these is possible one may have to re-``start'' the enumeration via `ACEStart' (see~"ACEStart"). Generally, the appropriate mode is invoked automatically when options are changed; so most users should be able to ignore the following three functions. \>ACEModes( <i> ) F \>ACEModes() F for the <i>th (or default) interactive {\ACE} process, return a record whose fields are the modes `ACEStart', `ACEContinue' and `ACERedo', and whose values are `true' if the mode is possible for the process and `false' otherwise. \>ACEContinue( <i> [:<options>] ) F \>ACEContinue( [:<options>] ) F for the <i>th (or default) interactive {\ACE} process, apply any <options> and then ``continue'' the current enumeration, building upon the existing table. If a previous run stopped without producing a finite index you can, in principle, change any of the options and continue on. Of course, if you make any changes which invalidate the current table, you won't be allowed to `ACEContinue' and an error will be raised. However, after `quit'ting the `break'-loop, the interactive {\ACE} process should normally still be active; after doing so, run `ACEModes' (see~"ACEModes") to see which of `ACERedo' or `ACEStart' is possible. \>ACERedo( <i> [:<options>] ) F \>ACERedo( [:<options>] ) F for the <i>th (or default) interactive {\ACE} process, apply any <options> and then ``redo'' the current enumeration from coset 1 (i.e., the subgroup), keeping any existing information in the table. *Notes:* The difference between `ACEContinue' and `ACERedo' is somewhat technical, and the user should regard it as a mode that is a little more expensive than `ACEContinue' but cheaper than `ACEStart'. `ACERedo' is really intended for the case where additional relators and/or subgroup generators have been introduced; the current table, which may be incomplete or exhibit a finite index, is still ``valid''. However, the new data may allow the enumeration to complete, or cause a collapse to a smaller index. In some cases, `ACERedo' may not be possible and an error will be raised; in this case, `quit' the `break'-loop, and try `ACEStart', which will discard the current table and re-``start'' the enumeration. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Interactive ACE Process Utility Functions and Interruption of an Interactive ACE Process} \>ACEProcessIndex( <i> ) F \>ACEProcessIndex() F With argument <i>, which must be a positive integer, `ACEProcessIndex' returns <i> if it corresponds to an active interactive process, or raises an error. With no arguments it returns the default active interactive process or returns `fail' and emits a warning message to `Info' at `InfoACE' or `InfoWarning' level 1. *Note:* Essentially, an interactive {\ACE} process <i> is ``active'' if `ACEData.io[<i>]' is bound (i.e.~we still have some data telling us about it). Also see~"ACEStart" note. \>ACEProcessIndices() F returns the list of integer indices of all active interactive {\ACE} processes (see~"ACEProcessIndex" for the meaning of ``active''). \>IsACEProcessAlive( <i> ) F \>IsACEProcessAlive() F return `true' if the {\GAP} iostream of the <i>th (or default) interactive {\ACE} process started by `ACEStart' is alive (i.e.~can still be written to), or `false', otherwise. (See the notes for~"ACEStart" and~"ACEQuit".) \atindex{interruption}{@interruption of an interactive ACE process} \atindex{break-loop}{@\noexpand`break'-loop} If the user does not yet have a `gap>' prompt then usually {\ACE} is still away doing something and an {\ACE} interface function is still waiting for a reply from {\ACE}. Typing a `Ctrl-C' (i.e.~holding down the `Ctrl' key and typing `c') will stop the waiting and send {\GAP} into a `break'-loop, from which one has no option but to `quit;'. The typing of `Ctrl-C', in such a circumstance, usually causes the stream of the interactive {\ACE} process to die; to check this we provide `IsACEProcessAlive' (see~"IsACEProcessAlive"). If the stream of an interactive {\ACE} process, indexed by <i>, say, has died, it may still be possible to recover enough of the state, before the death of the stream, from the information stored in the `ACEData.io[<i>]' record (see Section~"The ACEData Record"). For such a purpose, we have provided `ACEResurrectProcess' (see~"ACEResurrectProcess"). The {\GAP} iostream of an interactive {\ACE} process will also die if the {\ACE} binary has a segmentation fault. We do hope that this never happens to you, but if it does and the failure is reproducible, then it's a bug and we'd like to know about it. Please read the `README' that comes with the {\ACE} package to find out what to include in a bug report and who to email it to. \>ACEResurrectProcess( <i> [: <options>] ) F \>ACEResurrectProcess( [: <options>] ) F re-generate the {\GAP} iostream of the <i>th (or default) interactive {\ACE} process started by `ACEStart' (see~"ACEStart", the final note, in particular), and try to recover as much as possible of the previous state from saved values of the process's arguments and parameter options. The possible <options> here are `use' and `useboth' which are described in detail below. The arguments of the <i>th interactive {\ACE} process are stored in `ACEData.io[<i>].args', a record with fields `fgens', `rels' and `sgens', which are the {\GAP} group generators, relators and subgroup generators, respectively (see Section~"The ACEData Record"). Option information is saved in `ACEData.io[<i>].options' when a user uses an interactive {\ACE} interface function with options or uses `SetACEOptions' (see~"SetACEOptions"). Option information is saved in `ACEData.io[<i>].parameters' if `ACEParameters' (see~"ACEParameters") is used to extract from {\ACE} the current values of the {\ACE} parameter options (this is generally less reliable unless one of the general {\ACE} modes (see Section~"General ACE Modes"), has been run previously). By default, `ACEResurrectProcess' recovers parameter option information from `ACEData.io[<i>].options' if it is bound, or from `ACEData.io[<i>].parameters' if it is bound, otherwise. The `ACEData.io[<i>].options' record, however, is first filtered for parameter and strategy options (see Sections~"ACEParameterOptions" and~"The ACEStrategyOptions list") and the `echo' option (see~"option echo"). To alter this behaviour, the user is provided two options: \beginitems \quad`use := <useList>'& <useList> may contain one or both of `"options"' and `"parameters"'. By default, `use = ["options", "parameters"]'. \quad`useboth' & (A boolean option). By default, `useboth = false'. \enditems If `useboth = true', `SetACEOptions' (see~"SetACEOptions") is applied to the <i>th interactive {\ACE} process with each `ACEData.io[<i>].(<field>)' for each <field> (`"options"' or `"parameters"') that is bound and in <useList>, in the order implied by <useList>. If `useboth = false', `SetACEOptions' is applied with `ACEData.io[<i>].(<field>)' for only the first <field> that is bound in <useList>. The current value of the `echo' option is also preserved (no matter what values the user chooses for the `use' and `useboth' options). *Notes:* Do not use general {\ACE} options with `ACEResurrectProcess'; they will only be superseded by those options recovered from `ACEData.io[<i>].options' and/or `ACEData.io[<i>].parameters'. Instead, call `SetACEOptions' first (or afterwards). When called prior to `ACEResurrectProcess', `SetACEOptions' will emit a warning that the stream is dead; despite this, the `ACEData.io[<i>].options' *will* be updated. `ACEResurrectProcess' does *not* invoke an {\ACE} mode (see Section~"General ACE Modes"). This leaves the user free to use `SetACEOptions' (which does invoke an {\ACE} mode) to further modify options afterwards. \>ToACEGroupGenerators( <fgens> ) F This function produces, from a {\GAP} list <fgens> of free group generators, the {\ACE} directive string required by the `group' (see~"option group") option. (The `group' option may be used to define the equivalent of <fgens> in an {\ACE} process.) \>ToACEWords( <fgens>, <words> ) F This function produces, from a {\GAP} list <words> in free group generators <fgens>, a string that represents those <words> as an {\ACE} list of words. `ToACEWords' may be used to provide suitable values for the options `relators' (see~"option relators"), `generators' (see~"option generators"), `sg' (see~"option sg"), and `rl' (see~"option rl"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Experimentation ACE Modes} Now we describe the two *experimentation modes*. The term *mode* was defined in Section~"General ACE Modes". \>ACEAllEquivPresentations( <i>, <val> ) F \>ACEAllEquivPresentations( <val> ) F for the <i>th (or default) interactive {\ACE} process, generates and tests an enumeration for combinations of relator ordering, relator rotations, and relator inversions; <val> is in the integer range 1 to 7. The argument <val> is considered as a binary number. Its three bits are treated as flags, and control relator rotations (the $2^0$ bit), relator inversions (the $2^1$ bit) and relator orderings (the $2^2$ bit), respectively; where $1$ means ``active'' and $0$ means ``inactive''. (See below for an example). Before we describe the {\GAP} output of `ACEAllEquivPresentations' let us spend some time considering what happens before the {\ACE} binary output is parsed. The `ACEAllEquivPresentations' command first performs a ``priming run'' using the options as they stand. In particular, the `asis' and `messages' options are honoured. It then turns `asis' (see~"option asis") on and `messages' (see~"option messages") off (i.e.~sets `messages' to 0), and generates and tests the requested equivalent presentations. The maximum and minimum values attained by `m' (the maximum number of coset numbers defined at any stage) and `t' (the total number of coset numbers defined) are tracked, and each time the statistics are better than what we've already seen, the {\ACE} binary emits a summary result line for the relators used. See Appendix~"The Meanings of ACE's output messages" for a discussion of the statistics `m' and `t'. To observe these messages set the `InfoLevel' of `InfoACE' to 3; and it's *recommended* that you do this so that you get some idea of what the {\ACE} binary is doing. The order in which the equivalent presentations are generated and tested has no particular significance, but note that the presentation as given *after* the initial priming run) is the *last* presentation to be generated and tested, so that the group's relators are left ``unchanged'' by running the `ACEAllEquivPresentations' command. As discussed by Cannon, Dimino, Havas and Watson \cite{CDHW73} and Havas and Ramsay \cite{HR01} such equivalent presentations can yield large variations in the number of coset numbers required in an enumeration. For this command, we are interested in this variation. After the final presentation is run, some additional status information messages are printed to the {\ACE} output: \beginlist%unordered \item{--} the number of runs which yielded a finite index; \item{--} the total number of runs (excluding the priming run); and \item{--} the range of values observed for `m' and `t'. \endlist As an example (drawn from the discussion in \cite{HR99a}) consider the enumeration of the $448$ coset numbers of the subgroup $\langle a^2,a^{-1}b \rangle$ of the group $$ (8,7 \mid 2,3) = \langle a,b \mid a^8 = b^7 = (ab)^2 = (a^{-1}b)^3 = 1 \rangle. $$ There are $4!=24$ relator orderings and $2^4=16$ combinations of relator or inverted relator. Exponents are taken into account when rotating relators, so the relators given give rise to 1, 1, 2 and 2 rotations respectively, for a total of $1.1.2.2=4$ combinations. So, for <val>${} = 7$ (resp.~$3$), $24.16.4=1536$ (resp.~$16.4=64$) equivalent presentations are tested. Now we describe the output of `ACEAllEquivPresentations'; it is a record with fields: \beginitems \quad`primingResult' & the {\ACE} enumeration result message (see Section~"Results Messages") of the priming run; \quad`primingStats' & the enumeration result of the priming run as a {\GAP} record with fields `index', `cputime', `cputimeUnits', `activecosets', `maxcosets' and `totcosets', exactly as for the record returned by `ACEStats' (see~"ACEStats"); \quad`equivRuns' & a list of data records, one for each progressively ``best'' run, where each record has fields: \qquad`rels'& the relators in the order used for the run, \qquad`enumResult'& the {\ACE} enumeration result message (see Section~"Results Messages") of the run, and \qquad`stats'& the enumeration result as a {\GAP} record exactly like the record returned by `ACEStats' (see~"ACEStats"); \quad`summary' & a record with fields: \qquad`successes'& the total number of successful (i.e.~having finite enumeration index) runs, \qquad`runs'& the total number of equivalent presentation runs executed, \qquad`maxcosetsRange'& the range of values as a {\GAP} list inside which each `equivRuns[<i>].maxcosets' lies, and \qquad`totcosetsRange'& the range of values as a {\GAP} list inside which each `equivRuns[<i>].totcosets' lies. \enditems *Notes:* In general, the length of the `equivRuns' field list will be less than the number of runs executed. There is no way to stop the `ACEAllEquivPresentations' command before it has completed, other than killing the task. So do a reality check beforehand on the size of the search space and the time for each enumeration. If you are interested in finding a ``good'' enumeration, it can be very helpful, in terms of running time, to put a tight limit on the number of coset numbers via the `max' option. You may also have to set `compaction' = $100$ to prevent time-wasting attempts to recover space via compaction. This maximises throughput by causing the ``bad'' enumerations, which are in the majority, to overflow quickly and abort. If you wish to explore a very large search-space, consider firing up many copies of {\ACE}, and starting each with a ``random'' equivalent presentation. Alternatively, you could use the `ACERandomEquivPresentations' command. \>ACERandomEquivPresentations( <i>, <val> ) F \>ACERandomEquivPresentations( <val> ) F \>ACERandomEquivPresentations( <i>, [<val>] ) F \>ACERandomEquivPresentations( [<val>] ) F \>ACERandomEquivPresentations( <i>, [<val>, <Npresentations>] ) F \>ACERandomEquivPresentations( [<val>, <Npresentations>] ) F for the <i>th (or default) interactive {\ACE} process, generates and tests up to <Npresentations> (or 8, in the first 4 forms) random presentations; <val>, an integer in the range 1 to 7, acts as for `ACEAllEquivPresentations' and <Npresentations>, when given, should be a positive integer. The routine first turns `asis' (see~"option asis") on and `messages' (see~"option messages") off (i.e.~sets `messages' to 0), and then generates and tests the requested number of random equivalent presentations. For each presentation, the relators used and the summary result line are printed by {\ACE}. To observe these messages set the `InfoLevel' of `InfoACE' to at least 3. `ACERandomEquivPresentations' parses the {\ACE} messages, translating them to {\GAP}, and thus returns a list of records (similar to the field `equivRuns' of the returned record of `ACEAllEquivPresentations'). Each record of the returned list is the data derived from a presentation run and has fields: \beginitems \quad`rels'& the relators in the order used for the run, \quad`enumResult'& the {\ACE} enumeration result message (see Section~"Results Messages") of the run, and \quad`stats'& the enumeration result as a {\GAP} record exactly like the record returned by `ACEStats' (see~"ACEStats"). \enditems *Notes:* The relator inversions and rotations are ``genuinely'' random. The relator permuting is a little bit of a kludge, with the ``quality'' of the permutations tending to improve with successive presentations. When the `ACERandomEquivPresentations' command completes, the presentation active is the *last* one generated. *Guru Notes:* It might appear that neglecting to restore the original presentation is an error. In fact, it is a useful feature! Suppose that the space of equivalent presentations is too large to exhaustively test. As noted in the entry for `ACEAllEquivPresentations', we can start up multiple copies of `ACEAllEquivPresentations' at random points in the search-space. Manually generating `random' equivalent presentations to serve as starting-points is tedious and error-prone. The `ACERandomEquivPresentations' command provides a simple solution; simply run `ACERandomEquivPresentations(<i>, 7);' before `ACEAllEquivPresentations(<i>, 7);'. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Interactive Query Functions and an Option Setting Function} \>ACEGroupGenerators( <i> ) F \>ACEGroupGenerators() F return the {\GAP} group generators of the <i>th (or default) interactive {\ACE} process. If no generators have been saved for the interactive {\ACE} process, possibly because the process was started via `ACEStart(0);' (see~"ACEStart"), the {\ACE} process is interrogated, and the equivalent in {\GAP} is saved and returned. Essentially, `ACEGroupGenerators(<i>)' interrogates {\ACE} and establishes `ACEData.io[<i>].args.fgens', if necessary, and returns `ACEData.io[<i>].args.fgens'. As a side-effect, if any of the remaining fields of `ACEData.io[<i>].args' or `ACEData.io[<i>].acegens' are unset, they are also set. Note that {\GAP} provides `GroupWithGenerators' (see~"ref:GroupWithGenerators" in the {\GAP} Reference Manual) to establish a free group on a given set of already-defined generators. \>ACERelators( <i> ) F \>ACERelators() F return the {\GAP} relators of the <i>th (or default) interactive {\ACE} process. If no relators have been saved for the interactive {\ACE} process, possibly because the process was started via `ACEStart(0);' (see~"ACEStart"), the {\ACE} process is interrogated, the equivalent in {\GAP} is saved and returned. Essentially, `ACERelators(<i>)' interrogates {\ACE} and establishes `ACEData.io[<i>].args.rels', if necessary, and returns `ACEData.io[<i>].args.rels'. As a side-effect, if any of the remaining fields of `ACEData.io[<i>].args' or `ACEData.io[<i>].acegens' are unset, they are also set. \>ACESubgroupGenerators( <i> ) F \>ACESubgroupGenerators() F return the {\GAP} subgroup generators of the <i>th (or default) interactive {\ACE} process. If no subgroup generators have been saved for the interactive {\ACE} process, possibly because the process was started via `ACEStart(0);' (see~"ACEStart"), the {\ACE} process is interrogated, the equivalent in {\GAP} is saved and returned. Essentially, `ACESubgroupGenerators(<i>)' interrogates {\ACE} and establishes `ACEData.io[<i>].args.sgens', if necessary, and returns `ACEData.io[<i>].args.sgens'. As a side-effect, if any of the remaining fields of `ACEData.io[<i>].args' or `ACEData.io[<i>].acegens' are unset, they are also set. \>DisplayACEArgs( <i> ) F \>DisplayACEArgs() F display the arguments (i.e.~<fgens>, <rels> and <sgens>) of the <i>th (or default) process started by `ACEStart'. In fact, `DisplayACEArgs(<i>)' is just a pretty-printer of the `ACEData.io[<i>].args' record. Use `GetACEArgs' (see~"GetACEOptions") in assignments. Unlike `ACEGroupGenerators' (see~"ACEGroupGenerators"), `ACERelators' (see~"ACERelators") and `ACESubgroupGenerators' (see~"ACESubgroupGenerators"), `DisplayACEArgs' does not have the side-effect of setting any of the fields of `ACEData.io[<i>].args' if they are unset. \>GetACEArgs( <i> ) F \>GetACEArgs() F return a record of the current arguments (i.e.~<fgens>, <rels> and <sgens>) of the <i>th (or default) process started by `ACEStart'. In fact, `GetACEOptions(<i>)' simply returns the `ACEData.io[<i>].args' record, or an empty record if that record is unbound. Unlike `ACEGroupGenerators' (see~"ACEGroupGenerators"), `ACERelators' (see~"ACERelators") and `ACESubgroupGenerators' (see~"ACESubgroupGenerators"), `GetACEOptions' does not have the side-effect of setting any of the fields of `ACEData.io[<i>].args' if they are unset. \>DisplayACEOptions( <i> ) F \>DisplayACEOptions() F display the options, explicitly set by the user, of the <i>th (or default) process started by `ACEStart'. In fact, `DisplayACEOptions(<i>)' is just a pretty-printer of the `ACEData.io[<i>].options' record. Use `GetACEOptions' (see~"GetACEOptions") in assignments. Please note that no-value {\ACE} options will appear with the assigned value `true' (see Section~"Interpretation of ACE Options" for how the {\ACE} interface functions interpret such options). *Notes:* Any options set via `ACEWrite' (see~"ACEWrite") will *not* be displayed. Also, recall that if {\ACE} is not given any options it uses the `default' strategy (see Section~"What happens if no ACE Strategy Option or if no ACE Option is passed"). To discover the various settings of the {\ACE} Parameter Options (see~"ACEParameterOptions") in vogue for the {\ACE} process, use `ACEParameters' (see~"ACEParameters"). \>GetACEOptions( <i> ) F \>GetACEOptions() F return a record of the current options (those that have been explicitly set by the user) of the <i>th (or default) process started by `ACEStart'. Please note that no-value {\ACE} options will appear with the assigned value `true' (see Section~"Interpretation of ACE Options" for how the {\ACE} interface functions interpret such options). The notes applying to `DisplayACEOptions' (see~"DisplayACEOptions") also apply here. \>SetACEOptions( <i> [:<options>] ) F \>SetACEOptions( [:<options>] ) F modify the current options of the <i>th (or default) process started by `ACEStart'. Please ensure that the `OptionsStack' is empty before calling `SetACEOptions', otherwise the options already present on the `OptionsStack' will also be ``seen''. All interactive {\ACE} interface functions that accept options, actually call an internal version of `SetACEOptions'; so, it is generally important to keep the `OptionsStack' clear while working with {\ACE} interactively. After setting the options passed, the first mode of the following: `ACEContinue' (see~"ACEContinue"), `ACERedo' (see~"ACERedo") or `ACEStart' (see~"ACEStart"), that may be applied, is automatically invoked. Since a user will sometimes have options in the form of a record (e.g.~via `GetACEOptions'), we provide a `PushOptions'-like alternative to the behind-the-colon syntax for the passing of options via `SetACEOptions': \>SetACEOptions( <i>, <optionsRec> )!{record version} F \>SetACEOptions( <optionsRec> )!{record version} F In this form, the record <optionsRec> is used to update the current options of the <i>th (or default) process started by `ACEStart'. Note that since <optionsRec> is a record each field must have an assigned value; in particular, no-value {\ACE} options should be assigned the value `true' (see Section~"Interpretation of ACE Options"). Please don't mix these two forms of `SetACEOptions' with the previous two forms; i.e.~do *not* pass both a record argument and options, since this will lead to options appearing in the wrong order; if you want to do this, make two separate calls to `SetACEOptions', e.g.~let's say you have a process like that started by: \beginexample gap> ACEExample("A5", ACEStart); \endexample then the following demonstrates both usages of `SetACEOptions': \beginexample gap> SetACEOptions( rec(echo := 2) ); gap> SetACEOptions( : hlt); \endexample Each of the three commands above generates output; for brevity it has not been included. *Notes:* \atindex{break-loop}{@\noexpand`break'-loop} When `ACECosetTableFromGensAndRels' enters a `break'-loop (see~"ACECosetTable"), local versions of the second form of each of `DisplayACEOptions' and `SetACEOptions' become available. (Even though the names are similar and their function is analogous they are in fact different functions.) \>ACEParameters( <i> ) F \>ACEParameters() F return a record of the current values of the {\ACE} Parameter Options (see~"ACEParameterOptions") of the <i>th (or default) process started by `ACEStart', according to {\ACE}. Please note that some options may be reported with incorrect values if they have been changed recently without following up with one of the modes `ACEContinue', `ACERedo' or `ACEStart'. Together the commands `ACEGroupGenerators', `ACERelators', `ACESubgroupGenerators' and `ACEParameters' give the equivalent {\GAP} information that is obtained in {\ACE} with `sr := 1' (see~"option sr"), which is the ``Run Parameters'' block obtained in the messaging output (observable when the `InfoLevel' of `InfoACE' is set to at least 3), when `messages' (see~"option messages") is set a non-zero value. *Notes:* One use for this function might be to determine the options required to replicate a previous run, but be sure that, if this is your purpose, any recent change in the parameter option values has been followed by an invocation of one of `ACEContinue' (see~"ACEContinue"), `ACERedo' (see~"ACERedo") or `ACEStart' (see~"ACEStart"). As a side-effect, for {\ACE} process <i>, any of the fields of `ACEData.io[<i>].args' or `ACEData.io[<i>].acegens' that are unset, are set. \>IsCompleteACECosetTable( <i> ) F \>IsCompleteACECosetTable() F return, for the <i>th (or default) process started by `ACEStart', `true' if {\ACE}'s current coset table is complete, or `false' otherwise. *Note:* The completeness of the coset table of the <i>th interactive {\ACE} process is determined by checking whether `ACEData.io[<i>].stats.index' is positive; a value of zero indicates the last enumeration failed to complete. The record `ACEData.io[<i>].stats' is what is returned by `ACEStats(<i>)' (see~"ACEStats"). \>ACEDisplayCosetTable( <i> ) F \>ACEDisplayCosetTable() F \>ACEDisplayCosetTable( <i>, [<val>] ) F \>ACEDisplayCosetTable( [<val>] ) F \>ACEDisplayCosetTable( <i>, [<val>, <last>] ) F \>ACEDisplayCosetTable( [<val>, <last>] ) F \>ACEDisplayCosetTable( <i>, [<val>, <last>, <by>] ) F \>ACEDisplayCosetTable( [<val>, <last>, <by>] ) F compact and display the (possibly incomplete) coset table of the <i>th (or default) process started by `ACEStart'; <val> must be an integer, and <last> and <by> must be positive integers. In the first two forms of the command, the entire coset table is displayed, without orders or coset representatives. In the third and fourth forms, the absolute value of <val> is taken to be the last line of the table to be displayed (and 1 is taken to be the first); in the fifth and sixth forms, `|<val>|' is taken to be the first line of the table to be displayed, and <last> is taken to be the number of the last line to be displayed. In the last two forms, the table is displayed from line `|<val>|' to line <last> in steps of <by>. If <val> is negative, then the orders modulo the subgroup (if available) and coset representatives are displayed also. *Note:* The coset table displayed will normally only be `lenlex' standardised if the call to `ACEDisplayCosetTable' is preceded by `ACEStandardCosetNumbering' (see~"ACEStandardCosetNumbering"). The options `lenlex' (see~"option lenlex") and `semilenlex' (see~"option semilenlex") are only executed by `ACECosetTable' (see~"ACECosetTable"). The {\ACE} binary does not provide `semilenlex' standardisation, and hence `ACEDisplayCosetTable' will never display a `semilenlex' standard coset table. \>ACECosetRepresentative( <i>, <n> ) F \>ACECosetRepresentative( <n> ) F return, for the <i>th (or default) process started by `ACEStart', the coset representative of coset <n> of the current coset table held by {\ACE}, where <n> must be a positive integer. \>ACECosetRepresentatives( <i> ) F \>ACECosetRepresentatives() F return, for the <i>th (or default) process started by `ACEStart', the list of coset representatives of the current coset table held by {\ACE}. \>ACETransversal( <i> ) F \>ACETransversal() F return, for the <i>th (or default) process started by `ACEStart', the list of coset representatives of the current coset table held by {\ACE}, if the current table is complete, and `fail' otherwise. Essentially, `ACETransversal(<i>) = ACECosetRepresentatives(<i>)' for a complete table. \>ACECycles( <i> ) F \>ACECycles() F \>ACEPermutationRepresentation( <i> ) F \>ACEPermutationRepresentation() F return, for the <i>th (or default) process started by `ACEStart', a list of permutations corresponding to the group generators, (i.e., the permutation representation), if the current coset table held by {\ACE} is complete or `fail', otherwise. In the event of failure a message is emitted to `Info' at `InfoACE' or `InfoWarning' level 1. \>ACETraceWord( <i>, <n>, <word> ) F \>ACETraceWord( <n>, <word> ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', trace <word> through {\ACE}'s coset table, starting at coset <n>, and return the final coset number if the trace completes, and `fail' otherwise. In Group Theory terms, if the cosets of a subgroup $H$ in a group $G$ are the subject of interactive {\ACE} process <i> and the coset identified by that process by the integer <n> corresponds to some coset $Hx$, for some $x$ in $G$, and <word> represents the element $g$ of $G$, then, providing the current coset table is complete enough, `ACETraceWord( <i>, <n>, <word> )' returns the integer identifying the coset $Hxg$. *Notes:* You may wish to compact {\ACE}'s coset table first, either explicitly via `ACERecover' (see~"ACERecover"), or, implicitly, via any function call that invokes {\ACE}'s compaction routine (see~"ACERecover" note). If you actually wanted {\ACE}'s coset representative, then, for a *compact* table, feed the output of `ACETraceWord' to `ACECosetRepresentative' (see~"ACECosetRepresentative"). \>ACEOrders( <i> ) F \>ACEOrders() F \>ACEOrders( <i> : suborder := <suborder> ) F \>ACEOrders(: suborder := <suborder> ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', search for all coset numbers whose representatives' orders (modulo the subgroup) are either finite, or, if invoked with the `suborder' option, are multiples of <suborder>, where <suborder> should be a positive integer. `ACEOrders' returns a (possibly empty) list of records, each with fields `coset', `order' and `rep', which are respectively, the coset number, its order modulo the subgroup, and a representative for each coset number satisfying the criteria of the search. *Note:* You may wish to compact {\ACE}'s coset table first, either explicitly via `ACERecover' (see~"ACERecover"), or, implicitly, via any function call that invokes {\ACE}'s compaction routine (see~"ACERecover" note). \>ACEOrder( <i>, <suborder> ) F \>ACEOrder( <suborder> ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', search for coset number(s) whose coset representatives have order modulo the subgroup a multiple of <suborder>. When <suborder> is a positive integer, `ACEOrder' returns just one record with fields `coset', `order' and `rep', which are respectively, the coset number, its order modulo the subgroup, and a representative for the first coset number satisfying the criteria of the search, or `fail' if there is no such coset number. The value of <suborder> may also be a negative integer, in which case, `ACEOrder( <i>, <suborder> )' is equivalent to `ACEOrders( <i> : suborder := |<suborder>|)'; or <suborder> may be zero, in which case, `ACEOrder( <i>, 0 )' is equivalent to `ACEOrders( <i> )'. *Note:* You may wish to compact {\ACE}'s coset table first, either explicitly via `ACERecover' (see~"ACERecover"), or, implicitly, via any function call that invokes {\ACE}'s compaction routine (see~"ACERecover" note). \>ACECosetOrderFromRepresentative( <i>, <cosetrep> ) F \>ACECosetOrderFromRepresentative( <cosetrep> ) F for the <i>th (or default) interactive {\ACE} process return the order (modulo the subgroup) of the coset with representative <cosetrep>, a word in the free group generators. *Note:* `ACECosetOrderFromRepresentative' calls `ACETraceWord' to determine the coset (number) to which <cosetrep> belongs, and then scans the output of `ACEOrders' to determine the order of the coset (number). \>ACECosetsThatNormaliseSubgroup( <i>, <n> ) F \>ACECosetsThatNormaliseSubgroup( <n> ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', determine non-trivial (i.e.~other than coset 1) coset numbers whose representatives normalise the subgroup. \beginlist%unordered \item{--} If <n> $> 0$, the list of the first <n> non-trivial coset numbers whose representatives normalise the subgroup is returned. \item{--} If <n> $\< 0$, a list of records with fields `coset' and `rep' which represent the coset number and a representative, respectively, of the first <n> non-trivial coset numbers whose representatives normalise the subgroup is returned. \item{--} If <n> $= 0$, a list of records with fields `coset' and `rep' which represent the coset number and a representative, respectively, of all non-trivial coset numbers whose representatives normalise the subgroup is returned. \endlist *Note:* You may wish to compact {\ACE}'s coset table first, either explicitly via `ACERecover' (see~"ACERecover"), or, implicitly, via any function call that invokes {\ACE}'s compaction routine (see~"ACERecover" note). \>ACEStyle( <i> ) F \>ACEStyle() F returns the current enumeration style as one of the strings: `"C"', `"Cr"', `"CR"', `"R"', `"R*"', `"Rc"', `"R/C"', or `"R/C (defaulted)"' (see Section~"Enumeration Style"). The next two functions of this section are really intended for {\ACE} standalone gurus. To fully understand their output you will need to consult the standalone manual and the C source code. \>ACEDumpVariables( <i> ) F \>ACEDumpVariables() F \>ACEDumpVariables( <i>, [<level>] ) F \>ACEDumpVariables( [<level>] ) F \>ACEDumpVariables( <i>, [<level>, <detail>] ) F \>ACEDumpVariables( [<level>, <detail>] ) F dump the internal variables of {\ACE} of the <i>th (or default) process started by `ACEStart'; <level> should be one of 0, 1, or 2, and <detail> should be 0 or 1. The value of <level> determines which of the three levels of {\ACE} to dump. (You will need to read the standalone manual to understand what Levels 0, 1 and 2 are all about.) The value of <detail> determines the amount of detail (`<detail> = 0' means less detail). The first two forms of `ACEDumpVariables' (with no list argument) selects `<level> = 0, <detail> = 0'. The third and fourth forms (with a list argument containing the integer <level>) makes `<detail> = 0'. This command is intended for gurus; the source code should be consulted to see what the output means. \>ACEDumpStatistics( <i> ) F \>ACEDumpStatistics() F dump {\ACE}'s internal statistics accumulated during the most recent enumeration of the <i>th (or default) process started by `ACEStart', provided the {\ACE} binary was built with the statistics package (which it is by default). Use `ACEBinaryVersion();' (see~"ACEBinaryVersion") to check for the inclusion of the statistics package. See the `enum.c' source file for the meaning of the variables. \>ACEBinaryVersion( <i> ) F \>ACEBinaryVersion() F for the <i>th (or default) process started by `ACEStart', print, via `Info' (at `InfoACE' level 1), version details of the {\ACE} binary you are currently running, including what compiler flags were set when the executable was built, and also returns the version number of the binary as a string. Essentially the information obtained is what is obtained via {\ACE}'s `options' option (see~"option options"), and the returned value is what is stored in `ACEData.version' (see~"ACEData"). A typical output, illustrating the default build, is: \beginexample gap> ACEBinaryVersion(); #I ACE Binary Version: 3.001 #I ACE 3.001 executable built: #I Mon Aug 20 20:10:07 CEST 2001 #I Level 0 options: #I statistics package = on #I coinc processing messages = on #I dedn processing messages = on #I Level 1 options: #I workspace multipliers = decimal #I Level 2 options: #I host info = on "3.001" \endexample *Notes:* The {\ACE} binary's banner may also appear in the output (if it has not already appeared). Unlike other {\ACE} interface functions, the information obtained via `ACEBinaryVersion();' is absolutely independent of any enumeration. For this reason, we make it permissible to run `ACEBinaryVersion();' when there are no currently active interactive {\ACE} processes; and, in such a case, `ACEBinaryVersion();' emits a warning that there are no interactive {\ACE} sessions currently active and initiates (and closes again) its own stream to obtain the information from the {\ACE} binary. For the current version of the {\ACE} package (the {\GAP} code component) use `ACEPackageVersion();' (see~"ACEPackageVersion"). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Interactive Versions of Non-interactive ACE Functions} \>ACECosetTable( <i> [:<options>] )!{interactive} F \>ACECosetTable( [:<options>] )!{interactive} F return a coset table as a {\GAP} object, in standard form (for {\GAP}). These functions perform the same function as `ACECosetTableFromGensAndRels' and `ACECosetTable' on three arguments (see~"ACECosetTable"), albeit interactively, on the <i>th (or default) process started by `ACEStart'. If options are passed then an internal version of `ACEModes' is run to determine which of the general {\ACE} modes (see Section~"General ACE Modes") `ACEContinue', `ACERedo' or `ACEStart' is possible; and (an internal version of) the first mode of these that is allowed is executed, to ensure the resultant table is correct for the current options. \>ACEStats( <i> [:<options>] )!{interactive} F \>ACEStats( [:<options>] )!{interactive} F perform the same function as `ACEStats' on three arguments (see~"ACEStats" --- non-interactive version), albeit interactively, on the <i>th (or default) process started by `ACEStart'. If options are passed then an internal version of `ACEModes' is run to determine which of the general {\ACE} modes (see Section~"General ACE Modes") `ACEContinue', `ACERedo' or `ACEStart' is possible; and (an internal version of) the first mode of these that is allowed is executed, to ensure the resultant statistics are correct for the current options. See Section~"Example of Using ACE Interactively (Using ACEStart)" for an example demonstrating both these functions within an interactive process. \>IsACEGeneratorsInPreferredOrder( <i> )!{interactive} F \>IsACEGeneratorsInPreferredOrder()!{interactive} F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', return `true' if the group generators of that process, are in an order that will not be changed by {\ACE}, and `false' otherwise. This function has greatest relevance to users who call `ACECosetTable' (see~"ACECosetTable!interactive"), with the `lenlex' option (see~"option lenlex"). For more details, see the discussion for the non-interactive version of `IsACEGeneratorsInPreferredOrder' ("IsACEGeneratorsInPreferredOrder"), which is called with two arguments. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Steering ACE Interactively} \index{dead coset (number)} \>ACERecover( <i> ) F \>ACERecover() F invoke the compaction routine on the coset table of the <i>th (or default) interactive {\ACE} process started by `ACEStart', in order to recover the space used by the dead coset numbers. A `CO' message line is printed if any rows of the coset table were recovered, and a `co' line if none were. (See Appendix~"The Meanings of ACE's output messages" for the meanings of these messages.) *Note:* The compaction routine is called automatically when any of `ACEDisplayCosetTable' (see~"ACEDisplayCosetTable"), `ACECosetRepresentative' (see~"ACECosetRepresentative"), `ACECosetRepresentatives' (see~"ACECosetRepresentatives"), `ACETransversal' (see~"ACETransversal"), `ACECycles' (see~"ACECycles"), `ACEStandardCosetNumbering' (see~"ACEStandardCosetNumbering"), `ACECosetTable' (see~"ACECosetTable") or `ACEConjugatesForSubgroupNormalClosure' (see~"ACEConjugatesForSubgroupNormalClosure"), is invoked. \atindex{lenlex standardisation scheme}% {@\noexpand`lenlex' standardisation scheme} \>ACEStandardCosetNumbering( <i> ) F \>ACEStandardCosetNumbering() F compact and then do a `lenlex' standardisation (see Section~"Coset Table Standardisation Schemes") of the numbering of cosets in the coset table of the <i>th (or default) interactive {\ACE} process started by `ACEStart'. That is, for a given ordering of the generators in the columns of the table, they produce a canonic table. A table that includes a column for each generator inverse immediately following the column for the corresponding generator, standardised according to the `lenlex' scheme, has the property that a row-major scan (i.e.~a scan of the successive rows of the *body* of the table row by row, from left to right) encounters previously unseen cosets in numeric order. This function does not display the new table; use `ACEDisplayCosetTable' (see~"ACEDisplayCosetTable") for that. *Notes:* In a `lenlex' canonic table, the coset representatives are ordered first according to length and then the lexicographic order defined by the order the generators and their inverses head the columns. Note that, unless special action is taken, {\ACE} avoids having an involutory generator in the first column (by swapping the first two generators), except when there is only one generator, or when the second generator is also an involution; so the lexicographic order used by {\ACE} need not necessarily correspond with the order in which the generators were first put to {\ACE}. (We have used the term ``involution'' above; what we really mean is a generator `x' for which there is a relator `x*x' or `x^2'. Such a generator may, of course, turn out to actually be the identity.) The function `IsACEGeneratorsInPreferredOrder' (see "IsACEGeneratorsInPreferredOrder") detects cases when {\ACE} would swap the first two generators. Standardising the coset numbering within {\ACE} does *not* affect the {\GAP} coset table obtained via `ACECosetTable' (see~"ACECosetTable"). If `ACECosetTable' is called without the `lenlex' option {\GAP}'s default standardisation is applied after conversion of {\ACE}'s output, which undoes an {\ACE} standardisation. On the other hand, if `ACECosetTable' is called with the `lenlex' option then after a check and special action, if required, the equivalent of a call to `ACEStandardCosetNumbering' is invoked, irrespective of whether it has been done by the user beforehand. The check that is done is a call to `IsACEGeneratorsInPreferredOrder' (see "IsACEGeneratorsInPreferredOrder") to ensure that {\ACE} has not swapped the first two generators. The special action taken when the call to `IsACEGeneratorsInPreferredOrder' returns `false', is the setting of the `asis' option (see~"option asis") to 1 and the resubmission of the relators to {\ACE} taking care not to submit the relator that determines the first generator as an involution as that generator squared (these two actions together avert {\ACE}'s swapping of the first two generators), followed by the re-`start'ing of the enumeration. *Guru Notes:* In five of the ten standard enumeration strategies of Sims \cite{Sim94} (i.e.~the five Sims strategies not provided by {\ACE}), the table is standardised repeatedly. This is expensive computationally, but can result in fewer cosets being necessary. The effect of doing this can be investigated in {\ACE} by (repeatedly) halting the enumeration (via restrictive options), standardising the coset numbering, and continuing (see Section~"Emulating Sims" for an example). \>ACEAddRelators( <i>, <wordlist> ) F \>ACEAddRelators( <wordlist> ) F add, for the <i>th (or default) interactive {\ACE} process started by `ACEStart', the words in the list <wordlist> to any relators already present, and automatically invoke `ACERedo', if it can be applied, or otherwise `ACEStart'. Note that {\ACE} sorts the resultant relator list, unless the `asis' option (see~"option asis") has been set to 1; don't assume, unless `asis = 1', that the new relators have been appended in user-provided order to the previously existing relator list. `ACEAddRelators' also returns the new relator list. Use `ACERelators' (see~"ACERelators") to determine the current relator list. \>ACEAddSubgroupGenerators( <i>, <wordlist> ) F \>ACEAddSubgroupGenerators( <wordlist> ) F add, for the <i>th (or default) interactive {\ACE} process started by `ACEStart', the words in the list <wordlist> to any subgroup generators already present, and automatically invoke `ACERedo', if it can be applied, or otherwise `ACEStart'. Note that {\ACE} sorts the resultant subgroup generator list, unless the `asis' option (see~"option asis") has been set to 1; don't assume, unless `asis = 1', that the new subgroup generators have been appended in user-provided order to the previously existing subgroup generator list. `ACEAddSubgroupGenerators' also returns the new subgroup generator list. Use `ACESubgroupGenerators' (see~"ACESubgroupGenerators") to determine the current subgroup generator list. \>ACEDeleteRelators( <i>, <list> ) F \>ACEDeleteRelators( <list> ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', delete <list> from the current relators, if list is a list of words in the group generators, or those current relators indexed by the integers in <list>, if <list> is a list of positive integers, and automatically invoke `ACEStart'. `ACEDeleteRelators' also returns the new relator list. Use `ACERelators' (see~"ACERelators") to determine the current relator list. \>ACEDeleteSubgroupGenerators( <i>, <list> ) F \>ACEDeleteSubgroupGenerators( <list> ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', delete <list> from the current subgroup generators, if list is a list of words in the group generators, or those current subgroup generators indexed by the integers in <list>, if <list> is a list of positive integers, and automatically invoke `ACEStart'. `ACEDeleteSubgroupGenerators' also returns the new subgroup generator list. Use `ACESubgroupGenerators' (see~"ACESubgroupGenerators") to determine the current subgroup generator list. \>ACECosetCoincidence( <i>, <n> ) F \>ACECosetCoincidence( <n> ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', return the representative of coset <n>, where <n> must be a positive integer, and add it to the subgroup generators; i.e., equates this coset with coset 1, the subgroup. `ACERedo' is automatically invoked. \>ACERandomCoincidences( <i>, <subindex> ) F \>ACERandomCoincidences( <subindex> ) F \>ACERandomCoincidences( <i>, [<subindex>] ) F \>ACERandomCoincidences( [<subindex>] ) F \>ACERandomCoincidences( <i>, [<subindex>, <attempts>] ) F \>ACERandomCoincidences( [<subindex>, <attempts>] ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', attempt up to <attempts> (or, in the first four forms, 8) times to find nontrivial subgroups with index a multiple of <subindex> by repeatedly making random coset numbers coincident with coset 1 and seeing what happens. The starting coset table must be non-empty, but must *not* be complete (use `ACERandomlyApplyCosetCoincidence' (see~"ACERandomlyApplyCosetCoincidence") if your table is already complete). For each attempt, by applying {\ACE}'s `rc' option (see~"option rc") random coset representatives are repeatedly added to the subgroup and the enumeration `redo'ne. If the table becomes too small, the attempt is aborted, the original subgroup generators restored, and another attempt made. If an attempt succeeds, then the new set of subgroup generators is retained. `ACERandomCoincidences' returns the list of new subgroup generators added. Use `ACESubgroupGenerators' (see~"ACESubgroupGenerators") to determine the current subgroup generator list. *Notes:* `ACERandomCoincidences' may add subgroup generators even if it failed to determine a nontrivial subgroup with index a multiple of <subindex>; in such a case, the original status may be restored by applying `ACEDeleteSubgroupGenerators' (see~"ACEDeleteSubgroupGenerators") with the list returned by `ACERandomCoincidences'. `ACERandomCoincidences' applies the `rc' option (see~"option rc") of {\ACE} which takes the line that if an enumeration has already obtained a finite index then either, <subindex> is already a divisor of that finite index, or the request is impossible. Thus an invocation of `ACERandomCoincidences', in the case where the coset table is already complete, is an error. *Guru Notes:* A coset can have many different representatives. Consider running `ACEStandardCosetNumbering' (see~"ACEStandardCosetNumbering") before `ACERandomCoincidences', to canonicise the table and the representatives. \>ACERandomlyApplyCosetCoincidence( <i> [: <controlOptions>]) F \>ACERandomlyApplyCosetCoincidence( [: <controlOptions>]) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', try to find a larger proper subgroup (i.e.~a subgroup of smaller but nontrivial index), by repeatedly applying `ACECosetCoincidence' (see~"ACECosetCoincidence") and seeing what happens; `ACERandomlyApplyCosetCoincidence' returns the (possibly empty) list of new subgroup generators added. The starting coset table must already be complete (use `ACERandomCoincidences' (see~"ACERandomCoincidences") if your table is not already complete). `ACERandomlyApplyCosetCoincidence' provides the following four options (<controlOptions>). \beginitems \quad`subindex := <subindex>' & Sets the restriction that the final index should be a multiple of <subindex>; <subindex> must be a positive integer divisor of the initial subgroup index. \quad`hibound := <hibound>' & Sets the restriction that the final index should be (strictly) less than <hibound>; <hibound> must be an integer that is greater than 1 and at most the initial subgroup index. \quad`lobound := <lobound>' & Sets the restriction that the final index should be (strictly) greater than <lobound>; <lobound> must be an integer that is at least 1 and (strictly) less than the initial subgroup index. \quad`attempts := <attempts>' & Sets the restriction that the number of applications of `ACECosetCoincidence' should be at most <attempts>; <attempts> must be a positive integer. \enditems By default, `<subindex> = 1', <hibound> is the existing subgroup index, `<lobound> = 1' and `<attempts> = 8'. If after an attempt the new index is a multiple of <subindex>, less than <hibound> and greater than <lobound> then the process terminates (and the list of new subgroup generators is returned). Otherwise, if an attempt reaches a stage where the criteria cannot be satisfied, the attempt is aborted, the original subgroup generators restored, and another attempt made. If no attempt is successful an empty list is returned. Use `ACESubgroupGenerators' (see~"ACESubgroupGenerators") to determine the current subgroup generator list. \>ACEConjugatesForSubgroupNormalClosure( <i> ) F \>ACEConjugatesForSubgroupNormalClosure() F \>ACEConjugatesForSubgroupNormalClosure( <i> : add ) F \>ACEConjugatesForSubgroupNormalClosure(: add ) F for the <i>th (or default) interactive {\ACE} process started by `ACEStart', test each conjugate of a subgroup generator by a group generator for membership in the subgroup, and return the (possibly empty) list of conjugates that were determined to not belong to the subgroup (coset 1); and, if called with the `add' option, these conjugates are also added to the existing list of subgroup generators. *Notes:* A conjugate of a subgroup generator is tested for membership of the subgroup, by checking whether it can be traced from coset 1 to coset 1 (see `ACETraceWord':~"ACETraceWord"). For an *incomplete* coset table, such a trace may not complete, in which case `ACEConjugatesForSubgroupNormalClosure' may return an empty list even though the subgroup is *not* normally closed within the group. The `add' option does *not* guarantee that the resultant subgroup is normally closed. It is still possible that some conjugates of the newly added subgroup generators will not be elements of the subgroup. *Example:* To demonstrate the usage and features of `ACEConjugatesForSubgroupNormalClosure', let us consider an example where we know pretty well what to expect. Let $G$ be the group, isomorphic to the symmetric group $S_6$, with the presentation $$ \{ a, b \mid a^2, b^6, (ab^{-1}ab)^3, (ab^{-1}ab^2)^4, (ab)^5, (ab^{-2}ab^2)^2 \} $$ (from \cite{CM72}), and let $H$ be the subgroup $\langle ab^3 \rangle$. There is an isomorphism $\phi$ from $G$ to $S_6$ mapping $a$ onto $(1,2)$ and $ab^3$ onto $(1,2,3,4,5,6)$. It follows that $\phi$ maps $ab^3$ into $A_6$. So we know that the normal closure of $H$ has index 2 in $G$. Let us observe this via {\ACE}. First we start an enumeration with `max' set to 80. \beginexample gap> F := FreeGroup( "a", "b" );; gap> a := F.1;; b := F.2;; gap> fgens := GeneratorsOfGroup( F );; gap> rels := [ a^2, b^6, (a*b^-1*a*b)^3, (a*b^-1*a*b^2)^4, (a*b)^5, > (a*b^-2*a*b^2)^2 ];; gap> sgens := [ a*b^3 ];; gap> i := ACEStart( fgens, rels, sgens : max := 80 );; gap> IsCompleteACECosetTable( i ); false gap> ACEConjugatesForSubgroupNormalClosure( i : add ); #I ACEConjugatesForSubgroupNormalClosure: All (traceable) conjugates in subgp [ ] \endexample Though we know that $H$ is not equal to its normal closure, we did not get any new elements (we had warned above of such a possibility). Apparently our incomplete table is too small. So let us increase `max' to 100 and continue. \beginexample gap> ACEContinue( i : max := 100 );; gap> IsCompleteACECosetTable( i ); false gap> ACEConjugatesForSubgroupNormalClosure( i : add ); [ b^-1*a*b^4 ] gap> IsCompleteACECosetTable( i ); true gap> ACEStats( i ).index; 20 \endexample This time we got a new element, and after adding it to the subgroup generators we obtained a complete table. However the resulting subgroup need not yet be the normal closure of $H$ (and in fact we know that it is not). So we continue with another call to the function `ACEConjugatesForSubgroupNormalClosure'. \beginexample gap> ACEConjugatesForSubgroupNormalClosure( i : add ); [ b^-2*a*b^5, b*a*b^2 ] gap> ACEStats( i ).index; 2 \endexample Now we have the index that we expected. Another call to the function `ACEConjugatesForSubgroupNormalClosure' should not yield any more conjugates. We ensure that this is indeed the case and then display the resulting list of subgroup generators. \beginexample gap> ACEConjugatesForSubgroupNormalClosure( i : add ); #I ACEConjugatesForSubgroupNormalClosure: All (traceable) conjugates in subgp [ ] gap> ACESubgroupGenerators( i ); [ a*b^3, b*a*b^2, b^-1*a*b^4, b^-2*a*b^5 ] \endexample %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \Section{Primitive ACE Read/Write Functions} For those familiar with the workings of the {\ACE} standalone we provide primitive read/write tools to communicate directly with an interactive {\ACE} process, started via `ACEStart' (possibly with argument 0, but this is not essential). For the most part, it is up to the user to translate the output strings from {\ACE} into a form useful in {\GAP}. However, after the group generators, relators, and subgroup generators have been set in the {\ACE} process, via `ACEWrite', invocations of any of `ACEGroupGenerators' (see~"ACEGroupGenerators"), `ACERelators' (see~"ACERelators"), `ACESubgroupGenerators' (see~"ACESubgroupGenerators"), or `ACEParameters' (see~"ACEParameters") will establish the corresponding {\GAP} values. Be warned though, that unless one of the modes `ACEStart' (without a zero argument; see~"ACEStart"), `ACERedo' (see~"ACERedo") or `ACEContinue' (see~"ACEContinue"), or their equivalent for the standalone {\ACE} (`start;', `redo;', or `continue;'), has been invoked since the last change of any parameter options (see~"ACEParameterOptions"), some of the values reported by `ACEParameters' may well be *incorrect*. \>ACEWrite( <i>, <string> ) F \>ACEWrite( <string> ) F write <string> to the <i>th or default interactive {\ACE} process; <string> must be in exactly the form the {\ACE} standalone expects. The command is echoed via `Info' at `InfoACE' level 4 (with a ```ToACE> ''' prompt); i.e.~do `SetInfoACELevel(4);' to see what is transmitted to the {\ACE} binary. `ACEWrite' returns `true' if successful in writing to the stream of the interactive {\ACE} process, and `fail' otherwise. *Note:* If `ACEWrite' returns `fail' (which means that the {\ACE} process has died), you may like to try resurrecting the interactive {\ACE} process via `ACEResurrectProcess' (see~"ACEResurrectProcess"). \>ACERead( <i> ) F \>ACERead() F read a complete line of {\ACE} output, from the <i>th or default interactive {\ACE} process, if there is output to be read and returns `fail' otherwise. When successful, the line is returned as a string complete with trailing newline character. Please note that it is possible to be ``too quick'' (i.e.~the return can be `fail' purely because the output from {\ACE} is not there yet), but if `ACERead' finds any output at all, it waits for a complete line. \>ACEReadAll( <i> ) F \>ACEReadAll() F read and return as many *complete* lines of {\ACE} output, from the <i>th or default interactive {\ACE} process, as there are to be read, *at the time of the call*, as a list of strings with the trailing newlines removed and returns the empty list otherwise. `ACEReadAll' also writes each line read via `Info' at `InfoACE' level 3. Whenever `ACEReadAll' finds only a partial line, it waits for the complete line, thus increasing the probability that it has captured all the output to be had from {\ACE}. \>ACEReadUntil( <i>, <IsMyLine> ) F \>ACEReadUntil( <IsMyLine> ) F \>ACEReadUntil( <i>, <IsMyLine>, <Modify> ) F \>ACEReadUntil( <IsMyLine>, <Modify> ) F read complete lines of {\ACE} output, from the <i>th or default interactive {\ACE} process, ``chomps'' them (i.e.~removes any trailing newline character), emits them to `Info' at `InfoACE' level 3, and applies the function <Modify> (where <Modify> is just the identity map/function for the first two forms) until a ``chomped'' line <line> for which `<IsMyLine>( <Modify>(<line>) )' is true. `ACEReadUntil' returns the list of <Modify>-ed ``chomped'' lines read. *Notes:* When provided by the user, <Modify> should be a function that accepts a single string argument. <IsMyLine> should be a function that is able to accept the output of <Modify> (or take a single string argument when <Modify> is not provided) and should return a boolean. If `<IsMyLine>( <Modify>(<line>) )' is never true, `ACEReadUntil' will wait indefinitely. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %E