8 Match
= collections
.namedtuple('Match', 'text, rule, bindings')
21 halt_words
= 'quit halt exit stop'.split()
23 # def read_rules(rules_file):
24 # with open(rules_file) as f:
25 # rules = [{'pattern': r['pattern'].split(),
26 # 'responses': [t.split() for t in r['responses']]}
27 # for r in yaml.safe_load(f)]
30 def read_rules(rules_file
):
31 with
open(rules_file
) as f
:
32 rules
= [{'pattern': r
['pattern'].split(),
33 'responses': [t
.split() for t
in r
['responses']]}
34 for r
in json
.load(f
)]
42 return [(item
[:i
], item
[i
:]) for i
in range(len(item
)+1)]
44 def match(text
, rule
):
45 return all_matches([Match(text
, rule
, {})])
47 def all_matches(matches
):
50 # print(matches, successes)
53 if successful_match(current
):
54 successes
+= [current
.bindings
]
56 new_matches
= match_item(current
.text
, current
.rule
, current
.bindings
)
57 matches
= matches
[1:] + new_matches
60 def successful_match(match
):
61 return match
.text
== [] and match
.rule
== []
63 def match_item(text
, rule
, bindings
):
67 # already seen this variable
68 if text
[:len(bindings
[r0
])] == bindings
[r0
]:
69 return [Match(text
[(len(bindings
[r0
])):], rule
[1:], bindings
)]
73 # not seen this variable yet
75 for pre
, suf
in splits(text
):
76 new_bindings
= bindings
.copy()
77 new_bindings
[r0
] = pre
78 matches
+= [Match(suf
, rule
[1:], new_bindings
)]
80 elif text
and text
[0] == r0
:
81 return [Match(text
[1:], rule
[1:], bindings
)]
85 def candidate_rules(rules
, comment
):
86 return [(rule
, bindings
)
88 for bindings
in match(comment
, rule
['pattern'])]
91 def fill(response
, bindings
):
96 filled_response
+= bindings
[w
]
98 filled_response
+= ['MISSING']
100 filled_response
+= [w
]
101 return filled_response
104 def pronoun_person_swap(bindings
):
108 if w
in pronoun_swaps
:
109 sw
+= [pronoun_swaps
[w
]]
114 return {var
: swapped(bindings
[var
]) for var
in bindings
}
116 def respond(rule
, bindings
):
117 return fill(random
.choice(rule
['responses']), bindings
)
120 def eliza_loop(rules
):
121 print("Hello. I'm Eliza. What seems to be the problem?")
124 if c
.strip() in halt_words
: break
126 rule
, bindings
= candidate_rules(rules
, comment
)[0]
127 swapped_bindings
= pronoun_person_swap(bindings
)
128 print(' '.join(respond(rule
, swapped_bindings
)))
131 all_rules
= read_rules('rules.json')
132 eliza_loop(all_rules
)