*** empty log message ***
[pli.git] / pli / logictypes.py
blob25deabf1c8a2910ab465076921e414784f0e0281
1 #=======================================================================
3 __version__ = '''0.1.07'''
4 __sub_version__ = '''20041116002755'''
5 __copyright__ = '''(c) Alex A. Naanou 2003'''
7 __doc__ = '''\
8 this module defines a number of utilities and objects to assist advanced
9 usage of standard python types.
10 '''
12 #-----------------------------------------------------------------------
14 import pli.pattern.mixin.mapping as mapping
17 #-----------------------------------------------------------------------
18 # TODO create a logic proxy, with adapters....
19 # UNION(*p), INTERSECTION(*n), ...
21 #------------------------------------------------------------_Compare---
22 class _Compare(object):
23 '''
24 '''
25 def __init__(self, eq):
26 self._eq = eq
27 def __cmp__(self, other):
28 return self._eq
29 def __eq__(self, other):
30 return self._eq == 0
31 def __ne__(self, other):
32 return self._eq != 0
33 def __gt__(self, other):
34 return self._eq > 0
35 def __ge__(self, other):
36 return self._eq >= 0
37 def __lt__(self, other):
38 return self._eq < 0
39 def __le__(self, other):
40 return self._eq <= 0
42 #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
43 # this will compare to any value as equel (almost oposite to None)
44 Any = ANY = _Compare(0)
46 #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47 # this is bigger than any value...
48 MAXIMUM = _Compare(1)
50 #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
51 # this is smaller than any value...
52 MINIMUM = _Compare(-1)
56 #-----------------------------------------------------------------------
57 # this is to define basic pattern combination mathematics.
58 # Ex:
59 # Pab = Pa | Pb -- Pab is a pattern that will match either Pa
60 # or Pb...
62 # Operations:
63 # |
64 # &
65 # +
66 # rep
67 # not
70 class Pattern(object):
71 '''
72 '''
73 # cmp
74 def __eq__(self, other):
75 '''
76 '''
77 pass
78 def __ne__(self, other):
79 '''
80 '''
81 pass
82 def __gt__(self, other):
83 '''
84 '''
85 pass
86 def __ge__(self, other):
87 '''
88 '''
89 pass
90 def __lt__(self, other):
91 '''
92 '''
93 pass
94 def __le__(self, other):
95 '''
96 '''
97 pass
98 # op
99 ##!!!
102 #--------------------------------------------------------------oftype---
103 class oftype(Pattern):
105 this will create an object that can be used as a predicate to test type,
106 and it will copare True to objects of that type.
108 def __init__(self, *types, **n):
111 self._types = types
112 if 'doc' in n:
113 self.__doc__ = n['doc']
114 def __call__(self, other):
116 test if the the other object object is of type.
118 return isinstance(other, self._types) is True
119 __eq__ = __call__
120 def __ne__(self, other):
121 return not isinstance(other, self._types) is True
122 def __gt__(self, other):
123 return False
124 def __ge__(self, other):
125 return True
126 def __lt__(self, other):
127 return False
128 def __le__(self, other):
129 return True
131 #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
132 # simple type predicates...
133 isint = oftype(int)
134 isfloat = oftype(float)
135 iscomplex = oftype(complex)
137 isstr = oftype(str)
138 isunicode = oftype(unicode)
140 islist = oftype(list)
141 istuple = oftype(tuple)
142 isdict = oftype(dict)
144 #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
145 # general type groups predicates...
146 isnumber = oftype(int, float, complex)
147 isstring = oftype(str, unicode)
148 issequence = oftype(list, tuple)
150 isiterabletype = oftype(str, unicode, list, tuple, dict)
154 #-----------------------------------------------------------------------
155 #-------------------------------------------------------dictcopyunite---
156 def dictcopyunite(*members):
159 res = {}
160 for m in members:
161 res.update(m)
162 return res
165 #-----------------------------------------------------------DictUnion---
166 ##class DictUnion(mapping.MappingWithMethods):
167 class DictUnion(mapping.Mapping):
169 this is a dict like object, that acts as a union of its members but
170 without modifieng its members in any way.
172 this is similar to a sequential update of all members, but retains
173 the container information for each item, and does not have the
174 overhead of creating a new resulting dict.
176 NOTE: because of the nature of dicts, the later added members (unite)
177 have higher priority than the former.
178 NOTE: the members added in one call (be it __init__, unite or tailunite)
179 have descending priority -- first highest last lowest.
180 NOTE: due to ints nature this object is *live*, e.g. it emidiatly
181 reflects all modifications to its members as they are modified.
183 _members = ()
185 def __init__(self, *members):
188 members = list(members)
189 members.reverse()
190 self._members = tuple(members)
191 def __getitem__(self, name):
194 for m in self._members:
195 if name in m:
196 return m[name]
197 raise KeyError, 'key "%s" is not present in any of the members.' % name
198 def __setitem__(self, name, value):
201 # find source...
202 # set
203 raise TypeError, 'can\'t add values to a dict union object.'
204 def __delitem__(self, name):
207 raise TypeError, 'can\'t delete values from a dict union object.'
208 def __contains__(self, name):
211 for m in self._members:
212 if name in m:
213 return True
214 return False
215 def __iter__(self):
218 seen = []
219 for m in self._members:
220 for n in m:
221 if n not in seen:
222 seen += [n]
223 yield n
224 # the dict union specific interface...
225 ##!!! revise...
226 def unite(self, *others):
228 add members to the union object.
230 NOTE: this method will add members to the top of the pririty
231 stack.
233 others = list(others)
234 others.reverse()
235 self._members = tuple(others) + self._members
236 ##!!! revise...
237 def tailunite(self, *others):
239 this is the same as unite but adds low priority members (to the
240 botom of the priority stack).
242 others = list(others)
243 others.reverse()
244 self._members = self._members + tuple(others)
245 def memberindex(self, obj):
248 return list(self._members).index(obj)
249 def removemember(self, obj):
252 if obj in self._members:
253 self._members = tuple(list(self._members).remove(obj))
254 return
255 raise TypeError, '%s does not contain %s as a member.' % (self, obj)
256 def members(self):
259 return self._members
260 ##!!! revise...
261 def popmember(self, index=0):
264 NOTE: this by default will remove the highest priority member.
266 m = list(self._members)
267 res = m.pop(index)
268 self._members = tuple(m)
269 return res
270 def itermembers(self):
273 for m in self._members:
274 yield m
275 def getcontainerof(self, name):
278 for m in self._members:
279 if name in m:
280 return m
281 raise KeyError, '%s does not contain "%s"' % (self, name)
282 def getallcontainersof(self, name):
285 res = []
286 for m in self._members:
287 if name in m:
288 res += [m]
289 if res == []:
290 raise KeyError, '%s does not contain "%s"' % (self, name)
291 return res
292 def todict(self):
294 this will return a dict copy of the DictUnion object.
296 return dict(self.items())
299 #-------------------------------------------------------DictTypeUnion---
300 # WARNING: this is not done!
301 class DictTypeUnion(DictUnion, dict):
303 this is a diriviation from dict that can contain oun data.
305 ##!!!
306 pass
309 #-----------------------------------------------------------ListUnion---
310 ##def ListUnion(list):
311 ## '''
312 ## '''
313 ## pass
316 #-------------------------------------------------------DictIntersect---
317 ##class DictIntersect(object):
318 ## '''
319 ## '''
320 ## pass
324 #=======================================================================
325 # vim:set ts=4 sw=4 nowrap :