Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 Bib Ind
[Top of Book] [Contents] [Previous Chapter] [Next Chapter]

[MathJax on]

76 GAP Packages
76.1 Installing a GAP Package
76.2 Loading a GAP Package
76.2-1 LoadPackage
76.2-2 SetPackagePath
76.2-3 ExtendRootDirectories
76.2-4 DisplayPackageLoadingLog
76.3 Functions for GAP Packages
76.3-1 ReadPackage
76.3-2 TestPackageAvailability
76.3-3 InstalledPackageVersion
76.3-4 DirectoriesPackageLibrary
76.3-5 DirectoriesPackagePrograms
76.3-6 CompareVersionNumbers
76.3-7 IsPackageMarkedForLoading
76.3-8 DeclareAutoreadableVariables
76.3-9 Kernel modules in GAP packages
76.3-10 LoadDynamicModule
76.3-11 The PackageInfo.g File
76.3-12 ValidatePackageInfo
76.3-13 ShowPackageVariables
76.3-14 BibEntry

### 76 GAP Packages

The functionality of GAP can be extended by loading GAP packages. GAP distribution already contains all currently redistributed with GAP packages in the `gap4r6/pkg` directory.

GAP packages are written by (groups of) GAP users which may not be members of the GAP developer team. The responsibility and copyright of a GAP package remains with the original author(s).

GAP packages have their own documentation which is smoothly integrated into the GAP help system.

All GAP users who develop new code are invited to share the results of their efforts with other GAP users by making the code and its documentation available in form of a package. Information how to do this is available from the GAP Web pages (http://www.gap-system.org) and in the GAP package Example (see http://www.gap-system.org/Packages/example.html). There are possibilities to get a package distributed together with GAP and it is possible to submit a package to a formal refereeing process.

In this chapter we describe how to use existing packages.

#### 76.1 Installing a GAP Package

Before a package can be used it must be installed. With a standard installation of GAP there should be all currently redistributed with GAP packages already available. But since GAP packages are released independently of the main GAP system it may be sensible to upgrade or install new packages between upgrades of your GAP installation.

A package consists of a collection of files within a single directory that must be a subdirectory of the `pkg` directory in one of the GAP root directories, see 9.2. (If you don't have access to the `pkg` directory in your main GAP installation you can add private root directories as explained in that section.)

Whenever you get from somewhere an archive of a GAP package it should be accompanied with a `README` file that explains its installation. Some packages just consist of GAP code and the installation is done by unpacking the archive in one of the places described above. There are also packages that need further installation steps, there may be for example some external programs which have to be compiled (this is often done by just saying `./configure; make` inside the unpacked package directory, but check the individual `README` files). Note that if you use Windows you may not be able to use some or all external binaries.

#### 76.2 Loading a GAP Package

Some GAP packages are prepared for automatic loading, that is they will be loaded automatically with GAP, others must in each case be separately loaded by a call to `LoadPackage` (76.2-1).

##### 76.2-1 LoadPackage

`‣ LoadPackage`( name[, version][, banner] ) | ( function )

loads the GAP package with name name. If the optional version string version is given, the package will only be loaded in a version number at least as large as version, or equal to version if its first character is `=` (see `CompareVersionNumbers` (76.3-6)). The argument name is case insensitive.

`LoadPackage` will return `true` if the package has been successfully loaded and will return `fail` if the package could not be loaded. The latter may be the case if the package is not installed, if necessary binaries have not been compiled, or if the version number of the available version is too small. If the package cannot be loaded, `TestPackageAvailability` (76.3-2) can be used to find the reasons. Also, `DisplayPackageLoadingLog` (76.2-4) can be used to find out more about the failure reasons. To see the problems directly, one can change the verbosity using the user preference `InfoPackageLoadingLevel`, see `InfoPackageLoading` (76.2-4) for details.

If the package name has already been loaded in a version number at least or equal to version, respectively, `LoadPackage` returns `true` without doing anything else.

The argument name may be the prefix of a package name. If no package with name name is installed, the behaviour is as follows. If name is the prefix of exactly one name of an installed package then `LoadPackage` is called with this name; if the names of several installed packages start with name then the these names are printed, and `LoadPackage` returns `fail`. Thus the names of all installed packages can be shown by calling `LoadPackage` with an empty string.

If the optional argument banner is present then it must be either `true` or `false`; in the latter case, the effect is that no package banner is printed.

After a package has been loaded its code and documentation should be available as other parts of the GAP library are.

When GAP is started then some packages are loaded automatically. These are the packages listed in `GAPInfo.Dependencies.NeededOtherPackages` and (if this is not disabled, see below) `UserPreference( "PackagesToLoad" )`.

A GAP package may also install only its documentation automatically but still need loading by `LoadPackage`. In this situation the online help displays `(not loaded)` in the header lines of the manual pages belonging to this GAP package.

If for some reason you don't want certain packages to be automatically loaded, GAP provides three levels for disabling autoloading:

The autoloading of specific packages can be overwritten for the whole GAP installation by putting a file `NOAUTO` into a `pkg` directory that contains lines with the names of packages which should not be automatically loaded.

Furthermore, individual users can disable the autoloading of specific packages by putting the names of these packages into the list that is assigned to the user preference "ExcludeFromAutoload", for example in the user's `gap.ini` file (see 3.2-1).

Using the `-A` command line option when starting up GAP (see 3.1), automatic loading of packages is switched off for this GAP session.

In any of the above three cases, the packages listed in `GAPInfo.Dependencies.NeededOtherPackages` are still loaded automatically, and an error is signalled if not all of these packages are available.

See `SetPackagePath` (76.2-2) for a possibility to force that a prescribed package version will be loaded. See also `ExtendRootDirectories` (76.2-3) for a possibility to add directories containing packages after GAP has been started.

##### 76.2-2 SetPackagePath

`‣ SetPackagePath`( pkgname, pkgpath ) | ( function )

Let pkgname and pkgpath be strings denoting the name of a GAP package and the path to a directory where a version of this package can be found (i. e., calling `Directory` (9.3-2) with the argument pkgpath will yield a directory that contains the file `PackageInfo.g` of the package).

If the package pkgname is already loaded with an installation path different from pkgpath then `SetPackagePath` signals an error. If the package pkgname is not yet loaded then `SetPackagePath` erases the information about available versions of the package pkgname, and stores the record that is contained in the `PackageInfo.g` file at pkgpath instead, such that only the version installed at pkgpath can be loaded with `LoadPackage` (76.2-1).

This function can be used to force GAP to load a particular version of a package, although newer versions of the package might be available.

##### 76.2-3 ExtendRootDirectories

`‣ ExtendRootDirectories`( paths ) | ( function )

Let paths be a list of strings that denote paths to intended GAP root directories (see 9.2). The function `ExtendRootDirectories` adds these paths to the global list `GAPInfo.RootPaths` and calls the initialization of available GAP packages, such that later calls to `LoadPackage` (76.2-1) will find the GAP packages that are contained in `pkg` subdirectories of the directories given by paths.

Note that the purpose of this function is to make GAP packages in the given directories available. It cannot be used to influence the start of GAP, because the GAP library is loaded before `ExtendRootDirectories` can be called (and because `GAPInfo.RootPaths` is not used for reading the GAP library).

##### 76.2-4 DisplayPackageLoadingLog

`‣ DisplayPackageLoadingLog`( [severity] ) | ( function )

`‣ InfoPackageLoading` | ( info class )

`‣ PACKAGE_ERROR` | ( global variable )

`‣ PACKAGE_WARNING` | ( global variable )

`‣ PACKAGE_INFO` | ( global variable )

`‣ PACKAGE_DEBUG` | ( global variable )

`‣ LogPackageLoadingMessage`( severity, message[, name] ) | ( function )

Whenever GAP considers loading a package, log messages are collected in a global list. The messages for the current GAP session can be displayed with `DisplayPackageLoadingLog`. To each message, a "severity" is assigned, which is one of `PACKAGE_ERROR`, `PACKAGE_WARNING`, `PACKAGE_INFO`, `PACKAGE_DEBUG`, in increasing order. The function `DisplayPackageLoadingLog` shows only the messages whose severity is at most severity, the default for severity is `PACKAGE_WARNING`.

The intended meaning of the severity levels is as follows.

PACKAGE_ERROR

  should be used whenever GAP will run into an error during package loading, where the reason of the error shall be documented in the global list.

PACKAGE_WARNING

  should be used whenever GAP has detected a reason why a package cannot be loaded, and where the message describes how to solve this problem, for example if a package binary is missing.

PACKAGE_INFO

  should be used whenever GAP has detected a reason why a package cannot be loaded, and where it is not clear how to solve this problem, for example if the package is not compatible with other installed packages.

PACKAGE_DEBUG

  should be used for other messages reporting what GAP does when it loads packages (checking dependencies, reading files, etc.). One purpose is to record in which order packages have been considered for loading or have actually been loaded.

The log messages are created either by the functions of GAP's package loading mechanism or in the code of your package, for example in the `AvailabilityTest` function of the package's `PackageInfo.g` file (see 76.3-11), using `LogPackageLoadingMessage`. The arguments of this function are severity (which must be one of the above severity levels), message (which must be either a string or a list of strings), and optionally name (which must be the name of the package to which the message belongs). The argument name is not needed if the function is called from a call of a package's `AvailabilityTest` function (see 76.3-11) or is called from a package file that is read from `init.g` or `read.g`; in these cases, the name of the current package (stored in the record `GAPInfo.PackageCurrent`) is taken. According to the above list, the severity argument of `LogPackageLoadingMessage` calls in a package's `AvailabilityTest` function is either `PACKAGE_WARNING` or `PACKAGE_INFO`.

If you want to see the log messages already during the package loading process, you can set the level of the info class `InfoPackageLoading` to one of the severity values listed above; afterwards the messages with at most this severity are shown immediately when they arise. In order to make this work already for autoloaded packages, you can call `SetUserPreference("InfoPackageLoadingLevel", lev);` to set the desired severity level lev. This can for example be done in your `gap.ini` file, see Section 3.2-1.

#### 76.3 Functions for GAP Packages

The following functions are mainly used in files contained in a package and not by users of a package.

##### 76.3-1 ReadPackage

`‣ ReadPackage`( [name, ]file ) | ( function )

`‣ RereadPackage`( [name, ]file ) | ( function )

Called with two strings name and file, `ReadPackage` reads the file file of the GAP package name, where file is given as a path relative to the home directory of name. Note that file is read in the namespace of the package, see Section 4.10 for details.

If only one argument file is given, this should be the path of a file relative to the `pkg` subdirectory of GAP root paths (see 9.2). Note that in this case, the package name is assumed to be equal to the first part of file, so the one argument form is not recommended.

The absolute path is determined as follows. If the package in question has already been loaded then the file in the directory of the loaded version is read. If the package is available but not yet loaded then the directory given by `TestPackageAvailability` (76.3-2) is used, without prescribed version number. (Note that the `ReadPackage` call does not force the package to be loaded.)

If the file is readable then `true` is returned, otherwise `false`.

Each of name and file should be a string. The name argument is case insensitive.

`RereadPackage` does the same as `ReadPackage`, except that also read-only global variables are overwritten (cf. `Reread` (9.7-9)).

##### 76.3-2 TestPackageAvailability

`‣ TestPackageAvailability`( name[, version][, checkall] ) | ( function )

For strings name and version, this function tests whether the GAP package name is available for loading in a version that is at least version, or equal to version if the first character of version is `=` (see `CompareVersionNumbers` (76.3-6) for further details about version numbers).

The result is `true` if the package is already loaded, `fail` if it is not available, and the string denoting the GAP root path where the package resides if it is available, but not yet loaded. So the package name is available if the result of `TestPackageAvailability` is not equal to `fail`.

If the optional argument checkall is `true` then all dependencies are checked, even if some have turned out to be not satisfied. This is useful when one is interested in the reasons why the package name cannot be loaded. In this situation, calling first `TestPackageAvailability` and then `DisplayPackageLoadingLog` (76.2-4) with argument `PACKAGE_INFO` (76.2-4) will give an overview of these reasons.

You should not call `TestPackageAvailability` in the test function of a package (the value of the component `AvailabilityTest` in the `PackageInfo.g` file of the package, see 76.3-11), because `TestPackageAvailability` calls this test function.

The argument name is case insensitive.

##### 76.3-3 InstalledPackageVersion

`‣ InstalledPackageVersion`( name ) | ( function )

If the GAP package with name name has already been loaded then `InstalledPackageVersion` returns the string denoting the version number of this version of the package. If the package is available but has not yet been loaded then the version number string for that version of the package that currently would be loaded. (Note that loading another package might force loading another version of the package name, so the result of `InstalledPackageVersion` will be different afterwards.) If the package is not available then `fail` is returned.

The argument name is case insensitive.

##### 76.3-4 DirectoriesPackageLibrary

`‣ DirectoriesPackageLibrary`( name[, path] ) | ( function )

takes the string name, a name of a GAP package, and returns a list of directory objects for those sub-directory/ies containing the library functions of this GAP package, for the version that is already loaded or is currently going to be loaded or would be the first version GAP would try to load if no other version is explicitly prescribed. (If the package name is not yet loaded then we cannot guarantee that the returned directories belong to a version that really can be loaded.)

The default is that the library functions are in the subdirectory `lib` of the GAP package's home directory. If this is not the case, then the second argument path needs to be present and must be a string that is a path name relative to the home directory of the GAP package with name name.

Note that `DirectoriesPackageLibrary` is likely to be called in the `AvailabilityTest` function in the package's `PackageInfo.g` file (see 76.3-11).

As an example, the following returns a directory object for the library functions of the GAP package Example:

    gap> DirectoriesPackageLibrary( "Example", "gap" );
    [ dir("/home/werner/gap/4.0/pkg/example/gap/") ]

Observe that we needed the second argument `"gap"` here, since Example's library functions are in the subdirectory `gap` rather than `lib`.

In order to find a subdirectory deeper than one level in a package directory, the second argument is again necessary whether or not the desired subdirectory relative to the package's directory begins with `lib`. The directories in path should be separated by `/` (even on systems, like Windows, which use `\` as the directory separator). For example, suppose there is a package `somepackage` with a subdirectory `m11` in the directory `data`, then we might expect the following:

    gap> DirectoriesPackageLibrary( "somepackage", "data/m11" );
    [ dir("/home/werner/gap/4.0/pkg/somepackage/data/m11") ]

##### 76.3-5 DirectoriesPackagePrograms

`‣ DirectoriesPackagePrograms`( name ) | ( function )

returns a list of the `bin/`architecture subdirectories of all packages name where architecture is the architecture on which GAP has been compiled (this can be accessed as `GAPInfo.Architecture`, see `GAPInfo` (3.5-1)) and the version of the installed package coincides with the version of the package name that is already loaded or is currently going to be loaded or would be the first version GAP would try to load if no other version is explicitly prescribed. (If the package name is not yet loaded then we cannot guarantee that the returned directories belong to a version that really can be loaded.)

Note that `DirectoriesPackagePrograms` is likely to be called in the `AvailabilityTest` function in the package's `PackageInfo.g` file (see 76.3-11).

The directories returned by `DirectoriesPackagePrograms` are the place where external binaries of the GAP package name for the current package version and the current architecture should be located.

    gap> DirectoriesPackagePrograms( "nq" );
    [ dir("/home/gap/4.0/pkg/nq/bin/x86_64-unknown-linux-gnu-gcc/64-bit/"),
      dir("/home/gap/4.0/pkg/nq/bin/x86_64-unknown-linux-gnu-gcc/") ]

##### 76.3-6 CompareVersionNumbers

`‣ CompareVersionNumbers`( supplied, required[, "equal"] ) | ( function )

A version number is a string which contains nonnegative integers separated by non-numeric characters. Examples of valid version numbers are for example:

    "1.0"   "3.141.59"  "2-7-8.3" "5 release 2 patchlevel 666"

`CompareVersionNumbers` compares two version numbers, given as strings. They are split at non-digit characters, the resulting integer lists are compared lexicographically. The routine tests whether supplied is at least as large as required, and returns `true` or `false` accordingly. A version number ending in `dev` is considered to be infinite.

##### 76.3-7 IsPackageMarkedForLoading

`‣ IsPackageMarkedForLoading`( name, version ) | ( function )

This function can be used in the code of a package A, say, for testing whether the package name in version version will be loaded after the `LoadPackage` (76.2-1) call for the package A has been executed. This means that the package name had been loaded before, or has been (directly or indirectly) requested as a needed or suggested package of the package A or of a package whose loading requested that A was loaded.

##### 76.3-8 DeclareAutoreadableVariables

`‣ DeclareAutoreadableVariables`( pkgname, filename, varlist ) | ( function )

Let pkgname be the name of a package, let filename be the name of a file relative to the home directory of this package, and let varlist be a list of strings that are the names of global variables which get bound when the file is read. `DeclareAutoreadableVariables` notifies the names in varlist such that the first attempt to access one of the variables causes the file to be read.

##### 76.3-9 Kernel modules in GAP packages

If the package has a kernel module, then it can be compiled using the gac script. A kernel module is implemented in C and follows certain conventions to comply with the GAP kernel interface, which we plan to document later. In the meantime, we advice to get in touch with GAP developers if you plan to develop such a package.

To use the gac script to produce dynamically loadable modules, call it with the `-d` option, for example:

    $ gap4/bin/i386-ibm-linux-gcc2/gac -d test.c

This will produce a file `test.so`, which then can be loaded into GAP with `LoadDynamicModule` (76.3-10).

##### 76.3-10 LoadDynamicModule

`‣ LoadDynamicModule`( filename[, crc] ) | ( function )

To load a compiled file, the command `LoadDynamicModule` is used. This command loads filename as module. If given, the CRC checksum crc must match the value of the module (see 9.7-7).

    gap> LoadDynamicModule("./test.so");
    gap> CrcFile("test.so");
    2906458206
    gap> LoadDynamicModule("./test.so",1);
    Error, <crc> mismatch (or no support for dynamic loading) 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> quit;
    gap> LoadDynamicModule("./test.so",2906458206);

On some operating systems, once you have loaded a dynamic module with a certain filename, loading another with the same filename will have no effect, even if the file on disk has changed.

##### 76.3-11 The PackageInfo.g File

Each package has the file `PackageInfo.g` which contains meta-information about the package (package name, version, author(s), relations to other packages, homepage, download archives, banner, etc.). This file is used by the package loading mechanism and also for the distribution of a package to other users.

##### 76.3-12 ValidatePackageInfo

`‣ ValidatePackageInfo`( info ) | ( function )

This function is intended to support package authors who create or modify `PackageInfo.g` files. (It is not called when these files are read during the startup of GAP or when packages are actually loaded.)

The argument info must be either a record as is contained in a `PackageInfo.g` file or a a string which describes the path to such a file. The result is `true` if the record or the contents of the file, respectively, has correct format, and `false` otherwise; in the latter case information about the incorrect components is printed.

Note that the components used for package loading are checked as well as the components that are needed for composing the package overview web page or for updating the package archives.

If info is a string then `ValidatePackageInfo` checks additionally whether those package files exist that are mentioned in the file `info`, for example the `manual.six` file of the package documentation.

##### 76.3-13 ShowPackageVariables

`‣ ShowPackageVariables`( pkgname[, version][, arec] ) | ( function )

`‣ PackageVariablesInfo`( pkgname, version ) | ( function )

Let pkgname be the name of a GAP package. If the package pkgname is available but not yet loaded then `ShowPackageVariables` prints a list of global variables that become bound and of methods that become installed when the package is loaded. (For that, GAP actually loads the package.)

If a version number version is given (see Section Example: Version Numbers) then this version of the package is considered.

An error message is printed if (the given version of) the package is not available or already loaded.

Information is printed about new and redeclared global variables, and about names of global variables introduced in the package that differ from existing globals only by case; note that the GAP help system is case insensitive, so it is difficult to document identifiers that differ only by case.

Info lines for undocumented variables are marked with an asterisk `*`.

The following entries are omitted from the list: default setter methods for attributes and properties that are declared in the package, and `Setattr` and `Hasattr` type variables where attr is an attribute or property.

The output can be customized using the optional record arec, the following components of this record are supported.

`show`

  a list of strings describing those kinds of variables which shall be shown, such as `"new global functions"`; the default are all kinds that appear in the package,

`showDocumented`

  `true` (the default) if documented variables shall be shown, and `false` otherwise,

`showUndocumented`

  `true` (the default) if undocumented variables shall be shown, and `false` otherwise,

`showPrivate`

  `true` (the default) if variables from the package's name space (see Section 4.10) shall be shown, and `false` otherwise,

`Display`

  a function that takes a string and shows it on the screen; the default is `Print` (6.3-4), another useful value is `Pager` (2.4-1).

An interactive variant of `ShowPackageVariables` is the function `BrowsePackageVariables` (Browse: BrowsePackageVariables) that is provided by the GAP package Browse. For this function, it is not sensible to assume that the package pkgname is not yet loaded before the function call, because one might be interested in packages that must be loaded before Browse itself can be loaded. The solution is that `BrowsePackageVariables` (Browse: BrowsePackageVariables) takes the output of `PackageVariablesInfo` as its second argument. The function `PackageVariablesInfo` is used by both `ShowPackageVariables` and `BrowsePackageVariables` (Browse: BrowsePackageVariables) for collecting the information about the package in question, and can be called before the package Browse is loaded.

##### 76.3-14 BibEntry

`‣ BibEntry`( pkgname[, key] ) | ( function )

Returns: a string in BibXMLext format (see GAPDoc: The BibXMLext Format) that can be used for referencing the GAP system or a GAP package.

If the argument pkgname is the string `"GAP"`, the function returns an entry for the current version of GAP.

Otherwise, if a string pkgname is given, which is the name of a GAP package, an entry for this package is returned; this entry is computed from the `PackageInfo.g` file of the current version of the package, see `InstalledPackageVersion` (76.3-3). If no package with name pkgname is installed then the empty string is returned.

A string for a different version of GAP or a package can be computed by entering, as the argument pkgname, the desired record from the `PackageInfo.g` file. (One can access these records using the function `PackageInfo`.)

In each of the above cases, an optional argument key can be given, a string which is then used as the key of the BibTeX entry instead of the default key that is generated from the system/package name and the version number.

`BibEntry` requires the functions `FormatParagraph` (GAPDoc: FormatParagraph) and `NormalizedNameAndKey` (GAPDoc: NormalizedNameAndKey) from the GAP package GAPDoc.

The functions `ParseBibXMLextString` (GAPDoc: ParseBibXMLextString) and `StringBibXMLEntry` (GAPDoc: StringBibXMLEntry) can be used to create for example a BibTeX entry from the return value, as follows.

    gap> bib:= BibEntry( "GAP", "GAP4.5" );;
    gap> Print( bib, "\n" );
    <entry id="GAP4.5"><misc>
      <title><C>GAP</C> &ndash; <C>G</C>roups, <C>A</C>lgorithms,
             and <C>P</C>rogramming, <C>V</C>ersion 4.5.1</title>
      <howpublished><URL>http://www.gap-system.org</URL></howpublished>
      <key>GAP</key>
      <keywords>groups; *; gap; manual</keywords>
      <other type="organization">The GAP <C>G</C>roup</other>
    </misc></entry>
    gap> parse:= ParseBibXMLextString( bib );;
    gap> Print( StringBibXMLEntry( parse.entries[1], "BibTeX" ) );
    @misc{ GAP4.5,
      title =            {{GAP}   {\textendash}   {G}roups,   {A}lgorithms,  and
                          {P}rogramming, {V}ersion 4.5.1},
      organization =     {The GAP {G}roup},
      howpublished =     {\href                      {http://www.gap-system.org}
                          {\texttt{http://www.gap-system.org}}},
      key =              {GAP},
      keywords =         {groups; *; gap; manual}
    }

[Top of Book] [Contents] [Previous Chapter] [Next Chapter]
Goto Chapter: Top 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 Bib Ind

generated by GAPDoc2HTML