-
Notifications
You must be signed in to change notification settings - Fork 0
/
interpretTest.py
188 lines (165 loc) · 7.92 KB
/
interpretTest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
#!/usr/bin/python
import nltk
import re
#sent =['always not room1 and room2'] #ambiguous safety
#sent = ['if you are not in room1 and activating dig then go to room2'] #conditional
#sent = ['if you are not in room1 or in room2 then go to room2']
#sent = ['go to room1 and room2'] #ambiguous liveness
#sent = ['go to room1 and stay']
sent = ['group myGroup is room1, room2','if you are in any myGroup then do dig'] #region groups with 'any'
#sent = ['group myGroup is room1, room2','go to all myGroup'] #region groups with 'all'
#sent = ['mem1 is set on room2 and reset on beep'] #memory proposition
#sent = ['mem1 is toggled on beep'] #memory toggle
regions = ['room1','room2','room3']
actions = ['dig','beep']
sensors = ['door1','door2']
auxProps = ['mem1', 'mem2']
regionGroups = {}
sensorGroups = {}
spec = []
def main():
#Open CFG file
grammarFile = open('grammar1.fcfg')
grammarText = grammarFile.read()
#Add production rules for region names to our grammar string
for region in regions:
grammarText += '\nREGION[SEM=<'+region+'>] -> \''+region+'\''
#Add production rules for action names to our grammar string
for action in actions:
grammarText += '\nACTION[SEM=<'+action+'>] -> \''+action+'\''
#Add production rules for sensor names to our grammar string
for sensor in sensors:
grammarText += '\nSENSOR[SEM=<'+sensor+'>] -> \''+sensor+'\''
#Add production rules for auxilliary propositions to our grammar string
for prop in auxProps:
grammarText += '\nAUXPROP[SEM=<'+prop+'>] -> \''+prop+'\''
#Generate regular expression to match sentences defining region groups
#Resultant expression is: 'group (\w+) is (?:(region1),? ?|(region2),? ?|(region3),? ?)+'
groupDefPattern = 'group (\w+) is (?:('
groupDefPattern += '),? ?|('.join(regions)
groupDefPattern += '),? ?)+'
r_groupDef = re.compile(groupDefPattern)
#Generate regular expression to match sentences defining sensor groups
#Resultant expression is: 'group (\w+) is (?:(region1),? ?|(region2),? ?|(region3),? ?)+'
sensorGroupDefPattern = ' sensor group (\w+) is (?:('
sensorGroupDefPattern += '),? ?|('.join(sensors)
sensorGroupDefPattern += '),? ?)+'
r_sensorGroupDef = re.compile(sensorGroupDefPattern)
#Generate NLTK feature grammar object from grammar string
grammar = nltk.grammar.parse_fcfg(grammarText)
for inputString in sent:
print inputString
#Examine input to find any region group definitons
m_groupDef = r_groupDef.match(inputString)
if m_groupDef:
#Add semantics of group to our grammar string
groupName = m_groupDef.groups()[0]
grammarText += '\nGROUP[SEM=<' + groupName + '>] -> \'' + groupName + '\''
#Add specified regions to our dictionary of region groups
regionGroups[groupName] = filter(lambda x: x != None, m_groupDef.groups()[1:])
print 'Groups updated: ' + str(regionGroups)
#Re-compile grammar
grammar = nltk.grammar.parse_fcfg(grammarText)
continue
#Examine input to find any sensor group definitions
m_sensorGroupDef = r_sensorGroupDef.match(inputString)
if m_sensorGroupDef:
#Add semantics of group to our grammar string
groupName = m_sensorGroupDef.groups()[0]
grammarText += '\nSENSORGROUP[SEM=<' + groupName + '>] -> \'' + groupName + '\''
#Add specified sensors to out dictionary of sensor groups
sensorGroups[groupName] = filter(lambda x: x != None, m_sensorGroupDef.groups()[1:])
print 'Sensor groups updated: ' + str(sensorGroups)
#Re-compile grammar
grammar = nltk.grammar.parse_fcfg(grammarText)
continue
#Parse input string using grammar
result = nltk.sem.batch_interpret([inputString], grammar, u'SEM', 2)[0]
nTrees = 0;
for (syntree, semstring) in result:
if spec.count(semstring) != 0:
continue
spec.append(semstring)
nTrees += 1
#Expand 'stay' phrases
semstring = parseStay(str(semstring))
#Expand region groups, 'any' and 'all'
semstring = parseGroupAny(semstring, syntree)
semstring = parseGroupAll(semstring, syntree)
#Expand memory propositions
semstring = parseMemory(semstring, syntree)
semstring = parseToggle(semstring, syntree)
print
print 'Syntax tree ' + str(nTrees) + ': '
print syntree.pprint()
print
print 'Formula result ' + str(nTrees) + ': '
print semstring
print
if nTrees == 0:
print 'No valid parse found!'
def parseStay(semstring):
def appendStayClause(ind):
if ind == len(regions) - 1:
return 'Iff(Next('+regions[ind]+'),'+regions[ind]+')'
else:
return 'And(Iff(Next('+regions[ind]+'),'+regions[ind]+'),'+appendStayClause(ind+1)+')'
if semstring.find('$stay') != -1:
stay = appendStayClause(0)
return semstring.replace('$stay',stay)
else:
return semstring
def parseGroupAll(semstring, syntree):
def appendAllClause(semstring, ind, groupRegions):
if ind == len(groupRegions) - 1:
return re.sub('\$All\(\w+\)',groupRegions[ind],semstring)
else:
return 'And('+re.sub('\$All\(\w+\)',groupRegions[ind],semstring)+','+appendAllClause(semstring, ind+1, groupRegions)+')'
if semstring.find('$All') == -1:
return semstring
else:
groupName = re.search('\$All\((\w+)\)',semstring).groups()[0]
return appendAllClause(semstring, 0, regionGroups[groupName])
def parseGroupAny(semstring, syntree):
def appendAnyClause(ind, groupRegions):
if ind == len(groupRegions) - 1:
return groupRegions[ind]
else:
return 'Or('+groupRegions[ind]+','+appendAnyClause(ind+1, groupRegions)+')'
if semstring.find('$Any') != -1:
groupName = re.search('\$Any\((\w+)\)',semstring).groups()[0]
groupRegions = regionGroups[groupName]
anyClause = appendAnyClause(0, groupRegions)
return re.sub('\$Any\('+groupName+'\)', anyClause, semstring)
else:
return semstring
def parseMemory(semstring, syntree):
if semstring.find('$Mem') != -1:
m_Mem = re.search('\$Mem\((.*),(.*),(.*)\)',semstring)
phi_m = m_Mem.groups()[0]
phi_s = m_Mem.groups()[1]
phi_r = m_Mem.groups()[2]
setClause = 'Glob(Imp(And('+phi_s+',Not('+phi_r+')),Next('+phi_m+')))'
resetClause = 'Glob(Imp('+phi_r+',Not(Next('+phi_m+'))))'
holdOnClause = 'Glob(Imp(And('+phi_m+',Not('+phi_r+')),Next('+phi_m+')))'
holdOffClause = 'Glob(Imp(And(Not('+phi_m+'),Not('+phi_s+')),Not(Next('+phi_m+'))))'
if phi_r == 'false':
#Generate memory statement with no reset
semstring = 'And('+setClause+','+holdOnClause+')'
else:
#Generate memory statement with reset
semstring = 'And('+setClause+',And('+resetClause+',And('+holdOnClause+','+holdOffClause+')))'
return semstring
def parseToggle(semstring, syntree):
if semstring.find('$Tog') != -1:
m_Tog = re.search('\$Tog\((.*),(.*)\)',semstring)
phi_m = m_Tog.groups()[0]
phi_t = m_Tog.groups()[1]
turnOffClause = 'Glob(Imp(And('+phi_m+','+phi_t+'),Not(Next('+phi_m+'))))'
turnOnClause = 'Glob(Imp(And(Not('+phi_m+'),'+phi_t+'),Next('+phi_m+')))'
holdOnClause = 'Glob(Imp(And('+phi_m+',Not('+phi_t+')),Next('+phi_m+')))'
holdOffClause = 'Glob(Imp(And(Not('+phi_m+'),Not('+phi_t+')),Not(Next('+phi_m+'))))'
semstring = 'And('+turnOnClause+',And('+turnOffClause+',And('+holdOnClause+','+holdOffClause+')))'
return semstring
if __name__ == "__main__":
main()