source: git/dyn_modules/openmath/objects.py @ 021751

fieker-DuValspielwiese
Last change on this file since 021751 was 3c473c, checked in by Kai Krüger <krueger@…>, 14 years ago
rename directory modules to dyn_modules anticipating "modules" directory for cmake. git-svn-id: file:///usr/local/Singular/svn/trunk@13033 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.5 KB
Line 
1"""Implementation of openmath basic objects"""
2from omexceptions import UnsupportedOperationError
3from  omexceptions import OutOfScopeError, EvaluationFailedError
4from exceptions import NotImplementedError
5from copy import copy
6from xml.sax.xmlreader import AttributesImpl as attr
7from itertools import izip
8import base64
9
10raiseException=True
11#TODO: OMOBJ, OME, OMATTR
12#from cd import *
13try:
14    import psyco
15    def optimize(f):
16        psyco.bind(f)
17except:
18    def optimize(f):
19        pass
20
21class OMCD(object):
22    def __init__(self, name, base="http://www.openmath.org/cd"):
23        self.name = name
24        self.base = base
25    def  __eq__(self, other):
26        try:
27            return (self.name == other.name) and (self.base == other.base)
28        except:
29            return False
30    def __hash__(self):
31        return hash((self.name,self.base))
32
33
34       
35class OMCDImplementation(object):
36    converter=None
37    def __init__(self, cd):
38        object.__setattr__(self,"cd",cd)
39        #object.__setattr__(self,"converter",None)
40    def support(self,symbol):
41        setattr(self,symbol,OMS(symbol, self.cd))
42    def __setattr__(self, name,value):
43        if name=="converter":
44            object.__setattr__(self,name,value)
45            return
46        "FIXME: implements this later safer against name conflicts"
47        if callable(value) and (not isinstance(value, ImplementedSymbol)):
48           
49            if self.converter!=None:
50                object.__setattr__(
51                    self, 
52                    name, 
53                    ImplementedSymbol(
54                        OMS(name,self.cd), 
55                        self.converter(value)))
56            else:
57                object.__setattr__(self, name, ImplementedSymbol(OMS(name,self.cd), value))
58        else:
59            object.__setattr__(self,name,value)
60
61class OMS(object):
62    def __init__(self,name,cd = None):
63        #super(OMSymbol,self).__init__()
64        self.cd = cd
65        self.name = name
66    def __eq__(self, other):
67        try:
68            return bool(other.name == self.name and self.cd == other.cd)
69        except:
70            return False
71    def __str__(self):
72        return "OMS(" + self.name + ", " + self.cd.name + ")"
73    def __repr__(self):
74        return str(self)
75    def __hash__(self):#
76        return hash((self.name,self.cd.__hash__()))
77    def evaluate(self,context):
78        return context.evaluateSymbol(self)
79    XMLtag="OMS"
80    def getXMLAttributes(self):
81        #return [XMLAttribute("name", self.name),\
82        #         XMLAttribute("cdbase", self.cd.base),\
83        #         XMLAttribute("cd", self.cd.name)]
84        return {"name":self.name, "cdbase":self.cd.base, "cd": self.cd.name}
85    def setXMLAttributes(self):
86        raise UnsupportedOperationError
87
88
89class ImplementedSymbol(OMS):
90    def __init__(self,symbol, func):
91        super(ImplementedSymbol,self).__init__(symbol.name, symbol.cd)
92        self.implementation = func
93    def __str__(self):
94        return "OMS("+self.name+", " + self.cd.name +")"
95    def __call__(self, context, *args):
96        try:
97            erg=self.implementation(*args)
98        except KeyError:
99             raise EvaluationFailedError
100        return context.package(erg)
101
102cdFns1 = OMCD("fns1")
103lambdasym = OMS("lambda", cdFns1)
104
105def islambda(sym):
106    "return True, iff sym is the lambda binder"
107    return lambdasym == sym
108   
109class OMBIND(object):
110    """hopefully fixed possible problems: reevaluation writes new scope,
111       if it isn't
112       meant so, references do not work correctly because of scopes
113       solve this by first evaluation to bounded OMBinding"""
114    def __init__(self, binder, variables, block):
115        #super(OMBinding, self).__init__()
116        self.block = block
117        self.binder = binder
118        self.variables = variables
119        self.bounded = False
120    def evaluate(self, context):
121        "evaluate the OMbinding in context"
122        assert islambda(self.binder)
123        if not self.bounded:
124            mycopy = copy(self)
125            mycopy.scope = context.scopeFromCurrentScope()
126            mycopy.bounded = True
127            return mycopy
128        else:
129            return self
130    def bind(self, args):
131        "bind arguments to values"
132        #print args, self.variables
133        assert len(args) == len(self.variables)
134        varBindings = dict(izip([i.name for i in self.variables], args))
135        self.scope.push(varBindings)
136    def unbind(self):
137        "unbind the arguments"
138        self.scope.pop()
139
140    def calcErg(self, context):
141        "do the actual computation"
142        return context.evaluateInScope(self.block, self.scope)
143    def __call__(self, context, *args):
144        assert self.bounded
145        self.bind(args)
146        erg = self.calcErg(context)
147        self.unbind()
148        #print "__call__ erg is", erg
149        return erg   
150       
151    XMLtag = "OMBIND"
152    def getChildren(self):
153        "get children for (XML) representation"
154        return [self.binder]+self.variables+[self.block]
155   
156    def __str__(self):
157        return "OMBIND(self.binder"+", "+str(self.variables) +", " + str(self.block) +")"
158       
159
160class OMOBJ(object):
161    def __init__(self, children):
162        #super(OMObject, self).__init__()
163        self.children = children
164    def getChildren(self):
165        return self.__children
166    def setChildren(self ,children):
167        self.__children=children
168    XMLtag = "OMOBJ"
169    def evaluate(self, context):
170        return OMObject([context.evaluate(c) for c in self.children])
171class OMV(object):
172    def __init__(self,name):
173        #super(OMVar, self).__init__()
174        self.name = name
175    def evaluate(self, context):
176        try:
177            return context[self.name]
178        except OutOfScopeError:
179            return self
180    def __str__(self):
181        return "OMV(" + self.name +")"
182    def __repr__(self):
183        return str(self)
184    XMLtag="OMV"
185class OMA(object):
186    def __init__(self, func, args):
187        #super(OMApply, self).__init__()
188        self.func = func
189        self.args = args
190       
191    def evaluate(self, context):
192        efunc = context.evaluate(self.func)
193        eargs = [context.evaluate(a) for a in self.args]
194        if callable(efunc):
195            if raiseException:
196                return context.apply(efunc,eargs)
197            else:
198                try:
199                    return context.apply(efunc, eargs)
200                except EvaluationFailedError, NotImplementedError:
201                    return OMA(efunc, eargs)
202                #return self
203        else:
204            #print efunc
205            return OMA(efunc, eargs)
206    def __str__ (self):
207        return "OMA"+"("+str(self.func)+str(self.args)
208    def __repr__ (self):
209        return "OMA"+"("+str(self.func)+str(self.args)
210    XMLtag="OMA"
211       
212
213# class OMB(SimpleValue):
214#     def __init__(self, value):
215#         #super(OMByteArray,self).__init__(value)
216#         self.value=value
217#     def __str__(self):
218#         return "OMByteArray(" + repr(self.value) + ")"
219#     def parse(self, value):
220#         return value
221#     XMLtag = "OMB"
222#     def getBody(self):
223#         return base64.encodestring(self.value)
224class OMRef(object):
225    def __init__(self, ref):
226        self.ref=ref
227    def evaluate(self, context):
228        return context.evaluate(self.ref)
229    def XMLEncode(self, context):
230        "FIXME: maybe it should also be able to encode as reference"
231        return context.XMLEncodeObject(self.ref)
232
233class OMATTR(object):
234    def __init__(self, *args):
235        #super(OMAttribution,self).__init__()
236        self.attr = list(args[:-1])
237        self.value = args[-1]
238    def getChildren(self):
239        #print type(self.attr)
240        #print type(self.value)
241        return self.attr+[self.value]
242    def evaluate(self, context):
243        value = copy(self.value)
244        value.attributes = copy(value.attributes)
245        for attribute in self.attr:
246            attribute_evaluated=context.evaluate(attribute)
247            value.attributes[attribute_evaluated.key] = attribute_evaluated.value
248        return value
249    XMLtag = "OMATTR"
250if __name__ == '__main__':
251    print OMV("x")
252    print OMA(OMV("x"),[OMV("y"),1])
253 
254
255    #from binding import OMBinding, lambdasym
256
257   
258    context["x"] = 1
259
260    x = OMV("x")
261
262    y = OMV("y")
263
264    print context.evaluate(x)
265    print context.evaluateVariable(x)
266    print context.evaluate(y)
267    import cd.arith1 as arith1
268    context.addCDImplementation(arith1.implementation)
269    print OMA(arith1.implementation.plus, [1,2])
270    print context.evaluate(OMA(arith1.implementation.plus, [1,2]))
271    application = OMA(OMS("plus", arith1.content), [1,2])
272   
273    print context.evaluate(application)
274    firstArg=OMBinding(lambdasym,[OMVar("x"), OMVar("y")], OMVar("x"))
275    #print context.evaluate(firstArg)
276    application = OMApply(firstArg, [x,y])
277    print context.evaluate(application)
278    application = OMApply(firstArg, [y,x])
279    print context.evaluate(application)
280   
281    #print type(context.lookupImplementation(arith1.plussym))
282    #application=OMApply(arith1.plussym,[x])
283    #application=OMApply(arith1.plussym,[x,x])
284    application = OMApply(OMS("plus", arith1.content), [x, x])
285   
286    print context.evaluate(application)
287    application = OMApply(OMS("plus", arith1.content), [x, x, x])
288   
289    print context.evaluate(application)
290    i =  OMint(22482489)
291    print i.body
292    print i.XMLEncode(context)
293    print context.XMLEncodeObject(OMS("plus", arith1.content))
294    #i.body="dshj"
295   
296#optimize(OMObjectBase.__init__)
297#optimize(OMObjectBase.XMLPreEncode)
298#optimize(SimpleValue.__init__)
299#optimize(OMint.__init__)
300#optimize(OMApply.__init__)
Note: See TracBrowser for help on using the repository browser.