1 import string
2 from Tkinter import *
3 import tkMessageBox
4 import Pmw
5 from teamwork.math.Keys import ActionKey
6 from teamwork.widgets.TreeEditor import TreeEditor
7 from teamwork.math.KeyedVector import *
8 from teamwork.math.KeyedMatrix import *
9 from teamwork.math.KeyedTree import KeyedPlane
10 from teamwork.math.probability import Distribution
11 from MatrixEditor import MatrixEditor
12
15 optiondefs = (
16
17 ('society', {}, Pmw.INITOPT),
18 )
19 self.defineoptions(kw, optiondefs)
20 TreeEditor.__init__(self,parent)
21
22 stateKeys = {}
23 roleKeys = {}
24 classKeys = {}
25 relationKeys = {}
26 actionKeys = {}
27 if self['society']:
28 featureDict = {}
29 for entity in self['society'].members():
30 for feature in entity.getStateFeatures():
31 featureDict[feature] = True
32 for option in entity.actions.getOptions():
33 for action in option:
34 key = ActionKey({'type': action['type'],'object': None,
35 'entity': entity.name})
36 actionKeys[key] = True
37 key = ActionKey({'type': action['type'],'object': None,
38 'entity': None})
39 actionKeys[key] = True
40
41 roles = {'actor': True,'object': True,'self': True}
42
43 for entity in self['society'].members():
44 for relation in entity.relationships.keys():
45 for role in roles:
46 key = RelationshipKey({'feature':relation,
47 'relatee':role})
48 relationKeys[key.simpleText()] = key
49
50 for entity in self['society'].members():
51 roles.update(entity.relationships)
52
53 for role in roles.keys():
54 for feature in featureDict.keys():
55 key = StateKey({'entity':role,'feature':feature})
56 stateKeys[key.simpleText()] = key
57 key = IdentityKey({'entity':role,'relationship':'equals'})
58 roleKeys[key.simpleText()] = key
59
60 for role in roles.keys():
61 for entity in self['society'].keys():
62 key = ClassKey({'entity':role,
63 'value':entity})
64 classKeys[key.simpleText()] = key
65 self.createcomponent('menus',(),None,MatrixEditor,
66 (self.pane('editorPane'),),
67 states=stateKeys,
68 roles=roleKeys,
69 classes=classKeys,
70 relations=relationKeys,
71 actions=actionKeys,
72 ).pack(side='top',fill='both')
73
75 if isinstance(value,KeyedMatrix):
76 vector = value.values()[0]
77 if isinstance(vector,DeltaRow):
78 name = vector.simpleText()
79 else:
80 name = ''
81 rowKey = value.keys()[0]
82 elements = []
83 for colKey,value in vector.items():
84 if colKey == rowKey:
85 value -= 1.
86 if abs(value) > 0.:
87 if isinstance(colKey,ConstantKey):
88 elements.append('%5.3f' % (value))
89 else:
90 elements.append('%d%% of %s' % (value*100.,
91 colKey.simpleText()))
92 name = 'increment by %s' % (string.join(elements,' and '))
93 elif isinstance(value,str):
94 name = value
95 elif value is None or isinstance(value,bool):
96 name = str(value)
97 else:
98 tkMessageBox.showwarning('Warning','Unable to display leaf nodes of type %s' % (value.__class__.__name__))
99 name = ''
100 return name
101
103 if isinstance(planes,list):
104
105 planeStr = string.join(map(lambda p:p.simpleText(numbers=self['expert']),planes),' and ')
106 return 'if %s' % (planeStr)
107 elif len(planes) == 1:
108
109 return 'with 100% probability'
110 elif len(planes) == 2:
111
112 return 'with %d%% probability' % (planes['then']*100.)
113 else:
114
115 raise UserWarning,'Unable to display distributions with more than 2 branches'
116
156
159
161 self.component('menus').setBranch(rowType)
162
164 if not self['society']:
165 self.component('box_apply').configure(state='disabled')
166 self.component('box_add').configure(state='disabled')
167 self.component('box_delete').configure(state='disabled')
168 return
169
170 self.component('menus_type').configure(selectioncommand=self.setLeaf)
171 self.component('menus').displayDynamics(self.selectedTree().getValue())
172
174 if not self['society']:
175 self.component('box_apply').configure(state='disabled')
176 self.component('box_add').configure(state='disabled')
177 self.component('box_delete').configure(state='disabled')
178 return
179
180 self.component('menus_type').configure(selectioncommand=self.setBranch)
181 tree = self.selectedTree()
182 if isinstance(tree.split,list):
183 if len(tree.split) > 1:
184 raise NotImplementedError,'Currently unable to display multiple hyperplanes'
185 else:
186 self.component('menus').displayBranch(tree.split[0])
187 else:
188
189 self.component('menus').displayBranch(tree.split)
190
192 tree = self.selectedTree()
193 parent = self.selection()
194 if tree.isLeaf():
195
196 trueTree = tree.__class__()
197 trueTree.makeLeaf(copy.deepcopy(tree.getValue()))
198 falseTree = tree.__class__()
199 falseTree.makeLeaf(copy.deepcopy(tree.getValue()))
200 else:
201
202 for child in parent['children'][:]:
203 child.delete()
204 del self.nodes[id(child)]
205
206 trueTree = copy.deepcopy(tree)
207 falseTree = copy.deepcopy(tree)
208 row = TrueRow()
209 plane = KeyedPlane(row,-.1)
210
211
212 tree.branch(plane,trueTree=trueTree,falseTree=falseTree,
213 pruneF=False,pruneT=False)
214
215 self.component('tree').inhibitDraw = True
216 name = self.displayPlane(tree.split)
217 if tree.parent:
218 if tree.parent[1]:
219 name = 'then %s' % (name)
220 else:
221 name = 'else %s' % (name)
222
223 parent['label'] = name
224 parent['isLeaf'] = False
225 subnode = parent.addChild(self.component('tree'),isLeaf=True)
226 subnode['action'] = self.select
227 self.setTree(trueTree,subnode,'then ')
228 subnode = parent.addChild(self.component('tree'),isLeaf=True)
229 subnode['action'] = self.select
230 self.setTree(falseTree,subnode,'else ')
231 self.nodes[id(parent)] = tree
232 self.component('tree').inhibitDraw = False
233
234 parent.refresh(self.component('tree'))
235 self.select()
236 self.component('tree').find_full_id(parent.full_id()).expand()
237
242
244 childTree = self.selectedTree()
245 if childTree.parent:
246 parentTree,side = childTree.parent
247 else:
248 tkMessageBox.showerror('Delete Error',
249 'You cannot delete the entire tree!')
250 return
251 childNode = self.selection()
252
253 parentNode = childNode['parent']
254 if isinstance(parentTree.split,list):
255
256
257
258 del self.nodes[id(parentNode)]
259 del self.nodes[id(childNode)]
260
261 fTree,tTree = parentTree.getValue()
262 if parentTree.parent is None:
263 prefix = ''
264 elif parentTree.parent[1]:
265 prefix = 'then '
266 else:
267 prefix = 'else '
268 if side:
269
270 if fTree.isLeaf():
271 parentTree.makeLeaf(fTree.getValue())
272 elif fTree.isProbabilistic():
273 tkMessageBox.showerror('Not implemented','Unable to delete children from probabilistic branches.')
274 else:
275 plane = fTree.split
276 fTree,tTree = fTree.getValue()
277 parentTree.branch(plane,fTree,tTree)
278
279 name = parentNode['children'][1]['label']
280 parentNode['label'] = prefix+name[5:]
281 parentNode['children'][0].delete()
282 parentNode['isLeaf'] = True
283
284
285 else:
286
287 if tTree.isLeaf():
288 parentTree.makeLeaf(tTree.getValue())
289 elif tTree.isProbabilistic():
290 tkMessageBox.showerror('Not implemented','Unable to delete children from probabilistic branches.')
291 else:
292 plane = tTree.split
293 fTree,tTree = tTree.getValue()
294 parentTree.branch(plane,fTree,tTree)
295
296 name = parentNode['children'][0]['label']
297 parentNode['label'] = prefix+name[5:]
298 parentNode['children'][1].delete()
299 parentNode['isLeaf'] = True
300
301
302
303
304 children = parentNode['children'][0]['children'][:]
305
306 parentNode['children'][0].delete(recursive=False)
307
308 for child in children:
309
310 parentNode['children'].append(child)
311 child['parent'] = parentNode
312 parentNode['isLeaf'] = False
313
314 self.nodes[id(parentNode)] = parentTree
315 parentNode.selected = True
316 parentNode.refresh()
317 else:
318 tkMessageBox.showerror('Not implemented','Unable to delete children from probabilistic branches.')
319 return
320
321 if self.selectedTree().isLeaf():
322 self.selectLeaf()
323 else:
324 self.selectBranch()
325