Ticket #13588: trac_6391_libGAP.patch

File trac_6391_libGAP.patch, 140.6 KB (added by vbraun, 9 years ago)

patch from #6391

  • doc/en/reference/libs.rst

    # HG changeset patch
    # User Volker Braun <vbraun@stp.dias.ie>
    # Date 1346688895 -3600
    # Node ID 8e43e34aea6424eb2c58c902e353f9a059b98f16
    # Parent  8d76241354f25d5108073cf970ff49388b76c368
    Trac #6391: llibGAP, a Cython library interface to gap
    
    diff --git a/doc/en/reference/libs.rst b/doc/en/reference/libs.rst
    a b  
    2525.. toctree::
    2626   :maxdepth: 2
    2727   
     28   sage/libs/gap/libgap
     29   sage/libs/gap/element
    2830   sage/libs/flint/fmpz_poly
    2931   sage/libs/libecm
    3032   sage/libs/lrcalc/lrcalc
  • module_list.py

    diff --git a/module_list.py b/module_list.py
    a b  
    670670              sources = ["sage/libs/ratpoints.pyx"],
    671671              depends = [SAGE_INC + 'ratpoints.h'],
    672672              libraries = ["ratpoints", "gmp"]),
    673    
     673
    674674    Extension('sage.libs.singular.singular',
    675675              sources = ['sage/libs/singular/singular.pyx'],
    676676              libraries = singular_libs,
     
    741741              sources = ["sage/libs/mpmath/ext_libmp.pyx"],
    742742              libraries = ['gmp']),
    743743
     744        ################################
     745        ##
     746        ## sage.libs.gap
     747        ##
     748        ################################
     749
     750    Extension('sage.libs.gap.util',
     751              sources = ["sage/libs/gap/util.pyx"],
     752              libraries = ['csage', 'gmp', 'gap', 'm'],
     753              include_dirs = [SAGE_LOCAL + '/include/']),
     754
     755    Extension('sage.libs.gap.element',
     756              sources = ["sage/libs/gap/element.pyx"],
     757              libraries = ['csage', 'gmp', 'gap', 'm'],
     758              include_dirs = [SAGE_LOCAL + '/include/']),
     759
     760    # Extension('sage.libs.gap.type',
     761    #           sources = ["sage/libs/gap/type.pyx"],
     762    #           libraries = ['csage', 'gmp', 'gap', 'm'],
     763    #           include_dirs = [SAGE_LOCAL + '/include/']),
     764   
     765    Extension('sage.libs.gap.libgap',
     766              sources = ["sage/libs/gap/libgap.pyx"],
     767              libraries = ['csage', 'gmp', 'gap', 'm'],
     768              include_dirs = [SAGE_LOCAL + '/include/']),
     769
    744770        ###################################
    745771        ##
    746772        ## sage.libs.cremona
  • sage/libs/all.py

    diff --git a/sage/libs/all.py b/sage/libs/all.py
    a b  
    1212
    1313from cremona.all import CremonaModularSymbols
    1414
     15
     16from sage.misc.lazy_import import lazy_import
     17lazy_import('sage.libs.gap.libgap', 'libgap')
  • new file sage/libs/gap/__init__.py

    diff --git a/sage/libs/gap/__init__.py b/sage/libs/gap/__init__.py
    new file mode 100644
    - +  
     1# libgap
     2import all
  • new file sage/libs/gap/all.py

    diff --git a/sage/libs/gap/all.py b/sage/libs/gap/all.py
    new file mode 100644
    - +  
     1
     2
     3
     4
  • new file sage/libs/gap/element.pxd

    diff --git a/sage/libs/gap/element.pxd b/sage/libs/gap/element.pxd
    new file mode 100644
    - +  
     1###############################################################################
     2#       Copyright (C) 2012, Volker Braun <vbraun.name@gmail.com>
     3#
     4#   Distributed under the terms of the GNU General Public License (GPL)
     5#   as published by the Free Software Foundation; either version 2 of
     6#   the License, or (at your option) any later version.
     7#                   http://www.gnu.org/licenses/
     8###############################################################################
     9
     10from util cimport *
     11from sage.structure.sage_object cimport SageObject
     12from sage.structure.element cimport Element, ModuleElement, RingElement
     13
     14cdef libGAP_Obj make_gap_list(sage_list)
     15cdef libGAP_Obj make_gap_record(sage_dict)
     16cdef libGAP_Obj make_gap_integer(sage_dict)
     17cdef libGAP_Obj make_gap_string(sage_string)
     18
     19cdef GapElement make_any_gap_element(parent, libGAP_Obj obj)
     20cdef GapElement make_GapElement(parent, libGAP_Obj obj)
     21cdef GapElement_List make_GapElement_List(parent, libGAP_Obj obj)
     22cdef GapElement_Record make_GapElement_Record(parent, libGAP_Obj obj)
     23cdef GapElement_Integer make_GapElement_Integer(parent, libGAP_Obj obj)
     24cdef GapElement_Rational make_GapElement_Rational(parent, libGAP_Obj obj)
     25cdef GapElement_String make_GapElement_String(parent, libGAP_Obj obj)
     26cdef GapElement_Boolean make_GapElement_Boolean(parent, libGAP_Obj obj)
     27cdef GapElement_Function make_GapElement_Function(parent, libGAP_Obj obj)
     28
     29
     30
     31cdef class GapElement(RingElement):
     32   
     33    # the pointer to the GAP object (memory managed by GASMAN)
     34    cdef libGAP_Obj value
     35
     36    cdef _initialize(self, parent, libGAP_Obj obj)
     37    cdef int _cmp_c_impl(self, Element other)
     38    cpdef ModuleElement _add_(self, ModuleElement right)
     39    cpdef ModuleElement _sub_(self, ModuleElement right)
     40    cpdef RingElement _mul_(self, RingElement right)
     41    cpdef RingElement _div_(self, RingElement right)
     42    cpdef is_bool(self)
     43
     44
     45cdef class GapElement_Integer(GapElement):
     46    pass
     47
     48cdef class GapElement_Rational(GapElement):
     49    pass
     50
     51cdef class GapElement_String(GapElement):
     52    pass
     53
     54cdef class GapElement_Boolean(GapElement):
     55    pass
     56
     57cdef class GapElement_Function(GapElement):
     58    pass
     59
     60cdef class GapElement_MethodProxy(GapElement_Function):
     61    cdef GapElement first_argument
     62
     63cdef class GapElement_Record(GapElement):
     64    cpdef libGAP_UInt record_name_to_index(self, bytes py_name)
     65
     66cdef class GapElement_RecordIterator(object):
     67    cdef GapElement_Record rec
     68    cdef libGAP_UInt i
     69
     70cdef class GapElement_List(GapElement):
     71    pass
     72
     73cdef class GapElement_Permutation(GapElement):
     74    pass
  • new file sage/libs/gap/element.pyx

    diff --git a/sage/libs/gap/element.pyx b/sage/libs/gap/element.pyx
    new file mode 100644
    - +  
     1"""
     2libGAP element wrapper
     3
     4This document describes the individual wrappers for various GAP
     5elements. For general information about libGAP, you should read the
     6:mod:`~sage.libs.gap.libgap` module documentation.
     7"""
     8
     9###############################################################################
     10#       Copyright (C) 2012, Volker Braun <vbraun.name@gmail.com>
     11#
     12#   Distributed under the terms of the GNU General Public License (GPL)
     13#   as published by the Free Software Foundation; either version 2 of
     14#   the License, or (at your option) any later version.
     15#                   http://www.gnu.org/licenses/
     16###############################################################################
     17
     18from sage.structure.sage_object cimport SageObject
     19from sage.structure.parent import Parent
     20from sage.rings.all import ZZ
     21
     22
     23
     24
     25############################################################################
     26### helper functions to construct lists and records ########################
     27############################################################################
     28
     29cdef libGAP_Obj make_gap_list(sage_list):
     30    """
     31    Convert Sage lists into Gap lists
     32
     33    INPUT:
     34   
     35    - ``a`` -- list of :class:`GapElement`.
     36
     37    OUTPUT:
     38
     39    The list of the elements in ``a`` as a Gap ``Obj``.
     40    """
     41    # FIXME slow -- to make fast directly use ADD_LIST in Gap's C code.
     42    from sage.libs.gap.libgap import libgap
     43    cdef GapElement l = libgap.eval('[]')
     44    for x in sage_list:
     45        l.Add(x)
     46    return l.value
     47   
     48
     49cdef libGAP_Obj make_gap_record(sage_dict):
     50    """
     51    Convert Sage lists into Gap lists
     52
     53    INPUT:
     54   
     55    - ``a`` -- list of :class:`GapElement`.
     56
     57    OUTPUT:
     58
     59    The list of the elements in ``a`` as a Gap ``Obj``.
     60
     61    TESTS::
     62
     63        sage: libgap({'a': 1, 'b':123})   # indirect doctest
     64        rec( a := 1, b := 123 )
     65    """
     66    from sage.libs.gap.libgap import libgap
     67    data = [ (str(key), libgap(value)) for key, value in sage_dict.iteritems() ]
     68
     69    libgap_enter()
     70    cdef libGAP_Obj rec = libGAP_NEW_PREC(len(data))
     71    cdef GapElement val
     72    cdef libGAP_UInt rnam
     73    for d in data:
     74        key, val = d
     75        rnam = libGAP_RNamName(key)
     76        libGAP_AssPRec(rec, rnam, val.value)
     77    libgap_exit()
     78    return rec
     79   
     80
     81cdef libGAP_Obj make_gap_integer(sage_int):
     82    """
     83    Convert Sage lists into Gap lists
     84
     85    INPUT:
     86   
     87    - ``sage_int`` -- a Sage integer.
     88   
     89    OUTPUT
     90   
     91    The integer as a GAP ``Obj``.
     92
     93    TESTS::
     94   
     95        sage: libgap(1)   # indirect doctest
     96        1
     97    """
     98    libgap_enter()
     99    cdef libGAP_Obj result = libGAP_INTOBJ_INT(<int>sage_int)
     100    libgap_exit()
     101    return result
     102
     103
     104cdef libGAP_Obj make_gap_string(sage_string):
     105    """
     106    Convert a Sage string to a Gap string
     107
     108    INPUT:
     109   
     110    - ``sage_string`` -- a Sage integer.
     111   
     112    OUTPUT
     113   
     114    The string as a GAP ``Obj``.
     115
     116    TESTS::
     117   
     118        sage: libgap('string')   # indirect doctest
     119        "string"
     120    """
     121    libgap_enter()
     122    cdef libGAP_Obj result
     123    libGAP_C_NEW_STRING(result, len(sage_string), <char*>sage_string)
     124    libgap_exit()
     125    return result
     126
     127   
     128############################################################################
     129### generic construction of GapElements ####################################
     130############################################################################
     131
     132cdef GapElement make_any_gap_element(parent, libGAP_Obj obj):
     133    """
     134    Return the libGAP element wrapper of ``obj``
     135   
     136    The most suitable subclass of GapElement is determined
     137    automatically. Use this function to wrap GAP objects unless you
     138    know exactly which type it is (then you can use the specialized
     139    ``make_GapElement_...``)
     140    """
     141    if obj is NULL:
     142        return make_GapElement(parent, obj)
     143    # print 'num', libGAP_TNUM_OBJ(obj), libGAP_TNUM_BAG(obj), libGAP_T_STRING
     144    cdef int num = libGAP_TNUM_OBJ(obj)
     145    if num == libGAP_T_INT or num == libGAP_T_INTPOS or num == libGAP_T_INTNEG:
     146        return make_GapElement_Integer(parent, obj)
     147    elif num == libGAP_T_RAT:
     148        return make_GapElement_Rational(parent, obj)
     149    elif num == libGAP_T_BOOL:
     150        return make_GapElement_Boolean(parent, obj)
     151    elif num == libGAP_T_FUNCTION:
     152        return make_GapElement_Function(parent, obj)
     153    elif num == libGAP_T_PERM2 or num == libGAP_T_PERM4:
     154        return make_GapElement_Permutation(parent, obj)
     155    elif num == libGAP_T_PREC:
     156        return make_GapElement_Record(parent, obj)
     157    elif num >= libGAP_T_STRING and num <= libGAP_T_STRING_SSORT + libGAP_IMMUTABLE:
     158        # GAP strings are lists, too. Make sure this comes before make_GapElement_List
     159        return make_GapElement_String(parent, obj)
     160    elif num >= libGAP_FIRST_LIST_TNUM and num <= libGAP_LAST_LIST_TNUM:
     161        return make_GapElement_List(parent, obj)
     162    else:
     163        return make_GapElement(parent, obj)
     164       
     165
     166############################################################################
     167### GapElement #############################################################
     168############################################################################
     169
     170cdef GapElement make_GapElement(parent, libGAP_Obj obj):
     171    r"""
     172    Turn a Gap C object (of type ``Obj``) into a Cython ``GapElement``.
     173
     174    INPUT:
     175
     176    - ``parent`` -- the parent of the new :class:`GapElement`
     177
     178    - ``obj`` -- a GAP object.
     179
     180    OUTPUT:
     181
     182    A :class:`GapElement_Function` instance, or one of its derived
     183    classes if it is a better fit for the GAP object.
     184
     185    EXAMPLES::
     186
     187        sage: libgap(0)
     188        0
     189        sage: type(_)
     190        <type 'sage.libs.gap.element.GapElement_Integer'>
     191
     192        sage: libgap.eval('')
     193        NULL
     194
     195        sage: libgap(None)
     196        Traceback (most recent call last):
     197        ...
     198        AttributeError: 'NoneType' object has no attribute '_gap_init_'
     199    """
     200    cdef GapElement r = GapElement.__new__(GapElement)
     201    r._initialize(parent, obj)
     202    return r
     203
     204
     205cdef class GapElement(RingElement):
     206    r"""
     207    Wrapper for all Gap objects.
     208
     209    .. NOTE::
     210     
     211        In order to create ``GapElements`` you should use the
     212        ``libgap`` instance (the parent of all Gap elements) to
     213        convert things into ``GapElement``. You must not create
     214        ``GapElement`` instances manually.
     215
     216    EXAMPLES::
     217
     218        sage: libgap(0)
     219        0
     220
     221    If Gap finds an error while evaluating, a corresponding assertion is raised::
     222
     223        sage: libgap.eval('1/0')
     224        Traceback (most recent call last):
     225        ...
     226        ValueError: libGAP: Error, Rational operations: <divisor> must not be zero
     227
     228    Also, a ``ValueError`` is raised if the input is not a simple expression::
     229
     230        sage: libgap.eval('1; 2; 3')
     231        Traceback (most recent call last):
     232        ...
     233        ValueError: can only evaluate a single statement
     234    """
     235
     236    def __cinit__(self):
     237        """
     238        The Cython constructor.
     239
     240        EXAMPLES::
     241       
     242            sage: libgap.eval('1')
     243            1
     244        """
     245        self.value = NULL
     246
     247
     248    def __init__(self):
     249        """
     250        The ``GapElement`` constructor
     251       
     252        Users must use the ``libgap`` instance to construct instances
     253        of :class:`GapElement`. Cython programmers must use
     254        :funct:`make_GapElement` factory function.
     255
     256        TESTS::
     257
     258            sage: from sage.libs.gap.element import GapElement
     259            sage: GapElement()
     260            Traceback (most recent call last):
     261            ...
     262            TypeError: This class cannot be instantiated from Python
     263        """
     264        raise TypeError('This class cannot be instantiated from Python')       
     265
     266
     267    cdef _initialize(self, parent, libGAP_Obj obj):
     268        r"""
     269        Initialize the GapElement.
     270
     271        This Cython method is called from :func:`make_GapElement` to
     272        initialize the newly-constructed object. You must never call
     273        it manually.
     274
     275        TESTS::
     276
     277            sage: n_before = libgap.count_GAP_objects()
     278            sage: a = libgap.eval('123')
     279            sage: b = libgap.eval('456')
     280            sage: c = libgap.eval('CyclicGroup(3)')
     281            sage: d = libgap.eval('"a string"')
     282            sage: libgap.collect()
     283            sage: del c
     284            sage: libgap.collect()
     285            sage: n_after = libgap.count_GAP_objects()
     286            sage: n_after - n_before
     287            3
     288        """
     289        assert self.value is NULL
     290        self._parent = parent
     291        self.value = obj
     292        if obj is NULL:
     293            return
     294        reference_obj(obj)
     295
     296
     297    def __dealloc__(self):
     298        r"""
     299        The Cython destructor
     300
     301        TESTS::
     302
     303            sage: pre_refcount = libgap.count_GAP_objects()
     304            sage: def f():
     305            ...       local_variable = libgap.eval('"This is a new string"')
     306            sage: f()
     307            sage: f()
     308            sage: f()
     309            sage: post_refcount = libgap.count_GAP_objects()
     310            sage: post_refcount - pre_refcount
     311            0
     312        """
     313        if self.value is NULL:
     314            return
     315        dereference_obj(self.value)
     316
     317
     318    def trait_names(self):
     319        """
     320        Return all Gap function names.
     321
     322        OUTPUT:
     323       
     324        A list of strings.
     325       
     326        EXAMPLES::
     327
     328            sage: x = libgap(1)
     329            sage: len(x.trait_names()) > 1000
     330            True
     331        """
     332        import gap_functions
     333        return gap_functions.common_gap_functions
     334
     335
     336    def __getattr__(self, name):
     337        r"""
     338        Return functionoid implementing the function ``name``.
     339       
     340        EXAMPLES::
     341
     342            sage: lst = libgap([])
     343            sage: lst.Add(1)    # this is the syntactic sugar
     344            sage: lst
     345            [ 1 ]
     346
     347        The above is equivalent to the following calls::
     348
     349            sage: lst = libgap.eval('[]')
     350            sage: libgap.eval('Add') (lst, 1)
     351            sage: lst
     352            [ 1 ]
     353
     354        TESTS::
     355
     356            sage: lst.Adddddd(1)
     357            Traceback (most recent call last):
     358            ...
     359            AttributeError: Name "Adddddd" is not defined in GAP.
     360
     361            sage: libgap.eval('some_name := 1')
     362            1
     363            sage: lst.some_name
     364            Traceback (most recent call last):
     365            ...
     366            AttributeError: Name "some_name" does not define a GAP function.
     367        """
     368        try:
     369            sig_on()
     370            proxy = make_GapElement_MethodProxy\
     371                (self.parent(), gap_eval(name), self)
     372            sig_off()
     373        except RuntimeError:
     374            raise AttributeError, 'Name "'+str(name)+'" is not defined in GAP.'
     375        if not proxy.is_function():
     376            raise AttributeError, 'Name "'+str(name)+'" does not define a GAP function.'
     377        return proxy
     378       
     379
     380    def __repr__(self):
     381        r"""
     382        Return a string representation of ``self``.
     383
     384        EXAMPLES::
     385       
     386            sage: libgap(0)
     387            0
     388            sage: libgap.eval('')
     389            NULL
     390            sage: libgap(0)
     391            0
     392        """
     393        if  self.value == NULL:
     394            return 'NULL'
     395        try:
     396            libgap_enter()
     397            libgap_start_interaction('')
     398            libGAP_ViewObjHandler(self.value)
     399            s = libgap_get_output()
     400            return s.strip()
     401        finally:
     402            libgap_finish_interaction()
     403            libgap_exit()
     404
     405
     406    cdef int _cmp_c_impl(self, Element other):
     407        """
     408        Compare ``self`` with ``other``.
     409
     410        OUTPUT:
     411
     412        Boolean.
     413
     414        EXAMPLES::
     415
     416            sage: a = libgap(123)
     417            sage: b = libgap('string')
     418            sage: abs(a._cmp_(b))
     419            1
     420            sage: (a < b) or (a > b)
     421            True
     422            sage: a._cmp_(libgap(123))
     423            0
     424        """
     425        cdef GapElement c_other = <GapElement>other
     426        libgap_enter()
     427        equal = libGAP_EQ(self.value, c_other.value)
     428        if equal:
     429            libgap_exit()
     430            return 0
     431        less = libGAP_LT(self.value, c_other.value)
     432        libgap_exit()
     433        return -1 if less else +1
     434
     435
     436    cpdef ModuleElement _add_(self, ModuleElement right):
     437        r"""
     438        Add two GapElement objects.
     439
     440        EXAMPLES::
     441
     442            sage: g1 = libgap(1)
     443            sage: g2 = libgap(2)
     444            sage: g1._add_(g2)
     445            3
     446            sage: g1 + g2    # indirect doctest
     447            3
     448
     449            sage: libgap(1) + libgap.CyclicGroup(2)
     450            Traceback (most recent call last):
     451            ...
     452            ValueError: libGAP: Error, no method found!
     453            For debugging hints type ?Recovery from NoMethodFound
     454            Error, no 1st choice method found for `+' on 2 arguments
     455        """
     456        cdef libGAP_Obj result
     457        try:
     458            libgap_enter()
     459            sig_on()
     460            result = libGAP_SUM(self.value, (<GapElement>right).value)
     461            sig_off()
     462        except RuntimeError, msg:
     463            libGAP_ClearError()
     464            raise ValueError, 'libGAP: '+str(msg)
     465        finally:
     466            libgap_exit()
     467        return make_any_gap_element(self.parent(), result)
     468
     469
     470    cpdef ModuleElement _sub_(self, ModuleElement right):
     471        r"""
     472        Subtract two GapElement objects.
     473
     474        EXAMPLES::
     475
     476            sage: g1 = libgap(1)
     477            sage: g2 = libgap(2)
     478            sage: g1._sub_(g2)
     479            -1
     480            sage: g1 - g2    # indirect doctest
     481            -1
     482
     483            sage: libgap(1) - libgap.CyclicGroup(2)
     484            Traceback (most recent call last):
     485            ...
     486            ValueError: libGAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
     487            Error, no 1st choice method found for `-' on 2 arguments
     488        """
     489        cdef libGAP_Obj result
     490        try:
     491            libgap_enter()
     492            sig_on()
     493            result = libGAP_DIFF(self.value, (<GapElement>right).value)
     494            sig_off()
     495        except RuntimeError, msg:
     496            libGAP_ClearError()
     497            raise ValueError, 'libGAP: '+str(msg)
     498        finally:
     499            libgap_exit()
     500        return make_any_gap_element(self.parent(), result)
     501       
     502
     503    cpdef RingElement _mul_(self, RingElement right):
     504        r"""
     505        Multiply two GapElement objects.
     506
     507        EXAMPLES::
     508
     509            sage: g1 = libgap(3)
     510            sage: g2 = libgap(5)
     511            sage: g1._mul_(g2)
     512            15
     513            sage: g1 * g2    # indirect doctest
     514            15
     515
     516            sage: libgap(1) * libgap.CyclicGroup(2)
     517            Traceback (most recent call last):
     518            ...
     519            ValueError: libGAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
     520            Error, no 1st choice method found for `*' on 2 arguments
     521        """
     522        cdef libGAP_Obj result
     523        try:
     524            libgap_enter()
     525            sig_on()
     526            result = libGAP_PROD(self.value, (<GapElement>right).value)
     527            sig_off()
     528        except RuntimeError, msg:
     529            libGAP_ClearError()
     530            raise ValueError, 'libGAP: '+str(msg)
     531        finally:
     532            libgap_exit()
     533        return make_any_gap_element(self.parent(), result)
     534
     535
     536    cpdef RingElement _div_(self, RingElement right):
     537        r"""
     538        Divide two GapElement objects.
     539
     540        EXAMPLES::
     541
     542            sage: g1 = libgap(3)
     543            sage: g2 = libgap(5)
     544            sage: g1._div_(g2)
     545            3/5
     546            sage: g1 / g2    # indirect doctest
     547            3/5
     548           
     549            sage: libgap(1) / libgap.CyclicGroup(2)
     550            Traceback (most recent call last):
     551            ...
     552            ValueError: libGAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
     553            Error, no 1st choice method found for `/' on 2 arguments
     554           
     555            sage: libgap(1) / libgap(0)
     556            Traceback (most recent call last):
     557            ...
     558            ValueError: libGAP: Error, Rational operations: <divisor> must not be zero
     559        """
     560        cdef libGAP_Obj result
     561        try:
     562            libgap_enter()
     563            sig_on()
     564            result = libGAP_QUO(self.value, (<GapElement>right).value)
     565            sig_off()
     566        except RuntimeError, msg:
     567            libGAP_ClearError()
     568            raise ValueError, 'libGAP: '+str(msg)
     569        finally:
     570            libgap_exit()
     571        return make_any_gap_element(self.parent(), result)
     572
     573
     574    def __mod__(GapElement self, GapElement right):
     575        r"""
     576        Modulus of two GapElement objects.
     577
     578        EXAMPLES::
     579
     580            sage: g1 = libgap(5)
     581            sage: g2 = libgap(2)
     582            sage: g1 % g2
     583            1
     584
     585            sage: libgap(1) % libgap.CyclicGroup(2)
     586            Traceback (most recent call last):
     587            ...
     588            ValueError: libGAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
     589            Error, no 1st choice method found for `mod' on 2 arguments
     590        """
     591        cdef libGAP_Obj result
     592        try:
     593            libgap_enter()
     594            sig_on()
     595            result = libGAP_MOD(self.value, right.value)
     596            sig_off()
     597        except RuntimeError, msg:
     598            libGAP_ClearError()
     599            raise ValueError, 'libGAP: '+str(msg)
     600        finally:
     601            libgap_exit()
     602        return make_any_gap_element(self.parent(), result)
     603
     604
     605    def __pow__(GapElement self, right, dummy):
     606        r"""
     607        Exponentiation of two GapElement objects.
     608
     609        EXAMPLES::
     610
     611            sage: g1 = libgap(5)
     612            sage: g2 = libgap(2)
     613            sage: g1 ^ g2
     614            25
     615
     616            sage: libgap.CyclicGroup(2) ^ 2
     617            Traceback (most recent call last):
     618            ...
     619            ValueError: libGAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
     620            Error, no 1st choice method found for `^' on 2 arguments
     621
     622            sage: libgap(3) ^ Infinity
     623            Traceback (most recent call last):
     624            ...
     625            ValueError: libGAP: Error, Variable: 'Infinity' must have a value
     626        """
     627        if not PY_TYPE_CHECK(right, GapElement):
     628            libgap = self.parent()
     629            right = libgap(right)
     630        cdef libGAP_Obj result
     631        try:
     632            libgap_enter()
     633            sig_on()
     634            result = libGAP_POW(self.value, (<GapElement>right).value)
     635            sig_off()
     636        except RuntimeError, msg:
     637            libGAP_ClearError()
     638            raise ValueError, 'libGAP: '+str(msg)
     639        finally:
     640            libgap_exit()
     641        return make_any_gap_element(self.parent(), result)
     642       
     643
     644    def is_function(self):
     645        """
     646        Return whether the wrapped GAP object is a function.
     647
     648        OUTPUT:
     649
     650        Boolean.
     651
     652        EXAMPLES::
     653       
     654            sage: a = libgap.eval("NormalSubgroups")
     655            sage: a.is_function()
     656            True
     657            sage: a = libgap(2/3)
     658            sage: a.is_function()
     659            False
     660        """
     661        return libGAP_IS_FUNC(self.value)
     662
     663
     664    def is_list(self):
     665        r"""
     666        Return whether the wrapped GAP object is a GAP List.
     667
     668        OUTPUT:
     669
     670        Boolean.
     671
     672        EXAMPLES::
     673
     674            sage: libgap.eval('[1, 2,,,, 5]').is_list()
     675            True
     676            sage: libgap.eval('3/2').is_list()
     677            False
     678        """
     679        return libGAP_IS_PLIST(self.value)
     680
     681
     682    def is_record(self):
     683        r"""
     684        Return whether the wrapped GAP object is a GAP record.
     685
     686        OUTPUT:
     687
     688        Boolean.
     689
     690        EXAMPLES::
     691
     692            sage: libgap.eval('[1, 2,,,, 5]').is_record()
     693            False
     694            sage: libgap.eval('rec(a:=1, b:=3)').is_record()
     695            True
     696        """
     697        return libGAP_IS_REC(self.value)
     698
     699
     700    cpdef is_bool(self):
     701        r"""
     702        Return whether the wrapped GAP object is a GAP boolean.
     703
     704        OUTPUT:
     705
     706        Boolean.
     707
     708        EXAMPLES::
     709       
     710            sage: libgap(True).is_bool()
     711            True
     712        """
     713        libgap = self.parent()
     714        cdef GapElement r_sage = libgap.IsBool(self)
     715        cdef libGAP_Obj r_gap = r_sage.value
     716        return r_gap == libGAP_True
     717
     718
     719    def is_int(self):
     720        r"""
     721        Return whether the wrapped GAP object is a GAP integer.
     722
     723        OUTPUT:
     724
     725        Boolean.
     726
     727        EXAMPLES::
     728
     729            sage: libgap(1).is_int()
     730            True
     731        """
     732        return libGAP_IS_INTOBJ(self.value)
     733
     734   
     735    def is_string(self):
     736        r"""
     737        Return whether the wrapped GAP object is a GAP string.
     738
     739        OUTPUT:
     740
     741        Boolean.
     742
     743        EXAMPLES::
     744
     745            sage: libgap('this is a string').is_string()
     746            True
     747        """
     748        return libGAP_IS_STRING(self.value)
     749
     750
     751    def is_permutation(self):
     752        r"""
     753        Return whether the wrapped GAP object is a GAP permutation.
     754
     755        OUTPUT:
     756
     757        Boolean.
     758
     759        EXAMPLES::
     760
     761            sage: perm = libgap.PermList( libgap([1,5,2,3,4]) );  perm
     762            (2,5,4,3)
     763            sage: perm.is_permutation()
     764            True
     765            sage: libgap('this is a string').is_permutation()
     766            False
     767        """
     768        return (libGAP_TNUM_OBJ(self.value) == libGAP_T_PERM2 or
     769                libGAP_TNUM_OBJ(self.value) == libGAP_T_PERM4)
     770
     771
     772    def sage(self):
     773        r"""
     774        Return the Sage equivalent of the :class:`GapElement`
     775
     776        EXAMPLES::
     777       
     778            sage: libgap(1).sage()
     779            1
     780            sage: type(_)
     781            <type 'sage.rings.integer.Integer'>
     782
     783            sage: libgap(3/7).sage()
     784            3/7
     785            sage: type(_)
     786            <type 'sage.rings.rational.Rational'>
     787
     788            sage: libgap.eval('5 + 7*E(3)').sage()
     789            7*zeta3 + 5
     790
     791            sage: libgap(True).sage()
     792            True
     793            sage: libgap(False).sage()
     794            False
     795            sage: type(_)
     796            <type 'bool'>
     797
     798            sage: libgap('this is a string').sage()
     799            'this is a string'
     800            sage: type(_)
     801            <type 'str'>
     802        """
     803        if self.value is NULL:           
     804            return None
     805        libgap = self.parent()
     806        if libgap.IsCyc(self).sage():
     807            conductor = self.Conductor()
     808            coeff = self.CoeffsCyc(conductor)
     809            conductor = conductor.sage()
     810            coeff = coeff.sage()
     811            from sage.rings.number_field.number_field import CyclotomicField
     812            F = CyclotomicField(conductor)
     813            return F(coeff)
     814        raise NotImplementedError('cannot construct equivalent Sage object')
     815
     816
     817
     818
     819############################################################################
     820### GapElement_Integer #####################################################
     821############################################################################
     822
     823cdef GapElement_Integer make_GapElement_Integer(parent, libGAP_Obj obj):
     824    r"""
     825    Turn a Gap integer object into a GapElement_Integer Sage object
     826
     827    EXAMPLES::
     828
     829        sage: libgap(123)
     830        123
     831        sage: type(_)
     832        <type 'sage.libs.gap.element.GapElement_Integer'>
     833    """
     834    cdef GapElement_Integer r = GapElement_Integer.__new__(GapElement_Integer)
     835    r._initialize(parent, obj)
     836    return r
     837
     838
     839cdef class GapElement_Integer(GapElement):
     840    r"""
     841    Derived class of GapElement for GAP rational numbers.
     842
     843    EXAMPLES::
     844
     845        sage: i = libgap(123)
     846        sage: type(i)
     847        <type 'sage.libs.gap.element.GapElement_Integer'>
     848    """
     849
     850    def sage(self):
     851        r"""
     852        Return the Sage equivalent of the :class:`GapElement_Integer`
     853
     854        OUTPUT:
     855
     856        An integer
     857
     858        EXAMPLES::
     859       
     860            sage: libgap([ 1, 3, 4 ]).sage()
     861            [1, 3, 4]
     862            sage: all( x in ZZ for x in _ )
     863            True
     864        """
     865        return ZZ(libGAP_INT_INTOBJ(self.value))
     866
     867
     868############################################################################
     869### GapElement_Rational ####################################################
     870############################################################################
     871
     872cdef GapElement_Rational make_GapElement_Rational(parent, libGAP_Obj obj):
     873    r"""
     874    Turn a Gap Rational number (of type ``Obj``) into a Cython ``GapElement_Rational``.
     875
     876    EXAMPLES::
     877
     878        sage: libgap(123/456)
     879        41/152
     880        sage: type(_)
     881        <type 'sage.libs.gap.element.GapElement_Rational'>
     882    """
     883    cdef GapElement_Rational r = GapElement_Rational.__new__(GapElement_Rational)
     884    r._initialize(parent, obj)
     885    return r
     886
     887
     888cdef class GapElement_Rational(GapElement):
     889    r"""
     890    Derived class of GapElement for GAP rational numbers.
     891
     892    EXAMPLES::
     893
     894        sage: r = libgap(123/456)
     895        sage: type(r)
     896        <type 'sage.libs.gap.element.GapElement_Rational'>
     897    """
     898   
     899    def sage(self):
     900        r"""
     901        Return the Sage equivalent of the :class:`GapElement`
     902
     903        OUTPUT:
     904
     905        A Python list.
     906
     907        EXAMPLES::
     908       
     909            sage: r = libgap(123/456);  r
     910            41/152
     911            sage: type(_)
     912            <type 'sage.libs.gap.element.GapElement_Rational'>
     913            sage: r.sage()
     914            41/152
     915            sage: type(_)
     916            <type 'sage.rings.rational.Rational'>
     917        """
     918        libgap = self.parent()
     919        return libgap.NumeratorRat(self).sage() / libgap.DenominatorRat(self).sage()
     920
     921
     922############################################################################
     923### GapElement_Boolean #####################################################
     924############################################################################
     925
     926cdef GapElement_Boolean make_GapElement_Boolean(parent, libGAP_Obj obj):
     927    r"""
     928    Turn a Gap Boolean number (of type ``Obj``) into a Cython ``GapElement_Boolean``.
     929
     930    EXAMPLES::
     931
     932        sage: libgap(True)
     933        true
     934        sage: type(_)
     935        <type 'sage.libs.gap.element.GapElement_Boolean'>
     936    """
     937    cdef GapElement_Boolean r = GapElement_Boolean.__new__(GapElement_Boolean)
     938    r._initialize(parent, obj)
     939    return r
     940
     941
     942cdef class GapElement_Boolean(GapElement):
     943    r"""
     944    Derived class of GapElement for GAP boolean values.
     945
     946    EXAMPLES::
     947
     948        sage: b = libgap(True)
     949        sage: type(b)
     950        <type 'sage.libs.gap.element.GapElement_Boolean'>
     951    """
     952   
     953    def sage(self):
     954        r"""
     955        Return the Sage equivalent of the :class:`GapElement`
     956
     957        OUTPUT:
     958
     959        A Python boolean if the values is either true or false. GAP
     960        booleans can have the third value ``Fail``, in which case a
     961        ``ValueError`` is raised.
     962
     963        EXAMPLES::
     964       
     965            sage: b = libgap.eval('true');  b
     966            true
     967            sage: type(_)
     968            <type 'sage.libs.gap.element.GapElement_Boolean'>
     969            sage: b.sage()
     970            True
     971            sage: type(_)
     972            <type 'bool'>
     973           
     974            sage: libgap.eval('fail')
     975            fail
     976            sage: _.sage()
     977            Traceback (most recent call last):
     978            ...
     979            ValueError: the GAP boolean value "fail" cannot be represented in Sage
     980        """
     981        if self.value == libGAP_True:   return True
     982        if self.value == libGAP_False:  return False
     983        raise ValueError('the GAP boolean value "fail" cannot be represented in Sage')
     984
     985
     986############################################################################
     987### GapElement_String ####################################################
     988############################################################################
     989
     990cdef GapElement_String make_GapElement_String(parent, libGAP_Obj obj):
     991    r"""
     992    Turn a Gap String (of type ``Obj``) into a Cython ``GapElement_String``.
     993
     994    EXAMPLES::
     995
     996        sage: libgap('this is a string')
     997        "this is a string"
     998        sage: type(_)
     999        <type 'sage.libs.gap.element.GapElement_String'>
     1000    """
     1001    cdef GapElement_String r = GapElement_String.__new__(GapElement_String)
     1002    r._initialize(parent, obj)
     1003    return r
     1004
     1005
     1006cdef class GapElement_String(GapElement):
     1007    r"""
     1008    Derived class of GapElement for GAP strings.
     1009
     1010    EXAMPLES::
     1011
     1012        sage: s = libgap('string')
     1013        sage: type(s)
     1014        <type 'sage.libs.gap.element.GapElement_String'>
     1015    """
     1016   
     1017    def sage(self):
     1018        r"""
     1019        Return the Sage equivalent of the :class:`GapElement`
     1020
     1021        OUTPUT:
     1022
     1023        A Python list.
     1024
     1025        EXAMPLES::
     1026       
     1027            sage: s = libgap.eval(' "string" '); s
     1028            "string"
     1029            sage: type(_)
     1030            <type 'sage.libs.gap.element.GapElement_String'>
     1031            sage: s.sage()
     1032            'string'
     1033            sage: type(_)
     1034            <type 'str'>
     1035        """
     1036        libgap_enter()
     1037        s = libGAP_CSTR_STRING(self.value)
     1038        libgap_exit()
     1039        return s
     1040
     1041
     1042
     1043############################################################################
     1044### GapElement_Function ####################################################
     1045############################################################################
     1046
     1047cdef GapElement_Function make_GapElement_Function(parent, libGAP_Obj obj):
     1048    r"""
     1049    Turn a Gap C function object (of type ``Obj``) into a Cython ``GapElement_Function``.
     1050
     1051    INPUT:
     1052
     1053    - ``parent`` -- the parent of the new :class:`GapElement`
     1054
     1055    - ``obj`` -- a GAP function object.
     1056
     1057    OUTPUT:
     1058
     1059    A :class:`GapElement_Function` instance.
     1060
     1061    EXAMPLES::
     1062
     1063        sage: libgap.CycleLength
     1064        <Gap function "CycleLength">
     1065        sage: type(_)
     1066        <type 'sage.libs.gap.element.GapElement_Function'>
     1067    """
     1068    cdef GapElement_Function r = GapElement_Function.__new__(GapElement_Function)
     1069    r._initialize(parent, obj)
     1070    return r
     1071
     1072
     1073cdef class GapElement_Function(GapElement):
     1074    r"""
     1075    Derived class of GapElement for GAP functions.
     1076
     1077    EXAMPLES::
     1078
     1079        sage: f = libgap.Cycles
     1080        sage: type(f)
     1081        <type 'sage.libs.gap.element.GapElement_Function'>
     1082    """
     1083
     1084
     1085    def __repr__(self):
     1086        r"""
     1087        Return a string representation
     1088       
     1089        OUTPUT:
     1090
     1091        String.
     1092
     1093        EXAMPLES::
     1094       
     1095            sage: libgap.Orbits
     1096            <Gap function "Orbits">
     1097        """
     1098        libgap = self.parent()
     1099        name = libgap.NameFunction(self)
     1100        s = '<Gap function "'+name.sage()+'">'
     1101        return s
     1102   
     1103
     1104    def __call__(self, *args):
     1105        """
     1106        Call syntax for functions.
     1107
     1108        INPUT:
     1109
     1110        - ``*args`` -- arguments. Will be converted to `GapElement` if
     1111          they are not already of this type.
     1112
     1113        OUTPUT:
     1114
     1115        A :class:`GapElement` encapsulating the functions return
     1116        value, or ``None`` if it does not return anything.
     1117
     1118        EXAMPLES::
     1119       
     1120            sage: a = libgap.NormalSubgroups
     1121            sage: b = libgap.SymmetricGroup(4)
     1122            sage: libgap.collect()
     1123            sage: a
     1124            <Gap function "NormalSubgroups">
     1125            sage: b
     1126            Sym( [ 1 .. 4 ] )
     1127            sage: a(b)
     1128            [ Group(()),
     1129              Group([ (1,4)(2,3), (1,3)(2,4) ]),
     1130              Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]),
     1131              Sym( [ 1 .. 4 ] ) ]
     1132
     1133            sage: libgap.eval("a := NormalSubgroups")
     1134            <Gap function "NormalSubgroups">
     1135            sage: libgap.eval("b := SymmetricGroup(4)")
     1136            Sym( [ 1 .. 4 ] )
     1137            sage: libgap.collect()
     1138            sage: libgap.eval('a') (libgap.eval('b'))
     1139            [ Group(()),
     1140              Group([ (1,4)(2,3), (1,3)(2,4) ]),
     1141              Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]),
     1142              Sym( [ 1 .. 4 ] ) ]
     1143            sage: a = libgap.eval('a')
     1144            sage: b = libgap.eval('b')
     1145            sage: libgap.collect()
     1146            sage: a(b)
     1147            [ Group(()),
     1148              Group([ (1,4)(2,3), (1,3)(2,4) ]),
     1149              Group([ (2,4,3), (1,4)(2,3), (1,3)(2,4) ]),
     1150              Sym( [ 1 .. 4 ] ) ]
     1151
     1152        Not every ``GapElement`` is callable::
     1153       
     1154            sage: f = libgap(3)
     1155            sage: f()
     1156            Traceback (most recent call last):
     1157            ...
     1158            TypeError: 'sage.libs.gap.element.GapElement_Integer' object is not callable
     1159
     1160        We illustrate appending to a list which returns None::
     1161
     1162            sage: a = libgap([]); a
     1163            [  ]
     1164            sage: a.Add(5); a
     1165            [ 5 ]
     1166            sage: a.Add(10); a
     1167            [ 5, 10 ]       
     1168
     1169        TESTS::
     1170
     1171            sage: s = libgap.Sum
     1172            sage: s(libgap([1,2]))
     1173            3
     1174            sage: s(libgap(1), libgap(2))
     1175            Traceback (most recent call last):
     1176            ...
     1177            ValueError: libGAP: Error, no method found! For debugging hints type ?Recovery from NoMethodFound
     1178            Error, no 1st choice method found for `SumOp' on 2 arguments
     1179
     1180            sage: for i in range(0,100):
     1181            ...       rnd = [ randint(-10,10) for i in range(0,randint(0,7)) ]
     1182            ...       # compute the sum in GAP
     1183            ...       _ = libgap.Sum(rnd)
     1184            ...       try:
     1185            ...           libgap.Sum(*rnd)   
     1186            ...           print 'This should have triggered a ValueError'
     1187            ...           print 'because Sum needs a list as argument'
     1188            ...       except ValueError:
     1189            ...           pass
     1190        """
     1191        cdef libGAP_Obj result = NULL
     1192        cdef libGAP_Obj arg_list
     1193        cdef int i, n = len(args)
     1194       
     1195        if n > 0:
     1196            libgap = self.parent()
     1197            a = [x if isinstance(x,GapElement) else libgap(x) for x in args]
     1198
     1199        try:
     1200            libgap_enter()
     1201            sig_on()
     1202            if n == 0:
     1203                result = libGAP_CALL_0ARGS(self.value)
     1204            elif n == 1:
     1205                result = libGAP_CALL_1ARGS(self.value,
     1206                                           (<GapElement>a[0]).value)
     1207            elif n == 2:
     1208                result = libGAP_CALL_2ARGS(self.value,
     1209                                           (<GapElement>a[0]).value,
     1210                                           (<GapElement>a[1]).value)
     1211            elif n == 3:
     1212                result = libGAP_CALL_3ARGS(self.value,
     1213                                           (<GapElement>a[0]).value,
     1214                                           (<GapElement>a[1]).value,
     1215                                           (<GapElement>a[2]).value)
     1216            elif n == 4:
     1217                result = libGAP_CALL_4ARGS(self.value,
     1218                                           (<GapElement>a[0]).value,
     1219                                           (<GapElement>a[1]).value,
     1220                                           (<GapElement>a[2]).value,
     1221                                           (<GapElement>a[3]).value)
     1222            elif n == 5:
     1223                result = libGAP_CALL_5ARGS(self.value,
     1224                                           (<GapElement>a[0]).value,
     1225                                           (<GapElement>a[1]).value,
     1226                                           (<GapElement>a[2]).value,
     1227                                           (<GapElement>a[3]).value,
     1228                                           (<GapElement>a[4]).value)
     1229            elif n == 6:
     1230                result = libGAP_CALL_6ARGS(self.value,
     1231                                           (<GapElement>a[0]).value,
     1232                                           (<GapElement>a[1]).value,
     1233                                           (<GapElement>a[2]).value,
     1234                                           (<GapElement>a[3]).value,
     1235                                           (<GapElement>a[4]).value,
     1236                                           (<GapElement>a[5]).value)
     1237            elif n >= 7:
     1238                libgap_exit()
     1239                arg_list = make_gap_list(args)
     1240                libgap_enter()
     1241                result = libGAP_CALL_XARGS(self.value, arg_list)
     1242            sig_off()
     1243        except RuntimeError, msg:
     1244            raise ValueError, 'libGAP: '+str(msg)
     1245        finally:
     1246            libgap_exit()
     1247
     1248        if result == NULL:
     1249            # We called a procedure that does not return anything
     1250            return None
     1251           
     1252        return make_any_gap_element(self.parent(), result)
     1253
     1254
     1255    def _sage_doc_(self):
     1256        r"""
     1257        Return the help string
     1258
     1259        EXAMPLES::
     1260
     1261            sage: f = libgap.CyclicGroup
     1262            sage: 'constructs  the  cyclic  group' in f._sage_doc_()
     1263            True
     1264
     1265        You would get the full help by typing ``f?`` in the command line.
     1266        """
     1267        libgap = self.parent()
     1268        from sage.interfaces.gap import gap
     1269        return gap.help(libgap.NameFunction(self).sage(), pager=False)
     1270
     1271
     1272
     1273   
     1274############################################################################
     1275### GapElement_MethodProxy #################################################
     1276############################################################################
     1277
     1278cdef GapElement_MethodProxy make_GapElement_MethodProxy(parent, libGAP_Obj function, GapElement base_object):
     1279    r"""
     1280    Turn a Gap C rec object (of type ``Obj``) into a Cython ``GapElement_Record``.
     1281
     1282    This class implement syntactic sugar so that you can write
     1283    ``gapelement.f()`` instead of ``libgap.f(gapelement)`` for any GAP
     1284    function ``f``.
     1285
     1286    INPUT:
     1287
     1288    - ``parent`` -- the parent of the new :class:`GapElement`
     1289
     1290    - ``obj`` -- a GAP function object.
     1291
     1292    - ``base_object`` -- The first argument to be inserted into the function.
     1293
     1294    OUTPUT:
     1295
     1296    A :class:`GapElement_MethodProxy` instance.
     1297
     1298    EXAMPLES::
     1299
     1300        sage: lst = libgap([])
     1301        sage: type( lst.Add )
     1302        <type 'sage.libs.gap.element.GapElement_MethodProxy'>
     1303    """
     1304    cdef GapElement_MethodProxy r = GapElement_MethodProxy.__new__(GapElement_MethodProxy)
     1305    r._initialize(parent, function)
     1306    r.first_argument = base_object
     1307    return r
     1308
     1309
     1310cdef class GapElement_MethodProxy(GapElement_Function):
     1311    r"""
     1312    Helper class returned by ``GapElement.__getattr__``.
     1313
     1314    Derived class of GapElement for GAP functions. Like its parent,
     1315    you can call instances to implement function call syntax. The only
     1316    difference is that a fixed first argument is prepended to the
     1317    argument list.
     1318
     1319    EXAMPLES::
     1320
     1321        sage: lst = libgap([])
     1322        sage: lst.Add
     1323        <Gap function "Add">
     1324        sage: type(_)
     1325        <type 'sage.libs.gap.element.GapElement_MethodProxy'>
     1326        sage: lst.Add(1)
     1327        sage: lst
     1328        [ 1 ]
     1329    """
     1330
     1331    def __call__(self, *args):
     1332        """
     1333        Call syntax for methods.
     1334
     1335        This method is analogous to
     1336        :meth:`GapElement_Function.__call__`, except that it inserts a
     1337        fixed :class:`GapElement` in the first slot of the function.
     1338
     1339        INPUT:
     1340
     1341        - ``*args`` -- arguments. Will be converted to `GapElement` if
     1342          they are not already of this type.
     1343
     1344        OUTPUT:
     1345
     1346        A :class:`GapElement` encapsulating the functions return
     1347        value, or ``None`` if it does not return anything.
     1348
     1349        EXAMPLES::
     1350       
     1351            sage: lst = libgap.eval('[1,,3]')
     1352            sage: lst.Add.__call__(4)
     1353            sage: lst.Add(5)
     1354            sage: lst
     1355            [ 1,, 3, 4, 5 ]
     1356        """
     1357        if len(args) > 0:
     1358            return GapElement_Function.__call__(self, * ([self.first_argument] + list(args)))
     1359        else:
     1360            return GapElement_Function.__call__(self, self.first_argument)
     1361
     1362
     1363
     1364############################################################################
     1365### GapElement_List ########################################################
     1366############################################################################
     1367
     1368cdef GapElement_List make_GapElement_List(parent, libGAP_Obj obj):
     1369    r"""
     1370    Turn a Gap C List object (of type ``Obj``) into a Cython ``GapElement_List``.
     1371
     1372    EXAMPLES::
     1373
     1374        sage: libgap([0, 2, 3])
     1375        [ 0, 2, 3 ]
     1376        sage: type(_)
     1377        <type 'sage.libs.gap.element.GapElement_List'>
     1378    """
     1379    cdef GapElement_List r = GapElement_List.__new__(GapElement_List)
     1380    r._initialize(parent, obj)
     1381    return r
     1382
     1383
     1384cdef class GapElement_List(GapElement):
     1385    r"""
     1386    Derived class of GapElement for GAP Lists.
     1387
     1388    .. NOTE::
     1389
     1390        Lists are indexed by `0..len(l)-1`, as expected from
     1391        Python. This differs from the GAP convention where lists start
     1392        at `1`.
     1393
     1394    EXAMPLES::
     1395
     1396        sage: lst = libgap.SymmetricGroup(3).List(); lst
     1397        [ (), (1,3), (1,2,3), (2,3), (1,3,2), (1,2) ]
     1398        sage: type(lst)
     1399        <type 'sage.libs.gap.element.GapElement_List'>
     1400        sage: len(lst)
     1401        6
     1402        sage: lst[3]
     1403        (2,3)
     1404
     1405    We can easily convert a Gap ``List`` object into a Python ``list``::
     1406
     1407        sage: list(lst)
     1408        [(), (1,3), (1,2,3), (2,3), (1,3,2), (1,2)]
     1409        sage: type(_)
     1410        <type 'list'>
     1411
     1412    Range checking is performed::
     1413
     1414        sage: lst[10]
     1415        Traceback (most recent call last):
     1416        ...
     1417        IndexError: Index out of range.
     1418    """
     1419   
     1420    def __len__(self):
     1421        r"""
     1422        Return the length of the list.
     1423
     1424        OUTPUT:
     1425       
     1426        Integer.
     1427       
     1428        EXAMPLES::
     1429       
     1430            sage: lst = libgap.eval('[1,,,4]')   # a sparse list
     1431            sage: len(lst)
     1432            4
     1433        """
     1434        return libGAP_LEN_PLIST(self.value)
     1435       
     1436
     1437    def __getitem__(self, i):
     1438        r"""
     1439        Return the ``i``-th element of the list.
     1440
     1441        As usual in Python, indexing starts at `0` and not at `1` (as
     1442        in GAP).
     1443
     1444        INPUT:
     1445       
     1446        - ``i`` -- integer.
     1447
     1448        OUTPUT:
     1449
     1450        The ``i``-th element as a :class:`GapElement`.
     1451       
     1452        EXAMPLES::
     1453       
     1454            sage: lst = libgap.eval('["first",,,"last"]')   # a sparse list
     1455            sage: lst[0]
     1456            "first"
     1457        """
     1458        if i<0 or i>=len(self):
     1459            raise IndexError, 'Index out of range.'
     1460        return make_any_gap_element(self.parent(),
     1461                                    libGAP_ELM_PLIST(self.value, i+1))
     1462           
     1463
     1464    def sage(self):
     1465        r"""
     1466        Return the Sage equivalent of the :class:`GapElement`
     1467
     1468        OUTPUT:
     1469
     1470        A Python list.
     1471
     1472        EXAMPLES::
     1473       
     1474            sage: libgap([ 1, 3, 4 ]).sage()
     1475            [1, 3, 4]
     1476            sage: all( x in ZZ for x in _ )
     1477            True
     1478        """
     1479        return [ x.sage() for x in self ]
     1480
     1481
     1482
     1483
     1484############################################################################
     1485### GapElement_Permutation #################################################
     1486############################################################################
     1487
     1488
     1489cdef GapElement_Permutation make_GapElement_Permutation(parent, libGAP_Obj obj):
     1490    r"""
     1491    Turn a Gap C permutation object (of type ``Obj``) into a Cython ``GapElement_Permutation``.
     1492
     1493    EXAMPLES::
     1494
     1495        sage: libgap.eval('(1,3,2)(4,5,8)')
     1496        (1,3,2)(4,5,8)
     1497        sage: type(_)
     1498        <type 'sage.libs.gap.element.GapElement_Permutation'>
     1499    """
     1500    cdef GapElement_Permutation r = GapElement_Permutation.__new__(GapElement_Permutation)
     1501    r._initialize(parent, obj)
     1502    return r
     1503
     1504
     1505cdef class GapElement_Permutation(GapElement):
     1506    r"""
     1507    Derived class of GapElement for GAP permutations.
     1508
     1509    .. NOTE::
     1510
     1511        Permutations in GAP act on the numbers starting with 1.
     1512
     1513    EXAMPLES::
     1514
     1515        sage: perm = libgap.eval('(1,5,2)(4,3,8)')
     1516        sage: type(perm)
     1517        <type 'sage.libs.gap.element.GapElement_Permutation'>
     1518    """
     1519   
     1520    def sage(self):
     1521        r"""
     1522        Return the Sage equivalent of the :class:`GapElement`
     1523
     1524        EXAMPLES::
     1525       
     1526            sage: perm_gap = libgap.eval('(1,5,2)(4,3,8)');  perm_gap
     1527            (1,5,2)(3,8,4)
     1528            sage: perm_gap.sage()
     1529            (1,5,2)(3,8,4)
     1530            sage: type(_)
     1531            <type 'sage.groups.perm_gps.permgroup_element.PermutationGroupElement'>
     1532        """
     1533        from sage.groups.perm_gps.permgroup_element import PermutationGroupElement
     1534        libgap = self.parent()
     1535        return PermutationGroupElement(libgap.ListPerm(self).sage())
     1536
     1537
     1538
     1539############################################################################
     1540### GapElement_Record ######################################################
     1541############################################################################
     1542
     1543cdef GapElement_Record make_GapElement_Record(parent, libGAP_Obj obj):
     1544    r"""
     1545    Turn a Gap C rec object (of type ``Obj``) into a Cython ``GapElement_Record``.
     1546
     1547    EXAMPLES::
     1548
     1549        sage: libgap.eval('rec(a:=0, b:=2, c:=3)')
     1550        rec( a := 0, b := 2, c := 3 )
     1551        sage: type(_)
     1552        <type 'sage.libs.gap.element.GapElement_Record'>
     1553    """
     1554    cdef GapElement_Record r = GapElement_Record.__new__(GapElement_Record)
     1555    r._initialize(parent, obj)
     1556    return r
     1557
     1558
     1559cdef class GapElement_Record(GapElement):
     1560    r"""
     1561    Derived class of GapElement for GAP records.
     1562
     1563    EXAMPLES::
     1564
     1565        sage: rec = libgap.eval('rec(a:=123, b:=456)')
     1566        sage: type(rec)
     1567        <type 'sage.libs.gap.element.GapElement_Record'>
     1568        sage: len(rec)
     1569        2
     1570        sage: rec['a']
     1571        123
     1572
     1573    We can easily convert a Gap ``rec`` object into a Python ``dict``::
     1574
     1575        sage: dict(rec)
     1576        {'a': 123, 'b': 456}
     1577        sage: type(_)
     1578        <type 'dict'>
     1579
     1580    Range checking is performed::
     1581
     1582        sage: rec['no_such_element']
     1583        Traceback (most recent call last):
     1584        ...
     1585        IndexError: libGAP: Error, Record: '<rec>.no_such_element' must have an assigned value
     1586    """
     1587   
     1588    def __len__(self):
     1589        r"""
     1590        Return the length of the record.
     1591
     1592        OUTPUT:
     1593       
     1594        Integer. The number of entries in the record.
     1595       
     1596        EXAMPLES::
     1597       
     1598            sage: rec = libgap.eval('rec(a:=123, b:=456, S3:=SymmetricGroup(3))')
     1599            sage: len(rec)
     1600            3
     1601        """
     1602        return libGAP_LEN_PREC(self.value)
     1603       
     1604
     1605    def __iter__(self):
     1606        r"""
     1607        Iterate over the elements of the record.
     1608
     1609        OUTPUT:
     1610
     1611        A :class:`GapElement_RecordIterator`.
     1612
     1613        EXAMPLES::
     1614
     1615            sage: rec = libgap.eval('rec(a:=123, b:=456)')
     1616            sage: iter = rec.__iter__()
     1617            sage: type(iter)
     1618            <type 'sage.libs.gap.element.GapElement_RecordIterator'>
     1619            sage: list(rec)
     1620            [('a', 123), ('b', 456)]
     1621        """
     1622        return GapElement_RecordIterator(self)
     1623
     1624
     1625    cpdef libGAP_UInt record_name_to_index(self, bytes py_name):
     1626        r"""
     1627        Convert string to GAP record index.
     1628
     1629        INPUT:
     1630
     1631        - ``py_name`` -- a python string.
     1632
     1633        OUTPUT:
     1634
     1635        A ``UInt``, which is a GAP hash of the string. If this is the
     1636        first time the string is encountered, a new integer is
     1637        returned(!)
     1638       
     1639        EXAMPLE::
     1640
     1641            sage: rec = libgap.eval('rec(first:=123, second:=456)')
     1642            sage: rec.record_name_to_index('first')   # random output
     1643            1812L
     1644            sage: rec.record_name_to_index('no_such_name') # random output
     1645            3776L
     1646        """
     1647        cdef char* c_name = py_name
     1648        try:
     1649            libgap_enter()
     1650            return libGAP_RNamName(c_name)
     1651        finally:
     1652            libgap_exit()
     1653
     1654    def __getitem__(self, name):
     1655        r"""
     1656        Return the ``name``-th element of the GAP record.
     1657
     1658        INPUT:
     1659       
     1660        - ``name`` -- string.
     1661
     1662        OUTPUT:
     1663
     1664        The record element labelled by ``name`` as a :class:`GapElement`.
     1665       
     1666        EXAMPLES::
     1667       
     1668            sage: rec = libgap.eval('rec(first:=123, second:=456)')
     1669            sage: rec['first']
     1670            123
     1671        """
     1672        i = self.record_name_to_index(name)
     1673        cdef libGAP_Obj result
     1674        try:
     1675            sig_on()
     1676            result = libGAP_ELM_REC(self.value, i)
     1677            sig_off()
     1678        except RuntimeError, msg:
     1679            raise IndexError, 'libGAP: '+str(msg)
     1680        return make_any_gap_element(self.parent(), result)
     1681
     1682
     1683    def sage(self):
     1684        r"""
     1685        Return the Sage equivalent of the :class:`GapElement`
     1686
     1687        EXAMPLES::
     1688       
     1689            sage: libgap.eval('rec(a:=1, b:=2)').sage()
     1690            {'a': 1, 'b': 2}
     1691            sage: all( isinstance(key,str) and val in ZZ for key,val in _.items() )
     1692            True
     1693
     1694            sage: rec = libgap.eval('rec(a:=123, b:=456, Sym3:=SymmetricGroup(3))')
     1695            sage: rec.sage()
     1696            {'a': 123,
     1697             'Sym3': NotImplementedError('cannot construct equivalent Sage object',),
     1698             'b': 456}
     1699        """
     1700        result = dict()
     1701        for key, val in self:
     1702            try:
     1703                val = val.sage()
     1704            except Exception as ex:
     1705                val = ex
     1706            result[key] = val
     1707        return result
     1708
     1709
     1710cdef class GapElement_RecordIterator(object):
     1711    r"""
     1712    Iterator for :class:`GapElement_Record`
     1713
     1714    Since Cython does not support generators yet, we implement the
     1715    older iterator specification with this auxiliary class.
     1716
     1717    INPUT:
     1718
     1719    - ``rec`` -- the :class:`GapElement_Record` to iterate over.
     1720
     1721    EXAMPLES::
     1722
     1723        sage: rec = libgap.eval('rec(a:=123, b:=456)')
     1724        sage: list(rec)
     1725        [('a', 123), ('b', 456)]
     1726        sage: dict(rec)
     1727        {'a': 123, 'b': 456}
     1728    """
     1729   
     1730    def __cinit__(self, rec):
     1731        r"""
     1732        The Cython constructor.
     1733
     1734        INPUT:
     1735
     1736        - ``rec`` -- the :class:`GapElement_Record` to iterate over.
     1737       
     1738        EXAMPLES::
     1739
     1740            sage: libgap.eval('rec(a:=123, b:=456)')
     1741            rec( a := 123, b := 456 )
     1742        """
     1743        self.rec = rec
     1744        self.i = 1
     1745
     1746
     1747    def __next__(self):
     1748        r"""
     1749        The next elemnt in the record.
     1750
     1751        OUTPUT:
     1752
     1753        A tuple ``(key, value)`` where ``key`` is a string and
     1754        ``value`` is the corresponding :class:`GapElement`.
     1755
     1756        EXAMPLES::
     1757
     1758            sage: rec = libgap.eval('rec(a:=123, b:=456)')
     1759            sage: iter = rec.__iter__()
     1760            sage: iter.__next__()
     1761            ('a', 123)
     1762            sage: iter.next()
     1763            ('b', 456)
     1764        """
     1765        cdef libGAP_UInt i = self.i
     1766        if i>len(self.rec):
     1767            raise StopIteration
     1768        # note the abs: negative values mean the rec keys are not sorted
     1769        libgap_enter()
     1770        key_index = abs(libGAP_GET_RNAM_PREC(self.rec.value, i))
     1771        key = libGAP_NAME_RNAM(key_index)
     1772        cdef libGAP_Obj result = libGAP_GET_ELM_PREC(self.rec.value,i)
     1773        libgap_exit()
     1774        val = make_any_gap_element(self.rec.parent(), result)
     1775        self.i += 1
     1776        return (key, val)
     1777
  • new file sage/libs/gap/gap_functions.py

    diff --git a/sage/libs/gap/gap_functions.py b/sage/libs/gap/gap_functions.py
    new file mode 100644
    - +  
     1###############################################################################
     2#       Copyright (C) 2009, William Stein <wstein@gmail.com>
     3#       Copyright (C) 2012, Volker Braun <vbraun.name@gmail.com>
     4#
     5#   Distributed under the terms of the GNU General Public License (GPL)
     6#   as published by the Free Software Foundation; either version 2 of
     7#   the License, or (at your option) any later version.
     8#                   http://www.gnu.org/licenses/
     9###############################################################################
     10
     11
     12# selected gap functions to use in tab completion
     13common_gap_functions = [
     14  'AbelianGroup',
     15  'AbelianInvariants',
     16  'AbelianInvariantsMultiplier',
     17  'AbelianInvariantsOfList',
     18  'AbelianNumberField',
     19  'AbsInt',
     20  'AbsoluteValue',
     21  'Action',
     22  'ActionHomomorphism',
     23  'Add',
     24  'AddCoeffs',
     25  'AddGenerator',
     26  'AddRelator',
     27  'AddRowVector',
     28  'AddRule',
     29  'AddSet',
     30  'AdjointMatrix',
     31  'Algebra',
     32  'AlternatingGroup',
     33  'AntiSymmetricParts',
     34  'Append',
     35  'AppendTo',
     36  'Apply',
     37  'AsGroup',
     38  'Assert',
     39  'AutomorphismGroup',
     40  'BaseOfGroup',
     41  'Basis',
     42  'BasisVectors',
     43  'Binomial',
     44  'BlockMatrix',
     45  'Blocks',
     46  'CartanMatrix',
     47  'CartanSubalgebra',
     48  'Cartesian',
     49  'Center',
     50  'CentralCharacter',
     51  'Centralizer',
     52  'CentralizerInGLnZ',
     53  'CentralizerModulo',
     54  'Centre',
     55  'CentreOfCharacter',
     56  'Character',
     57  'CharacterDegrees',
     58  'CharacterNames',
     59  'CharacterTable',
     60  'Characteristic',
     61  'CharacteristicPolynomial',
     62  'CheckFixedPoints',
     63  'ChevalleyBasis',
     64  'ChiefNormalSeriesByPcgs',
     65  'ChiefSeries',
     66  'ChineseRem',
     67  'Chomp',
     68  'ClassElementLattice',
     69  'ClassFunction',
     70  'ClassFunctionSameType',
     71  'ClassOrbit',
     72  'ClassPermutation',
     73  'ClassRoots',
     74  'ClassesSolvableGroup',
     75  'CoKernel',
     76  'Coefficients',
     77  'CoefficientsRing',
     78  'CoeffsCyc',
     79  'CoeffsMod',
     80  'CollapsedMat',
     81  'Collected',
     82  'Combinations',
     83  'CombinatorialCollector',
     84  'CommutatorFactorGroup',
     85  'CommutatorLength',
     86  'CommutatorSubgroup',
     87  'Compacted',
     88  'CompanionMat',
     89  'ComplexConjugate',
     90  'ComplexificationQuat',
     91  'CompositionMapping',
     92  'CompositionMapping2',
     93  'CompositionMaps',
     94  'Concatenation',
     95  'Conductor',
     96  'ConjugacyClass',
     97  'ConjugacyClassSubgroups',
     98  'ConjugacyClasses',
     99  'ConjugateGroup',
     100  'ConjugateSubgroup',
     101  'ConjugateSubgroups',
     102  'ConstituentsCompositionMapping',
     103  'ContainedMaps',
     104  'ContinuedFractionApproximationOfRoot',
     105  'ContinuedFractionExpansionOfRoot',
     106  'ConvertToCharacterTable',
     107  'ConvertToMatrixRep',
     108  'ConvertToRangeRep',
     109  'ConvertToStringRep',
     110  'ConvertToTableOfMarks',
     111  'ConvertToVectorRep',
     112  'ConwayPolynomial',
     113  'CosetTable',
     114  'CosetTableInWholeGroup',
     115  'Cycle',
     116  'CycleLength',
     117  'CycleLengths',
     118  'CycleStructureClass',
     119  'CycleStructurePerm',
     120  'Cycles',
     121  'CyclicGroup',
     122  'CyclotomicField',
     123  'CyclotomicPolynomial',
     124  'Cyclotomics',
     125  'DefiningPolynomial',
     126  'Degree',
     127  'DegreeFFE',
     128  'DenominatorCyc',
     129  'DenominatorOfRationalFunction',
     130  'DenominatorRat',
     131  'Derivations',
     132  'Derivative',
     133  'DerivedLength',
     134  'DerivedSeries',
     135  'DerivedSeriesOfGroup',
     136  'DerivedSubgroup',
     137  'Determinant',
     138  'DeterminantIntMat',
     139  'DeterminantMat',
     140  'DeterminantMatDivFree',
     141  'DeterminantOfCharacter',
     142  'DiagonalMat',
     143  'DihedralGroup',
     144  'Dimension',
     145  'DimensionOfMatrixGroup',
     146  'DimensionsMat',
     147  'DirectProduct',
     148  'Discriminant',
     149  'Display',
     150  'DivisorsInt',
     151  'DnLattice',
     152  'DominantCharacter',
     153  'DominantWeights',
     154  'DoubleCoset',
     155  'DoubleCosetRepsAndSizes',
     156  'DoubleCosets',
     157  'DoubleHashArraySize',
     158  'DuplicateFreeList',
     159  'E',
     160  'Eigenspaces',
     161  'Eigenvalues',
     162  'Eigenvectors',
     163  'ElementOfFpGroup',
     164  'ElementOfFpSemigroup',
     165  'ElementOrdersPowerMap',
     166  'Elements',
     167  'ElementsStabChain',
     168  'EpimorphismFromFreeGroup',
     169  'EpimorphismNilpotentQuotient',
     170  'EpimorphismPGroup',
     171  'EpimorphismQuotientSystem',
     172  'EpimorphismSchurCover',
     173  'EuclideanQuotient',
     174  'EuclideanRemainder',
     175  'EulerianFunction',
     176  'Exponent',
     177  'Extension',
     178  'ExteriorCentre',
     179  'ExteriorPower',
     180  'Extract',
     181  'FactorGroup',
     182  'Factorial',
     183  'Factorization',
     184  'Factors',
     185  'FactorsInt',
     186  'Fibonacci',
     187  'Field',
     188  'FieldExtension',
     189  'FieldOfMatrixGroup',
     190  'Filtered',
     191  'First',
     192  'FittingSubgroup',
     193  'Flat',
     194  'ForAll',
     195  'ForAny',
     196  'FreeGroup',
     197  'FreeProduct',
     198  'FreeSemigroup',
     199  'FrobeniusAutomorphism',
     200  'GF',
     201  'GL',
     202  'GQuotients',
     203  'GaloisCyc',
     204  'GaloisField',
     205  'GaloisGroup',
     206  'GaloisMat',
     207  'GaloisStabilizer',
     208  'GaussianIntegers',
     209  'GaussianRationals',
     210  'Gcd',
     211  'GcdInt',
     212  'GcdOp',
     213  'GeneralLinearGroup',
     214  'GeneralOrthogonalGroup',
     215  'GeneralUnitaryGroup',
     216  'GeneralisedEigenspaces',
     217  'GeneralisedEigenvalues',
     218  'GeneralizedEigenspaces',
     219  'GeneralizedEigenvalues',
     220  'GeneratorsOfField',
     221  'GeneratorsOfGroup',
     222  'GeneratorsOfIdeal',
     223  'GlobalMersenneTwister',
     224  'GroebnerBasis',
     225  'Group',
     226  'GroupHomomorphismByFunction',
     227  'GroupHomomorphismByImages',
     228  'GroupRing',
     229  'HermiteNormalFormIntegerMat',
     230  'HermiteNormalFormIntegerMatTransform',
     231  'Hom',
     232  'IdGroup',
     233  'Ideal',
     234  'IdealByGenerators',
     235  'Idempotents',
     236  'Identifier',
     237  'Identity',
     238  'Image',
     239  'Images',
     240  'Index',
     241  'InfoAlgebra',
     242  'InfoAttributes',
     243  'InfoBckt',
     244  'InfoCharacterTable',
     245  'InfoCoh',
     246  'InfoComplement',
     247  'InfoCoset',
     248  'InfoFpGroup',
     249  'InfoGroebner',
     250  'InfoGroup',
     251  'InfoLattice',
     252  'InfoLevel',
     253  'InfoMatrix',
     254  'InfoMonomial',
     255  'InfoNumtheor',
     256  'InfoOptions',
     257  'InfoPcSubgroup',
     258  'InfoText',
     259  'InnerAutomorphism',
     260  'InnerAutomorphismsAutomorphismGroup',
     261  'Int',
     262  'IntFFE',
     263  'IntFFESymm',
     264  'IntHexString',
     265  'IntScalarProducts',
     266  'IntVecFFE',
     267  'Integers',
     268  'IntersectSet',
     269  'Intersection',
     270  'InvariantBilinearForm',
     271  'InvariantElementaryAbelianSeries',
     272  'InvariantLattice',
     273  'InvariantQuadraticForm',
     274  'InvariantSesquilinearForm',
     275  'Inverse',
     276  'InverseMap',
     277  'Irr',
     278  'IrrBaumClausen',
     279  'IrrConlon',
     280  'IrrDixonSchneider',
     281  'IrreducibleModules',
     282  'IrreducibleRepresentations',
     283  'IrreducibleRepresentationsDixon',
     284  'IsAbelian',
     285  'IsAbelianNumberField',
     286  'IsAbelianNumberFieldPolynomialRing',
     287  'IsAdditiveElement',
     288  'IsAdditiveElementWithInverse',
     289  'IsAdditiveElementWithZero',
     290  'IsAdditiveGroup',
     291  'IsAdditiveGroupGeneralMapping',
     292  'IsAdditiveGroupHomomorphism',
     293  'IsAdditivelyCommutative',
     294  'IsAdditivelyCommutativeElement',
     295  'IsAlgebra',
     296  'IsAlgebraGeneralMapping',
     297  'IsAlgebraHomomorphism',
     298  'IsAlgebraModule',
     299  'IsAlgebraWithOne',
     300  'IsAlgebraWithOneHomomorphism',
     301  'IsAlgebraicElement',
     302  'IsAlgebraicExtension',
     303  'IsAlternatingGroup',
     304  'IsAnticommutative',
     305  'IsAntisymmetricBinaryRelation',
     306  'IsAssocWord',
     307  'IsAssocWordWithInverse',
     308  'IsAssocWordWithOne',
     309  'IsAssociated',
     310  'IsAssociative',
     311  'IsAutomorphismGroup',
     312  'IsBasis',
     313  'IsBijective',
     314  'IsBinaryRelation',
     315  'IsBlockMatrixRep',
     316  'IsBool',
     317  'IsBound',
     318  'IsBoundGlobal',
     319  'IsBrauerTable',
     320  'IsBravaisGroup',
     321  'IsBuiltFromGroup',
     322  'IsBuiltFromSemigroup',
     323  'IsCanonicalBasis',
     324  'IsCanonicalBasisFullMatrixModule',
     325  'IsCanonicalBasisFullRowModule',
     326  'IsCanonicalNiceMonomorphism',
     327  'IsCentral',
     328  'IsCentralFactor',
     329  'IsChar',
     330  'IsCharacter',
     331  'IsCharacterTable',
     332  'IsCharacterTableInProgress',
     333  'IsCharacteristicSubgroup',
     334  'IsClosedStream',
     335  'IsCochain',
     336  'IsCochainCollection',
     337  'IsCommutative',
     338  'IsComponentObjectRep',
     339  'IsCompositionMappingRep',
     340  'IsConfluent',
     341  'IsConjugate',
     342  'IsCopyable',
     343  'IsCyc',
     344  'IsCyclic',
     345  'IsCyclotomic',
     346  'IsCyclotomicField',
     347  'IsCyclotomicMatrixGroup',
     348  'IsDenseList',
     349  'IsDiagonalMat',
     350  'IsDictionary',
     351  'IsDigitChar',
     352  'IsDivisionRing',
     353  'IsDomain',
     354  'IsDoneIterator',
     355  'IsDoubleCoset',
     356  'IsDuplicateFree',
     357  'IsDuplicateFreeList',
     358  'IsElementaryAbelian',
     359  'IsEmpty',
     360  'IsEmptyString',
     361  'IsEuclideanRing',
     362  'IsFFE',
     363  'IsField',
     364  'IsFinite',
     365  'IsFiniteDimensional',
     366  'IsFinitelyGeneratedGroup',
     367  'IsFixedStabilizer',
     368  'IsFpGroup',
     369  'IsFpMonoid',
     370  'IsFpSemigroup',
     371  'IsFreeGroup',
     372  'IsFreeLeftModule',
     373  'IsFullHomModule',
     374  'IsFullMatrixModule',
     375  'IsFullRowModule',
     376  'IsFunction',
     377  'IsGL',
     378  'IsGaussInt',
     379  'IsGaussRat',
     380  'IsGaussianIntegers',
     381  'IsGaussianRationals',
     382  'IsGaussianSpace',
     383  'IsGeneralLinearGroup',
     384  'IsGroup',
     385  'IsGroupHomomorphism',
     386  'IsGroupOfAutomorphisms',
     387  'IsGroupRing',
     388  'IsHasseDiagram',
     389  'IsHomogeneousList',
     390  'IsIdempotent',
     391  'IsInfinity',
     392  'IsInjective',
     393  'IsInnerAutomorphism',
     394  'IsInt',
     395  'IsIntegerMatrixGroup',
     396  'IsIntegers',
     397  'IsIntegralBasis',
     398  'IsIntegralCyclotomic',
     399  'IsIntegralRing',
     400  'IsIrreducible',
     401  'IsIrreducibleCharacter',
     402  'IsIrreducibleRingElement',
     403  'IsIterator',
     404  'IsJacobianRing',
     405  'IsLaurentPolynomial',
     406  'IsLaurentPolynomialDefaultRep',
     407  'IsLexicographicallyLess',
     408  'IsLieAbelian',
     409  'IsLieAlgebra',
     410  'IsLieMatrix',
     411  'IsLieObject',
     412  'IsLieObjectCollection',
     413  'IsLieSolvable',
     414  'IsLinearMapping',
     415  'IsLinearMappingsModule',
     416  'IsList',
     417  'IsMapping',
     418  'IsMatchingSublist',
     419  'IsMatrix',
     420  'IsMatrixGroup',
     421  'IsMatrixModule',
     422  'IsMatrixSpace',
     423  'IsMonomial',
     424  'IsMonomialGroup',
     425  'IsMonomialMatrix',
     426  'IsMonomialOrdering',
     427  'IsMultiplicativeZero',
     428  'IsMutable',
     429  'IsMutableBasis',
     430  'IsNilpotent',
     431  'IsNilpotentElement',
     432  'IsNilpotentGroup',
     433  'IsNormal',
     434  'IsNormalBasis',
     435  'IsNotIdenticalObj',
     436  'IsNumberField',
     437  'IsObject',
     438  'IsOddInt',
     439  'IsOne',
     440  'IsOrdering',
     441  'IsOrdinaryMatrix',
     442  'IsOrdinaryTable',
     443  'IsPGroup',
     444  'IsPSolvable',
     445  'IsPcGroup',
     446  'IsPcgs',
     447  'IsPerfect',
     448  'IsPerfectGroup',
     449  'IsPerm',
     450  'IsPermGroup',
     451  'IsPolycyclicGroup',
     452  'IsPolynomial',
     453  'IsPolynomialRing',
     454  'IsPosInt',
     455  'IsPosRat',
     456  'IsPositiveIntegers',
     457  'IsPrime',
     458  'IsPrimeField',
     459  'IsPrimeInt',
     460  'IsPrimePowerInt',
     461  'IsPrimitive',
     462  'IsPrimitiveCharacter',
     463  'IsPrimitivePolynomial',
     464  'IsProbablyPrimeInt',
     465  'IsPurePadicNumber',
     466  'IsQuaternion',
     467  'IsQuickPositionList',
     468  'IsQuotientSemigroup',
     469  'IsRandomSource',
     470  'IsRange',
     471  'IsRat',
     472  'IsRationalFunction',
     473  'IsRationalMatrixGroup',
     474  'IsRationals',
     475  'IsRecord',
     476  'IsReduced',
     477  'IsReductionOrdering',
     478  'IsReflexiveBinaryRelation',
     479  'IsRegular',
     480  'IsRegularSemigroup',
     481  'IsRegularSemigroupElement',
     482  'IsRing',
     483  'IsRingElement',
     484  'IsRingGeneralMapping',
     485  'IsRingWithOne',
     486  'IsRingWithOneGeneralMapping',
     487  'IsRingWithOneHomomorphism',
     488  'IsRowModule',
     489  'IsRowSpace',
     490  'IsRowVector',
     491  'IsSL',
     492  'IsSSortedList',
     493  'IsScalar',
     494  'IsSet',
     495  'IsSimple',
     496  'IsSimpleAlgebra',
     497  'IsSimpleGroup',
     498  'IsSimpleSemigroup',
     499  'IsSingleValued',
     500  'IsSolvable',
     501  'IsSolvableGroup',
     502  'IsSortedList',
     503  'IsSpecialLinearGroup',
     504  'IsSporadicSimple',
     505  'IsString',
     506  'IsStringRep',
     507  'IsSubgroup',
     508  'IsSubgroupFpGroup',
     509  'IsSubgroupOfWholeGroupByQuotientRep',
     510  'IsSubgroupSL',
     511  'IsSubset',
     512  'IsSubsetSet',
     513  'IsSubspace',
     514  'IsSupersolvable',
     515  'IsSupersolvableGroup',
     516  'IsSurjective',
     517  'IsSymmetricGroup',
     518  'IsTable',
     519  'IsTotal',
     520  'IsTotalOrdering',
     521  'IsTransformation',
     522  'IsTransitive',
     523  'IsTransitiveBinaryRelation',
     524  'IsTrivial',
     525  'IsTuple',
     526  'IsUniqueFactorizationRing',
     527  'IsUnit',
     528  'IsUnivariatePolynomial',
     529  'IsUnivariatePolynomialRing',
     530  'IsUnivariateRationalFunction',
     531  'IsUpperAlphaChar',
     532  'IsUpperTriangularMat',
     533  'IsValidIdentifier',
     534  'IsVector',
     535  'IsVectorSpace',
     536  'IsVirtualCharacter',
     537  'IsWeylGroup',
     538  'IsWord',
     539  'IsZero',
     540  'IsZeroGroup',
     541  'IsZeroSimpleSemigroup',
     542  'IsZeroSquaredRing',
     543  'IsZmodnZObj',
     544  'IsZmodnZObjNonprime',
     545  'IsZmodpZObj',
     546  'IsZmodpZObjLarge',
     547  'IsZmodpZObjSmall',
     548  'IsomorphicSubgroups',
     549  'IsomorphismFpAlgebra',
     550  'IsomorphismFpGroup',
     551  'IsomorphismFpGroupByGenerators',
     552  'IsomorphismFpGroupByPcgs',
     553  'IsomorphismFpSemigroup',
     554  'IsomorphismGroups',
     555  'IsomorphismMatrixAlgebra',
     556  'IsomorphismPcGroup',
     557  'IsomorphismPermGroup',
     558  'IsomorphismPermGroupImfGroup',
     559  'IsomorphismReesMatrixSemigroup',
     560  'IsomorphismRefinedPcGroup',
     561  'IsomorphismSimplifiedFpGroup',
     562  'IsomorphismSpecialPcGroup',
     563  'IsomorphismTransformationSemigroup',
     564  'IsomorphismTypeInfoFiniteSimpleGroup',
     565  'Iterated',
     566  'Iterator',
     567  'IteratorByBasis',
     568  'IteratorByFunctions',
     569  'IteratorList',
     570  'IteratorSorted',
     571  'Jacobi',
     572  'JenningsLieAlgebra',
     573  'JenningsSeries',
     574  'JordanDecomposition',
     575  'Kernel',
     576  'KernelOfAdditiveGeneralMapping',
     577  'KernelOfCharacter',
     578  'KernelOfMultiplicativeGeneralMapping',
     579  'KernelOfTransformation',
     580  'KillingMatrix',
     581  'KnuthBendixRewritingSystem',
     582  'KroneckerProduct',
     583  'KuKGenerators',
     584  'LLL',
     585  'LLLReducedBasis',
     586  'LLLReducedGramMat',
     587  'Lambda',
     588  'LargestElementGroup',
     589  'LargestElementStabChain',
     590  'LargestMovedPoint',
     591  'LastSystemError',
     592  'LatticeByCyclicExtension',
     593  'LatticeSubgroups',
     594  'Lcm',
     595  'LcmInt',
     596  'LcmOp',
     597  'LeadingCoefficient',
     598  'LeadingCoefficientOfPolynomial',
     599  'LeadingExponentOfPcElement',
     600  'LeadingMonomial',
     601  'LeadingMonomialOfPolynomial',
     602  'LeadingTermOfPolynomial',
     603  'Legendre',
     604  'Length',
     605  'LenstraBase',
     606  'LessThanFunction',
     607  'LessThanOrEqualFunction',
     608  'LetterRepAssocWord',
     609  'LevelsOfGenerators',
     610  'LeviMalcevDecomposition',
     611  'LexicographicOrdering',
     612  'LieAlgebra',
     613  'LieAlgebraByStructureConstants',
     614  'LieBracket',
     615  'LieCenter',
     616  'LieCentralizer',
     617  'LieCentre',
     618  'LieCoboundaryOperator',
     619  'LieDerivedSeries',
     620  'LieDerivedSubalgebra',
     621  'LieLowerCentralSeries',
     622  'LieNilRadical',
     623  'LieNormalizer',
     624  'LieObject',
     625  'LieSolvableRadical',
     626  'LieUpperCentralSeries',
     627  'LiftedInducedPcgs',
     628  'LiftedPcElement',
     629  'LinearAction',
     630  'LinearActionLayer',
     631  'LinearCharacters',
     632  'LinearCombination',
     633  'LinearCombinationPcgs',
     634  'LinearIndependentColumns',
     635  'LinearOperation',
     636  'LinearOperationLayer',
     637  'LinesOfStraightLineProgram',
     638  'List',
     639  'ListN',
     640  'ListPerm',
     641  'ListStabChain',
     642  'ListWithIdenticalEntries',
     643  'ListX',
     644  'LoadDynamicModule',
     645  'LoadPackage',
     646  'Log',
     647  'LogFFE',
     648  'LogInt',
     649  'LogMod',
     650  'LogModShanks',
     651  'LogTo',
     652  'LongestWeylWordPerm',
     653  'LookupDictionary',
     654  'LowIndexSubgroupsFpGroup',
     655  'LowIndexSubgroupsFpGroupIterator',
     656  'LowerCentralSeries',
     657  'LowerCentralSeriesOfGroup',
     658  'LowercaseString',
     659  'Lucas',
     660  'MakeConfluent',
     661  'MakeImmutable',
     662  'MakeReadOnlyGlobal',
     663  'MakeReadWriteGlobal',
     664  'MappedWord',
     665  'MappingByFunction',
     666  'MappingPermListList',
     667  'MatAlgebra',
     668  'MatClassMultCoeffsCharTable',
     669  'MatLieAlgebra',
     670  'MatScalarProducts',
     671  'MathieuGroup',
     672  'MatrixAlgebra',
     673  'MatrixAutomorphisms',
     674  'MatrixByBlockMatrix',
     675  'MatrixLieAlgebra',
     676  'MatrixOfAction',
     677  'MaximalAbelianQuotient',
     678  'MaximalBlocks',
     679  'MaximalNormalSubgroups',
     680  'MaximalSubgroupClassReps',
     681  'MaximalSubgroups',
     682  'MaximalSubgroupsLattice',
     683  'Maximum',
     684  'MaximumList',
     685  'MeetEquivalenceRelations',
     686  'MeetMaps',
     687  'MinimalElementCosetStabChain',
     688  'MinimalGeneratingSet',
     689  'MinimalNonmonomialGroup',
     690  'MinimalNormalSubgroups',
     691  'MinimalPolynomial',
     692  'MinimalStabChain',
     693  'MinimalSupergroupsLattice',
     694  'MinimizedBombieriNorm',
     695  'Minimum',
     696  'MinimumList',
     697  'MinusCharacter',
     698  'ModuleByRestriction',
     699  'ModuleOfExtension',
     700  'ModuloPcgs',
     701  'MoebiusMu',
     702  'MolienSeries',
     703  'MolienSeriesInfo',
     704  'MolienSeriesWithGivenDenominator',
     705  'Monoid',
     706  'MonoidByGenerators',
     707  'MonoidByMultiplicationTable',
     708  'MonoidOfRewritingSystem',
     709  'MonomialComparisonFunction',
     710  'MonomialExtGrlexLess',
     711  'MonomialExtrepComparisonFun',
     712  'MonomialGrevlexOrdering',
     713  'MonomialGrlexOrdering',
     714  'MonomialLexOrdering',
     715  'MonomialTotalDegreeLess',
     716  'MostFrequentGeneratorFpGroup',
     717  'MovedPoints',
     718  'MultRowVector',
     719  'MultiplicationTable',
     720  'MultiplicativeNeutralElement',
     721  'MultiplicativeZero',
     722  'MultiplicativeZeroOp',
     723  'NF',
     724  'NK',
     725  'NameFunction',
     726  'NaturalCharacter',
     727  'NaturalHomomorphismByGenerators',
     728  'NaturalHomomorphismByIdeal',
     729  'NaturalHomomorphismByNormalSubgroup',
     730  'NaturalHomomorphismBySubAlgebraModule',
     731  'NaturalHomomorphismBySubspace',
     732  'NearAdditiveGroup',
     733  'NearAdditiveGroupByGenerators',
     734  'NegativeRootVectors',
     735  'NegativeRoots',
     736  'NextIterator',
     737  'NextPrimeInt',
     738  'NiceBasis',
     739  'NiceBasisFiltersInfo',
     740  'NiceFreeLeftModule',
     741  'NiceFreeLeftModuleInfo',
     742  'NiceMonomorphism',
     743  'NiceMonomorphismAutomGroup',
     744  'NiceObject',
     745  'NiceVector',
     746  'NilpotencyClassOfGroup',
     747  'NonabelianExteriorSquare',
     748  'Norm',
     749  'NormalBase',
     750  'NormalClosure',
     751  'NormalFormIntMat',
     752  'NormalIntersection',
     753  'NormalSeriesByPcgs',
     754  'NormalSubgroups',
     755  'NormalizeWhitespace',
     756  'NormalizedWhitespace',
     757  'Normalizer',
     758  'NormalizerInGLnZ',
     759  'NormalizerInGLnZBravaisGroup',
     760  'NormedRowVector',
     761  'NrArrangements',
     762  'NrBasisVectors',
     763  'NrCombinations',
     764  'NrConjugacyClasses',
     765  'NrConjugacyClassesGL',
     766  'NrConjugacyClassesGU',
     767  'NrConjugacyClassesPGL',
     768  'NrConjugacyClassesPGU',
     769  'NrConjugacyClassesPSL',
     770  'NrConjugacyClassesPSU',
     771  'NrConjugacyClassesSL',
     772  'NrConjugacyClassesSLIsogeneous',
     773  'NrConjugacyClassesSU',
     774  'NrConjugacyClassesSUIsogeneous',
     775  'NrDerangements',
     776  'NrInputsOfStraightLineProgram',
     777  'NrMovedPoints',
     778  'NrOrderedPartitions',
     779  'NrPartitionTuples',
     780  'NrPartitions',
     781  'NrPartitionsSet',
     782  'NrPermutationsList',
     783  'NrPolyhedralSubgroups',
     784  'NrRestrictedPartitions',
     785  'NrTuples',
     786  'NrUnorderedTuples',
     787  'NullAlgebra',
     788  'NullMat',
     789  'NullspaceIntMat',
     790  'NullspaceMat',
     791  'NullspaceMatDestructive',
     792  'NullspaceModQ',
     793  'Number',
     794  'NumberArgumentsFunction',
     795  'NumberFFVector',
     796  'NumberPerfectGroups',
     797  'NumberPerfectLibraryGroups',
     798  'NumberSmallGroups',
     799  'NumberSyllables',
     800  'NumeratorOfModuloPcgs',
     801  'NumeratorOfRationalFunction',
     802  'NumeratorRat',
     803  'Objectify',
     804  'ObjectifyWithAttributes',
     805  'OctaveAlgebra',
     806  'OldGeneratorsOfPresentation',
     807  'Omega',
     808  'OnBreak',
     809  'OnBreakMessage',
     810  'OnIndeterminates',
     811  'OnLeftInverse',
     812  'OnLines',
     813  'OnPairs',
     814  'OnPoints',
     815  'OnRight',
     816  'OnSets',
     817  'OnSetsDisjointSets',
     818  'OnSetsSets',
     819  'OnSetsTuples',
     820  'OnSubspacesByCanonicalBasis',
     821  'OnTuples',
     822  'OnTuplesSets',
     823  'OnTuplesTuples',
     824  'One',
     825  'OneAttr',
     826  'OneCoboundaries',
     827  'OneCocycles',
     828  'OneFactorBound',
     829  'OneImmutable',
     830  'OneMutable',
     831  'OneOfPcgs',
     832  'OneOp',
     833  'OneSM',
     834  'OneSameMutability',
     835  'OperationAlgebraHomomorphism',
     836  'Orbit',
     837  'OrbitFusions',
     838  'OrbitLength',
     839  'OrbitLengths',
     840  'OrbitLengthsDomain',
     841  'OrbitPerms',
     842  'OrbitPowerMaps',
     843  'OrbitStabChain',
     844  'OrbitStabilizer',
     845  'OrbitStabilizerAlgorithm',
     846  'Orbits',
     847  'OrbitsDomain',
     848  'OrbitsPerms',
     849  'Order',
     850  'OrderMod',
     851  'OrderingOnGenerators',
     852  'Ordinal',
     853  'OrdinaryCharacterTable',
     854  'OrthogonalComponents',
     855  'OrthogonalEmbeddings',
     856  'OrthogonalEmbeddingsSpecialDimension',
     857  'PCentralLieAlgebra',
     858  'PCentralNormalSeriesByPcgsPGroup',
     859  'PCentralSeries',
     860  'PClassPGroup',
     861  'PCore',
     862  'PGL',
     863  'PGU',
     864  'POW',
     865  'PQuotient',
     866  'PROD',
     867  'PSL',
     868  'PSP',
     869  'PSU',
     870  'PSp',
     871  'PadicCoefficients',
     872  'PadicNumber',
     873  'PadicValuation',
     874  'Parametrized',
     875  'Parent',
     876  'ParentPcgs',
     877  'PartialFactorization',
     878  'PartialOrderByOrderingFunction',
     879  'PartialOrderOfHasseDiagram',
     880  'Partition',
     881  'PartitionTuples',
     882  'Partitions',
     883  'PartitionsGreatestEQ',
     884  'PartitionsGreatestLE',
     885  'PartitionsSet',
     886  'PcGroupCode',
     887  'PcGroupCodeRec',
     888  'PcGroupFpGroup',
     889  'PcGroupWithPcgs',
     890  'PcSeries',
     891  'Pcgs',
     892  'PcgsCentralSeries',
     893  'PcgsChiefSeries',
     894  'PcgsElementaryAbelianSeries',
     895  'PcgsPCentralSeriesPGroup',
     896  'Pcgs_OrbitStabilizer',
     897  'PerfectGroup',
     898  'PerfectIdentification',
     899  'PerfectResiduum',
     900  'Perform',
     901  'PermBounds',
     902  'PermCharInfo',
     903  'PermCharInfoRelative',
     904  'PermChars',
     905  'PermComb',
     906  'PermLeftQuoTransformation',
     907  'PermList',
     908  'PermListList',
     909  'Permanent',
     910  'Permutation',
     911  'PermutationCharacter',
     912  'PermutationCycle',
     913  'PermutationCycleOp',
     914  'PermutationGModule',
     915  'PermutationMat',
     916  'PermutationsList',
     917  'Permuted',
     918  'Phi',
     919  'PolynomialByExtRep',
     920  'PolynomialCoefficientsOfPolynomial',
     921  'PolynomialDivisionAlgorithm',
     922  'PolynomialModP',
     923  'PolynomialReducedRemainder',
     924  'PolynomialReduction',
     925  'PolynomialRing',
     926  'PopOptions',
     927  'Position',
     928  'PositionBound',
     929  'PositionCanonical',
     930  'PositionFirstComponent',
     931  'PositionNonZero',
     932  'PositionNot',
     933  'PositionNthOccurrence',
     934  'PositionProperty',
     935  'PositionSet',
     936  'PositionSorted',
     937  'PositionStream',
     938  'PositionSublist',
     939  'PositionWord',
     940  'PositionsOp',
     941  'PositiveRoots',
     942  'PossibleClassFusions',
     943  'PossiblePowerMaps',
     944  'PowerMap',
     945  'PowerMapOp',
     946  'PowerModCoeffs',
     947  'PowerModInt',
     948  'PowerPartition',
     949  'PreImage',
     950  'PreImageElm',
     951  'PreImages',
     952  'PreImagesElm',
     953  'PreImagesRange',
     954  'PreImagesRepresentative',
     955  'PreImagesSet',
     956  'PrefrattiniSubgroup',
     957  'PreimagesOfTransformation',
     958  'PresentationFpGroup',
     959  'PresentationNormalClosure',
     960  'PresentationNormalClosureRrs',
     961  'PresentationSubgroup',
     962  'PresentationSubgroupMtc',
     963  'PresentationSubgroupRrs',
     964  'PresentationViaCosetTable',
     965  'PrevPrimeInt',
     966  'PrimaryGeneratorWords',
     967  'PrimeBlocks',
     968  'PrimeBlocksOp',
     969  'PrimeField',
     970  'PrimePGroup',
     971  'PrimePowersInt',
     972  'PrimeResidues',
     973  'Primes',
     974  'PrimitiveElement',
     975  'PrimitiveGroup',
     976  'PrimitiveIdentification',
     977  'PrimitivePolynomial',
     978  'PrimitiveRoot',
     979  'PrimitiveRootMod',
     980  'Print',
     981  'PrintAmbiguity',
     982  'PrintArray',
     983  'PrintCharacterTable',
     984  'PrintFactorsInt',
     985  'PrintFormattingStatus',
     986  'PrintHashWithNames',
     987  'PrintObj',
     988  'PrintTo',
     989  'Process',
     990  'Product',
     991  'ProductCoeffs',
     992  'ProductSpace',
     993  'ProductX',
     994  'ProjectedInducedPcgs',
     995  'ProjectedPcElement',
     996  'Projection',
     997  'ProjectionMap',
     998  'ProjectiveActionHomomorphismMatrixGroup',
     999  'ProjectiveActionOnFullSpace',
     1000  'ProjectiveGeneralLinearGroup',
     1001  'ProjectiveGeneralUnitaryGroup',
     1002  'ProjectiveOrder',
     1003  'ProjectiveSpecialLinearGroup',
     1004  'ProjectiveSpecialUnitaryGroup',
     1005  'ProjectiveSymplecticGroup',
     1006  'PseudoRandom',
     1007  'PthPowerImage',
     1008  'PthPowerImages',
     1009  'PushOptions',
     1010  'QUO',
     1011  'Quadratic',
     1012  'QuaternionAlgebra',
     1013  'QuoInt',
     1014  'QuotRemLaurpols',
     1015  'Quotient',
     1016  'QuotientMod',
     1017  'QuotientPolynomialsExtRep',
     1018  'QuotientRemainder',
     1019  'READ',
     1020  'RadicalGroup',
     1021  'RadicalOfAlgebra',
     1022  'Random',
     1023  'RandomBinaryRelationOnPoints',
     1024  'RandomHashKey',
     1025  'RandomInvertibleMat',
     1026  'RandomIsomorphismTest',
     1027  'RandomList',
     1028  'RandomMat',
     1029  'RandomPrimitivePolynomial',
     1030  'RandomSource',
     1031  'RandomTransformation',
     1032  'RandomUnimodularMat',
     1033  'Range',
     1034  'Rank',
     1035  'RankAction',
     1036  'RankFilter',
     1037  'RankMat',
     1038  'RankOfTransformation',
     1039  'RankPGroup',
     1040  'Rat',
     1041  'RationalClass',
     1042  'RationalClasses',
     1043  'RationalizedMat',
     1044  'Rationals',
     1045  'Read',
     1046  'ReadAll',
     1047  'ReadAllLine',
     1048  'ReadAsFunction',
     1049  'ReadByte',
     1050  'ReadLine',
     1051  'ReadPackage',
     1052  'ReadPkg',
     1053  'ReadTest',
     1054  'RealClasses',
     1055  'RealPart',
     1056  'RealizableBrauerCharacters',
     1057  'RecFields',
     1058  'RecNames',
     1059  'RedispatchOnCondition',
     1060  'ReduceCoeffs',
     1061  'ReduceCoeffsMod',
     1062  'ReduceRules',
     1063  'ReduceStabChain',
     1064  'Reduced',
     1065  'ReducedAdditiveInverse',
     1066  'ReducedCharacters',
     1067  'ReducedClassFunctions',
     1068  'ReducedComm',
     1069  'ReducedConfluentRewritingSystem',
     1070  'ReducedConjugate',
     1071  'ReducedDifference',
     1072  'ReducedForm',
     1073  'ReducedGroebnerBasis',
     1074  'ReducedInverse',
     1075  'ReducedLeftQuotient',
     1076  'ReducedOne',
     1077  'ReducedPcElement',
     1078  'ReducedPower',
     1079  'ReducedProduct',
     1080  'ReducedQuotient',
     1081  'ReducedScalarProduct',
     1082  'ReducedSum',
     1083  'ReducedZero',
     1084  'Ree',
     1085  'ReeGroup',
     1086  'ReesCongruenceOfSemigroupIdeal',
     1087  'ReesMatrixSemigroup',
     1088  'ReesMatrixSemigroupElement',
     1089  'ReesZeroMatrixSemigroup',
     1090  'ReesZeroMatrixSemigroupElement',
     1091  'ReesZeroMatrixSemigroupElementIsZero',
     1092  'RefinedPcGroup',
     1093  'RegularActionHomomorphism',
     1094  'RegularModule',
     1095  'RelationsOfFpSemigroup',
     1096  'RelativeBasis',
     1097  'RelativeOrders',
     1098  'RelatorsOfFpGroup',
     1099  'RemInt',
     1100  'Remove',
     1101  'RemoveCharacters',
     1102  'RemoveFile',
     1103  'RemoveOuterCoeffs',
     1104  'RemoveRelator',
     1105  'RemoveSet',
     1106  'RemoveStabChain',
     1107  'ReplacedString',
     1108  'Representative',
     1109  'RepresentativeAction',
     1110  'RepresentativeLinearOperation',
     1111  'RepresentativeSmallest',
     1112  'RepresentativesContainedRightCosets',
     1113  'RepresentativesFusions',
     1114  'RepresentativesMinimalBlocks',
     1115  'RepresentativesPerfectSubgroups',
     1116  'RepresentativesPowerMaps',
     1117  'RepresentativesSimpleSubgroups',
     1118  'Reread',
     1119  'RereadPackage',
     1120  'Reset',
     1121  'RestoreStateRandom',
     1122  'RestrictOutputsOfSLP',
     1123  'Restricted',
     1124  'RestrictedClassFunction',
     1125  'RestrictedClassFunctions',
     1126  'RestrictedMapping',
     1127  'RestrictedPartitions',
     1128  'RestrictedPerm',
     1129  'RestrictedTransformation',
     1130  'ResultOfStraightLineProgram',
     1131  'Resultant',
     1132  'Reversed',
     1133  'RewriteWord',
     1134  'RightCoset',
     1135  'RightCosets',
     1136  'RightDerivations',
     1137  'Ring',
     1138  'RingWithOne',
     1139  'Root',
     1140  'RootInt',
     1141  'RootMod',
     1142  'RootOfDefiningPolynomial',
     1143  'RootSystem',
     1144  'RootsMod',
     1145  'RoundCyc',
     1146  'Rules',
     1147  'SL',
     1148  'SO',
     1149  'SP',
     1150  'SQ',
     1151  'SSortedList',
     1152  'SU',
     1153  'SameBlock',
     1154  'SandwichMatrixOfReesMatrixSemigroup',
     1155  'SandwichMatrixOfReesZeroMatrixSemigroup',
     1156  'SaveWorkspace',
     1157  'ScalarProduct',
     1158  'SchurCover',
     1159  'SemiSimpleType',
     1160  'SemidirectProduct',
     1161  'Semigroup',
     1162  'Set',
     1163  'SetAssertionLevel',
     1164  'SetCommutator',
     1165  'SetConjugate',
     1166  'SetCrystGroupDefaultAction',
     1167  'SetEntrySCTable',
     1168  'SetFilterObj',
     1169  'SetHashEntry',
     1170  'SetHashEntryAtLastIndex',
     1171  'SetHelpViewer',
     1172  'SetIndeterminateName',
     1173  'SetInfoLevel',
     1174  'SetName',
     1175  'SetParent',
     1176  'SetPower',
     1177  'ShallowCopy',
     1178  'ShiftedCoeffs',
     1179  'ShiftedPadicNumber',
     1180  'ShortLexOrdering',
     1181  'ShortestVectors',
     1182  'Sigma',
     1183  'SignInt',
     1184  'SignPartition',
     1185  'SignPerm',
     1186  'SimpleLieAlgebra',
     1187  'SimpleSystem',
     1188  'SimplifiedFpGroup',
     1189  'SimplifyPresentation',
     1190  'SimultaneousEigenvalues',
     1191  'SingleCollector',
     1192  'Size',
     1193  'SizeConsiderFunction',
     1194  'SizeNumbersPerfectGroups',
     1195  'SizeOfFieldOfDefinition',
     1196  'SizeScreen',
     1197  'SizeStabChain',
     1198  'SizesCentralizers',
     1199  'SizesConjugacyClasses',
     1200  'SizesPerfectGroups',
     1201  'SmallGeneratingSet',
     1202  'SmallGroup',
     1203  'SmallerDegreePermutationRepresentation',
     1204  'SmallestGeneratorPerm',
     1205  'SmallestMovedPoint',
     1206  'SmallestRootInt',
     1207  'SmithNormalFormIntegerMat',
     1208  'Socle',
     1209  'SocleTypePrimitiveGroup',
     1210  'SolutionIntMat',
     1211  'SolutionMat',
     1212  'SolutionMatDestructive',
     1213  'SolutionNullspaceIntMat',
     1214  'Sort',
     1215  'SortParallel',
     1216  'SortedCharacterTable',
     1217  'SortedCharacters',
     1218  'SortedList',
     1219  'SortedSparseActionHomomorphism',
     1220  'SortingPerm',
     1221  'Sp',
     1222  'SparseActionHomomorphism',
     1223  'SparseCartanMatrix',
     1224  'SparseHashTable',
     1225  'SparseIntKey',
     1226  'SpecialLinearGroup',
     1227  'SpecialOrthogonalGroup',
     1228  'SpecialPcgs',
     1229  'SpecialUnitaryGroup',
     1230  'SplitCharacters',
     1231  'SplitExtension',
     1232  'SplitString',
     1233  'SplittingField',
     1234  'Sqrt',
     1235  'SquareRoots',
     1236  'StabChain',
     1237  'StabChainBaseStrongGenerators',
     1238  'StabChainImmutable',
     1239  'StabChainMutable',
     1240  'StabChainOp',
     1241  'StabChainOptions',
     1242  'Stabilizer',
     1243  'StabilizerOfExternalSet',
     1244  'StabilizerPcgs',
     1245  'StandardAssociate',
     1246  'StandardGeneratorsInfo',
     1247  'StandardizeTable',
     1248  'StarCyc',
     1249  'Stirling1',
     1250  'Stirling2',
     1251  'StratMeetPartition',
     1252  'StretchImportantSLPElement',
     1253  'String',
     1254  'StringDate',
     1255  'StringOfResultOfStraightLineProgram',
     1256  'StringPP',
     1257  'StringTime',
     1258  'StructuralCopy',
     1259  'StructureConstantsTable',
     1260  'StructureDescription',
     1261  'SubAlgebraModule',
     1262  'Subalgebra',
     1263  'SubdirectProduct',
     1264  'SubdirectProducts',
     1265  'Subfield',
     1266  'Subfields',
     1267  'Subgroup',
     1268  'SubgroupByPcgs',
     1269  'SubgroupByProperty',
     1270  'SubgroupOfWholeGroupByCosetTable',
     1271  'SubgroupOfWholeGroupByQuotientSubgroup',
     1272  'SubgroupProperty',
     1273  'SubgroupShell',
     1274  'SubgroupsSolvableGroup',
     1275  'Submodule',
     1276  'Submonoid',
     1277  'SubnearAdditiveGroup',
     1278  'SubnormalSeries',
     1279  'Subring',
     1280  'SubringWithOne',
     1281  'Subsemigroup',
     1282  'Subspace',
     1283  'Subspaces',
     1284  'SubstitutedWord',
     1285  'SubtractSet',
     1286  'Subword',
     1287  'Successors',
     1288  'Sum',
     1289  'SumFactorizationFunctionPcgs',
     1290  'SumIntersectionMat',
     1291  'SumX',
     1292  'SupersolvableResiduum',
     1293  'SupportedCharacterTableInfo',
     1294  'SurjectiveActionHomomorphismAttr',
     1295  'SuzukiGroup',
     1296  'SylowComplement',
     1297  'SylowSubgroup',
     1298  'SylowSystem',
     1299  'SymmetricClosureBinaryRelation',
     1300  'SymmetricGroup',
     1301  'SymmetricParentGroup',
     1302  'SymmetricParts',
     1303  'SymmetricPower',
     1304  'SymmetricPowerOfAlgebraModule',
     1305  'Symmetrizations',
     1306  'SymplecticComponents',
     1307  'SymplecticGroup',
     1308  'TableAutomorphisms',
     1309  'TableOfMarks',
     1310  'TableOfMarksByLattice',
     1311  'TableOfMarksComponents',
     1312  'TableOfMarksCyclic',
     1313  'TableOfMarksDihedral',
     1314  'TableOfMarksFrobenius',
     1315  'Tau',
     1316  'TensorProduct',
     1317  'TensorProductGModule',
     1318  'TensorProductOfAlgebraModules',
     1319  'Tensored',
     1320  'TietzeWordAbstractWord',
     1321  'Trace',
     1322  'TraceImmediateMethods',
     1323  'TraceMat',
     1324  'TraceMethods',
     1325  'TracePolynomial',
     1326  'TracedCosetFpGroup',
     1327  'TransferDiagram',
     1328  'Transformation',
     1329  'TransformationData',
     1330  'TransformationRelation',
     1331  'TransformationType',
     1332  'TransformingPermutations',
     1333  'TransformingPermutationsCharacterTables',
     1334  'TransitiveClosureBinaryRelation',
     1335  'TransitiveIdentification',
     1336  'Transitivity',
     1337  'TranslatorSubalgebra',
     1338  'TransposedMat',
     1339  'TransposedMatAttr',
     1340  'TransposedMatDestructive',
     1341  'TransposedMatImmutable',
     1342  'TransposedMatMutable',
     1343  'TransposedMatOp',
     1344  'TransposedMatrixGroup',
     1345  'TriangulizeIntegerMat',
     1346  'TriangulizeMat',
     1347  'TriangulizedIntegerMat',
     1348  'TriangulizedIntegerMatTransform',
     1349  'TriangulizedNullspaceMat',
     1350  'TriangulizedNullspaceMatDestructive',
     1351  'TrivialCharacter',
     1352  'TrivialGroup',
     1353  'TrivialIterator',
     1354  'TrivialSubalgebra',
     1355  'TrivialSubgroup',
     1356  'TrivialSubmagmaWithOne',
     1357  'TrivialSubmodule',
     1358  'TrivialSubmonoid',
     1359  'TrivialSubspace',
     1360  'Tuple',
     1361  'Tuples',
     1362  'Unbind',
     1363  'UnbindElmWPObj',
     1364  'UnbindGlobal',
     1365  'UnderlyingCharacterTable',
     1366  'UnderlyingCharacteristic',
     1367  'UnderlyingElement',
     1368  'UnderlyingElementOfReesMatrixSemigroupElement',
     1369  'UnderlyingElementOfReesZeroMatrixSemigroupElement',
     1370  'UnderlyingExternalSet',
     1371  'UnderlyingGeneralMapping',
     1372  'UnderlyingGroup',
     1373  'UnderlyingLeftModule',
     1374  'UnderlyingLieAlgebra',
     1375  'UnderlyingRelation',
     1376  'Union',
     1377  'Union2',
     1378  'Unique',
     1379  'UniteSet',
     1380  'Units',
     1381  'UnivariatePolynomial',
     1382  'UnivariatePolynomialByCoefficients',
     1383  'UnivariatePolynomialRing',
     1384  'UnivariateRationalFunctionByCoefficients',
     1385  'UnivariatenessTestRationalFunction',
     1386  'UniversalEnvelopingAlgebra',
     1387  'Unknown',
     1388  'UnorderedTuples',
     1389  'UnprofileFunctions',
     1390  'UnprofileMethods',
     1391  'UntraceMethods',
     1392  'UpdateMap',
     1393  'UpperCentralSeries',
     1394  'UpperCentralSeriesOfGroup',
     1395  'UpperSubdiagonal',
     1396  'UseBasis',
     1397  'UseFactorRelation',
     1398  'UseIsomorphismRelation',
     1399  'UseSubsetRelation',
     1400  'Valuation',
     1401  'Value',
     1402  'ValueCochain',
     1403  'ValueGlobal',
     1404  'ValueMolienSeries',
     1405  'ValueOption',
     1406  'ValuePol',
     1407  'ValuesOfClassFunction',
     1408  'VectorSpace',
     1409  'VectorSpaceByPcgsOfElementaryAbelianGroup',
     1410  'View',
     1411  'VirtualCharacter',
     1412  'WeakPointerObj',
     1413  'WedgeGModule',
     1414  'WeekDay',
     1415  'WeightLexOrdering',
     1416  'WeightOfGenerators',
     1417  'WeightVecFFE',
     1418  'WeylGroup',
     1419  'WeylOrbitIterator',
     1420  'Where',
     1421  'WreathProduct',
     1422  'WreathProductImprimitiveAction',
     1423  'WreathProductOrdering',
     1424  'WreathProductProductAction',
     1425  'WriteAll',
     1426  'WriteByte',
     1427  'WriteLine',
     1428  'ZClassRepsQClass',
     1429  'Zero',
     1430  'ZeroAttr',
     1431  'ZeroCoefficient',
     1432  'ZeroCoefficientRatFun',
     1433  'ZeroMapping',
     1434  'ZeroMutable',
     1435  'ZeroOp',
     1436  'ZeroSM',
     1437  'ZeroSameMutability',
     1438 ]
  • new file sage/libs/gap/gap_includes.pxd

    diff --git a/sage/libs/gap/gap_includes.pxd b/sage/libs/gap/gap_includes.pxd
    new file mode 100644
    - +  
     1###############################################################################
     2#       Copyright (C) 2009, William Stein <wstein@gmail.com>
     3#       Copyright (C) 2012, Volker Braun <vbraun.name@gmail.com>
     4#
     5#   Distributed under the terms of the GNU General Public License (GPL)
     6#   as published by the Free Software Foundation; either version 2 of
     7#   the License, or (at your option) any later version.
     8#                   http://www.gnu.org/licenses/
     9###############################################################################
     10
     11
     12include "../../ext/stdsage.pxi"
     13include "../../ext/interrupt.pxi"  # ctrl-c interrupt block support
     14
     15cdef extern from "gap/libgap.h":
     16    void libgap_initialize(int argc, char** argv)
     17    ctypedef void(*libgap_gasman_callback_ptr)()
     18    void libgap_set_gasman_callback(libgap_gasman_callback_ptr callback)
     19    ctypedef void(*libgap_error_func_ptr)(char* msg)
     20    void libgap_set_error_handler(libgap_error_func_ptr error_handler)
     21    void libgap_call_error_handler()
     22    void libgap_finalize()
     23    void libgap_start_interaction(char* inputline)
     24    char* libgap_get_output()
     25    char* libgap_get_error()
     26    void libgap_finish_interaction()
     27    void libgap_mark_stack_bottom()
     28    void libgap_enter()
     29    void libgap_exit()
     30
     31cdef extern from "gap/system.h":
     32    ctypedef char libGAP_Char
     33    ctypedef unsigned char libGAP_UChar
     34
     35cdef extern from "gap/code.h":
     36    ctypedef unsigned int libGAP_Stat
     37    ctypedef libGAP_Stat* libGAP_PtrBody
     38
     39cdef extern from "gap/gap.h":
     40    ctypedef unsigned int libGAP_UInt
     41    ctypedef void* libGAP_ExecStatus
     42    void libGAP_ViewObjHandler(void*)
     43    void libGAP_InitializeGap(int*, char** argv)
     44    void libGAP_set_system_variables(char**, char**)
     45    cdef libGAP_UInt libGAP_Last
     46    cdef libGAP_UInt libGAP_Last2
     47    cdef libGAP_UInt libGAP_Last3
     48    cdef libGAP_ExecStatus libGAP_STATUS_END
     49    cdef libGAP_ExecStatus libGAP_STATUS_RETURN_VAL
     50    cdef libGAP_ExecStatus libGAP_STATUS_RETURN_VOID
     51    cdef libGAP_ExecStatus libGAP_STATUS_TNM
     52    cdef libGAP_ExecStatus libGAP_STATUS_QUIT
     53    cdef libGAP_ExecStatus libGAP_STATUS_EOF
     54    cdef libGAP_ExecStatus libGAP_STATUS_ERROR
     55    cdef libGAP_ExecStatus libGAP_STATUS_QQUIT
     56   
     57cdef extern from "gap/objects.h":
     58    ctypedef void* libGAP_Obj
     59    libGAP_Obj libGAP_SHALLOW_COPY_OBJ(libGAP_Obj obj)
     60    bint libGAP_IS_INTOBJ(libGAP_Obj obj)
     61    libGAP_Obj libGAP_INTOBJ_INT(int)
     62    int libGAP_INT_INTOBJ(libGAP_Obj)
     63    libGAP_UInt libGAP_TNUM_OBJ(libGAP_Obj obj)
     64    char* libGAP_TNAM_OBJ(libGAP_Obj obj)
     65    cdef int libGAP_FIRST_REAL_TNUM
     66    cdef int libGAP_FIRST_CONSTANT_TNUM
     67    cdef int libGAP_T_INT
     68    cdef int libGAP_T_INTPOS
     69    cdef int libGAP_T_INTNEG
     70    cdef int libGAP_T_RAT
     71    cdef int libGAP_T_CYC
     72    cdef int libGAP_T_FFE
     73    cdef int libGAP_T_PERM2
     74    cdef int libGAP_T_PERM4
     75    cdef int libGAP_T_BOOL
     76    cdef int libGAP_T_CHAR
     77    cdef int libGAP_T_FUNCTION
     78    cdef int libGAP_T_FLAGS
     79    cdef int libGAP_T_FLOAT
     80    cdef int libGAP_T_RESERVED_BY_GAP
     81    cdef int libGAP_LAST_CONSTANT_TNUM
     82    cdef int libGAP_IMMUTABLE
     83    cdef int libGAP_FIRST_IMM_MUT_TNUM
     84    cdef int libGAP_FIRST_RECORD_TNUM
     85    cdef int libGAP_T_PREC
     86    cdef int libGAP_LAST_RECORD_TNUM
     87    cdef int libGAP_FIRST_LIST_TNUM
     88    cdef int libGAP_FIRST_PLIST_TNUM
     89    cdef int libGAP_T_PLIST
     90    cdef int libGAP_T_PLIST_NDENSE
     91    cdef int libGAP_T_PLIST_DENSE
     92    cdef int libGAP_T_PLIST_DENSE_NHOM
     93    cdef int libGAP_T_PLIST_DENSE_NHOM_SSORT
     94    cdef int libGAP_T_PLIST_DENSE_NHOM_NSORT
     95    cdef int libGAP_T_PLIST_EMPTY
     96    cdef int libGAP_T_PLIST_HOM
     97    cdef int libGAP_T_PLIST_HOM_NSORT
     98    cdef int libGAP_T_PLIST_HOM_SSORT
     99    cdef int libGAP_T_PLIST_TAB
     100    cdef int libGAP_T_PLIST_TAB_NSORT
     101    cdef int libGAP_T_PLIST_TAB_SSORT
     102    cdef int libGAP_T_PLIST_TAB_RECT
     103    cdef int libGAP_T_PLIST_TAB_RECT_NSORT
     104    cdef int libGAP_T_PLIST_TAB_RECT_SSORT
     105    cdef int libGAP_T_PLIST_CYC
     106    cdef int libGAP_T_PLIST_CYC_NSORT
     107    cdef int libGAP_T_PLIST_CYC_SSORT
     108    cdef int libGAP_T_PLIST_FFE     
     109    cdef int libGAP_LAST_PLIST_TNUM
     110    cdef int libGAP_T_RANGE_NSORT 
     111    cdef int libGAP_T_RANGE_SSORT 
     112    cdef int libGAP_T_BLIST       
     113    cdef int libGAP_T_BLIST_NSORT 
     114    cdef int libGAP_T_BLIST_SSORT
     115    cdef int libGAP_T_STRING     
     116    cdef int libGAP_T_STRING_NSORT
     117    cdef int libGAP_T_STRING_SSORT
     118    cdef int libGAP_LAST_LIST_TNUM
     119    cdef int libGAP_LAST_IMM_MUT_TNUM
     120    cdef int libGAP_FIRST_EXTERNAL_TNUM
     121    cdef int libGAP_T_COMOBJ
     122    cdef int libGAP_T_POSOBJ
     123    cdef int libGAP_T_DATOBJ
     124    cdef int libGAP_T_WPOBJ
     125    cdef int libGAP_LAST_EXTERNAL_TNUM
     126    cdef int libGAP_LAST_REAL_TNUM
     127    cdef int libGAP_LAST_VIRTUAL_TNUM
     128    cdef int libGAP_FIRST_COPYING_TNUM
     129    cdef int libGAP_COPYING           
     130    cdef int libGAP_LAST_COPYING_TNUM
     131    cdef int libGAP_FIRST_TESTING_TNUM
     132    cdef int libGAP_TESTING         
     133    cdef int libGAP_LAST_TESTING_TNUM
     134
     135cdef extern from "gap/read.h":
     136    void* libGAP_ReadEvalCommand(libGAP_Obj context)
     137    void* libGAP_ReadEvalFile()
     138    void* libGAP_ReadEvalResult
     139    bint libGAP_READ_ERROR()
     140
     141cdef extern from "gap/scanner.h":
     142    void libGAP_ClearError()
     143    libGAP_UInt libGAP_NrError
     144    libGAP_UInt libGAP_Symbol
     145    void libGAP_GetSymbol()
     146    void libGAP_Match (libGAP_UInt symbol, char* msg, libGAP_UInt skipto)
     147    int libGAP_S_ILLEGAL
     148    int libGAP_S_IDENT
     149    int libGAP_S_UNBIND
     150    int libGAP_S_ISBOUND
     151    int libGAP_S_TRYNEXT
     152    int libGAP_S_INFO
     153    int libGAP_S_ASSERT
     154    int libGAP_S_SAVEWS
     155    int libGAP_S_LOADWS
     156    int libGAP_S_LBRACK
     157    int libGAP_S_LBRACE
     158    int libGAP_S_BLBRACK
     159    int libGAP_S_BLBRACE
     160    int libGAP_S_RBRACK
     161    int libGAP_S_RBRACE
     162    int libGAP_S_DOT
     163    int libGAP_S_BDOT
     164    int libGAP_S_LPAREN
     165    int libGAP_S_RPAREN
     166    int libGAP_S_COMMA
     167    int libGAP_S_DOTDOT
     168    int libGAP_S_COLON
     169    int libGAP_S_PARTIALINT
     170    int libGAP_S_INT
     171    int libGAP_S_TRUE
     172    int libGAP_S_FALSE
     173    int libGAP_S_CHAR
     174    int libGAP_S_STRING
     175    int libGAP_S_PARTIALSTRING
     176    int libGAP_S_REC
     177    int libGAP_S_FUNCTION
     178    int libGAP_S_LOCAL
     179    int libGAP_S_END
     180    int libGAP_S_MAPTO
     181    int libGAP_S_MULT
     182    int libGAP_S_DIV
     183    int libGAP_S_MOD
     184    int libGAP_S_POW
     185    int libGAP_S_PLUS
     186    int libGAP_S_MINUS
     187    int libGAP_S_EQ
     188    int libGAP_S_LT
     189    int libGAP_S_GT
     190    int libGAP_S_NE
     191    int libGAP_S_LE
     192    int libGAP_S_GE
     193    int libGAP_S_IN
     194    int libGAP_S_NOT
     195    int libGAP_S_AND
     196    int libGAP_S_OR
     197    int libGAP_S_ASSIGN
     198    int libGAP_S_IF
     199    int libGAP_S_FOR
     200    int libGAP_S_WHILE
     201    int libGAP_S_REPEAT
     202    int libGAP_S_THEN
     203    int libGAP_S_ELIF
     204    int libGAP_S_ELSE
     205    int libGAP_S_FI
     206    int libGAP_S_DO
     207    int libGAP_S_OD
     208    int libGAP_S_UNTIL
     209    int libGAP_S_BREAK
     210    int libGAP_S_RETURN
     211    int libGAP_S_QUIT
     212    int libGAP_S_QQUIT
     213    int libGAP_S_CONTINUE
     214    int libGAP_S_SEMICOLON
     215    int libGAP_S_EOF
     216
     217cdef extern from "gap/gvars.h":
     218    libGAP_UInt libGAP_GVarName(char* name)
     219    void libGAP_AssGVar(libGAP_UInt gvar, libGAP_Obj val)
     220    libGAP_Obj libGAP_VAL_GVAR(libGAP_UInt gvar)
     221
     222cdef extern from "gap/string.h":
     223    char* libGAP_CSTR_STRING(libGAP_Obj list)
     224    int libGAP_GET_LEN_STRING(libGAP_Obj list)
     225    bint libGAP_IS_STRING(libGAP_Obj obj)
     226    void libGAP_C_NEW_STRING(libGAP_Obj new_gap_string, int length, char* c_string)
     227
     228cdef extern from "gap/gasman.h":
     229    void libGAP_InitGlobalBag(libGAP_Obj* addr, char* cookie)
     230    libGAP_Obj libGAP_NewBag(libGAP_UInt type, libGAP_UInt size)
     231    void libGAP_CHANGED_BAG(libGAP_Obj bag)
     232    void libGAP_MARK_BAG(libGAP_Obj bag)
     233    bint libGAP_IS_MARKED_ALIVE(libGAP_Obj bag)
     234    bint libGAP_IS_MARKED_DEAD(libGAP_Obj bag)
     235    bint libGAP_IS_MARKED_HALFDEAD(libGAP_Obj bag)
     236    cdef libGAP_UInt libGAP_NrAllBags
     237    cdef libGAP_UInt libGAP_SizeAllBags
     238    cdef libGAP_UInt libGAP_NrLiveBags
     239    cdef libGAP_UInt libGAP_SizeLiveBags
     240    cdef libGAP_UInt libGAP_NrDeadBags
     241    cdef libGAP_UInt libGAP_SizeDeadBags
     242    cdef libGAP_UInt libGAP_NrHalfDeadBags
     243    libGAP_UInt libGAP_CollectBags(libGAP_UInt size, libGAP_UInt full)
     244    void libGAP_CallbackForAllBags(void (*func)(libGAP_Obj))
     245    char* libGAP_TNAM_BAG(libGAP_Obj obj)
     246    libGAP_UInt libGAP_TNUM_BAG(libGAP_Obj)
     247    libGAP_UInt libGAP_SIZE_BAG(libGAP_Obj)
     248    void libGAP_CheckMasterPointers()
     249    libGAP_Obj* libGAP_MptrBags
     250    libGAP_Obj* libGAP_YoungBags
     251    libGAP_Obj* libGAP_OldBags
     252    libGAP_Obj* libGAP_AllocBags
     253    libGAP_Obj* libGAP_MarkedBags
     254    libGAP_Obj* libGAP_ChangedBags
     255
     256# in gasman.c but not declared in gasman.h
     257cdef extern libGAP_Obj* libGAP_StopBags
     258cdef extern libGAP_Obj* libGAP_EndBags
     259
     260cdef extern from "gap/ariths.h":
     261    libGAP_Obj libGAP_SUM (libGAP_Obj, libGAP_Obj)
     262    libGAP_Obj libGAP_DIFF(libGAP_Obj, libGAP_Obj)
     263    libGAP_Obj libGAP_PROD(libGAP_Obj, libGAP_Obj)
     264    libGAP_Obj libGAP_QUO(libGAP_Obj, libGAP_Obj)
     265    libGAP_Obj libGAP_POW(libGAP_Obj, libGAP_Obj)
     266    libGAP_Obj libGAP_MOD(libGAP_Obj, libGAP_Obj)
     267    libGAP_Obj libGAP_CALL_0ARGS(libGAP_Obj f)              # 0 arguments
     268    libGAP_Obj libGAP_CALL_1ARGS(libGAP_Obj f, libGAP_Obj a1)      # 1 argument
     269    libGAP_Obj libGAP_CALL_2ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2)   
     270    libGAP_Obj libGAP_CALL_3ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3)   
     271    libGAP_Obj libGAP_CALL_4ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3,
     272                                 libGAP_Obj a4)   
     273    libGAP_Obj libGAP_CALL_5ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3,
     274                                 libGAP_Obj a4, libGAP_Obj a5)   
     275    libGAP_Obj libGAP_CALL_6ARGS(libGAP_Obj f, libGAP_Obj a1, libGAP_Obj a2, libGAP_Obj a3,
     276                                 libGAP_Obj a4, libGAP_Obj a5, libGAP_Obj a6)
     277    libGAP_Obj libGAP_CALL_XARGS(libGAP_Obj f, libGAP_Obj args)   # more than 6 arguments
     278    bint libGAP_EQ(libGAP_Obj opL, libGAP_Obj opR)
     279    bint libGAP_LT(libGAP_Obj opL, libGAP_Obj opR)
     280
     281cdef extern from "gap/calls.h":
     282    bint libGAP_IS_FUNC(libGAP_Obj)
     283
     284cdef extern from "gap/plist.h":
     285    libGAP_Obj libGAP_NEW_PLIST(int type, int len)
     286    bint libGAP_IS_PLIST(libGAP_Obj lst)
     287    int libGAP_LEN_PLIST(libGAP_Obj lst)
     288    libGAP_Obj libGAP_ELM_PLIST(libGAP_Obj lst, int pos)
     289
     290cdef extern from "gap/lists.h":
     291    void libGAP_UNB_LIST(libGAP_Obj list, int pos)
     292
     293cdef extern from "gap/listfunc.h":
     294    void libGAP_AddList(libGAP_Obj list, libGAP_Obj obj)
     295    void libGAP_AddPlist(libGAP_Obj list, libGAP_Obj obj)
     296
     297cdef extern from "gap/records.h":
     298    char* libGAP_NAME_RNAM(libGAP_UInt rnam)
     299    libGAP_UInt libGAP_RNamIntg(int i)
     300    bint libGAP_IS_REC(libGAP_Obj obj)
     301    libGAP_Obj libGAP_ELM_REC(libGAP_Obj rec, libGAP_UInt rnam)
     302    libGAP_UInt libGAP_RNamName(libGAP_Char* name)
     303
     304cdef extern from "gap/precord.h":
     305    libGAP_Obj libGAP_NEW_PREC(int len)
     306    int libGAP_LEN_PREC(libGAP_Obj rec)
     307    int libGAP_GET_RNAM_PREC(libGAP_Obj rec, int i)
     308    libGAP_Obj libGAP_GET_ELM_PREC(libGAP_Obj rec, int i)
     309    void libGAP_AssPRec(libGAP_Obj rec, libGAP_UInt rnam, libGAP_Obj val)
     310    void libGAP_UnbPRec(libGAP_Obj rec, libGAP_UInt rnam)
     311    bint libGAP_IsbPRec(libGAP_Obj rec, libGAP_UInt rnam)
     312    libGAP_Obj libGAP_ElmPRec(libGAP_Obj rec, libGAP_UInt rnam)
     313   
     314cdef extern from "gap/cyclotom.h":
     315    pass
     316
     317cdef extern from "gap/bool.h":
     318    cdef libGAP_Obj libGAP_True
     319    cdef libGAP_Obj libGAP_False
     320
     321cdef extern from "gap/vars.h":
     322     cdef int libGAP_T_LVARS
     323     libGAP_Obj libGAP_BottomLVars
     324
     325
     326
     327
     328
  • new file sage/libs/gap/libgap.pyx

    diff --git a/sage/libs/gap/libgap.pyx b/sage/libs/gap/libgap.pyx
    new file mode 100644
    - +  
     1"""
     2libGAP shared library Interface to GAP
     3
     4This module implements a fast C library interface to GAP. To use
     5libGAP you simply call ``libgap`` (the parent of all
     6:class:`~sage.libs.gap.element.GapElement` instances) and use it to
     7convert Sage objects into GAP objects.
     8
     9EXAMPLES::
     10
     11    sage: a = libgap(10)
     12    sage: a
     13    10
     14    sage: type(a)
     15    <type 'sage.libs.gap.element.GapElement_Integer'>
     16    sage: a*a
     17    100
     18    sage: timeit('a*a')   # random output
     19    625 loops, best of 3: 898 ns per loop
     20
     21Compared to the expect interface this is >1000 times faster::
     22
     23    sage: b = gap('10')
     24    sage: timeit('b*b')   # random output
     25    125 loops, best of 3: 2.05 ms per loop
     26
     27If you want to evaluate GAP commands, use the :meth:`Gap.eval` method::
     28
     29    sage: libgap.eval('List([1..10], i->i^2)')
     30    [ 1, 4, 9, 16, 25, 36, 49, 64, 81, 100 ]
     31
     32not to be confused with the ``libgap`` call, which converts Sage
     33objects to GAP objects, for example strings to strings::
     34
     35    sage: libgap('List([1..10], i->i^2)')
     36    "List([1..10], i->i^2)"
     37    sage: type(_)
     38    <type 'sage.libs.gap.element.GapElement_String'>
     39
     40You can usually use the :meth:`~sage.libs.gap.element.GapElement.sage`
     41method to convert the resulting GAP element back to its Sage
     42equivalent::
     43
     44    sage: a.sage()
     45    10
     46    sage: type(_)
     47    <type 'sage.rings.integer.Integer'>
     48
     49    sage: libgap.eval('5/3 + 7*E(3)').sage()
     50    7*zeta3 + 5/3
     51
     52    sage: generators = libgap.AlternatingGroup(4).GeneratorsOfGroup().sage()
     53    sage: generators   # a Sage list of Sage permutations!
     54    [(1,2,3), (2,3,4)]
     55    sage: PermutationGroup(generators).cardinality()   # computed in Sage
     56    12
     57    sage: libgap.AlternatingGroup(4).Size()            # computed in GAP
     58    12
     59
     60So far, the following GAP data types can be directly converted to the
     61corresponding Sage datatype:
     62
     63#. GAP booleans ``true`` / ``false`` to Sage booleans ``True`` /
     64   ``False``. The third GAP boolean value ``fail`` raises a
     65   ``ValueError``.
     66
     67#. GAP integers to Sage integers.
     68
     69#. GAP rational numbers to Sage rational numbers.
     70
     71#. GAP cyclotomic numbers to Sage cyclotomic numbers.
     72
     73#. GAP permutations to Sage permutations.
     74
     75#. The GAP containers ``List`` and ``rec`` are converted to Sage
     76   containers ``list`` and ``dict``.  Furthermore, the
     77   :meth:`~sage.libs.gap.element.GapElement.sage` method is applied
     78   recursively to the entries.
     79
     80Special support is available for the GAP container classes. GAP lists
     81can be used as follows::
     82
     83    sage: lst = libgap([1,5,7]);  lst
     84    [ 1, 5, 7 ]
     85    sage: type(lst)
     86    <type 'sage.libs.gap.element.GapElement_List'>
     87    sage: len(lst)
     88    3
     89    sage: lst[0]
     90    1
     91    sage: [ x^2 for x in lst ]
     92    [1, 25, 49]
     93    sage: type(_[0])
     94    <type 'sage.libs.gap.element.GapElement_Integer'>
     95
     96Note that you can access the elements of GAP ``List`` objects as you
     97would expect from Python (with indexing starting at 0), but the
     98elements are still of type
     99:class:`~sage.libs.gap.element.GapElement`. The other GAP container
     100type are records, which are similar to Python dictionaries. You can
     101construct them directly from Python dictionaries::
     102
     103    sage: libgap({'a':123, 'b':456})
     104    rec( a := 123, b := 456 )
     105
     106Or get them as results of computations::
     107
     108    sage: rec = libgap.eval('rec(a:=123, b:=456, Sym3:=SymmetricGroup(3))')
     109    sage: rec['Sym3']
     110    Sym( [ 1 .. 3 ] )
     111    sage: dict(rec) 
     112    {'a': 123, 'Sym3': Sym( [ 1 .. 3 ] ), 'b': 456}
     113
     114The output is a Sage dictionary whose keys are Sage strings and whose
     115Values are instances of :meth:`~sage.libs.gap.element.GapElement`. So,
     116for example, ``rec['a']`` is not a Sage integer. To recursively
     117convert the entries into Sage objects, you should use the
     118:meth:`~sage.libs.gap.element.GapElement.sage` method::
     119
     120    sage: rec.sage()
     121    {'a': 123,
     122     'Sym3': NotImplementedError('cannot construct equivalent Sage object',),
     123     'b': 456}
     124
     125Now ``rec['a']`` is a Sage integer. We have not implemented the
     126conversion of the GAP symmetric group to the Sage symmetric group yet,
     127so you end up with a ``NotImplementedError`` exception object. The
     128exception is returned and not raised so that you can work with the
     129partial result.
     130
     131While we don't directly support matrices yet, you can convert them to
     132Gap List of Lists. These lists are then easily converted into Sage
     133using the recursive expansion of the
     134:meth:`~sage.libs.gap.element.GapElement.sage` method::
     135
     136    sage: M = libgap.eval('BlockMatrix([[1,1,[[1, 2],[ 3, 4]]], [1,2,[[9,10],[11,12]]], [2,2,[[5, 6],[ 7, 8]]]],2,2)')
     137    sage: M
     138    <block matrix of dimensions (2*2)x(2*2)>
     139    sage: M.List()   # returns a GAP List of Lists
     140    [ [ 1, 2, 9, 10 ], [ 3, 4, 11, 12 ], [ 0, 0, 5, 6 ], [ 0, 0, 7, 8 ] ]
     141    sage: M.List().sage()   # returns a Sage list of lists
     142    [[1, 2, 9, 10], [3, 4, 11, 12], [0, 0, 5, 6], [0, 0, 7, 8]]
     143    sage: matrix(ZZ, _)
     144    [ 1  2  9 10]
     145    [ 3  4 11 12]
     146    [ 0  0  5  6]
     147    [ 0  0  7  8]
     148
     149
     150Using the libGAP C library from Cython
     151======================================
     152
     153The lower-case ``libgap_foobar`` functions are ones that we added to
     154make the libGAP C shared library. The ``libGAP_foobar`` methods are
     155the original GAP methods simply prefixed with the string
     156``libGAP_``. The latter were originally not designed to be in a
     157library, so some care needs to be taken to call them.
     158
     159In particular, you must call ``libgap_mark_stack_bottom()`` in every
     160function that calls into the libGAP C functions. The reason is that
     161the GAP memory manager will automatically keep objects alive that are
     162referenced in local (stack-allocated) variables. While convenient,
     163this requires to look through the stack to find anything that looks
     164like an address to a memory bag. But this requires vigilance against
     165the following pattern::
     166
     167    cdef f()
     168      libgap_mark_stack_bottom()
     169      libGAP_function()
     170
     171    cdef g()
     172      libgap_mark_stack_bottom();
     173      f()                #  f() changed the stack bottom marker
     174      libGAP_function()  #  boom
     175
     176The solution is to re-order ``g()`` to first call ``f()``. In order to
     177catch this error, it is recommended that you wrap calls into libGAP in
     178``libgap_enter`` / ``libgap_exit`` blocks and not call
     179``libgap_mark_stack_bottom`` manually. So instead, always write
     180
     181    cdef f()
     182      libgap_enter()
     183      libGAP_function()
     184      libgap_exit()
     185
     186    cdef g()
     187      f()
     188      libgap_enter()
     189      libGAP_function()
     190      libgap_exit()
     191
     192If you accidentally call ``libgap_enter()`` twice then an error
     193message is printed to help you debug this::
     194
     195    sage: from sage.libs.gap.util import error_enter_libgap_block_twice
     196    sage: error_enter_libgap_block_twice()
     197    Traceback (most recent call last):
     198    ...
     199    RuntimeError: Entered a critical block twice
     200
     201AUTHORS:
     202
     203  - William Stein, Robert Miller (2009-06-23): first version
     204  - Volker Braun, Dmitrii Pasechnik, Ivan Andrus (2011-03-25, Sage Days 29):
     205    almost complete rewrite; first usable version.
     206  - Volker Braun (2012-08-28, GAP/Singular workshop): update to
     207    gap-4.5.5, make it ready for public consumption.
     208"""
     209
     210###############################################################################
     211#       Copyright (C) 2009, William Stein <wstein@gmail.com>
     212#       Copyright (C) 2012, Volker Braun <vbraun.name@gmail.com>
     213#
     214#   Distributed under the terms of the GNU General Public License (GPL)
     215#   as published by the Free Software Foundation; either version 2 of
     216#   the License, or (at your option) any later version.
     217#                   http://www.gnu.org/licenses/
     218###############################################################################
     219
     220
     221##############################################################################
     222#
     223#  If you want to add support for converting some GAP datatype to its
     224#  Sage equivalent, you have two options. Either
     225#
     226#  1. add an if-clause to GapElement.sage(). This is the easiest
     227#     option and you should probably start with it first
     228#
     229#  2. Subclass GapElement to GapElement_Mydatatype. In that case you
     230#     need to write the derived class, a factory function to
     231#     instantiate it (GapElement cannot be instantiated by __init__),
     232#     and add an if-clause in make_GapElement. See GapElement_List,
     233#     for example. The advantage of this more complicated approach is
     234#     that you can then add extra methods to your data type. For
     235#     example, GapElement_List instances can access the individual
     236#     elements with the usual gapelement[i] syntax.
     237#
     238# TODO
     239#
     240# Not all GAP types have their own GapElement. We should wrap more
     241# stuff. Talk to me (Volker) if you want to work on that.
     242#
     243##############################################################################
     244
     245from gap_includes cimport *
     246
     247from sage.structure.sage_object cimport SageObject
     248from sage.structure.parent cimport Parent
     249from sage.structure.element cimport ModuleElement, RingElement
     250from sage.rings.all import ZZ
     251from sage.libs.gap.element cimport *
     252
     253
     254############################################################################
     255### Debugging ##############################################################
     256############################################################################
     257
     258cdef void report(libGAP_Obj bag):
     259    print libGAP_TNAM_OBJ(bag), <int>libGAP_TNUM_BAG(bag), <int>libGAP_SIZE_BAG(bag)
     260
     261
     262cdef void print_gasman_objects():
     263    libgap_enter()
     264    libGAP_CallbackForAllBags(report)
     265    libgap_exit()
     266
     267
     268
     269
     270
     271
     272
     273
     274############################################################################
     275### Gap  ###################################################################
     276############################################################################
     277# The libGap interpreter object Gap is the parent of the GapElements
     278
     279
     280class Gap(Parent):
     281    r"""
     282    The libgap interpreter object.
     283
     284    .. NOTE::
     285
     286        This object must be instantiated exactly once by the
     287        libgap. Always use the provided ``libgap`` instance, and never
     288        instantiate :class:`Gap` manually.
     289
     290    EXAMPLES::
     291   
     292        sage: libgap.eval('SymmetricGroup(4)')
     293        Sym( [ 1 .. 4 ] )
     294
     295    TESTS::
     296
     297        sage: TestSuite(libgap).run(skip=['_test_category', '_test_elements', '_test_pickling'])
     298    """
     299
     300    Element = GapElement
     301
     302
     303    def _element_constructor_(self, x):
     304        r"""
     305        Construct elements of this parent class
     306
     307        INPUT:
     308
     309        - ``x`` -- anything that defines a GAP object.
     310
     311        OUTPUT:
     312
     313        A :class:`GapElement`.
     314
     315        EXAMPLES::
     316         
     317            sage: libgap(0)   # indirect doctest
     318            0
     319            sage: libgap(ZZ(0))
     320            0
     321            sage: libgap(int(0))
     322            0
     323        """
     324        if isinstance(x, GapElement):
     325            return x
     326        elif isinstance(x, (list, tuple)):
     327            return make_GapElement_List(self, make_gap_list(x))
     328        elif isinstance(x, dict):
     329            return make_GapElement_Record(self, make_gap_record(x))
     330        elif isinstance(x, bool):
     331            # attention: must come before int
     332            return make_GapElement_Boolean(self, libGAP_True if x else libGAP_False)
     333        elif isinstance(x, int):
     334            return make_GapElement_Integer(self, make_gap_integer(x))
     335        elif isinstance(x, basestring):
     336            return make_GapElement_String(self, make_gap_string(x))
     337        else:
     338            x = str(x._gap_init_())
     339            return make_any_gap_element(self, gap_eval(x))
     340        raise ValueError('cannot represent '+str(x)+' as a GAP object')
     341
     342
     343    def eval(self, gap_command):
     344        """
     345        Evaluate a gap command and wrap the result
     346
     347        INPUT:
     348       
     349        - ``gap_command`` -- a string containing a valid gap command
     350          without the trailing semicolon.
     351
     352        OUTPUT:
     353
     354        A :class:`GapElement`.
     355
     356        EXAMPLES::
     357
     358            sage: libgap.eval('0')
     359            0
     360            sage: libgap.eval('"string"')
     361            "string"
     362        """
     363        if not isinstance(gap_command, basestring):
     364            gap_command = str(gap_command._gap_init_())
     365        return make_any_gap_element(self, gap_eval(gap_command))
     366
     367
     368    def _an_element_(self):
     369        r"""
     370        Return a :class:`GapElement`
     371       
     372        OUTPUT:
     373
     374        A :class:`GapElement`.
     375
     376        EXAMPLES::
     377         
     378            sage: libgap.an_element()   # indirect doctest
     379            0
     380        """
     381        return self(0)
     382
     383
     384    def __init__(self):
     385        r"""
     386        The Python constructor.
     387       
     388        EXAMPLES::
     389
     390            sage: type(libgap)
     391            <type 'sage.misc.lazy_import.LazyImport'>
     392            sage: type(libgap._get_object())
     393            <class 'sage.libs.gap.libgap.Gap'>
     394        """
     395        initialize()
     396        libgap_set_gasman_callback(gasman_callback)
     397        from sage.rings.integer_ring import ZZ
     398        Parent.__init__(self, base=ZZ)
     399
     400
     401    def __repr__(self):
     402        r"""
     403        Return a string representation of ``self``.
     404       
     405        OUTPUT:
     406
     407        String.
     408
     409        EXAMPLES::
     410
     411            sage: libgap
     412            C library interface to GAP
     413        """
     414        return 'C library interface to GAP'
     415   
     416
     417    def trait_names(self):
     418        """
     419        Return all Gap function names.
     420
     421        OUTPUT:
     422       
     423        A list of strings.
     424       
     425        EXAMPLES::
     426
     427            sage: len(libgap.trait_names()) > 1000
     428            True
     429        """
     430        import gap_functions
     431        return gap_functions.common_gap_functions
     432
     433
     434    def __getattr__(self, name):
     435        r"""
     436        The attributes of the Gap object are the Gap functions.
     437
     438        INPUT:
     439
     440        - ``name`` -- string. The name of the GAP function you want to
     441          call.
     442
     443        OUTPUT:
     444
     445        A :class:`GapElement_Function`. A ``AttributeError`` is raised
     446        if there is no such function.
     447
     448        EXAMPLES::
     449         
     450            sage: libgap.List
     451            <Gap function "List">
     452        """
     453        if name in self.trait_names():
     454            f = make_GapElement_Function(self, gap_eval(str(name)))
     455            assert f.is_function()
     456            self.__dict__[name] = f
     457            return f
     458        else:
     459            raise AttributeError, 'No such attribute: '+name+'.'
     460
     461
     462    def show(self):
     463        """
     464        Print statistics about the GAP owned object list
     465       
     466        Slight complication is that we want to do it without accessing
     467        libgap objects, so we don't create new GapElements as a side
     468        effect.
     469
     470        EXAMPLES::
     471
     472            sage: a = libgap(123)
     473            sage: b = libgap(456)
     474            sage: c = libgap(789)
     475            sage: del b
     476            sage: libgap.show() # random output
     477            11 LibGAP elements currently alive
     478            rec( full := rec( cumulative := 122, deadbags := 9,
     479            deadkb := 0, freekb := 7785, livebags := 304915,
     480            livekb := 47367, time := 33, totalkb := 68608 ),
     481            nfull := 3, npartial := 14 )
     482        """
     483        print self.count_GAP_objects(), 'LibGAP elements currently alive'
     484        print self.eval('GasmanStatistics()')
     485        # print_gasman_objects()
     486
     487
     488    def count_GAP_objects(self):
     489        """
     490        Return the number of GAP objects that are being tracked by
     491        libGAP
     492       
     493        OUTPUT:
     494       
     495        An integer
     496
     497        EXAMPLES::
     498
     499            sage: libgap.count_GAP_objects()   # random output
     500            5
     501        """
     502        return sum([1 for obj in get_owned_objects()])
     503
     504
     505    def mem(self):
     506        """
     507        Return information about libGAP memory usage
     508
     509        The GAP workspace is partitioned into 5 pieces (see gasman.c
     510        in the GAP sources for more details):
     511
     512        * The **masterpointer area**  contains  all the masterpointers  of  the bags.
     513       
     514        * The **old bags area** contains the bodies of all the  bags that survived at
     515          least one  garbage collection.  This area is  only  scanned for dead bags
     516          during a full garbage collection.
     517         
     518        * The **young bags area** contains the bodies of all  the bags that have been
     519          allocated since the  last garbage collection.  This  area is scanned  for
     520          dead  bags during  each garbage  collection.
     521
     522        * The **allocation area** is the storage  that is available for allocation of
     523          new bags.  When a new bag is allocated the storage for  the body is taken
     524          from  the beginning of   this area,  and  this  area  is  correspondingly
     525          reduced.   If  the body does not   fit in the  allocation  area a garbage
     526          collection is  performed.
     527
     528        * The **unavailable  area** is  the free  storage that  is not  available for
     529          allocation.
     530
     531        OUTPUT:
     532
     533        This function returns a tuple containing 5 integers. Each is
     534        the size (in bytes) of the five partitions of the
     535        workspace. This will potentially change after each GAP garbage
     536        collection.
     537       
     538        EXAMPLES::
     539         
     540            sage: libgap.collect()
     541            sage: libgap.mem()   # random output
     542            (1048576, 6706782, 0, 960930, 0)
     543
     544            sage: libgap.FreeGroup(3)
     545            <free group on the generators [ f1, f2, f3 ]>
     546            sage: libgap.mem()   # random output
     547            (1048576, 6706782, 47571, 913359, 0)
     548
     549            sage: libgap.collect()
     550            sage: libgap.mem()   # random output
     551            (1048576, 6734785, 0, 998463, 0)
     552        """
     553        return memory_usage()
     554
     555
     556    def collect(self):
     557        """
     558        Manually run the garbage collector
     559
     560        EXAMPLES::
     561
     562            sage: a = libgap(123)
     563            sage: del a
     564            sage: libgap.collect()
     565        """
     566        libgap_enter()
     567        rc = libGAP_CollectBags(0,1)
     568        libgap_exit()
     569        if rc != 1:
     570            raise RuntimeError('Garbage collection failed.')
     571
     572
     573
     574libgap = Gap()
     575
  • new file sage/libs/gap/test/Makefile

    diff --git a/sage/libs/gap/test/Makefile b/sage/libs/gap/test/Makefile
    new file mode 100644
    - +  
     1
     2
     3GAPDIR="$(SAGE_LOCAL)/gap/latest"
     4
     5# VALGRIND=valgrind --leak-check=full
     6# VALGRIND=valgrind --db-attach=yes
     7#VALGRIND=valgrind --suppressions=libgap.supp --gen-suppressions=yes
     8#VALGRIND=valgrind --suppressions=libgap.supp --db-attach=yes
     9VALGRIND=
     10
     11all: main
     12        LD_LIBRARY_PATH=$(SAGE_LOCAL)/lib $(VALGRIND) ./main
     13
     14main: main.o Makefile
     15        gcc -L$(SAGE_LOCAL)/lib -o main main.o -lgap -lcsage -lntl -lstdc++ -lpari -lpython2.7 -lm -lgmp
     16
     17main.o: main.c
     18        echo $(GAPDIR)
     19        gcc -std=gnu99 -DGAPDIR="\"$(GAPDIR)\"" -I$(SAGE_LOCAL)/include -I$(SAGE_LOCAL)/include/python2.6 -c -g $^
     20
     21clean:
     22        rm main.o main *~
     23
     24.PHONY: all clean
  • new file sage/libs/gap/test/README.txt

    diff --git a/sage/libs/gap/test/README.txt b/sage/libs/gap/test/README.txt
    new file mode 100644
    - +  
     1In this folder is a small stub program that uses libGAP library for
     2some simple computations for debugging purposes. It uses libGAP
     3essentially in the same as the Sage libgap interface, but without the
     4overhead.
     5
  • new file sage/libs/gap/test/main.c

    diff --git a/sage/libs/gap/test/main.c b/sage/libs/gap/test/main.c
    new file mode 100644
    - +  
     1#include <unistd.h>
     2#include <stdio.h>
     3#include "gap/libgap.h"
     4
     5#include "gap/config.h"
     6#include "gap/system.h"
     7#include "gap/objects.h"
     8#include "gap/gasman.h"
     9#include "gap/code.h"
     10#include "gap/vars.h"
     11#include "gap/read.h"
     12
     13extern char **environ;
     14
     15void error_handler(char* msg)
     16{
     17  printf("Error: %s\n", msg);
     18}
     19
     20void eval(char* cmd) {
     21  printf("Input:\n%s", cmd);
     22  libgap_start_interaction(cmd);
     23
     24  libgap_enter();
     25  libGAP_ReadEvalCommand(libGAP_BottomLVars);
     26  libGAP_ViewObjHandler(libGAP_ReadEvalResult);
     27  char* out = libgap_get_output();
     28  libgap_exit();
     29
     30  printf("Output:\n%s", out);
     31  libgap_finish_interaction();
     32}
     33
     34int main()
     35{
     36  char* argv[8];
     37  argv[0] = "gap";
     38  argv[1] = "-l";
     39  argv[2] = GAPDIR;
     40  argv[3] = "-m";
     41  argv[4] = "32M";
     42  argv[5] = "-q";
     43  argv[6] = "-T";
     44  argv[7] = NULL;
     45  int argc=7;
     46  // gap_main_loop(argc, argv, environ);
     47  libgap_set_error_handler(&error_handler);
     48  libgap_initialize(argc, argv);
     49  printf("Initialized\n");
     50 
     51  libgap_enter()
     52  libGAP_CollectBags(0,1);  // full GC
     53  libgap_exit()
     54
     55  eval("1+2+3;\n");
     56  eval("g:=FreeGroup(2);\n");
     57  eval("a:=g.1;\n");
     58  eval("b:=g.2;\n");
     59  eval("lis:=[a^2, a^2, b*a];\n");
     60  eval("h:=g/lis;\n");
     61  eval("c:=h.1;\n");
     62  eval("Set([1..1000000], i->Order(c));\n");
     63
     64  libgap_finalize();
     65  return 0;
     66}
     67
     68
     69/*
     70
     71g:=FreeGroup(2);
     72a:=g.1;
     73b:=g.2;
     74lis:=[a^2, a^2, b*a];
     75h:=g/lis;
     76c:=h.1;
     77Set([1..300000], i->Order(c));
     78
     79
     80 */
  • new file sage/libs/gap/test_long.py

    diff --git a/sage/libs/gap/test_long.py b/sage/libs/gap/test_long.py
    new file mode 100644
    - +  
     1"""
     2Long tests for libGAP
     3
     4These stress test the garbage collection inside GAP
     5"""
     6
     7from sage.libs.all import libgap
     8
     9
     10def test_loop_1():
     11    """
     12    EXAMPLES::
     13
     14        sage: from sage.libs.gap.test_long import test_loop_1
     15        sage: test_loop_1()
     16    """
     17    libgap.collect()
     18    for i in range(10000):
     19        G = libgap.CyclicGroup(2)
     20
     21
     22def test_loop_2():
     23    """
     24    EXAMPLES::
     25
     26        sage: from sage.libs.gap.test_long import test_loop_2
     27        sage: test_loop_2()
     28    """
     29    G =libgap.FreeGroup(2)
     30    a,b = G.GeneratorsOfGroup()
     31    for i in range(100):
     32        rel = libgap([a**2, b**2, a*b*a*b])
     33        H = G / rel
     34        H1 = H.GeneratorsOfGroup()[0]
     35        n = H1.Order()
     36        assert n.sage() == 2
     37
     38    for i in range(300000):
     39        n = libgap.Order(H1)
     40
     41
     42def test_loop_3():
     43    """
     44    EXAMPLES::
     45
     46        sage: from sage.libs.gap.test_long import test_loop_3
     47        sage: test_loop_3()
     48    """
     49    G = libgap.FreeGroup(2)
     50    (a,b) = G.GeneratorsOfGroup()
     51    for i in range(300000):
     52        lis=libgap([])
     53        lis.Add(a ** 2)
     54        lis.Add(b ** 2)
     55        lis.Add(b * a)
     56
     57
     58
  • new file sage/libs/gap/util.pxd

    diff --git a/sage/libs/gap/util.pxd b/sage/libs/gap/util.pxd
    new file mode 100644
    - +  
     1###############################################################################
     2#       Copyright (C) 2012, Volker Braun <vbraun.name@gmail.com>
     3#
     4#   Distributed under the terms of the GNU General Public License (GPL)
     5#   as published by the Free Software Foundation; either version 2 of
     6#   the License, or (at your option) any later version.
     7#                   http://www.gnu.org/licenses/
     8###############################################################################
     9
     10from gap_includes cimport *
     11
     12############################################################################
     13### Hooking into the GAP memory management #################################
     14############################################################################
     15
     16cdef class ObjWrapper(object):
     17    cdef libGAP_Obj value
     18
     19cdef ObjWrapper wrap_obj(libGAP_Obj obj)
     20
     21# a dictionary to keep all GAP elements
     22cdef dict owned_objects_refcount
     23
     24# returns the refcount dictionary for debugging purposes
     25cpdef get_owned_objects()
     26
     27# Reference count GAP objects that you want to prevent from being
     28# garbage collected
     29cdef void reference_obj(libGAP_Obj obj)
     30cdef void dereference_obj(libGAP_Obj obj)
     31
     32# callback from the GAP memory manager so we can mark all_gap_elements.values()
     33cdef void gasman_callback()
     34
     35
     36############################################################################
     37### Initialization of libGAP ###############################################
     38############################################################################
     39
     40# To ensure that we call initialize_libgap only once.
     41cdef bint _gap_is_initialized = False
     42cdef void initialize()
     43
     44
     45############################################################################
     46### Helper to protect temporary objects from deletion ######################
     47############################################################################
     48
     49# Hold a reference (inside the GAP kernel) to obj so that it doesn't
     50# get deleted this works by assigning it to a global variable. This is
     51# very simple, but you can't use it to keep two objects alive. Be
     52# careful.
     53cdef libGAP_UInt reference_holder
     54cdef void hold_reference(libGAP_Obj obj)
     55
     56
     57############################################################################
     58### Evaluate string in GAP #################################################
     59############################################################################
     60
     61# Evaluate a string
     62cdef libGAP_Obj gap_eval(str gap_string) except? NULL
     63
     64
     65############################################################################
     66### Debug functions ########################################################
     67############################################################################
     68
     69# Return details of the GAP memory pool
     70cpdef memory_usage()
  • new file sage/libs/gap/util.pyx

    diff --git a/sage/libs/gap/util.pyx b/sage/libs/gap/util.pyx
    new file mode 100644
    - +  
     1"""
     2Utility functions for libGAP
     3"""
     4
     5###############################################################################
     6#       Copyright (C) 2012, Volker Braun <vbraun.name@gmail.com>
     7#
     8#   Distributed under the terms of the GNU General Public License (GPL)
     9#   as published by the Free Software Foundation; either version 2 of
     10#   the License, or (at your option) any later version.
     11#                   http://www.gnu.org/licenses/
     12###############################################################################
     13
     14from sage.misc.misc import is_64_bit, SAGE_LOCAL, SAGE_ROOT
     15from libc.stdint cimport uintptr_t
     16from element cimport *
     17
     18
     19
     20############################################################################
     21### Hooking into the GAP memory management #################################
     22############################################################################
     23
     24cdef class ObjWrapper(object):
     25    """
     26    Wrapper for GAP master pointers
     27
     28    EXAMPLES::
     29
     30        sage: from sage.libs.gap.util import ObjWrapper
     31        sage: x = ObjWrapper()
     32        sage: y = ObjWrapper()
     33        sage: x == y
     34        True
     35    """
     36
     37    def __richcmp__(ObjWrapper self, ObjWrapper other, int op):
     38        r"""
     39        Comparison wrapped libGAP_Obj.
     40       
     41        INPUT:
     42
     43        - ``lhs``, ``rhs`` -- :class:`ObjWrapper`.
     44       
     45        - ``op`` -- integer. The comparison operation to be performed.
     46
     47        OUTPUT:
     48         
     49        Boolean.
     50
     51        EXAMPLES::
     52
     53            sage: from sage.libs.gap.util import ObjWrapper
     54            sage: x = ObjWrapper()
     55            sage: y = ObjWrapper()
     56            sage: x == y
     57            True
     58        """
     59        cdef result
     60        cdef libGAP_Obj self_value = self.value
     61        cdef libGAP_Obj other_value = other.value
     62        if op==0:      # <   0
     63            return self_value < other_value
     64        elif op==1:    # <=  1
     65            return self_value <= other_value
     66        elif op==2:    # ==  2
     67            return self_value == other_value
     68        elif op==4:    # >   4
     69            return self_value > other_value
     70        elif op==5:    # >=  5
     71            return self_value >= other_value
     72        elif op==3:    # !=  3
     73            return self_value != other_value
     74        else:
     75            assert False  # unreachable
     76       
     77    def __hash__(self):
     78        """
     79        Return a hash value
     80
     81        EXAMPLES::
     82
     83            sage: from sage.libs.gap.util import ObjWrapper
     84            sage: x = ObjWrapper()
     85            sage: hash(x)
     86            0
     87        """
     88        return <int>(self.value)
     89
     90
     91cdef ObjWrapper wrap_obj(libGAP_Obj obj):
     92    """
     93    Constructor function for :class:`ObjWrapper`
     94    """
     95    cdef ObjWrapper result = ObjWrapper.__new__(ObjWrapper)
     96    result.value = obj
     97    return result
     98
     99
     100owned_objects_refcount = dict()
     101
     102cpdef get_owned_objects():
     103    """
     104    Helper to access the refcount dictionary from Python code
     105    """
     106    return owned_objects_refcount
     107
     108
     109cdef void reference_obj(libGAP_Obj obj):
     110    """
     111    Reference ``obj``
     112    """
     113    cdef ObjWrapper wrapped = wrap_obj(obj)
     114    global owned_objects_refcount
     115    if wrapped in owned_objects_refcount:
     116        owned_objects_refcount[wrapped] += 1
     117    else:
     118        owned_objects_refcount[wrapped] = 1
     119
     120
     121cdef void dereference_obj(libGAP_Obj obj):
     122    """
     123    Reference ``obj``
     124    """
     125    cdef ObjWrapper wrapped = wrap_obj(obj)
     126    global owned_objects_refcount
     127    refcount = owned_objects_refcount.pop(wrapped)
     128    if refcount > 1:
     129        owned_objects_refcount[wrapped] = refcount - 1
     130
     131
     132cdef void gasman_callback():
     133    """
     134    Callback before each GAP garbage collection
     135    """
     136    global owned_objects_refcount
     137    for obj in owned_objects_refcount.iterkeys():
     138        libGAP_MARK_BAG((<ObjWrapper>obj).value)
     139
     140
     141
     142
     143
     144############################################################################
     145### Initialization of libGAP ###############################################
     146############################################################################
     147
     148def gap_root():
     149    """
     150    Find the location of the GAP root install which is stored in the gap
     151    startup script.
     152   
     153    EXAMPLES::
     154       
     155        sage: from sage.libs.gap.util import gap_root
     156        sage: gap_root()   # random output
     157        '/home/vbraun/opt/sage-5.3.rc0/local/gap/latest'
     158    """
     159    import os.path
     160    gapdir = os.path.join(SAGE_LOCAL, 'gap', 'latest')
     161    if os.path.exists(gapdir):
     162        return gapdir
     163    print 'The gap-4.5.5.spkg (or later) seems to be missing!'
     164    gap_sh = open(os.path.join(SAGE_LOCAL, 'bin', 'gap')).read().splitlines()
     165    gapdir = filter(lambda dir:dir.strip().startswith('GAP_DIR'), gap_sh)[0]
     166    gapdir = gapdir.split('"')[1]
     167    gapdir = gapdir.replace('$SAGE_ROOT', SAGE_ROOT)
     168    return gapdir
     169   
     170
     171cdef void initialize():
     172    """
     173    Initialize the GAP library, if it hasn't already been
     174    initialized.  It is safe to call this multiple times.
     175   
     176    INPUT:
     177   
     178    - ``max_workspace_size`` -- string. The size hint for GAP's memory
     179      pool. Same syntax as GAP's ``-o`` command line option.
     180   
     181    TESTS::
     182   
     183        sage: libgap(123)   # indirect doctest
     184        123
     185    """
     186    global _gap_is_initialized
     187    if _gap_is_initialized: return
     188   
     189    # Define argv and environ variables, which we will pass in to
     190    # initialize GAP. Note that we must pass define the memory pool
     191    # size!
     192    cdef char* argv[8]
     193    argv[0] = "sage"
     194    argv[1] = "-l"
     195    s = gap_root()
     196    argv[2] = s
     197   
     198    argv[3] = "-o"
     199    import platform
     200    if platform.architecture()[0] == '32bit':
     201        argv[4] = "3900m"
     202    else:
     203        argv[4] = "16384G"
     204               
     205    argv[5] = "-m"
     206    argv[6] = "64m"
     207   
     208    argv[7] = "-q"    # no prompt!
     209    argv[8] = "-T"    # no debug loop
     210    argv[9] = NULL
     211    cdef int argc = 9
     212    libgap_initialize(argc, argv)
     213    libgap_set_error_handler(&error_handler)
     214    libgap_enter()
     215   
     216    # Prepare global GAP variable to hold temporary GAP objects
     217    global reference_holder
     218    reference_holder = libGAP_GVarName("$SAGE_libgap_reference_holder")
     219   
     220    # Finished!
     221    libgap_exit()
     222    _gap_is_initialized = True
     223
     224
     225
     226############################################################################
     227### Evaluate string in GAP #################################################
     228############################################################################
     229
     230cdef libGAP_Obj gap_eval(str gap_string) except? NULL:
     231    r"""
     232    Evaluate a string in GAP.
     233
     234    INPUT:
     235   
     236    - ``gap_string`` -- string. A valid statement in GAP.
     237
     238    OUTPUT:
     239   
     240    The resulting GAP object or NULL+Python Exception in case of error.
     241
     242    EXAMPLES::
     243
     244        sage: libgap.eval('if 4>3 then\nPrint("hi");\nfi')
     245        NULL
     246        sage: libgap.eval('1+1')   # testing that we have sucessfully recovered
     247        2
     248
     249        sage: libgap.eval('if 4>3 thenPrint("hi");\nfi')
     250        Traceback (most recent call last):
     251        ...
     252        ValueError: libGAP: Syntax error: then expected
     253        if 4>3 thenPrint("hi");
     254        fi;
     255                       ^
     256        sage: libgap.eval('1+1')   # testing that we have sucessfully recovered
     257        2
     258    """
     259    initialize()
     260    cdef libGAP_ExecStatus status
     261
     262    cmd = gap_string + ';\n'
     263    try:
     264        libgap_enter()
     265        libgap_start_interaction(cmd)
     266        try:
     267            sig_on()
     268            status = libGAP_ReadEvalCommand(libGAP_BottomLVars)
     269            if status != libGAP_STATUS_END:
     270                libgap_call_error_handler()
     271            sig_off()
     272        except RuntimeError, msg:
     273            raise ValueError('libGAP: '+str(msg).strip())
     274
     275        if libGAP_Symbol != libGAP_S_SEMICOLON:
     276            raise ValueError('did not end with semicolon')
     277        libGAP_GetSymbol()
     278        if libGAP_Symbol != libGAP_S_EOF:
     279            raise ValueError('can only evaluate a single statement')
     280
     281    finally:
     282        libgap_finish_interaction()
     283        libgap_exit()
     284
     285    if libGAP_ReadEvalResult != NULL:
     286        libgap_enter()
     287        libGAP_AssGVar(libGAP_Last3, libGAP_VAL_GVAR(libGAP_Last2))
     288        libGAP_AssGVar(libGAP_Last2, libGAP_VAL_GVAR(libGAP_Last))
     289        libGAP_AssGVar(libGAP_Last, libGAP_ReadEvalResult)
     290        libgap_exit()
     291
     292    return libGAP_ReadEvalResult   # may be NULL, thats ok
     293
     294
     295############################################################################
     296### Helper to protect temporary objects from deletion ######################
     297############################################################################
     298
     299cdef void hold_reference(libGAP_Obj obj):
     300    """
     301    Hold a reference (inside the GAP kernel) to obj
     302
     303    This ensures that the GAP garbage collector does not delete
     304    ``obj``. This works by assigning it to a global variable. This is
     305    very simple, but you can't use it to keep two objects alive. Be
     306    careful.
     307    """
     308    libgap_enter()
     309    global reference_holder
     310    libGAP_AssGVar(reference_holder, obj)
     311    libgap_exit()
     312
     313
     314############################################################################
     315### Error handler ##########################################################
     316############################################################################
     317
     318cdef extern from 'stdlib.h':
     319    void abort()
     320
     321include '../../ext/interrupt.pxi'
     322
     323cdef void error_handler(char* msg):
     324    """
     325    The libgap error handler
     326
     327    We call ``abort()`` which causes us to jump back to the Sage
     328    signal handler.
     329    """
     330    sig_str(msg)
     331    abort()
     332    sig_off()
     333
     334
     335############################################################################
     336### Debug functions ########################################################
     337############################################################################
     338
     339cdef inline void DEBUG_CHECK(libGAP_Obj obj):
     340    """
     341    Check that ``obj`` is valid.
     342
     343    This function is only useful for debugging.
     344    """
     345    libgap_enter()
     346    libGAP_CheckMasterPointers()
     347    libgap_exit()
     348    if obj == NULL:
     349        print 'DEBUG_CHECK: Null pointer!'
     350   
     351
     352
     353
     354cpdef memory_usage():
     355    """
     356    Return information about the memory useage.
     357
     358    See :meth:`~sage.libs.gap.libgap.Gap.mem` for details.
     359    """
     360    cdef size_t SizeMptrsArea = libGAP_OldBags - libGAP_MptrBags
     361    cdef size_t SizeOldBagsArea = libGAP_YoungBags - libGAP_OldBags
     362    cdef size_t SizeYoungBagsArea = libGAP_AllocBags - libGAP_YoungBags
     363    cdef size_t SizeAllocationArea = libGAP_StopBags - libGAP_AllocBags
     364    cdef size_t SizeUnavailableArea = libGAP_EndBags - libGAP_StopBags
     365    return (SizeMptrsArea, SizeOldBagsArea, SizeYoungBagsArea, SizeAllocationArea, SizeUnavailableArea)
     366
     367
     368cpdef error_enter_libgap_block_twice():
     369    """
     370    Demonstrate that we catch errors from entering a block twice.
     371
     372    EXAMPLES::
     373   
     374        sage: from sage.libs.gap.util import error_enter_libgap_block_twice
     375        sage: error_enter_libgap_block_twice()
     376        Traceback (most recent call last):
     377        ...
     378        RuntimeError: Entered a critical block twice
     379    """
     380    from sage.libs.gap.libgap import libgap
     381    try:
     382        sig_on()
     383        libgap_enter()
     384        libgap_enter()
     385        sig_off()
     386    finally:
     387        libgap_exit()
     388
     389
     390cpdef error_exit_libgap_block_without_enter():
     391    """
     392    Demonstrate that we catch errors from omitting libgap_enter.
     393
     394    EXAMPLES::
     395   
     396        sage: from sage.libs.gap.util import error_exit_libgap_block_without_enter
     397        sage: error_exit_libgap_block_without_enter()
     398        Traceback (most recent call last):
     399        ...
     400        RuntimeError: Called libgap_exit without previous libgap_enter
     401    """
     402    from sage.libs.gap.libgap import libgap
     403    sig_on()
     404    libgap_exit()
     405    sig_off()
     406   
     407############################################################################
     408### Auxilliary functions ###################################################
     409############################################################################
     410
     411
     412def command(command_string):
     413    """
     414    Playground for accessing Gap via libGap.
     415
     416    You should not use this function in your own programs. This is
     417    just here for convenience if you want to play with the libgap
     418    libray code.
     419
     420    EXAMPLES::
     421
     422        sage: from sage.libs.gap.util import command
     423        sage: command('1')
     424        Output follows...
     425        1
     426       
     427        sage: command('1/0')
     428        Traceback (most recent call last):
     429        ...
     430        ValueError: libGAP: Error, Rational operations: <divisor> must not be zero
     431
     432        sage: command('NormalSubgroups')
     433        Output follows...
     434        <Attribute "NormalSubgroups">
     435
     436        sage: command('rec(a:=1, b:=2)')
     437        Output follows...
     438        rec( a := 1, b := 2 )
     439    """
     440    initialize()
     441    cdef libGAP_ExecStatus status
     442
     443    cmd = command_string + ';\n'
     444    try:
     445        libgap_enter()
     446        libgap_start_interaction(cmd)
     447        try:
     448            sig_on()
     449            status = libGAP_ReadEvalCommand(libGAP_BottomLVars)
     450            if status != libGAP_STATUS_END:
     451                libgap_call_error_handler()
     452            sig_off()
     453        except RuntimeError, msg:
     454            raise ValueError('libGAP: '+str(msg).strip())
     455
     456        assert libGAP_Symbol == libGAP_S_SEMICOLON, 'Did not end with semicolon?'
     457        libGAP_GetSymbol()
     458        if libGAP_Symbol != libGAP_S_EOF:
     459            raise ValueError('command() expects a single statement.')
     460
     461        if libGAP_ReadEvalResult:
     462            libGAP_ViewObjHandler(libGAP_ReadEvalResult)
     463            s = libgap_get_output()
     464            print 'Output follows...'
     465            print s.strip()
     466        else:
     467            print 'No output.'
     468           
     469    finally:
     470        libgap_exit()
     471        libgap_finish_interaction()
     472
     473    DEBUG_CHECK(libGAP_ReadEvalResult)
     474   
     475    if libGAP_ReadEvalResult != NULL:
     476        libgap_enter()
     477        libGAP_AssGVar(libGAP_Last3, libGAP_VAL_GVAR(libGAP_Last2))
     478        libGAP_AssGVar(libGAP_Last2, libGAP_VAL_GVAR(libGAP_Last))
     479        libGAP_AssGVar(libGAP_Last, libGAP_ReadEvalResult)
     480        libgap_exit()
     481 
  • sage/matrix/matrix_rational_dense.pyx

    diff --git a/sage/matrix/matrix_rational_dense.pyx b/sage/matrix/matrix_rational_dense.pyx
    a b  
    16671667        return misc.matrix_rational_echelon_form_multimodular(self,
    16681668                                 height_guess=height_guess, proof=proof)
    16691669
    1670     def _echelon_in_place_classical(self):
     1670    def _echelon_in_place_classical(self, steps=None):
    16711671        """
    16721672        Compute the echelon form of self using classical algorithm and
    16731673        set the pivots of self.  This is useful when the input matrix
     
    17011701                    # rescale row r by multiplying by tmp
    17021702                    for i in range(c, nc):
    17031703                        mpq_mul(self._matrix[r][i], self._matrix[r][i], tmp)
     1704                    if steps is not None: steps.append(self.copy())
    17041705                    # swap rows r and start_row
    17051706                    self.swap_rows_c(r, start_row)
     1707                    if steps is not None: steps.append(self.copy())
    17061708                    # clear column
    17071709                    for i in range(nr):
    17081710                        if i != start_row:
     
    17121714                                for j in range(c, nc):
    17131715                                    mpq_mul(tmp2, self._matrix[start_row][j], tmp)
    17141716                                    mpq_add(self._matrix[i][j], self._matrix[i][j], tmp2)
     1717                    if steps is not None: steps.append(self.copy())
    17151718                    start_row += 1
    17161719                    break
    17171720        mpq_clear(tmp); mpq_clear(tmp2)
  • setup.py

    diff --git a/setup.py b/setup.py
    a b  
    932932                     'sage.libs.flint',
    933933                     'sage.libs.lrcalc',
    934934                     'sage.libs.pari',
     935                     'sage.libs.gap',
    935936                     'sage.libs.singular',
    936937                     'sage.libs.symmetrica',
    937938                     'sage.libs.cremona',