Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/interfaces/fricas.py
4056 views
1
r"""
2
Interface to FriCAS
3
4
TODO:
5
6
- Evaluation using a file is not done. Any input line with more than a
7
few thousand characters would hang the system, so currently it
8
automatically raises an exception.
9
10
- All completions of a given command.
11
12
- Interactive help.
13
14
FriCAS is a free GPL-compatible (modified BSD license) general
15
purpose computer algebra system based on Axiom. The FriCAS
16
website can be found at http://fricas.sourceforge.net/.
17
18
AUTHORS:
19
20
- Mike Hansen (2009-02): Split off the FriCAS interface from
21
the Axiom interface.
22
23
If the string "error" (case insensitive) occurs in the output of
24
anything from FriCAS, a RuntimeError exception is raised.
25
26
EXAMPLES: We evaluate a very simple expression in FriCAS.
27
28
::
29
30
sage: fricas('3 * 5') # optional - fricas
31
15
32
sage: a = fricas(3) * fricas(5); a # optional - fricas
33
15
34
35
The type of a is FriCASElement, i.e., an element of the FriCAS
36
interpreter.
37
38
::
39
40
sage: type(a) # optional - fricas
41
<class 'sage.interfaces.fricas.FriCASElement'>
42
sage: a.parent() # optional - fricas
43
FriCAS
44
45
The underlying FriCAS type of a is also available, via the type
46
method::
47
48
sage: a.type() # optional - fricas
49
PositiveInteger
50
51
We factor `x^5 - y^5` in FriCAS in several different ways.
52
The first way yields a FriCAS object.
53
54
::
55
56
sage: F = fricas.factor('x^5 - y^5'); F # optional - fricas
57
4 3 2 2 3 4
58
- (y - x)(y + x y + x y + x y + x )
59
sage: type(F) # optional - fricas
60
<class 'sage.interfaces.fricas.FriCASElement'>
61
sage: F.type() # optional - fricas
62
Factored(Polynomial(Integer))
63
64
Note that FriCAS objects are normally displayed using "ASCII art".
65
66
::
67
68
sage: a = fricas(2/3); a # optional - fricas
69
2
70
-
71
3
72
sage: a = fricas('x^2 + 3/7'); a # optional - fricas
73
2 3
74
x + -
75
7
76
77
The ``fricas.eval`` command evaluates an expression in
78
FriCAS and returns the result as a string. This is exact as if we
79
typed in the given line of code to FriCAS; the return value is what
80
FriCAS would print out.
81
82
::
83
84
sage: print fricas.eval('factor(x^5 - y^5)') # optional - fricas
85
4 3 2 2 3 4
86
- (y - x)(y + x y + x y + x y + x ) Type: Factored(Polynomial(Integer))
87
88
We can create the polynomial `f` as a FriCAS polynomial,
89
then call the factor method on it. Notice that the notation
90
``f.factor()`` is consistent with how the rest of Sage
91
works.
92
93
::
94
95
sage: f = fricas('x^5 - y^5') # optional - fricas
96
sage: f^2 # optional - fricas
97
10 5 5 10
98
y - 2x y + x
99
sage: f.factor() # optional - fricas
100
4 3 2 2 3 4
101
- (y - x)(y + x y + x y + x y + x )
102
103
Control-C interruption works well with the FriCAS interface. For
104
example, try the following sum but with a much bigger range, and hit
105
control-C.
106
107
::
108
109
sage: f = fricas('(x^5 - y^5)^10000') # not tested - fricas
110
Interrupting FriCAS...
111
...
112
<type 'exceptions.TypeError'>: Ctrl-c pressed while running FriCAS
113
114
::
115
116
sage: fricas('1/100 + 1/101') # optional - fricas
117
201
118
-----
119
10100
120
sage: a = fricas('(1 + sqrt(2))^5'); a # optional - fricas
121
+-+
122
29\|2 + 41
123
124
TESTS: We check to make sure the subst method works with keyword
125
arguments.
126
127
::
128
129
sage: a = fricas(x+2); a #optional - fricas
130
x + 2
131
sage: a.subst(x=3) #optional - fricas
132
5
133
134
We verify that FriCAS floating point numbers can be converted to
135
Python floats.
136
137
::
138
139
sage: float(fricas(2)) #optional - fricas
140
2.0
141
"""
142
143
###########################################################################
144
# Copyright (C) 2008 Mike Hansen <[email protected]>
145
# 2007 Bill Page
146
# 2006 William Stein <[email protected]>
147
#
148
# Distributed under the terms of the GNU General Public License (GPL)
149
# The full text of the GPL is available at:
150
#
151
# http://www.gnu.org/licenses/
152
###########################################################################
153
from axiom import PanAxiom, PanAxiomElement, PanAxiomFunctionElement, PanAxiomExpectFunction
154
155
156
class FriCAS(PanAxiom):
157
"""
158
Interface to a FriCAS interpreter.
159
"""
160
def __init__(self, name='fricas', command='fricas -nox -noclef',
161
script_subdirectory=None, logfile=None,
162
server=None, server_tmpdir=None,
163
init_code=[')lisp (si::readline-off)']):
164
"""
165
Create an instance of the FriCAS interpreter.
166
167
TESTS::
168
169
sage: fricas == loads(dumps(fricas))
170
True
171
"""
172
PanAxiom.__init__(self, name, command,
173
script_subdirectory, logfile,
174
server, server_tmpdir,
175
init_code)
176
177
def __repr__(self):
178
"""
179
EXAMPLES::
180
181
sage: fricas
182
FriCAS
183
"""
184
return "FriCAS"
185
186
def __reduce__(self):
187
"""
188
EXAMPLES::
189
190
sage: fricas.__reduce__()
191
(<function reduce_load_fricas at 0x...>, ())
192
sage: f, args = _
193
sage: f(*args)
194
FriCAS
195
"""
196
return reduce_load_fricas, tuple([])
197
198
def _function_class(self):
199
"""
200
Return the FriCASExpectFunction class.
201
202
EXAMPLES::
203
204
sage: fricas._function_class()
205
<class 'sage.interfaces.fricas.FriCASExpectFunction'>
206
sage: type(fricas.gcd)
207
<class 'sage.interfaces.fricas.FriCASExpectFunction'>
208
"""
209
return FriCASExpectFunction
210
211
def _object_class(self):
212
"""
213
EXAMPLES::
214
215
sage: fricas._object_class()
216
<class 'sage.interfaces.fricas.FriCASElement'>
217
sage: type(fricas(2)) #optional - fricas
218
<class 'sage.interfaces.fricas.FriCASElement'>
219
"""
220
return FriCASElement
221
222
def _function_element_class(self):
223
"""
224
Returns the FriCAS function element class.
225
226
EXAMPLES::
227
228
sage: fricas._function_element_class()
229
<class 'sage.interfaces.fricas.FriCASFunctionElement'>
230
sage: type(fricas(2).gcd) #optional - fricas
231
<class 'sage.interfaces.fricas.FriCASFunctionElement'>
232
"""
233
return FriCASFunctionElement
234
235
def console(self):
236
"""
237
Spawn a new FriCAS command-line session.
238
239
EXAMPLES::
240
241
sage: fricas.console() #not tested
242
FriCAS (AXIOM fork) Computer Algebra System
243
Version: FriCAS 1.0.5
244
Timestamp: Thursday February 19, 2009 at 06:57:33
245
-----------------------------------------------------------------------------
246
Issue )copyright to view copyright notices.
247
Issue )summary for a summary of useful system commands.
248
Issue )quit to leave AXIOM and return to shell.
249
-----------------------------------------------------------------------------
250
"""
251
fricas_console()
252
253
class FriCASElement(PanAxiomElement):
254
def _sage_domain(self):
255
"""
256
A helper function for converting FriCAS domains to the corresponding
257
Sage object.
258
259
EXAMPLES::
260
261
sage: fricas('Integer').sage() #optional - fricas
262
Integer Ring
263
sage: fricas('Fraction Integer').sage() #optional - fricas
264
Rational Field
265
sage: fricas('DoubleFloat').sage() #optional - fricas
266
Real Double Field
267
268
"""
269
P = self._check_valid()
270
name = str(self)
271
if name == 'Integer':
272
from sage.rings.all import ZZ
273
return ZZ
274
elif name == 'DoubleFloat':
275
from sage.rings.all import RDF
276
return RDF
277
elif name.startswith('Fraction('):
278
name = name.lstrip('Fraction(')
279
name = name.rstrip(')')
280
return P(name)._sage_domain().fraction_field()
281
282
raise NotImplementedError
283
284
class FriCASFunctionElement(PanAxiomFunctionElement):
285
pass
286
287
class FriCASExpectFunction(PanAxiomExpectFunction):
288
pass
289
290
def is_FriCASElement(x):
291
"""
292
Returns True of x is of type FriCASElement.
293
294
EXAMPLES::
295
296
sage: from sage.interfaces.fricas import is_FriCASElement
297
sage: is_FriCASElement(fricas(2)) #optional - fricas
298
True
299
sage: is_FriCASElement(2)
300
False
301
"""
302
return isinstance(x, FriCASElement)
303
304
fricas = FriCAS(name='fricas', command='fricas -nox -noclef', init_code=[])
305
306
def reduce_load_fricas():
307
"""
308
Returns the FriCAS interface object defined in
309
sage.interfaces.fricas.
310
311
EXAMPLES::
312
313
sage: from sage.interfaces.fricas import reduce_load_fricas
314
sage: reduce_load_fricas()
315
FriCAS
316
"""
317
return fricas
318
319
import os
320
321
def fricas_console():
322
"""
323
Spawn a new FriCAS command-line session.
324
325
EXAMPLES::
326
327
sage: fricas_console() #not tested
328
FriCAS (AXIOM fork) Computer Algebra System
329
Version: FriCAS 1.0.5
330
Timestamp: Thursday February 19, 2009 at 06:57:33
331
-----------------------------------------------------------------------------
332
Issue )copyright to view copyright notices.
333
Issue )summary for a summary of useful system commands.
334
Issue )quit to leave AXIOM and return to shell.
335
-----------------------------------------------------------------------------
336
"""
337
os.system('fricas -nox')
338
339
def __doctest_cleanup():
340
"""
341
EXAMPLES::
342
343
sage: from sage.interfaces.fricas import __doctest_cleanup
344
sage: a = FriCAS()
345
sage: two = a(2) #optional - fricas
346
sage: a.is_running() #optional - fricas
347
True
348
sage: __doctest_cleanup()
349
sage: a.is_running()
350
False
351
"""
352
import sage.interfaces.quit
353
sage.interfaces.quit.expect_quitall()
354
355