Appendix GWorkbench: code and flowcharts
How ELIZA works
ELIZA read a sentence, found its most important keyword, matched a pattern the script gave for that keyword, and filled in a reply template with the person's own words. No learning and no prediction: every step was a rule a person wrote.1
ELIZA, step by step
- Read the sentence and look up each word in the script's list of keywords.
- Pick the keyword with the highest rank. Each keyword in the script carries a number for how important it is.1
- Match the keyword's pattern (Weizenbaum's decomposition rule), which splits the sentence into numbered parts.1
- Fill in a reply template (a reassembly rule) with some of those parts, after swapping words such as "I" for "you."1
- No keyword? Use a stock reply, or bring back something the person said earlier, from what the script calls MEMORY.1
One rule from the 1966 script
(REMEMBER 5
((0 YOU REMEMBER 0) (DO YOU OFTEN THINK OF 4)
(DOES THINKING OF 4 BRING ANYTHING ELSE TO MIND)
(WHAT ELSE DO YOU REMEMBER)In the script, 0 means "any number of words," and a number in a reply means that part of the match. So in (0 YOU REMEMBER 0), part 4 is whatever followed REMEMBER, and DO YOU OFTEN THINK OF 4 hands it back.1
A tiny ELIZA
The same idea in modern code, written for this book (Weizenbaum's own program was in MAD-SLIP). It is for reading; you don't need to run it.
// Each rule: a keyword's rank, a pattern, and replies that reuse what was captured.
const rules = [
{ rank: 5, pattern: /\byou remember (.*)/i, replies: ['Do you often think of $1?', 'What else do you remember?'] },
{ rank: 2, pattern: /\bmy (.*)/i, replies: ['Your $1?', 'Why do you say your $1?'] },
{ rank: 0, pattern: /.*/, replies: ['Please go on.', 'What does that suggest to you?'] },
];
// Turn "I" into "you" and "my" into "your" before the words are echoed back.
const swap = { i: 'you', me: 'you', my: 'your', am: 'are', you: 'I', your: 'my' };
const reflect = (s) => s.split(' ').map((w) => swap[w.toLowerCase()] ?? w).join(' ');
function eliza(sentence) {
const rule = rules.filter((r) => r.pattern.test(sentence)).sort((a, b) => b.rank - a.rank)[0];
const reply = rule.replies[Math.floor(Math.random() * rule.replies.length)];
const captured = sentence.match(rule.pattern)[1] ?? '';
return reply.replace('$1', reflect(captured).replace(/[.!?]$/, ''));
}
eliza('Well, my boyfriend made me come here.');
// "Your boyfriend made you come here?" or "Why do you say your boyfriend made you come here?"On the web, you can talk to a version of ELIZA in the Arcade: stevesparks.com/arcade/eliza.
Notes (1)
- 1Joseph Weizenbaum, “ELIZA—A Computer Program for the Study of Natural Language Communication Between Man and Machine,” Communications of the ACM 9, no. 1 (January 1966): 36–45, https://doi.org/10.1145/365153.365168. Cited at pages 36–37, 37–38, 37–39, 38–39, 41, 44.
Appendix G · page 1 of 3
Turn pages with the ← and → keys.