Path: blob/master/src/smc_sagews/smc_sagews/julia.py
Views: 286
r"""1Pexpect-based interface to Julia23EXAMPLES::45TODO67AUTHORS:8-- William Stein (2014-10-26)9"""1011##########################################################################12#13# Copyright (C) 2016, Sagemath Inc.14#15# Distributed under the terms of the GNU General Public License (GPL)16#17# http://www.gnu.org/licenses/18#19##########################################################################2021from __future__ import absolute_import2223import os, pexpect2425import six26def is_string(s):27return isinstance(s, six.string_types)2829from uuid import uuid4303132def uuid():33return str(uuid4())343536from sage.interfaces.expect import Expect, ExpectElement, ExpectFunction, FunctionElement, gc_disabled37from sage.structure.element import RingElement3839PROMPT_LENGTH = 16404142class Julia(Expect):43def __init__(self,44maxread=100000,45script_subdirectory=None,46logfile=None,47server=None,48server_tmpdir=None):49"""50Pexpect-based interface to Julia51"""52self._prompt = 'julia>'53Expect.__init__(self,54name='Julia',55prompt=self._prompt,56command="julia",57maxread=maxread,58server=server,59server_tmpdir=server_tmpdir,60script_subdirectory=script_subdirectory,61restart_on_ctrlc=False,62verbose_start=False,63logfile=logfile)6465self.__seq = 066self.__in_seq = 16768def _start(self):69"""70"""71pexpect_env = dict(os.environ)72pexpect_env[73'TERM'] = 'vt100' # we *use* the codes. DUH. I should have thought of this 10 years ago...74self._expect = pexpect.spawn(self._Expect__command,75logfile=self._Expect__logfile,76env=pexpect_env)77self._expect.delaybeforesend = 0 # not a good idea for a CAS.78self._expect.expect("\x1b\[0Kjulia>")7980def eval(self, code, **ignored):81"""82"""83if is_string(code):84code = code.encode('utf8')8586START = "\x1b[?2004l\x1b[0m"87END = "\x1b[0G\x1b[0K\x1b[0G\x1b[0Kjulia> "88if not self._expect:89self._start()90with gc_disabled():91s = self._expect92u = uuid()93line = code + '\n\n\n\n\n__ans__=ans;println("%s");ans=__ans__;\n' % u94s.send(line)95s.expect(u)96result = s.before97self._last_result = result98s.expect(u)99self._last_result += s.before100s.expect(u)101self._last_result += s.before102i = result.rfind(START)103if i == -1:104return result105result = result[len(START) + i:]106i = result.find(END)107if i == -1:108return result109result = result[:i].rstrip()110if result.startswith("ERROR:"):111julia_error = result.replace("in anonymous at no file", '')112raise RuntimeError(julia_error)113return result114115def _an_element_impl(self):116"""117EXAMPLES::118119sage: julia._an_element_impl()1200121"""122return self(0)123124def set(self, var, value):125"""126Set the variable var to the given value.127128EXAMPLES::129130sage: julia.set('x', '2')131sage: julia.get('x')132'2'133134TEST:135136It must also be possible to eval the variable by name::137138sage: julia.eval('x')139'2'140"""141cmd = '%s=%s;' % (var, value)142out = self.eval(cmd)143if '***' in out: #TODO144raise TypeError(145"Error executing code in Sage\nCODE:\n\t%s\nSAGE ERROR:\n\t%s"146% (cmd, out))147148def get(self, var):149"""150EXAMPLES::151152sage: julia.set('x', '2')153sage: julia.get('x')154'2'155"""156out = self.eval(var)157return out158159def _repr_(self):160return 'Julia Interpreter'161162def __reduce__(self):163"""164EXAMPLES::165166sage: julia.__reduce__()167"""168return reduce_load_Julia, tuple([])169170def _quit_string(self):171"""172EXAMPLES::173174sage: julia._quit_string()175'quit()'176177sage: l = Julia()178sage: l._start()179sage: l.quit()180sage: l.is_running()181False182"""183return 'quit()'184185def _read_in_file_command(self, filename):186"""187EXAMPLES::188189sage: julia._read_in_file_command(tmp_filename()) # TODO190"""191def trait_names(self):192"""193EXAMPLES::194195sage: julia.trait_names()196['ANY', ..., 'zip']197"""198s = julia.eval('\t\t')199v = []200for x in s.split('\x1b[')[:-1]:201i = x.find("G")202if i != -1:203c = x[i + 1:].strip()204if c and c.isalnum():205v.append(c)206v.sort()207return v208209def kill(self, var):210"""211EXAMPLES::212213sage: julia.kill('x')214Traceback (most recent call last):215...216NotImplementedError217"""218raise NotImplementedError219220def console(self):221"""222Spawn a new Julia command-line session.223224EXAMPLES::225226sage: julia.console() #not tested227...228"""229julia_console()230231def version(self):232"""233Returns the version of Julia being used.234235EXAMPLES::236237sage: julia.version()238'Version information is given by julia.console().'239"""240return self.eval("versioninfo()")241242def _object_class(self):243"""244EXAMPLES::245246sage: julia._object_class()247<class 'sage.interfaces.julia.JuliaElement'>248"""249return JuliaElement250251def _function_class(self):252"""253EXAMPLES::254255sage: julia._function_class()256<class 'sage.interfaces.julia.JuliaFunction'>257"""258return JuliaFunction259260def _function_element_class(self):261"""262EXAMPLES::263264sage: julia._function_element_class()265<class 'sage.interfaces.julia.JuliaFunctionElement'>266"""267return JuliaFunctionElement268269def _true_symbol(self):270"""271EXAMPLES::272273sage: julia._true_symbol()274'true'275"""276return 'true'277278def _false_symbol(self):279"""280EXAMPLES::281282sage: julia._false_symbol()283'false'284"""285return 'false'286287def _equality_symbol(self):288"""289"""290return "=="291292def help(self, command):293"""294EXAMPLES::295296297"""298if '"' in command:299raise ValueError('quote in command name')300return self.eval('help("%s")' % command)301302def function_call(self, function, args=None, kwds=None):303"""304EXAMPLES::305306sage: julia.function_call('sin', ['2'])3070.9092974308sage: julia.sin(2)3090.9092974310"""311args, kwds = self._convert_args_kwds(args, kwds)312self._check_valid_function_name(function)313return self.new("%s(%s)" %314(function, ",".join([s.name() for s in args])))315316317class JuliaElement(ExpectElement):318def trait_names(self):319# for now... (until I understand types)320return self._check_valid().trait_names()321322def __richcmp__(self, other):323"""324EXAMPLES::325326sage: one = julia(1); two = julia(2)327sage: one == one328True329sage: one != two330True331sage: one < two332True333sage: two > one334True335sage: one < 1336False337sage: two == 2338True339340"""341P = self._check_valid()342if not hasattr(other, 'parent') or P is not other.parent():343other = P(other)344345if P.eval('%s == %s' %346(self.name(), other.name())) == P._true_symbol():347return 0348elif P.eval('%s < %s' %349(self.name(), other.name())) == P._true_symbol():350return -1351else:352return 1353354def bool(self):355"""356EXAMPLES::357358sage: julia(2).bool()359True360sage: julia(0).bool()361False362sage: bool(julia(2))363True364"""365P = self._check_valid()366return P.eval("bool(%s)" % self.name()) == P._true_symbol()367368def _add_(self, right):369"""370EXAMPLES::371372sage: a = julia(1); b = julia(2)373sage: a + b3743375"""376P = self._check_valid()377return P.new('%s + %s' % (self._name, right._name))378379def _sub_(self, right):380"""381EXAMPLES::382383sage: a = julia(1); b = julia(2)384sage: a - b385-1386"""387P = self._check_valid()388return P.new('%s - %s' % (self._name, right._name))389390def _mul_(self, right):391"""392EXAMPLES::393394sage: a = julia(1); b = julia(2)395sage: a * b3962397"""398P = self._check_valid()399return P.new('%s * %s' % (self._name, right._name))400401def _div_(self, right):402"""403EXAMPLES::404405sage: a = julia(1); b = julia(2)406sage: a / b4071/2408"""409P = self._check_valid()410return P.new('%s / %s' % (self._name, right._name))411412def __pow__(self, n):413"""414EXAMPLES::415416sage: a = julia(3)417sage: a^341827419"""420P = self._check_valid()421right = P(n)422return P.new('%s ^ %s' % (self._name, right._name))423424425class JuliaFunctionElement(FunctionElement):426def _sage_doc_(self):427"""428EXAMPLES::429430sage: two = julia(2)431sage: two.sin._sage_doc_()432'Base.sin(x)\r\n\r\n Compute sine of "x", where "x" is in radians'433"""434M = self._obj.parent()435return M.help(self._name)436437438class JuliaFunction(ExpectFunction):439def _sage_doc_(self):440"""441EXAMPLES::442443sage: julia.sin._sage_doc_()444Traceback (most recent call last):445...446NotImplementedError447"""448M = self._parent449return M.help(self._name)450451452def is_JuliaElement(x):453"""454EXAMPLES::455456sage: from sage.interfaces.julia import is_JuliaElement457sage: is_JuliaElement(julia(2))458True459sage: is_JuliaElement(2)460False461"""462return isinstance(x, JuliaElement)463464465# An instance466julia = Julia()467468469def reduce_load_Julia():470"""471EXAMPLES::472473sage: from sage.interfaces.julia import reduce_load_Julia474sage: reduce_load_Julia()475Julia Interpreter476"""477return julia478479480def julia_console():481"""482Spawn a new Julia command-line session.483484EXAMPLES::485486sage: julia.console() #not tested487...488"""489os.system('julia')490491492