Ticket #7377: trac_7377-split_and_refactor-p2.patch

File trac_7377-split_and_refactor-p2.patch, 164.5 KB (added by jpflori, 8 years ago)

Updatred version for newlines in error reporting.

  • sage/calculus/calculus.py

    # HG changeset patch
    # User Jean-Pierre Flori <flori@enst.fr>
    # Date 1297688775 -3600
    # Node ID 8c40382f94338e8ab620b23988eeda45f0002bc0
    # Parent  d737d04798ad65f60a89dccafaee9d7d8abd5a87
    Split Expect interface.
    
    diff -r d737d04798ad -r 8c40382f9433 sage/calculus/calculus.py
    a b  
    364364from sage.rings.real_mpfr import create_RealNumber
    365365
    366366from sage.misc.latex import latex, latex_variable_name
    367 from sage.interfaces.maxima import Maxima
    368367from sage.misc.parser import Parser
    369368
    370369from sage.symbolic.ring import var, SR, is_SymbolicVariable
     
    374373from sage.symbolic.integration.integral import indefinite_integral, \
    375374        definite_integral
    376375import sage.symbolic.pynac
    377 import sage.interfaces.maxima_lib
    378376
    379377"""
    380378Check if maxima has redundant variables defined after initialization #9538::
    381379
    382     sage: maxima = sage.interfaces.maxima_lib.maxima
     380    sage: maxima = sage.interfaces.maxima.maxima
    383381    sage: maxima('f1')
    384382    f1
    385383    sage: sage.calculus.calculus.maxima('f1')
    386384    f1
    387385"""
    388 maxima = sage.interfaces.maxima_lib.maxima
    389 #maxima = Maxima(init_code = ['display2d:false', 'domain: complex',
    390 #                             'keepfloat: true', 'load(to_poly_solver)', 'load(simplify_sum)'],
     386import sage.interfaces.maxima_lib
     387maxima = sage.interfaces.maxima_lib.maxima_lib
     388# This is not the same instance of Maxima as the general purpose one
     389#from sage.interfaces.maxima import Maxima
     390#maxima = Maxima(init_code = ['display2d : false', 'domain : complex',
     391#                             'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)'],
    391392#                script_subdirectory=None)
    392393
    393394########################################################
  • sage/interfaces/all.py

    diff -r d737d04798ad -r 8c40382f9433 sage/interfaces/all.py
    a b  
    1717from magma_free import magma_free
    1818from macaulay2 import macaulay2, macaulay2_console, Macaulay2
    1919from maple import maple, maple_console, Maple
    20 from maxima import maxima, maxima_console, is_MaximaElement, Maxima
     20from maxima_abstract import maxima_console
     21from maxima import maxima, is_MaximaElement, Maxima
     22# import problems
     23#from maxima_lib import maxima_lib
    2124from mathematica import mathematica, mathematica_console, Mathematica
    2225from matlab import matlab, matlab_console, matlab_version, Matlab
    2326from mupad import mupad, mupad_console, Mupad  # NOT functional yet
  • sage/interfaces/expect.py

    diff -r d737d04798ad -r 8c40382f9433 sage/interfaces/expect.py
    a b  
    4242import time
    4343import gc
    4444import operator
     45import quit
     46import cleaner
    4547from random import randrange
    4648
    4749########################################################
     
    5153########################################################
    5254import pexpect
    5355from pexpect import ExceptionPexpect
    54 
     56from sage.interfaces.interface import Interface, InterfaceElement, InterfaceFunction, InterfaceFunctionElement, AsciiArtString
    5557
    5658from sage.structure.sage_object import SageObject
    5759from sage.structure.parent_base import ParentWithBase
    58 import  sage.structure.element
     60from sage.structure.element import RingElement
    5961
    6062import sage.misc.sage_eval
    61 
    62 import quit
    63 
    64 import cleaner
    65 
    66 import os
    67 
    6863from sage.misc.misc import SAGE_ROOT, verbose, SAGE_TMP_INTERFACE, LOCAL_IDENTIFIER
    69 from sage.structure.element import RingElement
    70 
    7164from sage.misc.object_multiplexer import Multiplex
    7265
    7366BAD_SESSION = -2
     
    142135            gc.enable()
    143136        return False
    144137
    145 class AsciiArtString(str):
    146     def __repr__(self):
    147         return str(self)
    148 
    149 class PropTypeError(Exception):
    150     pass
    151    
    152 
    153 class Expect(ParentWithBase):
     138class Expect(Interface):
    154139    """
    155140    Expect interface object.
    156141    """
     
    161146                 logfile = None, eval_using_file_cutoff=0,
    162147                 do_cleaner = True, remote_cleaner = False, path=None):
    163148
     149        Interface.__init__(self, name)
    164150        self.__is_remote = False
    165151        self.__remote_cleaner = remote_cleaner
    166152        if command == None:
     
    188174        self.__maxread = maxread
    189175        self._eval_using_file_cutoff = eval_using_file_cutoff
    190176        self.__script_subdirectory = script_subdirectory
    191         self.__name = name
    192         self.__coerce_name = '_' + name.lower() + '_'
    193177        self.__command = command
    194178        self._prompt = prompt
    195179        self._restart_on_ctrlc = restart_on_ctrlc
     
    199183        elif script_subdirectory is None:
    200184            self.__path = '.'
    201185        else:
    202             self.__path = '%s/data/extcode/%s/%s'%(SAGE_ROOT,self.__name,
     186            self.__path = '%s/data/extcode/%s/%s'%(SAGE_ROOT,name,
    203187                                                   self.__script_subdirectory)
    204188        self.__initialized = False
    205189        self.__seq = -1
     
    212196        if isinstance(logfile, basestring):
    213197            logfile = open(logfile,'w')
    214198        self.__logfile = logfile
    215 
    216199       
    217200        quit.expect_objects.append(weakref.ref(self))
    218201        self._available_vars = []
    219         ParentWithBase.__init__(self, self)
    220202
    221203    def _get(self, wait=0.1, alternate_prompt=None):
    222204        if self._expect is None:
     
    286268    def user_dir(self):
    287269        return self.__path
    288270
    289     def _repr_(self):
    290         return self.__name.capitalize()
    291 
    292271    def _change_prompt(self, prompt):
    293272        self._prompt = prompt
    294273
     
    299278#            os.makedirs(T)
    300279#        return T + str(x)
    301280
    302     def name(self, new_name=None):
    303         return self.__name
    304 
    305281    def path(self):
    306282        return self.__path
    307283
     
    461437        except (ExceptionPexpect, pexpect.EOF, IndexError):
    462438            self._expect = None
    463439            self._session_number = BAD_SESSION
    464             failed_to_start.append(self.__name)
     440            failed_to_start.append(self.name())
    465441            raise RuntimeError, "Unable to start %s because the command '%s' failed.\n%s"%(
    466                 self.__name, cmd, self._install_hints())
     442                self.name(), cmd, self._install_hints())
    467443
    468444        os.chdir(current_path)
    469445        self._expect.timeout = self.__max_startup_time
     
    476452        except (pexpect.TIMEOUT, pexpect.EOF), msg:
    477453            self._expect = None
    478454            self._session_number = BAD_SESSION
    479             failed_to_start.append(self.__name)
    480             raise RuntimeError, "Unable to start %s"%self.__name
     455            failed_to_start.append(self.name())
     456            raise RuntimeError, "Unable to start %s"%self.name()
    481457        self._expect.timeout = None
    482458        with gc_disabled():
    483459            if block_during_init:
     
    513489        except Exception, msg:
    514490            pass
    515491
    516     def cputime(self):
    517         """
    518         CPU time since this process started running.
    519         """
    520         raise NotImplementedError
    521 
    522492    def quit(self, verbose=False, timeout=0.25):
    523493        """
    524494        EXAMPLES::
     
    10561026        except TypeError, s:
    10571027            raise TypeError, 'error evaluating "%s":\n%s'%(code,s)
    10581028
    1059     def execute(self, *args, **kwds):
    1060         return self.eval(*args, **kwds)
    1061 
    1062     def __call__(self, x, name=None):
    1063 
    1064         r"""
    1065         Create a new object in self from x.
    1066 
    1067         The object X returned can be used like any Sage object, and
    1068         wraps an object in self.  The standard arithmetic operators
    1069         work.  Moreover if foo is a function then
    1070                       X.foo(y,z,...)
    1071         calls foo(X, y, z, ...) and returns the corresponding object.
    1072 
    1073         EXAMPLES::
    1074        
    1075             sage: gp(2)
    1076             2
    1077             sage: gp('2')
    1078             2
    1079             sage: a = gp(2); gp(a) is a
    1080             True
    1081 
    1082         """
    1083         cls = self._object_class()
    1084 
    1085         #Handle the case when x is an object
    1086         #in some interface.
    1087         if isinstance(x, ExpectElement):
    1088             if x.parent() is self:
    1089                 return x
    1090 
    1091             #We convert x into an object in this
    1092             #interface by first going through Sage.
    1093             try:
    1094                 return self(x._sage_())
    1095             except (NotImplementedError, TypeError):
    1096                 pass
    1097            
    1098         if isinstance(x, basestring):
    1099             return cls(self, x, name=name)
    1100         try:
    1101             return self._coerce_from_special_method(x)
    1102         except TypeError:
    1103             raise
    1104         except AttributeError, msg:
    1105             pass
    1106         try:
    1107             return self._coerce_impl(x, use_special=False)
    1108         except TypeError, msg:
    1109             try:
    1110                 return cls(self, str(x), name=name)
    1111             except TypeError, msg2:
    1112                 raise TypeError, msg
    1113 
    1114     def _coerce_from_special_method(self, x):
    1115         """
    1116         Tries to coerce to self by calling a special underscore method.
    1117        
    1118         If no such method is defined, raises an AttributeError instead of a
    1119         TypeError.
    1120         """
    1121         s = '_%s_'%self.name()
    1122         if s == '_pari_':
    1123             s = '_gp_'
    1124         try:
    1125             return (x.__getattribute__(s))(self)
    1126         except AttributeError:
    1127             return self(x._interface_init_())
    1128            
    1129     def _coerce_impl(self, x, use_special=True):
    1130         if isinstance(x, (int, long)):
    1131             import sage.rings.all
    1132             return self(sage.rings.all.Integer(x))
    1133         elif isinstance(x, float):
    1134             import sage.rings.all
    1135             return self(sage.rings.all.RDF(x))
    1136         if use_special:
    1137             try:
    1138                 return self._coerce_from_special_method(x)
    1139             except AttributeError, msg:
    1140                 pass
    1141            
    1142         if isinstance(x, (list, tuple)):
    1143             A = []
    1144             z = []
    1145             cls = self._object_class()
    1146             for v in x:
    1147                 if isinstance(v, cls):
    1148                     A.append(v.name())
    1149                     z.append(v)
    1150                 else:
    1151                     w = self(v)
    1152                     A.append(w.name())
    1153                     z.append(w)
    1154             X = ','.join(A)
    1155             r = self.new('%s%s%s'%(self._left_list_delim(), X, self._right_list_delim()))
    1156             r.__sage_list = z   # do this to avoid having the entries of the list be garbage collected
    1157             return r
    1158 
    1159 
    1160         raise TypeError, "unable to coerce element into %s"%self.name()
    1161 
    1162     def new(self, code):
    1163         return self(code)
    1164 
    1165     ###################################################################
    1166     # these should all be appropriately overloaded by the derived class
    1167     ###################################################################
    1168    
    1169     def _left_list_delim(self):
    1170         return "["
    1171 
    1172     def _right_list_delim(self):
    1173         return "]"
    1174 
    1175     def _assign_symbol(self):
    1176         return "="
    1177    
    1178     def _equality_symbol(self):
    1179         raise NotImplementedError
    1180 
    1181     # For efficiency purposes, you should definitely override these
    1182     # in your derived class.
    1183     def _true_symbol(self):
    1184         try:
    1185             return self.__true_symbol
    1186         except AttributeError:
    1187             self.__true_symbol = self.eval('1 %s 1'%self._equality_symbol())
    1188 
    1189     def _false_symbol(self):
    1190         try:
    1191             return self.__false_symbol
    1192         except AttributeError:
    1193             self.__false_symbol = self.eval('1 %s 2'%self._equality_symbol())
    1194 
    1195     def _lessthan_symbol(self):
    1196         return '<'
    1197 
    1198     def _greaterthan_symbol(self):
    1199         return '>'
    1200 
    1201     def _inequality_symbol(self):
    1202         return '!='
    1203 
    1204     def _relation_symbols(self):
    1205         """
    1206         Returns a dictionary with operators as the keys and their
    1207         string representation as the values.
    1208 
    1209         EXAMPLES::
    1210 
    1211             sage: import operator
    1212             sage: symbols = mathematica._relation_symbols()
    1213             sage: symbols[operator.eq]
    1214             '=='
    1215         """
    1216         return dict([(operator.eq, self._equality_symbol()), (operator.ne, self._inequality_symbol()),
    1217                      (operator.lt, self._lessthan_symbol()), (operator.le, "<="),
    1218                      (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")])
    1219 
    1220     def _exponent_symbol(self):
    1221         """
    1222         Return the symbol used to denote *10^ in floats, e.g 'e' in 1.5e6
    1223        
    1224         EXAMPLES::
    1225            
    1226             sage: from sage.interfaces.expect import Expect
    1227             sage: Expect('nonexistent_interface', 'fake')._exponent_symbol()
    1228             'e'
    1229         """
    1230         return 'e'
    1231 
    12321029    ############################################################
    12331030    #         Functions for working with variables.
    12341031    #  The first three must be overloaded by derived classes,
     
    12361033    #  the functionality one gets from this is very nice.
    12371034    ############################################################
    12381035
    1239     def set(self, var, value):
    1240         """
    1241         Set the variable var to the given value.
    1242         """
    1243         cmd = '%s%s%s;'%(var,self._assign_symbol(), value)
    1244         self.eval(cmd)
    1245 
    1246     def get(self, var):
    1247         """
    1248         Get the value of the variable var.
    1249         """
    1250         return self.eval(var)
    1251 
    1252     def get_using_file(self, var):
    1253         r"""
    1254         Return the string representation of the variable var in self,
    1255         possibly using a file. Use this if var has a huge string
    1256         representation, since it may be way faster.
    1257        
    1258         .. warning::
    1259 
    1260            In fact unless a special derived class implements this, it
    1261            will *not* be any faster. This is the case for this class
    1262            if you're reading it through introspection and seeing this.
    1263         """
    1264         return self.get(var)
    1265 
    1266     def clear(self, var):
    1267         """
    1268         Clear the variable named var.
    1269         """
    1270         self._available_vars.append(var)
    1271    
    1272     def _next_var_name(self):
    1273         if len(self._available_vars) != 0:
    1274             v = self._available_vars[0]
    1275             del self._available_vars[0]
    1276             return v
    1277         self.__seq += 1
    1278         return "sage%s"%self.__seq
    1279 
    1280     def _create(self, value, name=None):
    1281         name = self._next_var_name() if name is None else name
    1282         self.set(name, value)
    1283         return name
    1284 
    12851036    def _object_class(self):
    12861037        """
    12871038        EXAMPLES::
     
    13111062            <class 'sage.interfaces.expect.FunctionElement'>
    13121063        """
    13131064        return FunctionElement
     1065 
    13141066
    1315     def _convert_args_kwds(self, args=None, kwds=None):
    1316         """
    1317         Converts all of the args and kwds to be elements of this
    1318         interface.
    1319        
    1320         EXAMPLES::
    1321        
    1322             sage: args = [5]
    1323             sage: kwds = {'x': 6}
    1324             sage: args, kwds = gap._convert_args_kwds(args, kwds)
    1325             sage: args
    1326             [5]
    1327             sage: map(type, args)
    1328             [<class 'sage.interfaces.gap.GapElement'>]
    1329             sage: type(kwds['x'])
    1330             <class 'sage.interfaces.gap.GapElement'>
    1331         """
    1332         args = [] if args is None else args
    1333         kwds = {} if kwds is None else kwds
    1334         if not isinstance(args, list):
    1335             args = [args]
    1336         for i, arg in enumerate(args):
    1337             if not isinstance(arg, ExpectElement) or arg.parent() is not self:
    1338                 args[i] = self(arg)
    1339         for key, value in kwds.iteritems():
    1340             if not isinstance(value, ExpectElement) or value.parent() is not self:
    1341                 kwds[key] = self(value)
    1342 
    1343         return args, kwds
    1344 
    1345     def _check_valid_function_name(self, function):
    1346         """
    1347         Checks to see if function is a valid function name in this
    1348         interface. If it is not, an exception is raised. Otherwise, nothing
    1349         is done.
    1350        
    1351         EXAMPLES::
    1352        
    1353             sage: gap._check_valid_function_name('SymmetricGroup')
    1354             sage: gap._check_valid_function_name('')
    1355             Traceback (most recent call last):
    1356             ...
    1357             ValueError: function name must be nonempty
    1358             sage: gap._check_valid_function_name('__foo')
    1359             Traceback (most recent call last):
    1360             ...
    1361             AttributeError
    1362         """
    1363         if function == '':
    1364             raise ValueError, "function name must be nonempty"
    1365         if function[:2] == "__":
    1366             raise AttributeError       
    1367 
    1368     def function_call(self, function, args=None, kwds=None):
    1369         """
    1370         EXAMPLES::
    1371        
    1372             sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4)
    1373             [0.5,5.5511151231257...e-15,21,0]
    1374             sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'})
    1375             [0.5,5.5511151231257...e-15,21,0]
    1376         """
    1377         args, kwds = self._convert_args_kwds(args, kwds)
    1378         self._check_valid_function_name(function)
    1379         s = self._function_call_string(function,
    1380                                        [s.name() for s in args],
    1381                                        ['%s=%s'%(key,value.name()) for key, value in kwds.items()])
    1382         return self.new(s)
    1383 
    1384     def _function_call_string(self, function, args, kwds):
    1385         """
    1386         Returns the string used to make function calls.
    1387        
    1388         EXAMPLES::
    1389 
    1390             sage: maxima._function_call_string('diff', ['f(x)', 'x'], [])
    1391             'diff(f(x),x)'
    1392         """
    1393         return "%s(%s)"%(function, ",".join(list(args) + list(kwds)))
    1394            
    1395     def call(self, function_name, *args, **kwds):
    1396         return self.function_call(function_name, args, kwds)
    1397 
    1398     def _contains(self, v1, v2):
    1399         raise NotImplementedError
    1400    
    1401     def __getattr__(self, attrname):
    1402         """
    1403         TESTS::
    1404 
    1405             sage: ParentWithBase.__getattribute__(singular, '_coerce_map_from_')
    1406             <built-in method _coerce_map_from_ of Singular object at ...>
    1407         """
    1408         try:
    1409             return ParentWithBase.__getattribute__(self, attrname)
    1410         except AttributeError:
    1411             if attrname[:1] == "_":
    1412                 raise AttributeError
    1413             return self._function_class()(self, attrname)
    1414 
    1415     def __cmp__(self, other):
    1416         """
    1417         Compare two pseudo-tty interfaces. Two interfaces compare
    1418         equal if and only if they are identical objects (this is a
    1419         critical constraint so that caching of representations of
    1420         objects in interfaces works correctly). Otherwise they are
    1421         never equal.
    1422        
    1423         EXAMPLES::
    1424        
    1425             sage: Maxima() == maxima
    1426             False
    1427             sage: maxima == maxima
    1428             True
    1429         """
    1430         if self is other:
    1431             return 0
    1432         c = cmp(type(self), type(other))
    1433         if c:
    1434             return c
    1435         return -1  # sucky, but I can't think of anything better; it is important that different interfaces to the same system still compare differently; unfortunately there is nothing to distinguish them.
    1436 
    1437     def console(self):
    1438         raise NotImplementedError
    1439 
    1440     def help(self, s):
    1441         return AsciiArtString('No help on %s available'%s)
    1442    
    1443 
    1444 class ExpectFunction(SageObject):
     1067class ExpectFunction(InterfaceFunction):
    14451068    """
    14461069    Expect function.
    14471070    """
    1448     def __init__(self, parent, name):
    1449         self._parent = parent
    1450         self._name = name
    1451        
    1452     def __repr__(self):
    1453         return "%s"%self._name
    1454    
    1455     def __call__(self, *args, **kwds):
    1456         return self._parent.function_call(self._name, list(args), kwds)
    1457        
    1458     def _sage_doc_(self):
    1459         """
    1460         EXAMPLES::
    1461        
    1462             sage: gp.gcd._sage_doc_()
    1463             'gcd(x,{y}): greatest common divisor of x and y.'
    1464         """
    1465         M = self._parent
    1466         return M.help(self._name)
    1467        
     1071    pass
    14681072
    14691073
    1470        
    1471 class FunctionElement(SageObject):
     1074class FunctionElement(InterfaceFunctionElement):
    14721075    """
    14731076    Expect function element.
    14741077    """
    1475     def __init__(self, obj, name):
    1476         self._obj = obj
    1477         self._name = name
    1478 
    1479     def __repr__(self):
    1480         return "%s"%self._name
    1481 
    1482     def __call__(self, *args, **kwds):
    1483         return self._obj.parent().function_call(self._name, [self._obj] + list(args), kwds)
    1484    
    1485     def help(self):
    1486         print self._sage_doc_()
    1487 
    1488     def _sage_doc_(self):
    1489         """
    1490         EXAMPLES::
    1491        
    1492             sage: gp(2).gcd._sage_doc_()
    1493             'gcd(x,{y}): greatest common divisor of x and y.'
    1494         """
    1495         M = self._obj.parent()
    1496         return M.help(self._name)
     1078    pass
    14971079
    14981080
    14991081def is_ExpectElement(x):
    15001082    return isinstance(x, ExpectElement)
    15011083
    1502 
    1503 
    1504 class ExpectElement(RingElement):
     1084class ExpectElement(InterfaceElement):
    15051085    """
    15061086    Expect element.
    15071087    """
     
    15261106                raise TypeError, x
    15271107        self._session_number = parent._session_number
    15281108
    1529     def _latex_(self):
    1530 #        return "\\begin{verbatim}%s\\end{verbatim}"%self
    1531         string = str(self)
    1532         if not '|' in string:
    1533             delim = '|'
    1534         elif not '#' in string:
    1535             delim = '#'
    1536         elif not '@' in string:
    1537             delim = '@'
    1538         elif not '~' in string:
    1539             delim = '~'
    1540         return "\\verb%s%s%s"%(delim, string, delim)
    1541 
    1542     def __iter__(self):
    1543         for i in range(1, len(self)+1):
    1544             yield self[i]
    1545 
    1546     def __len__(self):
    1547         """
    1548         Call self.sage() and return the length of that sage object.
    1549        
    1550         This approach is inefficient - each interface should override
    1551         this method with one that calls the external program's length
    1552         function.
    1553        
    1554         EXAMPLES::
    1555        
    1556             sage: len(gp([1,2,3]))
    1557             3
    1558        
    1559         AUTHORS:
    1560        
    1561         - Felix Lawrence (2009-08-21)
    1562         """
    1563         return len(self.sage())
    1564 
    1565     def __reduce__(self):
    1566         return reduce_load, (self.parent(), self._reduce())
    1567 
    1568     def _reduce(self):
    1569         return repr(self)
    1570 
    1571     def __call__(self, *args):
    1572         self._check_valid()               
    1573         P = self.parent()
    1574         return getattr(P, self.name())(*args)
    1575 
    1576     def __contains__(self, x):
    1577         P = self._check_valid()               
    1578         if not isinstance(x, ExpectElement) or x.parent() is not self.parent():
    1579             x = P.new(x)
    1580         return P._contains(x.name(), self.name())
    1581 
    1582 
    1583     def _sage_doc_(self):
    1584         """
    1585         EXAMPLES::
    1586        
    1587             sage: gp(2)._sage_doc_()
    1588             '2'
    1589         """
    1590         return str(self)
    1591 
    15921109    def __hash__(self):
    15931110        """
    15941111        Returns the hash of self. This is a default implementation of hash
     
    15961113        """
    15971114        return hash('%s%s'%(self, self._session_number))
    15981115   
    1599     def __cmp__(self, other):
    1600         P = self.parent()
    1601         if P.eval("%s %s %s"%(self.name(), P._equality_symbol(),
    1602                                  other.name())) == P._true_symbol():
    1603             return 0
    1604         elif P.eval("%s %s %s"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol():
    1605             return -1
    1606         elif P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol():
    1607             return 1
    1608 
    1609         # everything is supposed to be comparable in Python, so we define
    1610         # the comparison thus when no comparison is available in interfaced system.
    1611         if (hash(self) < hash(other)):
    1612             return -1
    1613         else:
    1614             return 1
    1615 
    1616     def _matrix_(self, R):
    1617         raise NotImplementedError
    1618 
    1619     def _vector_(self, R):
    1620         raise NotImplementedError
    16211116
    16221117    def _check_valid(self):
    16231118        """
     
    16501145            #print msg
    16511146            pass
    16521147
    1653     def _sage_repr(self):
    1654         """
    1655         Return a sage-friendly string representation of the object.
    1656        
    1657         Some programs use different notation to Sage, e.g. Mathematica
    1658         writes lists with {} instead of [].  This method calls repr(self)
    1659         then converts the foreign notation into Sage's notation.
    1660        
    1661         OUTPUT:
    1662        
    1663         A string representation of the object that is ready for
    1664         sage_eval().
    1665        
    1666         EXAMPLES::
    1667        
    1668             sage: repr(mathematica([1,2,3]))    # optional - mathematica
    1669             '{1, 2, 3}'
    1670             sage: mathematica([1,2,3])._sage_repr() # optional - mathematica
    1671             '[1, 2, 3]'
    1672        
    1673         ::
    1674        
    1675             sage: gp(10.^80)._sage_repr()
    1676             '1.0000000000000000000000000000000000000e80'    # 64-bit
    1677             '1.000000000000000000000000000e80'              # 32-bit
    1678             sage: mathematica('10.^80')._sage_repr()  # optional - mathematica
    1679             '1.e80'
    1680        
    1681         AUTHORS:
    1682        
    1683         - Felix Lawrence (2009-08-21)
    1684         """
    1685         #TO DO: this could use file transfers when self.is_remote()
    1686        
    1687         string = repr(self).replace('\n',' ').replace('\r', '')
    1688         # Translate the external program's list formatting to Sage's
    1689         lld = self.parent()._left_list_delim()
    1690         if '[' != lld:      string = string.replace(lld, '[')
    1691         rld = self.parent()._right_list_delim()
    1692         if ']' != rld:      string = string.replace(rld, ']')
    1693         # Translate the external program's exponent formatting
    1694         expl = self.parent()._exponent_symbol()
    1695         if 'e' != expl: string = string.replace(expl, 'e')
    1696         return string
    1697 
    1698     def _sage_(self):
    1699         """
    1700         Attempt to return a Sage version of this object.
    1701         This is a generic routine that just tries to evaluate
    1702         the repr(self).
    1703 
    1704         EXAMPLES::
    1705        
    1706             sage: gp(1/2)._sage_()
    1707             1/2
    1708             sage: _.parent()
    1709             Rational Field
    1710        
    1711         AUTHORS:
    1712        
    1713         - William Stein
    1714        
    1715         - Felix Lawrence (2009-08-21)
    1716         """
    1717         try:
    1718             return sage.misc.sage_eval.sage_eval(self._sage_repr())
    1719         except:
    1720             raise NotImplementedError
    1721        
    1722 
    1723     def sage(self):
    1724         """
    1725         Attempt to return a Sage version of this object.
    1726 
    1727         EXAMPLES::
    1728        
    1729             sage: gp(1/2).sage()
    1730             1/2
    1731             sage: _.parent()
    1732             Rational Field
    1733         """
    1734         return self._sage_()
    1735        
    1736     def __repr__(self):
    1737         self._check_valid()
    1738         try:
    1739             if self._get_using_file:
    1740                 s = self.parent().get_using_file(self._name)
    1741         except AttributeError:
    1742             s = self.parent().get(self._name)
    1743         if s.__contains__(self._name):
    1744             if hasattr(self, '__custom_name'):
    1745                 s =  s.replace(self._name, self.__dict__['__custom_name'])
    1746         return s
    1747 
    1748     def __getattr__(self, attrname):
    1749         P = self._check_valid()
    1750         if attrname[:1] == "_":
    1751             raise AttributeError
    1752         return P._function_element_class()(self, attrname)
    1753 
    1754     def get_using_file(self):
    1755         """
    1756         Return this element's string representation using a file. Use this
    1757         if self has a huge string representation. It'll be way faster.
    1758        
    1759         EXAMPLES::
    1760        
    1761             sage: a = maxima(str(2^1000))
    1762             sage: a.get_using_file()
    1763             '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376'
    1764         """
    1765         try:
    1766             self._check_valid()
    1767         except ValueError:
    1768             return '(invalid object -- defined in terms of closed session)'
    1769         return self.parent().get_using_file(self._name)
    1770 
    1771     def hasattr(self, attrname):
    1772         """
    1773         Returns whether the given attribute is already defined by this
    1774         object, and in particular is not dynamically generated.
    1775        
    1776         EXAMPLES::
    1777        
    1778             sage: m = maxima('2')
    1779             sage: m.hasattr('integral')
    1780             True
    1781             sage: m.hasattr('gcd')
    1782             False
    1783         """
    1784         return not isinstance(getattr(self, attrname), FunctionElement)
    1785 
    1786     def attribute(self, attrname):
    1787         """
    1788         If this wraps the object x in the system, this returns the object
    1789         x.attrname. This is useful for some systems that have object
    1790         oriented attribute access notation.
    1791        
    1792         EXAMPLES::
    1793        
    1794             sage: g = gap('SO(1,4,7)')
    1795             sage: k = g.InvariantQuadraticForm()
    1796             sage: k.attribute('matrix')
    1797             [ [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), 0*Z(7) ],
    1798               [ 0*Z(7), 0*Z(7), Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ]
    1799        
    1800         ::
    1801        
    1802             sage: e = gp('ellinit([0,-1,1,-10,-20])')
    1803             sage: e.attribute('j')
    1804             -122023936/161051
    1805         """
    1806         P = self._check_valid()
    1807         return P('%s.%s'%(self.name(), attrname))
    1808 
    1809     def __getitem__(self, n):
    1810         P = self._check_valid()
    1811         if not isinstance(n, tuple):
    1812             return P.new('%s[%s]'%(self._name, n))
    1813         else:
    1814             return P.new('%s[%s]'%(self._name, str(n)[1:-1]))
    1815    
    1816     def __int__(self):
    1817         """
    1818         EXAMPLES::
    1819        
    1820             sage: int(maxima('1'))
    1821             1
    1822             sage: type(_)
    1823             <type 'int'>
    1824         """
    1825         return int(repr(self))
    1826 
    1827     def bool(self):
    1828         P = self.parent()
    1829         t = P._true_symbol()
    1830         cmd = '%s %s %s'%(self._name, P._equality_symbol(), t)
    1831         return P.eval(cmd) == t
    1832 
    1833     def __nonzero__(self):
    1834         """
    1835         EXAMPLES::
    1836        
    1837             sage: bool(maxima(0))
    1838             False
    1839             sage: bool(maxima(1))
    1840             True
    1841         """
    1842         return self.bool()
    1843 
    1844     def __long__(self):
    1845         """
    1846         EXAMPLES::
    1847        
    1848             sage: m = maxima('1')
    1849             sage: long(m)
    1850             1L
    1851         """
    1852         return long(repr(self))
    1853 
    1854     def __float__(self):
    1855         """
    1856         EXAMPLES::
    1857        
    1858             sage: m = maxima('1/2')
    1859             sage: m.__float__()
    1860             0.5
    1861             sage: float(m)
    1862             0.5
    1863         """
    1864         return float(repr(self))
    1865 
    1866     def _integer_(self, ZZ=None):
    1867         """
    1868         EXAMPLES::
    1869        
    1870             sage: m = maxima('1')
    1871             sage: m._integer_()
    1872             1
    1873             sage: _.parent()
    1874             Integer Ring
    1875             sage: QQ(m)
    1876             1
    1877         """
    1878         import sage.rings.all
    1879         return sage.rings.all.Integer(repr(self))
    1880 
    1881     def _rational_(self):
    1882         """
    1883         EXAMPLES::
    1884        
    1885             sage: m = maxima('1/2')
    1886             sage: m._rational_()
    1887             1/2
    1888             sage: _.parent()
    1889             Rational Field
    1890             sage: QQ(m)
    1891             1/2
    1892         """
    1893         import sage.rings.all       
    1894         return sage.rings.all.Rational(repr(self))
    1895 
    1896     def name(self, new_name=None):
    1897         """
    1898         Returns the name of self. If new_name is passed in, then this
    1899         function returns a new object identical to self whose name is
    1900         new_name.
    1901        
    1902         Note that this can overwrite existing variables in the system.
    1903        
    1904         EXAMPLES::
    1905        
    1906             sage: x = r([1,2,3]); x
    1907             [1] 1 2 3
    1908             sage: x.name()
    1909             'sage3'
    1910             sage: x = r([1,2,3]).name('x'); x
    1911             [1] 1 2 3
    1912             sage: x.name()
    1913             'x'
    1914        
    1915         ::
    1916        
    1917             sage: s5 = gap.SymmetricGroup(5).name('s5')
    1918             sage: s5
    1919             SymmetricGroup( [ 1 .. 5 ] )
    1920             sage: s5.name()
    1921             's5'
    1922         """
    1923         if new_name is not None:
    1924             if not isinstance(new_name, str):
    1925                 raise TypeError, "new_name must be a string"
    1926             p = self.parent()
    1927             p.set(new_name, self._name)
    1928             return p._object_class()(p, new_name, is_name=True)
    1929            
    1930         return self._name
    1931 
    1932     def gen(self, n):
    1933         P = self._check_valid()
    1934         return P.new('%s.%s'%(self._name, int(n)))
    1935 
    1936     def _operation(self, operation, right):
    1937         P = self._check_valid()
    1938         try:
    1939             return P.new('%s %s %s'%(self._name, operation, right._name))
    1940         except Exception, msg:
    1941             raise TypeError, msg
    1942 
    1943     def _add_(self, right):
    1944         """
    1945         EXAMPLES::
    1946        
    1947             sage: f = maxima.cos(x)
    1948             sage: g = maxima.sin(x)
    1949             sage: f + g
    1950             sin(x)+cos(x)
    1951             sage: f + 2
    1952             cos(x)+2
    1953             sage: 2 + f
    1954             cos(x)+2
    1955         """
    1956         return self._operation("+", right)
    1957        
    1958     def _sub_(self, right):
    1959         """
    1960         EXAMPLES::
    1961        
    1962             sage: f = maxima.cos(x)
    1963             sage: g = maxima.sin(x)
    1964             sage: f - g
    1965             cos(x)-sin(x)
    1966             sage: f - 2
    1967             cos(x)-2
    1968             sage: 2 - f
    1969             2-cos(x)
    1970         """
    1971         return self._operation('-', right)       
    1972 
    1973     def _mul_(self, right):
    1974         """
    1975         EXAMPLES::
    1976        
    1977             sage: f = maxima.cos(x)
    1978             sage: g = maxima.sin(x)
    1979             sage: f*g
    1980             cos(x)*sin(x)
    1981             sage: 2*f
    1982             2*cos(x)
    1983         """
    1984         return self._operation('*', right)
    1985 
    1986     def _div_(self, right):
    1987         """       
    1988         EXAMPLES::
    1989        
    1990             sage: f = maxima.cos(x)
    1991             sage: g = maxima.sin(x)
    1992             sage: f/g
    1993             cos(x)/sin(x)
    1994             sage: f/2
    1995             cos(x)/2
    1996         """
    1997         return self._operation("/", right)
    1998 
    1999     def __pow__(self, n):
    2000         """
    2001         EXAMPLES::
    2002        
    2003             sage: a = maxima('2')
    2004             sage: a^(3/4)
    2005             2^(3/4)
    2006         """
    2007         P = self._check_valid()
    2008         if not hasattr(n, 'parent') or P is not n.parent():
    2009             n = P(n)
    2010         return self._operation("^", n)
     1148#    def _sage_repr(self):
     1149#TO DO: this could use file transfers when self.is_remote()
    20111150
    20121151
    20131152class StdOutContext:
     
    20341173            sage: with StdOutContext(gp):
    20351174            ...       gp('1+1')
    20361175            ...
    2037             sage[...
     1176            sage=...
    20381177        """
    20391178        self.interface = interface
    20401179        self.silent = silent
     
    20761215        self.stdout.write("\n")
    20771216        self.interface._expect.logfile = self._logfile_backup
    20781217
    2079 def reduce_load(parent, x):
    2080     return parent(x)
    2081 
    20821218import os
    20831219def console(cmd):
    20841220    os.system(cmd)
  • sage/interfaces/gap.py

    diff -r d737d04798ad -r 8c40382f9433 sage/interfaces/gap.py
    a b  
    599599       
    600600            sage: s = gap.function_call('Display', [gap.SymmetricGroup(5).CharacterTable()])
    601601            sage: type(s)
    602             <class 'sage.interfaces.expect.AsciiArtString'>
     602            <class 'sage.interfaces.interface.AsciiArtString'>
    603603            sage: s.startswith('CT')
    604604            True
    605605        """
  • new file sage/interfaces/interface.py

    diff -r d737d04798ad -r 8c40382f9433 sage/interfaces/interface.py
    - +  
     1r"""
     2Common Interface Functionality
     3
     4See the examples in the other sections for how to use specific
     5interfaces. The interface classes all derive from the generic
     6interface that is described in this section.
     7
     8AUTHORS:
     9
     10- William Stein (2005): initial version
     11
     12- William Stein (2006-03-01): got rid of infinite loop on startup if
     13  client system missing
     14
     15- Felix Lawrence (2009-08-21): edited ._sage_() to support lists and float exponents in foreign notation.
     16
     17- Simon King (2010-09-25): Expect._local_tmpfile() depends on
     18  Expect.pid() and is cached; Expect.quit() clears that cache,
     19  which is important for forking.
     20"""
     21
     22#*****************************************************************************
     23#       Copyright (C) 2005 William Stein <wstein@gmail.com>
     24#
     25#  Distributed under the terms of the GNU General Public License (GPL)
     26#
     27#    This code is distributed in the hope that it will be useful,
     28#    but WITHOUT ANY WARRANTY; without even the implied warranty of
     29#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     30#    General Public License for more details.
     31#
     32#  The full text of the GPL is available at:
     33#
     34#                  http://www.gnu.org/licenses/
     35#*****************************************************************************
     36
     37import operator
     38
     39from sage.structure.sage_object import SageObject
     40from sage.structure.parent_base import ParentWithBase
     41from sage.structure.element import RingElement
     42
     43from sage.misc.sage_eval import sage_eval
     44
     45from sage.misc.misc import SAGE_ROOT, verbose, SAGE_TMP_INTERFACE, LOCAL_IDENTIFIER
     46
     47class AsciiArtString(str):
     48    def __repr__(self):
     49        return str(self)
     50
     51class PropTypeError(Exception):
     52    pass
     53   
     54
     55class Interface(ParentWithBase):
     56    """
     57    Interface interface object.
     58    """
     59    def __init__(self, name):
     60        self.__name = name
     61        self.__coerce_name = '_' + name.lower() + '_'
     62        self.__seq = -1
     63        self._available_vars = []
     64        ParentWithBase.__init__(self, self)
     65
     66    def _repr_(self):
     67        return self.__name.capitalize()
     68
     69    def name(self, new_name=None):
     70        return self.__name
     71
     72    def interact(self):
     73        r"""
     74        This allows you to interactively interact with the child
     75        interpreter. Press Ctrl-D or type 'quit' or 'exit' to exit and
     76        return to Sage.
     77       
     78        .. note::
     79
     80           This is completely different than the console() member
     81           function. The console function opens a new copy of the
     82           child interpreter, whereas the interact function gives you
     83           interactive access to the interpreter that is being used by
     84           Sage. Use sage(xxx) or interpretername(xxx) to pull objects
     85           in from sage to the interpreter.
     86        """
     87        import sage.misc.preparser_ipython
     88        sage.misc.preparser_ipython.switch_interface_general(self)
     89
     90    def _pre_interact(self):
     91        pass
     92
     93    def _post_interact(self):
     94        pass
     95
     96    def __del__(self):
     97        pass
     98
     99    def cputime(self):
     100        """
     101        CPU time since this process started running.
     102        """
     103        raise NotImplementedError
     104
     105    def read(self, filename):
     106        r"""
     107        EXAMPLES::
     108       
     109            sage: filename = tmp_filename()
     110            sage: f = open(filename, 'w')
     111            sage: f.write('x = 2\n')
     112            sage: f.close()
     113            sage: octave.read(filename)  #optional -- requires Octave
     114            sage: octave.get('x')        #optional
     115            ' 2'
     116            sage: import os
     117            sage: os.unlink(filename)
     118        """
     119        self.eval(self._read_in_file_command(filename))
     120
     121    def _read_in_file_command(self, filename):
     122        raise NotImplementedError
     123
     124    def eval(self, code, locals=None, **kwds):
     125        """
     126        INPUT:
     127       
     128       
     129        -  ``code`` - text to evaluate
     130               
     131        - ``locals`` - None (ignored); this is used for compatibility with the
     132          Sage notebook's generic system interface.
     133         
     134        -  ``**kwds`` - All other arguments are passed onto
     135           the _eval_line method. An often useful example is
     136           reformat=False.
     137        """
     138
     139        if not isinstance(code, basestring):
     140            raise TypeError, 'input code must be a string.'
     141
     142        #Remove extra whitespace
     143        code = code.strip()
     144       
     145        try:
     146            pass
     147        except KeyboardInterrupt:
     148            # DO NOT CATCH KeyboardInterrupt, as it is being caught
     149            # by _eval_line
     150            # In particular, do NOT call self._keyboard_interrupt()
     151            raise
     152        except TypeError, s:
     153            raise TypeError, 'error evaluating "%s":\n%s'%(code,s)
     154
     155    _eval_line = eval
     156
     157    def execute(self, *args, **kwds):
     158        return self.eval(*args, **kwds)
     159
     160    def __call__(self, x, name=None):
     161
     162        r"""
     163        Create a new object in self from x.
     164
     165        The object X returned can be used like any Sage object, and
     166        wraps an object in self.  The standard arithmetic operators
     167        work.  Moreover if foo is a function then
     168                      X.foo(y,z,...)
     169        calls foo(X, y, z, ...) and returns the corresponding object.
     170
     171        EXAMPLES::
     172       
     173            sage: gp(2)
     174            2
     175            sage: gp('2')
     176            2
     177            sage: a = gp(2); gp(a) is a
     178            True
     179
     180        """
     181        cls = self._object_class()
     182
     183        #Handle the case when x is an object
     184        #in some interface.
     185        if isinstance(x, InterfaceElement):
     186            if x.parent() is self:
     187                return x
     188
     189            #We convert x into an object in this
     190            #interface by first going through Sage.
     191            try:
     192                return self(x._sage_())
     193            except (NotImplementedError, TypeError):
     194                pass
     195           
     196        if isinstance(x, basestring):
     197            return cls(self, x, name=name)
     198        try:
     199            return self._coerce_from_special_method(x)
     200        except TypeError:
     201            raise
     202        except AttributeError, msg:
     203            pass
     204        try:
     205            return self._coerce_impl(x, use_special=False)
     206        except TypeError, msg:
     207            try:
     208                return cls(self, str(x), name=name)
     209            except TypeError, msg2:
     210                raise TypeError, msg
     211
     212    def _coerce_from_special_method(self, x):
     213        """
     214        Tries to coerce to self by calling a special underscore method.
     215       
     216        If no such method is defined, raises an AttributeError instead of a
     217        TypeError.
     218        """
     219        s = '_%s_'%self.name()
     220        if s == '_maxima_lib_':
     221            s = '_maxima_'
     222        if s == '_pari_':
     223            s = '_gp_'
     224        try:
     225            return (x.__getattribute__(s))(self)
     226        except AttributeError:
     227            return self(x._interface_init_())
     228           
     229    def _coerce_impl(self, x, use_special=True):
     230        if isinstance(x, (int, long)):
     231            import sage.rings.all
     232            return self(sage.rings.all.Integer(x))
     233        elif isinstance(x, float):
     234            import sage.rings.all
     235            return self(sage.rings.all.RDF(x))
     236        if use_special:
     237            try:
     238                return self._coerce_from_special_method(x)
     239            except AttributeError, msg:
     240                pass
     241           
     242        if isinstance(x, (list, tuple)):
     243            A = []
     244            z = []
     245            cls = self._object_class()
     246            for v in x:
     247                if isinstance(v, cls):
     248                    A.append(v.name())
     249                    z.append(v)
     250                else:
     251                    w = self(v)
     252                    A.append(w.name())
     253                    z.append(w)
     254            X = ','.join(A)
     255            r = self.new('%s%s%s'%(self._left_list_delim(), X, self._right_list_delim()))
     256            r.__sage_list = z   # do this to avoid having the entries of the list be garbage collected
     257            return r
     258
     259        raise TypeError, "unable to coerce element into %s"%self.name()
     260
     261    def new(self, code):
     262        return self(code)
     263
     264    ###################################################################
     265    # these should all be appropriately overloaded by the derived class
     266    ###################################################################
     267   
     268    def _left_list_delim(self):
     269        return "["
     270
     271    def _right_list_delim(self):
     272        return "]"
     273
     274    def _assign_symbol(self):
     275        return "="
     276   
     277    def _equality_symbol(self):
     278        raise NotImplementedError
     279
     280    # For efficiency purposes, you should definitely override these
     281    # in your derived class.
     282    def _true_symbol(self):
     283        try:
     284            return self.__true_symbol
     285        except AttributeError:
     286            self.__true_symbol = self.eval('1 %s 1'%self._equality_symbol())
     287
     288    def _false_symbol(self):
     289        try:
     290            return self.__false_symbol
     291        except AttributeError:
     292            self.__false_symbol = self.eval('1 %s 2'%self._equality_symbol())
     293
     294    def _lessthan_symbol(self):
     295        return '<'
     296
     297    def _greaterthan_symbol(self):
     298        return '>'
     299
     300    def _inequality_symbol(self):
     301        return '!='
     302
     303    def _relation_symbols(self):
     304        """
     305        Returns a dictionary with operators as the keys and their
     306        string representation as the values.
     307
     308        EXAMPLES::
     309
     310            sage: import operator
     311            sage: symbols = mathematica._relation_symbols()
     312            sage: symbols[operator.eq]
     313            '=='
     314        """
     315        return dict([(operator.eq, self._equality_symbol()), (operator.ne, self._inequality_symbol()),
     316                     (operator.lt, self._lessthan_symbol()), (operator.le, "<="),
     317                     (operator.gt, self._greaterthan_symbol()), (operator.ge, ">=")])
     318
     319    def _exponent_symbol(self):
     320        """
     321        Return the symbol used to denote *10^ in floats, e.g 'e' in 1.5e6
     322       
     323        EXAMPLES::
     324           
     325            sage: from sage.interfaces.expect import Expect
     326            sage: Expect('nonexistent_interface', 'fake')._exponent_symbol()
     327            'e'
     328        """
     329        return 'e'
     330
     331    ############################################################
     332    #         Functions for working with variables.
     333    #  The first three must be overloaded by derived classes,
     334    #  and the definition depends a lot on the class.  But
     335    #  the functionality one gets from this is very nice.
     336    ############################################################
     337
     338    def set(self, var, value):
     339        """
     340        Set the variable var to the given value.
     341        """
     342        cmd = '%s%s%s;'%(var,self._assign_symbol(), value)
     343        self.eval(cmd)
     344
     345    def get(self, var):
     346        """
     347        Get the value of the variable var.
     348        """
     349        return self.eval(var)
     350
     351    def get_using_file(self, var):
     352        r"""
     353        Return the string representation of the variable var in self,
     354        possibly using a file. Use this if var has a huge string
     355        representation, since it may be way faster.
     356       
     357        .. warning::
     358
     359           In fact unless a special derived class implements this, it
     360           will *not* be any faster. This is the case for this class
     361           if you're reading it through introspection and seeing this.
     362        """
     363        return self.get(var)
     364
     365    def clear(self, var):
     366        """
     367        Clear the variable named var.
     368        """
     369        self._available_vars.append(var)
     370   
     371    def _next_var_name(self):
     372        if len(self._available_vars) != 0:
     373            v = self._available_vars[0]
     374            del self._available_vars[0]
     375            return v
     376        self.__seq += 1
     377        return "sage%s"%self.__seq
     378
     379    def _create(self, value, name=None):
     380        name = self._next_var_name() if name is None else name
     381        self.set(name, value)
     382        return name
     383
     384    def _object_class(self):
     385        """
     386        EXAMPLES::
     387       
     388            sage: from sage.interfaces.expect import Expect
     389            sage: Expect._object_class(maxima)
     390            <class 'sage.interfaces.expect.ExpectElement'>
     391        """
     392        return InterfaceElement
     393
     394    def _function_class(self):
     395        """
     396        EXAMPLES::
     397       
     398            sage: from sage.interfaces.interface import Interface
     399            sage: Interface._function_class(maxima)
     400            <class 'sage.interfaces.interface.InterfaceFunction'>
     401        """
     402        return InterfaceFunction
     403
     404    def _function_element_class(self):
     405        """
     406        EXAMPLES::
     407       
     408            sage: from sage.interfaces.interface import Interface
     409            sage: Interface._function_element_class(maxima)
     410            <class 'sage.interfaces.interface.InterfaceFunctionElement'>
     411        """
     412        return InterfaceFunctionElement
     413
     414    def _convert_args_kwds(self, args=None, kwds=None):
     415        """
     416        Converts all of the args and kwds to be elements of this
     417        interface.
     418       
     419        EXAMPLES::
     420       
     421            sage: args = [5]
     422            sage: kwds = {'x': 6}
     423            sage: args, kwds = gap._convert_args_kwds(args, kwds)
     424            sage: args
     425            [5]
     426            sage: map(type, args)
     427            [<class 'sage.interfaces.gap.GapElement'>]
     428            sage: type(kwds['x'])
     429            <class 'sage.interfaces.gap.GapElement'>
     430        """
     431        args = [] if args is None else args
     432        kwds = {} if kwds is None else kwds
     433        if not isinstance(args, list):
     434            args = [args]
     435        for i, arg in enumerate(args):
     436            if not isinstance(arg, InterfaceElement) or arg.parent() is not self:
     437                args[i] = self(arg)
     438        for key, value in kwds.iteritems():
     439            if not isinstance(value, InterfaceElement) or value.parent() is not self:
     440                kwds[key] = self(value)
     441
     442        return args, kwds
     443
     444    def _check_valid_function_name(self, function):
     445        """
     446        Checks to see if function is a valid function name in this
     447        interface. If it is not, an exception is raised. Otherwise, nothing
     448        is done.
     449       
     450        EXAMPLES::
     451       
     452            sage: gap._check_valid_function_name('SymmetricGroup')
     453            sage: gap._check_valid_function_name('')
     454            Traceback (most recent call last):
     455            ...
     456            ValueError: function name must be nonempty
     457            sage: gap._check_valid_function_name('__foo')
     458            Traceback (most recent call last):
     459            ...
     460            AttributeError
     461        """
     462        if function == '':
     463            raise ValueError, "function name must be nonempty"
     464        if function[:2] == "__":
     465            raise AttributeError       
     466
     467    def function_call(self, function, args=None, kwds=None):
     468        """
     469        EXAMPLES::
     470       
     471            sage: maxima.quad_qags(x, x, 0, 1, epsrel=1e-4)
     472            [0.5,5.5511151231257...e-15,21,0]
     473            sage: maxima.function_call('quad_qags', [x, x, 0, 1], {'epsrel':'1e-4'})
     474            [0.5,5.5511151231257...e-15,21,0]
     475        """
     476        args, kwds = self._convert_args_kwds(args, kwds)
     477        self._check_valid_function_name(function)
     478        s = self._function_call_string(function,
     479                                       [s.name() for s in args],
     480                                       ['%s=%s'%(key,value.name()) for key, value in kwds.items()])
     481        return self.new(s)
     482
     483    def _function_call_string(self, function, args, kwds):
     484        """
     485        Returns the string used to make function calls.
     486       
     487        EXAMPLES::
     488
     489            sage: maxima._function_call_string('diff', ['f(x)', 'x'], [])
     490            'diff(f(x),x)'
     491        """
     492        return "%s(%s)"%(function, ",".join(list(args) + list(kwds)))
     493           
     494    def call(self, function_name, *args, **kwds):
     495        return self.function_call(function_name, args, kwds)
     496
     497    def _contains(self, v1, v2):
     498        raise NotImplementedError
     499   
     500    def __getattr__(self, attrname):
     501        """
     502        TESTS::
     503
     504            sage: ParentWithBase.__getattribute__(singular, '_coerce_map_from_')
     505            <built-in method _coerce_map_from_ of Singular object at ...>
     506        """
     507        try:
     508            return ParentWithBase.__getattribute__(self, attrname)
     509        except AttributeError:
     510            if attrname[:1] == "_":
     511                raise AttributeError
     512            return self._function_class()(self, attrname)
     513
     514    def __cmp__(self, other):
     515        """
     516        Compare two pseudo-tty interfaces. Two interfaces compare
     517        equal if and only if they are identical objects (this is a
     518        critical constraint so that caching of representations of
     519        objects in interfaces works correctly). Otherwise they are
     520        never equal.
     521       
     522        EXAMPLES::
     523       
     524            sage: Maxima() == maxima
     525            False
     526            sage: maxima == maxima
     527            True
     528        """
     529        if self is other:
     530            return 0
     531        c = cmp(type(self), type(other))
     532        if c:
     533            return c
     534        return -1  # sucky, but I can't think of anything better; it is important that different interfaces to the same system still compare differently; unfortunately there is nothing to distinguish them.
     535
     536    def console(self):
     537        raise NotImplementedError
     538
     539    def help(self, s):
     540        return AsciiArtString('No help on %s available'%s)
     541   
     542
     543class InterfaceFunction(SageObject):
     544    """
     545    Interface function.
     546    """
     547    def __init__(self, parent, name):
     548        self._parent = parent
     549        self._name = name
     550       
     551    def __repr__(self):
     552        return "%s"%self._name
     553   
     554    def __call__(self, *args, **kwds):
     555        return self._parent.function_call(self._name, list(args), kwds)
     556       
     557    def _sage_doc_(self):
     558        """
     559        EXAMPLES::
     560       
     561            sage: gp.gcd._sage_doc_()
     562            'gcd(x,{y}): greatest common divisor of x and y.'
     563        """
     564        M = self._parent
     565        return M.help(self._name)
     566       
     567       
     568class InterfaceFunctionElement(SageObject):
     569    """
     570    Interface function element.
     571    """
     572    def __init__(self, obj, name):
     573        self._obj = obj
     574        self._name = name
     575
     576    def __repr__(self):
     577        return "%s"%self._name
     578
     579    def __call__(self, *args, **kwds):
     580        return self._obj.parent().function_call(self._name, [self._obj] + list(args), kwds)
     581   
     582    def help(self):
     583        print self._sage_doc_()
     584
     585    def _sage_doc_(self):
     586        """
     587        EXAMPLES::
     588       
     589            sage: gp(2).gcd._sage_doc_()
     590            'gcd(x,{y}): greatest common divisor of x and y.'
     591        """
     592        M = self._obj.parent()
     593        return M.help(self._name)
     594
     595
     596
     597def is_InterfaceElement(x):
     598    return isinstance(x, InterfaceElement)
     599
     600class InterfaceElement(RingElement):
     601    """
     602    Interface element.
     603    """
     604    def __init__(self, parent, value, is_name=False, name=None):
     605        RingElement.__init__(self, parent)
     606        self._create = value
     607        if parent is None: return     # means "invalid element"
     608        # idea: Joe Wetherell -- try to find out if the output
     609        # is too long and if so get it using file, otherwise
     610        # don't.
     611           
     612        if is_name:
     613            self._name = value
     614        else:
     615            try:
     616                self._name = parent._create(value, name=name)
     617            except (TypeError, KeyboardInterrupt, RuntimeError, ValueError), x:
     618                raise TypeError, x
     619
     620    def _latex_(self):
     621#        return "\\begin{verbatim}%s\\end{verbatim}"%self
     622        string = str(self)
     623        if not '|' in string:
     624            delim = '|'
     625        elif not '#' in string:
     626            delim = '#'
     627        elif not '@' in string:
     628            delim = '@'
     629        elif not '~' in string:
     630            delim = '~'
     631        return "\\verb%s%s%s"%(delim, string, delim)
     632
     633    def __iter__(self):
     634        for i in range(1, len(self)+1):
     635            yield self[i]
     636
     637    def __len__(self):
     638        """
     639        Call self.sage() and return the length of that sage object.
     640       
     641        This approach is inefficient - each interface should override
     642        this method with one that calls the external program's length
     643        function.
     644       
     645        EXAMPLES::
     646       
     647            sage: len(gp([1,2,3]))
     648            3
     649       
     650        AUTHORS:
     651       
     652        - Felix Lawrence (2009-08-21)
     653        """
     654        return len(self.sage())
     655
     656    def __reduce__(self):
     657        return reduce_load, (self.parent(), self._reduce())
     658
     659    def _reduce(self):
     660        return repr(self)
     661
     662    def __call__(self, *args):
     663        self._check_valid()               
     664        P = self.parent()
     665        return getattr(P, self.name())(*args)
     666
     667    def __contains__(self, x):
     668        P = self._check_valid()               
     669        if not isinstance(x, InterfaceElement) or x.parent() is not self.parent():
     670            x = P.new(x)
     671        return P._contains(x.name(), self.name())
     672
     673
     674    def _sage_doc_(self):
     675        """
     676        EXAMPLES::
     677       
     678            sage: gp(2)._sage_doc_()
     679            '2'
     680        """
     681        return str(self)
     682
     683    def __hash__(self):
     684        """
     685        Returns the hash of self. This is a default implementation of hash
     686        which just takes the hash of the string of self.
     687        """
     688        return hash('%s'%(self))
     689   
     690    def __cmp__(self, other):
     691        P = self.parent()
     692        if P.eval("%s %s %s"%(self.name(), P._equality_symbol(),
     693                                 other.name())) == P._true_symbol():
     694            return 0
     695        elif P.eval("%s %s %s"%(self.name(), P._lessthan_symbol(), other.name())) == P._true_symbol():
     696            return -1
     697        elif P.eval("%s %s %s"%(self.name(), P._greaterthan_symbol(), other.name())) == P._true_symbol():
     698            return 1
     699
     700        # everything is supposed to be comparable in Python, so we define
     701        # the comparison thus when no comparison is available in interfaced system.
     702        if (hash(self) < hash(other)):
     703            return -1
     704        else:
     705            return 1
     706
     707    def _matrix_(self, R):
     708        raise NotImplementedError
     709
     710    def _vector_(self, R):
     711        raise NotImplementedError
     712
     713    def _check_valid(self):
     714        """
     715        Check that this object is valid, i.e., the session in which this
     716        object is defined is still running. This is relevant for
     717        interpreters that can't be interrupted via ctrl-C, hence get
     718        restarted.
     719        """
     720        try:
     721            P = self.parent()
     722            if P is None:
     723                raise ValueError, "The %s session in which this object was defined is no longer running."%P.name()
     724        except AttributeError:
     725            raise ValueError, "The session in which this object was defined is no longer running."
     726        return P
     727
     728    def __del__(self):
     729        try:
     730            self._check_valid()
     731        except ValueError:
     732            return
     733        if hasattr(self,'_name'):
     734            P = self.parent()
     735            if not (P is None):
     736                P.clear(self._name)
     737               
     738    def _sage_repr(self):
     739        """
     740        Return a sage-friendly string representation of the object.
     741       
     742        Some programs use different notation to Sage, e.g. Mathematica
     743        writes lists with {} instead of [].  This method calls repr(self)
     744        then converts the foreign notation into Sage's notation.
     745       
     746        OUTPUT:
     747       
     748        A string representation of the object that is ready for
     749        sage_eval().
     750       
     751        EXAMPLES::
     752       
     753            sage: repr(mathematica([1,2,3]))    # optional - mathematica
     754            '{1, 2, 3}'
     755            sage: mathematica([1,2,3])._sage_repr() # optional - mathematica
     756            '[1, 2, 3]'
     757       
     758        ::
     759       
     760            sage: gp(10.^80)._sage_repr()
     761            '1.0000000000000000000000000000000000000e80'    # 64-bit
     762            '1.000000000000000000000000000e80'              # 32-bit
     763            sage: mathematica('10.^80')._sage_repr()  # optional - mathematica
     764            '1.e80'
     765       
     766        AUTHORS:
     767       
     768        - Felix Lawrence (2009-08-21)
     769        """
     770        #TO DO: this could use file transfers when self.is_remote()
     771       
     772        string = repr(self).replace('\n',' ').replace('\r', '')
     773        # Translate the external program's list formatting to Sage's
     774        lld = self.parent()._left_list_delim()
     775        if '[' != lld:      string = string.replace(lld, '[')
     776        rld = self.parent()._right_list_delim()
     777        if ']' != rld:      string = string.replace(rld, ']')
     778        # Translate the external program's exponent formatting
     779        expl = self.parent()._exponent_symbol()
     780        if 'e' != expl: string = string.replace(expl, 'e')
     781        return string
     782
     783    def _sage_(self):
     784        """
     785        Attempt to return a Sage version of this object.
     786        This is a generic routine that just tries to evaluate
     787        the repr(self).
     788
     789        EXAMPLES::
     790       
     791            sage: gp(1/2)._sage_()
     792            1/2
     793            sage: _.parent()
     794            Rational Field
     795       
     796        AUTHORS:
     797       
     798        - William Stein
     799       
     800        - Felix Lawrence (2009-08-21)
     801        """
     802        try:
     803            return sage_eval(self._sage_repr())
     804        except:
     805            raise NotImplementedError
     806       
     807
     808    def sage(self):
     809        """
     810        Attempt to return a Sage version of this object.
     811
     812        EXAMPLES::
     813       
     814            sage: gp(1/2).sage()
     815            1/2
     816            sage: _.parent()
     817            Rational Field
     818        """
     819        return self._sage_()
     820       
     821    def __repr__(self):
     822        self._check_valid()
     823        try:
     824            if self._get_using_file:
     825                s = self.parent().get_using_file(self._name)
     826        except AttributeError:
     827            s = self.parent().get(self._name)
     828        if s.__contains__(self._name):
     829            if hasattr(self, '__custom_name'):
     830                s =  s.replace(self._name, self.__dict__['__custom_name'])
     831        return s
     832
     833    def __getattr__(self, attrname):
     834        P = self._check_valid()
     835        if attrname[:1] == "_":
     836            raise AttributeError
     837        return P._function_element_class()(self, attrname)
     838
     839    def get_using_file(self):
     840        """
     841        Return this element's string representation using a file. Use this
     842        if self has a huge string representation. It'll be way faster.
     843       
     844        EXAMPLES::
     845       
     846            sage: a = maxima(str(2^1000))
     847            sage: a.get_using_file()
     848            '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376'
     849        """
     850        try:
     851            self._check_valid()
     852        except ValueError:
     853            return '(invalid object -- defined in terms of closed session)'
     854        return self.parent().get_using_file(self._name)
     855
     856    def hasattr(self, attrname):
     857        """
     858        Returns whether the given attribute is already defined by this
     859        object, and in particular is not dynamically generated.
     860       
     861        EXAMPLES::
     862       
     863            sage: m = maxima('2')
     864            sage: m.hasattr('integral')
     865            True
     866            sage: m.hasattr('gcd')
     867            False
     868        """
     869        return not isinstance(getattr(self, attrname), InterfaceFunctionElement)
     870
     871    def attribute(self, attrname):
     872        """
     873        If this wraps the object x in the system, this returns the object
     874        x.attrname. This is useful for some systems that have object
     875        oriented attribute access notation.
     876       
     877        EXAMPLES::
     878       
     879            sage: g = gap('SO(1,4,7)')
     880            sage: k = g.InvariantQuadraticForm()
     881            sage: k.attribute('matrix')
     882            [ [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), 0*Z(7) ],
     883              [ 0*Z(7), 0*Z(7), Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ]
     884       
     885        ::
     886       
     887            sage: e = gp('ellinit([0,-1,1,-10,-20])')
     888            sage: e.attribute('j')
     889            -122023936/161051
     890        """
     891        P = self._check_valid()
     892        return P('%s.%s'%(self.name(), attrname))
     893
     894    def __getitem__(self, n):
     895        P = self._check_valid()
     896        if not isinstance(n, tuple):
     897            return P.new('%s[%s]'%(self._name, n))
     898        else:
     899            return P.new('%s[%s]'%(self._name, str(n)[1:-1]))
     900   
     901    def __int__(self):
     902        """
     903        EXAMPLES::
     904       
     905            sage: int(maxima('1'))
     906            1
     907            sage: type(_)
     908            <type 'int'>
     909        """
     910        return int(repr(self))
     911
     912    def bool(self):
     913        P = self.parent()
     914        t = P._true_symbol()
     915        cmd = '%s %s %s'%(self._name, P._equality_symbol(), t)
     916        return P.eval(cmd) == t
     917
     918    def __nonzero__(self):
     919        """
     920        EXAMPLES::
     921       
     922            sage: bool(maxima(0))
     923            False
     924            sage: bool(maxima(1))
     925            True
     926        """
     927        return self.bool()
     928
     929    def __long__(self):
     930        """
     931        EXAMPLES::
     932       
     933            sage: m = maxima('1')
     934            sage: long(m)
     935            1L
     936        """
     937        return long(repr(self))
     938
     939    def __float__(self):
     940        """
     941        EXAMPLES::
     942       
     943            sage: m = maxima('1/2')
     944            sage: m.__float__()
     945            0.5
     946            sage: float(m)
     947            0.5
     948        """
     949        return float(repr(self))
     950
     951    def _integer_(self, ZZ=None):
     952        """
     953        EXAMPLES::
     954       
     955            sage: m = maxima('1')
     956            sage: m._integer_()
     957            1
     958            sage: _.parent()
     959            Integer Ring
     960            sage: QQ(m)
     961            1
     962        """
     963        import sage.rings.all
     964        return sage.rings.all.Integer(repr(self))
     965
     966    def _rational_(self):
     967        """
     968        EXAMPLES::
     969       
     970            sage: m = maxima('1/2')
     971            sage: m._rational_()
     972            1/2
     973            sage: _.parent()
     974            Rational Field
     975            sage: QQ(m)
     976            1/2
     977        """
     978        import sage.rings.all       
     979        return sage.rings.all.Rational(repr(self))
     980
     981    def name(self, new_name=None):
     982        """
     983        Returns the name of self. If new_name is passed in, then this
     984        function returns a new object identical to self whose name is
     985        new_name.
     986       
     987        Note that this can overwrite existing variables in the system.
     988       
     989        EXAMPLES::
     990       
     991            sage: x = r([1,2,3]); x
     992            [1] 1 2 3
     993            sage: x.name()
     994            'sage3'
     995            sage: x = r([1,2,3]).name('x'); x
     996            [1] 1 2 3
     997            sage: x.name()
     998            'x'
     999       
     1000        ::
     1001       
     1002            sage: s5 = gap.SymmetricGroup(5).name('s5')
     1003            sage: s5
     1004            SymmetricGroup( [ 1 .. 5 ] )
     1005            sage: s5.name()
     1006            's5'
     1007        """
     1008        if new_name is not None:
     1009            if not isinstance(new_name, str):
     1010                raise TypeError, "new_name must be a string"
     1011            p = self.parent()
     1012            p.set(new_name, self._name)
     1013            return p._object_class()(p, new_name, is_name=True)
     1014           
     1015        return self._name
     1016
     1017    def gen(self, n):
     1018        P = self._check_valid()
     1019        return P.new('%s.%s'%(self._name, int(n)))
     1020
     1021    def _operation(self, operation, right):
     1022        P = self._check_valid()
     1023        try:
     1024            return P.new('%s %s %s'%(self._name, operation, right._name))
     1025        except Exception, msg:
     1026            raise TypeError, msg
     1027
     1028    def _add_(self, right):
     1029        """
     1030        EXAMPLES::
     1031       
     1032            sage: f = maxima.cos(x)
     1033            sage: g = maxima.sin(x)
     1034            sage: f + g
     1035            sin(x)+cos(x)
     1036            sage: f + 2
     1037            cos(x)+2
     1038            sage: 2 + f
     1039            cos(x)+2
     1040        """
     1041        return self._operation("+", right)
     1042       
     1043    def _sub_(self, right):
     1044        """
     1045        EXAMPLES::
     1046       
     1047            sage: f = maxima.cos(x)
     1048            sage: g = maxima.sin(x)
     1049            sage: f - g
     1050            cos(x)-sin(x)
     1051            sage: f - 2
     1052            cos(x)-2
     1053            sage: 2 - f
     1054            2-cos(x)
     1055        """
     1056        return self._operation('-', right)       
     1057
     1058    def _mul_(self, right):
     1059        """
     1060        EXAMPLES::
     1061       
     1062            sage: f = maxima.cos(x)
     1063            sage: g = maxima.sin(x)
     1064            sage: f*g
     1065            cos(x)*sin(x)
     1066            sage: 2*f
     1067            2*cos(x)
     1068        """
     1069        return self._operation('*', right)
     1070
     1071    def _div_(self, right):
     1072        """       
     1073        EXAMPLES::
     1074       
     1075            sage: f = maxima.cos(x)
     1076            sage: g = maxima.sin(x)
     1077            sage: f/g
     1078            cos(x)/sin(x)
     1079            sage: f/2
     1080            cos(x)/2
     1081        """
     1082        return self._operation("/", right)
     1083
     1084    def __pow__(self, n):
     1085        """
     1086        EXAMPLES::
     1087       
     1088            sage: a = maxima('2')
     1089            sage: a^(3/4)
     1090            2^(3/4)
     1091        """
     1092        P = self._check_valid()
     1093        if not hasattr(n, 'parent') or P is not n.parent():
     1094            n = P(n)
     1095        return self._operation("^", n)
     1096
     1097def reduce_load(parent, x):
     1098    return parent(x)
  • sage/interfaces/maxima.py

    diff -r d737d04798ad -r 8c40382f9433 sage/interfaces/maxima.py
    a b  
    4545    sage: F
    4646    -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
    4747    sage: type(F)
    48     <class 'sage.interfaces.maxima_abstract.MaximaElement'>
     48    <class 'sage.interfaces.maxima.MaximaElement'>
    4949
    5050Note that Maxima objects can also be displayed using "ASCII art";
    5151to see a normal linear representation of any Maxima object x. Just
     
    451451
    452452import os, re, sys, subprocess
    453453import pexpect
    454 cygwin = os.uname()[0][:6]=="CYGWIN"
    455 
    456 from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString
    457 from pexpect import EOF
     454#cygwin = os.uname()[0][:6]=="CYGWIN"
    458455
    459456from random import randrange
    460457
     458from sage.misc.misc import DOT_SAGE, SAGE_ROOT
     459
    461460##import sage.rings.all
    462461import sage.rings.complex_number
    463462
    464 from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT
     463from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString
    465464
    466 from sage.misc.multireplace import multiple_replace
     465from maxima_abstract import MaximaAbstract, MaximaAbstractFunction, MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction
    467466
    468 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE
    469 
    470 import sage.server.support
    471 
    472 import maxima_abstract
    473 from maxima_abstract import MaximaFunctionElement, MaximaExpectFunction, MaximaElement, MaximaFunction, maxima_console
    474 
    475 # The Maxima "apropos" command, e.g., apropos(det) gives a list
    476 # of all identifiers that begin in a certain way.  This could
    477 # maybe be useful somehow... (?)  Also maxima has a lot for getting
    478 # documentation from the system -- this could also be useful.
    479 
    480 class Maxima(maxima_abstract.Maxima):
     467# Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected
     468class Maxima(MaximaAbstract, Expect):
    481469    """
    482470    Interface to the Maxima interpreter.
    483471    """
     
    493481
    494482        We make sure labels are turned off (see trac 6816)::
    495483       
    496             sage: 'nolabels:true' in maxima._Expect__init_code
     484            sage: 'nolabels : true' in maxima._Expect__init_code
    497485            True
    498486        """
    499487        # TODO: Input and output prompts in maxima can be changed by
     
    509497        # this interface to preload commands, put them in
    510498        # $DOT_SAGE/maxima/maxima-init.mac
    511499        # (we use the "--userdir" option in maxima for this)
    512         import sage.misc.misc
    513         SAGE_MAXIMA_DIR = os.path.join(sage.misc.misc.DOT_SAGE,"maxima")
     500        SAGE_MAXIMA_DIR = os.path.join(DOT_SAGE,"maxima")
    514501       
    515502        if not os.path.exists(STARTUP):
    516503            raise RuntimeError, 'You must get the file local/bin/sage-maxima.lisp'
     
    525512        # Many thanks to andrej.vodopivec@gmail.com and also
    526513        # Robert Dodier for figuring this out!
    527514        # See trac # 6818. 
    528         init_code.append('nolabels:true')
    529        
    530        
    531        
     515        init_code.append('nolabels : true')
     516               
     517        MaximaAbstract.__init__(self,"maxima")
    532518        Expect.__init__(self,
    533519                        name = 'maxima',
    534520                        prompt = '\(\%i[0-9]+\)',
     
    552538
    553539
    554540
    555     def _function_class(self):
    556         """
    557         EXAMPLES::
    558        
    559             sage: maxima._function_class()
    560             <class 'sage.interfaces.maxima_abstract.MaximaExpectFunction'>
    561         """
    562         return MaximaExpectFunction
    563 
    564541    def _start(self):
    565542        """
    566543        Starts the Maxima interpreter.
     
    751728            o = out[m.end()+1:-2]
    752729        o = ''.join([x.strip() for x in o.split()])
    753730        return o
    754 
    755731       
    756732    def _synchronize(self):
    757733        """
     
    795771            self._crash_msg()
    796772            self.quit()
    797773
     774    def _batch(self, s, batchload=True):
     775        filename = '%s-%s'%(self._local_tmpfile(),randrange(2147483647))
     776        F = open(filename, 'w')
     777        F.write(s)
     778        F.close()
     779        if self.is_remote():
     780            self._send_tmpfile_to_server(local_file=filename)
     781            tmp_to_use = self._remote_tmpfile()
     782        tmp_to_use = filename
     783       
     784        if batchload:
     785            cmd = 'batchload("%s");'%tmp_to_use
     786        else:
     787            cmd = 'batch("%s");'%tmp_to_use
     788
     789        r = randrange(2147483647)
     790        s = str(r+1)
     791        cmd = "%s1+%s;\n"%(cmd,r)
     792
     793        self._sendline(cmd)
     794        self._expect_expr(s)
     795        out = self._before()
     796        self._error_check(str, out)
     797        os.unlink(filename)
     798        return out
     799
     800    def _quit_string(self):
     801        """
     802        EXAMPLES::
     803       
     804            sage: maxima._quit_string()
     805            'quit();'
     806        """
     807        return 'quit();'
     808
     809    def _crash_msg(self):
     810        """
     811        EXAMPLES::
     812       
     813            sage: maxima._crash_msg()
     814            Maxima crashed -- automatically restarting.
     815        """
     816        print "Maxima crashed -- automatically restarting."
     817
     818    def _error_check(self, str, out):
     819        r = self._error_re
     820        m = r.search(out)
     821        if not m is None:
     822            self._error_msg(str, out)
     823           
     824    def _error_msg(self, str, out):
     825        raise TypeError, "Error executing code in Maxima\nCODE:\n\t%s\nMaxima ERROR:\n\t%s"%(str, out.replace('-- an error.  To debug this try debugmode(true);',''))
     826
    798827    ###########################################
    799828    # Direct access to underlying lisp interpreter.
    800829    ###########################################
     
    817846        self._expect_expr('(%i)')
    818847        return self._before()
    819848
    820     ###########################################
    821     # Interactive help
    822     ###########################################
    823     def _command_runner(self, command, s, redirect=True):
    824         """
    825         Run ``command`` in a new Maxima session and return its
    826         output as an ``AsciiArtString``.
    827        
    828         If redirect is set to False, then the output of the command is not
    829         returned as a string. Instead, it behaves like os.system. This is
    830         used for interactive things like Maxima's demos. See maxima.demo?
    831        
    832         EXAMPLES::
    833        
    834             sage: maxima._command_runner('describe', 'gcd')
    835             -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
    836             ...
    837         """
    838         cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s)
    839         if sage.server.support.EMBEDDED_MODE:
    840             cmd += '< /dev/null'
    841 
    842         if redirect:
    843             p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
    844                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    845             res = p.stdout.read()
    846             # ecl-10.2 : 3 lines
    847             # ecl-10.4 : 5 lines
    848             # ecl-11.1 : 4 lines fancy a tango?
    849             # We now get 4 lines of commented verbosity
    850             # every time Maxima starts, so we need to get rid of them
    851             for _ in range(4):
    852                 res = res[res.find('\n')+1:]
    853             return AsciiArtString(res)
    854         else:
    855             subprocess.Popen(cmd, shell=True)
    856 
    857     def _object_class(self):
    858         """
    859         Return the Python class of Maxima elements.
    860        
    861         EXAMPLES::
    862        
    863             sage: maxima._object_class()
    864             <class 'sage.interfaces.maxima_abstract.MaximaElement'>
    865         """
    866         return MaximaElement
    867 
    868     def _function_element_class(self):
    869         """     
    870         EXAMPLES::
    871        
    872             sage: maxima._function_element_class()
    873             <class 'sage.interfaces.maxima_abstract.MaximaFunctionElement'>
    874         """
    875         return MaximaFunctionElement
    876 
    877     def function(self, args, defn, rep=None, latex=None):
    878         """
    879         Return the Maxima function with given arguments and definition.
    880        
    881         INPUT:
    882        
    883        
    884         -  ``args`` - a string with variable names separated by
    885            commas
    886        
    887         -  ``defn`` - a string (or Maxima expression) that
    888            defines a function of the arguments in Maxima.
    889        
    890         -  ``rep`` - an optional string; if given, this is how
    891            the function will print.
    892        
    893        
    894         EXAMPLES::
    895        
    896             sage: f = maxima.function('x', 'sin(x)')
    897             sage: f(3.2)
    898             -.058374143427580...
    899             sage: f = maxima.function('x,y', 'sin(x)+cos(y)')
    900             sage: f(2,3.5)
    901             sin(2)-.9364566872907963
    902             sage: f
    903             sin(x)+cos(y)
    904        
    905         ::
    906        
    907             sage: g = f.integrate('z')
    908             sage: g
    909             (cos(y)+sin(x))*z
    910             sage: g(1,2,3)
    911             3*(cos(2)+sin(1))
    912        
    913         The function definition can be a maxima object::
    914        
    915             sage: an_expr = maxima('sin(x)*gamma(x)')
    916             sage: t = maxima.function('x', an_expr)
    917             sage: t
    918             gamma(x)*sin(x)
    919             sage: t(2)
    920              sin(2)
    921             sage: float(t(2))
    922             0.90929742682568171
    923             sage: loads(t.dumps())
    924             gamma(x)*sin(x)
    925         """
    926         name = self._next_var_name()
    927         if isinstance(defn, MaximaElement):
    928             defn = defn.str()
    929         elif not isinstance(defn, str):
    930             defn = str(defn)
    931         if isinstance(args, MaximaElement):
    932             args = args.str()
    933         elif not isinstance(args, str):
    934             args = str(args)
    935         cmd = '%s(%s) := %s'%(name, args, defn)
    936         maxima._eval_line(cmd)
    937         if rep is None:
    938             rep = defn
    939         f = MaximaFunction(self, name, rep, args, latex)
    940         return f
     849    #####
     850    #
     851    #####
    941852
    942853    def set(self, var, value):
    943854        """
     
    999910        """
    1000911        s = self._eval_line('%s;'%var)
    1001912        return s
    1002    
    1003     def version(self):
     913
     914    def _function_class(self):
    1004915        """
    1005         Return the version of Maxima that Sage includes.
     916        EXAMPLES::
     917       
     918            sage: maxima._function_class()
     919            <class 'sage.interfaces.maxima.MaximaFunction'>
     920        """
     921        return MaximaFunction
     922
     923    def _object_class(self):
     924        """
     925        Return the Python class of Maxima elements.
    1006926       
    1007927        EXAMPLES::
    1008928       
    1009             sage: maxima.version()
    1010             '5.23.2'
     929            sage: maxima._object_class()
     930            <class 'sage.interfaces.maxima.MaximaElement'>
    1011931        """
    1012         return maxima_version()
     932        return MaximaElement
    1013933
    1014 ##some helper functions to wrap tha calculus use of the maxima interface.
    1015 ##these routines expect arguments living in the symbolic ring and return something
    1016 ##that is hopefully coercible into the symbolic ring again.
     934    def _function_element_class(self):
     935        """     
     936        EXAMPLES::
     937       
     938            sage: maxima._function_element_class()
     939            <class 'sage.interfaces.maxima.MaximaFunctionElement'>
     940        """
     941        return MaximaFunctionElement
     942
     943    def _object_function_class(self):
     944        """
     945        EXAMPLES::
     946       
     947            sage: maxima._object_function_class()
     948            <class 'sage.interfaces.maxima.MaximaElementFunction'>
     949        """
     950        return MaximaElementFunction
     951
     952    ##some helper functions to wrap tha calculus use of the maxima interface.
     953    ##these routines expect arguments living in the symbolic ring and return something
     954    ##that is hopefully coercible into the symbolic ring again.
    1017955
    1018956    def sr_integral(self,*args):
    1019957        return args[0]._maxima_().integrate(*args[1:])
     
    1029967
    1030968    def sr_tlimit(self,ex,*args):
    1031969        return ex._maxima_().tlimit(*args)
    1032    
    1033 ##     def display2d(self, flag=True):
    1034 ##         """
    1035 ##         Set the flag that determines whether Maxima objects are
    1036 ##         printed using their 2-d ASCII art representation.  When the
    1037 ##         maxima interface starts the default is that objects are not
    1038 ##         represented in 2-d.
    1039970
    1040 ##         INPUT:
    1041 ##             flag -- bool (default: True)
    1042 
    1043 ##         EXAMPLES
    1044 ##             sage: maxima('1/2')
    1045 ##             1/2
    1046 ##             sage: maxima.display2d(True)
    1047 ##             sage: maxima('1/2')
    1048 ##                                            1
    1049 ##                                            -
    1050 ##                                            2
    1051 ##             sage: maxima.display2d(False)
    1052 ##         """
    1053 ##         self._display2d = bool(flag)
    1054971
    1055972def is_MaximaElement(x):
    1056973    """
     
    1067984    """
    1068985    return isinstance(x, MaximaElement)
    1069986
     987# Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected
     988class MaximaElement(MaximaAbstractElement, ExpectElement):
     989    def __init__(self, parent, value, is_name=False, name=None):
     990        ExpectElement.__init__(self, parent, value, is_name=False, name=None)
     991
     992    def display2d(self, onscreen=True):
     993        """
     994        EXAMPLES::
     995       
     996            sage: F = maxima('x^5 - y^5').factor() 
     997            sage: F.display2d ()             
     998                                   4      3    2  2    3      4
     999                       - (y - x) (y  + x y  + x  y  + x  y + x )
     1000        """
     1001        self._check_valid()
     1002        P = self.parent()
     1003        with gc_disabled():
     1004            P._eval_line('display2d : true$')
     1005            s = P._eval_line('disp(%s)$'%self.name(), reformat=False)
     1006            P._eval_line('display2d : false$')
     1007           
     1008        s = s.strip('\r\n')
     1009
     1010        # if ever want to dedent, see
     1011        # http://mail.python.org/pipermail/python-list/2006-December/420033.html
     1012        if onscreen:
     1013            print s
     1014        else:
     1015            return s
     1016
     1017
     1018# Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected
     1019class MaximaFunctionElement(MaximaAbstractFunctionElement, FunctionElement):
     1020    pass
     1021#    def __init__(self, obj, name):
     1022#        MaximaAbstractFunctionElement.__init__(self, obj, name)
     1023#        FunctionElement.__init__(self, obj, name)
     1024
     1025
     1026# Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected
     1027class MaximaFunction(MaximaAbstractFunction, ExpectFunction):
     1028    pass
     1029#    def __init__(self, parent, name):
     1030#        MaximaAbstractFunction.__init__(self, parent, name)
     1031#        ExpectFunction.__init__(self, parent, name)
     1032
     1033
     1034# Thanks to the MRO for multiple inheritance used by the Sage's Python , this should work as expected
     1035class MaximaElementFunction(MaximaElement, MaximaAbstractElementFunction):
     1036    def __init__(self, parent, name, defn, args, latex):
     1037        MaximaElement.__init__(self, parent, name, is_name=True)
     1038        MaximaAbstractElementFunction.__init__(self, parent, name, defn, args, latex)
     1039
     1040
    10701041# An instance
    1071 maxima = Maxima(init_code = ['display2d:false; domain: complex; keepfloat: true'],
     1042maxima = Maxima(init_code = ['display2d : false; domain : complex; keepfloat : true'],
    10721043                script_subdirectory=None)
    10731044
     1045
    10741046def reduce_load_Maxima():
    10751047    """
    10761048    EXAMPLES::
     
    10811053    """
    10821054    return maxima
    10831055
    1084 
    1085 def maxima_version():
    1086     """
    1087     EXAMPLES::
    1088    
    1089         sage: from sage.interfaces.maxima import maxima_version
    1090         sage: maxima_version()
    1091         '5.23.2'
    1092     """
    1093     return os.popen('maxima --version').read().split()[-1]
     1056def reduce_load_Maxima_function(parent, defn, args, latex):
     1057    return parent.function(args, defn, defn, latex)
    10941058
    10951059def __doctest_cleanup():
    10961060    import sage.interfaces.quit
  • sage/interfaces/maxima_abstract.py

    diff -r d737d04798ad -r 8c40382f9433 sage/interfaces/maxima_abstract.py
    a b  
    2828
    2929If the string "error" (case insensitive) occurs in the output of
    3030anything from Maxima, a RuntimeError exception is raised.
    31 
    32 EXAMPLES: We evaluate a very simple expression in Maxima.
    33 
    34 ::
    35 
    36     sage: maxima('3 * 5')
    37     15
    38 
    39 We factor `x^5 - y^5` in Maxima in several different ways.
    40 The first way yields a Maxima object.
    41 
    42 ::
    43 
    44     sage: F = maxima.factor('x^5 - y^5')
    45     sage: F
    46     -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
    47     sage: type(F)
    48     <class 'sage.interfaces.maxima_abstract.MaximaElement'>
    49 
    50 Note that Maxima objects can also be displayed using "ASCII art";
    51 to see a normal linear representation of any Maxima object x. Just
    52 use the print command: use ``str(x)``.
    53 
    54 ::
    55 
    56     sage: print F
    57                                4      3    2  2    3      4
    58                    - (y - x) (y  + x y  + x  y  + x  y + x )
    59 
    60 You can always use ``repr(x)`` to obtain the linear
    61 representation of an object. This can be useful for moving maxima
    62 data to other systems.
    63 
    64 ::
    65 
    66     sage: repr(F)
    67     '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
    68     sage: F.str()
    69     '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
    70 
    71 The ``maxima.eval`` command evaluates an expression in
    72 maxima and returns the result as a *string* not a maxima object.
    73 
    74 ::
    75 
    76     sage: print maxima.eval('factor(x^5 - y^5)')
    77     -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
    78 
    79 We can create the polynomial `f` as a Maxima polynomial,
    80 then call the factor method on it. Notice that the notation
    81 ``f.factor()`` is consistent with how the rest of Sage
    82 works.
    83 
    84 ::
    85 
    86     sage: f = maxima('x^5 - y^5')
    87     sage: f^2
    88     (x^5-y^5)^2
    89     sage: f.factor()
    90     -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
    91 
    92 Control-C interruption works well with the maxima interface,
    93 because of the excellent implementation of maxima. For example, try
    94 the following sum but with a much bigger range, and hit control-C.
    95 
    96 ::
    97 
    98     sage: maxima('sum(1/x^2, x, 1, 10)')
    99     1968329/1270080
    100 
    101 Tutorial
    102 --------
    103 
    104 We follow the tutorial at
    105 http://maxima.sourceforge.net/docs/intromax/.
    106 
    107 ::
    108 
    109     sage: maxima('1/100 + 1/101')
    110     201/10100
    111 
    112 ::
    113 
    114     sage: a = maxima('(1 + sqrt(2))^5'); a
    115     (sqrt(2)+1)^5
    116     sage: a.expand()
    117     3*2^(7/2)+5*sqrt(2)+41
    118 
    119 ::
    120 
    121     sage: a = maxima('(1 + sqrt(2))^5')
    122     sage: float(a)               
    123     82.012193308819747
    124     sage: a.numer()
    125     82.01219330881975
    126 
    127 ::
    128 
    129     sage: maxima.eval('fpprec : 100')
    130     '100'
    131     sage: a.bfloat()
    132     8.20121933088197564152489730020812442785204843859314941221237124017312418754011041266612384955016056b1
    133 
    134 ::
    135 
    136     sage: maxima('100!')
    137     93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
    138 
    139 ::
    140 
    141     sage: f = maxima('(x + 3*y + x^2*y)^3')
    142     sage: f.expand()
    143     x^6*y^3+9*x^4*y^3+27*x^2*y^3+27*y^3+3*x^5*y^2+18*x^3*y^2+27*x*y^2+3*x^4*y+9*x^2*y+x^3
    144     sage: f.subst('x=5/z')
    145     (5/z+25*y/z^2+3*y)^3
    146     sage: g = f.subst('x=5/z')
    147     sage: h = g.ratsimp(); h
    148     (27*y^3*z^6+135*y^2*z^5+(675*y^3+225*y)*z^4+(2250*y^2+125)*z^3+(5625*y^3+1875*y)*z^2+9375*y^2*z+15625*y^3)/z^6
    149     sage: h.factor()
    150     (3*y*z^2+5*z+25*y)^3/z^6
    151 
    152 ::
    153 
    154     sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])
    155     sage: s = eqn.solve('[a,b,c]'); s
    156     [[a=(25*sqrt(79)*%i+25)/(6*sqrt(79)*%i-34),b=(5*sqrt(79)*%i+5)/(sqrt(79)*%i+11),c=(sqrt(79)*%i+1)/10],[a=(25*sqrt(79)*%i-25)/(6*sqrt(79)*%i+34),b=(5*sqrt(79)*%i-5)/(sqrt(79)*%i-11),c=-(sqrt(79)*%i-1)/10]]
    157 
    158 Here is an example of solving an algebraic equation::
    159 
    160     sage: maxima('x^2+y^2=1').solve('y')
    161     [y=-sqrt(1-x^2),y=sqrt(1-x^2)]
    162     sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')
    163     [y=-sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2),y=sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2)]
    164 
    165 You can even nicely typeset the solution in latex::
    166 
    167     sage: latex(s)
    168     \left[ \left[ a={{25\,\sqrt{79}\,i+25}\over{6\,\sqrt{79}\,i-34}} ,   b={{5\,\sqrt{79}\,i+5}\over{\sqrt{79}\,i+11}} , c={{\sqrt{79}\,i+1  }\over{10}} \right]  , \left[ a={{25\,\sqrt{79}\,i-25}\over{6\,  \sqrt{79}\,i+34}} , b={{5\,\sqrt{79}\,i-5}\over{\sqrt{79}\,i-11}} ,   c=-{{\sqrt{79}\,i-1}\over{10}} \right]  \right]
    169 
    170 To have the above appear onscreen via ``xdvi``, type
    171 ``view(s)``. (TODO: For OS X should create pdf output
    172 and use preview instead?)
    173 
    174 ::
    175 
    176     sage: e = maxima('sin(u + v) * cos(u)^3'); e
    177     cos(u)^3*sin(v+u)
    178     sage: f = e.trigexpand(); f
    179     cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))
    180     sage: f.trigreduce()
    181     (sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8
    182     sage: w = maxima('3 + k*%i')
    183     sage: f = w^2 + maxima('%e')^w
    184     sage: f.realpart()
    185     %e^3*cos(k)-k^2+9
    186 
    187 ::
    188 
    189     sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f
    190     x^3*%e^(k*x)*sin(w*x)
    191     sage: f.diff('x')
    192     k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x)*cos(w*x)
    193     sage: f.integrate('x')
    194     (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3+(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(-18*k*w^4-12*k^3*w^2+6*k^5)*x-6*w^4+36*k^2*w^2-6*k^4)*%e^(k*x)*sin(w*x)+((-w^7-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3+24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8)
    195 
    196 ::
    197 
    198     sage: f = maxima('1/x^2')
    199     sage: f.integrate('x', 1, 'inf')
    200     1
    201     sage: g = maxima('f/sinh(k*x)^4')
    202     sage: g.taylor('x', 0, 3)
    203     f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945
    204 
    205 ::
    206 
    207     sage: maxima.taylor('asin(x)','x',0, 10)
    208     x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152
    209 
    210 Examples involving matrices
    211 ---------------------------
    212 
    213 We illustrate computing with the matrix whose `i,j` entry
    214 is `i/j`, for `i,j=1,\ldots,4`.
    215 
    216 ::
    217 
    218     sage: f = maxima.eval('f[i,j] := i/j')
    219     sage: A = maxima('genmatrix(f,4,4)'); A
    220     matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])
    221     sage: A.determinant()
    222     0
    223     sage: A.echelon()
    224     matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])
    225     sage: A.eigenvalues()
    226     [[0,4],[3,1]]
    227     sage: A.eigenvectors()
    228     [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]
    229 
    230 We can also compute the echelon form in Sage::
    231 
    232     sage: B = matrix(QQ, A)
    233     sage: B.echelon_form()
    234     [  1 1/2 1/3 1/4]
    235     [  0   0   0   0]
    236     [  0   0   0   0]
    237     [  0   0   0   0]
    238     sage: B.charpoly('x').factor()
    239     (x - 4) * x^3
    240 
    241 Laplace Transforms
    242 ------------------
    243 
    244 We illustrate Laplace transforms::
    245 
    246     sage: _ = maxima.eval("f(t) := t*sin(t)")
    247     sage: maxima("laplace(f(t),t,s)")
    248     2*s/(s^2+1)^2
    249 
    250 ::
    251 
    252     sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function
    253     %e^-(3*s)
    254 
    255 ::
    256 
    257     sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")
    258     sage: maxima("laplace(f(t),t,s)")
    259     1/(s^2-2*s+2)
    260 
    261 ::
    262 
    263     sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")
    264     sage: maxima("laplace(f(t),t,s)")
    265     360*(2*s-2)/(s^2-2*s+2)^4-480*(2*s-2)^3/(s^2-2*s+2)^5+120*(2*s-2)^5/(s^2-2*s+2)^6
    266     sage: print maxima("laplace(f(t),t,s)")
    267                                              3                 5
    268                360 (2 s - 2)    480 (2 s - 2)     120 (2 s - 2)
    269               --------------- - --------------- + ---------------
    270                 2           4     2           5     2           6
    271               (s  - 2 s + 2)    (s  - 2 s + 2)    (s  - 2 s + 2)
    272 
    273 ::
    274 
    275     sage: maxima("laplace(diff(x(t),t),t,s)")
    276     s*'laplace(x(t),t,s)-x(0)
    277 
    278 ::
    279 
    280     sage: maxima("laplace(diff(x(t),t,2),t,s)")
    281     -?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s
    282 
    283 It is difficult to read some of these without the 2d
    284 representation::
    285 
    286     sage: print maxima("laplace(diff(x(t),t,2),t,s)")
    287                          !
    288                 d        !         2
    289               - -- (x(t))!      + s  laplace(x(t), t, s) - x(0) s
    290                 dt       !
    291                          !t = 0
    292 
    293 Even better, use
    294 ``view(maxima("laplace(diff(x(t),t,2),t,s)"))`` to see
    295 a typeset version.
    296 
    297 Continued Fractions
    298 -------------------
    299 
    300 A continued fraction `a + 1/(b + 1/(c + \cdots))` is
    301 represented in maxima by the list `[a, b, c, \ldots]`.
    302 
    303 ::
    304 
    305     sage: maxima("cf((1 + sqrt(5))/2)")
    306     [1,1,1,1,2]
    307     sage: maxima("cf ((1 + sqrt(341))/2)")
    308     [9,1,2,1,2,1,17,1,2,1,2,1,17,1,2,1,2,1,17,2]
    309 
    310 Special examples
    311 ----------------
    312 
    313 In this section we illustrate calculations that would be awkward to
    314 do (as far as I know) in non-symbolic computer algebra systems like
    315 MAGMA or GAP.
    316 
    317 We compute the gcd of `2x^{n+4} - x^{n+2}` and
    318 `4x^{n+1} + 3x^n` for arbitrary `n`.
    319 
    320 ::
    321 
    322     sage: f = maxima('2*x^(n+4) - x^(n+2)')
    323     sage: g = maxima('4*x^(n+1) + 3*x^n')
    324     sage: f.gcd(g)
    325     x^n
    326 
    327 You can plot 3d graphs (via gnuplot)::
    328 
    329     sage: maxima('plot3d(x^2-y^2, [x,-2,2], [y,-2,2], [grid,12,12])')  # not tested
    330     [displays a 3 dimensional graph]
    331 
    332 You can formally evaluate sums (note the ``nusum``
    333 command)::
    334 
    335     sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')
    336     sage: print S
    337                             2/n + 3                   2/n + 1
    338                           %e                        %e
    339                    ----------------------- - -----------------------
    340                       1/n         1/n           1/n         1/n
    341                    (%e    - 1) (%e    + 1)   (%e    - 1) (%e    + 1)
    342 
    343 We formally compute the limit as `n\to\infty` of
    344 `2S/n` as follows::
    345 
    346     sage: T = S*maxima('2/n')
    347     sage: T.tlimit('n','inf')
    348     %e^3-%e
    349 
    350 Miscellaneous
    351 -------------
    352 
    353 Obtaining digits of `\pi`::
    354 
    355     sage: maxima.eval('fpprec : 100')
    356     '100'
    357     sage: maxima(pi).bfloat()
    358     3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068b0
    359 
    360 Defining functions in maxima::
    361 
    362     sage: maxima.eval('fun[a] := a^2')
    363     'fun[a]:=a^2'
    364     sage: maxima('fun[10]')
    365     100
    366 
    367 Interactivity
    368 -------------
    369 
    370 Unfortunately maxima doesn't seem to have a non-interactive mode,
    371 which is needed for the Sage interface. If any Sage call leads to
    372 maxima interactively answering questions, then the questions can't be
    373 answered and the maxima session may hang. See the discussion at
    374 http://www.ma.utexas.edu/pipermail/maxima/2005/011061.html for some
    375 ideas about how to fix this problem. An example that illustrates this
    376 problem is ``maxima.eval('integrate (exp(a*x), x, 0, inf)')``.
    377 
    378 Latex Output
    379 ------------
    380 
    381 To TeX a maxima object do this::
    382 
    383     sage: latex(maxima('sin(u) + sinh(v^2)'))
    384     \sinh v^2+\sin u
    385 
    386 Here's another example::
    387 
    388     sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c')
    389     sage: latex(g)
    390     -{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c
    391 
    392 Long Input
    393 ----------
    394 
    395 The MAXIMA interface reads in even very long input (using files) in
    396 a robust manner, as long as you are creating a new object.
    397 
    398 .. note::
    399 
    400    Using ``maxima.eval`` for long input is much less robust, and is
    401    not recommended.
    402 
    403 ::
    404 
    405     sage: t = '"%s"'%10^10000   # ten thousand character string.
    406     sage: a = maxima(t)
    407 
    408 TESTS: This working tests that a subtle bug has been fixed::
    409 
    410     sage: f = maxima.function('x','gamma(x)')
    411     sage: g = f(1/7)
    412     sage: g
    413     gamma(1/7)
    414     sage: del f
    415     sage: maxima(sin(x))
    416     sin(x)
    417 
    418 This tests to make sure we handle the case where Maxima asks if an
    419 expression is positive or zero.
    420 
    421 ::
    422 
    423     sage: var('Ax,Bx,By')
    424     (Ax, Bx, By)
    425     sage: t = -Ax*sin(sqrt(Ax^2)/2)/(sqrt(Ax^2)*sqrt(By^2 + Bx^2))
    426     sage: t.limit(Ax=0, dir='+')
    427     0
    428 
    429 A long complicated input expression::
    430 
    431     sage: maxima._eval_line('((((((((((0) + ((1) / ((n0) ^ (0)))) + ((1) / ((n1) ^ (1)))) + ((1) / ((n2) ^ (2)))) + ((1) / ((n3) ^ (3)))) + ((1) / ((n4) ^ (4)))) + ((1) / ((n5) ^ (5)))) + ((1) / ((n6) ^ (6)))) + ((1) / ((n7) ^ (7)))) + ((1) / ((n8) ^ (8)))) + ((1) / ((n9) ^ (9)));')
    432     '1/n9^9+1/n8^8+1/n7^7+1/n6^6+1/n5^5+1/n4^4+1/n3^3+1/n2^2+1/n1+1'
    43331"""
    43432
    43533#*****************************************************************************
     
    44745#                  http://www.gnu.org/licenses/
    44846#*****************************************************************************
    44947
    450 from __future__ import with_statement
     48import os, re, sys, subprocess
    45149
    452 import os, re, sys, subprocess
    453 import pexpect
    454 cygwin = os.uname()[0][:6]=="CYGWIN"
     50from sage.misc.misc import DOT_SAGE
     51COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE
    45552
    456 from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString
    457 from pexpect import EOF
     53from sage.misc.multireplace import multiple_replace
    45854
    459 from random import randrange
     55import sage.server.support
    46056
    46157##import sage.rings.all
    46258import sage.rings.complex_number
    46359
    464 from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT
    465 
    466 from sage.misc.multireplace import multiple_replace
    467 
    468 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE
    469 
    470 import sage.server.support
     60from interface import Interface, InterfaceElement, InterfaceFunctionElement, InterfaceFunction, AsciiArtString
    47161
    47262# The Maxima "apropos" command, e.g., apropos(det) gives a list
    47363# of all identifiers that begin in a certain way.  This could
    47464# maybe be useful somehow... (?)  Also maxima has a lot for getting
    47565# documentation from the system -- this could also be useful.
    47666
    477 class Maxima(Expect):
     67class MaximaAbstract(Interface):
    47868    """
    47969    Interface to the Maxima interpreter.
    48070    """
    481     def __init__(self, script_subdirectory=None, logfile=None, server=None,
    482                  init_code = None):
     71    def __init__(self, name):
    48372        """
    484         Create an instance of the Maxima interpreter.
    485 
    486         TESTS::
    487        
    488             sage: maxima == loads(dumps(maxima))
    489             True
    490 
    491         We make sure labels are turned off (see trac 6816)::
    492        
    493             sage: 'nolabels:true' in maxima._Expect__init_code
    494             True
     73        Create an instance of an abstract interface to Maxima.
    49574        """
    496         # TODO: Input and output prompts in maxima can be changed by
    497         # setting inchar and outchar..
    498         eval_using_file_cutoff = 256
    499         self.__eval_using_file_cutoff = eval_using_file_cutoff
    500         STARTUP = '%s/local/bin/sage-maxima.lisp'%SAGE_ROOT
    501        
    502         # We set maxima's configuration directory to $DOT_SAGE/maxima
    503         # This avoids that sage's maxima inadvertently loads
    504         # ~/.maxima/maxima-init.mac
    505         # If you absolutely want maxima instances that are started by
    506         # this interface to preload commands, put them in
    507         # $DOT_SAGE/maxima/maxima-init.mac
    508         # (we use the "--userdir" option in maxima for this)
    509         import sage.misc.misc
    510         SAGE_MAXIMA_DIR = os.path.join(sage.misc.misc.DOT_SAGE,"maxima")
    511        
    512         if not os.path.exists(STARTUP):
    513             raise RuntimeError, 'You must get the file local/bin/sage-maxima.lisp'
    514         if init_code is None:
    515             # display2d -- no ascii art output
    516             # keepfloat -- don't automatically convert floats to rationals
    517             init_code = ['display2d : false', 'keepfloat : true']
    518            
    519         # Turn off the prompt labels, since computing them *very
    520         # dramatically* slows down the maxima interpret after a while.
    521         # See the function makelabel in suprv1.lisp.
    522         # Many thanks to andrej.vodopivec@gmail.com and also
    523         # Robert Dodier for figuring this out!
    524         # See trac # 6818. 
    525         init_code.append('nolabels:true')
    526        
    527         Expect.__init__(self,
    528                         name = 'maxima',
    529                         prompt = '\(\%i[0-9]+\)',
    530                         command = 'maxima-noreadline --userdir="%s" -p "%s"'%(SAGE_MAXIMA_DIR,STARTUP),
    531                         maxread = 10000,
    532                         script_subdirectory = script_subdirectory,
    533                         restart_on_ctrlc = False,
    534                         verbose_start = False,
    535                         init_code = init_code,
    536                         logfile = logfile,
    537                         eval_using_file_cutoff=eval_using_file_cutoff)
    538         self._display_prompt = '<sage-display>'  # must match what is in the file local/bin/sage-maxima.lisp!!
    539         self._output_prompt_re = re.compile('\(\%o[0-9]+\)')
    540         self._ask = ['zero or nonzero?', 'an integer?', 'positive, negative, or zero?',
    541                      'positive or negative?', 'positive or zero?']
    542         self._prompt_wait = [self._prompt] + [re.compile(x) for x in self._ask] + \
    543                             ['Break [0-9]+'] #note that you might need to change _expect_expr if you
    544                                              #change this
    545         self._error_re = re.compile('(Principal Value|debugmode|incorrect syntax|Maxima encountered a Lisp error)')
    546         self._display2d = False
    547 
    548     def _quit_string(self):
    549         """
    550         EXAMPLES::
    551        
    552             sage: maxima._quit_string()
    553             'quit();'
    554         """
    555         return 'quit();'
    556 
    557     def _crash_msg(self):
    558         """
    559         EXAMPLES::
    560        
    561             sage: maxima._crash_msg()
    562             Maxima crashed -- automatically restarting.
    563         """
    564         print "Maxima crashed -- automatically restarting."
    565 
    566 
    567     def _batch(self, s, batchload=True):
    568         filename = '%s-%s'%(self._local_tmpfile(),randrange(2147483647))
    569         F = open(filename, 'w')
    570         F.write(s)
    571         F.close()
    572         if self.is_remote():
    573             self._send_tmpfile_to_server(local_file=filename)
    574             tmp_to_use = self._remote_tmpfile()
    575         tmp_to_use = filename
    576        
    577         if batchload:
    578             cmd = 'batchload("%s");'%tmp_to_use
    579         else:
    580             cmd = 'batch("%s");'%tmp_to_use
    581 
    582         r = randrange(2147483647)
    583         s = str(r+1)
    584         cmd = "%s1+%s;\n"%(cmd,r)
    585 
    586         self._sendline(cmd)
    587         self._expect_expr(s)
    588         out = self._before()
    589         self._error_check(str, out)
    590         os.unlink(filename)
    591         return out
    592 
    593     def _error_check(self, str, out):
    594         r = self._error_re
    595         m = r.search(out)
    596         if not m is None:
    597             self._error_msg(str, out)
    598            
    599     def _error_msg(self, str, out):
    600         raise TypeError, "Error executing code in Maxima\nCODE:\n\t%s\nMaxima ERROR:\n\t%s"%(str, out.replace('-- an error.  To debug this try debugmode(true);',''))
    601 
     75        Interface.__init__(self,name)
    60276
    60377    ###########################################
    60478    # System -- change directory, etc
     
    61690    ###########################################
    61791    # Interactive help
    61892    ###########################################
     93    def _command_runner(self, command, s, redirect=True):
     94        """
     95        Run ``command`` in a new Maxima session and return its
     96        output as an ``AsciiArtString``.
     97       
     98        If redirect is set to False, then the output of the command is not
     99        returned as a string. Instead, it behaves like os.system. This is
     100        used for interactive things like Maxima's demos. See maxima.demo?
     101       
     102        EXAMPLES::
     103       
     104            sage: maxima._command_runner('describe', 'gcd')
     105            -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
     106            ...
     107        """
     108        cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s)
     109        if sage.server.support.EMBEDDED_MODE:
     110            cmd += '< /dev/null'
    619111
     112        if redirect:
     113            p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
     114                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
     115            res = p.stdout.read()
     116            # ecl-10.2 : 3 lines
     117            # ecl-10.4 : 5 lines
     118            # ecl-11.1 : 4 lines fancy a tango?
     119            # We now get 4 lines of commented verbosity
     120            # every time Maxima starts, so we need to get rid of them
     121            for _ in range(4):
     122                res = res[res.find('\n')+1:]
     123            return AsciiArtString(res)
     124        else:
     125            subprocess.Popen(cmd, shell=True)
    620126
    621127    def help(self, s):
    622128        """
     
    736242            sage.misc.persist.save(v, COMMANDS_CACHE)
    737243            return v
    738244
     245    def console(self):
     246        r"""
     247        Start the interactive Maxima console. This is a completely separate
     248        maxima session from this interface. To interact with this session,
     249        you should instead use ``maxima.interact()``.
     250       
     251        EXAMPLES::
     252       
     253            sage: maxima.console()             # not tested (since we can't)
     254            Maxima 5.13.0 http://maxima.sourceforge.net
     255            Using Lisp CLISP 2.41 (2006-10-13)
     256            Distributed under the GNU Public License. See the file COPYING.
     257            Dedicated to the memory of William Schelter.
     258            This is a development version of Maxima. The function bug_report()
     259            provides bug reporting information.
     260            (%i1)
     261       
     262        ::
     263       
     264            sage: maxima.interact()     # this is not tested either
     265              --> Switching to Maxima <--
     266            maxima: 2+2
     267            4
     268            maxima:
     269              --> Exiting back to Sage <--
     270        """
     271        maxima_console()
     272
     273    def cputime(self, t=None):
     274        r"""
     275        Returns the amount of CPU time that this Maxima session has used.
     276        If \var{t} is not None, then it returns the difference between
     277        the current CPU time and \var{t}.
     278       
     279        EXAMPLES:
     280            sage: t = maxima.cputime()
     281            sage: _ = maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])
     282            sage: maxima.cputime(t) # output random
     283            0.568913
     284        """
     285        if t:
     286            return float(self.eval('elapsed_run_time()')) - t
     287        else:
     288            return float(self.eval('elapsed_run_time()'))
     289
     290    def version(self):
     291        """
     292        Return the version of Maxima that Sage includes.
     293       
     294        EXAMPLES::
     295       
     296            sage: maxima.version()
     297            '5.23.2'
     298        """
     299        return maxima_version()
     300
     301    ####
     302    # Overriding default values
     303    ###
     304
     305    def _assign_symbol(self):
     306        return ":"
     307
    739308    def _true_symbol(self):
    740309        """
    741310        Return the true symbol in Maxima.
     
    786355        """
    787356        return '#'
    788357
    789     def console(self):
    790         r"""
    791         Start the interactive Maxima console. This is a completely separate
    792         maxima session from this interface. To interact with this session,
    793         you should instead use ``maxima.interact()``.
     358    def _function_class(self):
     359        """
     360        EXAMPLES::
     361       
     362            sage: maxima._function_class()
     363            <class 'sage.interfaces.maxima.MaximaFunction'>
     364        """
     365        return MaximaAbstractFunction
     366
     367    def _object_class(self):
     368        """
     369        Return the Python class of Maxima elements.
    794370       
    795371        EXAMPLES::
    796372       
    797             sage: maxima.console()             # not tested (since we can't)
    798             Maxima 5.13.0 http://maxima.sourceforge.net
    799             Using Lisp CLISP 2.41 (2006-10-13)
    800             Distributed under the GNU Public License. See the file COPYING.
    801             Dedicated to the memory of William Schelter.
    802             This is a development version of Maxima. The function bug_report()
    803             provides bug reporting information.
    804             (%i1)
     373            sage: maxima._object_class()
     374            <class 'sage.interfaces.maxima.MaximaElement'>
     375        """
     376        return MaximaAbstractElement
     377
     378    def _function_element_class(self):
     379        """     
     380        EXAMPLES::
     381       
     382            sage: maxima._function_element_class()
     383            <class 'sage.interfaces.maxima.MaximaFunctionElement'>
     384        """
     385        return MaximaAbstractFunctionElement
     386
     387    def _object_function_class(self):
     388        """
     389        EXAMPLES::
     390       
     391            sage: maxima._object_function_class()
     392            <class 'sage.interfaces.maxima.MaximaElementFunction'>
     393        """
     394        return MaximaAbstractElementFunction
     395
     396    ####
     397    #
     398    ####
     399
     400    def function(self, args, defn, rep=None, latex=None):
     401        """
     402        Return the Maxima function with given arguments and definition.
     403       
     404        INPUT:
     405       
     406       
     407        -  ``args`` - a string with variable names separated by
     408           commas
     409       
     410        -  ``defn`` - a string (or Maxima expression) that
     411           defines a function of the arguments in Maxima.
     412       
     413        -  ``rep`` - an optional string; if given, this is how
     414           the function will print.
     415       
     416       
     417        EXAMPLES::
     418       
     419            sage: f = maxima.function('x', 'sin(x)')
     420            sage: f(3.2)
     421            -.058374143427580...
     422            sage: f = maxima.function('x,y', 'sin(x)+cos(y)')
     423            sage: f(2,3.5)
     424            sin(2)-.9364566872907963
     425            sage: f
     426            sin(x)+cos(y)
    805427       
    806428        ::
    807429       
    808             sage: maxima.interact()     # this is not tested either
    809               --> Switching to Maxima <--
    810             maxima: 2+2
    811             4
    812             maxima:
    813               --> Exiting back to Sage <--
     430            sage: g = f.integrate('z')
     431            sage: g
     432            (cos(y)+sin(x))*z
     433            sage: g(1,2,3)
     434            3*(cos(2)+sin(1))
     435       
     436        The function definition can be a maxima object::
     437       
     438            sage: an_expr = maxima('sin(x)*gamma(x)')
     439            sage: t = maxima.function('x', an_expr)
     440            sage: t
     441            gamma(x)*sin(x)
     442            sage: t(2)
     443             sin(2)
     444            sage: float(t(2))
     445            0.90929742682568171
     446            sage: loads(t.dumps())
     447            gamma(x)*sin(x)
    814448        """
    815         maxima_console()
     449        name = self._next_var_name()
     450        if isinstance(defn, MaximaAbstractElement):
     451            defn = defn.str()
     452        elif not isinstance(defn, str):
     453            defn = str(defn)
     454        if isinstance(args, MaximaAbstractElement):
     455            args = args.str()
     456        elif not isinstance(args, str):
     457            args = str(args)
     458        cmd = '%s(%s) := %s'%(name, args, defn)
     459        self._eval_line(cmd)
     460        if rep is None:
     461            rep = defn
     462        f = self._object_function_class()(self, name, rep, args, latex)
     463        return f
    816464
    817     def cputime(self, t=None):
    818         r"""
    819         Returns the amount of CPU time that this Maxima session has used.
    820         If \var{t} is not None, then it returns the difference between
    821         the current CPU time and \var{t}.
    822        
    823         EXAMPLES:
    824             sage: t = maxima.cputime()
    825             sage: _ = maxima.de_solve('diff(y,x,2) + 3*x = y', ['x','y'], [1,1,1])
    826             sage: maxima.cputime(t) # output random
    827             0.568913
    828         """
    829         if t:
    830             return float(self.eval('elapsed_run_time()')) - t
    831         else:
    832             return float(self.eval('elapsed_run_time()'))
    833 
    834 
     465    #####
     466    # Maxima functions
     467    #####
     468   
    835469##     def display2d(self, flag=True):
    836470##         """
    837471##         Set the flag that determines whether Maxima objects are
     
    1248882            self('plot2d('+cmd+','+options+')')
    1249883   
    1250884
    1251 class MaximaElement(ExpectElement):
     885class MaximaAbstractElement(InterfaceElement):
    1252886    def __str__(self):
    1253887        """
    1254888        Printing an object explicitly gives ASCII art:
     
    14691103            sage: a = maxima('sqrt(2)').numer(); a
    14701104            1.41421356237309...
    14711105            sage: type(a)
    1472             <class 'sage.interfaces.maxima_abstract.MaximaElement'>
     1106            <class 'sage.interfaces.maxima.MaximaElement'>
    14731107        """
    14741108        return self.comma('numer')
    14751109
     
    15031137        self.__repr = r
    15041138        return r
    15051139
    1506     def display2d(self, onscreen=True):
    1507         """
    1508         EXAMPLES::
    1509        
    1510             sage: F = maxima('x^5 - y^5').factor() 
    1511             sage: F.display2d ()             
    1512                                    4      3    2  2    3      4
    1513                        - (y - x) (y  + x y  + x  y  + x  y + x )
    1514         """
    1515         self._check_valid()
    1516         P = self.parent()
    1517         with gc_disabled():
    1518             P._eval_line('display2d : true$')
    1519             s = P._eval_line('disp(%s)$'%self.name(), reformat=False)
    1520             P._eval_line('display2d: false$')
    1521            
    1522         s = s.strip('\r\n')
    1523 
    1524         # if ever want to dedent, see
    1525         # http://mail.python.org/pipermail/python-list/2006-December/420033.html
    1526         if onscreen:
    1527             print s
    1528         else:
    1529             return s
    1530 
    15311140    def diff(self, var='x', n=1):
    15321141        """
    15331142        Return the n-th derivative of self.
     
    15621171            sage: f.diff('y')                               
    15631172            34*y
    15641173        """
    1565         return ExpectElement.__getattr__(self, 'diff')(var, n)
     1174        return InterfaceElement.__getattr__(self, 'diff')(var, n)
    15661175
    15671176    derivative = diff
    15681177
     
    16751284            sage: f.numer()
    16761285            1.46265174590718...
    16771286        """
    1678         I = ExpectElement.__getattr__(self, 'integrate')
     1287        I = InterfaceElement.__getattr__(self, 'integrate')
    16791288        if min is None:
    16801289            return I(var)
    16811290        else:
     
    17571366        if n < 0 or n >= len(self):
    17581367            raise IndexError, "n = (%s) must be between %s and %s"%(n, 0, len(self)-1)
    17591368        # If you change the n+1 to n below, better change __iter__ as well.
    1760         return ExpectElement.__getitem__(self, n+1)
     1369        return InterfaceElement.__getitem__(self, n+1)
    17611370
    17621371    def __iter__(self):
    17631372        """
     
    19401549        """
    19411550        P = self._check_valid()
    19421551
    1943         if isinstance(right, MaximaFunction):
     1552        if isinstance(right, P._object_function_class()):
    19441553            fself = P.function('', repr(self))
    19451554            return fself._operation(operation, right)
    19461555
     
    19501559            raise TypeError, msg
    19511560
    19521561
    1953        
    1954 class MaximaFunctionElement(FunctionElement):
    1955     def _sage_doc_(self):
    1956         """
    1957         EXAMPLES::
    1958        
    1959             sage: m = maxima(4)
    1960             sage: m.gcd._sage_doc_()
    1961             -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
    1962             ...
    1963         """
    1964         return self._obj.parent().help(self._name)
     1562class MaximaAbstractFunctionElement(InterfaceFunctionElement):
     1563    pass
    19651564
    1966 class MaximaExpectFunction(ExpectFunction):
    1967     def _sage_doc_(self):
    1968         """
    1969         EXAMPLES::
    1970        
    1971             sage: maxima.gcd._sage_doc_()
    1972             -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
    1973             ...
    1974         """
    1975         M = self._parent
    1976         return M.help(self._name)
    19771565
     1566class MaximaAbstractFunction(InterfaceFunction):
     1567    pass
    19781568
    1979 class MaximaFunction(MaximaElement):
     1569
     1570class MaximaAbstractElementFunction(MaximaAbstractElement):
    19801571    def __init__(self, parent, name, defn, args, latex):
    19811572        """
    19821573        EXAMPLES::
     
    19851576            sage: f == loads(dumps(f))
    19861577            True
    19871578        """
    1988         MaximaElement.__init__(self, parent, name, is_name=True)
     1579        MaximaAbstractElement.__init__(self, parent, name, is_name=True)
    19891580        self.__defn = defn
    19901581        self.__args = args
    19911582        self.__latex = latex
     
    19961587       
    19971588            sage: f = maxima.function('x,y','sin(x+y)')
    19981589            sage: f.__reduce__()
    1999             (<function reduce_load_Maxima_function at 0x...>,
     1590            (<function reduce_load_MaximaAbstract_function at 0x...>,
    20001591             (Maxima, 'sin(x+y)', 'x,y', None))
    20011592        """
    2002         return reduce_load_Maxima_function, (self.parent(), self.__defn, self.__args, self.__latex)
     1593        return reduce_load_MaximaAbstract_function, (self.parent(), self.__defn, self.__args, self.__latex)
    20031594       
    20041595    def __call__(self, *x):
    20051596        """
     
    21271718            1/sin(y+x)
    21281719        """
    21291720        P = self._check_valid()
    2130         if isinstance(f, MaximaFunction):
     1721        if isinstance(f, P._object_function_class()):
    21311722            tmp = list(sorted(set(self.arguments() + f.arguments())))
    21321723            args = ','.join(tmp)
    21331724            defn = "(%s)%s(%s)"%(self.definition(), operation, f.definition())
     
    22981889        return self._operation("^", f)
    22991890
    23001891
    2301 def reduce_load_Maxima_function(parent, defn, args, latex):
     1892def reduce_load_MaximaAbstract_function(parent, defn, args, latex):
    23021893    return parent.function(args, defn, defn, latex)
    23031894   
     1895def maxima_version():
     1896    """
     1897    EXAMPLES::
     1898   
     1899        sage: from sage.interfaces.maxima_abstract import maxima_version
     1900        sage: maxima_version()
     1901        '5.23.2'
     1902    """
     1903    return os.popen('maxima --version').read().split()[-1]
    23041904
    2305 import os
    23061905def maxima_console():
    23071906    """
    23081907    Spawn a new Maxima command-line session.
    23091908   
    23101909    EXAMPLES::
    23111910   
    2312         sage: from sage.interfaces.maxima import maxima_console
     1911        sage: from sage.interfaces.maxima_abstract import maxima_console
    23131912        sage: maxima_console()                    # not tested
    23141913        Maxima 5.23.2 http://maxima.sourceforge.net
    23151914        ...
  • sage/interfaces/maxima_lib.py

    diff -r d737d04798ad -r 8c40382f9433 sage/interfaces/maxima_lib.py
    a b  
    2828
    2929If the string "error" (case insensitive) occurs in the output of
    3030anything from Maxima, a RuntimeError exception is raised.
    31 
    32 EXAMPLES: We evaluate a very simple expression in Maxima.
    33 
    34 ::
    35 
    36     sage: maxima('3 * 5')
    37     15
    38 
    39 We factor `x^5 - y^5` in Maxima in several different ways.
    40 The first way yields a Maxima object.
    41 
    42 ::
    43 
    44     sage: F = maxima.factor('x^5 - y^5')
    45     sage: F
    46     -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
    47     sage: type(F)
    48     <class 'sage.interfaces.maxima_abstract.MaximaElement'>
    49 
    50 Note that Maxima objects can also be displayed using "ASCII art";
    51 to see a normal linear representation of any Maxima object x. Just
    52 use the print command: use ``str(x)``.
    53 
    54 ::
    55 
    56     sage: print F
    57                                4      3    2  2    3      4
    58                    - (y - x) (y  + x y  + x  y  + x  y + x )
    59 
    60 You can always use ``repr(x)`` to obtain the linear
    61 representation of an object. This can be useful for moving maxima
    62 data to other systems.
    63 
    64 ::
    65 
    66     sage: repr(F)
    67     '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
    68     sage: F.str()
    69     '-(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)'
    70 
    71 The ``maxima.eval`` command evaluates an expression in
    72 maxima and returns the result as a *string* not a maxima object.
    73 
    74 ::
    75 
    76     sage: print maxima.eval('factor(x^5 - y^5)')
    77     -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
    78 
    79 We can create the polynomial `f` as a Maxima polynomial,
    80 then call the factor method on it. Notice that the notation
    81 ``f.factor()`` is consistent with how the rest of Sage
    82 works.
    83 
    84 ::
    85 
    86     sage: f = maxima('x^5 - y^5')
    87     sage: f^2
    88     (x^5-y^5)^2
    89     sage: f.factor()
    90     -(y-x)*(y^4+x*y^3+x^2*y^2+x^3*y+x^4)
    91 
    92 Control-C interruption works well with the maxima interface,
    93 because of the excellent implementation of maxima. For example, try
    94 the following sum but with a much bigger range, and hit control-C.
    95 
    96 ::
    97 
    98     sage: maxima('sum(1/x^2, x, 1, 10)')
    99     1968329/1270080
    100 
    101 Tutorial
    102 --------
    103 
    104 We follow the tutorial at
    105 http://maxima.sourceforge.net/docs/intromax/.
    106 
    107 ::
    108 
    109     sage: maxima('1/100 + 1/101')
    110     201/10100
    111 
    112 ::
    113 
    114     sage: a = maxima('(1 + sqrt(2))^5'); a
    115     (sqrt(2)+1)^5
    116     sage: a.expand()
    117     3*2^(7/2)+5*sqrt(2)+41
    118 
    119 ::
    120 
    121     sage: a = maxima('(1 + sqrt(2))^5')
    122     sage: float(a)               
    123     82.012193308819747
    124     sage: a.numer()
    125     82.01219330881975
    126 
    127 ::
    128 
    129     sage: maxima.eval('fpprec : 100')
    130     '100'
    131     sage: a.bfloat()
    132     8.20121933088197564152489730020812442785204843859314941221237124017312418754011041266612384955016056b1
    133 
    134 ::
    135 
    136     sage: maxima('100!')
    137     93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
    138 
    139 ::
    140 
    141     sage: f = maxima('(x + 3*y + x^2*y)^3')
    142     sage: f.expand()
    143     x^6*y^3+9*x^4*y^3+27*x^2*y^3+27*y^3+3*x^5*y^2+18*x^3*y^2+27*x*y^2+3*x^4*y+9*x^2*y+x^3
    144     sage: f.subst('x=5/z')
    145     (5/z+25*y/z^2+3*y)^3
    146     sage: g = f.subst('x=5/z')
    147     sage: h = g.ratsimp(); h
    148     (27*y^3*z^6+135*y^2*z^5+(675*y^3+225*y)*z^4+(2250*y^2+125)*z^3+(5625*y^3+1875*y)*z^2+9375*y^2*z+15625*y^3)/z^6
    149     sage: h.factor()
    150     (3*y*z^2+5*z+25*y)^3/z^6
    151 
    152 ::
    153 
    154     sage: eqn = maxima(['a+b*c=1', 'b-a*c=0', 'a+b=5'])
    155     sage: s = eqn.solve('[a,b,c]'); s
    156     [[a=(25*sqrt(79)*%i+25)/(6*sqrt(79)*%i-34),b=(5*sqrt(79)*%i+5)/(sqrt(79)*%i+11),c=(sqrt(79)*%i+1)/10],[a=(25*sqrt(79)*%i-25)/(6*sqrt(79)*%i+34),b=(5*sqrt(79)*%i-5)/(sqrt(79)*%i-11),c=-(sqrt(79)*%i-1)/10]]
    157 
    158 Here is an example of solving an algebraic equation::
    159 
    160     sage: maxima('x^2+y^2=1').solve('y')
    161     [y=-sqrt(1-x^2),y=sqrt(1-x^2)]
    162     sage: maxima('x^2 + y^2 = (x^2 - y^2)/sqrt(x^2 + y^2)').solve('y')
    163     [y=-sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2),y=sqrt((-y^2-x^2)*sqrt(y^2+x^2)+x^2)]
    164 
    165 You can even nicely typeset the solution in latex::
    166 
    167     sage: latex(s)
    168     \left[ \left[ a={{25\,\sqrt{79}\,i+25}\over{6\,\sqrt{79}\,i-34}} ,   b={{5\,\sqrt{79}\,i+5}\over{\sqrt{79}\,i+11}} , c={{\sqrt{79}\,i+1  }\over{10}} \right]  , \left[ a={{25\,\sqrt{79}\,i-25}\over{6\,  \sqrt{79}\,i+34}} , b={{5\,\sqrt{79}\,i-5}\over{\sqrt{79}\,i-11}} ,   c=-{{\sqrt{79}\,i-1}\over{10}} \right]  \right]
    169 
    170 To have the above appear onscreen via ``xdvi``, type
    171 ``view(s)``. (TODO: For OS X should create pdf output
    172 and use preview instead?)
    173 
    174 ::
    175 
    176     sage: e = maxima('sin(u + v) * cos(u)^3'); e
    177     cos(u)^3*sin(v+u)
    178     sage: f = e.trigexpand(); f
    179     cos(u)^3*(cos(u)*sin(v)+sin(u)*cos(v))
    180     sage: f.trigreduce()
    181     (sin(v+4*u)+sin(v-2*u))/8+(3*sin(v+2*u)+3*sin(v))/8
    182     sage: w = maxima('3 + k*%i')
    183     sage: f = w^2 + maxima('%e')^w
    184     sage: f.realpart()
    185     %e^3*cos(k)-k^2+9
    186 
    187 ::
    188 
    189     sage: f = maxima('x^3 * %e^(k*x) * sin(w*x)'); f
    190     x^3*%e^(k*x)*sin(w*x)
    191     sage: f.diff('x')
    192     k*x^3*%e^(k*x)*sin(w*x)+3*x^2*%e^(k*x)*sin(w*x)+w*x^3*%e^(k*x)*cos(w*x)
    193     sage: f.integrate('x')
    194     (((k*w^6+3*k^3*w^4+3*k^5*w^2+k^7)*x^3+(3*w^6+3*k^2*w^4-3*k^4*w^2-3*k^6)*x^2+(-18*k*w^4-12*k^3*w^2+6*k^5)*x-6*w^4+36*k^2*w^2-6*k^4)*%e^(k*x)*sin(w*x)+((-w^7-3*k^2*w^5-3*k^4*w^3-k^6*w)*x^3+(6*k*w^5+12*k^3*w^3+6*k^5*w)*x^2+(6*w^5-12*k^2*w^3-18*k^4*w)*x-24*k*w^3+24*k^3*w)*%e^(k*x)*cos(w*x))/(w^8+4*k^2*w^6+6*k^4*w^4+4*k^6*w^2+k^8)
    195 
    196 ::
    197 
    198     sage: f = maxima('1/x^2')
    199     sage: f.integrate('x', 1, 'inf')
    200     1
    201     sage: g = maxima('f/sinh(k*x)^4')
    202     sage: g.taylor('x', 0, 3)
    203     f/(k^4*x^4)-2*f/(3*k^2*x^2)+11*f/45-62*k^2*f*x^2/945
    204 
    205 ::
    206 
    207     sage: maxima.taylor('asin(x)','x',0, 10)
    208     x+x^3/6+3*x^5/40+5*x^7/112+35*x^9/1152
    209 
    210 Examples involving matrices
    211 ---------------------------
    212 
    213 We illustrate computing with the matrix whose `i,j` entry
    214 is `i/j`, for `i,j=1,\ldots,4`.
    215 
    216 ::
    217 
    218     sage: f = maxima.eval('f[i,j] := i/j')
    219     sage: A = maxima('genmatrix(f,4,4)'); A
    220     matrix([1,1/2,1/3,1/4],[2,1,2/3,1/2],[3,3/2,1,3/4],[4,2,4/3,1])
    221     sage: A.determinant()
    222     0
    223     sage: A.echelon()
    224     matrix([1,1/2,1/3,1/4],[0,0,0,0],[0,0,0,0],[0,0,0,0])
    225     sage: A.eigenvalues()
    226     [[0,4],[3,1]]
    227     sage: A.eigenvectors()
    228     [[[0,4],[3,1]],[[[1,0,0,-4],[0,1,0,-2],[0,0,1,-4/3]],[[1,2,3,4]]]]
    229 
    230 We can also compute the echelon form in Sage::
    231 
    232     sage: B = matrix(QQ, A)
    233     sage: B.echelon_form()
    234     [  1 1/2 1/3 1/4]
    235     [  0   0   0   0]
    236     [  0   0   0   0]
    237     [  0   0   0   0]
    238     sage: B.charpoly('x').factor()
    239     (x - 4) * x^3
    240 
    241 Laplace Transforms
    242 ------------------
    243 
    244 We illustrate Laplace transforms::
    245 
    246     sage: _ = maxima.eval("f(t) := t*sin(t)")
    247     sage: maxima("laplace(f(t),t,s)")
    248     2*s/(s^2+1)^2
    249 
    250 ::
    251 
    252     sage: maxima("laplace(delta(t-3),t,s)") #Dirac delta function
    253     %e^-(3*s)
    254 
    255 ::
    256 
    257     sage: _ = maxima.eval("f(t) := exp(t)*sin(t)")
    258     sage: maxima("laplace(f(t),t,s)")
    259     1/(s^2-2*s+2)
    260 
    261 ::
    262 
    263     sage: _ = maxima.eval("f(t) := t^5*exp(t)*sin(t)")
    264     sage: maxima("laplace(f(t),t,s)")
    265     360*(2*s-2)/(s^2-2*s+2)^4-480*(2*s-2)^3/(s^2-2*s+2)^5+120*(2*s-2)^5/(s^2-2*s+2)^6
    266     sage: print maxima("laplace(f(t),t,s)")
    267                                              3                 5
    268                360 (2 s - 2)    480 (2 s - 2)     120 (2 s - 2)
    269               --------------- - --------------- + ---------------
    270                 2           4     2           5     2           6
    271               (s  - 2 s + 2)    (s  - 2 s + 2)    (s  - 2 s + 2)
    272 
    273 ::
    274 
    275     sage: maxima("laplace(diff(x(t),t),t,s)")
    276     s*'laplace(x(t),t,s)-x(0)
    277 
    278 ::
    279 
    280     sage: maxima("laplace(diff(x(t),t,2),t,s)")
    281     -?%at('diff(x(t),t,1),t=0)+s^2*'laplace(x(t),t,s)-x(0)*s
    282 
    283 It is difficult to read some of these without the 2d
    284 representation::
    285 
    286     sage: print maxima("laplace(diff(x(t),t,2),t,s)")
    287                          !
    288                 d        !         2
    289               - -- (x(t))!      + s  laplace(x(t), t, s) - x(0) s
    290                 dt       !
    291                          !t = 0
    292 
    293 Even better, use
    294 ``view(maxima("laplace(diff(x(t),t,2),t,s)"))`` to see
    295 a typeset version.
    296 
    297 Continued Fractions
    298 -------------------
    299 
    300 A continued fraction `a + 1/(b + 1/(c + \cdots))` is
    301 represented in maxima by the list `[a, b, c, \ldots]`.
    302 
    303 ::
    304 
    305     sage: maxima("cf((1 + sqrt(5))/2)")
    306     [1,1,1,1,2]
    307     sage: maxima("cf ((1 + sqrt(341))/2)")
    308     [9,1,2,1,2,1,17,1,2,1,2,1,17,1,2,1,2,1,17,2]
    309 
    310 Special examples
    311 ----------------
    312 
    313 In this section we illustrate calculations that would be awkward to
    314 do (as far as I know) in non-symbolic computer algebra systems like
    315 MAGMA or GAP.
    316 
    317 We compute the gcd of `2x^{n+4} - x^{n+2}` and
    318 `4x^{n+1} + 3x^n` for arbitrary `n`.
    319 
    320 ::
    321 
    322     sage: f = maxima('2*x^(n+4) - x^(n+2)')
    323     sage: g = maxima('4*x^(n+1) + 3*x^n')
    324     sage: f.gcd(g)
    325     x^n
    326 
    327 You can plot 3d graphs (via gnuplot)::
    328 
    329     sage: maxima('plot3d(x^2-y^2, [x,-2,2], [y,-2,2], [grid,12,12])')  # not tested
    330     [displays a 3 dimensional graph]
    331 
    332 You can formally evaluate sums (note the ``nusum``
    333 command)::
    334 
    335     sage: S = maxima('nusum(exp(1+2*i/n),i,1,n)')
    336     sage: print S
    337                             2/n + 3                   2/n + 1
    338                           %e                        %e
    339                    ----------------------- - -----------------------
    340                       1/n         1/n           1/n         1/n
    341                    (%e    - 1) (%e    + 1)   (%e    - 1) (%e    + 1)
    342 
    343 We formally compute the limit as `n\to\infty` of
    344 `2S/n` as follows::
    345 
    346     sage: T = S*maxima('2/n')
    347     sage: T.tlimit('n','inf')
    348     %e^3-%e
    349 
    350 Miscellaneous
    351 -------------
    352 
    353 Obtaining digits of `\pi`::
    354 
    355     sage: maxima.eval('fpprec : 100')
    356     '100'
    357     sage: maxima(pi).bfloat()
    358     3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068b0
    359 
    360 Defining functions in maxima::
    361 
    362     sage: maxima.eval('fun[a] := a^2')
    363     'fun[a]:=a^2'
    364     sage: maxima('fun[10]')
    365     100
    366 
    367 Interactivity
    368 -------------
    369 
    370 Unfortunately maxima doesn't seem to have a non-interactive mode,
    371 which is needed for the Sage interface. If any Sage call leads to
    372 maxima interactively answering questions, then the questions can't be
    373 answered and the maxima session may hang. See the discussion at
    374 http://www.ma.utexas.edu/pipermail/maxima/2005/011061.html for some
    375 ideas about how to fix this problem. An example that illustrates this
    376 problem is ``maxima.eval('integrate (exp(a*x), x, 0, inf)')``.
    377 
    378 Latex Output
    379 ------------
    380 
    381 To TeX a maxima object do this::
    382 
    383     sage: latex(maxima('sin(u) + sinh(v^2)'))
    384     \sinh v^2+\sin u
    385 
    386 Here's another example::
    387 
    388     sage: g = maxima('exp(3*%i*x)/(6*%i) + exp(%i*x)/(2*%i) + c')
    389     sage: latex(g)
    390     -{{i\,e^{3\,i\,x}}\over{6}}-{{i\,e^{i\,x}}\over{2}}+c
    391 
    392 Long Input
    393 ----------
    394 
    395 The MAXIMA interface reads in even very long input (using files) in
    396 a robust manner, as long as you are creating a new object.
    397 
    398 .. note::
    399 
    400    Using ``maxima.eval`` for long input is much less robust, and is
    401    not recommended.
    402 
    403 ::
    404 
    405     sage: t = '"%s"'%10^10000   # ten thousand character string.
    406     sage: a = maxima(t)
    407 
    408 TESTS: This working tests that a subtle bug has been fixed::
    409 
    410     sage: f = maxima.function('x','gamma(x)')
    411     sage: g = f(1/7)
    412     sage: g
    413     gamma(1/7)
    414     sage: del f
    415     sage: maxima(sin(x))
    416     sin(x)
    417 
    418 This tests to make sure we handle the case where Maxima asks if an
    419 expression is positive or zero.
    420 
    421 ::
    422 
    423     sage: var('Ax,Bx,By')
    424     (Ax, Bx, By)
    425     sage: t = -Ax*sin(sqrt(Ax^2)/2)/(sqrt(Ax^2)*sqrt(By^2 + Bx^2))
    426     sage: t.limit(Ax=0,dir='+')
    427     0
    428 
    429 A long complicated input expression::
    430 
    431     sage: maxima._eval_line('((((((((((0) + ((1) / ((n0) ^ (0)))) + ((1) / ((n1) ^ (1)))) + ((1) / ((n2) ^ (2)))) + ((1) / ((n3) ^ (3)))) + ((1) / ((n4) ^ (4)))) + ((1) / ((n5) ^ (5)))) + ((1) / ((n6) ^ (6)))) + ((1) / ((n7) ^ (7)))) + ((1) / ((n8) ^ (8)))) + ((1) / ((n9) ^ (9)));')
    432     '1/n9^9+1/n8^8+1/n7^7+1/n6^6+1/n5^5+1/n4^4+1/n3^3+1/n2^2+1/n1+1'
    43331"""
    43432
    43533#*****************************************************************************
     
    44745#                  http://www.gnu.org/licenses/
    44846#*****************************************************************************
    44947
    450 from __future__ import with_statement
     48from sage.symbolic.ring import SR
    45149
    452 import os, re, sys, subprocess
    453 import pexpect
    454 cygwin = os.uname()[0][:6]=="CYGWIN"
     50from sage.libs.ecl import *
    45551
    456 from expect import Expect, ExpectElement, FunctionElement, ExpectFunction, gc_disabled, AsciiArtString
    457 from pexpect import EOF
     52from maxima_abstract import MaximaAbstract, MaximaAbstractFunction, MaximaAbstractElement, MaximaAbstractFunctionElement, MaximaAbstractElementFunction
    45853
    459 from random import randrange
    460 
    461 ##import sage.rings.all
    462 import sage.rings.complex_number
    463 
    464 from sage.misc.misc import verbose, DOT_SAGE, SAGE_ROOT
    465 
    466 from sage.misc.multireplace import multiple_replace
    467 
    468 COMMANDS_CACHE = '%s/maxima_commandlist_cache.sobj'%DOT_SAGE
    469 
    470 import sage.server.support
    471 
    472 import maxima_abstract
    473 from maxima_abstract import MaximaFunctionElement, MaximaExpectFunction, MaximaFunction, maxima_console
    474 
    475 # The Maxima "apropos" command, e.g., apropos(det) gives a list
    476 # of all identifiers that begin in a certain way.  This could
    477 # maybe be useful somehow... (?)  Also maxima has a lot for getting
    478 # documentation from the system -- this could also be useful.
    479 
    480 ####################################################################
    481 ## We begin here by initializing maxima in library more
    482 from sage.libs.ecl import *
     54## We begin here by initializing maxima in library mode
    48355ecl_eval("(setf *load-verbose* NIL)")
    48456ecl_eval("(require 'maxima)")
    48557ecl_eval("(in-package :maxima)")
     
    49769(defun retrieve (msg flag &aux (print? nil))
    49870  (declare (special msg flag print?))
    49971  (or (eq flag 'noprint) (setq print? t))
    500   (error (concatenate 'string "Maxima asks:" (with-output-to-string (*standard-output*)
    501       (terpri)
     72  (error
     73      (concatenate 'string "Maxima asks: "
     74      (string-trim '(#\Newline)
     75      (with-output-to-string (*standard-output*)
    50276      (cond ((not print?)
    503              (setq print? t)
    504              (princ *prompt-prefix*)
    505              (princ *prompt-suffix*))
    506             ((null msg)
    507              (princ *prompt-prefix*)
    508              (princ *prompt-suffix*))
    509             ((atom msg)
    510              (format t "~a~a~a" *prompt-prefix* msg *prompt-suffix*)
    511              (mterpri))
    512             ((eq flag t)
    513              (princ *prompt-prefix*)
    514              (mapc #'princ (cdr msg))
    515              (princ *prompt-suffix*)
    516              (mterpri))
    517             (t
    518              (princ *prompt-prefix*)
    519              (displa msg)
    520              (princ *prompt-suffix*)
    521              (mterpri)))))))
     77             (setq print? t)
     78             (princ *prompt-prefix*)
     79             (princ *prompt-suffix*)
     80             )
     81            ((null msg)
     82             (princ *prompt-prefix*)
     83             (princ *prompt-suffix*)
     84             )
     85            ((atom msg)
     86             (format t "~a~a~a" *prompt-prefix* msg *prompt-suffix*)
     87             )
     88            ((eq flag t)
     89             (princ *prompt-prefix*)
     90             (mapc #'princ (cdr msg))
     91             (princ *prompt-suffix*)
     92             )
     93            (t
     94             (princ *prompt-prefix*)
     95             (displa msg)
     96             (princ *prompt-suffix*)
     97             )
     98      ))))
     99  )
     100)
    522101""")
    523102
    524103ecl_eval('(defparameter *dev-null* (make-two-way-stream (make-concatenated-stream) (make-broadcast-stream)))')
    525104ecl_eval('(defun principal nil (error "Divergent Integral"))')
    526 
    527105ecl_eval("(setf $errormsg nil)")
    528106
     107#ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))")
     108
     109#ecl_eval('(defun ask-evod (x even-odd)(error "Maxima asks a question"))')
     110#ecl_eval('(defun ask-integerp (x)(error "Maxima asks a question"))')
     111#ecl_eval('(defun ask-declare (x property)(error "Maxima asks a question"))')
     112#ecl_eval('(defun ask-prop (object property fun-or-number)(error "Maxima asks a question"))')
     113#ecl_eval('(defun asksign01 (a)(error "Maxima asks a question"))')
     114#ecl_eval('(defun asksign (x)(error "Maxima asks a question"))')
     115#ecl_eval('(defun asksign1 ($askexp)(error "Maxima asks a question"))')
     116#ecl_eval('(defun ask-greateq (x y)(error "Maxima asks a question"))')
     117#ecl_eval('(defun askinver (a)(error "Maxima asks a question"))')
     118#ecl_eval('(defun npask (exp)(error "Maxima asks a question"))')
     119
     120ecl_eval("(setf original-standard-output *standard-output*)")
     121ecl_eval("(setf *standard-output* *dev-null*)")
     122#ecl_eval("(setf *error-output* *dev-null*)")
     123
     124# display2d -- no ascii art output
     125# keepfloat -- don't automatically convert floats to rationals
     126init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)']
     127# Turn off the prompt labels, since computing them *very
     128# dramatically* slows down the maxima interpret after a while.
     129# See the function makelabel in suprv1.lisp.
     130# Many thanks to andrej.vodopivec@gmail.com and also
     131# Robert Dodier for figuring this out!
     132# See trac # 6818. 
     133init_code.append('nolabels : true')
     134for l in init_code:
     135    ecl_eval("#$%s$"%l)
     136## To get more debug information uncomment the next line
     137## should allow to do this through a method
     138#ecl_eval("(setf *standard-output* original-standard-output)")
     139
     140# This returns an EclObject
    529141maxima_eval=ecl_eval("""
    530142(defun maxima-eval( form )
    531143    (let ((result (catch 'macsyma-quit (cons 'maxima_eval (meval form)))))
     
    554166)
    555167""")
    556168
    557 #ecl_eval('(defun ask-evod (x even-odd)(error "Maxima asks a question"))')
    558 #ecl_eval('(defun ask-integerp (x)(error "Maxima asks a question"))')
    559 #ecl_eval('(defun ask-declare (x property)(error "Maxima asks a question"))')
    560 #ecl_eval('(defun ask-prop (object property fun-or-number)(error "Maxima asks a question"))')
    561 #ecl_eval('(defun asksign01 (a)(error "Maxima asks a question"))')
    562 #ecl_eval('(defun asksign (x)(error "Maxima asks a question"))')
    563 #ecl_eval('(defun asksign1 ($askexp)(error "Maxima asks a question"))')
    564 #ecl_eval('(defun ask-greateq (x y)(error "Maxima asks a question"))')
    565 #ecl_eval('(defun askinver (a)(error "Maxima asks a question"))')
    566 #ecl_eval('(defun npask (exp)(error "Maxima asks a question"))')
    567 
    568 
    569 import sage.symbolic.expression
    570 from sage.symbolic.ring import is_SymbolicVariable
    571 from sage.symbolic.ring import SR
    572 
    573169maxima_lib_instances = 0
    574170
    575 maxprint=EclObject("$STRING")
     171# The Maxima string function can change the structure of its input
     172#maxprint=EclObject("$STRING")
     173maxprint=EclObject("(defun mstring-for-sage (form) (coerce (mstring form) 'string))").eval()
    576174meval=EclObject("MEVAL")
    577175msetq=EclObject("MSETQ")
    578176mlist=EclObject("MLIST")
     
    590188max_use_grobner=EclObject("$USE_GROBNER")
    591189max_to_poly_solve=EclObject("$TO_POLY_SOLVE")
    592190
     191def stdout_to_string(s):
     192    return ecl_eval("(with-output-to-string (*standard-output*) (maxima-eval #$%s$))"%s).python()[1:-1]
     193
    593194def max_to_string(s):
    594      return meval(EclObject([[maxprint],s])).python()[1:-1]
     195     return maxprint(s).python()[1:-1]
    595196
    596 class Maxima(maxima_abstract.Maxima):
     197my_mread=ecl_eval("""
     198(defun my-mread (cmd)
     199  (caddr (mread (make-string-input-stream cmd))))
     200""")
     201
     202def parse_max_string(l):
     203  return my_mread('"%s;"'%l)
     204
     205class MaximaLib(MaximaAbstract):
    597206    """
    598     Interface to the Maxima interpreter.
     207    Interface to Maxima as a Library.
    599208    """
    600     def __init__(self, script_subdirectory=None, logfile=None, server=None,
    601                  init_code = None):
     209    def __init__(self):
    602210        """
    603211        Create an instance of the Maxima interpreter.
    604212
    605213        TESTS::
    606        
    607             sage: maxima == loads(dumps(maxima))
     214
     215            sage: from sage.interfaces.maxima_lib import maxima_lib
     216            sage: maxima_lib == loads(dumps(maxima_lib))
    608217            True
    609218
    610219        We make sure labels are turned off (see trac 6816)::
    611220       
    612             sage: 'nolabels:true' in maxima._Expect__init_code
     221            sage: 'nolabels : true' in maxima_lib._MaximaLib__init_code
    613222            True
    614223        """
    615224        global maxima_lib_instances
    616225        if maxima_lib_instances > 0:
    617226            raise RuntimeError, "Maxima interface in library mode can only be instantiated once"
    618227        maxima_lib_instances += 1
    619        
    620         #the single one gets defined in the Expect interface
    621         self._eval_using_file_cutoff = 10**9
    622         #the double underscore one seems to by private to the Maxima interface
    623         #this must have started as a typo by someone
    624         self.__eval_using_file_cutoff = 10**9
    625         self._available_vars = []
    626         self._Expect__seq = 0
    627         self._session_number = 1
    628         self._Expect__name = "maxima"
    629228
    630         if True:
    631             # display2d -- no ascii art output
    632             # keepfloat -- don't automatically convert floats to rationals
    633             init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)']
    634            
    635         # Turn off the prompt labels, since computing them *very
    636         # dramatically* slows down the maxima interpret after a while.
    637         # See the function makelabel in suprv1.lisp.
    638         # Many thanks to andrej.vodopivec@gmail.com and also
    639         # Robert Dodier for figuring this out!
    640         # See trac # 6818. 
    641         init_code.append('nolabels : true')
    642         ecl_eval("(setf original-standard-output *standard-output*)")
    643         ecl_eval("(setf *standard-output* *dev-null*)")
    644         for l in init_code:
    645             ecl_eval("#$%s$"%l)
    646         ecl_eval("(setf *standard-output* original-standard-output)")
     229        global init_code
     230        self.__init_code = init_code
     231
     232        ## The name should definitely be changed to maxima_lib, however much more changes are then needed elsewhere
     233        ## With maxima, more things are fine, but for example _maxima_init_ gets called in calculus.calculus and the classic interface gets initialized (not started, it is already initialized by default, so that is not really a big deal)
     234        MaximaAbstract.__init__(self,"maxima_lib")
     235        self.__seq = 0
    647236 
    648237    def _coerce_from_special_method(self, x):
    649238        if isinstance(x, EclObject):
    650             return MaximaElement(self,self._create(x))
     239            return MaximaLibElement(self,self._create(x))
    651240        else:
    652             return maxima_abstract.Maxima._coerce_from_special_method(self,x)
    653        
    654        
    655     def _function_class(self):
    656         """
    657         EXAMPLES::
    658        
    659             sage: maxima._function_class()
    660             <class 'sage.interfaces.maxima_abstract.MaximaExpectFunction'>
    661         """
    662         return MaximaExpectFunction
    663 
    664     def _start(self):
    665         """
    666         Starts the Maxima interpreter.
    667        
    668         EXAMPLES::
    669        
    670             sage: m = Maxima()
    671             sage: m.is_running()
    672             False
    673             sage: m._start()
    674             sage: m.is_running()
    675             True
    676         """
    677 #        ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))")
    678         pass
     241            return MaximaAbstract._coerce_from_special_method(self,x)
    679242       
    680243    def __reduce__(self):
    681244        """
    682245        EXAMPLES::
    683246       
    684             sage: maxima.__reduce__()
    685             (<function reduce_load_Maxima at 0x...>, ())
     247            sage: from sage.interfaces.maxima_lib import maxima_lib
     248            sage: maxima_lib.__reduce__()
     249            (<function reduce_load_MaximaLib at 0x...>, ())
    686250        """
    687         return reduce_load_Maxima, tuple([])
     251        return reduce_load_MaximaLib, tuple([])
    688252
    689     def _sendline(self, str):
    690         self._sendstr(str)
    691         os.write(self._expect.child_fd, os.linesep)
    692 
    693     def _expect_expr(self, expr=None, timeout=None):
    694         """
    695         EXAMPLES:
    696             sage: a,b=var('a,b')
    697             sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x)
    698             Traceback (most recent call last):
    699             ...
    700             RuntimeError: ECL says: Maxima asks:...
    701             sage: assume(a>0)
    702             sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x)
    703             2/9*sqrt(3)*b^2*arctan(1/3*(2*(b*x + a)^(1/3) + a^(1/3))*sqrt(3)/a^(1/3))/a^(7/3) + 2/9*b^2*log((b*x + a)^(1/3) - a^(1/3))/a^(7/3) - 1/9*b^2*log((b*x + a)^(2/3) + (b*x + a)^(1/3)*a^(1/3) + a^(2/3))/a^(7/3) + 1/6*(4*(b*x + a)^(5/3)*b^2 - 7*(b*x + a)^(2/3)*a*b^2)/((b*x + a)^2*a^2 - 2*(b*x + a)*a^3 + a^4)
    704             sage: var('x, n')
    705             (x, n)
    706             sage: integral(x^n,x)
    707             Traceback (most recent call last):
    708             ...
    709             RuntimeError: ECL says: Maxima asks:...
    710             sage: assume(n+1>0)
    711             sage: integral(x^n,x)
    712             x^(n + 1)/(n + 1)
    713             sage: forget()
    714         """
    715         if expr is None:
    716             expr = self._prompt_wait
    717         if self._expect is None:
    718             self._start()
    719         try:
    720             if timeout:
    721                 i = self._expect.expect(expr,timeout=timeout)
    722             else:
    723                 i = self._expect.expect(expr)
    724             if i > 0:
    725                 v = self._expect.before
    726 
    727                 #We check to see if there is a "serious" error in Maxima.
    728                 #Note that this depends on the order of self._prompt_wait
    729                 if expr is self._prompt_wait and i > len(self._ask):
    730                     self.quit()
    731                     raise ValueError, "%s\nComputation failed due to a bug in Maxima -- NOTE: Maxima had to be restarted."%v
    732 
    733                 j = v.find('Is ')
    734                 v = v[j:]
    735                 k = v.find(' ',4)
    736                 msg = "Computation failed since Maxima requested additional constraints (try the command 'assume(" + v[4:k] +">0)' before integral or limit evaluation, for example):\n" + v + self._ask[i-1]
    737                 self._sendline(";")
    738                 self._expect_expr()
    739                 raise ValueError, msg
    740         except KeyboardInterrupt, msg:
    741             #print self._expect.before
    742             i = 0
    743             while True:
    744                 try:
    745                     print "Control-C pressed.  Interrupting Maxima. Please wait a few seconds..."
    746                     self._sendstr('quit;\n'+chr(3))
    747                     self._sendstr('quit;\n'+chr(3))
    748                     self.interrupt()
    749                     self.interrupt()
    750                 except KeyboardInterrupt:
    751                     i += 1
    752                     if i > 10:
    753                         break
    754                     pass
    755                 else:
    756                     break
    757             raise KeyboardInterrupt, msg
    758 
    759     def _eval_line(self, line, allow_use_file=False,
    760                    wait_for_prompt=True, reformat=True, error_check=True):
     253    # This outputs a string
     254    def eval(self, line, locals=None, reformat=True, **kwds):
    761255        result = ''
    762256        while line:
    763257            ind_dollar=line.find("$")
     
    769263                else:
    770264                    statement = line[:ind_semi]
    771265                    line = line[ind_semi+1:]
    772                 if statement: result = ((result + '\n') if result else '')+ max_to_string(maxima_eval("#$%s$"%statement))
     266                if statement: result = ((result + '\n') if result else '') + max_to_string(maxima_eval("#$%s$"%statement))
    773267            else:
    774268                statement = line[:ind_dollar]
    775269                line = line[ind_dollar+1:]
    776                 if statement: _ = max_to_string(maxima_eval("#$%s$"%statement))
    777         return result
     270                if statement: _ = maxima_eval("#$%s$"%statement)
     271        if not reformat:
     272            return result
     273        return ''.join([x.strip() for x in result.split()])
    778274
    779     def _synchronize(self):
    780         """
    781         Synchronize pexpect interface.
    782        
    783         This put a random integer (plus one!) into the output stream, then
    784         waits for it, thus resynchronizing the stream. If the random
    785         integer doesn't appear within 1 second, maxima is sent interrupt
    786         signals.
    787        
    788         This way, even if you somehow left maxima in a busy state
    789         computing, calling _synchronize gets everything fixed.
    790        
    791         EXAMPLES: This makes Maxima start a calculation::
    792        
    793             sage: maxima._sendstr('1/1'*500)
    794        
    795         When you type this command, this synchronize command is implicitly
    796         called, and the above running calculation is interrupted::
    797        
    798             sage: maxima('2+2')
    799             4
    800         """
    801         marker = '__SAGE_SYNCHRO_MARKER_'
    802         if self._expect is None: return
    803         r = randrange(2147483647)
    804         s = marker + str(r+1)
    805 
    806         # The 0; *is* necessary... it comes up in certain rare cases
    807         # that are revealed by extensive testing.  Don't delete it. -- william stein
    808         cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r)
    809         self._sendstr(cmd)
    810         try:
    811             self._expect_expr(timeout=0.5)
    812             if not s in self._before():
    813                 self._expect_expr(s,timeout=0.5)
    814                 self._expect_expr(timeout=0.5)
    815         except pexpect.TIMEOUT, msg:
    816             self._interrupt()
    817         except pexpect.EOF:
    818             self._crash_msg()
    819             self.quit()
     275    _eval_line = eval
    820276
    821277    ###########################################
    822278    # Direct access to underlying lisp interpreter.
     
    831287       
    832288        EXAMPLES::
    833289       
    834             sage: maxima.lisp("(+ 2 17)")   # random formatted output
    835              :lisp (+ 2 17)
    836             19
    837             (
     290            sage: from sage.interfaces.maxima_lib import maxima_lib
     291            sage: maxima_lib.lisp("(+ 2 17)")
     292            <ECL: 19>
    838293        """
    839         self._eval_line(':lisp %s\n""'%cmd, allow_use_file=False, wait_for_prompt=False, reformat=False, error_check=False)
    840         self._expect_expr('(%i)')
    841         return self._before()
    842 
    843     ###########################################
    844     # Interactive help
    845     ###########################################
    846     def _command_runner(self, command, s, redirect=True):
    847         """
    848         Run ``command`` in a new Maxima session and return its
    849         output as an ``AsciiArtString``.
    850        
    851         If redirect is set to False, then the output of the command is not
    852         returned as a string. Instead, it behaves like os.system. This is
    853         used for interactive things like Maxima's demos. See maxima.demo?
    854        
    855         EXAMPLES::
    856        
    857             sage: maxima._command_runner('describe', 'gcd')
    858             -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
    859             ...
    860         """
    861         cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s)
    862         if sage.server.support.EMBEDDED_MODE:
    863             cmd += '< /dev/null'
    864 
    865         if redirect:
    866             p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
    867                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    868             res = p.stdout.read()
    869             # ecl-10.2 : 3 lines
    870             # ecl-10.4 : 5 lines
    871             # ecl-11.1 : 4 lines fancy a tango?
    872             # We now get 4 lines of commented verbosity
    873             # every time Maxima starts, so we need to get rid of them
    874             for _ in range(4):
    875                 res = res[res.find('\n')+1:]
    876             return AsciiArtString(res)
    877         else:
    878             subprocess.Popen(cmd, shell=True)
    879 
    880     def _object_class(self):
    881         """
    882         Return the Python class of Maxima elements.
    883        
    884         EXAMPLES::
    885        
    886             sage: maxima._object_class()
    887             <class 'sage.interfaces.maxima_abstract.MaximaElement'>
    888         """
    889         return MaximaElement
    890 
    891     def _function_element_class(self):
    892         """     
    893         EXAMPLES::
    894        
    895             sage: maxima._function_element_class()
    896             <class 'sage.interfaces.maxima_abstract.MaximaFunctionElement'>
    897         """
    898         return MaximaFunctionElement
    899 
    900     def function(self, args, defn, rep=None, latex=None):
    901         """
    902         Return the Maxima function with given arguments and definition.
    903        
    904         INPUT:
    905        
    906        
    907         -  ``args`` - a string with variable names separated by
    908            commas
    909        
    910         -  ``defn`` - a string (or Maxima expression) that
    911            defines a function of the arguments in Maxima.
    912        
    913         -  ``rep`` - an optional string; if given, this is how
    914            the function will print.
    915        
    916        
    917         EXAMPLES::
    918        
    919             sage: f = maxima.function('x', 'sin(x)')
    920             sage: f(3.2)
    921             -.058374143427580...
    922             sage: f = maxima.function('x,y', 'sin(x)+cos(y)')
    923             sage: f(2,3.5)
    924             sin(2)-.9364566872907963
    925             sage: f
    926             sin(x)+cos(y)
    927        
    928         ::
    929        
    930             sage: g = f.integrate('z')
    931             sage: g
    932             (cos(y)+sin(x))*z
    933             sage: g(1,2,3)
    934             3*(cos(2)+sin(1))
    935        
    936         The function definition can be a maxima object::
    937        
    938             sage: an_expr = maxima('sin(x)*gamma(x)')
    939             sage: t = maxima.function('x', an_expr)
    940             sage: t
    941             gamma(x)*sin(x)
    942             sage: t(2)
    943              sin(2)
    944             sage: float(t(2))
    945             0.90929742682568171
    946             sage: loads(t.dumps())
    947             gamma(x)*sin(x)
    948         """
    949         name = self._next_var_name()
    950         if isinstance(defn, MaximaElement):
    951             defn = defn.str()
    952         elif not isinstance(defn, str):
    953             defn = str(defn)
    954         if isinstance(args, MaximaElement):
    955             args = args.str()
    956         elif not isinstance(args, str):
    957             args = str(args)
    958         cmd = '%s(%s) := %s'%(name, args, defn)
    959         maxima._eval_line(cmd)
    960         if rep is None:
    961             rep = defn
    962         f = MaximaFunction(self, name, rep, args, latex)
    963         return f
     294        return ecl_eval(cmd)
    964295
    965296    def set(self, var, value):
    966297        """
     
    976307       
    977308        EXAMPLES::
    978309       
    979             sage: maxima.set('xxxxx', '2')
    980             sage: maxima.get('xxxxx')
     310            sage: from sage.interfaces.maxima_lib import maxima_lib
     311            sage: maxima_lib.set('xxxxx', '2')
     312            sage: maxima_lib.get('xxxxx')
    981313            '2'
    982314        """
    983315        if not isinstance(value, str):
    984316            raise TypeError
    985317        cmd = '%s : %s$'%(var, value.rstrip(';'))
    986         if len(cmd) > self.__eval_using_file_cutoff:
    987             self._batch(cmd, batchload=True)
    988         else:
    989             self._eval_line(cmd)
    990             #self._sendline(cmd)
    991             #self._expect_expr()
    992             #out = self._before()
    993             #self._error_check(cmd, out)
     318        self.eval(cmd)
    994319
    995320    def clear(self, var):
    996321        """
     
    998323
    999324        EXAMPLES::
    1000325
    1001             sage: maxima.set('xxxxx', '2')
    1002             sage: maxima.get('xxxxx')
     326            sage: from sage.interfaces.maxima_lib import maxima_lib
     327            sage: maxima_lib.set('xxxxx', '2')
     328            sage: maxima_lib.get('xxxxx')
    1003329            '2'
    1004             sage: maxima.clear('xxxxx')
    1005             sage: maxima.get('xxxxx')
     330            sage: maxima_lib.clear('xxxxx')
     331            sage: maxima_lib.get('xxxxx')
    1006332            'xxxxx'
    1007333        """
    1008334        try:
    1009             self._expect.send('kill(%s)$'%var)
     335            self.eval('kill(%s)$'%var)
    1010336        except (TypeError, AttributeError):
    1011              pass
     337            pass
    1012338
    1013339    def get(self, var):
    1014340        """
     
    1016342       
    1017343        EXAMPLES::
    1018344       
    1019             sage: maxima.set('xxxxx', '2')
    1020             sage: maxima.get('xxxxx')
     345            sage: from sage.interfaces.maxima_lib import maxima_lib
     346            sage: maxima_lib.set('xxxxx', '2')
     347            sage: maxima_lib.get('xxxxx')
    1021348            '2'
    1022349        """
    1023         s = self._eval_line('%s;'%var)
     350        s = self.eval('%s;'%var)
    1024351        return s
    1025352 
    1026353    def _create(self, value, name=None):
     
    1030357        else:
    1031358            self.set(name, value)
    1032359        return name
    1033                
    1034     def version(self):
     360
     361    def _function_class(self):
    1035362        """
    1036         Return the version of Maxima that Sage includes.
     363        EXAMPLES::
     364       
     365            sage: from sage.interfaces.maxima_lib import maxima_lib
     366            sage: maxima_lib._function_class()
     367            <class 'sage.interfaces.maxima_lib.MaximaLibFunction'>
     368        """
     369        return MaximaLibFunction
     370
     371    def _object_class(self):
     372        """
     373        Return the Python class of Maxima elements.
    1037374       
    1038375        EXAMPLES::
    1039376       
    1040             sage: maxima.version()
    1041             '5.23.2'
     377            sage: from sage.interfaces.maxima_lib import maxima_lib
     378            sage: maxima_lib._object_class()
     379            <class 'sage.interfaces.maxima_lib.MaximaLibElement'>
    1042380        """
    1043         return maxima_version()
     381        return MaximaLibElement
    1044382
    1045 ##some helper functions to wrap tha calculus use of the maxima interface.
    1046 ##these routines expect arguments living in the symbolic ring and return something
    1047 ##that is hopefully coercible into the symbolic ring again.
     383    def _function_element_class(self):
     384        """     
     385        EXAMPLES::
     386       
     387            sage: from sage.interfaces.maxima_lib import maxima_lib
     388            sage: maxima_lib._function_element_class()
     389            <class 'sage.interfaces.maxima_lib.MaximaLibFunctionElement'>
     390        """
     391        return MaximaLibFunctionElement
     392
     393    def _object_function_class(self):
     394        """
     395        EXAMPLES::
     396       
     397            sage: from sage.interfaces.maxima_lib import maxima_lib
     398            sage: maxima_lib._object_function_class()
     399            <class 'sage.interfaces.maxima_lib.MaximaLibElementFunction'>
     400        """
     401        return MaximaLibElementFunction
     402
     403    ##some helper functions to wrap the calculus use of the maxima interface.
     404    ##these routines expect arguments living in the symbolic ring and return something
     405    ##that is hopefully coercible into the symbolic ring again.
    1048406
    1049407    def sr_integral(self,*args):
    1050408        try:
     
    1082440            L.append(max_minus)
    1083441        return max_to_sr(maxima_eval(([max_tlimit],L)))
    1084442
    1085 ##     def display2d(self, flag=True):
    1086 ##         """
    1087 ##         Set the flag that determines whether Maxima objects are
    1088 ##         printed using their 2-d ASCII art representation.  When the
    1089 ##         maxima interface starts the default is that objects are not
    1090 ##         represented in 2-d.
    1091443
    1092 ##         INPUT:
    1093 ##             flag -- bool (default: True)
     444def is_MaximaLibElement(x):
     445    """
     446    Returns True if x is of type MaximaLibElement.
     447   
     448    EXAMPLES::
     449   
     450        sage: from sage.interfaces.maxima_lib import maxima_lib, is_MaximaLibElement
     451        sage: m = maxima_lib(1)
     452        sage: is_MaximaLibElement(m)
     453        True
     454        sage: is_MaximaLibElement(1)
     455        False
     456    """
     457    return isinstance(x, MaximaLibElement)
    1094458
    1095 ##         EXAMPLES
    1096 ##             sage: maxima('1/2')
    1097 ##             1/2
    1098 ##             sage: maxima.display2d(True)
    1099 ##             sage: maxima('1/2')
    1100 ##                                            1
    1101 ##                                            -
    1102 ##                                            2
    1103 ##             sage: maxima.display2d(False)
    1104 ##         """
    1105 ##         self._display2d = bool(flag)
    1106 
    1107 class MaximaElement(maxima_abstract.MaximaElement):
     459class MaximaLibElement(MaximaAbstractElement):
    1108460    """
    1109461    """   
    1110462    def ecl(self):
     
    1122474            cmd=EclObject([[max_to_poly_solve], self.ecl(), sr_to_max(vars)])
    1123475        return self.parent()(maxima_eval(cmd))
    1124476
    1125 def is_MaximaElement(x):
    1126     """
    1127     Returns True if x is of type MaximaElement.
    1128    
    1129     EXAMPLES::
    1130    
    1131         sage: from sage.interfaces.maxima import is_MaximaElement
    1132         sage: m = maxima(1)
    1133         sage: is_MaximaElement(m)
    1134         True
    1135         sage: is_MaximaElement(1)
    1136         False
    1137     """
    1138     return isinstance(x, MaximaElement)
     477    def display2d(self, onscreen=True):
     478        """
     479        EXAMPLES::
     480       
     481            sage: from sage.interfaces.maxima_lib import maxima_lib
     482            sage: F = maxima_lib('x^5 - y^5').factor() 
     483            sage: F.display2d ()             
     484                                   4      3    2  2    3      4
     485                       - (y - x) (y  + x y  + x  y  + x  y + x )
     486        """
     487        self._check_valid()
     488        P = self.parent()
     489        P._eval_line('display2d : true$')
     490        s = stdout_to_string('disp(%s)'%self.name())
     491        #s = P._eval_line('disp(%s)$'%self.name())
     492        P._eval_line('display2d : false$')
     493        s = s.strip('\r\n')
    1139494
    1140 # An instance
    1141 maxima = Maxima()
     495        # if ever want to dedent, see
     496        # http://mail.python.org/pipermail/python-list/2006-December/420033.html
     497        if onscreen:
     498            print s
     499        else:
     500            return s
    1142501
    1143 def reduce_load_Maxima():
     502
     503class MaximaLibFunctionElement(MaximaAbstractFunctionElement):
     504    pass
     505
     506
     507class MaximaLibFunction(MaximaAbstractFunction):
     508    pass
     509
     510
     511class MaximaLibElementFunction(MaximaLibElement, MaximaAbstractElementFunction):
     512    pass
     513
     514
     515# The (unique) instance
     516maxima_lib = MaximaLib()
     517maxima = maxima_lib
     518
     519
     520def reduce_load_MaximaLib():
    1144521    """
    1145522    EXAMPLES::
    1146523   
    1147         sage: from sage.interfaces.maxima import reduce_load_Maxima
    1148         sage: reduce_load_Maxima()
    1149         Maxima
     524        sage: from sage.interfaces.maxima_lib import reduce_load_MaximaLib
     525        sage: reduce_load_MaximaLib()
     526        Maxima_lib
    1150527    """
    1151     return maxima
     528    return maxima_lib
    1152529
    1153 
    1154 def maxima_version():
    1155     """
    1156     EXAMPLES::
    1157    
    1158         sage: from sage.interfaces.maxima import maxima_version
    1159         sage: maxima_version()
    1160         '5.23.2'
    1161     """
    1162     return os.popen('maxima --version').read().split()[-1]
    1163 
    1164 def __doctest_cleanup():
    1165     import sage.interfaces.quit
    1166     sage.interfaces.quit.expect_quitall()
    1167 
    1168 
    1169 import sage.symbolic.expression
    1170 from sage.symbolic.ring import SR
     530#**********************************
     531# ???
    1171532
    1172533import sage.symbolic.expression
    1173534import sage.functions.trig
    1174535import sage.functions.log
    1175536import sage.functions.other
    1176537import sage.symbolic.integration.integral
     538from sage.symbolic.operators import FDerivativeOperator
    1177539
    1178540car=EclObject("car")
    1179541cdr=EclObject("cdr")
     
    1187549NIL=EclObject("NIL")
    1188550ratdisrep=EclObject("ratdisrep")
    1189551
    1190 sage_op_dict={}
    1191 
    1192552sage_op_dict = {
    1193553    sage.symbolic.expression.operator.abs : "MABS",
    1194554    sage.symbolic.expression.operator.add : "MPLUS",
     
    1223583    sage.functions.other.erf : "%ERF",
    1224584    sage.functions.other.gamma_inc : "%GAMMA_INCOMPLETE"
    1225585}
    1226 
    1227586#we compile the dictionary
    1228587sage_op_dict = dict([(k,EclObject(sage_op_dict[k])) for k in sage_op_dict])
    1229588max_op_dict = dict([(sage_op_dict[k],k) for k in sage_op_dict])
     589
    1230590def add_vararg(*args):
    1231591    S=0
    1232592    for a in args:
     
    1244604
    1245605mplus=EclObject("MPLUS")
    1246606mtimes=EclObject("MTIMES")
     607mdiff=EclObject("%DERIVATIVE")
    1247608rat=EclObject("RAT")
    1248609max_i=EclObject("$%I")
    1249610max_op_dict[mplus]=add_vararg
     
    1290651    else:
    1291652        return sage.symbolic.integration.integral.indefinite_integral(*args, hold=True)
    1292653
     654def mdiff_to_sage(expr):
     655    return max_to_sr(expr.cadr()).diff(*[max_to_sr(e) for e in expr.cddr()])
     656
    1293657special_max_to_sage={
    1294658    EclObject("MRAT") : mrat_to_sage,
    1295     EclObject("MQAPPLY") : mqapply_to_sage,
    1296     EclObject("%INTEGRATE") : dummy_integrate
     659    mqapply : mqapply_to_sage,
     660    EclObject("%INTEGRATE") : dummy_integrate,
     661    mdiff : mdiff_to_sage
    1297662}
    1298663
    1299664special_sage_to_max={
     
    1312677    elif isinstance(obj,sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic) and obj.parent().defining_polynomial().list() == [1,0,1]:
    1313678        re, im = obj.list()
    1314679        return EclObject([[mplus], pyobject_to_max(re), [[mtimes], pyobject_to_max(im), max_i]])
    1315    
    1316680    return EclObject(obj)
    1317681
     682# This goes from SR to EclObject
    1318683def sr_to_max(expr):
    1319684    r"""
    1320685    """
     
    1324689        return EclObject(([mlist],[sr_to_max(e) for e in expr]))
    1325690    op = expr.operator()
    1326691    if op:
    1327         if (op in special_sage_to_max):
     692        # Stolen from sage.symbolic.expression_conversion
     693        # Should be defined in a function and then put in special_sage_to_max
     694        # For that, we should change the API of the functions there (we need to have access to op, not only to expr.operands()
     695        if isinstance(op, FDerivativeOperator):
     696            from sage.symbolic.ring import is_SymbolicVariable
     697            args = expr.operands()
     698            if (not all(is_SymbolicVariable(v) for v in args) or
     699                len(args) != len(set(args))):
     700                raise NotImplementedError, "arguments must be distinct variables"
     701            f = sr_to_max(op.function()(*args))
     702            params = op.parameter_set()
     703            deriv_max = []
     704            [deriv_max.extend([sr_to_max(args[i]), EclObject(params.count(i))]) for i in set(params)]
     705            l = [mdiff,f]
     706            l.extend(deriv_max)
     707            return EclObject(l)
     708        elif (op in special_sage_to_max):
    1328709            return EclObject(special_sage_to_max[op](*[sr_to_max(o) for o in expr.operands()]))
    1329710        elif not (op in sage_op_dict):
    1330             op_max=caar(maxima(expr).ecl())
     711            # Maxima does some simplifications automatically by default
     712            # so calling maxima(expr) can change the structure of expr
     713            #op_max=caar(maxima(expr).ecl())
     714            # This should be safe if we treated all special operators above
     715            op_max=maxima(op).ecl()
    1331716            sage_op_dict[op]=op_max
    1332717            max_op_dict[op_max]=op
    1333718        return EclObject(([sage_op_dict[op]],
     
    1344729        except TypeError:
    1345730            return maxima(expr).ecl()
    1346731   
     732# This goes from EclObject to SR
    1347733def max_to_sr(expr):
    1348734    if expr.consp():
    1349735        op_max=caar(expr)
    1350736        if op_max in special_max_to_sage:
    1351737            return special_max_to_sage[op_max](expr)
    1352738        if not(op_max in max_op_dict):
     739            # This could be unsafe if the conversion to SR chenges the structure of expr
    1353740            sage_expr=SR(maxima(expr))
    1354741            max_op_dict[op_max]=sage_expr.operator()
    1355742            sage_op_dict[sage_expr.operator()]=op_max
    1356743        op=max_op_dict[op_max]
    1357744        max_args=cdr(expr)
    1358         args=[ max_to_sr(a) for a in max_args]
     745        args=[max_to_sr(a) for a in max_args]
    1359746        return op(*args)
    1360747    elif expr.symbolp():
    1361748        if not(expr in max_sym_dict):
  • sage/structure/sage_object.pyx

    diff -r d737d04798ad -r 8c40382f9433 sage/structure/sage_object.pyx
    a b  
    519519        import sage.interfaces.maxima
    520520        I = sage.interfaces.maxima.maxima
    521521        return self._interface_init_(I)
     522
     523    def _maxima_lib_(self, G=None):
     524        from sage.interfaces.maxima_lib import maxima_lib
     525        return self._interface_(maxima_lib)
    522526   
     527    def _maxima_lib_init_(self):
     528        return self._maxima_init_()
     529
    523530    def _magma_init_(self, magma):
    524531        """
    525532        Given a Magma interpreter M, return a string that evaluates in
  • sage/symbolic/expression.pyx

    diff -r d737d04798ad -r 8c40382f9433 sage/symbolic/expression.pyx
    a b  
    444444            True
    445445        """
    446446        if session is None:
     447            # This chooses the Maxima interface used by calculus
     448            # Maybe not such a great idea because the "default" interface is another one
    447449            from sage.calculus.calculus import maxima
    448450            return super(Expression, self)._interface_(maxima)
    449451        else:
  • sage/symbolic/integration/external.py

    diff -r d737d04798ad -r 8c40382f9433 sage/symbolic/integration/external.py
    a b  
    2626                raise ValueError, "Integral is divergent."
    2727            else:
    2828                raise
    29     return result
     29    return result._sage_()
    3030
    3131def sympy_integrator(expression, v, a=None, b=None):
    3232    """
  • sage/symbolic/integration/integral.py

    diff -r d737d04798ad -r 8c40382f9433 sage/symbolic/integration/integral.py
    a b  
    596596            raise ValueError, "Unknown algorithm: %s" % algorithm
    597597        return integrator(expression, v, a, b)
    598598
    599 
    600599    if a is None:
    601600        return indefinite_integral(expression, v)
    602601    else: