Ticket #7377: trac_7377-split_and_refactor.patch

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

Version 0.2

  • sage/interfaces/expect.py

    # HG changeset patch
    # User Jean-Pierre Flori <flori@enst.fr>
    # Date 1297688775 -3600
    # Node ID b766df9c34391b224035c0f8e4a54524c59b0dfd
    # Parent  a928dca2950bd0506e978caee270e9c1c059a560
    Split Expect interface.
    
    diff -r a928dca2950b -r b766df9c3439 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(name())
    465441            raise RuntimeError, "Unable to start %s because the command '%s' failed.\n%s"%(
    466                 self.__name, cmd, self._install_hints())
     442                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(name())
     456            raise RuntimeError, "Unable to start %s"%name()
    481457        self._expect.timeout = None
    482458        with gc_disabled():
    483459            if block_during_init:
     
    10561032        except TypeError, s:
    10571033            raise TypeError, 'error evaluating "%s":\n%s'%(code,s)
    10581034
    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 
    12321035    ############################################################
    12331036    #         Functions for working with variables.
    12341037    #  The first three must be overloaded by derived classes,
     
    12361039    #  the functionality one gets from this is very nice.
    12371040    ############################################################
    12381041
    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 
    12851042    def _object_class(self):
    12861043        """
    12871044        EXAMPLES::
     
    13111068            <class 'sage.interfaces.expect.FunctionElement'>
    13121069        """
    13131070        return FunctionElement
     1071 
    13141072
    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):
     1073class ExpectFunction(InterfaceFunction):
    14451074    """
    14461075    Expect function.
    14471076    """
    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        
     1077    pass
    14681078
    14691079
    1470        
    1471 class FunctionElement(SageObject):
     1080class FunctionElement(InterfaceFunctionElement):
    14721081    """
    14731082    Expect function element.
    14741083    """
    1475     def __init__(self, obj, name):
    1476         self._obj = obj
    1477         self._name = name
     1084    pass
    14781085
    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)
    14971086
    14981087
    14991088def is_ExpectElement(x):
    15001089    return isinstance(x, ExpectElement)
    15011090
    1502 
    1503 
    1504 class ExpectElement(RingElement):
     1091class ExpectElement(InterfaceElement):
    15051092    """
    15061093    Expect element.
    15071094    """
     
    15261113                raise TypeError, x
    15271114        self._session_number = parent._session_number
    15281115
    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 
    15921116    def __hash__(self):
    15931117        """
    15941118        Returns the hash of self. This is a default implementation of hash
     
    15961120        """
    15971121        return hash('%s%s'%(self, self._session_number))
    15981122   
    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
    16211123
    16221124    def _check_valid(self):
    16231125        """
     
    16501152            #print msg
    16511153            pass
    16521154
    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
     1155#    def _sage_repr(self):
     1156#TO DO: this could use file transfers when self.is_remote()
    16971157
    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_()
    17351158       
    17361159    def __repr__(self):
    17371160        self._check_valid()
     
    17451168                s =  s.replace(self._name, self.__dict__['__custom_name'])
    17461169        return s
    17471170
    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 
    17541171    def get_using_file(self):
    17551172        """
    17561173        Return this element's string representation using a file. Use this
     
    17671184        except ValueError:
    17681185            return '(invalid object -- defined in terms of closed session)'
    17691186        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]))
    18151187   
    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)
    2011 
    20121188
    20131189class StdOutContext:
    20141190    """
     
    20341210            sage: with StdOutContext(gp):
    20351211            ...       gp('1+1')
    20361212            ...
    2037             sage[...
     1213            sage=...
    20381214        """
    20391215        self.interface = interface
    20401216        self.silent = silent
     
    20761252        self.stdout.write("\n")
    20771253        self.interface._expect.logfile = self._logfile_backup
    20781254
    2079 def reduce_load(parent, x):
    2080     return parent(x)
    2081 
    20821255import os
    20831256def console(cmd):
    20841257    os.system(cmd)
  • sage/interfaces/gap.py

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

    diff -r a928dca2950b -r b766df9c3439 sage/interfaces/maxima_lib.py
    a b  
    624624        self.__eval_using_file_cutoff = 10**9
    625625        self._available_vars = []
    626626        self._Expect__seq = 0
     627        self._Interface__seq = 0
    627628        self._session_number = 1
    628629        self._Expect__name = "maxima"
     630        self._Interface__name = "maxima"
    629631
    630632        if True:
    631633            # display2d -- no ascii art output
  • sage/symbolic/integration/integral.py

    diff -r a928dca2950b -r b766df9c3439 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:
  • sage/calculus/calculus.py

    # HG changeset patch
    # User Jean-Pierre Flori <flori@enst.fr>
    # Date 1297870719 -3600
    # Node ID fba59ed64da68b2a44e625ba60be03d053407484
    # Parent  b766df9c34391b224035c0f8e4a54524c59b0dfd
    Refactor Maxima's interfaces.
    
    diff -r b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 sage/interfaces/expect.py
    a b  
    489489        except Exception, msg:
    490490            pass
    491491
    492     def cputime(self):
    493         """
    494         CPU time since this process started running.
    495         """
    496         raise NotImplementedError
    497 
    498492    def quit(self, verbose=False, timeout=0.25):
    499493        """
    500494        EXAMPLES::
     
    10841078    pass
    10851079
    10861080
    1087 
    10881081def is_ExpectElement(x):
    10891082    return isinstance(x, ExpectElement)
    10901083
     
    11551148#    def _sage_repr(self):
    11561149#TO DO: this could use file transfers when self.is_remote()
    11571150
    1158        
    1159     def __repr__(self):
    1160         self._check_valid()
    1161         try:
    1162             if self._get_using_file:
    1163                 s = self.parent().get_using_file(self._name)
    1164         except AttributeError:
    1165             s = self.parent().get(self._name)
    1166         if s.__contains__(self._name):
    1167             if hasattr(self, '__custom_name'):
    1168                 s =  s.replace(self._name, self.__dict__['__custom_name'])
    1169         return s
    1170 
    1171     def get_using_file(self):
    1172         """
    1173         Return this element's string representation using a file. Use this
    1174         if self has a huge string representation. It'll be way faster.
    1175        
    1176         EXAMPLES::
    1177        
    1178             sage: a = maxima(str(2^1000))
    1179             sage: a.get_using_file()
    1180             '10715086071862673209484250490600018105614048117055336074437503883703510511249361224931983788156958581275946729175531468251871452856923140435984577574698574803934567774824230985421074605062371141877954182153046474983581941267398767559165543946077062914571196477686542167660429831652624386837205668069376'
    1181         """
    1182         try:
    1183             self._check_valid()
    1184         except ValueError:
    1185             return '(invalid object -- defined in terms of closed session)'
    1186         return self.parent().get_using_file(self._name)
    1187    
    11881151
    11891152class StdOutContext:
    11901153    """
  • sage/interfaces/interface.py

    diff -r b766df9c3439 -r fba59ed64da6 sage/interfaces/interface.py
    a b  
    5757    Interface interface object.
    5858    """
    5959    def __init__(self, name):
    60 
    6160        self.__name = name
    6261        self.__coerce_name = '_' + name.lower() + '_'
    6362        self.__seq = -1
     
    9796    def __del__(self):
    9897        pass
    9998
     99    def cputime(self):
     100        """
     101        CPU time since this process started running.
     102        """
     103        raise NotImplementedError
     104
    100105    def read(self, filename):
    101106        r"""
    102107        EXAMPLES::
     
    147152        except TypeError, s:
    148153            raise TypeError, 'error evaluating "%s":\n%s'%(code,s)
    149154
     155    _eval_line = eval
     156
    150157    def execute(self, *args, **kwds):
    151158        return self.eval(*args, **kwds)
    152159
     
    210217        TypeError.
    211218        """
    212219        s = '_%s_'%self.name()
     220#       if s == '_maxima_lib_':
     221#            s = '_maxima_'
    213222        if s == '_pari_':
    214223            s = '_gp_'
    215224        try:
  • sage/interfaces/maxima.py

    diff -r b766df9c3439 -r fba59ed64da6 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]
    1094 
    10951056def __doctest_cleanup():
    10961057    import sage.interfaces.quit
    10971058    sage.interfaces.quit.expect_quitall()
  • sage/interfaces/maxima_abstract.py

    diff -r b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 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*)
     72  (error
     73      (concatenate 'string "Maxima asks: "
     74      (string-trim '(#\Newline) (with-output-to-string (*standard-output*)
    50175      (terpri)
    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            ((null msg)
     81             (princ *prompt-prefix*)
     82             (princ *prompt-suffix*))
     83            ((atom msg)
     84             (format t "~a~a~a" *prompt-prefix* msg *prompt-suffix*)
     85             (mterpri))
     86            ((eq flag t)
     87             (princ *prompt-prefix*)
     88             (mapc #'princ (cdr msg))
     89             (princ *prompt-suffix*)
     90             (mterpri))
     91            (t
     92             (princ *prompt-prefix*)
     93             (displa msg)
     94             (princ *prompt-suffix*)
     95             (mterpri))))))))
    52296""")
    52397
    52498ecl_eval('(defparameter *dev-null* (make-two-way-stream (make-concatenated-stream) (make-broadcast-stream)))')
    52599ecl_eval('(defun principal nil (error "Divergent Integral"))')
    526 
    527100ecl_eval("(setf $errormsg nil)")
    528101
     102#ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))")
     103
     104#ecl_eval('(defun ask-evod (x even-odd)(error "Maxima asks a question"))')
     105#ecl_eval('(defun ask-integerp (x)(error "Maxima asks a question"))')
     106#ecl_eval('(defun ask-declare (x property)(error "Maxima asks a question"))')
     107#ecl_eval('(defun ask-prop (object property fun-or-number)(error "Maxima asks a question"))')
     108#ecl_eval('(defun asksign01 (a)(error "Maxima asks a question"))')
     109#ecl_eval('(defun asksign (x)(error "Maxima asks a question"))')
     110#ecl_eval('(defun asksign1 ($askexp)(error "Maxima asks a question"))')
     111#ecl_eval('(defun ask-greateq (x y)(error "Maxima asks a question"))')
     112#ecl_eval('(defun askinver (a)(error "Maxima asks a question"))')
     113#ecl_eval('(defun npask (exp)(error "Maxima asks a question"))')
     114
     115ecl_eval("(setf original-standard-output *standard-output*)")
     116ecl_eval("(setf *standard-output* *dev-null*)")
     117#ecl_eval("(setf *error-output* *dev-null*)")
     118
     119# display2d -- no ascii art output
     120# keepfloat -- don't automatically convert floats to rationals
     121init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)']
     122# Turn off the prompt labels, since computing them *very
     123# dramatically* slows down the maxima interpret after a while.
     124# See the function makelabel in suprv1.lisp.
     125# Many thanks to andrej.vodopivec@gmail.com and also
     126# Robert Dodier for figuring this out!
     127# See trac # 6818. 
     128init_code.append('nolabels : true')
     129for l in init_code:
     130    ecl_eval("#$%s$"%l)
     131## To get more debug information uncomment the next line
     132## should allow to do this through a method
     133#ecl_eval("(setf *standard-output* original-standard-output)")
     134
     135# This returns an EclObject
    529136maxima_eval=ecl_eval("""
    530137(defun maxima-eval( form )
    531138    (let ((result (catch 'macsyma-quit (cons 'maxima_eval (meval form)))))
     
    554161)
    555162""")
    556163
    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 
    573164maxima_lib_instances = 0
    574165
    575 maxprint=EclObject("$STRING")
     166# The Maxima string function can change the structure of its input
     167#maxprint=EclObject("$STRING")
     168maxprint=EclObject("(defun mstring-for-sage (form) (coerce (mstring form) 'string))").eval()
    576169meval=EclObject("MEVAL")
    577170msetq=EclObject("MSETQ")
    578171mlist=EclObject("MLIST")
     
    590183max_use_grobner=EclObject("$USE_GROBNER")
    591184max_to_poly_solve=EclObject("$TO_POLY_SOLVE")
    592185
     186def stdout_to_string(s):
     187    return ecl_eval("(with-output-to-string (*standard-output*) (maxima-eval #$%s$))"%s).python()[1:-1]
     188
    593189def max_to_string(s):
    594      return meval(EclObject([[maxprint],s])).python()[1:-1]
     190     return maxprint(s).python()[1:-1]
    595191
    596 class Maxima(maxima_abstract.Maxima):
     192my_mread=ecl_eval("""
     193(defun my-mread (cmd)
     194  (caddr (mread (make-string-input-stream cmd))))
     195""")
     196
     197def parse_max_string(l):
     198  return my_mread('"%s;"'%l)
     199
     200class MaximaLib(MaximaAbstract):
    597201    """
    598     Interface to the Maxima interpreter.
     202    Interface to Maxima as a Library.
    599203    """
    600     def __init__(self, script_subdirectory=None, logfile=None, server=None,
    601                  init_code = None):
     204    def __init__(self):
    602205        """
    603206        Create an instance of the Maxima interpreter.
    604207
    605208        TESTS::
    606        
    607             sage: maxima == loads(dumps(maxima))
     209
     210            sage: from sage.interfaces.maxima_lib import maxima_lib
     211            sage: maxima_lib == loads(dumps(maxima_lib))
    608212            True
    609213
    610214        We make sure labels are turned off (see trac 6816)::
    611215       
    612             sage: 'nolabels:true' in maxima._Expect__init_code
     216            sage: 'nolabels : true' in maxima_lib._MaximaLib__init_code
    613217            True
    614218        """
    615219        global maxima_lib_instances
    616220        if maxima_lib_instances > 0:
    617221            raise RuntimeError, "Maxima interface in library mode can only be instantiated once"
    618222        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._Interface__seq = 0
    628         self._session_number = 1
    629         self._Expect__name = "maxima"
    630         self._Interface__name = "maxima"
    631223
    632         if True:
    633             # display2d -- no ascii art output
    634             # keepfloat -- don't automatically convert floats to rationals
    635             init_code = ['display2d : false', 'domain : complex', 'keepfloat : true', 'load(to_poly_solver)', 'load(simplify_sum)']
    636            
    637         # Turn off the prompt labels, since computing them *very
    638         # dramatically* slows down the maxima interpret after a while.
    639         # See the function makelabel in suprv1.lisp.
    640         # Many thanks to andrej.vodopivec@gmail.com and also
    641         # Robert Dodier for figuring this out!
    642         # See trac # 6818. 
    643         init_code.append('nolabels : true')
    644         ecl_eval("(setf original-standard-output *standard-output*)")
    645         ecl_eval("(setf *standard-output* *dev-null*)")
    646         for l in init_code:
    647             ecl_eval("#$%s$"%l)
    648         ecl_eval("(setf *standard-output* original-standard-output)")
     224        global init_code
     225        self.__init_code = init_code
     226
     227        ## The name should definitely be changed to maxima_lib, however much more changes are then needed elsewhere
     228        ## 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)
     229        MaximaAbstract.__init__(self,"maxima")
     230        self.__seq = 0
    649231 
    650232    def _coerce_from_special_method(self, x):
    651233        if isinstance(x, EclObject):
    652             return MaximaElement(self,self._create(x))
     234            return MaximaLibElement(self,self._create(x))
    653235        else:
    654             return maxima_abstract.Maxima._coerce_from_special_method(self,x)
    655        
    656        
    657     def _function_class(self):
    658         """
    659         EXAMPLES::
    660        
    661             sage: maxima._function_class()
    662             <class 'sage.interfaces.maxima_abstract.MaximaExpectFunction'>
    663         """
    664         return MaximaExpectFunction
    665 
    666     def _start(self):
    667         """
    668         Starts the Maxima interpreter.
    669        
    670         EXAMPLES::
    671        
    672             sage: m = Maxima()
    673             sage: m.is_running()
    674             False
    675             sage: m._start()
    676             sage: m.is_running()
    677             True
    678         """
    679 #        ecl_eval(r"(defun tex-derivative (x l r) (tex (if $derivabbrev (tex-dabbrev x) (tex-d x '\partial)) l r lop rop ))")
    680         pass
     236            return MaximaAbstract._coerce_from_special_method(self,x)
    681237       
    682238    def __reduce__(self):
    683239        """
    684240        EXAMPLES::
    685241       
    686             sage: maxima.__reduce__()
    687             (<function reduce_load_Maxima at 0x...>, ())
     242            sage: from sage.interfaces.maxima_lib import maxima_lib
     243            sage: maxima_lib.__reduce__()
     244            (<function reduce_load_MaximaLib at 0x...>, ())
    688245        """
    689         return reduce_load_Maxima, tuple([])
     246        return reduce_load_MaximaLib, tuple([])
    690247
    691     def _sendline(self, str):
    692         self._sendstr(str)
    693         os.write(self._expect.child_fd, os.linesep)
    694 
    695     def _expect_expr(self, expr=None, timeout=None):
    696         """
    697         EXAMPLES:
    698             sage: a,b=var('a,b')
    699             sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x)
    700             Traceback (most recent call last):
    701             ...
    702             RuntimeError: ECL says: Maxima asks:...
    703             sage: assume(a>0)
    704             sage: integrate(1/(x^3 *(a+b*x)^(1/3)),x)
    705             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)
    706             sage: var('x, n')
    707             (x, n)
    708             sage: integral(x^n,x)
    709             Traceback (most recent call last):
    710             ...
    711             RuntimeError: ECL says: Maxima asks:...
    712             sage: assume(n+1>0)
    713             sage: integral(x^n,x)
    714             x^(n + 1)/(n + 1)
    715             sage: forget()
    716         """
    717         if expr is None:
    718             expr = self._prompt_wait
    719         if self._expect is None:
    720             self._start()
    721         try:
    722             if timeout:
    723                 i = self._expect.expect(expr,timeout=timeout)
    724             else:
    725                 i = self._expect.expect(expr)
    726             if i > 0:
    727                 v = self._expect.before
    728 
    729                 #We check to see if there is a "serious" error in Maxima.
    730                 #Note that this depends on the order of self._prompt_wait
    731                 if expr is self._prompt_wait and i > len(self._ask):
    732                     self.quit()
    733                     raise ValueError, "%s\nComputation failed due to a bug in Maxima -- NOTE: Maxima had to be restarted."%v
    734 
    735                 j = v.find('Is ')
    736                 v = v[j:]
    737                 k = v.find(' ',4)
    738                 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]
    739                 self._sendline(";")
    740                 self._expect_expr()
    741                 raise ValueError, msg
    742         except KeyboardInterrupt, msg:
    743             #print self._expect.before
    744             i = 0
    745             while True:
    746                 try:
    747                     print "Control-C pressed.  Interrupting Maxima. Please wait a few seconds..."
    748                     self._sendstr('quit;\n'+chr(3))
    749                     self._sendstr('quit;\n'+chr(3))
    750                     self.interrupt()
    751                     self.interrupt()
    752                 except KeyboardInterrupt:
    753                     i += 1
    754                     if i > 10:
    755                         break
    756                     pass
    757                 else:
    758                     break
    759             raise KeyboardInterrupt, msg
    760 
    761     def _eval_line(self, line, allow_use_file=False,
    762                    wait_for_prompt=True, reformat=True, error_check=True):
     248    # This outputs a string
     249    def eval(self, line, locals=None, reformat=True, **kwds):
    763250        result = ''
    764251        while line:
    765252            ind_dollar=line.find("$")
     
    771258                else:
    772259                    statement = line[:ind_semi]
    773260                    line = line[ind_semi+1:]
    774                 if statement: result = ((result + '\n') if result else '')+ max_to_string(maxima_eval("#$%s$"%statement))
     261                if statement: result = ((result + '\n') if result else '') + max_to_string(maxima_eval("#$%s$"%statement))
    775262            else:
    776263                statement = line[:ind_dollar]
    777264                line = line[ind_dollar+1:]
    778                 if statement: _ = max_to_string(maxima_eval("#$%s$"%statement))
    779         return result
     265                if statement: _ = maxima_eval("#$%s$"%statement)
     266        if not reformat:
     267            return result
     268        return ''.join([x.strip() for x in result.split()])
    780269
    781     def _synchronize(self):
    782         """
    783         Synchronize pexpect interface.
    784        
    785         This put a random integer (plus one!) into the output stream, then
    786         waits for it, thus resynchronizing the stream. If the random
    787         integer doesn't appear within 1 second, maxima is sent interrupt
    788         signals.
    789        
    790         This way, even if you somehow left maxima in a busy state
    791         computing, calling _synchronize gets everything fixed.
    792        
    793         EXAMPLES: This makes Maxima start a calculation::
    794        
    795             sage: maxima._sendstr('1/1'*500)
    796        
    797         When you type this command, this synchronize command is implicitly
    798         called, and the above running calculation is interrupted::
    799        
    800             sage: maxima('2+2')
    801             4
    802         """
    803         marker = '__SAGE_SYNCHRO_MARKER_'
    804         if self._expect is None: return
    805         r = randrange(2147483647)
    806         s = marker + str(r+1)
    807 
    808         # The 0; *is* necessary... it comes up in certain rare cases
    809         # that are revealed by extensive testing.  Don't delete it. -- william stein
    810         cmd = '''0;sconcat("%s",(%s+1));\n'''%(marker,r)
    811         self._sendstr(cmd)
    812         try:
    813             self._expect_expr(timeout=0.5)
    814             if not s in self._before():
    815                 self._expect_expr(s,timeout=0.5)
    816                 self._expect_expr(timeout=0.5)
    817         except pexpect.TIMEOUT, msg:
    818             self._interrupt()
    819         except pexpect.EOF:
    820             self._crash_msg()
    821             self.quit()
     270    _eval_line = eval
    822271
    823272    ###########################################
    824273    # Direct access to underlying lisp interpreter.
     
    833282       
    834283        EXAMPLES::
    835284       
    836             sage: maxima.lisp("(+ 2 17)")   # random formatted output
    837              :lisp (+ 2 17)
    838             19
    839             (
     285            sage: from sage.interfaces.maxima_lib import maxima_lib
     286            sage: maxima_lib.lisp("(+ 2 17)")
     287            <ECL: 19>
    840288        """
    841         self._eval_line(':lisp %s\n""'%cmd, allow_use_file=False, wait_for_prompt=False, reformat=False, error_check=False)
    842         self._expect_expr('(%i)')
    843         return self._before()
    844 
    845     ###########################################
    846     # Interactive help
    847     ###########################################
    848     def _command_runner(self, command, s, redirect=True):
    849         """
    850         Run ``command`` in a new Maxima session and return its
    851         output as an ``AsciiArtString``.
    852        
    853         If redirect is set to False, then the output of the command is not
    854         returned as a string. Instead, it behaves like os.system. This is
    855         used for interactive things like Maxima's demos. See maxima.demo?
    856        
    857         EXAMPLES::
    858        
    859             sage: maxima._command_runner('describe', 'gcd')
    860             -- Function: gcd (<p_1>, <p_2>, <x_1>, ...)
    861             ...
    862         """
    863         cmd = 'maxima --very-quiet -r "%s(%s);" '%(command, s)
    864         if sage.server.support.EMBEDDED_MODE:
    865             cmd += '< /dev/null'
    866 
    867         if redirect:
    868             p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
    869                              stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    870             res = p.stdout.read()
    871             # ecl-10.2 : 3 lines
    872             # ecl-10.4 : 5 lines
    873             # ecl-11.1 : 4 lines fancy a tango?
    874             # We now get 4 lines of commented verbosity
    875             # every time Maxima starts, so we need to get rid of them
    876             for _ in range(4):
    877                 res = res[res.find('\n')+1:]
    878             return AsciiArtString(res)
    879         else:
    880             subprocess.Popen(cmd, shell=True)
    881 
    882     def _object_class(self):
    883         """
    884         Return the Python class of Maxima elements.
    885        
    886         EXAMPLES::
    887        
    888             sage: maxima._object_class()
    889             <class 'sage.interfaces.maxima_abstract.MaximaElement'>
    890         """
    891         return MaximaElement
    892 
    893     def _function_element_class(self):
    894         """     
    895         EXAMPLES::
    896        
    897             sage: maxima._function_element_class()
    898             <class 'sage.interfaces.maxima_abstract.MaximaFunctionElement'>
    899         """
    900         return MaximaFunctionElement
    901 
    902     def function(self, args, defn, rep=None, latex=None):
    903         """
    904         Return the Maxima function with given arguments and definition.
    905        
    906         INPUT:
    907        
    908        
    909         -  ``args`` - a string with variable names separated by
    910            commas
    911        
    912         -  ``defn`` - a string (or Maxima expression) that
    913            defines a function of the arguments in Maxima.
    914        
    915         -  ``rep`` - an optional string; if given, this is how
    916            the function will print.
    917        
    918        
    919         EXAMPLES::
    920        
    921             sage: f = maxima.function('x', 'sin(x)')
    922             sage: f(3.2)
    923             -.058374143427580...
    924             sage: f = maxima.function('x,y', 'sin(x)+cos(y)')
    925             sage: f(2,3.5)
    926             sin(2)-.9364566872907963
    927             sage: f
    928             sin(x)+cos(y)
    929        
    930         ::
    931        
    932             sage: g = f.integrate('z')
    933             sage: g
    934             (cos(y)+sin(x))*z
    935             sage: g(1,2,3)
    936             3*(cos(2)+sin(1))
    937        
    938         The function definition can be a maxima object::
    939        
    940             sage: an_expr = maxima('sin(x)*gamma(x)')
    941             sage: t = maxima.function('x', an_expr)
    942             sage: t
    943             gamma(x)*sin(x)
    944             sage: t(2)
    945              sin(2)
    946             sage: float(t(2))
    947             0.90929742682568171
    948             sage: loads(t.dumps())
    949             gamma(x)*sin(x)
    950         """
    951         name = self._next_var_name()
    952         if isinstance(defn, MaximaElement):
    953             defn = defn.str()
    954         elif not isinstance(defn, str):
    955             defn = str(defn)
    956         if isinstance(args, MaximaElement):
    957             args = args.str()
    958         elif not isinstance(args, str):
    959             args = str(args)
    960         cmd = '%s(%s) := %s'%(name, args, defn)
    961         maxima._eval_line(cmd)
    962         if rep is None:
    963             rep = defn
    964         f = MaximaFunction(self, name, rep, args, latex)
    965         return f
     289        return ecl_eval(cmd)
    966290
    967291    def set(self, var, value):
    968292        """
     
    978302       
    979303        EXAMPLES::
    980304       
    981             sage: maxima.set('xxxxx', '2')
    982             sage: maxima.get('xxxxx')
     305            sage: from sage.interfaces.maxima_lib import maxima_lib
     306            sage: maxima_lib.set('xxxxx', '2')
     307            sage: maxima_lib.get('xxxxx')
    983308            '2'
    984309        """
    985310        if not isinstance(value, str):
    986311            raise TypeError
    987312        cmd = '%s : %s$'%(var, value.rstrip(';'))
    988         if len(cmd) > self.__eval_using_file_cutoff:
    989             self._batch(cmd, batchload=True)
    990         else:
    991             self._eval_line(cmd)
    992             #self._sendline(cmd)
    993             #self._expect_expr()
    994             #out = self._before()
    995             #self._error_check(cmd, out)
     313        self.eval(cmd)
    996314
    997315    def clear(self, var):
    998316        """
     
    1000318
    1001319        EXAMPLES::
    1002320
    1003             sage: maxima.set('xxxxx', '2')
    1004             sage: maxima.get('xxxxx')
     321            sage: from sage.interfaces.maxima_lib import maxima_lib
     322            sage: maxima_lib.set('xxxxx', '2')
     323            sage: maxima_lib.get('xxxxx')
    1005324            '2'
    1006             sage: maxima.clear('xxxxx')
    1007             sage: maxima.get('xxxxx')
     325            sage: maxima_lib.clear('xxxxx')
     326            sage: maxima_lib.get('xxxxx')
    1008327            'xxxxx'
    1009328        """
    1010329        try:
    1011             self._expect.send('kill(%s)$'%var)
     330            self.eval('kill(%s)$'%var)
    1012331        except (TypeError, AttributeError):
    1013              pass
     332            pass
    1014333
    1015334    def get(self, var):
    1016335        """
     
    1018337       
    1019338        EXAMPLES::
    1020339       
    1021             sage: maxima.set('xxxxx', '2')
    1022             sage: maxima.get('xxxxx')
     340            sage: from sage.interfaces.maxima_lib import maxima_lib
     341            sage: maxima_lib.set('xxxxx', '2')
     342            sage: maxima_lib.get('xxxxx')
    1023343            '2'
    1024344        """
    1025         s = self._eval_line('%s;'%var)
     345        s = self.eval('%s;'%var)
    1026346        return s
    1027347 
    1028348    def _create(self, value, name=None):
     
    1032352        else:
    1033353            self.set(name, value)
    1034354        return name
    1035                
    1036     def version(self):
     355
     356    def _function_class(self):
    1037357        """
    1038         Return the version of Maxima that Sage includes.
     358        EXAMPLES::
     359       
     360            sage: from sage.interfaces.maxima_lib import maxima_lib
     361            sage: maxima_lib._function_class()
     362            <class 'sage.interfaces.maxima_lib.MaximaLibFunction'>
     363        """
     364        return MaximaLibFunction
     365
     366    def _object_class(self):
     367        """
     368        Return the Python class of Maxima elements.
    1039369       
    1040370        EXAMPLES::
    1041371       
    1042             sage: maxima.version()
    1043             '5.23.2'
     372            sage: from sage.interfaces.maxima_lib import maxima_lib
     373            sage: maxima_lib._object_class()
     374            <class 'sage.interfaces.maxima_lib.MaximaLibElement'>
    1044375        """
    1045         return maxima_version()
     376        return MaximaLibElement
    1046377
    1047 ##some helper functions to wrap tha calculus use of the maxima interface.
    1048 ##these routines expect arguments living in the symbolic ring and return something
    1049 ##that is hopefully coercible into the symbolic ring again.
     378    def _function_element_class(self):
     379        """     
     380        EXAMPLES::
     381       
     382            sage: from sage.interfaces.maxima_lib import maxima_lib
     383            sage: maxima_lib._function_element_class()
     384            <class 'sage.interfaces.maxima_lib.MaximaLibFunctionElement'>
     385        """
     386        return MaximaLibFunctionElement
     387
     388    def _object_function_class(self):
     389        """
     390        EXAMPLES::
     391       
     392            sage: from sage.interfaces.maxima_lib import maxima_lib
     393            sage: maxima_lib._object_function_class()
     394            <class 'sage.interfaces.maxima_lib.MaximaLibElementFunction'>
     395        """
     396        return MaximaLibElementFunction
     397
     398    ##some helper functions to wrap the calculus use of the maxima interface.
     399    ##these routines expect arguments living in the symbolic ring and return something
     400    ##that is hopefully coercible into the symbolic ring again.
    1050401
    1051402    def sr_integral(self,*args):
    1052403        try:
     
    1084435            L.append(max_minus)
    1085436        return max_to_sr(maxima_eval(([max_tlimit],L)))
    1086437
    1087 ##     def display2d(self, flag=True):
    1088 ##         """
    1089 ##         Set the flag that determines whether Maxima objects are
    1090 ##         printed using their 2-d ASCII art representation.  When the
    1091 ##         maxima interface starts the default is that objects are not
    1092 ##         represented in 2-d.
    1093438
    1094 ##         INPUT:
    1095 ##             flag -- bool (default: True)
     439def is_MaximaLibElement(x):
     440    """
     441    Returns True if x is of type MaximaLibElement.
     442   
     443    EXAMPLES::
     444   
     445        sage: from sage.interfaces.maxima_lib import maxima_lib, is_MaximaLibElement
     446        sage: m = maxima_lib(1)
     447        sage: is_MaximaLibElement(m)
     448        True
     449        sage: is_MaximaLibElement(1)
     450        False
     451    """
     452    return isinstance(x, MaximaLibElement)
    1096453
    1097 ##         EXAMPLES
    1098 ##             sage: maxima('1/2')
    1099 ##             1/2
    1100 ##             sage: maxima.display2d(True)
    1101 ##             sage: maxima('1/2')
    1102 ##                                            1
    1103 ##                                            -
    1104 ##                                            2
    1105 ##             sage: maxima.display2d(False)
    1106 ##         """
    1107 ##         self._display2d = bool(flag)
    1108 
    1109 class MaximaElement(maxima_abstract.MaximaElement):
     454class MaximaLibElement(MaximaAbstractElement):
    1110455    """
    1111456    """   
    1112457    def ecl(self):
     
    1124469            cmd=EclObject([[max_to_poly_solve], self.ecl(), sr_to_max(vars)])
    1125470        return self.parent()(maxima_eval(cmd))
    1126471
    1127 def is_MaximaElement(x):
    1128     """
    1129     Returns True if x is of type MaximaElement.
    1130    
    1131     EXAMPLES::
    1132    
    1133         sage: from sage.interfaces.maxima import is_MaximaElement
    1134         sage: m = maxima(1)
    1135         sage: is_MaximaElement(m)
    1136         True
    1137         sage: is_MaximaElement(1)
    1138         False
    1139     """
    1140     return isinstance(x, MaximaElement)
     472    def display2d(self, onscreen=True):
     473        """
     474        EXAMPLES::
     475       
     476            sage: from sage.interfaces.maxima_lib import maxima_lib
     477            sage: F = maxima_lib('x^5 - y^5').factor() 
     478            sage: F.display2d ()             
     479                                   4      3    2  2    3      4
     480                       - (y - x) (y  + x y  + x  y  + x  y + x )
     481        """
     482        self._check_valid()
     483        P = self.parent()
     484        P._eval_line('display2d : true$')
     485        s = stdout_to_string('disp(%s)'%self.name())
     486        #s = P._eval_line('disp(%s)$'%self.name())
     487        P._eval_line('display2d : false$')
     488        s = s.strip('\r\n')
    1141489
    1142 # An instance
    1143 maxima = Maxima()
     490        # if ever want to dedent, see
     491        # http://mail.python.org/pipermail/python-list/2006-December/420033.html
     492        if onscreen:
     493            print s
     494        else:
     495            return s
    1144496
    1145 def reduce_load_Maxima():
     497
     498class MaximaLibFunctionElement(MaximaAbstractFunctionElement):
     499    pass
     500
     501
     502class MaximaLibFunction(MaximaAbstractFunction):
     503    pass
     504
     505
     506class MaximaLibElementFunction(MaximaLibElement, MaximaAbstractElementFunction):
     507    pass
     508
     509
     510# The (unique) instance
     511maxima_lib = MaximaLib()
     512maxima = maxima_lib
     513
     514
     515def reduce_load_MaximaLib():
    1146516    """
    1147517    EXAMPLES::
    1148518   
    1149         sage: from sage.interfaces.maxima import reduce_load_Maxima
    1150         sage: reduce_load_Maxima()
     519        sage: from sage.interfaces.maxima_lib import reduce_load_MaximaLib
     520        sage: reduce_load_MaximaLib()
    1151521        Maxima
    1152522    """
    1153     return maxima
     523    return maxima_lib
    1154524
    1155 
    1156 def maxima_version():
    1157     """
    1158     EXAMPLES::
    1159    
    1160         sage: from sage.interfaces.maxima import maxima_version
    1161         sage: maxima_version()
    1162         '5.23.2'
    1163     """
    1164     return os.popen('maxima --version').read().split()[-1]
    1165 
    1166 def __doctest_cleanup():
    1167     import sage.interfaces.quit
    1168     sage.interfaces.quit.expect_quitall()
    1169 
    1170 
    1171 import sage.symbolic.expression
    1172 from sage.symbolic.ring import SR
     525#**********************************
     526# ???
    1173527
    1174528import sage.symbolic.expression
    1175529import sage.functions.trig
    1176530import sage.functions.log
    1177531import sage.functions.other
    1178532import sage.symbolic.integration.integral
     533from sage.symbolic.operators import FDerivativeOperator
    1179534
    1180535car=EclObject("car")
    1181536cdr=EclObject("cdr")
     
    1189544NIL=EclObject("NIL")
    1190545ratdisrep=EclObject("ratdisrep")
    1191546
    1192 sage_op_dict={}
    1193 
    1194547sage_op_dict = {
    1195548    sage.symbolic.expression.operator.abs : "MABS",
    1196549    sage.symbolic.expression.operator.add : "MPLUS",
     
    1225578    sage.functions.other.erf : "%ERF",
    1226579    sage.functions.other.gamma_inc : "%GAMMA_INCOMPLETE"
    1227580}
    1228 
    1229581#we compile the dictionary
    1230582sage_op_dict = dict([(k,EclObject(sage_op_dict[k])) for k in sage_op_dict])
    1231583max_op_dict = dict([(sage_op_dict[k],k) for k in sage_op_dict])
     584
    1232585def add_vararg(*args):
    1233586    S=0
    1234587    for a in args:
     
    1246599
    1247600mplus=EclObject("MPLUS")
    1248601mtimes=EclObject("MTIMES")
     602mdiff=EclObject("%DERIVATIVE")
    1249603rat=EclObject("RAT")
    1250604max_i=EclObject("$%I")
    1251605max_op_dict[mplus]=add_vararg
     
    1292646    else:
    1293647        return sage.symbolic.integration.integral.indefinite_integral(*args, hold=True)
    1294648
     649def mdiff_to_sage(expr):
     650    return max_to_sr(expr.cadr()).diff(*[max_to_sr(e) for e in expr.cddr()])
     651
    1295652special_max_to_sage={
    1296653    EclObject("MRAT") : mrat_to_sage,
    1297     EclObject("MQAPPLY") : mqapply_to_sage,
    1298     EclObject("%INTEGRATE") : dummy_integrate
     654    mqapply : mqapply_to_sage,
     655    EclObject("%INTEGRATE") : dummy_integrate,
     656    mdiff : mdiff_to_sage
    1299657}
    1300658
    1301659special_sage_to_max={
     
    1314672    elif isinstance(obj,sage.rings.number_field.number_field_element_quadratic.NumberFieldElement_quadratic) and obj.parent().defining_polynomial().list() == [1,0,1]:
    1315673        re, im = obj.list()
    1316674        return EclObject([[mplus], pyobject_to_max(re), [[mtimes], pyobject_to_max(im), max_i]])
    1317    
    1318675    return EclObject(obj)
    1319676
     677# This goes from SR to EclObject
    1320678def sr_to_max(expr):
    1321679    r"""
    1322680    """
     
    1326684        return EclObject(([mlist],[sr_to_max(e) for e in expr]))
    1327685    op = expr.operator()
    1328686    if op:
    1329         if (op in special_sage_to_max):
     687        # Stolen from sage.symbolic.expression_conversion
     688        # Should be defined in a function and then put in special_sage_to_max
     689        # For that, we should change the API of the functions there (we need to have access to op, not only to expr.operands()
     690        if isinstance(op, FDerivativeOperator):
     691            from sage.symbolic.ring import is_SymbolicVariable
     692            args = expr.operands()
     693            if (not all(is_SymbolicVariable(v) for v in args) or
     694                len(args) != len(set(args))):
     695                raise NotImplementedError, "arguments must be distinct variables"
     696            f = sr_to_max(op.function()(*args))
     697            params = op.parameter_set()
     698            deriv_max = []
     699            [deriv_max.extend([sr_to_max(args[i]), EclObject(params.count(i))]) for i in set(params)]
     700            l = [mdiff,f]
     701            l.extend(deriv_max)
     702            return EclObject(l)
     703        elif (op in special_sage_to_max):
    1330704            return EclObject(special_sage_to_max[op](*[sr_to_max(o) for o in expr.operands()]))
    1331705        elif not (op in sage_op_dict):
    1332             op_max=caar(maxima(expr).ecl())
     706            # Maxima does some simplifications automatically by default
     707            # so calling maxima(expr) can change the structure of expr
     708            #op_max=caar(maxima(expr).ecl())
     709            # This should be safe if we treated all special operators above
     710            op_max=maxima(op).ecl()
    1333711            sage_op_dict[op]=op_max
    1334712            max_op_dict[op_max]=op
    1335713        return EclObject(([sage_op_dict[op]],
     
    1346724        except TypeError:
    1347725            return maxima(expr).ecl()
    1348726   
     727# This goes from EclObject to SR
    1349728def max_to_sr(expr):
    1350729    if expr.consp():
    1351730        op_max=caar(expr)
    1352731        if op_max in special_max_to_sage:
    1353732            return special_max_to_sage[op_max](expr)
    1354733        if not(op_max in max_op_dict):
     734            # This could be unsafe if the conversion to SR chenges the structure of expr
    1355735            sage_expr=SR(maxima(expr))
    1356736            max_op_dict[op_max]=sage_expr.operator()
    1357737            sage_op_dict[sage_expr.operator()]=op_max
    1358738        op=max_op_dict[op_max]
    1359739        max_args=cdr(expr)
    1360         args=[ max_to_sr(a) for a in max_args]
     740        args=[max_to_sr(a) for a in max_args]
    1361741        return op(*args)
    1362742    elif expr.symbolp():
    1363743        if not(expr in max_sym_dict):
  • sage/structure/sage_object.pyx

    diff -r b766df9c3439 -r fba59ed64da6 sage/structure/sage_object.pyx
    a b  
    518518    def _maxima_init_(self):
    519519        import sage.interfaces.maxima
    520520        I = sage.interfaces.maxima.maxima
     521        return self._interface_init_(I)   
     522
     523    def _maxima_lib_(self, G=None):
     524        if G is None:
     525            import sage.interfaces.maxima_lib
     526            G = sage.interfaces.maxima_lib.maxima_lib
     527        return self._interface_(G)
     528   
     529    def _maxima_lib_init_(self):
     530        import sage.interfaces.maxima_lib
     531        I = sage.interfaces.maxima_lib.maxima_lib
    521532        return self._interface_init_(I)
    522533   
    523534    def _magma_init_(self, magma):
  • sage/symbolic/expression.pyx

    diff -r b766df9c3439 -r fba59ed64da6 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 b766df9c3439 -r fba59ed64da6 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    """