-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsir.py
100 lines (86 loc) · 3.2 KB
/
sir.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
__author__ = 'zoiloft'
# sir.py
import re, sys
debug = 0
facts = []
rules = (
( "(every|any|an|a) (.*) is (a|an) (.*)", lambda g: addFact(g,"1s3|3S1")),
( "(.*) is (a|an) (.*)", lambda g: addFact(g,"0m2|2M0")),
( "(.*) is (.*)", lambda g: addFact(g,"0e1|1e0")),
( "(every|any|an|a) (.*) owns (a|an) (.*)", lambda g: addFact(g,"1p3|3P1")),
( "(.*) owns (a|an) (.*)", lambda g: addFact(g,"0p2|2P0")),
( "(.*) owns (.*)", lambda g: addFact(g,"0p1|1P0")),
( "is (every|an|a) (.*) (a|an) (.*)", lambda g: getPath(g,"1e*s*3")),
( "is (.*) (a|an) (.*)", lambda g: getPath(g,"0e*ms*2")),
( "does (every|an|a) (.*) own (a|an) (.*)", lambda g: getPath(g,"1e*ms*ps*3")),
( "does any (.*) own (a|an) (.*)", lambda g: getPath(g,"0S*Me*ps*2")),
( "does (.*) own (a|an) (.*)", lambda g: getPath(g,"0e*ms*ps*2")),
( "dump", lambda g: dump() ),
( "debug", lambda g: toggleDebug() ),
( "quit", lambda g: sys.exit() ),
)
def addFact(grp, phrases) :
global facts
for p in phrases.split("|") :
f = (grp[int(p[0])], p[1], grp[int(p[2])])
if debug : print " adding fact", f
facts.append(f)
print " I understand"
def matchSent (sent) :
sent = re.sub(" *"," ",sent.strip().lower())
for pattern, action in rules :
match = re.match(pattern, sent)
if match :
action(match.groups())
return
def getPath (grp, rule) :
pattern = rule[1:-1]; start=grp[int(rule[0])]; stop=grp[int(rule[-1])]
ans = []
p = path(pattern, start, stop, ans=ans)
if debug : detail = "%s %s" % (pattern,ans)
else : detail = ""
if ans : print " Yes", detail
else : print " Not sure", detail
def path (pat, start, end, before={}, ans=[], sofar="", indent=" ") :
used = {}
used.update(before)
if debug : print indent,"path - ",start," to ",end
if len(indent) > 20 : return
for fact in facts :
if used.get(fact) : continue
a,rel,b = fact
if a != start : continue
sts = okSoFar(pat, sofar+rel)
if not sts : continue
used[fact] = 1
if b == end :
if sts == 2 : ans.append(sofar+rel)
else :
# find inner solutions recursively
path (pat, b, end, used, ans, sofar+rel, indent+" ")
def okSoFar (a, b) :
"return 1 for partial match, 2 for complete match"
ans = 2
while a :
if re.match("^%s$"%a, b) : return ans
if a[-1] == '*' : a = a[:-2]
else : a = a[:-1]
ans = 1
return 0
def toggleDebug () :
global debug
debug = not debug
def dump () :
for p,rel,q in facts : print " %-10s : %s : %s" % (p,rel,q)
def main () :
sys.stderr = sys.stdout
for file in sys.argv[1:] :
if file == '.' : return
lins = open(file).readlines()
for lin in lins :
print lin.strip()
matchSent (lin)
while 1 :
sent = raw_input("? ")
matchSent(sent)
if __name__ == "__main__" : main()