Annotation of OpenXM/src/sage/asir.py, Revision 1.2
1.2 ! takayama 1: # $OpenXM: OpenXM/src/sage/asir.py,v 1.1 2018/09/08 05:35:35 takayama Exp $
1.1 takayama 2: from __future__ import print_function
3: from __future__ import absolute_import
4:
5: import os
1.2 ! takayama 6: from sage.interfaces.expect import Expect, ExpectElement
1.1 takayama 7: from sage.misc.misc import verbose
8:
1.2 ! takayama 9: ##Ref: @s/2018/09/20180907-sage-asir-proj, Using External Libraries and Interfaces
! 10: ##Ref: /usr/lib/python2.7/dist-packages/sage/interfaces
! 11: ##Usage: load("asir.py");
! 12:
1.1 takayama 13: class Asir(Expect):
14: r"""
15: Interface to the Asir interpreter.
16:
17: EXAMPLES::
18:
1.2 ! takayama 19: sage: asir.eval("F=fctr(x^10-1)") # optional - asir
1.1 takayama 20: """
21:
22: def __init__(self, maxread=None, script_subdirectory=None, logfile=None,
23: server=None, server_tmpdir=None, seed=None, command=None):
24: """
25: EXAMPLES::
26:
27: sage: asir == loads(dumps(asir))
28: True
29: """
30: if command is None:
31: import os
32: command = os.getenv('SAGE_ASIR_COMMAND') or 'openxm ox_texmacs --view sage --quiet --noCopyright'
33: if server is None:
34: import os
35: server = os.getenv('SAGE_ASIR_SERVER') or None
36: Expect.__init__(self,
37: name = 'asir',
38: # We want the prompt sequence to be unique to avoid confusion with syntax error messages containing >>>
39: prompt = 'asir>',
40: # We don't want any pagination of output
41: command = 'openxm ox_texmacs --view sage --quiet --noCopyright',
42: maxread = maxread,
43: server = server,
44: server_tmpdir = server_tmpdir,
45: script_subdirectory = script_subdirectory,
46: restart_on_ctrlc = False,
47: verbose_start = False,
48: logfile = logfile,
49: eval_using_file_cutoff=100)
50: self._seed = seed
51:
52: def set_seed(self, seed=None):
53: """
1.2 ! takayama 54: Not implemented. Sets the seed for the random number generator
1.1 takayama 55: for this asir interpreter.
1.2 ! takayama 56: """
! 57: return 0
1.1 takayama 58:
59: def __reduce__(self):
60: """
61: EXAMPLES::
62:
63: sage: asir.__reduce__()
64: (<function reduce_load_Asir at 0x...>, ())
65: """
66: return reduce_load_Asir, tuple([])
67:
68: def _read_in_file_command(self, filename):
69: """
70: EXAMPLES::
71:
72: sage: filename = tmp_filename()
73: sage: asir._read_in_file_command(filename)
1.2 ! takayama 74: 'load("...");'
1.1 takayama 75: """
1.2 ! takayama 76: return 'load("%s");'%filename
1.1 takayama 77:
78: def _quit_string(self):
79: """
80: EXAMPLES::
81:
82: sage: asir._quit_string()
83: 'quit;'
84: """
85: return '!quit;'
86:
87: def _install_hints(self):
88: """
89: Returns hints on how to install Asir.
90:
91: EXAMPLES::
92:
93: sage: print(asir._install_hints())
94: You must get ...
95: """
96: return """
1.2 ! takayama 97: You must get the program "asir" and "ox_texmacs" in order to use Asir
1.1 takayama 98: from Sage. You can read all about Asir at
1.2 ! takayama 99: http://www.openxm.org
! 100: The command openxm must be in the search path.
1.1 takayama 101: """
102:
103: def _eval_line(self, line, reformat=True, allow_use_file=False,
104: wait_for_prompt=True, restart_if_needed=False):
105: """
106: EXAMPLES::
107:
108: sage: print(asir._eval_line('2+2')) #optional - asir
1.2 ! takayama 109: '4'
1.1 takayama 110: """
111: from pexpect.exceptions import EOF
112: if not wait_for_prompt:
113: return Expect._eval_line(self, line)
114: if line == '':
115: return ''
116: if self._expect is None:
117: self._start()
118: if allow_use_file and len(line)>3000:
119: return self._eval_line_using_file(line)
120: try:
121: E = self._expect
122: # debug
123: # self._synchronize(cmd='1+%s\n')
124: verbose("in = '%s'"%line,level=3)
125: E.sendline(line)
126: E.expect(self._prompt)
127: out = E.before
128: # debug
129: verbose("out = '%s'"%out,level=3)
130: except EOF:
131: if self._quit_string() in line:
132: return ''
133: except KeyboardInterrupt:
134: self._keyboard_interrupt()
135: try:
136: if reformat:
137: if 'syntax error' in out:
138: raise SyntaxError(out)
139: out = "\n".join(out.splitlines()[1:])
140: return out
141: except NameError:
142: return ''
143:
144: def _keyboard_interrupt(self):
1.2 ! takayama 145: print("Ctrl-C: Interrupting %s..."%self)
1.1 takayama 146: if self._restart_on_ctrlc:
147: try:
148: self._expect.close(force=1)
149: except pexpect.ExceptionPexpect as msg:
150: raise RuntimeError( "THIS IS A BUG -- PLEASE REPORT. This should never happen.\n" + msg)
151: self._start()
152: raise KeyboardInterrupt("Restarting %s (WARNING: all variables defined in previous session are now invalid)"%self)
153: else:
154: self._expect.send('\003') # control-c
155: raise KeyboardInterrupt("Ctrl-c pressed while running %s"%self)
156:
157: def quit(self, verbose=False):
158: """
159: EXAMPLES::
160:
161: sage: o = Asir()
162: sage: o._start() # optional - asir
163: sage: o.quit(True) # optional - asir
164: Exiting spawned Asir process.
165: """
166: # Don't bother, since it just hangs in some cases, and it
167: # isn't necessary, since asir behaves well with respect
168: # to signals.
169: if not self._expect is None:
170: if verbose:
171: print("Exiting spawned %s process." % self)
172: return
173:
174: def _start(self):
175: """
176: Starts the Asir process.
177:
178: EXAMPLES::
179:
180: sage: o = Asir() # optional - asir
181: sage: o.is_running() # optional - asir
182: False
183: sage: o._start() # optional - asir
184: sage: o.is_running() # optional - asir
185: True
186: """
187: Expect._start(self)
188: # self.eval("page_screen_output=0;")
189: # self.eval("format none;")
190: # set random seed
191: # self.set_seed(self._seed)
192:
193: def _equality_symbol(self):
194: """
195: EXAMPLES::
196:
197: sage: asir('0 == 1') # optional - asir
198: 0
199: sage: asir('1 == 1') # optional - asir
200: 1
201: """
202: return '=='
203:
204: def _true_symbol(self):
205: """
206: EXAMPLES::
207:
208: sage: asir('1 == 1') # optional - asir
209: 1
210: """
211: return '1'
212:
213: def _false_symbol(self):
214: """
215: EXAMPLES::
216:
217: sage: asir('0 == 1') # optional - asir
218: 0
219: """
220: return '0'
221:
222: def set(self, var, value):
223: """
224: Set the variable ``var`` to the given ``value``.
225:
226: EXAMPLES::
227:
1.2 ! takayama 228: sage: asir.set('X', '2') # optional - asir
! 229: sage: asir.get('X') # optional - asir
1.1 takayama 230: ' 2'
231: """
232: cmd = '%s=%s;'%(var,value)
233: out = self.eval(cmd)
234: if out.find("error") != -1 or out.find("Error") != -1:
235: raise TypeError("Error executing code in Asir\nCODE:\n\t%s\nAsir ERROR:\n\t%s"%(cmd, out))
236:
237: def get(self, var):
238: """
239: Get the value of the variable ``var``.
240:
241: EXAMPLES::
242:
1.2 ! takayama 243: sage: asir.set('X', '2') # optional - asir
! 244: sage: asir.get('X') # optional - asir
1.1 takayama 245: ' 2'
246: """
247: s = self.eval('%s;'%var)
248: i = s.find('=')
249: return s[i+1:]
250:
251: def console(self):
252: """
253: Spawn a new Asir command-line session.
254:
255: This requires that the optional asir program be installed and in
256: your PATH, but no optional Sage packages need be installed.
257:
258: EXAMPLES::
259:
1.2 ! takayama 260: sage: asir_console()
! 261: This is Risa/Asir, ....
1.1 takayama 262: ...
1.2 ! takayama 263: [nnnn] 2+3;
! 264: 5
! 265: [nnnn] quit();
! 266:
! 267: quit(); exits the asir console and returns you to Sage.
1.1 takayama 268: """
269: asir_console()
270:
271: def version(self):
272: """
273: Return the version of Asir.
1.2 ! takayama 274: bug: it returns error because sage tries to set sage0=version();
! 275: insread of Sage0=version();
1.1 takayama 276: OUTPUT: string
277:
278: EXAMPLES::
279:
280: sage: v = asir.version() # optional - asir
281: sage: v # optional - asir; random
282: '2.13.7'
283:
284: """
285: return str(self("version()")).strip()
286:
287: def _object_class(self):
288: """
289: EXAMPLES::
290:
291: sage: asir._object_class()
292: <class 'sage.interfaces.asir.AsirElement'>
293: """
294: return AsirElement
295:
296:
297: asir_functions = set()
298:
1.2 ! takayama 299: #Todo, the following class has not yet been implemented.
! 300: # These are sample interface with octave.
1.1 takayama 301: class AsirElement(ExpectElement):
302: def _get_sage_ring(self):
303: r"""
304: TESTS::
305:
306: sage: asir('1')._get_sage_ring() # optional - asir
307: Real Double Field
308: sage: asir('I')._get_sage_ring() # optional - asir
309: Complex Double Field
310: sage: asir('[]')._get_sage_ring() # optional - asir
311: Real Double Field
312: """
313: if self.isinteger():
314: import sage.rings.integer_ring
315: return sage.rings.integer_ring.ZZ
316: elif self.isreal():
317: import sage.rings.real_double
318: return sage.rings.real_double.RDF
319: elif self.iscomplex():
320: import sage.rings.complex_double
321: return sage.rings.complex_double.CDF
322: else:
323: raise TypeError("no Sage ring associated to this element.")
324:
325: def __nonzero__(self):
326: r"""
327: Test whether this element is nonzero.
328:
329: EXAMPLES::
330:
331: sage: bool(asir('0')) # optional - asir
332: False
333: sage: bool(asir('[]')) # optional - asir
334: False
335: sage: bool(asir('[0,0]')) # optional - asir
336: False
337: sage: bool(asir('[0,0,0;0,0,0]')) # optional - asir
338: False
339:
340: sage: bool(asir('0.1')) # optional - asir
341: True
342: sage: bool(asir('[0,1,0]')) # optional - asir
343: True
344: sage: bool(asir('[0,0,-0.1;0,0,0]')) # optional - asir
345: True
346: """
347: return str(self) != ' [](0x0)' and any(x != '0' for x in str(self).split())
348:
349: def _matrix_(self, R=None):
350: r"""
351: Return Sage matrix from this asir element.
352:
353: EXAMPLES::
354:
355: sage: A = asir('[1,2;3,4.5]') # optional - asir
356: sage: matrix(A) # optional - asir
357: [1.0 2.0]
358: [3.0 4.5]
359: sage: _.base_ring() # optional - asir
360: Real Double Field
361:
362: sage: A = asir('[I,1;-1,0]') # optional - asir
363: sage: matrix(A) # optional - asir
364: [1.0*I 1.0]
365: [ -1.0 0.0]
366: sage: _.base_ring() # optional - asir
367: Complex Double Field
368:
369: sage: A = asir('[1,2;3,4]') # optional - asir
370: sage: matrix(ZZ, A) # optional - asir
371: [1 2]
372: [3 4]
373: sage: A = asir('[1,2;3,4.5]') # optional - asir
374: sage: matrix(RR, A) # optional - asir
375: [1.00000000000000 2.00000000000000]
376: [3.00000000000000 4.50000000000000]
377: """
378: if not self.ismatrix():
379: raise TypeError('not an asir matrix')
380: if R is None:
381: R = self._get_sage_ring()
382:
383: s = str(self).strip('\n ')
384: w = [u.strip().split(' ') for u in s.split('\n')]
385: nrows = len(w)
386: ncols = len(w[0])
387:
388: if self.iscomplex():
389: w = [[to_complex(x,R) for x in row] for row in w]
390:
391: from sage.matrix.all import MatrixSpace
392: return MatrixSpace(R, nrows, ncols)(w)
393:
394: def _vector_(self, R=None):
395: r"""
396: Return Sage vector from this asir element.
397:
398: EXAMPLES::
399:
400: sage: A = asir('[1,2,3,4]') # optional - asir
401: sage: vector(ZZ, A) # optional - asir
402: (1, 2, 3, 4)
403: sage: A = asir('[1,2.3,4.5]') # optional - asir
404: sage: vector(A) # optional - asir
405: (1.0, 2.3, 4.5)
406: sage: A = asir('[1,I]') # optional - asir
407: sage: vector(A) # optional - asir
408: (1.0, 1.0*I)
409: """
410: oc = self.parent()
411: if not self.isvector():
412: raise TypeError('not an asir vector')
413: if R is None:
414: R = self._get_sage_ring()
415:
416: s = str(self).strip('\n ')
417: w = s.strip().split(' ')
418: nrows = len(w)
419:
420: if self.iscomplex():
421: w = [to_complex(x, R) for x in w]
422:
423: from sage.modules.free_module import FreeModule
424: return FreeModule(R, nrows)(w)
425:
426: def _scalar_(self):
427: """
428: Return Sage scalar from this asir element.
429:
430: EXAMPLES::
431:
432: sage: A = asir('2833') # optional - asir
433: sage: As = A.sage(); As # optional - asir
434: 2833.0
435: sage: As.parent() # optional - asir
436: Real Double Field
437:
438: sage: B = sqrt(A) # optional - asir
439: sage: Bs = B.sage(); Bs # optional - asir
440: 53.2259
441: sage: Bs.parent() # optional - asir
442: Real Double Field
443:
444: sage: C = sqrt(-A) # optional - asir
445: sage: Cs = C.sage(); Cs # optional - asir
446: 53.2259*I
447: sage: Cs.parent() # optional - asir
448: Complex Double Field
449: """
450: if not self.isscalar():
451: raise TypeError("not an asir scalar")
452:
453: R = self._get_sage_ring()
454: if self.iscomplex():
455: return to_complex(str(self), R)
456: else:
457: return R(str(self))
458:
459: def _sage_(self):
460: """
461: Try to parse the asir object and return a sage object.
462:
463: EXAMPLES::
464:
465: sage: A = asir('2833') # optional - asir
466: sage: A.sage() # optional - asir
467: 2833.0
468: sage: B = sqrt(A) # optional - asir
469: sage: B.sage() # optional - asir
470: 53.2259
471: sage: C = sqrt(-A) # optional - asir
472: sage: C.sage() # optional - asir
473: 53.2259*I
474: sage: A = asir('[1,2,3,4]') # optional - asir
475: sage: A.sage() # optional - asir
476: (1.0, 2.0, 3.0, 4.0)
477: sage: A = asir('[1,2.3,4.5]') # optional - asir
478: sage: A.sage() # optional - asir
479: (1.0, 2.3, 4.5)
480: sage: A = asir('[1,2.3+I,4.5]') # optional - asir
481: sage: A.sage() # optional - asir
482: (1.0, 2.3 + 1.0*I, 4.5)
483: """
484: if self.isscalar():
485: return self._scalar_()
486: elif self.isvector():
487: return self._vector_()
488: elif self.ismatrix():
489: return self._matrix_()
490: else:
491: raise NotImplementedError('asir type is not recognized')
492:
493: # An instance
494: asir = Asir()
495:
496: def reduce_load_Asir():
497: """
498: EXAMPLES::
499:
500: sage: from sage.interfaces.asir import reduce_load_Asir
501: sage: reduce_load_Asir()
502: Asir
503: """
504: return asir
505:
506:
507: def asir_console():
508: """
509: Spawn a new Asir command-line session.
510:
511: This requires that the optional asir program be installed and in
512: your PATH, but no optional Sage packages need be installed.
513:
514: EXAMPLES::
515:
516: sage: asir_console() # not tested
1.2 ! takayama 517: This is Risa/Asir ....
1.1 takayama 518: ...
1.2 ! takayama 519: [nnnn] 2+3;
! 520: 5
! 521: [nnnn] quit();
! 522:
! 523: quit(); exits the asir console and returns you to Sage.
1.1 takayama 524: """
525: from sage.repl.rich_output.display_manager import get_display_manager
526: if not get_display_manager().is_in_terminal():
527: raise RuntimeError('Can use the console only in the terminal. Try %%asir magics instead.')
1.2 ! takayama 528: os.system('openxm fep asir') # with asir prompt
1.1 takayama 529: # os.system('openxm asir -quiet')
530:
531:
532: def asir_version():
533: """
534: DEPRECATED: Return the version of Asir installed.
535:
536: EXAMPLES::
537:
538: sage: asir_version() # optional - asir
539: doctest:...: DeprecationWarning: This has been deprecated. Use
540: asir.version() instead
541: See http://trac.sagemath.org/21135 for details.
542: '...'
543: """
544: from sage.misc.superseded import deprecation
545: deprecation(21135, "This has been deprecated. Use asir.version() instead")
546: return asir.version()
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>