Welcome To Our Shell

Mister Spy & Souheyl Bypass Shell

Current Path : /usr/share/gap/doc/ref/

Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64
Upload File :
Current File : //usr/share/gap/doc/ref/chap76.txt

  
  76 Using and Developing GAP Packages
  
  The  functionality  of  GAP can be extended by loading GAP packages. The GAP
  distribution  already  contains  all currently redistributed GAP packages in
  the gap-4.10.2/pkg directory.
  
  GAP packages are written by (groups of) GAP users who may not necessarily 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.  (When  GAP  is started, LoadPackageDocumentation is
  called for all packages.)
  
  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. Guidance on how to do this is available from
  the  GAP website (https://www.gap-system.org) and in the GAP package Example
  (see https://www.gap-system.org/Packages/example.html).
  
  The  GAP development team will assist in making any new package suitable for
  distribution  with  GAP. It is also possible to submit a package to a formal
  refereeing process.
  
  In  this  chapter  we  first describe how to use existing packages, and then
  provide guidelines for writing a GAP package.
  
  
  76.1 Installing a GAP Package
  
  Before  a  package can be used it must be installed. A standard distribution
  of  GAP  already contains all the packages currently redistributed with GAP.
  This  set of packages has been checked for compatibility with the system and
  with each other during release preparation. Most of the packages can be used
  immediately,  but  some  of them may require further installation steps (see
  below).
  
  Also,  since GAP packages are released independently of the main GAP system,
  it  may  sometimes  be  useful  to  upgrade  or install new packages between
  upgrades  of  your GAP installation, e.g. if a new version of a package adds
  new capabilities or bug fixes that you need.
  
  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
  section 9.2.
  
  Whenever  you download or clone an archive of a GAP package, it will contain
  a  README file (or README.md etc.) that explains how it should be installed.
  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,  such  as compilation or
  installing  additional  software to satisfy their dependencies. If there are
  some  external  programs  which  have  to be compiled, this is often done by
  executing ./configure; make inside the unpacked package directory (but check
  the individual README files).
  
  Most  of  the  packages that require compilation can be compiled in a single
  step  by  changing to the pkg directory of your GAP installation and calling
  the ../bin/BuildPackages.sh script.
  
  Note that if you use Windows you may not be able to use some or all external
  binaries.
  
  
  76.2 Loading a GAP Package
  
  If  a  package  is  not  already loaded, it may be loaded using the function
  LoadPackage (76.2-1).
  
  Some  GAP  packages are prepared for automatic loading, that is they will be
  loaded automatically when GAP starts (see 76.2-2).
  
  76.2-1 LoadPackage
  
  LoadPackage( name[, version][, banner] )  function
  
  loads the GAP package with name name.
  
  As an example, the following loads the GAP package SONATA (case insensitive)
  which   provides  methods  for  the  construction  and  analysis  of  finite
  nearrings:
  
    Example  
    gap> LoadPackage("sonata");
    ... some more lines with package banner(s) ...
    true
  
  
  The  package  name is case insensitive and may be appropriately abbreviated.
  At  the  time  of  writing,  for example, LoadPackage("semi"); will load the
  Semigroups package, and LoadPackage("j"); will load the json package. If the
  abbreviation  cannot  be uniquely completed, a list of available completions
  will  be  offered,  and  LoadPackage  returns  fail.  Thus  the names of all
  installed packages can be shown by calling LoadPackage("");.
  
  When  the optional argument string version is present, the package will only
  be   loaded   in   a  version  number  equal  to  or  greater  than  version
  (see CompareVersionNumbers (76.3-9)). If the first character of version is =
  then only that version will be loaded.
  
  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-5) can be
  used  to  find out more about the failure. To see the problems directly, one
  can  change the verbosity using the user preference InfoPackageLoadingLevel,
  see InfoPackageLoading (76.2-5) for details.
  
  If  the package name has already been loaded in a version number equal to or
  greater than version, LoadPackage returns true without doing anything else.
  
  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, all its code becomes available to use with
  the rest of the GAP library.
  
  
  76.2-2 Automatic loading of GAP packages
  
  When GAP is started some packages are loaded automatically, and these belong
  to  two  categories.  The first are those packages which are needed to start
  GAP  (at  the  present time, the only such package is GAPDoc). Their list is
  contained   in   GAPInfo.Dependencies.NeededOtherPackages.  The  second  are
  packages which are loaded during GAP startup by default. The latter list may
  be  obtained by calling UserPreference("PackagesToLoad") and is customisable
  as described in Section 'Reference: Configuring User preferences'.
  
  While  GAP  will  not  start if any of the packages from the former group is
  missing,  loading of the packages from the latter group may be suppressed by
  using the -A command line option (see 3.1).
  
  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 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 any of these packages is unavailable.
  
  See  SetPackagePath  (76.2-3) for a way to force the loading of a prescribed
  package  version.  See  also  ExtendRootDirectories (76.2-4) for a method of
  adding directories containing packages after GAP has been started.
  
  76.2-3 SetPackagePath
  
  SetPackagePath( pkgname, pkgpath )  function
  
  This  function  can  be  used to force GAP to load a particular version of a
  package, even though newer versions of the package are available.
  
  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).
  
  76.2-4 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-5 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-13),
  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-13)  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. They are needed to organise reading package files
  into  GAP  in  the  right  order, performing maintenance tasks like building
  documentation and running package tests, checking package dependencies, etc.
  You  will  find  further  information  about  their  use in Section 76.4 and
  subsequent sections.
  
  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-10)).
  
  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-9) 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-5)  with argument PACKAGE_INFO (76.2-5) 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-13), because TestPackageAvailability calls
  this test function.
  
  The argument name is case insensitive.
  
  76.3-3 IsPackageLoaded
  
  IsPackageLoaded( name[, version] )  function
  
  For  strings  name  and version, this function tests whether the GAP package
  name  is  already  loaded in a version that is at least version, or equal to
  version  if  the  first character of version is = (see CompareVersionNumbers
  (76.3-9) for further details about version numbers).
  
  The result is true if the package is already loaded, false otherwise.
  
  76.3-4 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-5 TestPackage
  
  TestPackage( pkgname )  function
  
  It  is  recommended  that  a  GAP  package  specifies a standard test in its
  PackageInfo.g  file.  If pkgname is a string with the name of a GAP package,
  then TestPackage(pkgname) will check if this package is loadable and has the
  standard test, and will run this test in the current GAP session.
  
  The  output  of  the test depends on the particular package, and it also may
  depend  on  the  current  GAP  session (loaded packages, state of the random
  sources,  defined  global variables etc.). If you would like to run the test
  for the same package in the same setting that is used for the testing of GAP
  releases, you have to call
  
    Example  
    make testpackage PKGNAME=pkgname
  
  
  in  the  UNIX  shell  (without  quotes  around  pkgname).  This will run the
  standard test for the package pkgname three times in different settings, and
  will write test output to three files in the dev/log directory. These output
  files  will be named in the format testpackageX_timestamp.pkgname, where X=A
  for the test with packages loaded by default, X=1 for the test without other
  packages  (i.e.  when  GAP  is started with -A command line option), and X=2
  when the test is run with all packages loaded.
  
  76.3-6 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-7 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-13).
  
  As  an  example,  the  following  returns a directory object for the library
  functions of the GAP package Example:
  
    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:
  
    Example  
    gap> DirectoriesPackageLibrary( "somepackage", "data/m11" );
    [ dir("/home/werner/gap/4.0/pkg/somepackage/data/m11") ]
  
  
  76.3-8 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-13).
  
  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.
  
    Example  
    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-9 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:
  
    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-10 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-11 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:
  
    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-12).
  
  76.3-12 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).
  
    Example  
    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-13 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,  etc.).  This  file is used by the
  package  loading mechanism and also for the redistribution of a package with
  GAP
  
  76.3-14 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-15 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 'Reference: 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  (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
  (BrowsePackageVariables???)  takes the output of PackageVariablesInfo as its
  second   argument.   The  function  PackageVariablesInfo  is  used  by  both
  ShowPackageVariables  and BrowsePackageVariables (BrowsePackageVariables???)
  for  collecting  the  information  about the package in question, and can be
  called before the package Browse is loaded.
  
  76.3-16 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-6).  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.
  
    Example  
    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>https://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                      {https://www.gap-system.org}
                          {\texttt{https://www.gap-system.org}}},
      key =              {GAP},
      keywords =         {groups; *; gap; manual}
    }
  
  
  76.3-17 Cite
  
  Cite( [pkgname[, key]] )  function
  
  Used  with  no  arguments  or  with  argument "GAP" (case-insensitive), Cite
  displays  instructions  on  citing  the  version  of GAP that is being used.
  Suggestions  are  given  in plain text, HTML, BibXML and BibTeX formats. The
  same  instructions  are  also contained in the CITATION file in the GAP root
  directory.
  
  If pkgname is the name of a GAP package, instructions on citing this package
  will  be displayed. They will be produced from the PackageInfo.g file of the
  working  version  of  this  package  that  must  be  available  in  the  GAP
  installation  being  used. Otherwise, one will get a warning that no working
  version of the package is available.
  
  The optional 2nd argument key has the same meaning as in BibEntry (76.3-16).
  
  
  76.4 Guidelines for Writing a GAP Package
  
  The remaining part of this chapter explains the basics of how to write a GAP
  package so that it integrates properly into GAP.
  
  There are two basic aspects of creating a GAP package.
  
  First,  it is a convenient possibility to load additional functionality into
  GAP  including  a smooth integration of the package documentation. Second, a
  package is a way to make your code available to other GAP users.
  
  Moreover,  the  GAP  Group  may  provide  some help with redistributing your
  package  via the GAP website after checking if the package provides some new
  or  improved  functionality  which  looks interesting for other users, if it
  contains reasonable documentation, and if it seems to work smoothly with the
  GAP  library  and  other  distributed packages. In this case the package can
  take  part  in the GAP distribution update mechanism and becomes a deposited
  package.
  
  Furthermore, package authors are encouraged to check if the package would be
  appropriate  for the refereeing process and submit it. If the refereeing has
  been  successful,  the  package  becomes  an  accepted  package.  Check  out
  https://www.gap-system.org/Packages/Authors/authors.html  on the GAP website
  for more details.
  
  Below  we  start  with  a  description  how the directory structure of a GAP
  package  should  be  constructed  and then add remarks on certain aspects of
  creating  a  package, some of these only apply to some packages. Finally, we
  provide guidelines for the release preparation and its distribution.
  
  
  76.5 Structure of a GAP Package
  
  A  GAP  package  should  have an alphanumeric name (packagename, say); mixed
  case  is  fine, but there should be no whitespace characters. All files of a
  GAP  package packagename must be collected in a single directory packagedir,
  where   packagedir  should  be  just  packagename  optionally  converted  to
  lowercase  and  optionally  followed by the package version (with or without
  hyphen to separate the version from packagename). Let us call this directory
  the home directory of the package.
  
  To use the package with GAP, the directory packagedir must be a subdirectory
  of  a  pkg  directory  in  (one  of) the GAP root directories (see 9.2). For
  example,  if  GAP  is  installed  in  /usr/local/gap4  then the files of the
  package  MyPack  may  be placed in the directory /usr/local/gap4/pkg/mypack.
  The  directory  packagedir  preferably  should  have the following structure
  (below, a trailing / distinguishes directories from ordinary files):
  
    Example  
    packagedir/
      doc/
      lib/
      tst/
      CHANGES
      LICENSE
      README
      PackageInfo.g
      init.g
      read.g
  
  
  This   layout   of  directories  and  files  may  be  created  manually,  or
  automatically   using   the   tool   called   PackageMaker,   available   at
  https://github.com/gap-system/PackageMaker.  The  PackageMaker  asks several
  questions about the intended package and then creates a new directory for it
  and populates it with all the files needed for a basic package.
  
  Packages  that contain some code that requires compilation will usually have
  it  in  the  src  subdirectory.  They  may  also  have  extra  files such as
  configure,  Makefile.in  etc.  that  automate the build procedure. There are
  three  file names with a special meaning in the home directory of a package:
  PackageInfo.g  and  init.g  which  must  be  present,  and  read.g  which is
  optional.
  
  On  the  other  hand, the names of CHANGES, LICENSE and README files are not
  strictly fixed. They may have extensions .txt or .md, and instead of LICENSE
  one  could  use  e.g.  COPYING or GPL for packages distributed under the GNU
  General Public License, or use HISTORY instead of CHANGES.
  
  We now describe the above files and directories in more details:
  
   README
        The filename may optionally have an extension, e.g. .txt or .md.
  
        This  should  contain  how to get it instructions (covering the way of
        getting  it  with  the  GAP  distribution and from the GAP website, if
        applicable),  as  well  as  installation instructions and names of the
        package   authors   and  their  email  addresses.  These  installation
        instructions  should  be  repeated  or  referenced  from the package's
        documentation,  which  should  be  in  the  doc  directory (see 76.6).
        Authors'  names and addresses should be repeated both in the package's
        documentation and in the PackageInfo.g (see below).
  
   CHANGES
        For  further versions of the package, it will be also useful to have a
        CHANGES  file  that  records  the main changes between versions of the
        package.
  
        The filename may optionally have an extension, e.g. .txt or .md.
  
   LICENSE
        The   file   which   explains  conditions  on  which  the  package  is
        distributed.
  
        We  advise  all  package authors to make clear in the documentation of
        their  package  the  basis  on which it is being distributed to users.
        Technically, this is the terms of the license which you give the users
        to   copy,  modify  and  redistribute  your  software  (of  which  you
        presumably own the copyright) for their purposes.
  
        GAP itself is distributed under the GNU General Public License version
        2,  a popular free software license which allows users to redistribute
        it  freely  under the same terms, and requires that any software which
        incorporates  GAP  (technically, any derived work) also be distributed
        under those terms. We would encourage you to consider the GPL for your
        packages,  but  you  might  wish  to be more restrictive (for instance
        forbidding  redistribution  for  profit) or less restrictive (allowing
        your software to be incorporated into commercial software).
  
        The  filename may optionally have an extension, e.g. .txt or .md. Some
        packages also use different filenames, like COPYING.
  
  configure, Makefile.in
        These  files  are typically only used by packages which have a non-GAP
        component,  e.g. some  C code (the files of which should be in the src
        directory). The configure and Makefile.in files of the Example package
        provide  prototypes  (or  they  may  be created using the PackageMaker
        mentioned  above).  The  configure file typically takes a path path to
        the  GAP  root  directory  as  argument and uses the value assigned to
        GAParch  in  the  file  sysinfo.gap,  created when GAP was compiled to
        determine  the  compilation architecture, inserts this in place of the
        string @GAPARCH@ in Makefile.in and creates a file Makefile. When make
        is run (which, of course, reads the constructed Makefile), a directory
        bin  (if  necessary)  and subdirectories of bin with the path equal to
        the  string  assigned  to  GAParch  in  the file sysinfo.gap should be
        created;  any binaries constructed by compiling the code in src should
        end up in this subdirectory of bin.
  
  PackageInfo.g
        Every  GAP  package  must  have  a  PackageInfo.g  file which contains
        meta-information  about the package (package name, version, author(s),
        relations  to other packages, homepage, download archives, etc.). This
        information  is used by the package loading mechanism and also for the
        redistribution   of   a   package  with  GAP.  The  Example  package's
        PackageInfo.g  file  is  well-commented and can be used as a prototype
        (see  also  76.3-13 for further details). It may also be created using
        the PackageMaker mentioned above.
  
  init.g, read.g
        A GAP package must have a file init.g. Typical init.g and read.g files
        should normally consist entirely of ReadPackage (76.3-1) commands (and
        possibly  also Read (9.7-1) commands) for reading further files of the
        package.  If  the  declaration and implementation parts of the package
        are  separated  (and  this  is  recommended), there should be a read.g
        file.  The  declaration  part  of  a  package consists of function and
        variable  name declarations and these go in files with .gd extensions;
        these  files  are read in via ReadPackage commands in the init.g file.
        The   implementation   part  of  a  package  consists  of  the  actual
        definitions  of  the functions and variables whose names were declared
        in  the  declaration  part, and these go in files with .gi extensions;
        these  files  are read in via ReadPackage commands in the read.g file.
        The  reason  for following the above dichotomy is that the read.g file
        is  read  after  the  init.g  file, thus enabling the possibility of a
        function's  implementation  to refer to another function whose name is
        known  but  is  not  actually  defined  yet  (see 76.12 below for more
        details).
  
        The  GAP  code  (whether  or  not  it  is  split  into declaration and
        implementation  parts)  should  go in the package's lib directory (see
        below).
  
  doc
        This  directory should contain the package's documentation, written in
        an  XML-based documentation format supported by the GAP package GAPDoc
        (see  'GAPDoc:  Introduction  and  Example') which is used for the GAP
        documentation itself.
  
        The  Example  package's  documentation  (see its doc directory) may be
        used  as a prototype. It consists of the master file main.xml, further
        .xml  files  for  manual  chapters (included in the manual via Include
        directives  in the master file) and the GAP input file ../makedocrel.g
        which  generates  the  manuals.  Generally,  one should also provide a
        manual.bib BibTeX database file or an xml file in the BibXMLext format
        (see 'GAPDoc: The BibXMLext Format').
  
        One  could also use the AutoDoc which simplifies writing documentation
        by generating most of the GAPDoc code automatically.
  
  lib
        This  is the preferred place for the GAP code of the package, i.e. the
        .g,  .gd  and .gi files (other than PackageInfo.g, init.g and read.g).
        For some packages, the directory gap has been used instead of lib; lib
        has  the  advantage  that  it is the default subdirectory of a package
        directory  searched  for  by  the  DirectoriesPackageLibrary  (76.3-7)
        command.
  
  src
        If  the  package  contains non-GAP code, e.g. C code, then this source
        code should go in the src directory. If there are .h include files you
        may  prefer to put these all together in a separate include directory.
        There  is  one further rule for the location of kernel library modules
        or external programs which is explained in 76.14-1 below.
  
  tst
        It  is highly recommended that a package should have test files, which
        then  should  go in the tst directory. For a deposited package, a test
        file  with  a basic test of the package (for example, to check that it
        works  as expected and/or that the manual examples are correct) may be
        specified in the PackageInfo.g to be included in the GAP standard test
        suite  and run as a part of the GAP release preparation. More specific
        and  time  consuming  tests  are  not supposed to be a part of the GAP
        standard  test  suite  but  may  be  placed  in the tst directory with
        further  instructions  on how to run them. See Section 76.18 about the
        requirements to the test files formats and further recommendations.
  
  All other files can be organised as you like. But we suggest that you have a
  look  at  existing  packages  and  use  a  similar  scheme, for example, put
  examples   in   the   examples   subdirectory,   data   libraries  in  extra
  subdirectories, and so on.
  
  Sometimes  there  may be a need to include an empty directory in the package
  distribution  (for example, as a place to store some data that may appear at
  runtime).  In this case package authors are advised to put in this directory
  a  short  README  file  describing its purpose to ensure that such directory
  will be included in the redistribution.
  
  Concerning  the  GAP  code  in  packages,  it  is  recommended  to  use only
  documented  GAP  functions, see 83.3. In particular if you want to make your
  package available to other GAP users it is advisable to avoid using obsolete
  variables (see 77). To test that the package does not use obsolete variables
  you  can  set  the ReadObsolete component in your gap.ini file to false (see
  3.2)  or  start GAP with -A -O command line options (note that this may also
  cause problems with loading other packages that use obsolete variables).
  
  
  76.6 Writing Documentation and Tools Needed
  
  If  you intend to make your package available to other users it is essential
  to include documentation explaining how to install and use your programs.
  
  Concerning  the  installation you should produce a README file which gives a
  short  description  of  the  purpose  of  the  package  and  contains proper
  instructions  how  to  install  your package. Again, check out some existing
  packages to get an idea how this could look like.
  
  Documentation   for   GAP   package  should  be  prepared  in  an  XML-based
  documentation  format  that  is  defined  in and can be used with the GAPDoc
  package (see 'GAPDoc: Introduction and Example').
  
  There  should  be at least a text version of your documentation provided for
  use  in  the  terminal running GAP and some nicely printable version in .pdf
  format.  Many  GAP users like to browse the documentation in HTML format via
  their  Web  browser.  As a package author, you are not obliged to provide an
  HTML  version  of your package manual, but if you use the GAPDoc package you
  should have no trouble in producing one.
  
  Moreover,  using  the  GAPDoc  package,  it is also possible to produce HTML
  version  of  the  documentation supporting MathJax (http://www.mathjax.org/)
  for  the  high  quality  rendering  of mathematical symbols while viewing it
  online.  For  example,  if  you  are viewing the HTML version of the manual,
  compare how this formula will look with MathJax turned on/off:
  
  
  [ χ, ψ ] = ( ∑_{g ∈ G} χ(g) ψ(g^{-1}) ) / |G|.
  
  The  manual  of  the  Example  package  is written in the GAPDoc format, and
  commands  needed  to  build  it  are contained in the file makedocrel.g (you
  don't  need  to  re-build  the  manual  since  it is already included in the
  package). You will also need to have certain TeX tools installed: to produce
  manuals in the .pdf format, you need pdflatex.
  
  In  principle  it is also possible to use alternative documentation systems.
  Historically, there is one such TeX-based system, which predates GAPDoc, and
  which  is  still  in  use  by several packages. However, we do not recommend
  using it for new packages.
  
  
  76.7 An Example of a GAP Package
  
  We  illustrate  the  creation of a GAP package by an example of a very basic
  package.
  
  Create  the following directories in your home directory: .gap, .gap/pkg and
  .gap/pkg/test.  Then inside the directory .gap/pkg/test create an empty file
  init.g, and a file PackageInfo.g with the following contents:
  
    Example  
    SetPackageInfo( rec(
      PackageName := "test",
      Version := "1.0",
      PackageDoc := rec(
          BookName  := "test",
          SixFile   := "doc/manual.six",
          Autoload  := true ),
      Dependencies := rec(
          GAP       := "4.9",
          NeededOtherPackages := [ ["GAPDoc", "1.6"] ],
          SuggestedOtherPackages := [ ] ),
      AvailabilityTest := ReturnTrue ) );
  
  
  This  file  declares  the  GAP  package  with  name test in version 1.0. The
  package documentation consists of one autoloaded book; the SixFile component
  is  needed  by  the  GAP  help  system. Package dependencies (picked for the
  purposes  of  this  example)  require at least GAP 4.9 and GAPDoc package at
  version  at least 1.6, and these conditions will be checked when the package
  will  be loaded (see 76.17). Since there are no requirements that have to be
  tested, AvailabilityTest just uses ReturnTrue (5.4-1).
  
  Now  start  GAP (without using the -r option) and the .gap directory will be
  added  to the GAP root directory to allow GAP to find the packages installed
  there (see 9.2).
  
    Example  
    gap> LoadPackage("test");
    true
  
  
  This  GAP  package  is  too  simple  to  be useful, but we have succeeded in
  loading it via LoadPackage (76.2-1), satisfying all specified dependencies.
  
  
  76.8 File Structure
  
  Package  files  may follow the style used for the GAP library. Every file in
  the  GAP  library starts with a header that lists the filename, copyright, a
  short  description  of  the  file  contents and the original authors of this
  file,  and ends with a comment line #E. Indentation in functions and the use
  of  decorative spaces in the code are left to the decision of the authors of
  each  file. Global (i.e. re-used elsewhere) comments usually are indented by
  two hash marks and two blanks, in particular, every declaration or method or
  function  installation  which  is  not only of local scope is separated by a
  header.
  
  Facilities  to  distribute  a  document  over  several  files  to  allow the
  documentation  for  parts  of some code to be stored in the same file as the
  code  itself are provided by the GAPDoc package (see 'GAPDoc: Distributing a
  Document  into  Several  Files').  The  same approach is demonstrated by the
  Example  package.  E.g.  example/doc/example.xml has the statement <#Include
  Label="ListDirectory"> and example/lib/files.gd contains
  
    Example  
    ##  <#GAPDoc Label="ListDirectory">
    ##  <ManSection>
    ##  <Func Name="ListDirectory" Arg="[dir]"/>
    ##
    ##  <Description>
    ##  lists the files in directory <A>dir</A> (a string) 
    ##  or the current directory if called with no arguments.
    ##  </Description>
    ##  </ManSection>
    ##  <#/GAPDoc>
    DeclareGlobalFunction( "ListDirectory" );
  
  
  This  is  all put together in the file example/makedocrel.g which builds the
  package  documentation,  calling  MakeGAPDocDoc (GAPDoc: MakeGAPDocDoc) with
  locations of library files containing parts of the documentation.
  
  Alternatively,   one   could  use  the  AutoDoc,  which  simplifies  writing
  documentation  by  generating  most  of  the  GAPDoc code automatically. The
  equivalent of the fragment of the code above for AutoDoc would look like
  
    Example  
    #! @Arguments [dir]
    #! @Description
    #!  lists the files in directory <A>dir</A> (a string) 
    #!  or the current directory if called with no arguments.
    DeclareGlobalFunction( "ListDirectory" );
  
  
  
  76.9 Creating the PackageInfo.g File
  
  While the minimalistic PackageInfo.g file described in 76.7 is enough to let
  GAP  load  the package, and check all specified dependencies, it is actually
  missing  many  extra  fields which become relevant if you want to distribute
  your  package:  they  contain  lists of authors and/or maintainers including
  contact  information,  URLs of the package archives and README files, status
  information,  text  for  a  package  overview  webpage, and so on. All these
  details are required for a package to be redistributed with GAP.
  
  The  command  ValidatePackageInfo  (76.3-14) can be used to get a quick idea
  about which fields are missing:
  
    Example  
    gap> ValidatePackageInfo("PackageInfo.g");
    #E  component `Subtitle' must be bound to a string
    #E  component `Date' must be bound to a string of the form `dd/mm/yyyy'
    #E  component `ArchiveURL' must be bound to a string started with http://, https:// or ftp://
    #E  component `ArchiveFormats' must be bound to a string
    #E  component `Status' must be bound to one of "accepted", "deposited", "dev", "other"
    #E  component `README_URL' must be bound to a string started with http://, https:// or ftp://
    #E  component `PackageInfoURL' must be bound to a string started with http://, https:// or ftp://
    #E  component `AbstractHTML' must be bound to a string
    #E  component `PackageWWWHome' must be bound to a string started with http://, https:// or ftp://
    #E  component `ArchiveURLSubset' must be bound to a list of strings denoting relative paths to readable files or directories
    #E  component `HTMLStart' must be bound to a string denoting a relative path to a readable file
    #E  component `PDFFile' must be bound to a string denoting a relative path to a readable file
    #E  component `SixFile' must be bound to a string denoting a relative path to a readable file
    #E  component `LongTitle' must be bound to a string
    false
  
  
  We  suggest  to  create a PackageInfo.g file for your package by copying the
  one  in the Example package, distributed with GAP, or using the PackageMaker
  (https://github.com/gap-system/PackageMaker), and then adjusting it for your
  package.  Within  GAP  you  can  look  at  this template file for a list and
  explanation of all recognised entries by
  
    Example  
    Pager(StringFile(Filename(DirectoriesLibrary(), 
                              "../pkg/example/PackageInfo.g")));
  
  
  Instead  of  populating the rest of the PackageInfo.g by hands, you can also
  create  a  basic  GAP package with the help of the tool called PackageMaker,
  available  at  https://github.com/gap-system/PackageMaker.  The PackageMaker
  asks  several  questions  about  the intended package and then creates a new
  directory  for  it  and  populates  it with all the files needed for a basic
  package.
  
  
  76.10 Functions and Variables and Choices of Their Names
  
  In  writing the GAP code for your package you need to be a little careful on
  just how you define your functions and variables.
  
  Firstly,  in  general  one should avoid defining functions and variables via
  assignment statements in the way you would interactively, e.g.
  
    Example  
    gap> Squared := x -> x^2;;
    gap> Cubed := function(x) return x^3; end;;
  
  
  The  reason  for  this  is  that  such  functions  and  variables are easily
  overwritten and what's more you are not warned about it when it happens.
  
  To  protect a function or variable against overwriting there is the function
  BindGlobal  (4.9-8),  or  alternatively  (and equivalently) you may define a
  global    function    via    a    DeclareGlobalFunction    (79.18-14)    and
  InstallGlobalFunction   (79.18-14)   pair   or   a  global  variable  via  a
  DeclareGlobalVariable (79.18-15) and InstallValue (79.18-16) pair. There are
  also  operations  and their methods, and related objects like attributes and
  filters which also have Declare... and Install... pairs.
  
  Secondly, it's a good idea to reduce the chance of accidental overwriting by
  choosing  names  for  your  functions and variables that begin with a string
  that identifies it with the package, e.g. some of the undocumented functions
  in  the Example package begin with Eg. This is especially important in cases
  where  you  actually  want  the  user  to  be  able to change the value of a
  function or variable defined by your package, for which you have used direct
  assignments  (for which the user will receive no warning if she accidentally
  overwrites  them).  It's  also important for functions and variables defined
  via      BindGlobal,     DeclareGlobalFunction/InstallGlobalFunction     and
  DeclareGlobalVariable/InstallValue,  in order to avoid name clashes that may
  occur with (extensions of) the GAP library and other packages.
  
  Additionally,  since  GAP 4.5  a  package  may place global variables into a
  local  namespace  as  explained  in  4.10 in order to avoid name clashes and
  preserve  compatibility.  This  new  feature  allows  you  to define in your
  package  global variables with the identifier ending with the @ symbol, e.g.
  xYz@. Such variables may be used in your package code safely, as they may be
  accessed   from   outside   the  package  only  by  their  full  name,  i.e.
  xYz@YourPackageName.   This  helps  to  prevent  clashes  between  different
  packages  or  between  a  package  and  the  GAP library because of the same
  variable names.
  
  On   the   other   hand,   operations   and   their   methods  (defined  via
  DeclareOperation  (79.18-12),  InstallMethod  (78.2-1) etc. pairs) and their
  relatives  do  not  need  this  consideration, as they avoid name clashes by
  allowing for more than one method for the same-named object.
  
  To     demonstrate     the     definition    of    a    function    via    a
  DeclareOperation/InstallMethod  pair,  the  method  Recipe  (Recipe???)  was
  included  in  the  Example  package; Recipe( FruitCake ); gives a method for
  making a fruit cake (forgive the pun).
  
  Thirdly,  functions  or  variables with SetXXX or HasXXX names (even if they
  are defined as operations) should be avoided as these may clash with objects
  associated  with  attributes  or  properties  (attributes and properties XXX
  declared   via   the  DeclareAttribute  and  DeclareProperty  commands  have
  associated with them testers of form HasXXX and setters of form SetXXX).
  
  Fourthly,  it  is a good idea to have some convention for internal functions
  and  variables  (i.e. the  functions  and variables you don't intend for the
  user to use). For example, they might be entirely CAPITALISED.
  
  Additionally,  there  is  a  recommended naming convention that the GAP core
  system  and  GAP  packages  should  not use global variables starting in the
  lowercase. This allows to reserve variables with names starting in lowercase
  to  the  GAP  user so they will never clash with the system. It is extremely
  important  to  avoid  using  for  package  global variables very short names
  started  in  lowercase. For example, such names like cs, exp, ngens, pc, pow
  which  are  perfectly  fine  for  local  variables, should never be used for
  globals.  Additionally,  the package must not have writable global variables
  with  very  short names even if they are starting in uppercase, for example,
  C1 or ORB, since they also could be easily overwritten by the user.
  
  It  is a good practice to follow naming conventions used in GAP as explained
  in  5.6  and  'Tutorial:  Changing the Structure', which might help users to
  memorize or even guess names of functions provided by the package.
  
  Finally,         note         the         advantage         of         using
  DeclareGlobalFunction/InstallGlobalFunction,
  DeclareGlobalVariable/InstallValue,  etc. pairs  (rather than BindGlobal) to
  define  functions  and variables, which allow the package author to organise
  her  function- and variable- definitions in any order without worrying about
  any  interdependence.  The Declare... statements should go in files with .gd
  extensions  and  be  loaded  by ReadPackage statements in the package init.g
  file,  and the Install... definitions should go in files with .gi extensions
  and  be  loaded  by  ReadPackage statements in the package read.g file; this
  ensures  that  the .gi files are read after the .gd files. All other package
  code  should  go  in  .g  files  (other  than  the  init.g  and read.g files
  themselves) and be loaded via ReadPackage statements in the init.g file.
  
  In conclusion, here is some practical advice on how to check which variables
  are used by the package.
  
  Firstly,  there is a function ShowPackageVariables (76.3-15). If the package
  pkgname is available but not yet loaded then ShowPackageVariables( pkgname )
  prints  a  list  of  global  variables that become bound and of methods that
  become  installed  when the package is loaded (for that, the package will be
  actually  loaded,  so  ShowPackageVariables  can be called only once for the
  same  package in the same GAP session.) The second optional argument version
  may specify a particular package version to be loaded. An error message will
  be printed if (the given version of) the package is not available or already
  loaded.
  
  Info  lines  for  undocumented  variables will be marked with an asterisk *.
  Note  that  the  GAP  help system is case insensitive, so it is difficult to
  document identifiers that differ only by case.
  
  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.
  
  For  example, for the Example package it may produce the output looking like
  this:
  
    Example  
    gap> ShowPackageVariables("example");
    ----------------------------------------------------------------
    Loading  Example 3.3 (Example/Template of a GAP Package)
    by Werner Nickel (http://www.mathematik.tu-darmstadt.de/~nickel),
       Greg Gamble (http://www.math.rwth-aachen.de/~Greg.Gamble), and
       Alexander Konovalov (http://www.cs.st-andrews.ac.uk/~alexk/).
    ----------------------------------------------------------------
    new global functions:
      EgSeparatedString( str, c )*
      FindFile( dir, file )
      HelloWorld(  )
      ListDirectory( arg )
      LoadedPackages(  )
      WhereIsPkgProgram( prg )
      Which( prg )
    
    new global variables:
      FruitCake
    
    new operations:
      Recipe( arg )
    
    new methods:
      Recipe( cake )
  
  
  Another  trick  is  to  start  GAP with -r -A options, immediately load your
  package  and  then  call NamesUserGVars (4.9-11) which returns a list of the
  global  variable  names created since the library was read, to which a value
  is currently bound. For example, for the Example it produces
  
    Example  
    gap> NamesUserGVars();
    [ "EgSeparatedString", "FindFile", "FruitCake", "HelloWorld", "ListDirectory",
      "LoadedPackages", "Recipe", "WhereIsPkgProgram", "Which" ]
  
  
  but for packages with dependencies it will also contain variables created by
  other  packages.  Nevertheless,  it  may  be  a  useful  check to search for
  unwanted  variables appearing after package loading. A potentially dangerous
  situation which should be avoided is when the package uses some simply named
  temporary  variables  at  the loading stage. Such phantom variables may then
  remain  unnoticed  and,  as  a result, there will be no warnings if the user
  occasionally uses the same name as a local variable name in a function. Even
  more dangerous is the case when the user variable with the same name already
  exists before the package is loaded so it will be silently overwritten.
  
  
  76.11 Package Dependencies (Requesting one GAP Package from within Another)
  
  It is possible for one GAP package A, say, to require another package B. For
  that, one simply adds the name and the (least) version number of the package
  B  to the NeededOtherPackages component of the Dependencies component of the
  PackageInfo.g  file of the package A. In this situation, loading the package
  A forces that also the package B is loaded, and that A cannot be loaded if B
  is not available.
  
  If  B  is  not  essential for A but should be loaded if it is available (for
  example  because  B  provides  some improvements of the main system that are
  useful  for  A)  then the name and the (least) version number of B should be
  added  to the SuggestedOtherPackages component of the Dependencies component
  of  the  PackageInfo.g  file  of  A.  In this situation, loading A forces an
  attempt to load also B, but A is loaded even if B is not available.
  
  Also     the    component    Dependencies.OtherPackagesLoadedInAdvance    in
  PackageInfo.g  is  supported,  which describes needed packages that shall be
  loaded  before  the  current  package is loaded. See 76.12 for details about
  this  and  more generally about the order in which the files of the packages
  in question are read.
  
  All  package dependencies must be documented explicitly in the PackageInfo.g
  file. It is important to properly identify package dependencies and make the
  right  decision whether the other package should be needed or suggested. For
  example,  declaring package as needed when suggested might be sufficient may
  prevent loading of packages under Windows for no good reason.
  
  It  is  not  appropriate  to  explicitly  call LoadPackage (76.2-1) when the
  package  is  loaded, since this may distort the order of package loading and
  result in warning messages. It is recommended to turn such dependencies into
  needed or suggested packages. For example, a package can be designed in such
  a way that it can be loaded with restricted functionality if another package
  (or standalone program) is missing, and in this case the missing package (or
  binary)  is  suggested.  Alternatively,  if  the package author decides that
  loading  the  package  in  this  situation  makes no sense, then the missing
  component is needed.
  
  On the other hand, if LoadPackage (76.2-1) is called inside functions of the
  package  then  there  is  no such problem, provided that these functions are
  called  only  after  the  package has been loaded, so it is not necessary to
  specify  the  other package as suggested. The same applies to test files and
  manual  examples,  which  may  be  simply  extended  by calls to LoadPackage
  (76.2-1).
  
  It  may  happen  that  a  package B that is listed as a suggested package of
  package A is actually needed by A. If no explicit LoadPackage (76.2-1) calls
  for  B  occur  in  A at loading time, this can now be detected using the new
  possibility  to  load a package without loading its suggested packages using
  the  global  option  OnlyNeeded  which can be used to (recursively) suppress
  loading  the  suggested  packages  of  the  package  in question. Using this
  option,  one  can  check  whether  errors  or  warnings appear when B is not
  available  (note  that  this  option  should be used only for such checks to
  simulate  the  situation when package B is not available; it is not supposed
  to  be  used  in  an actual GAP session when package B will be loaded later,
  since  this  may  cause  problems). In case of any errors or warnings, their
  consequence  can  then  be  either turning B into a needed package or (since
  apparently  B was not intended to become a needed package) changing the code
  accordingly.  Only  if package A calls LoadPackage (76.2-1) for B at loading
  time  (see  above)  then package B needs to be deinstalled (i.e. removed) to
  test loading of A without B.
  
  Finally,  if  the package manual is in the GAPDoc format, then GAPDoc should
  still  be  listed as needed for this package (not as suggested), even though
  GAPDoc is now a needed package for GAP itself.
  
  
  76.12 Declaration and Implementation Part of a Package
  
  When  GAP  packages  require  each  other in a circular way, a bootstrapping
  problem  arises  of  defining  functions  before  they  are called. The same
  problem  occurs  in  the GAP library, and it is resolved there by separating
  declarations  (which define global variables such as filters and operations)
  and   implementations  (which  install  global  functions  and  methods)  in
  different files. Any implementation file may use global variables defined in
  any  declaration  file.  GAP  initially  reads all declaration files (in the
  library  they  have  a  .gd  suffix) and afterwards reads all implementation
  files (which have a .gi suffix).
  
  Something  similar  is possible for GAP packages: if a file read.g exists in
  the  home  directory  of  the  package, this file is read only after all the
  init.g  files  of  all (implicitly) required GAP packages are read. Thus one
  can  separate  declaration  and implementation for a GAP package in the same
  way  as  is done for the GAP library, by creating a file read.g, restricting
  the  ReadPackage  (76.3-1)  statements in init.g to only read those files of
  the  package that provide declarations, and to read the implementation files
  from read.g.
  
  Examples:
  
  Suppose  that  there  are  two  packages A and B, each with files init.g and
  read.g.
  
      If  package  A suggests or needs package B and package B does not need
        or  suggest  any  other  package  then first init.g of B is read, then
        read.g of B, then init.g of A, then read.g of A.
  
      If  package  A suggests or needs package B and package B (or a package
        that  is  suggested  or  needed by B) suggests or needs package A then
        first  the  files init.g of A and B are read (in an unspecified order)
        and then the files read.g of A and B (in the same order).
  
  In  general, when GAP is asked to load a package then first the dependencies
  between  this  packages  and its needed and suggested packages are inspected
  (recursively),  and  a  list of package sets is computed such that no cyclic
  dependencies  occur  between different package sets and such that no package
  in any of the package sets needs any package in later package sets. Then GAP
  runs  through the package sets and reads for each set first all init.g files
  and  then  all  read.g  files  of  the  packages  in  the set. (There is one
  exception  from  this  rule:  Whenever  packages  are  autoloaded before the
  implementation part of the GAP library is read, only the init.g files of the
  packages  are  read;  as  soon  as the GAP library has been read, the read.g
  files of these packages are also read, and afterwards the above rule holds.)
  
  It  can  happen  that  some code of a package depends on the availability of
  suggested  packages, i.e., different initialisations are performed depending
  on  whether  a  suggested  package will eventually be loaded or not. One can
  test this condition with the function IsPackageMarkedForLoading (76.3-4). In
  particular,  one  should  not call (and use the value returned by this call)
  the  function  LoadPackage  (76.2-1) inside package code that is read during
  package loading. Note that for debugging purposes loading suggested packages
  may have been deliberately disabled via the global option OnlyNeeded.
  
  Note  that  the separation of the GAP code of packages into declaration part
  and  implementation  part  does  in  general  not allow one to actually call
  functions  from a package when the implementation part is read. For example,
  in  the  case of a cyclic dependency as in the second example above, suppose
  that  B  provides  a new function f or a new global record r, say, which are
  declared  in  the declaration part of B. Then the code in the implementation
  part of A may contain calls to the functions defined in the declaration part
  of  B.  However,  the  implementation  part  of  A  may  be  read before the
  implementation  part  of B. So one can in general not assume that during the
  loading  of  A,  the  function  f  can  be  called,  or  that one can access
  components of the record r.
  
  If  one wants to call the function f or to access components of the record r
  in the code of the package A then the problem is that it may be not possible
  to  determine  a cyclic dependency between A and B from the packages A and B
  alone.  A  safe  solution  is  then  to  add  the name of B to the component
  Dependencies.OtherPackagesLoadedInAdvance  of  the  PackageInfo.g file of A.
  The  effect is that package B is completely loaded before the file read.g of
  A  is read, provided that there is no cyclic dependency between A and B, and
  that  package  A is regarded as not available in the case that such a cyclic
  dependency between A and B exists.
  
  A special case where Dependencies.OtherPackagesLoadedInAdvance can be useful
  is  that a package wants to force the complete GAP library to be read before
  the  file  read.g  of  the package A is read. In this situation, the package
  name "gap" should be added to this component in the PackageInfo.g file of A.
  
  In the case of cyclic dependencies, one solution for the above problem might
  be to delay those computations (typically initialisations) in package A that
  require  package  B  to be loaded until all required packages are completely
  loaded. This can be done by moving the declaration and implementation of the
  variables that are created in the initialisation into a separate file and to
  declare  these  variables  in  the init.g file of the package, via a call to
  DeclareAutoreadableVariables (76.3-10) (see also 76.13).
  
  
  76.13 Autoreadable Variables
  
  Package  files containing method installations must be read when the package
  is  loaded.  For  package  files  not  containing method installations (this
  applies,  for  example,  to many data files) another mechanism allows one to
  delay  reading  such files until the data are actually accessed. See 76.3-10
  for further details.
  
  
  76.14 Standalone Programs in a GAP Package
  
  GAP  packages  that involve stand-alone programs are fundamentally different
  from GAP packages that consist entirely of GAP code.
  
  This  difference is threefold: A user who installs the GAP package must also
  compile  (or install) the package's binaries, the package must check whether
  the  binaries  are indeed available, and finally the GAP code of the package
  has  to  start the external binary and to communicate with it. We will cover
  these three points in the following sections.
  
  If the package does not solely consist of an interface to an external binary
  and  if  the external program called is not just special-purpose code, but a
  generally available program, chances are high that sooner or later other GAP
  packages  might  also  require this program. We therefore strongly recommend
  the  provision  of  a  documented  GAP  function that will call the external
  binary.  We  also  suggest  to  create  actually two GAP packages; the first
  providing  only  the  binary and the interface and the second (requiring the
  first, see 76.11) being the actual GAP package.
  
  
  76.14-1 Installation of GAP Package Binaries
  
  The  scheme  for  the  installation  of  package binaries which is described
  further on is intended to permit the installation on different architectures
  which  share  a  common  file system (and share the architecture independent
  file).
  
  A  GAP package which includes external binaries contains a bin subdirectory.
  This   subdirectory  in  turn  contains  subdirectories  for  the  different
  architectures  on which the GAP package binaries are installed. The names of
  these  directories  must  be  the  same  as  the  names  of the architecture
  dependent  subdirectories  of  the main bin directory. Unless you use a tool
  like  autoconf  yourself,  you  must  obtain  the correct name of the binary
  directory  from  the  main  GAP  branch.  To  help  with  this, the main GAP
  directory  contains  a  file  sysinfo.gap  which  assigns the shell variable
  GAParch  to  the  proper  name as determined by GAP's configure process. For
  example on a Linux system, the file sysinfo.gap may look like this:
  
    Example  
    GAParch=i586-unknown-linux2.0.31-gcc
  
  
  We  suggest  that your GAP package contains a file configure which is called
  with  the  path  of the GAP root directory as parameter. This file then will
  read  sysinfo.gap  and  set  up  everything  for  compiling  under the given
  architecture  (for example creating a Makefile from Makefile.in). As initial
  templates,  you may use installation scripts of the Example package or files
  generated with the help of PackageMaker.
  
  
  76.14-2 Test for the Existence of GAP Package Binaries
  
  If  an  external  binary is essential for the workings of a GAP package, the
  function  stored in the component AvailabilityTest of the PackageInfo.g file
  of  the  package  should  test  whether the program has been compiled on the
  architecture  (and inhibit package loading if this is not the case). This is
  especially important if the package is loaded automatically.
  
  The  easiest  way to accomplish this is to use Filename (9.4-1) for checking
  for  the  actual  binaries  in  the path given by DirectoriesPackagePrograms
  (76.3-8)  for  the  respective  package. For example the example GAP package
  could  use  the following function to test whether the binary hello has been
  compiled;  it will issue a warning if not, and will only load the package if
  the binary is indeed available:
  
    Example  
    ...
    AvailabilityTest := function()
      local path,file;
        # test for existence of the compiled binary
        path:= DirectoriesPackagePrograms( "example" );
        file:= Filename( path, "hello" );
        if file = fail then
          LogPackageLoadingMessage( PACKAGE_WARNING,
              [ "The program `hello' is not compiled,",
                "`HelloWorld()' is thus unavailable.",
                "See the installation instructions;",
                "type: ?Installing the Example package" ] );
        fi;
        return file <> fail;
      end,
    ...
  
  
  However,  if  you  look  at  the  actual  PackageInfo.g  file of the example
  package,  you  will  see  that  its AvailabilityTest function always returns
  true, and just logs the warning if the binary is not available (which may be
  later  viewed  with  DisplayPackageLoadingLog (76.2-5)). This means that the
  binary is not regarded as essential for this package.
  
  You  might  also have to cope with the situation that external binaries will
  only  run  under UNIX (and not, say, under Windows), or may not compile with
  some  compilers  or default compiler options. See 3.4 for information on how
  to test for the architecture.
  
  Last  but  not least: do not print anything in the AvailabilityTest function
  of   the   package   via   Print   or   Info.   Instead   one   should  call
  LogPackageLoadingMessage  (76.2-5)  to  store  a message which may be viewed
  later  with DisplayPackageLoadingLog (76.2-5) (the latter two functions have
  been introduced in GAP 4.5)
  
  
  76.14-3 Calling of and Communication with External Binaries
  
  There  are  two  reasons for this: the input data has to be passed on to the
  stand-alone  program  and  the  stand-alone  program  has to be started from
  within GAP.
  
  There are two principal ways of doing this.
  
  The first possibility is to write all the data for the stand-alone to one or
  several  files,  then  start  the  stand-alone with Process (11.1-1) or Exec
  (11.1-2)  which then writes the output data to file, and finally read in the
  standalone's output file.
  
  The second way is interfacing via input-output streams, see Section 10.8.
  
  Some  GAP  packages  use  kernel  modules  (see 76.3-11) instead of external
  binaries.   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 advise you to look at existing examples
  of such packages and get in touch with GAP developers if you plan to develop
  such a package.
  
  
  76.15 Having an InfoClass
  
  It  is  a good idea to declare an InfoClass for your package. This gives the
  package  user  the opportunity to control the verbosity of output and/or the
  possibility  of  receiving debugging information (see 7.4). Below, we give a
  quick overview of its utility.
  
  An  InfoClass  is  defined with a DeclareInfoClass( InfoPkgname ); statement
  and  may  be  set  to  have an initial InfoLevel other than the zero default
  (which means no Info statement is to output information) via a SetInfoLevel(
  InfoPkgname, level ); statement. An initial InfoLevel of 1 is typical.
  
  Info statements have the form: Info( InfoPkgname, level, expr1, expr2, ...);
  where  the expression list expr1, expr2, ... appears just like it would in a
  Print  statement.  The  only  difference is that the expression list is only
  printed  (or  even  executed)  if  the  InfoLevel of InfoPkgname is at least
  level.
  
  
  76.16 The Banner
  
  When  the  package  is  loaded,  GAP  will display a default package banner,
  constructed from the package metadata provided in the PackageInfo.g file.
  
  Alternatively,  the  package  may  establish  its  own banner by assigning a
  string to the BannerString field of the record argument of SetPackageInfo in
  the PackageInfo.g file.
  
  If  you  will  be  designing a banner for your package, it is a good idea to
  suggest  there  how to access package documentation. For example, the banner
  of the Example package says:
  
    Example  
    For help, type: ?Example package
  
  
  In  order  for  this  to display the introduction of the Example package the
  index-entry  <Index>Example  package</Index> was added just before the first
  paragraph  of  the  introductory  section in the file doc/example.xml of the
  Example package.
  
  
  76.17 Version Numbers
  
  Version  numbers  are  strings  containing nonnegative integers separated by
  non-numeric  characters. They are compared by CompareVersionNumbers (76.3-9)
  which  first  splits them at non-digit characters and then lexicographically
  compares  the  resulting  integer  lists.  Thus version "2-3" is larger than
  version "2-2-5" but smaller than "4r2p3" or "11.0".
  
  It is possible for code to require GAP packages in certain versions. In this
  case,  all  versions,  whose  number  is  equal or larger than the requested
  number  are  acceptable.  It  is  the  task of the package author to provide
  upwards compatibility.
  
  Loading  a  specific  version  of  a package (that is, not one with a larger
  version  number)  can  be  achieved  by  prepending = to the desired version
  number.  For  example,  LoadPackage(  "example",  "=1.0" ) will load version
  "1.0"  of  the  package  "example", even if version "1.1" is available. As a
  consequence, version numbers must not start with =, so "=1.0" is not a valid
  version number.
  
  Package  authors  should choose a version numbering scheme that admits a new
  version  number  even  after  tiny  changes  to the package, and ensure that
  version  numbers  of  successive  package  versions  increase. The automatic
  update  of  package  archives  in  the  GAP distribution will only work if a
  package has a new version number.
  
  It   is   a   well-established   custom   to   name  package  archives  like
  name-version.tar.gz, name-version.tar.bz2 etc., where name is the lower case
  name,  and  version  is the version (another custom is that the archive then
  should extract to a directory that has exactly the name name-version).
  
  It is very important that there should not ever be, for a given GAP package,
  two  different  archives  with  the same package version number. If you make
  changes  to  your  package  and  place a new archive of the package onto the
  public  server,  please  ensure that a new archive has a new version number.
  This should be done even for very minor changes.
  
  For  most of the packages it will be inappropriate to re-use the date of the
  release  as a version number. It's much more obvious how big are the changes
  between  versions  "4.4.12",  "4.5.1"  and  "4.5.2"  than  between  versions
  "2008.12.17",  "2011.04.15"  and  "2011.09.14". The concept of using version
  numbers  to  convey the meaning of the status of the code and the way it has
  been  modified  is  known as Semantic Versioning, see http://semver.org/ for
  further recommendations on its use.
  
  Since  version  information  is  duplicated in several places throughout the
  package  documentation,  for GAPDoc-based manuals you may define the version
  and  the  release  manual in the comments in PackageInfo.g file close to the
  place where you specified its Version and Date components, for example
  
    Example  
    ##  <#GAPDoc Label="PKGVERSIONDATA">
    ##  <!ENTITY VERSION "3.3">
    ##  <!ENTITY RELEASEDATE "12/09/2017">
    ##  <!ENTITY RELEASEYEAR "2017">
    ##  <#/GAPDoc>
  
  
  notify  MakeGAPDocDoc (GAPDoc: MakeGAPDocDoc) that a part of the document is
  stored  in PackageInfo.g (see example/makedocrel.g), read this data into the
  header  of the main document via <#Include Label="PKGVERSIONDATA"> directive
  and then use them via &VERSION; and &RELEASEDATE; entities almost everywhere
  where  you  need  to  refer  to  them  (most commonly, in the title page and
  installation instructions).
  
  
  76.18 Testing a GAP package
  
  There are several aspects of testing a GAP package.
  
  First,  one  should ensure that the package functionality works as expected.
  Below  we give an advice on creating test files for automated tests that may
  be  run  by  package  authors,  by  GAP  developers  as  part of the release
  preparation,  and  by  package users interested in checking that the package
  works.  Such  tests  should be included in the package distribution, and the
  responsibility for ensuring that they pass stays with package authors.
  
  Second,  the  package should cleanly integrate into the GAP system and other
  packages, and should not break their functionality. In particular, all tests
  from  the  standard  GAP testing suite should pass if the package is loaded.
  This  is  more  comprehensive  and time consuming test, which GAP developers
  regularly  run  using  special  tools.  They will report to you any detected
  issues.  Below  we  explain how to do several simple and less time consuming
  checks which package authors are recommended to perform themselves.
  
  
  76.18-1 Tests files for a GAP package
  
  The  (optional)  tst  directory of your package may contain as many tests of
  the  package  functionality  as  appears  appropriate. These tests should be
  organised into test files similarly to those in the tst directory of the GAP
  distribution as documented in 7.10.
  
  For  a  deposited package, a test file with a basic test of the package (for
  example,  to check that it works as expected and/or that the manual examples
  are correct) may be specified in the component TestFile in the PackageInfo.g
  to  be included in the GAP standard test suite. This file can either consist
  of  calls  of  TestDirectory  (7.10-3) or Test (7.10-2) (in this case, it is
  common  to  call  it testall.g) or be itself a test file having an extension
  .tst  and  supposed  to  be  read  via Test (7.10-2). It is assumed that the
  latter case occurs if and only if the file contains the substring
  
   "gap> START_TEST("
  
  (with exactly one space after the GAP prompt).
  
  For deposited packages, these tests are run by the GAP Group regularly, as a
  part  of  the  standard  GAP  test  suite.  For  the efficient testing it is
  important that the test specified in the PackageInfo.g file does not display
  any output (e.g. no test progress indicators) except reporting discrepancies
  if such occur and the completion report as in the example below:
  
    Example  
    gap> Test("tst/testall.tst");
    Example package: testall.tst
    GAP4stones: 3333
    true
  
  
  Tests  which  produce extended output and/or require substantial runtime are
  not  supposed  to be a part of the GAP standard test suite but may be placed
  in the tst directory of the packages with further instructions on how to run
  them elsewhere.
  
  Because  of  different approaches to testing, used by different packages, it
  is  not  always easy to identify whether an automated test passed or failed.
  Presently,  automated  detection  works fine if a package uses a single .tst
  file or uses TestDirectory (7.10-3) to run a collection of tests. Otherwise,
  one  should  follow  the  convention to output a string of a fixed format to
  indicate  the  result  of  the  test  in the test script along the following
  lines:
  
    Example  
    if testresult then
      Print("#I  No errors detected while testing"\n");
    else
      Print("#I  Errors detected while testing\n");
    fi;
  
  
  
  76.18-2 Testing GAP package loading
  
  To  test  that  your package may be loaded into GAP without any problems and
  conflicts  with  other  packages,  test  that  it  may  be loaded in various
  configurations:
  
      starting  GAP  with  no  packages  (except needed for GAP) using -r -A
        options and calling LoadPackage("packagename");
  
      starting  GAP  with  no  packages  (except needed for GAP) using -r -A
        options and calling LoadPackage("packagename" : OnlyNeeded );
  
      starting  GAP  in  the  default  configuration  (with  no options) and
        calling LoadPackage("packagename");
  
      starting  GAP  in  the  default  configuration  (with  no options) and
        calling LoadPackage("packagename" : OnlyNeeded );
  
      finally,  together  with  all  other  packages  using  LoadAllPackages
        (76.18-3)  (see  below)  in four possible combinations of starting GAP
        with/without  -r  -A  options  and  calling  LoadAllPackages (76.18-3)
        with/without reversed option.
  
  The  test  of  loading  all  packages is the most subtle one. Quite often it
  reveals  problems  which  do  not occur in the default configuration but may
  cause difficulties to the users of specialised packages.
  
  For your convenience, make testpackagesload called in the GAP root directory
  will run all package loading tests listed in this subsection and write their
  output in its dev/log directory.
  
  It  will  produce four files with test logs, corresponding to the four cases
  above  (the  letter  N  in  the  filename  stands  for  needed, A stands for
  autoloaded):
  
      dev/log/testpackagesload1_...
  
      dev/log/testpackagesloadN1_...
  
      dev/log/testpackagesloadA_...
  
      dev/log/testpackagesloadNA_...
  
  Each  file  contains  small  sections for loading individual packages: among
  those,  you  need to find the section related to your package and may ignore
  all  other  sections. For example, the section for the Example package looks
  like
  
    Example  
    %%% Loading example 3.3.3
    [  ]
    ### Loaded example 3.3.3
  
  
  so it has clearly passed the test. If there are any error messages displayed
  between  Loading ... and Loaded ... lines, they will signal on errors during
  loading of your package.
  
  Additionally,  this  test collects information about variables created since
  the  library  was  read (obtained using NamesUserGVars (4.9-11)) with either
  short  names (no more than three characters) or names breaking a recommended
  naming  convention  that the GAP core system and GAP packages should not use
  global  variables  starting in the lowercase (see Section 76.10). Their list
  will  be  displayed  in the test log (in the example above, Example packages
  does  not  create any such variables, so an empty list is displayed). It may
  be  hard  to attribute a particular identifier to a package, since it may be
  created  by  another  package loaded because of dependencies, so when a more
  detailed  and  precise  report  on  package  variables  is needed, it may be
  obtained  using  ShowPackageVariables (76.3-15) (also, make testpackagesvars
  called  in the GAP root directory produces such reports for each package and
  writes them to a file dev/log/testpackagesvars_...).
  
  Finally,  each  log  file  finishes  with two large sections for loading all
  packages  in  the alphabetical and reverse alphabetical order (to check more
  combinations  of  loading  one  package  after  another).  We  are aiming at
  releasing  only  collections  of  package which do not break LoadAllPackages
  (76.18-3)  in  any  of  the four configurations, so if it is broken when you
  plug in the development version of your package into the released version of
  GAP, it is likely that your package triggers this error. If you observe that
  LoadAllPackages  (76.18-3)  is broken and suspect that this is not the fault
  of your package, please contact the GAP Support.
  
  76.18-3 LoadAllPackages
  
  LoadAllPackages( : reversed )  function
  
  loads  all GAP packages from their list sorted in alphabetical order (needed
  and  suggested  packages  will be loaded when required). This is a technical
  function  to  check  packages compatibility, so it should NOT be used to run
  anything  except  tests;  it  is known that GAP performance is slower if all
  packages  are  loaded.  To  introduce  some variations of the order in which
  packages will be loaded for testing purposes, LoadAllPackages accepts option
  reversed to load packages from their list sorted in the reverse alphabetical
  order.
  
  
  76.18-4 Testing a GAP package with the GAP standard test suite
  
  The tst directory of the GAP installation contains a selection of test files
  and scripts such as testinstall.g and teststandard.g which are a part of the
  GAP standard test suite.
  
  It  is  important  to  check  that  your package does not break GAP standard
  tests.  To  perform  a clean test and avoid interfering with other packages,
  first you must start a new GAP session and then read either testinstall.g or
  teststandard.g as demonstrated below.
  
  The  quicker test, testinstall.g, requires about 1 GB of memory and runs for
  several minutes. It may be started with the command
  
    Example  
    gap> Read( Filename( DirectoriesLibrary( "tst" ), "testinstall.g" ) );
  
  
  You  will  get a large number of lines with output about the progress of the
  tests, for example:
  
    Example  
    You should start GAP4 using `gap -A -x 80 -r -m 100m -o 1g -K 2g'.
    
    Architecture: x86_64-apple-darwin15.6.0-gcc-6-default64
    
    testing: /Users/alexk/GITREPS/gap/tst/testinstall/alghom.tst
         140 msec for alghom.tst        
    testing: /Users/alexk/GITREPS/gap/tst/testinstall/algmat.tst
        1309 msec for algmat.tst        
    testing: /Users/alexk/GITREPS/gap/tst/testinstall/algsc.tst
         500 msec for algsc.tst         
    ... further lines deleted ...
  
  
  (optionally,  you may start GAP with the command line options which you will
  see in the test output, to run it in a more conservative settings).
  
  The  more  thorough  test  is  teststandard.g  which exercises more of GAP's
  capabilities, also including all test files from teststandard.g. It requires
  about  1  GB  of  memory,  runs  for  about one hour, and produces an output
  similar  to  the testinstall.g test. To run it, also start a new GAP session
  and then call
  
    Example  
    gap> Read( Filename( DirectoriesLibrary( "tst" ), "testall.g" ) );
  
  
  You  may  repeat the same check loading your package with OnlyNeeded option.
  Remember to perform each subsequent test in a new GAP session.
  
  Also  you  may  perform  individual  tests from the tst directory of the GAP
  installation loading them with Test (7.10-2).
  
  
  76.19 Access to the GAP Development Version
  
  We  are  aiming  at  providing a stable platform for package development and
  testing with official GAP releases. We also invite everyone to contribute by
  submitting  patches,  pull  requests, and bug reports. We would like to make
  the contributing process as easy as possible.
  
  The   main   GAP   development   repository   is   hosted   on   GitHub   at
  https://github.com/gap-system/gap.   Many  GAP  packages  also  have  public
  repositories  and issue trackers, and we are keeping a list of such packages
  at https://gap-packages.github.io/.
  
  For  further  information  about contributing to the GAP development, please
  see https://github.com/gap-system/gap/blob/master/CONTRIBUTING.md.
  
  
  76.20 Version control and continuous integration for GAP packages
  
  As  we  have mentioned above, many GAP packages have public repositories and
  issue  trackers  on  GitHub,  and  we are keeping a list of such packages at
  https://gap-packages.github.io/. We welcome establishing public repositories
  for  new packages and migrating existing package repositories there as well.
  Such  repositories  may be hosted under their authors' accounts or under the
  gap-packages organisation (https://github.com/gap-packages/). The latter has
  the  benefit that while the authors will preserve their deciding role on all
  aspects of the package development, the package will become more visible for
  potential  collaborators  and  GAP  developers may help to set up continuous
  integration  for  your  package  so that every commit to the repository will
  trigger  automated  running  of  package tests and reporting any failures to
  package maintainers.
  
  
  76.21 Selecting a license for a GAP Package
  
  As  it was mentioned in the description of the LICENSE file in Section 76.5,
  it is advised to make clear in the documentation of the package the basis on
  which  it is being distributed to users. GAP itself is distributed under the
  GNU Public License version 2 (version 2 or later). We would encourage you to
  consider  the  GPL  license for your packages, but you might wish to be more
  restrictive  (for  instance  forbidding  redistribution  for profit) or less
  restrictive  (allowing  your  software  to  be  incorporated into commercial
  software).  See Choosing a License for the Distribution of Your Package from
  http://www.gap-system.org/Packages/Authors/authors.html       and       also
  https://choosealicense.com/ for further details.
  
  In  the  past  many  GAP  packages  used  the  text  We  adopt the copyright
  regulations  of GAP as detailed in the copyright notice in the GAP manual or
  a  similar  statement. We now advise to be more explicit by making the exact
  reference to the GPL license, for example:
  
    packagename  is  free  software;  you can redistribute it and/or modify it
  under     the     terms     of    the    GNU    General    Public    License
  (http://www.fsf.org/licenses/gpl.html)  as  published  by  the Free Software
  Foundation;  either  version 2 of the License, or (at your option) any later
  version.  and also including a copy of the full text of the license.
  
  
  76.22 Releasing a GAP Package
  
  Currently, the GAP distribution provides archives in four different formats.
  
  .tar.gz
        a standard UNIX tar archive, compressed with gzip
  
  .tar.bz2
        a standard UNIX tar archive, compressed with bzip2
  
  .zip
        an archive in zip format, where text files should have UNIX style line
        breaks
  
  -win.zip
        an  archive  in zip format, where text files should have Windows style
        line breaks
  
  For convenience of possible users it is sensible that you provide an archive
  of your package in at least one of these formats.
  
  For example, if you wish to supply a .tar.gz archive, you may create it with
  the command
  
   tar -cvzf packagename-version.tar.gz packagename
  
  Because the release of the GAP package is independent of the version of GAP,
  a  GAP  package  should be wrapped up in separate file that can be installed
  onto  any  version  of  GAP. In this way, a package can be upgraded any time
  without  the  need to wait for new GAP releases. To ensure this, the package
  should  be  archived  from  the  GAP  pkg  directory,  that is all files are
  archived with the path starting at the package's name.
  
  The  archive  of  a  GAP  package should contain all files necessary for the
  package  to  work.  In  particular there should be a compiled documentation,
  which  includes  the  manual.six,  manual.toc  and  manual.lab  file  in the
  documentation  subdirectory  which  are  created  by GAPDoc while TeXing the
  documentation.  (The  first two files are needed by the GAP help system, and
  the  manual.lab  file  is  needed  if the main manuals or another package is
  referring  to  your package. Use the command GAPDocManualLab( packagename );
  to create this file for your help books if you use GAPDoc.)
  
  For  packages  which  are  redistributed  via  the  GAP website, we offer an
  automatic  conversion  of  any of the formats listed above to all the others
  (note  that  this,  as  well  as  wrapping  the GAP distribution as a single
  archive containing the core system and all currently redistributed packages,
  will  change file timestamps, so one should not rely on them anywhere in the
  package).
  
  To  use  the  conversion and repackaging service, you can provide any of the
  four archive formats or even more than one, however you should adhere to the
  following  rule:  text files in .tar.gz and .tar.bz2 archives must have UNIX
  style  line  breaks,  while  text  files  in  -win.zip  archives  must  have
  DOS/Windows line breaks.
  
  The  package  wrapping tools for the GAP distribution and webpages then will
  use  a  sensible  list of file extensions to decide if a file is a text file
  (being  conservative,  it  may  miss  a  few text files). These rules may be
  prepended by the application of rules from the PackageInfo.g file:
  
      if  it  has  a  .TextFiles component, then consider the given files as
        text files before GAP defaults will be applied;
  
      if  it  has  a  .BinaryFiles  component,  then consider given files as
        binary files before GAP defaults will be applied;
  
      if  it  has a .TextBinaryFilesPatterns component, then apply it before
        GAP defaults will be applied;
  
  Utility    functions   from   the   lib/lbutil.g   file   in   GAP,   namely
  DosUnixLinebreaks, UnixDosLinebreaks, MacUnixLinebreaks may be helpful. They
  are described in the comments to their source code.
  
  For  packages  hosted  on GitHub publishing package release and establishing
  its  website can be very efficiently automated using two tools: ReleaseTools
  (https://github.com/gap-system/ReleaseTools)      and      GitHubPagesForGAP
  (https://github.com/gap-system/GitHubPagesForGAP).
  
  
  76.23 The homepage of a Package
  
  If  you  want  to  distribute  your  package  you should create its homepage
  containing  some  basic  information, archives for download, the README file
  with  installation  instructions,  and a copy of the package's PackageInfo.g
  file.
  
  The   responsibility   to   maintain  this  homepage  is  with  the  package
  authors/maintainers.
  
  If   you   tell   the  GAP  Group  about  your  package  (say,  by  mail  to
  mailto:support@gap-system.org) we may consider either
  
      adding a link to your package homepage from the GAP website (thus, the
        package will be an undeposited contribution);
  
      or redistributing the current version of your package as a part of the
        GAP distribution (this, the package will be deposited), also ;
  
  In  the  latter case we can also provide some services for producing several
  archive  formats  from  the archive you provide (e.g., you produce a .tar.gz
  version  of your archive and we produce also a .tar.bz2, .zip and a -win.zip
  version from it).
  
  Please  also  consider submitting your package to the GAP package refereeing
  process   (see  http://www.gap-system.org/Contacts/submit.html  for  further
  information).
  
  For  packages  hosted  on GitHub publishing package release and establishing
  its   website   can   be   very   efficiently  automated  using  two  tools:
  GitHubPagesForGAP    (https://github.com/gap-system/GitHubPagesForGAP)   and
  ReleaseTools (https://github.com/gap-system/ReleaseTools).
  
  
  76.24 Some things to keep in mind
  
      Some  packages  still  use  for their manuals the old gapmacro format,
        support  for  which  may  be  discontinued in the future. We encourage
        authors  of  those  packages to eventually convert their documentation
        GAPDoc.  New  packages  are  recommended  to  use  GAPDoc,  which, for
        example,  is  capable  of  creating  HTML  documentation  with MathJax
        support,  allows  easy  extraction  of examples from documentation for
        testing,  etc. One could also use the AutoDoc which simplifies writing
        documentation by generating most of the GAPDoc code automatically.
  
      The  concept  of  an autoloaded package, which existed before GAP 4.5,
        has  been  integrated  with  the  needed  and suggested mechanism that
        exists  between  packages.  GAP itself now needs certain packages (for
        instance GAPDoc) and suggests others (typically the packages that were
        autoloaded).  The  decisions which packages GAP should need or suggest
        are made by developers based on technical criteria. They can be easily
        overridden by a user using the new gap.ini (see 3.2). The default file
        ensures  that  all  formerly  autoloaded  packages are still loaded if
        present.
  
      Optional  ~/.gap directory for user's customisations which may contain
        e.g.  locally  installed  packages  (see 9.2). If package installation
        instructions  explain  how  to  install  the package in a non-standard
        location, they should mention this.
  
      Packages  loading  mechanism  allows  to  make  loading  packages more
        informative,  while avoiding confusing the user with warning and error
        messages for packages they didn't know they were loading. For example,
        many  messages  are  stored  but  not  displayed  using  the  function
        LogPackageLoadingMessage    (76.2-5)   and   there   is   a   function
        DisplayPackageLoadingLog  (76.2-5)  to  show  log  messages that occur
        during   package   loading.  Packages  are  encouraged  to  use  these
        mechanisms to report problems in loading (e.g. binaries not compiled),
        rather than printing messages directly.
  
  
  76.25 Package release checklists
  
  The   following   checklists   should  be  useful  to  package  authors  and
  maintainers,  as  well  as  to  everyone  involved  in  the  depositing  and
  refereeing of GAP packages.
  
  
  76.25-1 Checklist for releasing a new package
  
      Test that the package:
  
            does  not  break  testinstall.g and teststandard.g, and does not
              slow them down noticeably (see 76.18-4);
  
            may be loaded in various configurations (see 76.18-2);
  
            follows the guidelines of Section 76.10 about names of functions
              and variables;
  
      PackageInfo.g file:
  
            correctly  specifies  package version, release date, and package
              authors;
  
            passes validation using ValidatePackageInfo (76.3-14);
  
            besides   mandatory  components,  which  are  required  to  pass
              validation,  also has relevant optional components (such as, for
              example,  URLs  of  public  source  code  repository  and  issue
              tracker;  hints  to distinguish binary and text files in case of
              non-standard file names and extensions, etc.);
  
      Package documentation:
  
            is  built  and included in the package archive together with its
              source files;
  
            states  the  same  version,  release date and package authors as
              specified in the PackageInfo.g file;
  
            has  the  same version, release date and package authors details
              as stated in the PackageInfo.g file;
  
            is  searchable  using  the GAP help system in all formats (text,
              HTML and PDF);
  
            is   clear   about  the  license  under  which  the  package  is
              distributed,  and  refers  to  the  LICENSE file which should be
              included in the package;
  
      Package archive(s):
  
            have  correct  permissions  for  all files and directories after
              their  unpacking  (755  for directories and executables, if any;
              644 for other files);
  
            contain files with correct line breaks for the given format (see
              Section 76.22);
  
            contain  no  hidden  system  files  and directories that are not
              supposed  to  be  included in the package, e.g. .gitignore, .git
              etc.;
  
      Package availability:
  
            not  only the package archive(s), but also the PackageInfo.g and
              README files are available online;
  
  
  76.25-2  Checklist  for  upgrading the package for the next major release of
  GAP
  
  GAP  ecosystem  is  not  static:  both  the  core  GAP  system  and packages
  redistributed  with  GAP  are in constant development. GAP has a policy that
  changes that may have a disruptive effect on packages redistributed with GAP
  should  only  be  introduced  in major GAP releases. When the next GAP major
  release  is  prepared,  a  beta  version  for  package  authors will be made
  available  in  order  to  give  them  an opportunity to check and update, if
  necessary,  their  packages for the public release of the next major version
  of GAP.
  
  The  following  checklist  will  help  you to check how well your package is
  ready to work with the next major release of GAP
  
      Check  that the package functionality works as expected, package tests
        run  with  no  discrepancies,  and  manual  examples correspond to new
        version  of  GAP.  This is a convenient opportunity to polish existing
        and add new tests, and improve manual examples.
  
      Revise  package  dependencies:  check  that the PackageInfo.g file has
        correct list of needed and suggested packages (see Section 76.11).
  
      Revise  licensing  information:  check that the package states clearly
        under which conditions it is distributed and includes a LICENSING file
        with the text of a license (see Section 76.21).
  
      Rebuild  the  package documentation to update cross-references to main
        GAP  manuals  and,  if  relevant,  to  the  documentation of other GAP
        packages.  This  will  ensure  that  cross-references from the package
        manual  to  the  main  GAP  manuals  are correct and that the GAP help
        system  will  be  able to navigate to the more precise location in the
        package  manual.  This  will  also  improve  the layout of the package
        documentation by picking up the changes in documenting tools.
  
      Check  if  the  package  still  relies on some obsolete variables (see
        Chapter  77)  and  replace their usage by the new commands. To perform
        such check, start GAP with `-O` command line option to disable loading
        obsoletes, and then load your package.
  
      Check  for  any  specific advice in release notes for the beta release
        for package authors.
  

bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped)
Email: contact@elmoujehidin.net bypass 1.0, Devloped By El Moujahidin (the source has been moved and devloped) Email: contact@elmoujehidin.net