Skip to main content

Python interface to GAP

Project description

gappy logo

gappy — a Python interface to GAP

Documentation Status Test Status

gappy provides a Python interface to the GAP computer algebra system by linking to its library interface.

It allows calling functions in GAP directly from Python, and passing supported Python objects back to GAP.

gappy is based on SageMath’s LibGAP interface to GAP, originally developed by Volker Braun, but is completely independent of Sage–it does not require or use Sage at all, and can be used in any Python code. If there is enough interest, it may also be enhanced with a complementary GAP package for interacting with Python from within GAP.

Quickstart

To start using GAP functions from Python, just run:

>>> from gappy import gap

Then any global variable in GAP, including functions, can be accessed as attributes on gap like:

>>> gap.Cite()
Please use one of the following samples
to cite GAP version from this installation

Text:

[GAP] GAP  Groups, Algorithms, and Programming, Version 4.dev, The GAP Group, https://www.gap-system.org.
...

All global variables that would be available in a GAP session can be accessed in this way:

>>> GAPInfo.Version
"4.dev"

Most basic Python types have direct equivalents in GAP, and can be passed directly to GAP functions without explicit conversion to their equivalent GAP types:

>>> S4 = gap.SymmetricGroup(4)
>>> S4
Sym( [ 1 .. 4 ] )

You can also call “methods” on GapObjs. This is just syntactic sugar for calling a GAP function with that object as its first argument, in cases where that function supports the object bound to the method. For example:

>>> S4.GeneratorsOfGroup()
[ (1,2,3,4), (1,2) ]

Values returned from GAP functions are GAP objects wrapped in a Python class for containing them called GapObj:

>>> type(S4)
<class 'gappy.gapobj.GapObj'>

There are also specialized subclasses of GapObj for many types of objects in GAP. To explicitly convert a Python object directly to its GAP equivalent, you can call gap like:

>>> one = gap(1)
>>> type(one)
<class 'gappy.gapobj.GapInteger'>

GAP objects are displayed (with repr) or stringified (with str) the same way they would be in GAP, when displaying the object in the REPL or when calling GAP’s Print() function on the object, respectively:

>>> one
1
>>> s = gap("Hello GAP!")
>>> s
"Hello GAP!"
>>> print(s)
Hello GAP!

Not all GAP objects have an equivalent in basic Python types, so there is no implicit conversion from GAP back to Python. However, all Python types that can be converted to GAP objects can be converted back to their equivalent Python types in a symmetrical manner:

>>> int(one)
1
>>> type(int(one))
<class 'int'>
>>> str(s)
'Hello GAP!'
>>> type(str(s))
<class 'str'>

Likewise for floats, lists, dicts, among others.

Finally, you can execute arbitrary GAP code directly with gap.eval. This is often the easiest way to construct more complicated GAP objects, especially if you are more familiar with GAP syntax. The return value of gap.eval is the result of evaluating the same statement in GAP (the semicolon is optional when evaluating a single statement):

>>> rec = gap.eval('rec(a:=123, b:=456, Sym3:=SymmetricGroup(3))')
>>> rec['Sym3']
Sym( [ 1 .. 3 ] )

This is also an easy way to declare new GAP functions from gappy:

>>> sign = gap.eval("""sign := function(n)
...     if n < 0 then
...         return -1;
...     elif n = 0 then
...         return 0;
...     else
...         return 1;
...     fi;
... end;""")
>>> sign
<GAP function "sign">
>>> sign(0)
0
>>> sign(-99)
-1

See the full API documentation for many additional examples of how to use the gap object as well as the built-in GapObj types.

Installation

Prerequisites

  • Supported platforms: Linux, MacOS, Cygwin.

    • Likely works with most other *BSD flavors but has not been tested.

  • Python 3.6 or up with development headers installed. On Debian-based systems this means:

    $ sudo apt-get install python3.7-dev
  • GAP 4.10.2 or greater

Currently it is necessary to install from source:

$ git clone https://github.com/embray/gappy.git
$ cd gappy/

It is possible to install gappy in the usual way using pip:

$ pip install .

However, depending on how GAP is installed, some extra steps may be required. In particular, if you installed GAP from source using the typical instructions on the GAP website you will need to make sure the libgap shared library is built by running:

$ make install-libgap

in the GAP source directory.

You will also need to point to the location of your GAP installation by setting the GAP_ROOT environment variable like:

$ GAP_ROOT=<path/to/gap/root> pip install .

If you needed to provide GAP_ROOT for the installation, it is also generally necessary to set this environment variable before using gappy, so that it can find the path to your GAP installation. See the documentation for the Gap class for more information.

If using GAP from a distribution system such as APT on Debian/Ubuntu or from Conda, however, the GAP library (libgap) is typically installed in a standard system location, and it may not be necessary to provide GAP_ROOT. See the next section for example.

Conda installation

To give an example of the above point, you can install gappy in a Conda environment as follows:

$ conda create -n gap
$ conda activate gap
$ conda install -c conda-forge gap-defaults==4.11 python==3.8
$ pip install .

Alternatively, you can create the conda environment using the supplied environment.yml file:

$ conda env create

Cygwin installation

Additional notes for installation on Cygwin:

  • The dependency psutil does not support Cygwin. However, there is an unofficial fork which does at: https://github.com/embray/psutil/tree/cygwin/v3. You can install it by running:

    $ pip install git+https://github.com/embray/psutil.git@cygwin/v3
  • The path to the libgap DLL (filename cyggap-0.dll) needs to be on your PATH environment variable in order for gappy to be importable. To do this you can either copy it from your GAP installation to a standard location like:

    $ cp /path/to/gap_root/.libs/cyggap-0.dll /usr/local/bin

    or you can modify your environment to point to where GAP places the built DLL:

    $ export PATH="/path/to/gap_root/.libs:$PATH"

    and add this to your .profile.

Changelog

v0.1.0a2 (2021-02-03)

Bug fixes

  • Made fixes for MacOS and Cygwin support.

v0.1.0a1 (2021-02-03)

Enhancements
  • Added LRU cache for functions defined with gap.gap_functions, restoring some of the caching functionality from Sage’s Gap.function_factory.

Bug fixes
  • Fixed bug in multi-indexing of nested lists.

  • Fixed minor formatting difference in the IndexError message when indexing single lists versus multi-indexing nested lists.

  • Fixed a bug when using functions defined with gap.gap_function as arguments to another GAP function before they have been called once.

v0.1.0a0 (2021-01-26)

  • Initial alpha release for testing against SageMath.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gappy-system-0.1.0a2.tar.gz (112.5 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page