Main Loop and Break Loop

This chapter is a first of a series of chapters that describe the interactive environment in which you use &GAP;.

Main Loop
read eval print loop
loop
prompt
prompt
syntax errors
errors
output
last
last2
last3
previous result
The normal interaction with &GAP; happens in the so-called read-eval-print loop. This means that you type an input, &GAP; first reads it, evaluates it, and then shows the result. Note that the term print may be confusing since there is a &GAP; function called (see ) which is in fact not used in the read-eval-print loop, but traditions are hard to break. In the following, whenever we want to express that &GAP; places some characters on the standard output, we will say that &GAP; shows something.

The exact sequence in the read-eval-print loop is as follows.

To signal that it is ready to accept your input, &GAP; shows the prompt gap>. When you see this, you know that &GAP; is waiting for your input.

Note that every statement must be terminated by a semicolon. You must also enter Return (i.e., strike the Return key) before &GAP; starts to read and evaluate your input. (The Return key may actually be marked with the word Enter and a returning arrow on your terminal.) Because &GAP; does not do anything until you enter Return, you can edit your input to fix typos and only when everything is correct enter Return and have &GAP; take a look at it (see ). It is also possible to enter several statements as input on a single line. Of course each statement must be terminated by a semicolon.

It is absolutely acceptable to enter a single statement on several lines. When you have entered the beginning of a statement, but the statement is not yet complete, and you enter Return, &GAP; will show the partial prompt >. When you see this, you know that &GAP; is waiting for the rest of the statement. This happens also when you forget the semicolon ; that terminates every &GAP; statement. Note that when Return has been entered and the current statement is not yet complete, &GAP; will already evaluate those parts of the input that are complete, for example function calls that appear as arguments in another function call which needs several input lines. So it may happen that one has to wait some time for the partial prompt.

When you enter Return, &GAP; first checks your input to see if it is syntactically correct (see Chapter for the definition of syntactically correct). If it is not, &GAP; prints an error message of the following form

gap> 1 * ; Syntax error: expression expected 1 * ; ^

The first line tells you what is wrong about the input, in this case the * operator takes two expressions as operands, so obviously the right one is missing. If the input came from a file (see ), this line will also contain the filename and the line number. The second line is a copy of the input. And the third line contains a caret pointing to the place in the previous line where &GAP; realized that something is wrong. This need not be the exact place where the error is, but it is usually quite close.

Sometimes, you will also see a partial prompt after you have entered an input that is syntactically incorrect. This is because &GAP; is so confused by your input, that it thinks that there is still something to follow. In this case you should enter ;Return repeatedly, ignoring further error messages, until you see the full prompt again. When you see the full prompt, you know that &GAP; forgave you and is now ready to accept your next –hopefully correct– input.

If your input is syntactically correct, &GAP; evaluates or executes it, i.e., performs the required computations (see Chapter for the definition of the evaluation).

If you do not see a prompt, you know that &GAP; is still working on your last input. Of course, you can type ahead, i.e., already start entering new input, but it will not be accepted by &GAP; until &GAP; has completed the ongoing computation.

When &GAP; is ready it will usually show the result of the computation, i.e., the value computed. Note that not all statements produce a value, for example, if you enter a for loop, nothing will be printed, because the for loop does not produce a value that could be shown.

Also sometimes you do not want to see the result. For example if you have computed a value and now want to assign the result to a variable, you probably do not want to see the value again. You can terminate statements by two semicolons to suppress showing the result.

If you have entered several statements on a single line &GAP; will first read, evaluate, and show the first one, then read, evaluate, and show the second one, and so on. This means that the second statement will not even be checked for syntactical correctness until &GAP; has completed the first computation.

After the result has been shown &GAP; will display another prompt, and wait for your next input. And the whole process starts all over again. Note that if you have entered several statements on a single line, a new prompt will only be printed after &GAP; has read, evaluated, and shown the last statement.

In each statement that you enter, the result of the previous statement that produced a value is available in the variable last. The next to previous result is available in last2 and the result produced before that is available in last3.

gap> 1;2;3; 1 2 3 gap> last3 + last2 * last; 7

Also in each statement the time spent by the last statement, whether it produced a value or not, is available in the variable . This is an integer that holds the number of milliseconds.

Special Rules for Input Lines

The input for some &GAP; objects may not fit on one line, in particular big integers, long strings or long identifiers. In these cases you can still type or paste them in long single lines. For nicer display you can also specify the input on several lines. This is achieved by ending a line by a backslash or by a backslash and a carriage return character, then continue the input on the beginning of the next line. When reading this &GAP; will ignore such continuation backslashes, carriage return characters and newline characters. &GAP; also prints long strings and integers this way.

gap> n := 1234\ > 567890; 1234567890 gap> "This is a very long string that does not fit on a line \ > and is therefore continued on the next line."; "This is a very long string that does not fit on a line and is therefo\ re continued on the next line." gap> bla\ > bla := 5;; blabla; 5

There is a special rule about &GAP; prompts in input lines: In line editing mode (usual user input and &GAP; started without -n) in lines starting with whitespace following gap> , > or brk> this beginning part is removed. This rule is very convenient because it allows to cut and paste input from other &GAP; sessions or manual examples easily into your current session.

View and Print

&GAP; has three different operations to display or print objects: , and , and these three have different purposes as follows. The first, , should print the object to the standard output in a human-readable relatively complete and verbose form. The second, , should print the object to the standard output in a short and concise form, it is used in the main read-eval-print loop to display the resulting object of a computation. The third, , should print the object to the standard output in a complete form which is &GAP;-readable if at all possible, such that reading the output into &GAP; produces an object which is equal to the original one.

All three operations have corresponding operations which do not print anything to standard output but return the output as a string. These are , and (corresponding to ). Additionally, there is which is very similar to but does not insert control characters for line breaks.

For implementation convenience it is allowed that some of these operations have methods which delegate to some other of these operations. However, the rules for this are that a method may only delegate to another operation which appears further down in the following table:

This is to avoid circular delegations.

Note in particular that none of the methods of the string producing operations may delegate to the corresponding printing operations. Note also that the above mentioned purposes of the different operations suggest that delegations between different operations will be sub-optimal in most scenarios.

Default delegations in the library

The library contains the following low ranked default methods:

A method for which returns the constant value of the global variable .
A method for which returns the constant value of the global variable .
A method for which first calls and prints the result, if it is a different object than . Otherwise the method delegates to .
A method for which first calls and prints the result, if it is a different object than . Otherwise the method delegates to .
A method for which prints the result of .
A method for which returns the result of
Recommendations for the implementation

This subsection describes what methods for printing and viewing one should implement for new &GAP; objects.

One should at the very least install a method to allow printing. Using the standard delegations this enables a limited form of viewing, displaying and printing.

If, for larger objects, nicer line breaks are needed, one should install a separate method which puts in positions for good line breaks using the control characters \< (ASCII 1) and \> (ASCII 2).

If, for even larger objects, output performance and memory usage matters, one should install a separate method.

One should usually install a method, unless the above method is good enough for purposes. Performance and memory should never matter here, so it is usually unnecessary to install a separate method.

If the type of object calls for it one should install a method. This is the case if a human readable verbose form is required.

If the performance and memory usage for matters, one should install a separate method.

Note that if only a method is installed, then works and returns . Likewise, works and returns . If you want to avoid this then install methods for these operations as well.
<#Include Label="View">

Also shows the objects obj1, obj2... etc. on the standard output. The difference compared to is in general that the shown form is not required to be short, and that in many cases the form shown by is &GAP; readable.

gap> z:= Z(2); Z(2)^0 gap> v:= [ z, z, z, z, z, z, z ]; [ Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0 ] gap> ConvertToVectorRep(v);; v; <a GF2 vector of length 7> gap> Print( v, "\n" ); [ Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0, Z(2)^0 ]

Another difference is that shows strings without the enclosing quotes, so can be used to produce formatted text on the standard output (see also chapter ). Some characters preceded by a backslash, such as \n, are processed specially (see chapter ). can be used to print to a file.

gap> for i in [1..5] do > Print( i, " ", i^2, " ", i^3, "\n" ); > od; 1 1 1 2 4 8 3 9 27 4 16 64 5 25 125 gap> g:= SmallGroup(12,5); <pc group of size 12 with 3 generators> gap> Print( g, "\n" ); Group( [ f1, f2, f3 ] ) gap> View( g ); Print( "\n" ); <pc group of size 12 with 3 generators>

The functions and actually call the operations and , respectively, for each argument. By installing special methods for these operations, it is possible to achieve special printing behavior for certain objects (see chapter ). The only exceptions are strings (see Chapter ), for which the default and methods as well as the function print also the enclosing doublequotes, whereas strips the doublequotes.

The default method for is to call . So it is sufficient to have a method for an object in order to it. If one wants to supply a short form for , one can install additionally a method for .
<#Include Label="Display">

When setting up examples, in particular if for beginning users, it sometimes can be convenient to hide the structure behind a printing name. For many objects, such as groups, this can be done using . If the objects however is represented internally, for example permutations representing group elements, this function is not applicable. Instead the function can be used to interface with the display routines on a lower level.

<#Include Label="SetNameObject">

Break Loops

When an error has occurred or when you interrupt &GAP; (usually by hitting Ctrl-C) &GAP; enters a break loop, that is in most respects like the main read eval print loop (see ). That is, you can enter statements, &GAP; reads them, evaluates them, and shows the result if any. However those evaluations happen within the context in which the error occurred. So you can look at the arguments and local variables of the functions that were active when the error happened and even change them. The prompt is changed from gap> to brk> to indicate that you are in a break loop.

gap> 1/0; Rational operations: <divisor> must not be zero not in any function Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can replace <divisor> via 'return <divisor>;' to continue

If errors occur within a break loop &GAP; enters another break loop at a deeper level. This is indicated by a number appended to brk:

brk> 1/0; Rational operations: <divisor> must not be zero not in any function Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can replace <divisor> via 'return <divisor>;' to continue brk_02>

There are two ways to leave a break loop, see and .

quit from a break loop

The first way to leave a break loop is to quit the break loop. To do this you enter quit; or type the eof (end of file) character, which is usually Ctrl-D except when using the -e option (see Section ). Note that &GAP; code between quit; and the end of the input line is ignored.

brk_02> quit; brk>

In this case control returns to the break loop one level above or to the main loop, respectively. So iterated break loops must be left iteratively. Note also that if you type quit; from a gap> prompt, &GAP; will exit (see ).

Note:
If you leave a break loop with quit without completing a command it is possible (though not very likely) that data structures will be corrupted or incomplete data have been stored in objects. Therefore no guarantee can be given that calculations afterwards will return correct results! If you have been using options quitting a break loop generally leaves the options stack with options you no longer want. The function removes all options on the options stack, and this is the sole intended purpose of this function.

return from a break loop
return
return from break loop
The other way to leave a break loop is to return from a break loop. To do this you type return; or return obj;. If the break loop was entered because you interrupted &GAP;, then you can continue by typing return;. If the break loop was entered due to an error, you may have to modify the value of a variable before typing return; (see the example for ) or you may have to return an object obj (by typing: return obj;) to continue the computation; in any case, the message printed on entering the break loop will tell you which of these alternatives is possible. For example, if the break loop was entered because a variable had no assigned value, the value to be returned is often a value that this variable should have to continue the computation.

brk> return 9; # we had tried to enter the divisor 9 but typed 0 ... 1/9 gap>
By default, when a break loop is entered, &GAP; prints a trace of the innermost 5 commands currently being executed. This behaviour can be configured by changing the value of the global variable . When a break loop is entered, the value of is checked. If it is a function, then it is called with no arguments. By default, the value of is .

gap> OnBreak := function() Print("Hello\n"); end; function( ) ... end

gap> Error("!\n"); Error, ! Hello Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> quit;

In cases where a break loop is entered during a function that was called with options (see Chapter ), a quit; will also cause the options stack to be reset and an Info-ed warning stating this is emitted at level 1 (see Chapter ).

Note that for break loops entered by a call to , the lines after Entering break read-eval-print loop ... and before the brk> prompt can also be customised, namely by redefining .

ErrorNoTraceBack
Also, note that one can achieve the effect of changing locally. As mentioned above, the default value of is . Thus, a call to generally gives a trace back up to five levels of calling functions. Conceivably, we might like to have a function like that does not trace back without globally changing . Such a function we might call ErrorNoTraceBack and here is how we might define it. (Note ErrorNoTraceBack is not a &GAP; function.)

gap> ErrorNoTraceBack := function(arg) # arg is special variable that GAP > # knows to treat as list of arg's > local SavedOnBreak, ENTBOnBreak; > SavedOnBreak := OnBreak; # save current value of OnBreak > > ENTBOnBreak := function() # our `local' OnBreak > local s; > for s in arg do > Print(s); > od; > OnBreak := SavedOnBreak; # restore OnBreak afterwards > end; > > OnBreak := ENTBOnBreak; > Error(); > end; function( arg ) ... end

Here is a somewhat trivial demonstration of the use of ErrorNoTraceBack.

gap> ErrorNoTraceBack("Gidday!", " How's", " it", " going?\n"); Error, Gidday! How's it going? Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> quit;

Now we call with the same arguments to show the difference.

gap> Error("Gidday!", " How's", " it", " going?\n"); Error, Gidday! How's it going? Hello Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> quit;

Observe that the value of before the ErrorNoTraceBack call was restored. However, we had changed from its default value; to restore to its default value, we should do the following.

gap> OnBreak := Where;;
Break loop message
When a break loop is entered by a call to the message after the Entering break read-eval-print loop ... line is produced by the function OnBreakMessage, which just like is a user-configurable global variable that is a function with no arguments.

gap> OnBreakMessage(); # By default, OnBreakMessage prints the following you can 'quit;' to quit to outer loop, or you can 'return;' to continue

Perhaps you are familiar with what's possible in a break loop, and so don't need to be reminded. In this case, you might wish to do the following (the first line just makes it easy to restore the default value later).

gap> NormalOnBreakMessage := OnBreakMessage;; # save the default value gap> OnBreakMessage := function() end; # do-nothing function function( ) ... end gap> OnBreakMessage(); gap> OnBreakMessage := NormalOnBreakMessage;; # reset

With still set away from its default value, calling as we did above, now produces:

gap> Error("!\n"); Error, ! Hello Entering break read-eval-print loop ... brk> quit; # to get back to outer loop

However, suppose you are writing a function which detects an error condition and OnBreakMessage needs to be changed only locally, i.e., the instructions on how to recover from the break loop need to be specific to that function. The same idea used to define ErrorNoTraceBack (see ) can be adapted to achieve this. The function is an example in the &GAP; code where the idea is actually used.

Backtrace
Stack trace
shows the last nr commands on the execution stack during whose execution the error occurred. If not given, nr defaults to 5. (Assume, for the following example, that after the last example has been set back to its default value.)

gap> StabChain(SymmetricGroup(100)); # After this we typed ^C user interrupt at bpt := S.orbit[1]; called from SiftedPermutation( S, (g * rep) ^ -1 ) called from StabChainStrong( S.stabilizer, [ sch ], options ); called from StabChainStrong( S.stabilizer, [ sch ], options ); called from StabChainStrong( S, GeneratorsOfGroup( G ), options ); called from StabChainOp( G, rec( ) ) called from ... Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> Where(2); called from SiftedPermutation( S, (g * rep) ^ -1 ) called from StabChainStrong( S.stabilizer, [ sch ], options ); called from ...

Note that the variables displayed even in the first line of the list (after the called from line) may be already one environment level higher and may be necessary to access them.

At the moment this backtrace does not work from within compiled code (this includes the method selection which by default is compiled into the kernel). If this creates problems for debugging, call &GAP; with the -M option (see ) to avoid loading compiled code.

(Function calls to and methods installed for binary operations are handled in a special way. In rare circumstances it is possible therefore that they do not show up in a log but the log refers to the last proper function call that happened before.)

The command line option -T to &GAP; disables the break loop. This is mainly intended for testing purposes and for special applications. If this option is given then errors simply cause &GAP; to return to the main loop.
Variable Access in a Break Loop

In a break loop access to variables of the current break level and higher levels is possible, but if the same variable name is used for different objects or if a function calls itself recursively, of course only the variable at the lowest level can be accessed.

DownEnv and UpEnv
moves down nr steps in the environment and allows one to inspect variables on this level; if nr is negative it steps up in the environment again; nr defaults to 1 if not given. acts similarly to but in the reverse direction (the mnemonic rule to remember the difference between and is the order in which commands on the execution stack are displayed by ).

gap> OnBreak := function() Where(0); end;; # eliminate back-tracing on gap> # entry to break loop gap> test:= function( n ) > if n > 3 then Error( "!\n" ); fi; test( n+1 ); end;; gap> test( 1 ); Error, ! Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> Where(); called from test( n + 1 ); called from test( n + 1 ); called from test( n + 1 ); called from <function>( <arguments> ) called from read-eval-loop brk> n; 4 brk> DownEnv(); brk> n; 3 brk> Where(); called from test( n + 1 ); called from test( n + 1 ); called from <function>( <arguments> ) called from read-eval-loop brk> DownEnv( 2 ); brk> n; 1 brk> Where(); called from <function>( <arguments> ) called from read-eval-loop brk> DownEnv( -2 ); brk> n; 3 brk> quit; gap> OnBreak := Where;; # restore OnBreak to its default value

Note that the change of the environment caused by only affects variable access in the break loop. If you use return to continue a calculation &GAP; automatically jumps to the right environment level again.

Note also that search for variables looks first in the chain of outer functions which enclosed the definition of a currently executing function, before it looks at the chain of calling functions which led to the current invocation of the function.

gap> foo := function() > local x; x := 1; > return function() local y; y := x*x; Error("!!\n"); end; > end; function( ) ... end gap> bar := foo(); function( ) ... end gap> fun := function() local x; x := 3; bar(); end; function( ) ... end gap> fun(); Error, !! called from bar( ); called from <function>( <arguments> ) called from read-eval-loop Entering break read-eval-print loop ... you can 'quit;' to quit to outer loop, or you can 'return;' to continue brk> x; 1 brk> DownEnv(1); brk> x; 3

Here the x of foo which contained the definition of bar is found before that of fun which caused its execution. Using we can access the x from fun.
Error and ErrorCount
signals an error from within a function. First the messages messages are printed, this is done exactly as if (see ) were called with these arguments. Then a break loop (see ) is entered, unless the standard error output is not connected to a terminal. You can leave this break loop with return; to continue execution with the statement following the call to .
returns a count of the number of errors (including user interruptions) which have occurred in the &GAP; session so far. This count is reduced modulo 2^{28} on 32 bit systems, 2^{60} on 64 bit systems. The count is incremented by each error, even if &GAP; was started with the -T option to disable the break loop.
Leaving GAP
quit
exit
at exit functions
saving on exit
The normal way to terminate a &GAP; session is to enter either quit; (note the semicolon) or an end-of-file character (usually Ctrl-D) at the gap> prompt in the main read eval print loop.

An emergency way to leave &GAP; is to enter QUIT QUIT at any gap> or brk> or brk_nn> prompt.
Before actually terminating, &GAP; will call (with no arguments) all of the functions that have been installed using InstallAtExit. These typically perform tasks such as cleaning up temporary files created during the session, and closing open files. If an error occurs during the execution of one of these functions, that function is simply abandoned, no break loop is entered.

gap> InstallAtExit(function() Print("bye\n"); end); gap> quit; bye

During execution of these functions, the global variable QUITTING will be set to true if &GAP; is exiting because the user typed QUIT and false otherwise. Since QUIT is considered as an emergency measure, different action may be appropriate.
If, when &GAP; is exiting due to a quit or end-of-file (i.e. not due to a QUIT) the variable is bound to a string value, then the system will try to save the workspace to that file.
Line Editing

In most installations &GAP; will be compiled to use the Gnu readline library (see the line Libs used: on &GAP; startup). In that case skip to the next section . (The line editing commands described in the rest of this section were available in previous versions of &GAP;, they will work almost the same in the standard configuration of the Gnu readline library.)

&GAP; allows one you to edit the current input line with a number of editing commands. Those commands are accessible either as control keys or as escape keys. You enter a control key by pressing the Ctrl key, and, while still holding the Ctrl key down, hitting another key key. You enter an escape key by hitting Esc and then hitting another key key. Below we denote control keys by Ctrl-key and escape keys by Esc-key. The case of key does not matter, i.e., Ctrl-A and Ctrl-a are equivalent.

Normally, line editing will be enabled if the input is connected to a terminal. Line editing can be enabled or disabled using the command line options -f and -n respectively (see ), however this is a machine dependent feature of &GAP;.

Typing Ctrl-key or Esc-key for characters not mentioned below always inserts Ctrl-key resp. Esc-key at the current cursor position.

The first few commands allow you to move the cursor on the current line.

Ctrl-A
move the cursor to the beginning of the line.
Esc-B
move the cursor to the beginning of the previous word.
Ctrl-B
move the cursor backward one character.
Ctrl-F
move the cursor forward one character.
Esc-F
move the cursor to the end of the next word.
Ctrl-E
move the cursor to the end of the line.

The next commands delete or kill text. The last killed text can be reinserted, possibly at a different position, with the yank command Ctrl-Y. Ctrl-H or del delete the character left of the cursor. Ctrl-D delete the character under the cursor. Ctrl-K kill up to the end of the line. Esc-D kill forward to the end of the next word. Esc-del kill backward to the beginning of the last word. Ctrl-X kill entire input line, and discard all pending input. Ctrl-Y insert (yank) a just killed text.

The next commands allow you to change the input.

Ctrl-T
exchange (twiddle) current and previous character.
Esc-U
uppercase next word.
Esc-L
lowercase next word.
Esc-C
capitalize next word.

The Tab character, which is in fact the control key Ctrl-I, looks at the characters before the cursor, interprets them as the beginning of an identifier and tries to complete this identifier. If there is more than one possible completion, it completes to the longest common prefix of all those completions. If the characters to the left of the cursor are already the longest common prefix of all completions hitting Tab a second time will display all possible completions.

tab
complete the identifier before the cursor.

The next commands allow you to fetch previous lines, e.g., to correct typos, etc.

Ctrl-L
insert last input line before current character.
Ctrl-P
redisplay the last input line, another Ctrl-P will redisplay the line before that, etc. If the cursor is not in the first column only the lines starting with the string to the left of the cursor are taken.
Ctrl-N
Like Ctrl-P but goes the other way round through the history.
Esc-<
goes to the beginning of the history.
Esc->
goes to the end of the history.
Ctrl-O
accepts this line and perform a Ctrl-N.

Finally there are a few miscellaneous commands.

Ctrl-V
enter next character literally, i.e., enter it even if it is one of the control keys.
Ctrl-U
execute the next line editing command 4 times.
Esc- num
execute the next line editing command num times.
Esc-Ctrl-L
redisplay input line.

The four arrow keys (cursor keys) can be used instead of Ctrl-B, Ctrl-F, Ctrl-P, and Ctrl-N, respectively.

<#Include Label="readline">

Editing Files

In most cases, it is preferable to create longer input (in particular &GAP; programs) separately in an editor, and to read in the result via . Note that by default reads from the directory in which &GAP; was started (respectively under Windows the directory containing the &GAP; binary), so you might have to give an absolute path to the file.

If you cannot create several windows, the command may be used to leave &GAP;, start an editor, and read in the edited file automatically.

<#Include Label="Edit">

Editor Support
utilities for editing GAP files
vi
vim
emacs
In the etc subdirectory of the &GAP; installation we provide some setup files for the editors vim and emacs/xemacs.

vim
is a powerful editor that understands the basic vi commands but provides much more functionality. You can find more information about it (and download it) from http://www.vim.org.

To get support for &GAP; syntax in vim, create in your home directory a directory .vim with subdirectories .vim/syntax and .vim/indent (If you are not using Unix, refer to the vim documentation on where to place syntax files). Then copy the file etc/gap.vim to .vim/syntax/gap.vim and the file etc/gap_indent.vim to .vim/indent/gap.vim.

Then edit the .vimrc file in your home directory. Add lines as in the following example:

if has("syntax") syntax on " Default to no syntax highlightning endif

" For GAP files augroup gap " Remove all gap autocommands au! autocmd BufRead,BufNewFile *.g,*.gi,*.gd set filetype=gap comments=s:##\ \ ,m:##\ \ ,e:##\ \ b:#

" I'm using the external program `par' for formating comment lines starting " with `## '. Include these lines only when you have par installed. autocmd BufRead,BufNewFile *.g,*.gi,*.gd set formatprg="par w76p4s0j" autocmd BufWritePost,FileWritePost *.g,*.gi,*.gd set formatprg="par w76p0s0j" augroup END

See the headers of the two mentioned files for additional comments and adjust details according to your personal taste. Send comments and suggestions to support@gap-system.org. Setup files for emacs/xemacs are contained in the etc/emacs subdirectory.

Changing the Screen Size
Called with no arguments, returns the size of the screen as a list with two entries. The first is the length of each line, the second is the number of lines.

Called with one argument that is a list sz, sets the size of the screen; The first entry of sz, if bound, is the length of each line, and the second entry of sz, if bound, is the number of lines. The values for unbound entries of sz are left unaffected. The function returns the new values.

Note that those parameters can also be set with the command line options -x for the line length and -y for the number of lines (see Section ).

To check/change whether line breaking occurs for files and streams see and .

The line length must be between 20 and 4096 characters (inclusive) and the number of lines must be at least 10. Values outside this range will be adjusted to the nearest endpoint of the range.
Teaching Mode

When using &GAP; in the context of (undergraduate) teaching it is often desirable to simplify some of the system output and functionality defaults (potentially at the cost of making the printing of objects more expensive). This can be achieved by turning on a teaching mode:

When called with a boolean argument switch, this function will turn teaching mode respectively on or off. gap> a:=Z(11)^3; Z(11)^3 gap> TeachingMode(true); #I Teaching mode is turned ON gap> a; ZmodnZObj(8,11) gap> TeachingMode(false); #I Teaching mode is turned OFF gap> a; Z(11)^3

At the moment, teaching mode changes the following things

Prime Field Elements
Elements of fields of prime order are printed as instead as power of a primitive root.
Quadratic Irrationalities
Elements of a quadratic extension of the rationals are printed using the square root instead of using roots of unity.
Creation of some small groups
The group creator functions , , , and create by default (if no other representation is specified) not a pc group, but a finitely presented group, which makes the generators easier to interpret.