1 __author__ = 'David V. Pynadath <pynadath@isi.edu>'
2 """Class definition of messages"""
3
4 import string
5 from types import *
6 from teamwork.math.Interval import Interval
7 from teamwork.action.PsychActions import *
8
9 from teamwork.messages.PsychMessage import *
10
11
13 fields = {
14
15 'actor':{},'sender':{},
16 'object':{},'receiver':{},
17
18 'type':{},'command':{},
19
20 'factors':{},'performative':{},'force':{},
21 '_observed':{},'_unobserved':{},
22
23 'sact_type':{},
24 'attitude':{'pos_face':0.0,'neg_face':0.0},
25 'addressee':{},
26 }
27 acceptString = 'accept'
28 rejectString = 'reject'
29
31 if isinstance(arg,str):
32 Message.__init__(self)
33
34
35 try:
36
37 if string.find(arg,',')>-1:
38 try:
39 sender,addressee, sact_type, formality,politeness,detail,emphasis, factors = string.split(arg,',')
40 self['attitude'] = {'formality':float(formality),'politeness':float(politeness),\
41 'detail':float(detail),'emphasis':float(emphasis)}
42 except:
43 try:
44 sender,addressee, sact_type, formality, politeness,factors = string.split(arg,',')
45 self['attitude'] = {'formality':float(formality),'politeness':float(politeness)}
46 except:
47 try:
48 sender,addressee, sact_type, mtype, factors = string.split(arg,',')
49 self['type'] = string.strip(mtype)
50 except:
51 try:
52 sender,addressee, sact_type, factors = string.split(arg,',')
53 except:
54
55 raise arg
56
57 self['actor'] = self['sender'] = string.strip(sender)
58
59 if string.find(addressee,'+')>-1:
60 addrs = string.split(string.strip(addressee),'+')
61 addressee = []
62 for addr in addrs:
63 addressee.append(addr)
64 self['addressee'] = addressee
65 else:
66 self['addressee'] = [string.strip(addressee)]
67
68 self['object']=None
69
70 self['sact_type'] = string.strip(sact_type)
71
72 self.extractFromString(string.strip(factors))
73 elif not arg == '':
74 self.extractFromString(arg)
75 except:
76
77 raise arg
78
79 else:
80 dict.__init__(self,arg)
81
82
83 if not self['type'] or self['type'] == 'wait':
84 if self['sact_type']:
85 if not self['sact_type'] in ['inform','request','accept','reject','message']:
86 self['type'] = self['sact_type']
87 else:
88 self['type'] = '_message'
89 else:
90 self['type'] = '_message'
91
92 if self.has_key('sender') and not self.has_key('actor'):
93 self['actor'] = self['sender']
94 elif not self.has_key('sender') and self.has_key('actor'):
95 self['sender'] = self['actor']
96
97
98
99
100
101
102
103 if not self.has_key('addressee') or self['addressee'] == None or self['addressee'] == []:
104 if self.has_key('object'):
105 self['addressee'] = [self['object']]
106 else:
107
108 self['addressee'] = None
109
110
111
112 self['object'] = None
113
114
115
116 if not self.has_key('force'):
117 self['force'] = {}
118
119 if not self.has_key('performative'):
120 self['performative'] = 'tell'
121
122 if not self.has_key('attitude'):
123 self['attitude'] = {'formality':0.0,'politeness':0.0,'detail':0.0,'emphasis':0.0}
124
125 for key in ['formality','politeness','detail','emphasis']:
126 if not self['attitude'].has_key(key):
127 self['attitude'][key]=0.0
128
129
130 if not self.has_key('sact_type'):
131 self['sact_type'] = 'wait'
132
133
134
135
137 """The string representation of a non-command message is:
138 <key11>:<key12>:...:<key1n>=<value1>;<key21>:<key22>:...:<key2m>=<value2>;...
139 e.g., entities:Psyops:state:power=0.7;entities:Paramilitary:entities:Psyops:state:power=0.7
140 e.g., message Psyops Paramilitary entities:Psyops:policy:observation depth 3 actor Paramilitary type violence object UrbanPoor violence-to-Paramilitary
141 For commands, the syntax is
142 'command;<key1>=<val1>;<key2>=<val2>;...', where the usual keys
143 are 'object' (e.g., 'opponent') and 'type' (e.g., 'violence').
144 This same format is expected by the constructor and returned by
145 the string converter."""
146
147 self['factors'] = []
148 factors = string.split(str,';')
149 if factors[0] == 'command':
150 self['command'] = {}
151 for factor in factors[1:]:
152 key,value = string.split(factor,'=')
153 self['command'][key] = value
154 else:
155 self['command'] = None
156 for factor in factors:
157 factor = string.strip(factor)
158 if factor == self.acceptString:
159 self.forceAccept()
160 elif factor == self.rejectString:
161 self.forceReject()
162 else:
163 relation = '='
164 pair = string.split(factor,relation)
165 if len(pair) == 1:
166 relation = '>>'
167 pair = string.split(factor,relation)
168 lhs = string.split(string.strip(pair[0]),':')
169 rhs = string.split(string.strip(pair[1]),':')
170 factor = {'lhs':lhs,'rhs':rhs,'relation':relation,
171 'topic':'state'}
172 if len(rhs) == 1:
173 try:
174 value = float(pair[1])
175 except ValueError:
176 value = pair[1]
177 factor['value'] = value
178 elif len(rhs) == 2:
179 try:
180 lo = float(rhs[0])
181 hi = float(rhs[1])
182 factor['value'] = Interval(lo,hi)
183 except ValueError:
184 pass
185 self['factors'].append(factor)
186
187
188
190 return TactLangMessage(self)
191
193 rep = ''
194
195 if self['actor']:
196
197 if type(self['actor']) is ListType:
198 for actor in self['actor']:
199 if not type(actor) is StringType and actor != None:
200 actor = actor.name
201 rep += '; %s' % (actor)
202 else:
203 if not type(self['actor']) is StringType and self['actor']:
204 actor = self['actor'].name
205 rep += '; %s' % (actor)
206 elif type(self['actor']) is StringType:
207 actor = self['actor']
208 rep += '; %s' % (actor)
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226 if self['addressee']:
227
228 if type(self['addressee']) is ListType:
229 for actor in self['addressee']:
230 if not type(actor) is StringType and actor != None:
231 actor = actor.name
232 rep += '; %s' % (actor)
233 else:
234 if not type(self['addressee']) is StringType and self['addressee']:
235 addressee = self['addressee'].name
236 rep += '; %s' % (addressee)
237 elif type(self['addressee']) is StringType:
238 addressee = self['addressee']
239 rep += '; %s' % (addressee)
240
241
242 rep += '; %s' % (self['sact_type'])
243
244 rep += '; %s' % (self['type'])
245
246
247
248
249
250
251
252 if self['factors']:
253 for factor in self['factors']:
254
255 if factor['topic'] == 'state':
256 substr = string.join(factor['lhs'],':')
257 try:
258 value = string.join(factor['rhs'],':')
259 except KeyError:
260 value = str(factor['value'])
261 rep += '; %s%s%s' % (substr,factor['relation'],value)
262 elif factor['topic'] == 'observation':
263 rep += '; %s %s' % (factor['actor'],str(factor['action']))
264
265
266 return rep[1:]
267
269 """Returns a more user-friendly string rep of this message"""
270 rep = ''
271 for factor in self['factors']:
272 if factor['topic'] == 'state':
273 substr = ''
274 if factor['lhs'][0] == 'entities':
275 entity = factor['lhs'][1]
276 if factor['lhs'][2] == 'state':
277 feature = factor['lhs'][3]
278 substr = 'the %s of %s' % (feature,entity)
279 try:
280 value = '%4.2f' % (float(factor['rhs'][0]))
281 except KeyError:
282 value = '%4.2f' % (factor['value'])
283 if len(substr) == 0:
284
285 substr = string.join(factor['lhs'],':')
286 value = string.join(factor['rhs'],':')
287 rep += '; %s %s %s' % (substr,factor['relation'],value)
288 elif factor['topic'] == 'observation':
289 rep += '; %s chose %s' % (factor['actor'],
290 str(factor['action']))
291 if self.mustAccept():
292 rep += ' (force to accept)'
293 elif self.mustReject():
294 rep += ' (force to reject)'
295 return rep[2:]
296