1 """Collection of inter-related L{teamwork.agent.Generic.GenericModel} instances
2 @author: David V. Pynadath <pynadath@isi.edu>
3 """
4 from xml.dom.minidom import *
5
6 from teamwork.agent.Generic import GenericModel
7 from teamwork.agent.Entities import *
8 from teamwork.multiagent.Multiagent import *
9
11 """A taxonomy of generic agent models
12
13 In essence, a generic society is simply a dictionary of L{GenericModel}
14 objects. You can manipulate the society through the following operations:
15
16 0. Creating a new society:
17 - C{society = L{GenericSociety}()}
18
19 1. Insert/overwrite a generic model:
20 - C{society.L{addMember}(model)}
21
22 2. Get a generic model by name
23 - C{model = society[name]}
24
25 3. Get a list of model objects:
26 - C{society.L{members}()}
27
28 4. Get a list of names of leaf nodes
29 - C{society.L{leaves}()}
30
31 5. Get a list of leaf node model objects
32 - C{society.L{leafModels}()}
33
34 6. Delete a generic model
35 - C{del society[model.name]}
36
37 7. Get a list of model names:
38 - C{society.keys()}
39
40 8. Get a list of (name,model) tuples
41 - C{society.items()}
42
43 9. Create an instantiated agent model of a particular class
44 - C{entity = society.L{instantiate}(className,instanceName)}
45
46 @ivar network: a dictionary representation of the descendent relationships in this society
47 @ivar root: a list of all of the root models in this society
48 """
57
86
88 """
89 @param old: the current name of the member
90 @param new: the new name of the member
91 @type old,new: str
92 """
93 try:
94
95 turn = self._keys.index(old)
96 agent = self[old]
97 index = self._keys.index(old)
98 self._keys.insert(index,new)
99 except ValueError:
100
101 for names in self._keys:
102 try:
103 names.remove(old)
104 names.append(new)
105 break
106 except ValueError:
107 pass
108 self[new] = agent
109 for agent in self.members():
110 agent.renameEntity(old,new)
111
112 self.network[new] = self.network[old]
113 for names in self.network.values():
114 if old in names:
115 names.append(new)
116 if old in self.root:
117 self.root.append(new)
118 del self[old]
119
120 - def merge(self,society):
121 """Merges the contents of a new society into this one
122 """
123 warnings = []
124 leftover = []
125 for name,entity in society.items():
126 if self.has_key(name):
127 warnings += self[name].merge(entity)
128 else:
129 self.addMember(entity)
130 for name,entity in society.items():
131 if len(entity.getParents()) == 0:
132 self.root.append(entity.name)
133 self.root.sort()
134 for parent in entity.getParents():
135 if not name in self.network[parent]:
136 self.network[parent].append(name)
137 self.network[parent].sort()
138 return warnings
139
141 """
142 @return: the names of the given entity and all of its descendents in the hierarchy
143 @rtype: str[]
144 """
145 result = {}
146 remaining = [name]
147 while len(remaining) > 0:
148 current = remaining.pop(0)
149 result[current] = True
150 remaining += self.network[current]
151 return result.keys()
152
154 MultiagentSystem.__delitem__(self,name)
155 for agent in self.members():
156 try:
157 agent.parentModels.remove(name)
158 except ValueError:
159
160 pass
161 try:
162
163 self._keys.remove(name)
164 except ValueError:
165
166 for names in self._keys:
167 try:
168 names.remove(name)
169 break
170 except ValueError:
171 pass
172 del self.network[name]
173 try:
174 self.root.remove(name)
175 except ValueError:
176 pass
177 for names in self.network.values():
178 try:
179 names.remove(name)
180 except ValueError:
181 pass
182
184 doc = MultiagentSystem.__xml__(self)
185 node = doc.createElement('order')
186 if self._keys and isinstance(self._keys[0],list):
187 node.setAttribute('serial','0')
188 else:
189 node.setAttribute('serial','1')
190 for index in range(len(self._keys)):
191 if isinstance(self._keys[index],str):
192 names = [self._keys[index]]
193 else:
194 names = self._keys[index]
195 for name in names:
196 child = doc.createElement('turn')
197 child.setAttribute('name',name)
198 child.setAttribute('position',str(index))
199 node.appendChild(child)
200 doc.documentElement.appendChild(node)
201 return doc
202
203 - def parse(self,element):
239
241 """Updates society from dictionary-style hierarchy
242 @param hierarchy: the specification of the generic society
243 @type hierarchy: C{dict}
244 @param modelClass: the class for the individual generic agent models (default is L{GenericModel}
245 @type modelClass: C{class}
246 """
247 if not modelClass:
248 modelClass = GenericModel
249
250 for name,generic in hierarchy.items():
251 if not name:
252
253 continue
254 model = modelClass(name)
255 self.addMember(model)
256 model.importDict(generic)
257
258 for name,generic in self.items():
259 self.__copyGeneric(generic)
260
262 """Copies top-level generic values onto nested belief models"""
263 for other in generic.getEntities():
264 entity = generic.getEntity(other)
265 if self.has_key(other):
266
267 toExplore = [other]
268 while len(toExplore) > 0:
269 cls = toExplore.pop()
270 if len(self[cls].models) > 0:
271 entity.models = self[cls].models
272 break
273 toExplore += self[cls].getParents()
274 entity.dynamics = self[other].dynamics
275
276
277 self.__copyGeneric(entity)
278
289
291 """Returns a list of generic model objects that are leaf nodes"""
292 return map(lambda name,s=self:s[name], self.leaves())
293
294 - def instantiate(self,className,instanceName,objClass=None):
295 """Returns a new instantiated agent model
296 @param className: name of the relevant generic model
297 @type className: C{str}
298 @param instanceName: name for the new instance
299 @type instanceName: C{str}
300 objClass: class to create agent object from (defaults to L{PsychEntity})
301 """
302 if not objClass:
303 objClass = PsychEntity
304 if not self.has_key(className):
305 raise UserWarning,'Unknown class: %s' % (className)
306 entity = objClass(instanceName)
307 entity.applyDefaults(className,self)
308 entity.society = self
309 return entity
310
311 if __name__ == '__main__':
312 import sys
313 import bz2
314 from xml.dom.minidom import parseString
315
316 f = bz2.BZ2File(sys.argv[1],'r')
317 data = f.read()
318 f.close()
319
320 try:
321 key = sys.argv[2].lower()
322 except IndexError:
323 key = ''
324
325 doc = parseString(data)
326 newClasses = GenericSociety()
327 newClasses.parse(doc.documentElement)
328
329 names = newClasses.keys()
330 names.sort(lambda x,y:cmp(x.lower(),y.lower()))
331
332 for name in names:
333 entity = newClasses[name]
334 if key[:5] == 'state':
335 for feature in entity.getStateFeatures():
336 print '%s,%s,%5.3f' % (name,feature,entity.getState(feature))
337 elif key[:6] == 'action':
338 for action in entity.actions.getOptions():
339 if action[0]['object']:
340 print '%s,%s,%s' % (name,action[0]['type'],
341 action[0]['object'])
342 else:
343 print '%s,%s,' % (name,action[0]['type'])
344 elif key[:8] == 'relation':
345 for relation in entity.getLinkTypes():
346 for other in entity.getLinkees(relation):
347 print '%s,%s,%s,%5.3f' % (name,relation,other,
348 entity.getLink(relation,other))
349 elif key[:6] == 'leaves':
350 if name in newClasses.leaves():
351 print name
352 elif key[:6] == 'static':
353 for relation,fillers in entity.relationships.items():
354 for other in fillers:
355 print '%s,%s,%s' % (name,relation,other)
356 elif key[:5] == 'neigh':
357 if 'Neighborhood' in entity.getParents():
358 print name
359 else:
360 print name
361