Got eliza working
[eliza.git] / eliza.ipynb
1 {
2 "cells": [
3 {
4 "cell_type": "code",
5 "execution_count": 100,
6 "metadata": {
7 "collapsed": true
8 },
9 "outputs": [],
10 "source": [
11 "import yaml\n",
12 "import collections\n",
13 "import random"
14 ]
15 },
16 {
17 "cell_type": "code",
18 "execution_count": 84,
19 "metadata": {
20 "collapsed": false
21 },
22 "outputs": [],
23 "source": [
24 "Match = collections.namedtuple('Match', 'text, rule, bindings')"
25 ]
26 },
27 {
28 "cell_type": "code",
29 "execution_count": 169,
30 "metadata": {
31 "collapsed": false
32 },
33 "outputs": [
34 {
35 "data": {
36 "text/plain": [
37 "[{'pattern': ['?X', 'hello', '?Y'],\n",
38 " 'responses': [['how',\n",
39 " 'do',\n",
40 " 'you',\n",
41 " 'do.',\n",
42 " 'please',\n",
43 " 'state',\n",
44 " 'your',\n",
45 " 'problem']]},\n",
46 " {'pattern': ['?X', 'computer', '?Y'],\n",
47 " 'responses': [['do', 'computers', 'worry', 'you'],\n",
48 " ['what', 'do', 'you', 'think', 'about', 'machines'],\n",
49 " ['why', 'do', 'you', 'mention', 'computers'],\n",
50 " ['what',\n",
51 " 'do',\n",
52 " 'you',\n",
53 " 'think',\n",
54 " 'machines',\n",
55 " 'have',\n",
56 " 'to',\n",
57 " 'do',\n",
58 " 'with',\n",
59 " 'your',\n",
60 " 'problem']]},\n",
61 " {'pattern': ['?X', 'name', '?Y'],\n",
62 " 'responses': [['i', 'am', 'not', 'interested', 'in', 'names']]},\n",
63 " {'pattern': ['?X', 'sorry', '?Y'],\n",
64 " 'responses': [['please', \"don't\", 'apologize'],\n",
65 " ['apologies', 'are', 'not', 'necessary'],\n",
66 " ['what', 'feelings', 'do', 'you', 'have', 'when', 'you', 'apologize']]},\n",
67 " {'pattern': ['?X', 'i', 'remember', '?Y'],\n",
68 " 'responses': [['do', 'you', 'often', 'think', 'of', '?Y'],\n",
69 " ['does', 'thinking', 'of', '?Y', 'bring', 'anything', 'else', 'to', 'mind'],\n",
70 " ['what', 'else', 'do', 'you', 'remember?'],\n",
71 " ['why', 'do', 'you', 'recall', '?Y', 'right', 'now'],\n",
72 " ['what',\n",
73 " 'in',\n",
74 " 'this',\n",
75 " 'present',\n",
76 " 'situation',\n",
77 " 'reminds',\n",
78 " 'you',\n",
79 " 'of',\n",
80 " '?Y'],\n",
81 " ['what', 'is', 'the', 'connection', 'between', 'me', 'and', '?Y']]},\n",
82 " {'pattern': ['?X', 'do', 'you', 'remember', '?Y'],\n",
83 " 'responses': [['did', 'you', 'think', 'i', 'would', 'forget', '?Y'],\n",
84 " ['why', 'do', 'you', 'think', 'i', 'should', 'recall', '?Y'],\n",
85 " ['what', 'about', '?Y'],\n",
86 " ['you', 'mentioned', '?Y']]},\n",
87 " {'pattern': ['?X', 'if', '?Y'],\n",
88 " 'responses': [['do',\n",
89 " 'you',\n",
90 " 'really',\n",
91 " 'think',\n",
92 " 'it',\n",
93 " 'is',\n",
94 " 'likely',\n",
95 " 'that',\n",
96 " '?Y'],\n",
97 " ['do', 'you', 'wish', 'that', '?Y'],\n",
98 " ['what', 'do', 'you', 'think', 'about', '?Y'],\n",
99 " ['really', '--', 'if', '?Y']]},\n",
100 " {'pattern': ['?X', 'i', 'dreamt', '?Y'],\n",
101 " 'responses': [['really', '--', '?Y'],\n",
102 " ['have',\n",
103 " 'you',\n",
104 " 'ever',\n",
105 " 'fantasized',\n",
106 " '?Y',\n",
107 " 'while',\n",
108 " 'you',\n",
109 " 'were',\n",
110 " 'awake'],\n",
111 " ['have', 'you', 'dreamt', '?Y', 'before']]},\n",
112 " {'pattern': ['?X', 'i', 'dreamed', '?Y'],\n",
113 " 'responses': [['really', '--', '?Y'],\n",
114 " ['have',\n",
115 " 'you',\n",
116 " 'ever',\n",
117 " 'fantasized',\n",
118 " '?Y',\n",
119 " 'while',\n",
120 " 'you',\n",
121 " 'were',\n",
122 " 'awake'],\n",
123 " ['have', 'you', 'dreamed', '?Y', 'before']]},\n",
124 " {'pattern': ['?X', 'dream', '?Y'],\n",
125 " 'responses': [['what', 'does', 'this', 'dream', 'suggest', 'to', 'you'],\n",
126 " ['do', 'you', 'dream', 'often'],\n",
127 " ['what', 'persons', 'appear', 'in', 'your', 'dreams'],\n",
128 " [\"don't\",\n",
129 " 'you',\n",
130 " 'believe',\n",
131 " 'that',\n",
132 " 'dream',\n",
133 " 'has',\n",
134 " 'to',\n",
135 " 'do',\n",
136 " 'with',\n",
137 " 'your',\n",
138 " 'problem']]},\n",
139 " {'pattern': ['?X', 'my', 'mother', '?Y'],\n",
140 " 'responses': [['who', 'else', 'is', 'in', 'your', 'family', '?Y'],\n",
141 " ['tell', 'me', 'more', 'about', 'your', 'family']]},\n",
142 " {'pattern': ['?X', 'my', 'father', '?Y'],\n",
143 " 'responses': [['your', 'father'],\n",
144 " ['does', 'he', 'influence', 'you', 'strongly'],\n",
145 " ['what',\n",
146 " 'else',\n",
147 " 'comes',\n",
148 " 'to',\n",
149 " 'mind',\n",
150 " 'when',\n",
151 " 'you',\n",
152 " 'think',\n",
153 " 'of',\n",
154 " 'your',\n",
155 " 'father']]},\n",
156 " {'pattern': ['?X', 'i', 'want', '?Y'],\n",
157 " 'responses': [['what', 'would', 'it', 'mean', 'if', 'you', 'got', '?Y'],\n",
158 " ['why', 'do', 'you', 'want', '?Y'],\n",
159 " ['suppose', 'you', 'got', '?Y', 'soon']]},\n",
160 " {'pattern': ['?X', 'i', 'am', 'glad', '?Y'],\n",
161 " 'responses': [['how', 'have', 'i', 'helped', 'you', 'to', 'be', '?Y'],\n",
162 " ['what', 'makes', 'you', 'happy', 'just', 'now'],\n",
163 " ['can', 'you', 'explain', 'why', 'you', 'are', 'suddenly', '?Y']]},\n",
164 " {'pattern': ['?X', 'i', 'am', 'happy', '?Y'],\n",
165 " 'responses': [['how', 'have', 'i', 'helped', 'you', 'to', 'be', '?Y'],\n",
166 " ['what', 'makes', 'you', 'glad', 'just', 'now'],\n",
167 " ['can', 'you', 'explain', 'why', 'you', 'are', 'suddenly', '?Y']]},\n",
168 " {'pattern': ['?X', 'i', 'am', 'sad', '?Y'],\n",
169 " 'responses': [['i', 'am', 'sorry', 'to', 'hear', 'you', 'are', 'depressed'],\n",
170 " [\"i'm\", 'sure', \"it's\", 'not', 'pleasant', 'to', 'be', 'sad']]},\n",
171 " {'pattern': ['?X', 'i', 'am', 'unhappy', '?Y'],\n",
172 " 'responses': [['i', 'am', 'sorry', 'to', 'hear', 'you', 'are', 'depressed'],\n",
173 " [\"i'm\", 'sure', \"it's\", 'not', 'pleasant', 'to', 'be', 'unhappy']]},\n",
174 " {'pattern': ['?X', 'are', 'like', '?Y'],\n",
175 " 'responses': [['what',\n",
176 " 'resemblence',\n",
177 " 'do',\n",
178 " 'you',\n",
179 " 'see',\n",
180 " 'between',\n",
181 " '?X',\n",
182 " 'and',\n",
183 " '?Y']]},\n",
184 " {'pattern': ['?X', 'is', 'like', '?Y'],\n",
185 " 'responses': [['in',\n",
186 " 'what',\n",
187 " 'way',\n",
188 " 'is',\n",
189 " 'it',\n",
190 " 'that',\n",
191 " '?X',\n",
192 " 'is',\n",
193 " 'like',\n",
194 " '?Y'],\n",
195 " ['what', 'resemblence', 'do', 'you', 'see'],\n",
196 " ['could', 'there', 'really', 'be', 'some', 'connection'],\n",
197 " ['how']]},\n",
198 " {'pattern': ['?X', 'alike', '?Y'],\n",
199 " 'responses': [['in', 'what', 'way'],\n",
200 " ['what', 'similarities', 'are', 'there']]},\n",
201 " {'pattern': ['?X', 'same', '?Y'],\n",
202 " 'responses': [['what', 'other', 'connections', 'do', 'you', 'see']]},\n",
203 " {'pattern': ['?X', 'i', 'was', '?Y'],\n",
204 " 'responses': [['were', 'you', 'really'],\n",
205 " ['perhaps', 'i', 'already', 'knew', 'you', 'were', '?Y'],\n",
206 " ['why', 'do', 'you', 'tell', 'me', 'you', 'were', '?Y', 'now']]},\n",
207 " {'pattern': ['?X', 'was', 'i', '?Y'],\n",
208 " 'responses': [['what', 'if', 'you', 'were', '?Y'],\n",
209 " ['do', 'you', 'think', 'you', 'were', '?Y'],\n",
210 " ['what', 'would', 'it', 'mean', 'if', 'you', 'were', '?Y']]},\n",
211 " {'pattern': ['?X', 'i', 'am', '?Y'],\n",
212 " 'responses': [['in', 'what', 'way', 'are', 'you', '?Y'],\n",
213 " ['do', 'you', 'want', 'to', 'be', '?Y']]},\n",
214 " {'pattern': ['?X', 'am', 'i', '?Y'],\n",
215 " 'responses': [['do', 'you', 'believe', 'you', 'are', '?Y'],\n",
216 " ['would', 'you', 'want', 'to', 'be', '?Y'],\n",
217 " ['you', 'wish', 'i', 'would', 'tell', 'you', 'you', 'are', '?Y'],\n",
218 " ['what', 'would', 'it', 'mean', 'if', 'you', 'were', '?Y']]},\n",
219 " {'pattern': ['?X', 'am', '?Y'],\n",
220 " 'responses': [['why', 'do', 'you', 'say', '\"am\"'],\n",
221 " ['i', \"don't\", 'understand', 'that']]},\n",
222 " {'pattern': ['?X', 'are', 'you', '?Y'],\n",
223 " 'responses': [['why',\n",
224 " 'are',\n",
225 " 'you',\n",
226 " 'interested',\n",
227 " 'in',\n",
228 " 'whether',\n",
229 " 'i',\n",
230 " 'am',\n",
231 " '?Y',\n",
232 " 'or',\n",
233 " 'not'],\n",
234 " ['would', 'you', 'prefer', 'it', 'if', 'i', \"weren't\", '?Y'],\n",
235 " ['perhaps', 'i', 'am', '?Y', 'in', 'your', 'fantasies']]},\n",
236 " {'pattern': ['?X', 'you', 'are', '?Y'],\n",
237 " 'responses': [['what', 'makes', 'you', 'think', 'i', 'am', '?Y']]},\n",
238 " {'pattern': ['?X', 'because', '?Y'],\n",
239 " 'responses': [['is', 'that', 'the', 'real', 'reason'],\n",
240 " ['what', 'other', 'reason', 'might', 'there', 'be'],\n",
241 " ['does', 'that', 'reason', 'seem', 'to', 'explain', 'anything', 'else']]},\n",
242 " {'pattern': ['?X', 'were', 'you', '?Y'],\n",
243 " 'responses': [['perhaps', 'i', 'was', '?Y'],\n",
244 " ['what', 'do', 'you', 'think'],\n",
245 " ['what', 'if', 'i', 'had', 'been', '?Y']]},\n",
246 " {'pattern': ['?X', 'i', \"can't\", '?Y'],\n",
247 " 'responses': [['maybe', 'you', 'could', '?Y', 'now'],\n",
248 " ['what', 'if', 'you', 'could', '?Y']]},\n",
249 " {'pattern': ['?X', 'i', 'feel', '?Y'],\n",
250 " 'responses': [['do', 'you', 'often', 'feel', '?Y']]},\n",
251 " {'pattern': ['?X', 'i', 'felt', '?Y'],\n",
252 " 'responses': [['what', 'other', 'feelings', 'do', 'you', 'have']]},\n",
253 " {'pattern': ['?X', 'i', '?Y', 'you', '?Z'],\n",
254 " 'responses': [['perhaps',\n",
255 " 'in',\n",
256 " 'your',\n",
257 " 'fantasies',\n",
258 " 'we',\n",
259 " '?Y',\n",
260 " 'each',\n",
261 " 'other']]},\n",
262 " {'pattern': ['?X', 'why', \"don't\", 'you', '?Y'],\n",
263 " 'responses': [['should', 'you', '?Y', 'yourself'],\n",
264 " ['do', 'you', 'believe', 'i', \"don't\", '?Y'],\n",
265 " ['perhaps', 'i', 'will', '?Y', 'in', 'good', 'time']]},\n",
266 " {'pattern': ['?X', 'yes', '?Y'],\n",
267 " 'responses': [['you', 'seem', 'quite', 'positive'],\n",
268 " ['you', 'are', 'sure'],\n",
269 " ['i', 'understand']]},\n",
270 " {'pattern': ['?X', 'no', '?Y'],\n",
271 " 'responses': [['why', 'not'],\n",
272 " ['you', 'are', 'being', 'a', 'bit', 'negative'],\n",
273 " ['are', 'you', 'saying', '\"no\"', 'just', 'to', 'be', 'negative']]},\n",
274 " {'pattern': ['?X', 'someone', '?Y'],\n",
275 " 'responses': [['can', 'you', 'be', 'more', 'specific']]},\n",
276 " {'pattern': ['?X', 'everyone', '?Y'],\n",
277 " 'responses': [['surely', 'not', 'everyone'],\n",
278 " ['can', 'you', 'think', 'of', 'anyone', 'in', 'particular'],\n",
279 " ['who', 'for', 'example'],\n",
280 " ['you', 'are', 'thinking', 'of', 'a', 'special', 'person']]},\n",
281 " {'pattern': ['?X', 'always', '?Y'],\n",
282 " 'responses': [['can', 'you', 'think', 'of', 'a', 'specific', 'example'],\n",
283 " ['when'],\n",
284 " ['what', 'incident', 'are', 'you', 'thinking', 'of'],\n",
285 " ['really', '--', 'always']]},\n",
286 " {'pattern': ['?X', 'what', '?Y'],\n",
287 " 'responses': [['why', 'do', 'you', 'ask'],\n",
288 " ['does', 'that', 'question', 'interest', 'you'],\n",
289 " ['what', 'is', 'it', 'you', 'really', 'want', 'to', 'know'],\n",
290 " ['what', 'do', 'you', 'think'],\n",
291 " ['what', 'comes', 'to', 'your', 'mind', 'when', 'you', 'ask', 'that']]},\n",
292 " {'pattern': ['?X', 'perhaps', '?Y'],\n",
293 " 'responses': [['you', 'do', 'not', 'seem', 'quite', 'certain']]},\n",
294 " {'pattern': ['?X', 'are', '?Y'],\n",
295 " 'responses': [['do', 'you', 'think', 'they', 'might', 'not', 'be', '?Y'],\n",
296 " ['possibly', 'they', 'are', '?Y']]},\n",
297 " {'pattern': ['?X'],\n",
298 " 'responses': [['very', 'interesting'],\n",
299 " ['i', 'am', 'not', 'sure', 'i', 'understand', 'you', 'fully'],\n",
300 " ['what', 'does', 'that', 'suggest', 'to', 'you'],\n",
301 " ['please', 'continue'],\n",
302 " ['go', 'on'],\n",
303 " ['do',\n",
304 " 'you',\n",
305 " 'feel',\n",
306 " 'strongly',\n",
307 " 'about',\n",
308 " 'discussing',\n",
309 " 'such',\n",
310 " 'things']]}]"
311 ]
312 },
313 "execution_count": 169,
314 "metadata": {},
315 "output_type": "execute_result"
316 }
317 ],
318 "source": [
319 "def read_rules(rules_file):\n",
320 " with open(rules_file) as f:\n",
321 " rules = [{'pattern': r['pattern'].split(),\n",
322 " 'responses': [t.split() for t in r['responses']]}\n",
323 " for r in yaml.load(f)]\n",
324 " return rules\n",
325 "\n",
326 "all_rules = read_rules('rules.yaml')\n",
327 "all_rules"
328 ]
329 },
330 {
331 "cell_type": "code",
332 "execution_count": 4,
333 "metadata": {
334 "collapsed": false
335 },
336 "outputs": [
337 {
338 "name": "stdout",
339 "output_type": "stream",
340 "text": [
341 "> tom dick harry\n"
342 ]
343 },
344 {
345 "data": {
346 "text/plain": [
347 "['tom', 'dick', 'harry']"
348 ]
349 },
350 "execution_count": 4,
351 "metadata": {},
352 "output_type": "execute_result"
353 }
354 ],
355 "source": [
356 "i = input(\"> \")\n",
357 "i.split()"
358 ]
359 },
360 {
361 "cell_type": "code",
362 "execution_count": 102,
363 "metadata": {
364 "collapsed": true
365 },
366 "outputs": [],
367 "source": [
368 "def match(text, rule):\n",
369 " return all_matches([Match(text, rule, {})])"
370 ]
371 },
372 {
373 "cell_type": "code",
374 "execution_count": 240,
375 "metadata": {
376 "collapsed": true
377 },
378 "outputs": [],
379 "source": [
380 "def all_matches(matches):\n",
381 " successes = []\n",
382 " while matches:\n",
383 " # print(matches, successes)\n",
384 " current = matches[0]\n",
385 " new_matches = []\n",
386 " if successful_match(current):\n",
387 " successes += [current.bindings]\n",
388 " elif current.rule:\n",
389 " new_matches = match_item(current.text, current.rule, current.bindings)\n",
390 " matches = matches[1:] + new_matches\n",
391 " return successes"
392 ]
393 },
394 {
395 "cell_type": "code",
396 "execution_count": 22,
397 "metadata": {
398 "collapsed": true
399 },
400 "outputs": [],
401 "source": [
402 "def is_var(word):\n",
403 " return word[0] == '?'"
404 ]
405 },
406 {
407 "cell_type": "code",
408 "execution_count": 23,
409 "metadata": {
410 "collapsed": true
411 },
412 "outputs": [],
413 "source": [
414 "def successful_match(match):\n",
415 " return match.text == [] and match.rule == []"
416 ]
417 },
418 {
419 "cell_type": "code",
420 "execution_count": 24,
421 "metadata": {
422 "collapsed": true
423 },
424 "outputs": [],
425 "source": [
426 "def splits(item):\n",
427 " return [(item[:i], item[i:]) for i in range(len(item)+1)]"
428 ]
429 },
430 {
431 "cell_type": "code",
432 "execution_count": 25,
433 "metadata": {
434 "collapsed": false
435 },
436 "outputs": [
437 {
438 "data": {
439 "text/plain": [
440 "[('', 'harry'),\n",
441 " ('h', 'arry'),\n",
442 " ('ha', 'rry'),\n",
443 " ('har', 'ry'),\n",
444 " ('harr', 'y'),\n",
445 " ('harry', '')]"
446 ]
447 },
448 "execution_count": 25,
449 "metadata": {},
450 "output_type": "execute_result"
451 }
452 ],
453 "source": [
454 "splits(\"harry\")"
455 ]
456 },
457 {
458 "cell_type": "code",
459 "execution_count": 236,
460 "metadata": {
461 "collapsed": true
462 },
463 "outputs": [],
464 "source": [
465 "def match_item(text, rule, bindings):\n",
466 " r0 = rule[0]\n",
467 " if is_var(r0):\n",
468 " if r0 in bindings:\n",
469 " # already seen this variable\n",
470 " if text[:len(bindings[r0])] == bindings[r0]:\n",
471 " return [Match(text[(len(bindings[r0])):], rule[1:], bindings)]\n",
472 " else:\n",
473 " return []\n",
474 " else:\n",
475 " # not seen this variable yet\n",
476 " matches = []\n",
477 " for pre, suf in splits(text):\n",
478 " new_bindings = bindings.copy()\n",
479 " new_bindings[r0] = pre\n",
480 " matches += [Match(suf, rule[1:], new_bindings)]\n",
481 " return matches\n",
482 " elif text and text[0] == r0:\n",
483 " return [Match(text[1:], rule[1:], bindings)]\n",
484 " else:\n",
485 " return []\n"
486 ]
487 },
488 {
489 "cell_type": "code",
490 "execution_count": 213,
491 "metadata": {
492 "collapsed": false
493 },
494 "outputs": [
495 {
496 "data": {
497 "text/plain": [
498 "[{'?X': ['fred'], '?Y': ['jane']}]"
499 ]
500 },
501 "execution_count": 213,
502 "metadata": {},
503 "output_type": "execute_result"
504 }
505 ],
506 "source": [
507 "match('fred hello jane'.split(), '?X hello ?Y'.split())"
508 ]
509 },
510 {
511 "cell_type": "code",
512 "execution_count": 214,
513 "metadata": {
514 "collapsed": false
515 },
516 "outputs": [
517 {
518 "data": {
519 "text/plain": [
520 "[{'?X': [], '?Y': ['jane']}]"
521 ]
522 },
523 "execution_count": 214,
524 "metadata": {},
525 "output_type": "execute_result"
526 }
527 ],
528 "source": [
529 "match('hello jane'.split(), '?X hello ?Y'.split())"
530 ]
531 },
532 {
533 "cell_type": "code",
534 "execution_count": 215,
535 "metadata": {
536 "collapsed": false
537 },
538 "outputs": [
539 {
540 "data": {
541 "text/plain": [
542 "[{'?X': ['fred'], '?Y': []}]"
543 ]
544 },
545 "execution_count": 215,
546 "metadata": {},
547 "output_type": "execute_result"
548 }
549 ],
550 "source": [
551 "match('fred hello'.split(), '?X hello ?Y'.split())"
552 ]
553 },
554 {
555 "cell_type": "code",
556 "execution_count": 216,
557 "metadata": {
558 "collapsed": false
559 },
560 "outputs": [
561 {
562 "data": {
563 "text/plain": [
564 "[{'?X': [], '?Y': []}]"
565 ]
566 },
567 "execution_count": 216,
568 "metadata": {},
569 "output_type": "execute_result"
570 }
571 ],
572 "source": [
573 "match('hello'.split(), '?X hello ?Y'.split())"
574 ]
575 },
576 {
577 "cell_type": "code",
578 "execution_count": 217,
579 "metadata": {
580 "collapsed": false
581 },
582 "outputs": [
583 {
584 "data": {
585 "text/plain": [
586 "[]"
587 ]
588 },
589 "execution_count": 217,
590 "metadata": {},
591 "output_type": "execute_result"
592 }
593 ],
594 "source": [
595 "match('fred jane'.split(), '?X hello ?Y'.split())"
596 ]
597 },
598 {
599 "cell_type": "code",
600 "execution_count": 218,
601 "metadata": {
602 "collapsed": false
603 },
604 "outputs": [
605 {
606 "data": {
607 "text/plain": [
608 "[{'?X': ['fred']}]"
609 ]
610 },
611 "execution_count": 218,
612 "metadata": {},
613 "output_type": "execute_result"
614 }
615 ],
616 "source": [
617 "match('fred hello'.split(), '?X hello'.split())"
618 ]
619 },
620 {
621 "cell_type": "code",
622 "execution_count": 219,
623 "metadata": {
624 "collapsed": false
625 },
626 "outputs": [
627 {
628 "data": {
629 "text/plain": [
630 "[]"
631 ]
632 },
633 "execution_count": 219,
634 "metadata": {},
635 "output_type": "execute_result"
636 }
637 ],
638 "source": [
639 "match('hello fred'.split(), '?X hello'.split())"
640 ]
641 },
642 {
643 "cell_type": "code",
644 "execution_count": 220,
645 "metadata": {
646 "collapsed": false
647 },
648 "outputs": [
649 {
650 "data": {
651 "text/plain": [
652 "[{'?X': ['yes'], '?Y': ['rain']}]"
653 ]
654 },
655 "execution_count": 220,
656 "metadata": {},
657 "output_type": "execute_result"
658 }
659 ],
660 "source": [
661 "match('yes i remember rain'.split(), '?X i remember ?Y'.split())"
662 ]
663 },
664 {
665 "cell_type": "code",
666 "execution_count": 221,
667 "metadata": {
668 "collapsed": false
669 },
670 "outputs": [
671 {
672 "data": {
673 "text/plain": [
674 "[{'?X': ['no'], '?Y': ['rain']}]"
675 ]
676 },
677 "execution_count": 221,
678 "metadata": {},
679 "output_type": "execute_result"
680 }
681 ],
682 "source": [
683 "match('no i remember rain'.split(), '?X i remember ?Y'.split())"
684 ]
685 },
686 {
687 "cell_type": "code",
688 "execution_count": 222,
689 "metadata": {
690 "collapsed": false
691 },
692 "outputs": [
693 {
694 "data": {
695 "text/plain": [
696 "[]"
697 ]
698 },
699 "execution_count": 222,
700 "metadata": {},
701 "output_type": "execute_result"
702 }
703 ],
704 "source": [
705 "match(\"no remember rain\".split(), '?X i remember ?Y'.split())"
706 ]
707 },
708 {
709 "cell_type": "code",
710 "execution_count": 223,
711 "metadata": {
712 "collapsed": false
713 },
714 "outputs": [
715 {
716 "data": {
717 "text/plain": [
718 "[{'?X': [], '?Y': ['rain']}]"
719 ]
720 },
721 "execution_count": 223,
722 "metadata": {},
723 "output_type": "execute_result"
724 }
725 ],
726 "source": [
727 "match(\"i remember rain\".split(), '?X i remember ?Y'.split())"
728 ]
729 },
730 {
731 "cell_type": "code",
732 "execution_count": 241,
733 "metadata": {
734 "collapsed": false,
735 "scrolled": true
736 },
737 "outputs": [
738 {
739 "data": {
740 "text/plain": [
741 "[{'?X': [], '?Y': ['hello', 'there', 'hello']},\n",
742 " {'?X': ['hello'], '?Y': ['there']}]"
743 ]
744 },
745 "execution_count": 241,
746 "metadata": {},
747 "output_type": "execute_result"
748 }
749 ],
750 "source": [
751 "match(\"hello there hello\".split(), '?X ?Y ?X'.split())"
752 ]
753 },
754 {
755 "cell_type": "code",
756 "execution_count": 242,
757 "metadata": {
758 "collapsed": false,
759 "scrolled": true
760 },
761 "outputs": [
762 {
763 "data": {
764 "text/plain": [
765 "[{'?X': ['hello']}]"
766 ]
767 },
768 "execution_count": 242,
769 "metadata": {},
770 "output_type": "execute_result"
771 }
772 ],
773 "source": [
774 "match(\"hello there hello\".split(), '?X there ?X'.split())"
775 ]
776 },
777 {
778 "cell_type": "code",
779 "execution_count": 244,
780 "metadata": {
781 "collapsed": false
782 },
783 "outputs": [
784 {
785 "data": {
786 "text/plain": [
787 "[{'?X': [], '?Y': ['hello', 'hello', 'hello']},\n",
788 " {'?X': ['hello'], '?Y': ['hello', 'hello']},\n",
789 " {'?X': ['hello', 'hello'], '?Y': ['hello']},\n",
790 " {'?X': ['hello', 'hello', 'hello'], '?Y': []}]"
791 ]
792 },
793 "execution_count": 244,
794 "metadata": {},
795 "output_type": "execute_result"
796 }
797 ],
798 "source": [
799 "match(\"hello hello hello\".split(), '?X ?Y'.split())"
800 ]
801 },
802 {
803 "cell_type": "code",
804 "execution_count": 245,
805 "metadata": {
806 "collapsed": false
807 },
808 "outputs": [
809 {
810 "data": {
811 "text/plain": [
812 "[{'?X': [], '?Y': ['hello', 'hello', 'hello']},\n",
813 " {'?X': ['hello'], '?Y': ['hello']}]"
814 ]
815 },
816 "execution_count": 245,
817 "metadata": {},
818 "output_type": "execute_result"
819 }
820 ],
821 "source": [
822 "match(\"hello hello hello\".split(), '?X ?Y ?X'.split())"
823 ]
824 },
825 {
826 "cell_type": "code",
827 "execution_count": 196,
828 "metadata": {
829 "collapsed": true
830 },
831 "outputs": [],
832 "source": [
833 "def candidate_rules(rules, comment):\n",
834 " return [(rule, bindings) \n",
835 " for rule in rules \n",
836 " for bindings in match(comment, rule['pattern'])]"
837 ]
838 },
839 {
840 "cell_type": "code",
841 "execution_count": 197,
842 "metadata": {
843 "collapsed": false,
844 "scrolled": true
845 },
846 "outputs": [
847 {
848 "data": {
849 "text/plain": [
850 "[({'pattern': ['?X', 'i', 'remember', '?Y'],\n",
851 " 'responses': [['do', 'you', 'often', 'think', 'of', '?Y'],\n",
852 " ['does',\n",
853 " 'thinking',\n",
854 " 'of',\n",
855 " '?Y',\n",
856 " 'bring',\n",
857 " 'anything',\n",
858 " 'else',\n",
859 " 'to',\n",
860 " 'mind'],\n",
861 " ['what', 'else', 'do', 'you', 'remember?'],\n",
862 " ['why', 'do', 'you', 'recall', '?Y', 'right', 'now'],\n",
863 " ['what',\n",
864 " 'in',\n",
865 " 'this',\n",
866 " 'present',\n",
867 " 'situation',\n",
868 " 'reminds',\n",
869 " 'you',\n",
870 " 'of',\n",
871 " '?Y'],\n",
872 " ['what', 'is', 'the', 'connection', 'between', 'me', 'and', '?Y']]},\n",
873 " {'?X': [], '?Y': ['rain']}),\n",
874 " ({'pattern': ['?X'],\n",
875 " 'responses': [['very', 'interesting'],\n",
876 " ['i', 'am', 'not', 'sure', 'i', 'understand', 'you', 'fully'],\n",
877 " ['what', 'does', 'that', 'suggest', 'to', 'you'],\n",
878 " ['please', 'continue'],\n",
879 " ['go', 'on'],\n",
880 " ['do',\n",
881 " 'you',\n",
882 " 'feel',\n",
883 " 'strongly',\n",
884 " 'about',\n",
885 " 'discussing',\n",
886 " 'such',\n",
887 " 'things']]},\n",
888 " {'?X': ['i', 'remember', 'rain']})]"
889 ]
890 },
891 "execution_count": 197,
892 "metadata": {},
893 "output_type": "execute_result"
894 }
895 ],
896 "source": [
897 "candidate_rules(all_rules, \"i remember rain\".split())"
898 ]
899 },
900 {
901 "cell_type": "code",
902 "execution_count": 198,
903 "metadata": {
904 "collapsed": true
905 },
906 "outputs": [],
907 "source": [
908 "def fill(response, bindings):\n",
909 " filled_response = []\n",
910 " for w in response:\n",
911 " if is_var(w):\n",
912 " if w in bindings:\n",
913 " filled_response += bindings[w]\n",
914 " else:\n",
915 " filled_response += ['MISSING']\n",
916 " else:\n",
917 " filled_response += [w]\n",
918 " return filled_response"
919 ]
920 },
921 {
922 "cell_type": "code",
923 "execution_count": 202,
924 "metadata": {
925 "collapsed": false
926 },
927 "outputs": [
928 {
929 "data": {
930 "text/plain": [
931 "'do you often think of rain'"
932 ]
933 },
934 "execution_count": 202,
935 "metadata": {},
936 "output_type": "execute_result"
937 }
938 ],
939 "source": [
940 "bs = match('yes i remember rain'.split(), '?X i remember ?Y'.split())[0]\n",
941 "fr = fill(['do', 'you', 'often', 'think', 'of', '?Y'], bs)\n",
942 "' '.join(fr)"
943 ]
944 },
945 {
946 "cell_type": "code",
947 "execution_count": 165,
948 "metadata": {
949 "collapsed": true
950 },
951 "outputs": [],
952 "source": [
953 "pronoun_swaps = {\n",
954 " 'i': 'you',\n",
955 " 'me': 'you',\n",
956 " 'my': 'your',\n",
957 " 'mine': 'yours',\n",
958 " 'am': 'are'\n",
959 "}\n",
960 "\n",
961 "def pronoun_person_swap(bindings):\n",
962 " def swapped(words):\n",
963 " sw = []\n",
964 " for w in words:\n",
965 " if w in pronoun_swaps:\n",
966 " sw += [pronoun_swaps[w]]\n",
967 " else:\n",
968 " sw += [w]\n",
969 " return sw\n",
970 " \n",
971 " return {var: swapped(bindings[var]) for var in bindings}"
972 ]
973 },
974 {
975 "cell_type": "code",
976 "execution_count": 166,
977 "metadata": {
978 "collapsed": false
979 },
980 "outputs": [
981 {
982 "data": {
983 "text/plain": [
984 "{'?X': ['your', 'father'], '?Y': ['you', 'are', 'your', 'brother', 'keeper']}"
985 ]
986 },
987 "execution_count": 166,
988 "metadata": {},
989 "output_type": "execute_result"
990 }
991 ],
992 "source": [
993 "pronoun_person_swap({'?X': ['my', 'father'], '?Y': 'i am my brother keeper'.split()})"
994 ]
995 },
996 {
997 "cell_type": "code",
998 "execution_count": 101,
999 "metadata": {
1000 "collapsed": true
1001 },
1002 "outputs": [],
1003 "source": [
1004 "def respond(rule, bindings):\n",
1005 " return fill(random.choice(rule['responses']), bindings)"
1006 ]
1007 },
1008 {
1009 "cell_type": "code",
1010 "execution_count": 231,
1011 "metadata": {
1012 "collapsed": false
1013 },
1014 "outputs": [
1015 {
1016 "data": {
1017 "text/plain": [
1018 "['why', 'do', 'you', 'recall', 'rain', 'right', 'now']"
1019 ]
1020 },
1021 "execution_count": 231,
1022 "metadata": {},
1023 "output_type": "execute_result"
1024 }
1025 ],
1026 "source": [
1027 "r0, b0 = candidate_rules(all_rules, \"i remember rain\".split())[0]\n",
1028 "respond(r0, b0)"
1029 ]
1030 },
1031 {
1032 "cell_type": "code",
1033 "execution_count": 167,
1034 "metadata": {
1035 "collapsed": false
1036 },
1037 "outputs": [],
1038 "source": [
1039 "def eliza_loop():\n",
1040 " print(\"Hello. I'm Eliza. What seems to be the problem?\")\n",
1041 " while True:\n",
1042 " c = input(\"> \")\n",
1043 " if c.strip() in 'quit halt exit stop'.split(): break\n",
1044 " comment = c.split()\n",
1045 " rule, bindings = candidate_rules(all_rules, comment)[0]\n",
1046 " swapped_bindings = pronoun_person_swap(bindings)\n",
1047 " print(' '.join(respond(rule, swapped_bindings)))"
1048 ]
1049 },
1050 {
1051 "cell_type": "code",
1052 "execution_count": 168,
1053 "metadata": {
1054 "collapsed": false,
1055 "scrolled": true
1056 },
1057 "outputs": [
1058 {
1059 "name": "stdout",
1060 "output_type": "stream",
1061 "text": [
1062 "Hello. I'm Eliza. What seems to be the problem?\n",
1063 "> this is weird\n",
1064 "i am not sure i understand you fully\n",
1065 "> i love my father\n",
1066 "your father\n",
1067 "> yes, my father\n",
1068 "what else comes to mind when you think of your father\n",
1069 "> i remember my father\n",
1070 "does thinking of your father bring anything else to mind\n",
1071 "> i remember i am a saint\n",
1072 "does thinking of you are a saint bring anything else to mind\n",
1073 "> saints are always happy\n",
1074 "really -- always\n",
1075 "> yes, always\n",
1076 "can you think of a specific example\n",
1077 "> saint george was happy when he killed the dragon\n",
1078 "go on\n",
1079 "> i don't think you understand me\n",
1080 "perhaps in your fantasies we don't think each other\n",
1081 "> i aardvark you understand me\n",
1082 "perhaps in your fantasies we aardvark each other\n",
1083 "> exit\n"
1084 ]
1085 }
1086 ],
1087 "source": [
1088 "eliza_loop()"
1089 ]
1090 },
1091 {
1092 "cell_type": "code",
1093 "execution_count": null,
1094 "metadata": {
1095 "collapsed": true
1096 },
1097 "outputs": [],
1098 "source": []
1099 }
1100 ],
1101 "metadata": {
1102 "kernelspec": {
1103 "display_name": "Python 3",
1104 "language": "python",
1105 "name": "python3"
1106 },
1107 "language_info": {
1108 "codemirror_mode": {
1109 "name": "ipython",
1110 "version": 3
1111 },
1112 "file_extension": ".py",
1113 "mimetype": "text/x-python",
1114 "name": "python",
1115 "nbconvert_exporter": "python",
1116 "pygments_lexer": "ipython3",
1117 "version": "3.5.2+"
1118 }
1119 },
1120 "nbformat": 4,
1121 "nbformat_minor": 0
1122 }