Package teamwork :: Package examples :: Package Thespian :: Module ThespianShell
[hide private]
[frames] | no frames]

Source Code for Module teamwork.examples.Thespian.ThespianShell

   1  ## branching tree doesn't work
 
   2  ## specified .8, .6
 
   3  ## resulted in .36 .64
 
   4  ## dyn with branch couldn't be fitted, assert domain() ==1
 
   5  
 
   6  import string 
   7  import sys 
   8  import random 
   9  
 
  10  
 
  11  from teamwork.shell.PsychShell import * 
  12  from teamwork.utils.PsychUtils import * 
  13  
 
  14  from teamwork.math.Keys import * 
  15  from teamwork.math.probability import * 
  16  
 
  17  from ThespianAgent import * 
  18  from ThespianAgents import * 
  19  from ThespianUtils import * 
  20  from appraisalDimentions import * 
  21  
 
  22  ## use CVXOPT
 
  23  from cvxopt.base import matrix 
  24  from cvxopt.blas import dot  
  25  from cvxopt.solvers import qp 
  26  
 
  27  from teamwork.math.probability import Distribution 
  28  from teamwork.math.Keys import StateKey,ConstantKey 
  29      
 
  30  useAppraisalModule = False 
  31  
 
  32  ##partial order of actions
 
  33  orders = [] 
  34  ## action should happen only after 10 steps
 
  35  laterThan = {} 
  36  ## at step 20, action should already happened
 
  37  earlierThan = {} 
  38  
 
  39  orders = [['wolf-eat-granny','anybody-kill-wolf'],
 
  40              ['red-give-cake-granny','wolf-eat-red'],
 
  41              ['red-give-cake-granny','wolf-eat-granny'],
 
  42              ] 
  43  
 
  44  earlierThan = {50:['wolf-eat-red'],80:['wolf-eat-granny']} 
  45  earlierThan2 = [('wolf-eat-granny',30,['anybody-kill-wolf'])] 
  46  NOearlierThan = {60:['wolf-eat-red']} 
  47  laterThan2 = [('wolf-eat-red',10,'wolf-eat-granny')] 
  48  
 
  49  
 
50 -def progress(msg,pct):
51 if pct > 0.: 52 print 'done.' 53 elif len(msg) > 0: 54 print msg,'...'
55 56
57 -class ThespianShell(PsychShell):
58 """Shell subclass enhanced for stories.""" 59 60 agentClass = ThespianAgent ##this is the module 61 multiagentClass = ThespianAgents 62 63 64 entityList={\ 65 ## '3':[('granny','granny'),('hunter','hunter'),('wolf','wolf'),('red','red'),('Entity','fairy')], 66 '3':[('granny','granny'),('hunter','hunter'),('wolf','wolf'),('red','red'),('woodcutter','woodcutter')], 67 ## '3':[('wolf','wolf'),('hunter','hunter')], 68 ## '3':[('wolf','wolf'),('red','red'),('granny','granny')], 69 #'3':[('hunter','hunter'),('wolf','wolf'),('red','red')], 70 '31':[('red','red'),('wolf','wolf')], 71 '4':[('usr','usr'),('cha','cha')], 72 '6':[('usr','usr'),('labrat','labrat1'),('labrat','labrat2'),('streetrat','streetrat'),('otherTeam','otherTeam'),('timer','timer')], 73 ## '6':[('usr','usr'),('labrat','labrat1'),('labrat','labrat2'),('streetrat','streetrat'),], 74 # '6':[('usr','usr'),('labrat','labrat1')], 75 '7':[('usr','usr'),('vc','vc')], 76 } 77 78 # Uncomment the following to support the undo command 79 ## __UNDO__ = 1 80
81 - def __init__(self,entities=None,classes=None,scene='3',debug=10):
82 83 self.scene = scene 84 85 self.loadClasses() 86 PsychShell.__init__(self,None,self.classes,self.agentClass,self.multiagentClass,debug=0) 87 scenario = self.setupEntities(self.createEntities(),None, 88 compileDynamics=True,compilePolicies=None) 89 self.setupScenario(scenario) 90 91 #test func for director agent 92 self.handlers['director'] = self.director 93 self.handlers['path'] = self.printPath 94 self.handlers['locations'] = self.printLocation 95 self.handlers['log'] = self.printLogFileName 96 97 98 self.helpWolf = 0 99 self.wolfMetGranny = False 100 101 self.AP = appraisal() 102 if useAppraisalModule: 103 self.AP.initEntities = copy.deepcopy(self.entities) 104 self.AP.setupEntities(self.AP.initEntities) 105 self.AP.curEntities = copy.deepcopy(self.entities) 106 self.AP.setupEntities(self.AP.curEntities ) 107 108 self.copyEntities = copy.deepcopy(self.entities) 109 110 # for entityName in self.copyEntities: 111 # self.AP.setupDynamics(entities=self.copyEntities,entity=entityName,copyEntities=self.entities) 112 113 self.history = [] 114 115 self.logfile = None 116 self.logfileName = None 117 118 while self.logfile == None: 119 self.logfileName = 'log'+str(int(100*random.random()))+'.txt' 120 try: 121 open(self.logfileName,'r') 122 except: 123 print self.logfileName 124 self.logfile = open(self.logfileName,'w')
125 126 127 128 129 # mei 06/30/04 change the param to indicate which scene we working on
130 - def createEntities(self):
131 entities=[] 132 for newEntity in self.entityList[self.scene]: 133 entity = self.classes.instantiate(newEntity[0],newEntity[1],ThespianAgent) 134 135 if entity: 136 entities.append(entity) 137 138 ## turned off temperately because: 139 ## couldn't use lookup 140 ## will create too manys state features for obligation keys 141 ## createObligations(entities,1, 0) 142 ## ObligationDyns(entities) 143 ## SatisfyObliPolicies(entities) 144 return entities
145
146 - def executeCommand(self,cmd):
147 start = time.time() 148 result = self.execute(cmd) 149 diff = time.time()-start 150 if result: 151 self.displayResult(cmd,`self.debug`) 152 self.debug.reset() 153 self.displayResult(cmd,result) 154 self.displayResult(cmd,'Time: %7.4f' % (diff)) 155 else: 156 self.done = 1
157 158
159 - def displayResult(self,cmd,result):
160 """Terminal version of the output display method. Uses 161 standard output.""" 162 print result 163 ## print 164 sys.stdout.flush()
165 166
167 - def printPath(self,result=[]):
168 for act in self.history: 169 #if not isinstance(act,Message): 170 # continue 171 print `act`
172 173
174 - def printLocation(self,result=[]):
175 print 'locations of characters' 176 for entity in self.entities: 177 tmp = self.entities.__getitem__(entity).getState('location').expectation() 178 print entity,tmp,' ',
179
180 - def printLogFileName(self,result=[]):
181 print self.logfileName
182
183 - def runAppraisal(self, action,lookahead = 1):
184 if useAppraisalModule == False: 185 return 186 try: 187 self.AP.lookaheadTest() 188 except: 189 lookahead = 0 190 ## calculate appraisal dimentions 191 for entity in self.entities: 192 print entity 193 for i in range(lookahead+1): 194 print 'lookahead level ',i 195 print ' novelty: ',self.AP.novelty(entity,action,i) 196 preUtility, curUtility = self.AP.calUtilities(entity,action,i) 197 relevance = self.AP.Relevance(entity,preUtility, curUtility,i) 198 desirability = self.AP.Desirability(entity,preUtility, curUtility,i) 199 print ' Relevance:',relevance, ' Desirability:',desirability 200 print ' causalAttribution ' 201 202 if relevance > 0: 203 agents,attr = self.AP.causalAttribution(entity,action,lookahead=i) 204 for i in range(len(agents)): 205 print ' ',agents[i],attr[i] 206 207 if relevance > .2 and desirability < 0: 208 print ' self agency', self.AP.Agency(entity,entity, action,i) 209 for other in self.entities: 210 if not other == entity: 211 print ' other agency ', other,' ',self.AP.Agency(entity,other, action,i) 212 print 213 214 self.AP.updateHistory(action) 215 print 216 print
217 218
219 - def genObjectives(self, history):
220 lastAct = history[len(history)-1] 221 objectives = [] 222 for order in orders: 223 check_order_result = self.checkOrder(history,order) 224 if check_order_result == -1: 225 tmp = order[1] 226 tmp = tmp.replace('anybody','') 227 tmpAct = `lastAct` 228 if tmpAct.find(tmp)>-1: 229 print 'violate order ',order 230 # we want the first action to happen 231 actor,type,obj = stringToAct(order[0]) 232 objectives.append((actor,type,'Maximize',obj)) 233 # we want the second action to not happen 234 actor,type,obj = stringToAct(order[1]) 235 objectives.append((actor,type,'Minimize',obj)) 236 237 tmpact = `lastAct` 238 for key in laterThan: 239 tmp = key 240 if tmp.find('anybody')>-1: 241 tmp = key.replace('anybody','') 242 if tmpact.find(tmp)>-1: 243 if laterThan[`lastAct`] > len(history): 244 print `lastAct`, ' should happen after ',laterThan[`lastAct`],' steps' 245 objectives.append((lastAct['actor'],lastAct['type'],'Minimize',lastAct['object'])) 246 247 248 for key in earlierThan: 249 if len(history) >= key: 250 for act in earlierThan[key]: 251 if self.searchPath(history,act) == -1: 252 #if the only constaints are certain actions need to happen in the future, i will let it be? 253 actor,type,obj = stringToAct(act) 254 print act, ' should happen before ',key,' steps' 255 objectives.append((actor,type,'Maximize',obj)) 256 return objectives
257
258 - def getLastAct(self,history,changeEntity):
259 for act in self.history: 260 if isinstance(act,Message): 261 continue 262 if act['actor'] == changeEntity: 263 return act
264 265 266 #def director2(self, result=[]): 267 # receivers = ['woodcutter','hunter','wolf','red','granny'] 268 # for i in range(4): 269 # next = self.entities.next() 270 # delta = self.entities.microstep(next,hypothetical=True,explain=False) 271 # for key in delta['decision'].keys(): 272 # res = delta['decision'][key][0] 273 # #print res 274 # tmp = copy.copy(self.history) 275 # tmp.append(res) 276 # objectives = self.genObjectives(tmp) 277 # if len(objectives)>0: 278 # options = self.entities.__getitem__(next[0]['name']).actions.getOptions() 279 # options = self.entities.__getitem__(next[0]['name']).updateActionChoices(options,includeLocation = True) 280 # bestAct = options[0] 281 # minObj = 100 282 # for option in options: 283 # tmp = copy.copy(self.history) 284 # tmp.append(option[0]) 285 # obj = self.genObjectives(tmp) 286 # if obj < minObj: 287 # minObj = obj 288 # bestAct = option 289 # next[0]['choices']=[bestAct] 290 # 291 # if minObj>0: 292 # newMsg = self.change_characters_state(next[0]['name'],delta['decision'],objectives) 293 # messages = [] 294 # for msg in newMsg: 295 # if not msg in messages: 296 # messages.append(msg) 297 # 298 # factor = {} 299 # factor['topic'] = 'state' 300 # factor['relation'] = '=' 301 # for msg in messages: 302 # if msg[1] in ['being-enquired']: 303 # factor['lhs'] = ['entities', msg[0], 'state', msg[1]] 304 # factor['value'] = msg[2] 305 # self.entities.__getitem__(msg[0]).setState(msg[1],factor['value']) 306 # msg = Message({'factors':[factor]}) 307 # print msg 308 # self.history.append(copy.deepcopy(msg)) 309 # self.entities.performMsg(msg,'granny',receivers,[],self.debug) 310 # else: 311 # res, act = self.make_story_false(msg[0],msg[1],msg[2],self.entities,self.history,next[0]['name']) 312 # if res: 313 # next[0]['choices']=[act] 314 # else: 315 # nextLocation = self.entities.__getitem__(next[0]['name']).getState('location').expectation() 316 # msgLocation = self.entities.__getitem__(msg[0]).getState('location').expectation() 317 # if not nextLocation == msgLocation: 318 # factor['lhs'] = ['entities', next[0]['name'], 'state', 'location'] 319 # factor['value'] = msgLocation 320 # msg1 = Message({'factors':[factor]}) 321 # self.entities.performMsg(msg1,'granny',receivers,[],self.debug) 322 # res, act = self.make_story_false(msg[0],msg[1],msg[2],self.entities,self.history,next[0]['name']) 323 # if res: 324 # next[0]['choices']=[act] 325 # print msg1 326 # self.logfile.write(str(msg1)) 327 # self.logfile.write('\n') 328 # self.history.append(copy.deepcopy(msg1)) 329 # self.entities.__getitem__(next[0]['name']).setState('location',factor['value']) 330 # else: 331 # factor['value'] = nextLocation 332 # msg1 = Message({'factors':[factor]}) 333 # self.entities.performMsg(msg1,'granny',receivers,[],self.debug) 334 # 335 # 336 # break 337 # 338 # delta = self.entities.microstep(next,hypothetical=False,explain=False) 339 # for key in delta['decision'].keys(): 340 # res = delta['decision'][key][0] 341 # self.history.append(res) 342 # print res 343 # self.logfile.write(str(res)) 344 # self.logfile.write('\n') 345 # 346 # 347 # 348 # 349 350
351 - def director2(self, result=[]):
352 lookaheadstep = 10 353 acturalLookaheadSteps = 4 354 totalTests = 9 355 356 receivers = ['woodcutter','hunter','wolf','red','granny'] 357 changeCharacter = 0 358 characters = ['red','woodcutter','granny','hunter','wolf'] 359 objectives = [] 360 satObjective = [] 361 decision = {} 362 363 # moveToCharacter: 0 relacate changeCharacter to the location of targetEntity before targetEntity act 364 # moveToCharacter: 1 relacate changeCharacter to the location of targetEntity before changeCharacter act 365 # set initial value to 0 because the first test will increase it to 1 while not perform any character realocation 366 moveToCharacter = 0 367 368 #best result among the test 369 bestPath=[] 370 minViolation = 100 371 372 for testNum in range(totalTests): 373 if changeCharacter == 0 and testNum >2: 374 break 375 print 376 print 'test',testNum 377 378 entities = copy.deepcopy(self.entities) 379 history = copy.deepcopy(self.history) 380 wolfMetGranny = self.wolfMetGranny 381 actions = [] 382 nochange = True 383 moveToCharacter = (moveToCharacter+1)%2 384 moveOnce = True 385 386 387 if len(objectives)>0: 388 messages = [] 389 testMessages = [] 390 391 for cha in characters: 392 newMsg = self.change_characters_state(cha,decision,objectives) 393 for msg in newMsg: 394 if not msg in messages: 395 messages.append(msg) 396 397 for msg in messages: 398 if not msg[1] in ['being-enquired']: 399 testMessages.append(msg) 400 continue 401 factor = {} 402 factor['topic'] = 'state' 403 factor['relation'] = '=' 404 factor['lhs'] = ['entities', msg[0], 'state', msg[1]] 405 factor['value'] = msg[2] 406 entities.__getitem__(msg[0]).setState(msg[1],factor['value']) 407 msg = Message({'factors':[factor]}) 408 print msg 409 actions.append(copy.deepcopy(msg)) 410 history.append(copy.deepcopy(msg)) 411 entities.performMsg(msg,'granny',receivers,[],self.debug) 412 msg = None 413 414 finishedMsg = [] 415 for i in range(lookaheadstep): 416 next = entities.next() 417 entity = next[0]['name'] 418 searchNextAction = False 419 420 for tmp in satObjective: 421 try: 422 objectives.remove(tmp) 423 except: 424 pass 425 satObjective = [] 426 427 if len(objectives)>0: 428 searchNextAction = True 429 # try fit characters' actions first 430 for objective in objectives: 431 tmpAct =objective[0]+'-'+objective[1]+'-'+objective[3] 432 if self.searchPath(history,tmpAct) > -1: 433 continue 434 if (not entity == 'wolf') and (entity == objective[0] or (objective[0] == 'anybody' and not entity == objective[3])): 435 actorLocation = entities.__getitem__(entity).getState('location').expectation() 436 objectLocation = entities.__getitem__(objective[3]).getState('location').expectation() 437 if not actorLocation == objectLocation: 438 continue 439 if objective[2] == 'Maximize': 440 actNext = Action({'actor':entity,'type':objective[1],'object':objective[3]}) 441 options = entities.__getitem__(entity).actions.getOptions() 442 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 443 if [actNext] in options: 444 searchNextAction = False 445 # don't need to fit since we don't care about character motivation 446 next[0]['choices'] = [[actNext]] 447 # take care of the 1st objective only 448 break 449 elif objective[2] == 'Minimize': 450 options = entities.__getitem__(entity).actions.getOptions() 451 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 452 453 for option in options: 454 if not option[0]['type'] == objective[1]: 455 searchNextAction = False 456 # don't need to fit since we don't care about character motivation 457 next[0]['choices'] = [option] 458 # take care of the 1st objective only 459 break 460 461 462 if searchNextAction: 463 #only move one chanracter once during each lookahead 464 reLocate = False 465 if moveOnce: 466 objectEntity = objectives[0][0] 467 # change the location of one character at a time 468 changeEntity = characters[changeCharacter] 469 470 # idnore characters whose locations can't be changed 471 if entities.__getitem__(changeEntity).getState('eaten').expectation() >.5: 472 changeCharacter = (changeCharacter+1)%len(characters) 473 changeEntity = characters[changeCharacter] 474 475 # anybody-kill-wolf -> hunter-kill-wolf ->move hunter's location 476 if objectEntity == 'anybody': 477 objectEntity = changeEntity 478 #the character is within the sight of wolf, i can't make it disppear 479 if entities.__getitem__(changeEntity).getState('location').expectation() == entities.__getitem__('wolf').getState('location').expectation(): 480 wolfLastAct = self.getLastAct(history,'wolf') 481 changeEntityLastAct = self.getLastAct(history,changeEntity) 482 # I can change their locations if the wolf just moved or the current chracter just moved 483 if not (`wolfLastAct`.find('move') >-1 or not `changeEntityLastAct`.find('move') >-1) : 484 changeCharacter = (changeCharacter+1)%len(characters) 485 changeEntity = characters[changeCharacter] 486 487 reLocate = True 488 if changeEntity == objectEntity: 489 if changeEntity == entity: 490 moveToCharacter = 1 491 changeCharacter = (changeCharacter+1)%len(characters) 492 else: 493 reLocate = False 494 elif moveToCharacter == 0: 495 if not objectEntity == entity: 496 reLocate = False 497 elif moveToCharacter == 1: 498 if not changeEntity == entity: 499 reLocate = False 500 else: 501 changeCharacter = (changeCharacter+1)%len(characters) 502 else: 503 reLocate = False 504 505 if reLocate: 506 moveOnce = False 507 changeEntityLocation = entities.__getitem__(changeEntity).getState('location').expectation() 508 if changeEntity == objectEntity: 509 #change my location to affect my own behavior 510 # e.g. hunter kills wolf 511 objobj = objectives[0][3] 512 objectEntityLocation = entities.__getitem__(objobj).getState('location').expectation() 513 else: 514 #change my location to affect other characters' behaviors 515 #e.g.woodcutter move to wolf 516 objectEntityLocation = entities.__getitem__(objectEntity).getState('location').expectation() 517 518 519 #if not (objectEntityLocation == 0.25 and changeEntity == 'granny'): 520 if changeEntity == 'granny': 521 if objectEntityLocation == 0.25 or wolfMetGranny == True: 522 # we won't move the character and will abonden this test 523 continue 524 525 factor = {} 526 factor['topic'] = 'state' 527 factor['relation'] = '=' 528 factor['lhs'] = ['entities', changeEntity, 'state', 'location'] 529 if objectEntityLocation == changeEntityLocation: 530 #granny moves away from Red to prevent cake being delivered too soon 531 factor['value'] = objectEntityLocation -.2 532 else: 533 factor['value'] = objectEntityLocation 534 msg = Message({'factors':[factor]}) 535 print msg 536 actions.append(copy.deepcopy(msg)) 537 history.append(copy.deepcopy(msg)) 538 entities.performMsg(msg,'granny',receivers,[],self.debug) 539 entities.__getitem__(changeEntity).setState('location',factor['value']) 540 541 finishedMsg = [] 542 for msg in testMessages: 543 if self.make_story_false(msg[0],msg[1],msg[2],entities,history,next[0]['name']): 544 factor = {} 545 factor['topic'] = 'state' 546 factor['relation'] = '=' 547 factor['lhs'] = ['entities', msg[0], 'state', msg[1]] 548 factor['value'] = msg[2] 549 entities.__getitem__(msg[0]).setState(msg[1],factor['value']) 550 msg1 = Message({'factors':[factor]}) 551 print msg1 552 actions.append(copy.deepcopy(msg1)) 553 history.append(copy.deepcopy(msg1)) 554 entities.performMsg(msg1,'granny',receivers,[],self.debug) 555 finishedMsg.append(msg) 556 for tmp in finishedMsg: 557 testMessages.remove(tmp) 558 559 for objective in objectives: 560 tmpAct =objective[0]+'-'+objective[1]+'-'+objective[3] 561 if self.searchPath(history,tmpAct) > -1: 562 continue 563 if (not entity == 'wolf') and (entity == objective[0] or (objective[0] == 'anybody' and not entity == objective[3])): 564 actorLocation = entities.__getitem__(entity).getState('location').expectation() 565 objectLocation = entities.__getitem__(objective[3]).getState('location').expectation() 566 if not actorLocation == objectLocation: 567 continue 568 if objective[2] == 'Maximize': 569 actNext = Action({'actor':entity,'type':objective[1],'object':objective[3]}) 570 options = entities.__getitem__(entity).actions.getOptions() 571 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 572 if [actNext] in options: 573 searchNextAction = False 574 next[0]['choices'] = [[actNext]] 575 # take care of the 1st objective only 576 break 577 578 elif objective[2] == 'Minimize': 579 options = entities.__getitem__(entity).actions.getOptions() 580 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 581 582 for option in options: 583 if not option[0]['type'] == objective[1]: 584 searchNextAction = False 585 next[0]['choices'] = [option] 586 # take care of the 1st objective only 587 break 588 589 if searchNextAction == False: 590 break 591 592 delta = entities.microstep(next,hypothetical=False,explain=False) 593 for key in delta['decision'].keys(): 594 res = delta['decision'][key][0] 595 print `res` 596 actions.append(res) 597 history.append(res) 598 if not decision.has_key(key): 599 decision[key]=delta['decision'][key] 600 601 if abs(entities.__getitem__('wolf').getState('location').expectation()-entities.__getitem__('granny').getState('location').expectation())<=.2\ 602 and entities.__getitem__('wolf').getState('know-granny').expectation()>.5: 603 wolfMetGranny = True 604 605 tmpHistory = copy.deepcopy(self.history) 606 objectives = [] 607 608 # test simulation results 609 actionCount = -1 610 for i in range(len(actions)): 611 tmpHistory.append(actions[i]) 612 613 # don't consider messages when testing 614 if isinstance(actions[i],Message): 615 continue 616 617 actionCount = actionCount+1 618 619 # lookahead 15 steps, but only use the first 5 steps for these two check 620 # the rest are for lookahead to see if certain event will happen 621 if actionCount <= acturalLookaheadSteps: 622 #if i < lookaheadstep: 623 for order in orders: 624 check_order_result = self.checkOrder(tmpHistory,order) 625 if check_order_result == -1: 626 tmp = order[1] 627 tmp = tmp.replace('anybody','') 628 tmpAct = `actions[i]` 629 if tmpAct.find(tmp)>-1: 630 nochange = False 631 print 'violate order ',order 632 # we want the first action to happen 633 actor,type,obj = stringToAct(order[0]) 634 objectives.append((actor,type,'Maximize',obj)) 635 # we want the second action to not happen 636 actor,type,obj = stringToAct(order[1]) 637 objectives.append((actor,type,'Minimize',obj)) 638 639 tmpact = `actions[i]` 640 for key in laterThan: 641 tmp = key 642 if tmp.find('anybody')>-1: 643 tmp = key.replace('anybody','') 644 if tmpact.find(tmp)>-1: 645 if laterThan[`actions[i]`] > len(tmpHistory): 646 nochange = False 647 print `actions[i]`, ' should happen after ',laterThan[`actions[i]`],' steps' 648 objectives.append((actions[i]['actor'],actions[i]['type'],'Minimize',actions[i]['object'])) 649 650 651 # only add the constraints once 652 if i == len(actions)-1: 653 for key in earlierThan: 654 if len(history) >= key: 655 for act in earlierThan[key]: 656 if self.searchPath(tmpHistory,act) == -1: 657 for key in NOearlierThan: 658 if not act in NOearlierThan[key]: 659 actor,type,obj = stringToAct(act) 660 print act, ' should happen before ',key,' steps' 661 objectives.append((actor,type,'Maximize',obj)) 662 663 664 if len(objectives)-len(finishedMsg)< minViolation: 665 minViolation = len(objectives) 666 bestPath=[] 667 bestPath=copy.deepcopy(actions) 668 669 if nochange and len(objectives) == 0: 670 break 671 672 673 print 674 print 'real steps' 675 resolvedE = [] 676 resolvedL = [] 677 i = 0 678 for desired in bestPath: 679 if i < acturalLookaheadSteps: 680 print desired 681 self.logfile.write(str(desired)) 682 self.logfile.write('\n') 683 self.history.append(desired) 684 if isinstance(desired,Message): 685 self.entities.performMsg(desired,'granny',receivers,[],self.debug) 686 self.entities.__getitem__(desired['factors'][0]['lhs'][1]).setState(desired['factors'][0]['lhs'][3],desired['factors'][0]['value']) 687 else: 688 self.entities.microstep([{'name':desired['actor'],'choices':[[desired]]}],hypothetical=False,explain=False) 689 i = i+1 690 for unresolved in earlierThan2: 691 if unresolved[0] == `desired`: 692 resolvedE.append(unresolved) 693 earlierThan[len(self.history)+unresolved[1]] = unresolved[2] 694 for unresolved in laterThan2: 695 if unresolved[0] == `desired`: 696 resolvedL.append(unresolved) 697 laterThan[unresolved[2]] = len(self.history)+unresolved[1] 698 699 if i == acturalLookaheadSteps and isinstance(desired,Message): 700 print desired 701 self.logfile.write(str(desired)) 702 self.logfile.write('\n') 703 self.history.append(desired) 704 self.entities.performMsg(desired,'granny',receivers,[],self.debug) 705 self.entities.__getitem__(desired['factors'][0]['lhs'][1]).setState(desired['factors'][0]['lhs'][3],desired['factors'][0]['value']) 706 707 if abs(self.entities.__getitem__('wolf').getState('location').expectation()-self.entities.__getitem__('granny').getState('location').expectation())<=.2\ 708 and self.entities.__getitem__('wolf').getState('know-granny').expectation()>.5: 709 self.wolfMetGranny = True 710 711 if i == acturalLookaheadSteps and isinstance(desired,Message): 712 break 713 714 for tmp in resolvedE: 715 earlierThan2.remove(tmp) 716 for tmp in resolvedL: 717 laterThan2.remove(tmp)
718 719 720 721 722 723 724
725 - def director(self, result=[]):
726 lookaheadstep = 10 727 acturalLookaheadSteps = 4 728 totalTests = 9 729 730 receivers = ['woodcutter','hunter','wolf','red','granny'] 731 changeCharacter = 0 732 characters = ['red','woodcutter','granny','hunter'] 733 objectives = [] 734 satObjective = [] 735 decision = {} 736 737 # moveToCharacter: 0 relacate changeCharacter to the location of targetEntity before targetEntity act 738 # moveToCharacter: 1 relacate changeCharacter to the location of targetEntity before changeCharacter act 739 # set initial value to 0 because the first test will increase it to 1 while not perform any character realocation 740 moveToCharacter = 0 741 742 #best result among the test 743 bestPath=[] 744 minViolation = 100 745 746 for testNum in range(totalTests): 747 if changeCharacter == 0 and testNum >2: 748 break 749 750 print 751 print 'test',testNum 752 753 entities = copy.deepcopy(self.entities) 754 history = copy.deepcopy(self.history) 755 wolfMetGranny = self.wolfMetGranny 756 actions = [] 757 nochange = True 758 moveToCharacter = (moveToCharacter+1)%2 759 moveOnce = True 760 761 762 if len(objectives)>0: 763 messages = [] 764 testMessages = [] 765 766 for cha in characters: 767 newMsg = self.change_characters_state(cha,decision,objectives) 768 for msg in newMsg: 769 if not msg in messages: 770 messages.append(msg) 771 772 for msg in messages: 773 if not msg[1] in ['being-enquired']: 774 testMessages.append(msg) 775 continue 776 factor = {} 777 factor['topic'] = 'state' 778 factor['relation'] = '=' 779 factor['lhs'] = ['entities', msg[0], 'state', msg[1]] 780 factor['value'] = msg[2] 781 entities.__getitem__(msg[0]).setState(msg[1],factor['value']) 782 msg = Message({'factors':[factor]}) 783 print msg 784 actions.append(copy.deepcopy(msg)) 785 history.append(copy.deepcopy(msg)) 786 entities.performMsg(msg,'granny',receivers,[],self.debug) 787 msg = None 788 789 finishedMsg = [] 790 for i in range(lookaheadstep): 791 next = entities.next() 792 entity = next[0]['name'] 793 searchNextAction = False 794 795 for tmp in satObjective: 796 try: 797 objectives.remove(tmp) 798 except: 799 pass 800 satObjective = [] 801 802 if len(objectives)>0: 803 searchNextAction = True 804 # try fit characters' actions first 805 for objective in objectives: 806 tmpAct =objective[0]+'-'+objective[1]+'-'+objective[3] 807 if self.searchPath(history,tmpAct) > -1: 808 continue 809 if (not entity == 'wolf') and (entity == objective[0] or (objective[0] == 'anybody' and not entity == objective[3])): 810 actorLocation = entities.__getitem__(entity).getState('location').expectation() 811 objectLocation = entities.__getitem__(objective[3]).getState('location').expectation() 812 if not actorLocation == objectLocation: 813 continue 814 if objective[2] == 'Maximize': 815 actNext = Action({'actor':entity,'type':objective[1],'object':objective[3]}) 816 options = entities.__getitem__(entity).actions.getOptions() 817 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 818 if [actNext] in options: 819 fitPath = history+[actNext] 820 newGoals = self.easyFit(entity, fitPath) 821 if newGoals: 822 print 'fit succeed ',fitPath 823 searchNextAction = False 824 satObjective.append(objective) 825 entities.__getitem__(entity).setGoals(newGoals) 826 next[0]['choices'] = [[actNext]] 827 # take care of the 1st objective only 828 break 829 elif objective[2] == 'Minimize': 830 options = entities.__getitem__(entity).actions.getOptions() 831 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 832 833 for option in options: 834 if not option[0]['type'] == objective[1]: 835 fitPath = history+option 836 newGoals = self.easyFit(entity, fitPath) 837 if newGoals: 838 print 'fit succeed ',fitPath 839 searchNextAction = False 840 satObjective.append(objective) 841 entities.__getitem__(entity).setGoals(newGoals) 842 next[0]['choices'] = [option] 843 # take care of the 1st objective only 844 break 845 846 847 if searchNextAction: 848 #only move one chanracter once during each lookahead 849 reLocate = False 850 if moveOnce: 851 objectEntity = objectives[0][0] 852 # change the location of one character at a time 853 changeEntity = characters[changeCharacter] 854 855 # idnore characters whose locations can't be changed 856 if entities.__getitem__(changeEntity).getState('eaten').expectation() >.5: 857 changeCharacter = (changeCharacter+1)%len(characters) 858 changeEntity = characters[changeCharacter] 859 860 # anybody-kill-wolf -> hunter-kill-wolf ->move hunter's location 861 if objectEntity == 'anybody': 862 objectEntity = changeEntity 863 #the character is within the sight of wolf, i can't make it disppear 864 if entities.__getitem__(changeEntity).getState('location').expectation() == entities.__getitem__('wolf').getState('location').expectation(): 865 wolfLastAct = self.getLastAct(history,'wolf') 866 changeEntityLastAct = self.getLastAct(history,changeEntity) 867 # I can change their locations if the wolf just moved or the current chracter just moved 868 if not (`wolfLastAct`.find('move') >-1 or not `changeEntityLastAct`.find('move') >-1) : 869 changeCharacter = (changeCharacter+1)%len(characters) 870 changeEntity = characters[changeCharacter] 871 872 reLocate = True 873 if changeEntity == objectEntity: 874 if changeEntity == entity: 875 moveToCharacter = 1 876 changeCharacter = (changeCharacter+1)%len(characters) 877 else: 878 reLocate = False 879 elif moveToCharacter == 0: 880 if not objectEntity == entity: 881 reLocate = False 882 elif moveToCharacter == 1: 883 if not changeEntity == entity: 884 reLocate = False 885 else: 886 changeCharacter = (changeCharacter+1)%len(characters) 887 else: 888 reLocate = False 889 890 if reLocate: 891 moveOnce = False 892 changeEntityLocation = entities.__getitem__(changeEntity).getState('location').expectation() 893 if changeEntity == objectEntity: 894 #change my location to affect my own behavior 895 # e.g. hunter kills wolf 896 objobj = objectives[0][3] 897 objectEntityLocation = entities.__getitem__(objobj).getState('location').expectation() 898 else: 899 #change my location to affect other characters' behaviors 900 #e.g.woodcutter move to wolf 901 objectEntityLocation = entities.__getitem__(objectEntity).getState('location').expectation() 902 903 904 #if not (objectEntityLocation == 0.25 and changeEntity == 'granny'): 905 if changeEntity == 'granny': 906 if objectEntityLocation == 0.25 or wolfMetGranny == True: 907 # we won't move the character and will abonden this test 908 continue 909 910 factor = {} 911 factor['topic'] = 'state' 912 factor['relation'] = '=' 913 factor['lhs'] = ['entities', changeEntity, 'state', 'location'] 914 if abs(objectEntityLocation - changeEntityLocation)<.01: 915 #granny moves away from Red to prevent cake being delivered too soon 916 factor['value'] = objectEntityLocation -.2 917 else: 918 factor['value'] = objectEntityLocation 919 msg = Message({'factors':[factor]}) 920 print msg 921 actions.append(copy.deepcopy(msg)) 922 history.append(copy.deepcopy(msg)) 923 entities.performMsg(msg,'granny',receivers,[],self.debug) 924 entities.__getitem__(changeEntity).setState('location',factor['value']) 925 926 finishedMsg = [] 927 for msg in testMessages: 928 if self.make_story(msg[0],msg[1],msg[2],entities,history): 929 factor = {} 930 factor['topic'] = 'state' 931 factor['relation'] = '=' 932 factor['lhs'] = ['entities', msg[0], 'state', msg[1]] 933 factor['value'] = msg[2] 934 entities.__getitem__(msg[0]).setState(msg[1],factor['value']) 935 msg1 = Message({'factors':[factor]}) 936 print msg1 937 actions.append(copy.deepcopy(msg1)) 938 history.append(copy.deepcopy(msg1)) 939 entities.performMsg(msg1,'granny',receivers,[],self.debug) 940 finishedMsg.append(msg) 941 for tmp in finishedMsg: 942 testMessages.remove(tmp) 943 944 for objective in objectives: 945 tmpAct =objective[0]+'-'+objective[1]+'-'+objective[3] 946 if self.searchPath(history,tmpAct) > -1: 947 continue 948 if (not entity == 'wolf') and (entity == objective[0] or (objective[0] == 'anybody' and not entity == objective[3])): 949 actorLocation = entities.__getitem__(entity).getState('location').expectation() 950 objectLocation = entities.__getitem__(objective[3]).getState('location').expectation() 951 if not actorLocation == objectLocation: 952 continue 953 if objective[2] == 'Maximize': 954 actNext = Action({'actor':entity,'type':objective[1],'object':objective[3]}) 955 options = entities.__getitem__(entity).actions.getOptions() 956 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 957 if [actNext] in options: 958 fitPath = history+[actNext] 959 newGoals = self.easyFit(entity, fitPath) 960 if newGoals: 961 print 'fit succeed ',fitPath 962 searchNextAction = False 963 satObjective.append(objective) 964 entities.__getitem__(entity).setGoals(newGoals) 965 next[0]['choices'] = [[actNext]] 966 # take care of the 1st objective only 967 break 968 969 elif objective[2] == 'Minimize': 970 options = entities.__getitem__(entity).actions.getOptions() 971 options = entities.__getitem__(entity).updateActionChoices(options,includeLocation = True) 972 973 for option in options: 974 if not option[0]['type'] == objective[1]: 975 fitPath = history+option 976 #print 'easyFit ',fitPath 977 newGoals = self.easyFit(entity, fitPath) 978 if newGoals: 979 print 'fit succeed ',fitPath 980 searchNextAction = False 981 satObjective.append(objective) 982 entities.__getitem__(entity).setGoals(newGoals) 983 next[0]['choices'] = [option] 984 # take care of the 1st objective only 985 break 986 #else: 987 # print 'fit failed ' 988 if searchNextAction == False: 989 break 990 991 delta = entities.microstep(next,hypothetical=False,explain=False) 992 for key in delta['decision'].keys(): 993 res = delta['decision'][key][0] 994 print `res` 995 actions.append(res) 996 history.append(res) 997 if not decision.has_key(key): 998 decision[key]=delta['decision'][key] 999 1000 if abs(entities.__getitem__('wolf').getState('location').expectation()-entities.__getitem__('granny').getState('location').expectation())<=.2\ 1001 and entities.__getitem__('wolf').getState('know-granny').expectation()>.5: 1002 wolfMetGranny = True 1003 1004 tmpHistory = copy.deepcopy(self.history) 1005 objectives = [] 1006 1007 # test simulation results 1008 actionCount = -1 1009 for i in range(len(actions)): 1010 tmpHistory.append(actions[i]) 1011 1012 # don't consider messages when testing 1013 if isinstance(actions[i],Message): 1014 continue 1015 1016 actionCount = actionCount+1 1017 1018 # lookahead 15 steps, but only use the first 5 steps for these two check 1019 # the rest are for lookahead to see if certain event will happen 1020 if actionCount <= acturalLookaheadSteps: 1021 #if i < lookaheadstep: 1022 for order in orders: 1023 check_order_result = self.checkOrder(tmpHistory,order) 1024 if check_order_result == -1: 1025 tmp = order[1] 1026 tmp = tmp.replace('anybody','') 1027 tmpAct = `actions[i]` 1028 if tmpAct.find(tmp)>-1: 1029 nochange = False 1030 print 'violate order ',order 1031 # we want the first action to happen 1032 actor,type,obj = stringToAct(order[0]) 1033 objectives.append((actor,type,'Maximize',obj)) 1034 # we want the second action to not happen 1035 actor,type,obj = stringToAct(order[1]) 1036 objectives.append((actor,type,'Minimize',obj)) 1037 1038 tmpact = `actions[i]` 1039 for key in laterThan: 1040 tmp = key 1041 if tmp.find('anybody')>-1: 1042 tmp = key.replace('anybody','') 1043 if tmpact.find(tmp)>-1: 1044 if laterThan[`actions[i]`] > len(tmpHistory): 1045 nochange = False 1046 print `actions[i]`, ' should happen after ',laterThan[`actions[i]`],' steps' 1047 objectives.append((actions[i]['actor'],actions[i]['type'],'Minimize',actions[i]['object'])) 1048 1049 1050 # only add the constraints once 1051 if i == len(actions)-1: 1052 for key in earlierThan: 1053 if len(history) >= key: 1054 for act in earlierThan[key]: 1055 if self.searchPath(tmpHistory,act) == -1: 1056 for key in NOearlierThan: 1057 if not act in NOearlierThan[key]: 1058 actor,type,obj = stringToAct(act) 1059 print act, ' should happen before ',key,' steps' 1060 objectives.append((actor,type,'Maximize',obj)) 1061 1062 1063 if len(objectives)-len(finishedMsg)< minViolation: 1064 minViolation = len(objectives) 1065 bestPath=[] 1066 bestPath=copy.deepcopy(actions) 1067 1068 if nochange and len(objectives) == 0: 1069 break 1070 1071 1072 print 1073 print 'real steps' 1074 resolvedE = [] 1075 resolvedL = [] 1076 i = 0 1077 for desired in bestPath: 1078 if i < acturalLookaheadSteps: 1079 print desired 1080 self.logfile.write(str(desired)) 1081 self.logfile.write('\n') 1082 self.history.append(desired) 1083 if isinstance(desired,Message): 1084 self.entities.performMsg(desired,'granny',receivers,[],self.debug) 1085 self.entities.__getitem__(desired['factors'][0]['lhs'][1]).setState(desired['factors'][0]['lhs'][3],desired['factors'][0]['value']) 1086 else: 1087 self.entities.microstep([{'name':desired['actor'],'choices':[[desired]]}],hypothetical=False,explain=False) 1088 i = i+1 1089 for unresolved in earlierThan2: 1090 if unresolved[0] == `desired`: 1091 resolvedE.append(unresolved) 1092 earlierThan[len(self.history)+unresolved[1]] = unresolved[2] 1093 for unresolved in laterThan2: 1094 if unresolved[0] == `desired`: 1095 resolvedL.append(unresolved) 1096 laterThan[unresolved[2]] = len(self.history)+unresolved[1] 1097 1098 if i == acturalLookaheadSteps and isinstance(desired,Message): 1099 print desired 1100 self.logfile.write(str(desired)) 1101 self.logfile.write('\n') 1102 self.history.append(desired) 1103 self.entities.performMsg(desired,'granny',receivers,[],self.debug) 1104 self.entities.__getitem__(desired['factors'][0]['lhs'][1]).setState(desired['factors'][0]['lhs'][3],desired['factors'][0]['value']) 1105 1106 if abs(self.entities.__getitem__('wolf').getState('location').expectation()-self.entities.__getitem__('granny').getState('location').expectation())<=.2\ 1107 and self.entities.__getitem__('wolf').getState('know-granny').expectation()>.5: 1108 self.wolfMetGranny = True 1109 1110 if i == acturalLookaheadSteps and isinstance(desired,Message): 1111 break 1112 1113 for tmp in resolvedE: 1114 earlierThan2.remove(tmp) 1115 for tmp in resolvedL: 1116 laterThan2.remove(tmp) 1117 1118 1119
1120 - def make_story(self,entity, state, target,entities,history):
1121 curValue = entities.__getitem__(entity).getState(state).expectation() 1122 diff = target-curValue 1123 for actor in ['woodcutter','hunter','red','wolf']: 1124 options = entities.__getitem__(actor).actions.getOptions() 1125 options = entities.__getitem__(actor).updateActionChoices(options,includeLocation = True) 1126 for option in options: 1127 if actor == 'wolf': 1128 if not option[0]['type']=='help': 1129 continue 1130 actionDict = {} 1131 actionDict[actor] = option 1132 result = entities.hypotheticalAct(actionDict) 1133 for value,prob in result['state'].items(): 1134 for key in value: 1135 try: 1136 if key['entity'] == entity and key['feature']== state: 1137 if abs(diff-value[key][keyConstant]) <=.2 : 1138 path = history+option 1139 #print 'make story fit ',path 1140 if self.easyFit(actor,path): 1141 print 'make story',option,entity,state 1142 if option[0]['type']=='help' and actor == 'wolf': 1143 print 'show option for helpping the wolf' 1144 self.helpWolf = 1 1145 return 1 1146 except: 1147 pass 1148 return 0
1149 1150
1151 - def make_story_false(self,entity, state, target,entities,history,actor):
1152 res = False 1153 act = None 1154 curValue = entities.__getitem__(entity).getState(state).expectation() 1155 diff = target-curValue 1156 1157 options = entities.__getitem__(actor).actions.getOptions() 1158 options = entities.__getitem__(actor).updateActionChoices(options,includeLocation = True) 1159 for option in options: 1160 actionDict = {} 1161 actionDict[actor] = option 1162 result = entities.hypotheticalAct(actionDict) 1163 for value,prob in result['state'].items(): 1164 for key in value: 1165 try: 1166 if key['entity'] == entity and key['feature']== state: 1167 if abs(diff-value[key][keyConstant]) <=.2 : 1168 return True,option 1169 except: 1170 pass 1171 return 0,act
1172 1173
1174 - def change_characters_state(self,character,choices,objectives):
1175 messages = [] 1176 topics = [] 1177 1178 for objective in objectives: 1179 if character == 'red' and objective[0]=='wolf' and objective[1] == 'eat': 1180 continue 1181 if objective[0]=='wolf' and objective[1] == 'enquiry': 1182 continue 1183 if character == 'wolf' and not objective[0]=='wolf': 1184 continue 1185 1186 #print objective[0],objective[1] 1187 #replace suggest function 1188 if (objective[0] in ['red','granny']) and (objective[1] == 'kill'): 1189 topic = [objective[0]+'power'] 1190 returnRes = [(objective[0],'power',1.0)] 1191 elif (objective[0] == 'anybody') and (objective[1] == 'kill'): 1192 topic = [] 1193 returnRes = [] 1194 elif (objective[3] == 'anybody') and (objective[1] == 'eat'): 1195 topic = [] 1196 returnRes = [] 1197 elif (objective[0] in ['red']) and (objective[1] == 'give-cake')and (objective[2] == 'Minimize'): 1198 topic = [] 1199 returnRes = [] 1200 elif (objective[0] in ['red']) and (objective[1] == 'give-cake')and (objective[2] == 'Maximize'): 1201 topic = [objective[0]+'eaten',objective[0]+'has-cake'] 1202 returnRes = [(objective[0],'eaten',0.0),(objective[0],'has-cake',1.0)] 1203 elif (objective[0] in ['wolf']) and (objective[1] == 'give-cake'): 1204 topic = [objective[0]+'has-cake'] 1205 returnRes = [(objective[0],'has-cake',1.0)] 1206 elif (objective[0] in ['wolf']) and (objective[1] == 'eat') and (objective[2] == 'Minimize')and (objective[3] == 'granny'): 1207 topic = [objective[0]+'know-granny'] 1208 returnRes = [(objective[0],'know-granny',0.0)] 1209 elif (objective[0] in ['wolf']) and (objective[1] == 'eat') and (objective[2] == 'Minimize')and (objective[3] == 'red'): 1210 topic = [] 1211 returnRes = [] 1212 elif (not character == 'wolf') and (objective[0] in ['wolf']) and (objective[1] == 'eat') and (objective[2] == 'Maximize')and (objective[3] == 'granny'): 1213 topic = [objective[0]+'know-granny',character+'being-enquired','wolfSD','wolfhas-cake'] 1214 returnRes = [(objective[0],'know-granny',1.0),(character,'being-enquired',1.0),('wolf','SD',1.0),('wolf','has-cake',1.0)] 1215 elif (objective[3] == 'wolf') and (objective[1] == 'talkabout-granny') and (objective[2] == 'Maximize'): 1216 topic = ['wolfSD','wolfhas-cake'] 1217 returnRes = [('wolf','SD',1.0),('wolf','has-cake',1.0)] 1218 else: 1219 res = self.entities.suggest(character,choices[character][0],objective[:3]) 1220 topic,returnRes = self.formMessage(res) 1221 1222 for i in range(len(topic)): 1223 if topic[i] in topics: 1224 continue 1225 topics.append(topic[i]) 1226 messages.append(returnRes[i]) 1227 1228 #print messages 1229 return messages 1230 1231 1232
1233 - def formMessage(self,res):
1234 returnRes = [] 1235 topic = [] 1236 for choice in res: 1237 if choice == {}: 1238 continue 1239 for item in choice: 1240 entity = item['entity'] 1241 state = item['feature'] 1242 1243 if state == 'location': 1244 continue 1245 else: 1246 content = choice[item] 1247 for item1 in content: 1248 if item1 == 'max': 1249 value = content[item1] 1250 #elif item1 == 'min': 1251 # value = -content[item1]+self.entities.__getitem__(entity).getState(state).expectation() 1252 1253 if not entity+state in topic: 1254 topic.append(entity+state) 1255 returnRes.append((entity,state,value)) 1256 1257 return topic,returnRes 1258 1259 1260 1261
1262 - def step(self,length='100',results=[]):
1263 try: 1264 length = int(length) 1265 except TypeError: 1266 results = length 1267 length = 1 1268 1269 sequence, res = self._step(length) 1270 return sequence
1271 1272
1273 - def _step(self,length=100,results=[]):
1274 """Steps the simulation the specified number of micro-steps 1275 into the future (default is 1)""" 1276 1277 sequence = [] 1278 for t in range(length): 1279 sequence = [] 1280 res=None 1281 ## self.director(result=[]) 1282 self.director2(result=[]) 1283 #nextturn = self.entities.next() 1284 ##actor = nextturn[0]['name'] 1285 ##entity = self.entities.__getitem__(actor) 1286 ##print entity.updateActionChoices(entity.actions.getOptions(),entity.getAllBeliefs()) 1287 # 1288 #delta = self.entities.microstep(turns=nextturn,explain=False, debug=self.debug) 1289 # 1290 #if delta['decision']: 1291 # for key in delta['decision'].keys(): 1292 # res = delta['decision'][key][0] 1293 # print `res` 1294 # sequence.append(delta['decision'][key][0]) 1295 # 1296 # # appraisal 1297 # self.runAppraisal(res) 1298 # self.history.append(res) 1299 1300 return sequence, res
1301 1302
1303 - def send(self,sender,receiver,*content):
1304 print content 1305 try: 1306 if receiver == '*': 1307 # Message sent to all 1308 receivers = ['wolf','red','hunter','woodcutter','granny'] 1309 else: 1310 receivers = [receiver] 1311 if type(content[len(content)-1]) is ListType: 1312 results = content[len(content)-1] 1313 msg = string.join(content[:len(content)-1]) 1314 elif type(content[0]) is StringType: 1315 results = [] 1316 msg = content[0] 1317 else: 1318 results = [] 1319 msg = string.join(content) 1320 except IndexError: 1321 return 'Usage: message <sender> <receiver> <content>' 1322 1323 msg = Message(msg) 1324 msg['type'] = '_message' 1325 1326 self.history.append(msg) 1327 1328 result = self.entities.performMsg(msg,sender,receivers,[],self.debug)
1329 1330 1331
1332 - def __act__(self,actList,results):
1333 action = extractAction(actList,self.entities,self.actionFormat, 1334 self.debug) 1335 resolved = [] 1336 for unresolved in earlierThan2: 1337 if unresolved[0] == `action`: 1338 resolved.append(unresolved) 1339 earlierThan[len(self.history)+unresolved[1]] = unresolved[2] 1340 for tmp in resolved: 1341 earlierThan2.remove(tmp) 1342 1343 resolved = [] 1344 for unresolved in laterThan2: 1345 if unresolved[0] == `action`: 1346 resolved.append(unresolved) 1347 laterThan[unresolved[2]] = len(self.history)+unresolved[1] 1348 for tmp in resolved: 1349 laterThan2.remove(tmp) 1350 1351 1352 if action: 1353 if self.__UNDO__: 1354 self.lastStep=copy.deepcopy (self.entities) 1355 return self.doActions(actions={action['actor']:[action]}, 1356 detailLevel=0, 1357 results=results) 1358 else: 1359 results.append('Usage: act <entity> <type> <obj>') 1360 return {}
1361
1362 - def doActions(self,actions,detailLevel=10,results=[],entities=None,isRealStep = 1):
1363 1364 """Performs the actions, provided in dictionary form 1365 @param actions: dictionary of actions to be performed, indexed by actor, e.g.: 1366 - I{agent1}: [I{act11}, I{act12}, ... ] 1367 - I{agent2}: [I{act21}, I{act22}, ... ] 1368 - ... 1369 @type actions: C{dict:strS{->}L{Action}[]} 1370 @param detailLevel: the level of detail requested for the explanation, where higher numbers mean more detail. The default level is 10 (the maximum level of detail) 1371 @type detailLevel: C{int} 1372 """ 1373 1374 if entities == None: 1375 entities = self.entities 1376 1377 1378 turns = [] 1379 for actor,actList in actions.items(): 1380 turns.append({'name':actor,'choices':[actList]}) 1381 1382 ##appraisal 1383 #isRealStep = 0 1384 if isRealStep == 1: 1385 self.runAppraisal(actList[0]) 1386 self.history.append(actList[0]) 1387 1388 delta = entities.microstep(turns,hypothetical=False, 1389 explain=False, 1390 debug=self.debug) 1391 1392 return {}
1393 1394 1395
1396 - def loadClasses(self):
1397 if self.scene == '3': 1398 import RedRidingHoodClasses_director 1399 self.classes = RedRidingHoodClasses_director.classHierarchy 1400 1401 elif self.scene == '31': 1402 import RedRidingHoodClasses_test 1403 self.classes = RedRidingHoodClasses_test.classHierarchy 1404 1405 ## import RedRidingHoodClassesStage 1406 ## self.classes = RedRidingHoodClassesStage.classHierarchy 1407 1408 elif self.scene == '4': 1409 import ChatClasses 1410 self.classes = ChatClasses.classHierarchy 1411 elif self.scene == '6': 1412 import RatClasses 1413 self.classes = RatClasses.classHierarchy 1414 elif self.scene == '7': 1415 import UAIClasses 1416 self.classes = UAIClasses.classHierarchy 1417 else: 1418 raise "wrong scene ID" 1419 1420 ## mei 07/12/05 1421 if isinstance(self.classes,GenericSociety): 1422 pass 1423 elif isinstance(self.classes,dict): 1424 society = GenericSociety() 1425 ## society.importDict(self.classes,ThespianGenericModel) 1426 society.importDict(self.classes) 1427 self.classes = society
1428 1429 1430
1431 - def setScene(self,scene,results=[]):
1432 self.scene = scene 1433 ThespianAgents.sceneID = scene 1434 1435 self.loadClasses() 1436 1437 scenario = self.setupEntities(self.createEntities(),None, 1438 compileDynamics=True,compilePolicies=None) 1439 self.setupScenario(scenario)
1440 1441 1442
1443 - def reSetScene(self,results=[],entities=None,copyEntities=None):
1444 if entities == None: 1445 entities = self.entities 1446 if copyEntities == None: 1447 copyEntities = self.copyEntities 1448 entities = copy.deepcopy(copyEntities) 1449 #for entityName in entities: 1450 # self.AP.setupDynamics(entities,entityName,self.copyEntities) 1451 self.history=[]
1452 1453
1454 - def reSetSceneWithGoals(self,goals={},entities=None,copyEntities=None):
1455 if entities == None: 1456 entities = self.entities 1457 if copyEntities == None: 1458 copyEntities = self.copyEntities 1459 self.reSetScene([],entities,copyEntities) 1460 for entity in entities: 1461 if goals.has_key(entity): 1462 entities.__getitem__(entity).setGoals(goals[entity])
1463 1464 1465
1466 - def getCommand(self):
1467 """Terminal version of command entry. Prints a prompt 1468 (currently assumes turn-based execution) and reads the command 1469 entry from the input file.""" 1470 if self.phase == 'setup': 1471 prompt = '?' 1472 else: 1473 next = self.entities.next() 1474 if next[0]['name'] == 'wolf': 1475 indoor = self.entities.__getitem__('wolf').getState('indoor').expectation() 1476 wolfLocation = self.entities.__getitem__('wolf').getState('location').expectation() 1477 1478 print 'wolf SD ',self.entities.__getitem__('wolf').getState('SD').expectation(),' ', 1479 self.logfile.write('wolf SD '+str(self.entities.__getitem__('wolf').getState('SD').expectation())+' \n') 1480 print 1481 1482 if not indoor >0.5: 1483 print 'characters closeby: ', 1484 self.logfile.write('characters closeby: ') 1485 for entity in self.entities: 1486 if entity == 'wolf': 1487 continue 1488 tmp = self.entities.__getitem__(entity).getState('location').expectation() 1489 if abs(tmp-wolfLocation)<=.01: 1490 if entity == 'granny': 1491 if self.entities.__getitem__('wolf').getState('know-granny').expectation() <.5: 1492 continue 1493 if entity in ['granny','red']: 1494 if self.entities.__getitem__(entity).getState('eaten').expectation() >.5: 1495 continue 1496 print entity,tmp-wolfLocation,' ', 1497 self.logfile.write(entity+str(0)+' ') 1498 1499 if entity in ['red','granny']: 1500 print '(power ',self.entities.__getitem__(entity).getState('power').expectation(),') ', 1501 self.logfile.write('(power '+str(self.entities.__getitem__(entity).getState('power').expectation())+') ') 1502 #can detect hunter in a distance 1503 elif abs(tmp-wolfLocation)<=.2: 1504 if entity == 'hunter': 1505 print entity,tmp-wolfLocation,' ', 1506 self.logfile.write(entity+str(tmp-wolfLocation)+' ') 1507 1508 print 'available actions' 1509 self.logfile.write('available actions') 1510 entity = self.entities.__getitem__(next[0]['name']) 1511 options = entity.actions.getOptions() 1512 options = entity.updateActionChoices(options,includeLocation = True) 1513 for option in options: 1514 # unless the wolf already know where granny is, there may randomly appear houses on side of the road for the wolf to enter 1515 if option[0]['type'] == 'enter-house': 1516 if self.entities.__getitem__('wolf').getState('location').expectation() == self.entities.__getitem__('granny').getState('location').expectation() \ 1517 and self.entities.__getitem__('wolf').getState('know-granny').expectation() >.5: 1518 pass 1519 else: 1520 continue 1521 1522 # only occationally the woodcutter needs help 1523 if option[0]['type'] == 'help': 1524 # if decided by the director agent to help wolf, show this option 1525 if self.helpWolf: 1526 pass 1527 elif random.random() < .8: 1528 continue 1529 1530 if option[0].has_key('object'): 1531 if indoor > 0.5: 1532 if not option[0]['object'] in ['granny','red']: 1533 continue 1534 1535 print option 1536 self.logfile.write(str(option)) 1537 self.logfile.write('\n') 1538 1539 1540 prompt = '%s (%d)> ' % (next[0]['name'], 1541 self.entities.time) 1542 print prompt, 1543 1544 try: 1545 cmd = string.strip(sys.stdin.readline()) 1546 self.logfile.write(cmd) 1547 self.logfile.write('\n') 1548 except KeyboardInterrupt: 1549 cmd = 'quit' 1550 return cmd
1551 1552 1553 ## the exclude list contains list of agents whose model WILLNOT be adjusted in this function
1554 - def varyModel(self,actor,exclude=[],models=[],entities=None):
1555 1556 if entities == None: 1557 entities = self.entities 1558 1559 entity = entities.__getitem__(actor) 1560 fixedgoals = ['sameLocation','actAlive','resp-norm','specialRule'] 1561 1562 origoals = entity.getGoals() 1563 adjgoals = copy.deepcopy(origoals) 1564 removeList = [] 1565 for goal in adjgoals: 1566 if goal.key in fixedgoals: 1567 removeList.append(goal) 1568 for goal in removeList: 1569 adjgoals.remove(goal) 1570 1571 adjgoalKeys = [] 1572 for goal in adjgoals: 1573 adjgoalKeys.append(goal.toKey()) 1574 1575 n = len(adjgoals) 1576 ## construct the P matrix 1577 P = matrix (0.0,(n,n),tc = 'd') 1578 P [::n+1]+=2 1579 1580 for other in entities: 1581 if other in exclude: 1582 continue 1583 beliefAboutOther = entity.getEntity(other) 1584 for model in models: 1585 beliefAboutOther.setModel(model) 1586 print actor,"'s belief about ",other," is set to ",model 1587 self.generateAllPosPath(actor,['sameLocation','actAlive','resp-norm','specialRule'],5, 1588 adjgoals=adjgoals, adjgoalKeys=adjgoalKeys, P=P, entities=entities) 1589 self.reSetScene(entities) 1590 print 1591 print
1592 1593 1594
1595 - def varyInitialState(self,actor,varyList={},entities=None):
1596 1597 if entities == None: 1598 entities = self.entities 1599 1600 entity = entities.__getitem__(actor) 1601 fixedgoals = ['sameLocation','actAlive','resp-norm','specialRule'] 1602 1603 origoals = entity.getGoals() 1604 adjgoals = copy.deepcopy(origoals) 1605 removeList = [] 1606 for goal in adjgoals: 1607 if goal.key in fixedgoals: 1608 removeList.append(goal) 1609 for goal in removeList: 1610 adjgoals.remove(goal) 1611 1612 adjgoalKeys = [] 1613 for goal in adjgoals: 1614 adjgoalKeys.append(goal.toKey()) 1615 1616 n = len(adjgoals) 1617 ## construct the P matrix 1618 P = matrix (0.0,(n,n),tc = 'd') 1619 P [::n+1]+=2 1620 1621 1622 for other in varyList: 1623 state = varyList[other] 1624 for value in [-1,0,1]: 1625 entity.setBelief(other,state,value) 1626 print actor,"'s belief about ",other,"\'s ",state," is set to ",value 1627 self.generateAllPosPath(actor,['sameLocation','actAlive','resp-norm','specialRule'],5, 1628 adjgoals=adjgoals, adjgoalKeys=adjgoalKeys, P=P, entities=entities) 1629 self.reSetScene(entities) 1630 print 1631 print
1632 1633
1634 - def varyGoal(self,actor,fixedgoals=[],entities=None):
1635 1636 if entities == None: 1637 entities = self.entities 1638 1639 entity = entities.__getitem__(actor) 1640 origoals = copy.deepcopy(entity.goals) 1641 1642 allGoalNames = [] 1643 for goal in origoals: 1644 allGoalNames.append(goal.key) 1645 1646 ## the goals we will play with 1647 adjgoals = copy.deepcopy(origoals) 1648 1649 for goal in adjgoals: 1650 if goal.key in fixedgoals: 1651 adjgoals.remove(goal) 1652 1653 for i in range(min(5,len(adjgoals))): 1654 for value in [-5,5]: 1655 entity.setGoalWeight(adjgoals[i],value,None) 1656 for j in range(len(fixedgoals)): 1657 for fullGoal in origoals: 1658 ## find out the corresponding goal 1659 if fixedgoals[j] == fullGoal.key: 1660 entity.setGoalWeight(fullGoal,1000,None) 1661 break 1662 entity.normalizeGoals() 1663 print actor,' goal ',adjgoals[i].name,' weight set to ',value 1664 ## self.executeCommand('step 20') 1665 self.generateAllPosPath(actor,allGoalNames,5,entities) 1666 self.reSetSceneWithGoals(entities,{actor:copy.deepcopy(origoals)}) 1667 print 1668 print
1669 1670
1671 - def searchPath(self, path, act):
1672 index = -1 1673 1674 if not isinstance((path[0]),str): 1675 newPath = [] 1676 for tmp in path: 1677 newPath.append(`tmp`) 1678 else: 1679 newPath = copy.copy(path) 1680 1681 try: 1682 index = newPath.index(act) 1683 except: 1684 if act.find('anybody')>-1: 1685 tmp = act.replace('anybody','') 1686 for tact in newPath: 1687 if tact.find(tmp)>-1: 1688 return newPath.index(tact) 1689 1690 if act.find('talk')>-1: 1691 tmp = act.replace('talk','inform') 1692 try: 1693 index = newPath.index(tmp) 1694 except: 1695 tmp = act.replace('talk','enquiry') 1696 try: 1697 index = newPath.index(tmp) 1698 except: 1699 pass 1700 return index
1701 1702
1703 - def checkOrder(self,path,order):
1704 index1 = self.searchPath(path, order[0]) 1705 index2 = self.searchPath(path, order[1]) 1706 1707 if index2 > -1 and index2 < index1: 1708 return -1 1709 1710 if index2 > -1 and index1 == -1: 1711 return -1 1712 1713 if index2 == -1 and index1 == -1: 1714 return 0 1715 1716 return 1
1717 1718
1719 - def checkComplete(self,path,complete):
1720 actPath = [] 1721 for action in path: 1722 if not isinstance(action,Message): 1723 actPath.append(action) 1724 1725 for act in complete: 1726 if act in actPath: 1727 pass 1728 else: 1729 ## print act,'(',type(act),') is not in ',actList 1730 return False 1731 1732 return True
1733 1734 1735
1736 - def FitToPlotPoint(self,storyPath,fixedgoals=[],delta=0,entities=None):
1737 1738 if entities == None: 1739 entities = self.entities 1740 1741 newStoryPath = copy.copy(storyPath) 1742 ## only loop once for now 1743 for i in range(0,1): 1744 for actor in entities.members(): 1745 ## print newStoryPath 1746 name = actor.name 1747 self.reSetScene(entities) 1748 res = self.fitSequence(newStoryPath,name,fixedgoals,delta,entities) 1749 if not res == 1: 1750 pathWithGap = self.incrementalFitSequence(newStoryPath,fixedgoals,delta,entities) 1751 break 1752 else: 1753 print "result" ,newStoryPath 1754 return True 1755 1756 if len(pathWithGap)>=2: 1757 islands = [pathWithGap[len(pathWithGap)-2],pathWithGap[len(pathWithGap)-1]] 1758 actors = [0]*2 1759 actors [0] = string.split(`islands[0]`,'-') 1760 actors [0] = actors [0][0] 1761 actors [1] = string.split(`islands[1]`,'-') 1762 actors [1] = actors [1][0] 1763 path = pathWithGap[0:len(pathWithGap)-2] 1764 else: 1765 islands = [pathWithGap[0]] 1766 path = [] 1767 actors = [] 1768 for actor in self.entities.members(): 1769 actors.append(actor.name) 1770 1771 print 'filling in Gap ',islands 1772 print 'path is ',path 1773 res = self.fillGap(fixedgoals,4,path,islands,actors,entities) 1774 1775 if res == None: 1776 print 'can not use social normative actions to fill in the gap between: ',islands 1777 if len(islands) == 1: 1778 res = self.findSuggestion(path,islands[0],exclude=[{'feature': 'location', 'entity': 'red'}, 1779 {'feature': 'alive', 'entity': 'red'}],entities=entities) 1780 else: 1781 res = self.findSuggestion(path+[islands[0]],islands[1],exclude=[ 1782 {'feature': 'location', 'entity': 'red'}, 1783 {'feature': 'alive', 'entity': 'red'}],entities=entities) 1784 1785 if not res == None and len(res)>0: 1786 res = self.formMessage(res) 1787 print 'suggestion for actor\'s believe change: ',res 1788 else: 1789 print 'can not use msg to actor\'s own beliefs to fill in the gap between: ',islands 1790 if len(islands) == 1: 1791 res = self.findSuggestion2(path,islands[0],exclude=[{'feature': 'location', 'entity': 'red'}, 1792 {'feature': 'alive', 'entity': 'red'}],entities=entities) 1793 else: 1794 res = self.findSuggestion2(path+[islands[0]],islands[1],exclude=[{'feature': 'location', 'entity': 'red'}, 1795 {'feature': 'alive', 'entity': 'red'}],entities=entities) 1796 1797 if not res == None and len(res)>0: 1798 res = self.formMessage(res) 1799 print 'suggestion for actor\'s believe change: ',res 1800 else: 1801 print 'cannot fill the gap' 1802 1803 1804 if not res == None: 1805 index = storyPath.index(islands[0]) 1806 path1 = storyPath[0:index] 1807 if index+1 > len(storyPath)-1: 1808 path2 = [] 1809 else: 1810 path2 = storyPath[index+1:len(storyPath)] 1811 1812 if type(res) == list: 1813 ## by default, we use the first result 1814 res = res[0] 1815 if isinstance(res,Message): 1816 res = [res,storyPath[index]] 1817 newStoryPath = path1+res+path2 1818 1819 1820 return False
1821 1822 ##{{'feature': 'location', 'entity': 'red'}: {'max': 1.0, 'key': {'feature': 'location', 'entity': 'red'}, 'min': 0.9}, {'feature': 'alive', 'entity': 'red'}: {'max': 1.0, 'key': {'feature': 'alive', 'entity': 'red'}, 'min': 0.001}}
1823 - def searchResult(self,res,exclude):
1824 if exclude == []: 1825 return res 1826 1827 for choice in res: 1828 delList = [] 1829 for msg in choice: 1830 for key in exclude: 1831 if msg == key or msg == {}: 1832 delList.append(msg) 1833 1834 for delItem in delList: 1835 try: 1836 del choice[delItem] 1837 except: 1838 print choice 1839 1840 while 1: 1841 try: 1842 res.remove({}) 1843 except: 1844 break 1845 1846 return res
1847 1848
1849 - def findSuggestion(self,path,obj,exclude=[{'feature': 'location', 'entity': 'red'}],entities=None):
1850 1851 if entities == None: 1852 entities = self.entities 1853 1854 self.reSetScene(entities) 1855 1856 if len(path)>0: 1857 for action in path: 1858 if not isinstance(action,Message): 1859 res = self.doActions(actions={action['actor']:[action]}, 1860 detailLevel=0,entities=entities) 1861 1862 actorName = obj['actor'] 1863 try: 1864 actorName = actorName.name 1865 except: 1866 pass 1867 print 'actorName ',actorName 1868 entities.objectives = [(actorName,obj['type'],'Maximize')] 1869 turn = [{'name':actorName}] 1870 1871 result = entities.microstep(turn,hypothetical=True,explain=False) 1872 for key,observed in result.items(): 1873 if key != 'explanation': 1874 try: 1875 actor = self.entities.__getitem__(key) 1876 except KeyError: 1877 continue 1878 print 'actor ',actor 1879 res = entities.suggest(actor.name,observed['decision'],entities.objectives,entities) 1880 print res 1881 res = self.searchResult(res,exclude) 1882 if not res == {}: 1883 return res 1884 else: 1885 return None
1886 1887 1888
1889 - def findSuggestion2(self,path,obj,exclude,entities=None):
1890 1891 if entities == None: 1892 entities = self.entities 1893 1894 self.reSetScene(entities) 1895 1896 if len(path)>0: 1897 for action in path: 1898 if not isinstance(action,Message): 1899 res = self.doActions(actions={action['actor']:[action]}, 1900 detailLevel=0,entities=entities) 1901 1902 actorName = obj['actor'] 1903 1904 nextturn = entities.next() 1905 1906 try: 1907 actorName = actorName.name 1908 except: 1909 pass 1910 1911 actor = entities.__getitem__(actorName) 1912 1913 otherObj = None 1914 1915 for other in entities: 1916 if other == actorName: 1917 continue 1918 1919 otherEntity = entities.__getitem__(other) 1920 1921 for option in otherEntity.actions.getOptions(): 1922 ## [{'red-move2':[Action({'actor':'wolf','type':'wait'})]}] 1923 if option[0]['object']: 1924 actor.fixedActions=[{`obj`:[Action({'actor':other,'type':option[0]['type'], 1925 'object':option[0]['object']})]}] 1926 else: 1927 actor.fixedActions=[{`obj`:[Action({'actor':other,'type':option[0]['type']})]}] 1928 1929 result = entities.microstep(nextturn,hypothetical=True,explain=False) 1930 1931 for key in result['decision'].keys(): 1932 if obj == result['decision'][key][0]: 1933 otherObj = option[0] 1934 break 1935 1936 actor.fixedActions = [] 1937 if not otherObj == None: 1938 break 1939 1940 1941 #actor.entities.objectives = [(otherObj['actor'],otherObj['type'],'Maximize')] 1942 actor.entities.objectives = [('wolf','move2','Maximize')] 1943 #turn = [{'name':otherObj['actor']}] 1944 turn = [{'name':'wolf'}] 1945 1946 #self.execute('act '+actorName+' '+obj['type']) 1947 self.execute('act red move2 wolf') 1948 1949 result = actor.entities.microstep(turn,hypothetical=True,explain=False) 1950 1951 for key,observed in result.items(): 1952 if key != 'explanation': 1953 #try: 1954 # actorSuggest = entities.__getitem__(key] 1955 #except KeyError: 1956 # continue 1957 1958 #res = entities.suggest(actorSuggest.name,observed['decision'],entities.objectives) 1959 res = actor.entities.suggest('wolf',result['decision'],actor.entities.objectives) 1960 print res 1961 res = self.searchResult(res,exclude) 1962 if not res == {}: 1963 return res 1964 else: 1965 return None
1966 1967
1968 - def incrementalFitSequence(self,storyPath,fixedgoals=[],delta=0,entities=None):
1969 if entities == None: 1970 entities = self.entities 1971 1972 self.reSetScene(entities) 1973 for i in range(-1,len(storyPath)): 1974 path = storyPath[0:i+1] 1975 for actor in entities.members(): 1976 name = actor.name 1977 self.reSetScene(entities) 1978 res = self.fitSequence(path,name,fixedgoals,delta,entities) 1979 if not res == 1: 1980 return path 1981 return []
1982 1983 1984 1985
1986 - def fillGap(self,fixedgoals=[],maxstep=4,path=[], 1987 islands = [],actors = ['wolf','red'],entities=None):
1988 1989 if entities == None: 1990 entities = self.entities 1991 1992 entityname = '' 1993 1994 self.reSetScene(entities) 1995 1996 if len(path)>0: 1997 for action in path: 1998 if action['actor']== actors[0]: 1999 entityname = actors[1] 2000 else: 2001 entityname = actors[0] 2002 else: 2003 nextturn = entities.next() 2004 for turn in nextturn: 2005 entityname = turn['name'] 2006 2007 entity = entities.__getitem__(entityname) 2008 options = entity.actions.getOptions() 2009 options = entity.updateActionChoices(options,includeLocation = True) 2010 for action in options: 2011 ## if action[0]['type']in['move2'] and path ==[]: 2012 #if action[0]['type']in['move2']: 2013 # continue 2014 pathnew = copy.copy(path) 2015 pathnew.append(action[0]) 2016 if self.checkOrder(pathnew,islands): 2017 if self.checkComplete(pathnew,islands): 2018 for actor in actors: 2019 self.reSetScene(entities) 2020 print 'fillGap, try: ',pathnew 2021 res = self.fitSequence(pathnew,actor,fixedgoals,delta=-.000001,entities=entities) 2022 if not res == 1: 2023 break 2024 else: 2025 return pathnew 2026 else: 2027 maxstepnew = maxstep-1 2028 if maxstepnew >= 0: 2029 res = self.fillGap(fixedgoals,maxstepnew,pathnew,islands,actors,entities) 2030 if (not res == None): 2031 return res 2032 2033 return None
2034 2035 2036 2037 2038
2039 - def generateAllPosPath(self,actor,fixedgoals=[],maxstep=20,path=[],delta=-.000001, 2040 constraints=[],adjgoals=None, adjgoalKeys=None, P=None, start=[],entities=None):
2041 2042 if entities == None: 2043 entities = self.entities 2044 2045 entity = entities.__getitem__(actor) 2046 2047 ## bring the simulation to the state as specified in path 2048 self.reSetScene(entities) 2049 if len(path)>0: 2050 for action in path: 2051 res = self.doActions(actions={action['actor']:[action]}, 2052 detailLevel=0,entities=entities) 2053 2054 2055 ## now start generating process 2056 allConstraints = entity.fitAllAction() 2057 2058 allActionString = [] 2059 for action in entity.actions.getOptions(): 2060 allActionString.append(`action[0]`) 2061 2062 i = 0 2063 if start == []: 2064 finiedIndex = -1 2065 else: 2066 finiedIndex = allActionString.index(start[5-maxstep]) 2067 for action in entity.actions.getOptions(): 2068 if i < finiedIndex: 2069 i += 1 2070 continue 2071 i += 1 2072 2073 pathnew = copy.copy(path) 2074 pathnew.append(action[0]) 2075 2076 myConstraints = copy.copy(constraints) 2077 for newConstraints in allConstraints[str(action)]: 2078 myConstraints.append(newConstraints) 2079 2080 ## note myConstraints will be updated in this step 2081 res = self.adjustGoalWeights(myConstraints,actor,fixedgoals,delta,entities) 2082 if res == 1: 2083 res1 = self.doActions(actions={action[0]['actor']:[action[0]]}, 2084 detailLevel=0,entities=entities) 2085 while (1): 2086 actorHasTurn = 0 2087 nextturn = entities.next() 2088 for turn in nextturn: 2089 if turn['name'] == actor: 2090 actorHasTurn = 1 2091 break 2092 if actorHasTurn == 1: 2093 break 2094 else: 2095 res2 = self.step() 2096 pathnew.append(copy.deepcopy(res2[0])) 2097 2098 2099 maxstepnew = maxstep-1 2100 if maxstepnew >= 0: 2101 self.generateAllPosPath(actor,fixedgoals,maxstepnew,pathnew,delta,myConstraints,adjgoals, adjgoalKeys, P, start,entities) 2102 else: 2103 print pathnew
2104 2105
2106 - def easyFit(self,actor,storyPath):
2107 #print 'fit path: ',storyPath 2108 entities = copy.deepcopy(self.copyEntities) 2109 # delta -0.01 allows wolf to help woodcutter, but also granny to kill wolf 2110 # delta -0.001 can fit woodcutter to not kill wolf 2111 if self.fitSequence(storyPath,actor,fixedgoals=['alive','eaten'],delta=0,entities=entities) == 1: 2112 entity = entities.__getitem__(actor) 2113 return entity.goals 2114 #receivers = ['woodcutter','hunter','wolf','red','granny'] 2115 #entity = self.entities.__getitem__(actor) 2116 # 2117 #for feature in ['likeTalk','likeMove','has-cake','full','redEaten','wolfAlive']: 2118 # for goal,weight in entity.goals.items(): 2119 # key = goal.toKey() 2120 # if key['feature'] == feature: 2121 # break 2122 # 2123 # for weight in [0.00000000000000000001,0.001,0.01]: 2124 # success = 1 2125 # entities = copy.deepcopy(self.copyEntities) 2126 # entity = entities.__getitem__(actor) 2127 # entity.setGoalWeight(goal,weight,False) 2128 # 2129 # for desired in storyPath: 2130 # #next = entities.next() 2131 # #print next[0]['name'] 2132 # if not isinstance(desired,Message): 2133 # if desired['actor']==actor: 2134 # try: 2135 # #delta = entities.microstep(hypothetical=False,explain=False) 2136 # #for key in delta['decision'].keys(): 2137 # # res = delta['decision'][key][0] 2138 # # print res 2139 # # if not res == desired: 2140 # # # except may be generated when try to fit an action that is not possible, e.g. not at the same places 2141 # # constraints = entity.generateConstraints([desired]) 2142 # # 2143 # # for constraint in constraints: 2144 # # #break the tie 2145 # # if constraint['delta'] <0: 2146 # # print res,constraint['delta'] 2147 # # if constraint['delta'] <= -0.01: 2148 # # success = 0 2149 # # break 2150 # constraints = entity.generateConstraints([desired]) 2151 # for constraint in constraints: 2152 # #break the tie 2153 # #if constraint['delta'] <0: 2154 # # print constraint['delta'] 2155 # if constraint['delta'] <= -0.01: 2156 # success = 0 2157 # break 2158 # if success: 2159 # #print desired 2160 # entities.microstep([{'name':desired['actor'],'choices':[[desired]]}],hypothetical=False,explain=False) 2161 # 2162 # except: 2163 # #print 'generateConstraints error' 2164 # success = 0 2165 # 2166 # if success == 0: 2167 # break 2168 # 2169 # 2170 # if isinstance(desired,Message): 2171 # #print 'message' 2172 # entities.performMsg(desired,'granny',receivers,[],self.debug) 2173 # else: 2174 # #print desired 2175 # entities.microstep([{'name':desired['actor'],'choices':[[desired]]}],hypothetical=False,explain=False) 2176 # 2177 # if success == 1: 2178 # #print entity.goals 2179 # return entity.goals 2180 return None
2181 2182
2183 - def fitSequence(self,storyPath,actor,fixedgoals=[],delta=0,entities=None):
2184 receivers = ['woodcutter','hunter','wolf','red','granny'] 2185 if entities == None: 2186 entities = self.entities 2187 2188 constraints = [] 2189 entity = entities.__getitem__(actor) 2190 for desired in storyPath: 2191 if not isinstance(desired,Message): 2192 if desired['actor']==actor: 2193 try: 2194 # except may be generated when try to fit an action that is not possible, e.g. not at the same places 2195 newConstraints = entity.generateConstraints([desired]) 2196 except: 2197 return -1 2198 for new in newConstraints: 2199 constraints.append(new) 2200 2201 if isinstance(desired,Message): 2202 entities.performMsg(desired,'granny',receivers,[],self.debug) 2203 else: 2204 entities.microstep([{'name':desired['actor'],'choices':[[desired]]}],hypothetical=False,explain=False) 2205 res = self.adjustGoalWeights(constraints,entity,fixedgoals,delta) 2206 #print 'adjustGoalWeights result',res 2207 2208 #if res == -1 or res == 0: 2209 # return -1 2210 #else: 2211 # return 1 2212 return res
2213 2214
2215 - def adjustGoalWeights(self,constraints,entity,fixedgoals=[],delta=0):
2216 origoals = copy.deepcopy(entity.goals) 2217 2218 initViolation = 0 2219 for constraint in constraints: 2220 # break the tie here, only fit if action acturally gets a lower utility 2221 # don't need delta anymore 2222 if constraint['delta'] < 0: 2223 initViolation +=1 2224 2225 if initViolation == 0: 2226 return 1 2227 2228 2229 if len(fixedgoals) >= len(origoals): 2230 return 0 2231 2232 Violation = self.satisfyConstraints(constraints,entity,fixedgoals,delta) 2233 2234 if Violation > initViolation: 2235 entity.setGoals(origoals) 2236 2237 2238 if Violation > initViolation or Violation == -1: 2239 return -1 2240 elif Violation == 0: 2241 return 1 2242 else: 2243 print Violation 2244 return 0
2245 2246 2247 2248 ## fixedgoals: a list of goals whose weights will not be adjusted 2249 ## delta: threshold for constraint, default to be 0 in fitting, e.g., the value of the selected action 2250 ## must be bigger than all other actions 2251 ## when generating possible path, delta is set to -.00000001, so that actions with equal utility are all 2252 ## possible actions for the character 2253 ## returns the number of violated constraints afer fitting
2254 - def satisfyConstraints(self,constraints,entity,fixedgoals=[], delta = 0,):
2255 origoals = entity.getGoals() 2256 2257 ## the goals we will play with, if not success in fitting, will set back to original setting 2258 adjgoals = copy.deepcopy(origoals) 2259 2260 removeList = [] 2261 for goal in adjgoals: 2262 if goal.key in fixedgoals: 2263 #if goal.entity[0] == 'wolf': 2264 # continue 2265 removeList.append(goal) 2266 for goal in removeList: 2267 adjgoals.remove(goal) 2268 2269 adjgoalKeys = [] 2270 for goal in adjgoals: 2271 adjgoalKeys.append(goal.toKey()) 2272 2273 n = len(adjgoals) 2274 ## construct the P matrix 2275 P = matrix (0.0,(n,n),tc = 'd') 2276 P [::n+1]+=2 2277 2278 ## construct the Q matrix 2279 Q = matrix (0.0, (n,1),tc = 'd') 2280 for i in range(n): 2281 Q[i] = entity.getGoalWeight(adjgoals[i])*(-2) 2282 2283 ## construct G,h 2284 h = [delta]*(len(constraints)+2*n) 2285 g = [[]]*n 2286 j = 0 2287 for constraint in constraints: 2288 for goal in constraint['slope']: 2289 if goal in adjgoalKeys: 2290 ## if goal['feature'] == 'alive': 2291 ## print 'alive is adjustable',goal 2292 i = adjgoalKeys.index(goal) 2293 if g[i] == []: 2294 g[i] = [-constraint['slope'][goal]] 2295 else: 2296 g[i].append(-constraint['slope'][goal]) 2297 else: 2298 for fullGoal in origoals: 2299 ## find out the corresponding goal 2300 if goal == fullGoal.toKey(): 2301 ## assume goals not entering the fitting process have high weight 2302 if goal['feature'] == 'alive': 2303 ## print 'alive set to 10',goal 2304 value = constraint['slope'][goal]*1000 2305 else: 2306 value = constraint['slope'][goal]*1000 2307 if fullGoal.direction == 'min': 2308 value = -1*value 2309 h[j]+= value 2310 #print goal,value 2311 break 2312 j=j+1 2313 2314 ## add inequations that each of the goal weight is in [-5 5] 2315 for i in range(n): 2316 for j in range(n): 2317 if j == i: 2318 g[j].append(1) 2319 else: 2320 g[j].append(0) 2321 2322 for i in range(n): 2323 for j in range(n): 2324 if j == i: 2325 g[j].append(-1) 2326 else: 2327 g[j].append(0) 2328 2329 for i in range (len(constraints),len(h)): 2330 index = i - len(constraints) -n 2331 if index >= 0: 2332 if string.find(adjgoals[index].key,'norm')>-1: 2333 ## all the norm related goals should have weight >=0 2334 h[i] = 0.0000001 2335 else: 2336 h[i] = 5 2337 else: 2338 h[i] = 5 2339 2340 G = matrix(g,tc='d') 2341 2342 h = matrix(h,tc='d') 2343 2344 res = None 2345 ## there is no solution 2346 try: 2347 res = qp(P,Q,G,h) 2348 except StandardError: 2349 print 'fitting result: StandardError' 2350 return -1 2351 2352 if not res['status']=='optimal': 2353 print 'fitting result: not optimal' 2354 return -1 2355 2356 2357 for i in range(len(adjgoals)): 2358 entity.setGoalWeight(adjgoals[i],res['x'][i],None) 2359 2360 for fullGoal in origoals: 2361 for i in range(len(fixedgoals)): 2362 ## find out the corresponding goal 2363 if fixedgoals[i] == fullGoal.key: 2364 if fixedgoals[i] == 'alive': 2365 entity.setGoalWeight(fullGoal,5,None) 2366 else: 2367 entity.setGoalWeight(fullGoal,5,None) 2368 break 2369 2370 2371 entity.normalizeGoals() 2372 print entity.name 2373 print entity.goals 2374 2375 Violation=0 2376 excludeList = [] 2377 notfitted = [] 2378 #for constraint in constraints: 2379 # actgoals = entity.getGoalVector()['total'].domain()[0] 2380 # actgoals.fill(constraint['plane'].keys()) 2381 # if actgoals*constraint['plane'] > delta: 2382 # ## if constraint is satisfied 2383 # continue 2384 # Violation += 1 2385 ## 2386 ## for goal in adjgoals: 2387 ## if constraint['slope'][goal.toKey()] == 0.0: 2388 ## excludeList.append(goal.name) 2389 ## 2390 ## if len(excludeList) == len(adjgoals): 2391 ## notfitted.append(constraint) 2392 ## continue 2393 2394 ## print 'number of violations that could not be fitted: ',len(notfitted) 2395 ## print 'number of violations after fitting: ',Violation 2396 2397 2398 #return Violation 2399 return 0
2400 2401 2402 2403 2404 2405 if __name__ == '__main__': 2406 import getopt 2407 import sys 2408 2409 try: 2410 import psyco 2411 psyco.full() 2412 except ImportError: 2413 print 'Unable to find psyco module for maximum speed' 2414 2415 script = None 2416 scenario = None 2417 society = None 2418 domain = None 2419 display = 'tk' 2420 debug = 0 2421 error = None 2422 agentClass = ThespianAgent ##this is the module 2423 multiagentClass = ThespianAgents 2424 2425 ThespianAgents.sceneID = '3' 2426 2427 try: 2428 optlist,args = getopt.getopt(sys.argv[1:],'hf:s:d:v', 2429 ['file=','shell=','domain=','society=', 2430 'debug=','help','version']) 2431 except getopt.error: 2432 error = 1 2433 optlist = [] 2434 args = [] 2435 2436 for option in optlist: 2437 if option[0] == '--file' or option[0] == '-f': 2438 script = option[1] 2439 elif option[0] == '--shell' or option[0] == '-s': 2440 display = option[1] 2441 elif option[0] == '--domain' or option[0] == '-d': 2442 domain = option[1] 2443 exec('import teamwork.examples.%s as classModule' % (domain)) 2444 # Convert any old-school hierarchies 2445 if isinstance(classModule.classHierarchy,dict): 2446 society = GenericSociety() 2447 society.importDict(classModule.classHierarchy) 2448 else: 2449 society = classModule.classHierarchy 2450 elif option[0] == '--society': 2451 society = option[1] 2452 elif option[0] == '--help' or option[0] == '-h': 2453 error = 1 2454 elif option[0] == '--debug': 2455 debug = int(option[1]) 2456 elif option[0] == '--version' or option[0] == '-v': 2457 print 'PsychSim %s' % (PsychShell.__VERSION__) 2458 sys.exit(0) 2459 else: 2460 error = 1 2461 2462 if len(args) > 0: 2463 if len(args) > 1: 2464 error = 1 2465 else: 2466 scenario = args[0] 2467 2468 if error: 2469 print 'PsychShell.py',\ 2470 '[--domain|-d <domain>]',\ 2471 '[--file|-f <script filename>]',\ 2472 '[--shell|-s tk|terminal]',\ 2473 '[--society <filename>]',\ 2474 '<scenario filename>' 2475 print 2476 print '--domain|-d\tIndicates the class path to the generic society definition' 2477 print '--society\tIndicates the file name containing the generic society' 2478 print '--file|-f\tIndicates the file containing a script of commands to execute' 2479 print '--shell|-s\tIf "tk", use GUI; if "terminal", use interactive text (default is "tk")' 2480 print '--version|-v\tPrints out version information' 2481 print '--help|-h\tPrints out this message' 2482 print 2483 sys.exit(-1) 2484 2485 if domain: 2486 pass 2487 else: 2488 domain = 'Thespian.RedRidingHoodClasses' 2489 exec('import teamwork.examples.%s as classModule' % (domain)) 2490 # Convert any old-school hierarchies 2491 if isinstance(classModule.classHierarchy,dict): 2492 society = GenericSociety() 2493 society.importDict(classModule.classHierarchy) 2494 else: 2495 society = classModule.classHierarchy 2496 2497 2498 2499 if display == 'tk': 2500 from teamwork.widgets.PsychGUI.Gui import * 2501 shell = GuiShell(scenario=scenario, 2502 classes=society, 2503 agentClass=agentClass, 2504 multiagentClass=multiagentClass, 2505 debug=debug) 2506 2507 2508 else: 2509 from teamwork.shell.TerminalShell import TerminalShell 2510 shell = TerminalShell(entities=scenario, 2511 classes=society, 2512 file=script, 2513 agentClass=agentClass, 2514 multiagentClass=multiagentClass, 2515 debug=debug) 2516 2517 if society and not domain: 2518 shell.loadSociety(society,overwrite=True) 2519 shell.mainloop() 2520