Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/interfaces/gap3.py
4045 views
1
r"""
2
Interface to GAP3
3
4
This module implements an interface to GAP3.
5
6
AUTHORS:
7
8
- Franco Saliola (February 2010)
9
10
.. WARNING::
11
12
GAP3 is not distrubuted with Sage. You need to install it
13
separately; see the section `Obtaining GAP3`_.
14
15
Obtaining GAP3
16
--------------
17
18
The GAP3 interface will only work if GAP3 is installed on your computer.
19
Here are some ways to obtain GAP3:
20
21
- There is an optional Sage package providing GAP3 pre-packaged
22
with several GAP3 packages:
23
24
http://trac.sagemath.org/sage_trac/ticket/8906
25
26
- Frank Luebeck maintains a GAP3 Linux executable, optimized
27
for i686 and statically linked for jobs of 2 GByte or more:
28
29
http://www.math.rwth-aachen.de/~Frank.Luebeck/gap/GAP3
30
31
- Jean Michel maintains a version of GAP3 pre-packaged with
32
CHEVIE and VKCURVE. It can be obtained here:
33
34
http://people.math.jussieu.fr/~jmichel/chevie/chevie.html
35
36
- Finally, you can download GAP3 from the GAP website below. Since GAP3
37
is no longer supported, it may not be easy to install this version.
38
39
http://www.gap-system.org/Gap3/Download3/download.html
40
41
Changing which GAP3 is used
42
---------------------------
43
44
.. WARNING::
45
46
There is a bug in the pexpect module (see trac ticket #8471) that
47
prevents the following from working correctly. For now, just make sure
48
that ``gap3`` is in your ``PATH``.
49
50
Sage assumes that GAP3 can be launched with the command ``gap3``; that is,
51
Sage assumes that the command ``gap3`` is in your ``PATH``. If this is not
52
the case, then you can start GAP3 using the following command::
53
54
sage: gap3 = Gap3(command='/usr/local/bin/gap3') #not tested
55
56
Functionality and Examples
57
--------------------------
58
59
The interface to GAP3 offers the following functionality.
60
61
#. ``gap3(expr)`` - Evaluation of arbitrary GAP3 expressions, with the
62
result returned as a Sage object wrapping the corresponding GAP3 element::
63
64
sage: a = gap3('3+2') #optional - gap3
65
sage: a #optional - gap3
66
5
67
sage: type(a) #optional - gap3
68
<class 'sage.interfaces.gap3.GAP3Element'>
69
70
::
71
72
sage: S5 = gap3('SymmetricGroup(5)') #optional - gap3
73
sage: S5 #optional - gap3
74
Group( (1,5), (2,5), (3,5), (4,5) )
75
sage: type(S5) #optional - gap3
76
<class 'sage.interfaces.gap3.GAP3Record'>
77
78
This provides a Pythonic interface to GAP3. If ``gap_function`` is the
79
name of a GAP3 function, then the syntax ``gap_element.gap_function()``
80
returns the ``gap_element`` obtained by evaluating the command
81
``gap_function(gap_element)`` in GAP3::
82
83
sage: S5.Size() #optional - gap3
84
120
85
sage: S5.CharTable() #optional - gap3
86
CharTable( Group( (1,5), (2,5), (3,5), (4,5) ) )
87
88
Alternatively, you can instead use the syntax
89
``gap3.gap_function(gap_element)``::
90
91
sage: gap3.DerivedSeries(S5) #optional - gap3
92
[ Group( (1,5), (2,5), (3,5), (4,5) ),
93
Subgroup( Group( (1,5), (2,5), (3,5), (4,5) ),
94
[ (1,2,5), (1,3,5), (1,4,5) ] ) ]
95
96
If ``gap_element`` corresponds to a GAP3 record, then
97
``gap_element.recfield`` provides a means to access the record element
98
corresponding to the field ``recfield``::
99
100
sage: S5.IsRec() #optional - gap3
101
true
102
sage: S5.recfields() #optional - gap3
103
['isDomain', 'isGroup', 'identity', 'generators', 'operations',
104
'isPermGroup', 'isFinite', '1', '2', '3', '4', 'degree']
105
sage: S5.identity #optional - gap3
106
()
107
sage: S5.degree #optional - gap3
108
5
109
sage: S5.1 #optional - gap3
110
(1,5)
111
sage: S5.2 #optional - gap3
112
(2,5)
113
114
#. By typing ``%gap3`` or ``gap3.interact()`` at the command-line, you can
115
interact directly with the underlying GAP3 session.
116
117
::
118
119
sage: gap3.interact() #not tested
120
121
--> Switching to Gap3 <--
122
123
gap3:
124
125
#. You can start a new GAP3 session as follows::
126
127
sage: gap3.console() #not tested
128
129
######## Lehrstuhl D fuer Mathematik
130
### #### RWTH Aachen
131
## ##
132
## # ####### #########
133
## # ## ## # ##
134
## # # ## # ##
135
#### ## ## # # ##
136
##### ### ## ## ## ##
137
######### # ######### #######
138
# #
139
## Version 3 #
140
### Release 4.4 #
141
## # 18 Apr 97 #
142
## #
143
## # Alice Niemeyer, Werner Nickel, Martin Schoenert
144
## # Johannes Meier, Alex Wegner, Thomas Bischops
145
## # Frank Celler, Juergen Mnich, Udo Polis
146
### ## Thomas Breuer, Goetz Pfeiffer, Hans U. Besche
147
###### Volkmar Felsch, Heiko Theissen, Alexander Hulpke
148
Ansgar Kaup, Akos Seress, Erzsebet Horvath
149
Bettina Eick
150
For help enter: ?<return>
151
gap>
152
153
#. The interface also has access to the GAP3 help system::
154
155
sage: gap3.help('help', pager=False) #not tested
156
Help _______________________________________________________...
157
158
This section describes together with the following sections the GAP
159
help system. The help system lets you read the manual interactively...
160
161
Common Pitfalls
162
---------------
163
164
#. If you want to pass a string to GAP3, then you need to wrap it in
165
single quotes as follows::
166
167
sage: gap3('"This is a GAP3 string"') #optional - gap3
168
"This is a GAP3 string"
169
170
This is particularly important when a GAP3 package is loaded via the
171
``RequirePackage`` method (note that one can instead use the
172
``load_package`` method)::
173
174
sage: gap3.RequirePackage('"chevie"') #optional - gap3chevie
175
W... to the CHEVIE package, ...
176
177
Examples
178
--------
179
180
Load a GAP3 package::
181
182
sage: gap3.load_package("chevie") #optional - gap3chevie
183
sage: gap3.version() # random #optional - gap3
184
'lib: v3r4p4 1997/04/18, src: v3r4p0 1994/07/10, sys: usg gcc ansi'
185
186
Working with GAP3 lists. Note that GAP3 lists are 1-indexed::
187
188
sage: L = gap3([1,2,3]) #optional - gap3
189
sage: L[1] #optional - gap3
190
1
191
sage: L[2] #optional - gap3
192
2
193
sage: 3 in L #optional - gap3
194
True
195
sage: 4 in L #optional - gap3
196
False
197
sage: m = gap3([[1,2],[3,4]]) #optional - gap3
198
sage: m[2,1] #optional - gap3
199
3
200
sage: [1,2] in m #optional - gap3
201
True
202
sage: [3,2] in m #optional - gap3
203
False
204
sage: gap3([1,2]) in m #optional - gap3
205
True
206
207
Controlling variable names used by GAP3::
208
209
sage: gap3('2', name='x') #optional - gap3
210
2
211
sage: gap3('x') #optional - gap3
212
2
213
sage: gap3.unbind('x') #optional - gap3
214
sage: gap3('x') #optional - gap3
215
Traceback (most recent call last):
216
...
217
TypeError: Gap3 produced error output
218
Error, Variable: 'x' must have a value
219
...
220
"""
221
222
#*****************************************************************************
223
# Copyright (C) 2010 Franco Saliola <[email protected]>
224
#
225
# Distributed under the terms of the GNU General Public License (GPL)
226
#
227
# This code is distributed in the hope that it will be useful,
228
# but WITHOUT ANY WARRANTY; without even the implied warranty of
229
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
230
# General Public License for more details.
231
#
232
# The full text of the GPL is available at:
233
#
234
# http://www.gnu.org/licenses/
235
#*****************************************************************************
236
from sage.interfaces.expect import Expect
237
from sage.interfaces.gap import Gap_generic, GapElement_generic
238
239
# gap3_cmd should point to the gap3 executable
240
gap3_cmd = 'gap3'
241
242
class Gap3(Gap_generic):
243
r"""
244
A simple Expect interface to GAP3.
245
246
EXAMPLES::
247
248
sage: from sage.interfaces.gap3 import Gap3
249
sage: gap3 = Gap3(command='gap3')
250
251
TESTS::
252
253
sage: gap3(2) == gap3(3) #optional - gap3
254
False
255
sage: gap3(2) == gap3(2) #optional - gap3
256
True
257
sage: gap3.trait_names() #optional - gap3
258
[]
259
260
We test the interface behaves correctly after a keyboard interrupt::
261
262
sage: gap3(2) #optional - gap3
263
2
264
sage: try:
265
... gap3._keyboard_interrupt()
266
... except:
267
... pass #optional - gap3
268
Interrupting Gap3...
269
sage: gap3(2) #optional - gap3
270
2
271
272
We test that the interface busts out of GAP3's break loop correctly::
273
274
sage: f = gap3('function(L) return L[0]; end;;') #optional - gap3
275
sage: f([1,2,3]) #optional - gap3
276
Traceback (most recent call last):
277
...
278
RuntimeError: Gap3 produced error output
279
Error, List Element: <position> must be a positive integer at
280
return L[0] ...
281
282
AUTHORS:
283
284
- Franco Saliola (Feb 2010)
285
"""
286
def __init__(self, command=gap3_cmd):
287
r"""
288
Initialize the GAP3 interface and start a session.
289
290
INPUT:
291
292
- command - string (default "gap3"); points to the gap3
293
executable on your system; by default, it is assumed the
294
executable is in your path.
295
296
EXAMPLES::
297
298
sage: gap3 = Gap3() #optional - gap3
299
sage: gap3.is_running()
300
False
301
sage: gap3._start() #optional - gap3
302
sage: gap3.is_running() #optional - gap3
303
True
304
"""
305
self.__gap3_command_string = command
306
# Explanation of additional command-line options passed to gap3:
307
#
308
# -p invokes the internal programmatic interace, which is how Sage
309
# talks to GAP4. This allows reuse some of the GAP4 interface code.
310
#
311
# -y -- sets the number of lines of the terminal; controls how many
312
# lines of text are output by GAP3 before the pager is invoked.
313
# This option is useful in dealing with the GAP3 help system.
314
Expect.__init__(self,
315
name='gap3',
316
prompt='gap> ',
317
command=self.__gap3_command_string + " -p -y 500",
318
server=None,
319
ulimit=None,
320
maxread=100000,
321
script_subdirectory=None,
322
restart_on_ctrlc=True,
323
verbose_start=False,
324
init_code=[],
325
max_startup_time=None,
326
logfile=None,
327
eval_using_file_cutoff=100,
328
do_cleaner=True,
329
remote_cleaner=False,
330
path=None)
331
332
def _start(self):
333
r"""
334
EXAMPLES::
335
336
sage: gap3 = Gap3() #optional - gap3
337
sage: gap3.is_running()
338
False
339
sage: gap3._start() #optional - gap3
340
sage: gap3.is_running() #optional - gap3
341
True
342
sage: gap3.quit() #optional - gap3
343
"""
344
n = self._session_number
345
Expect._start(self)
346
# The -p command-line option to GAP3 produces the following
347
# funny-looking patterns in the interface. We compile the patterns
348
# now, and use them later for interpreting interface messages.
349
self._compiled_full_pattern = self._expect.compile_pattern_list([
350
'@p\d+\.','@@','@[A-Z]','@[123456!"#$%&][^+]*\+', '@e','@c',
351
'@f','@h','@i','@m','@n','@r','@s\d','@w.*\+','@x','@z'])
352
self._compiled_small_pattern = self._expect.compile_pattern_list('@J')
353
354
def _object_class(self):
355
r"""
356
Return the class used for constructing GAP3 elements.
357
358
TESTS::
359
sage: gap3._object_class()
360
<class 'sage.interfaces.gap3.GAP3Element'>
361
"""
362
return GAP3Element
363
364
def _execute_line(self, line, wait_for_prompt=True, expect_eof=False):
365
r"""
366
Execute a line of code in GAP3 and parse the output.
367
368
TESTS:
369
370
Test that syntax errors are handled correctly::
371
372
sage: gap3('syntax error', name='x') #optional - gap3
373
Traceback (most recent call last):
374
...
375
TypeError: Gap3 produced error output
376
Syntax error: ; expected
377
x:=syntax error;
378
^
379
gap>
380
...
381
382
Test that error messages are detected and reported correctly::
383
384
sage: gap3.SymmetricGroup(5,3) #optional - gap3
385
Traceback (most recent call last):
386
...
387
RuntimeError: Gap3 produced error output
388
Error, Record: left operand must be a record at
389
return arg[1].operations.SymmetricGroup( arg[1], arg[2] ) ... in
390
SymmetricGroup( ..., ... ) called from
391
main loop
392
brk> quit;
393
...
394
395
Test that break loops are detected and exited properly::
396
397
sage: f = gap3('function(L) return L[0]; end;;') #optional - gap3
398
sage: f([1,2,3]) #optional - gap3
399
Traceback (most recent call last):
400
...
401
RuntimeError: Gap3 produced error output
402
Error, List Element: <position> must be a positive integer at
403
return L[0] ... in
404
... called from
405
main loop
406
brk> quit;
407
...
408
"""
409
# It seems that GAP3 does not classify syntax errors as regular error
410
# messages, so the generic GAP interface processing code does not
411
# detect it. So we test for a syntax error explicitly.
412
normal_output, error_output = \
413
super(Gap3, self)._execute_line(line, wait_for_prompt=True, expect_eof=False)
414
if normal_output.startswith("Syntax error:"):
415
normal_output, error_output = "", normal_output
416
return (normal_output, error_output)
417
418
def help(self, topic, pager=True):
419
r"""
420
Print help on the given topic.
421
422
INPUT:
423
424
- ``topic`` -- string
425
426
EXAMPLES::
427
428
sage: gap3.help('help', pager=False) #optional - gap3
429
Help _______________________________________________________...
430
<BLANKLINE>
431
This section describes together with the following sectio...
432
help system. The help system lets you read the manual inter...
433
434
::
435
436
sage: gap3.help('SymmetricGroup', pager=False) #optional - gap3
437
no section with this name was found
438
439
TESTS::
440
441
sage: m = gap3([[1,2,3],[4,5,6]]); m #optional - gap3
442
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
443
sage: gap3.help('help', pager=False) #optional - gap3
444
Help _______________________________________________________...
445
sage: m #optional - gap3
446
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
447
sage: m.Print() #optional - gap3
448
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
449
sage: gap3.help('Group', pager=False) #optional - gap3
450
Group ______________________________________________________...
451
sage: m #optional - gap3
452
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
453
sage: m.Print() #optional - gap3
454
[ [ 1, 2, 3 ], [ 4, 5, 6 ] ]
455
"""
456
457
import pexpect
458
if self._expect is None:
459
self._start()
460
E = self._expect
461
helptext = []
462
463
# we request the help document
464
E.sendline("? %s" % topic)
465
# it seems necessary to skip TWO echoes (as is done in the GAP4 interface)
466
E.expect("\r\n")
467
E.expect("\r\n")
468
469
# next we process the help document; translating special characters, etc.
470
while True:
471
try:
472
x = E.expect_list(self._compiled_full_pattern, timeout=2)
473
except pexpect.TIMEOUT:
474
break
475
if x == 1:
476
# matched @@; replace with @
477
helptext.append('@')
478
helptext.append(E.before)
479
elif x == 2:
480
# matched a special char; convert and insert
481
helptext.append(chr(ord(E.after[1:2])-ord('A')+1))
482
helptext.append(E.before)
483
elif x == 10:
484
# matched @n (normal input mode); it seems we're done
485
break
486
elif x==11:
487
# matched @r (echoing input); skip to end of line
488
E.expect_list(self._compiled_small_pattern)
489
490
# merge the help text into one string and print it.
491
helptext = "".join(helptext).strip()
492
if pager is True:
493
import IPython.genutils
494
IPython.genutils.page(helptext)
495
else:
496
print helptext
497
498
def cputime(self, t=None):
499
r"""
500
Returns the amount of CPU time that the GAP session has used in
501
seconds. If ``t`` is not None, then it returns the difference
502
between the current CPU time and ``t``.
503
504
EXAMPLES::
505
506
sage: t = gap3.cputime() #optional - gap3
507
sage: t #random #optional - gap3
508
0.02
509
sage: gap3.SymmetricGroup(5).Size() #optional - gap3
510
120
511
sage: gap3.cputime() #random #optional - gap3
512
0.14999999999999999
513
sage: gap3.cputime(t) #random #optional - gap3
514
0.13
515
"""
516
if t is not None:
517
return self.cputime() - t
518
else:
519
return eval(self.eval('Runtime();'))/1000.0
520
521
def console(self):
522
r"""
523
Spawn a new GAP3 command-line session.
524
525
EXAMPLES::
526
527
sage: gap3.console() #not tested
528
529
######## Lehrstuhl D fuer Mathematik
530
### #### RWTH Aachen
531
## ##
532
## # ####### #########
533
## # ## ## # ##
534
## # # ## # ##
535
#### ## ## # # ##
536
##### ### ## ## ## ##
537
######### # ######### #######
538
# #
539
## Version 3 #
540
### Release 4.4 #
541
## # 18 Apr 97 #
542
## #
543
## # Alice Niemeyer, Werner Nickel, Martin Schoenert
544
## # Johannes Meier, Alex Wegner, Thomas Bischops
545
## # Frank Celler, Juergen Mnich, Udo Polis
546
### ## Thomas Breuer, Goetz Pfeiffer, Hans U. Besche
547
###### Volkmar Felsch, Heiko Theissen, Alexander Hulpke
548
Ansgar Kaup, Akos Seress, Erzsebet Horvath
549
Bettina Eick
550
For help enter: ?<return>
551
gap>
552
"""
553
os.system(self.__gap3_command_string)
554
555
def _install_hints(self):
556
r"""
557
558
TESTS::
559
560
sage: gap3 = Gap3(command='/wrongpath/gap3')
561
sage: gap3('3+2')
562
Traceback (most recent call last):
563
...
564
TypeError: Unable to start gap3 because the command ... failed.
565
<BLANKLINE>
566
Your attempt to start GAP3 failed, either because you do not have
567
have GAP3 installed, or because it is not configured correctly.
568
<BLANKLINE>
569
- If you do not have GAP3 installed, then you must download ...
570
sage: print gap3._install_hints()
571
<BLANKLINE>
572
Your attempt to start GAP3 failed, either because you do not have
573
have GAP3 installed, or because it is not configured correctly.
574
<BLANKLINE>
575
- If you do not have GAP3 installed, then you must download ...
576
"""
577
return r"""
578
Your attempt to start GAP3 failed, either because you do not have
579
have GAP3 installed, or because it is not configured correctly.
580
581
- If you do not have GAP3 installed, then you must download and
582
install it yourself because it is not distrubuted with Sage.
583
Here are some ways to obtain GAP3:
584
585
- There is an optional Sage package providing GAP3 pre-packaged
586
with several GAP3 packages:
587
http://trac.sagemath.org/sage_trac/ticket/8906
588
589
- Frank Luebeck maintains a GAP3 Linux executable, optimized
590
for i686 and statically linked for jobs of 2 GByte or more:
591
http://www.math.rwth-aachen.de/~Frank.Luebeck/gap/GAP3
592
593
- Jean Michel maintains a version of GAP3 pre-packaged with
594
CHEVIE and VKCURVE. It can be obtained here:
595
http://people.math.jussieu.fr/~jmichel/chevie/chevie.html
596
597
- Finally, you can download GAP3 from the GAP website below. Since
598
GAP3 is no longer an officially supported distribution of GAP, it
599
may not be easy to install this version.
600
http://www.gap-system.org/Gap3/Download3/download.html
601
602
- If you have GAP3 installed, then perhaps it is not configured
603
correctly. Sage assumes that you can start GAP3 with the command
604
%s. Alternatively, you can use the following command
605
to point Sage to the correct command for your system.
606
607
gap3 = Gap3(command='/usr/local/bin/gap3')
608
""" % self.__gap3_command_string
609
610
gap3 = Gap3()
611
612
class GAP3Element(GapElement_generic):
613
r"""
614
A GAP3 element
615
616
.. NOTE::
617
618
If the corresponding GAP3 element is a GAP3 record,
619
then the class is changed to a ``GAP3Record``.
620
621
INPUT:
622
623
- ``parent`` -- the GAP3 session
624
625
- ``value`` -- the GAP3 command as a string
626
627
- ``is_name`` -- bool (default: False); if True, then ``value`` is
628
the variable name for the object
629
630
- ``name`` -- str (default: ``None``); the variable name to use for the
631
object. If ``None``, then a variable name is generated.
632
633
.. NOTE::
634
635
If you pass ``E``, ``X`` or ``Z`` for ``name``, then an error is
636
raised because these are sacred variable names in GAP3 that should
637
never be redefined. Sage raises an error because GAP3 does not!
638
639
EXAMPLES::
640
641
sage: from sage.interfaces.gap3 import GAP3Element #optional - gap3
642
sage: gap3 = Gap3() #optional - gap3
643
sage: GAP3Element(gap3, value='3+2') #optional - gap3
644
5
645
sage: GAP3Element(gap3, value='sage0', is_name=True) #optional - gap3
646
5
647
648
TESTS::
649
650
sage: GAP3Element(gap3, value='3+2', is_name=False, name='X') #optional - gap3
651
Traceback (most recent call last):
652
...
653
ValueError: you are attempting to redefine X; but you should never redefine E, X or Z in gap3 (because things will break!)
654
655
AUTHORS:
656
657
- Franco Saliola (Feb 2010)
658
"""
659
def __init__(self, parent, value, is_name=False, name=None):
660
r"""
661
See ``GAP3Element`` for full documentation.
662
663
EXAMPLES::
664
665
sage: from sage.interfaces.gap3 import GAP3Element #optional - gap3
666
sage: gap3 = Gap3() #optional - gap3
667
sage: GAP3Element(gap3, value='3+2') #optional - gap3
668
5
669
sage: GAP3Element(gap3, value='sage0', is_name=True) #optional - gap3
670
5
671
672
TESTS::
673
674
sage: GAP3Element(gap3, value='3+2', is_name=False, name='X') #optional - gap3
675
Traceback (most recent call last):
676
...
677
ValueError: you are attempting to redefine X; but you should never redefine E, X or Z in gap3 (because things will break!)
678
"""
679
# Warning: One should not redefine E, X or Z in gap3, because
680
# things will break, but gap3 raises no errors if one does this!
681
if name in ["E","X","Z"]:
682
raise ValueError, "you are attempting to redefine %s; but you should never redefine E, X or Z in gap3 (because things will break!)" % name
683
684
# initialize the superclass
685
super(GAP3Element, self).__init__(parent, value, is_name, name)
686
687
# check for a GAP record; if so then change the class
688
if parent.eval("IsRec(%s)" % self._name) == "true":
689
self.__class__ = GAP3Record
690
691
def __getitem__(self, n):
692
r"""
693
EXAMPLES::
694
695
sage: l = gap3('[1,2,3]') #optional - gap3
696
sage: l[1] #optional - gap3
697
1
698
sage: a = gap3([1,2,3]) #optional - gap3
699
sage: a[1] #optional - gap3
700
1
701
sage: m = gap3([[1,2,3],[4,5,6],[7,8,9]]) #optional - gap3
702
sage: m[1,3] #optional - gap3
703
3
704
sage: m[2][1] #optional - gap3
705
4
706
"""
707
gap3_session = self._check_valid()
708
if not isinstance(n, tuple):
709
return gap3_session.new('%s[%s]'%(self.name(), n))
710
else:
711
return gap3_session.new('%s%s'%(self.name(), ''.join(['[%s]'%x for x in n])))
712
713
def _latex_(self):
714
r"""
715
EXAMPLES::
716
717
sage: s = gap("[[1,2], [3/4, 5/6]]")
718
sage: s._latex_()
719
'\\left(\\begin{array}{rr} 1&2\\\\ 3/4&\\frac{5}{6}\\\\ \\end{array}\\right)'
720
sage: latex(s)
721
\left(\begin{array}{rr} 1&2\\ 3/4&\frac{5}{6}\\ \end{array}\right)
722
"""
723
gap3_session = self._check_valid()
724
try:
725
s = gap3_session.eval('FormatLaTeX(%s)'%self.name())
726
s = s.replace('\\\\','\\').replace('"','')
727
s = s.replace('%\\n',' ')
728
return s
729
except RuntimeError:
730
return str(self)
731
732
class GAP3Record(GAP3Element):
733
r"""
734
A GAP3 record
735
736
.. NOTE::
737
738
This class should not be called directly, use GAP3Element instead.
739
If the corresponding GAP3 element is a GAP3 record, then the class
740
is changed to a ``GAP3Record``.
741
742
AUTHORS:
743
744
- Franco Saliola (Feb 2010)
745
"""
746
def recfields(self):
747
r"""
748
Return a list of the fields for the record. (Record fields are akin
749
to object attributes in Sage.)
750
751
OUTPUT:
752
753
- list of strings - the field records
754
755
EXAMPLES::
756
757
sage: S5 = gap3.SymmetricGroup(5) #optional - gap3
758
sage: S5.recfields() #optional - gap3
759
['isDomain', 'isGroup', 'identity', 'generators',
760
'operations', 'isPermGroup', 'isFinite', '1', '2',
761
'3', '4', 'degree']
762
sage: S5.degree #optional - gap3
763
5
764
"""
765
gap3_session = self._check_valid()
766
if not hasattr(self, "_gap_recfields"):
767
s = str(gap3_session.eval("RecFields(%s)" % self._name))
768
s = s.strip('[] ').replace('\n','')
769
self._gap_recfields = [ss.strip('" ') for ss in s.split(',')]
770
return getattr(self,"_gap_recfields")
771
772
def operations(self):
773
r"""
774
Return a list of the GAP3 operations for the record.
775
776
OUTPUT:
777
778
- list of strings - operations of the record
779
780
EXAMPLES::
781
782
sage: S5 = gap3.SymmetricGroup(5) #optional - gap3
783
sage: S5.operations() #optional - gap3
784
[..., 'NormalClosure', 'NormalIntersection', 'Normalizer',
785
'NumberConjugacyClasses', 'PCore', 'Radical', 'SylowSubgroup',
786
'TrivialSubgroup', 'FusionConjugacyClasses', 'DerivedSeries', ...]
787
sage: S5.DerivedSeries() #optional - gap3
788
[ Group( (1,5), (2,5), (3,5), (4,5) ),
789
Subgroup( Group( (1,5), (2,5), (3,5), (4,5) ),
790
[ (1,2,5), (1,3,5), (1,4,5) ] ) ]
791
"""
792
gap3_session = self._check_valid()
793
if not hasattr(self,"_gap_operations"):
794
s = str(gap3_session.eval("RecFields(%s.operations)" % self._name))
795
s = s.strip('[] ').replace('\n','')
796
self._gap_operations = [ss.strip('" ') for ss in s.split(',')]
797
return getattr(self,"_gap_operations")
798
799
def __getattr__(self, attrname):
800
r"""
801
OUTPUT:
802
803
- ``GAP3Record`` -- if ``attrname`` is a field of the GAP record
804
805
- ``ExpectFunction`` -- if ``attrname`` is the name of a GAP3 function
806
807
EXAMPLES::
808
809
sage: S5 = gap3.SymmetricGroup(5) #optional - gap3
810
sage: S5.__getattr__('Size') #optional - gap3
811
Size
812
sage: gap3.IsFunc(S5.__getattr__('Size')) #optional - gap3
813
true
814
sage: S5.__getattr__('generators') #optional - gap3
815
[ (1,5), (2,5), (3,5), (4,5) ]
816
"""
817
gap3_session = self._check_valid()
818
if attrname[:1] == "_":
819
raise AttributeError
820
if attrname in self.recfields():
821
return gap3_session.new('%s.%s' % (self.name(), attrname))
822
return gap3_session._function_element_class()(self, attrname)
823
824
def trait_names(self):
825
r"""
826
Defines the list of methods and attributes that will appear for tab
827
completion.
828
829
OUTPUT:
830
831
- list of strings -- the available fields and operations of the
832
record
833
834
EXAMPLES::
835
836
sage: S5 = gap3.SymmetricGroup(5) #optional - gap3
837
sage: S5.trait_names() #optional - gap3
838
[..., 'ConjugacyClassesTry', 'ConjugateSubgroup', 'ConjugateSubgroups',
839
'Core', 'DegreeOperation', 'DerivedSeries', 'DerivedSubgroup',
840
'Difference', 'DimensionsLoewyFactors', 'DirectProduct', ...]
841
"""
842
if not hasattr(self, "__trait_names"):
843
self.__trait_names = self.recfields() + self.operations()
844
self.__trait_names.sort()
845
return self.__trait_names
846
847
848
import os
849
def gap3_console():
850
r"""
851
Spawn a new GAP3 command-line session.
852
853
EXAMPLES::
854
855
sage: gap3.console() #not tested
856
857
######## Lehrstuhl D fuer Mathematik
858
### #### RWTH Aachen
859
## ##
860
## # ####### #########
861
## # ## ## # ##
862
## # # ## # ##
863
#### ## ## # # ##
864
##### ### ## ## ## ##
865
######### # ######### #######
866
# #
867
## Version 3 #
868
### Release 4.4 #
869
## # 18 Apr 97 #
870
## #
871
## # Alice Niemeyer, Werner Nickel, Martin Schoenert
872
## # Johannes Meier, Alex Wegner, Thomas Bischops
873
## # Frank Celler, Juergen Mnich, Udo Polis
874
### ## Thomas Breuer, Goetz Pfeiffer, Hans U. Besche
875
###### Volkmar Felsch, Heiko Theissen, Alexander Hulpke
876
Ansgar Kaup, Akos Seress, Erzsebet Horvath
877
Bettina Eick
878
For help enter: ?<return>
879
gap>
880
"""
881
os.system(gap3_cmd)
882
883
def gap3_version():
884
r"""
885
Return the version of GAP3 that you have in your PATH on your computer.
886
887
EXAMPLES::
888
889
sage: gap3_version() # random, optional - gap3
890
'lib: v3r4p4 1997/04/18, src: v3r4p0 1994/07/10, sys: usg gcc ansi'
891
"""
892
return gap3.eval('VERSION')[1:-1]
893
894