.he'ELIZARULES''Page %'
.fo'Aaron Sloman'%'July 21 1978'
.mh
EXTENDING ELIZA
===============
.hm
You can run the ELIZA program by typing
 	: LIB ELIZA;
.br
The program will then be compiled (which takes quite a long time), after
which it will print out:
 	PLEASE TYPE
 		ELIZA
.br
You should then type
 	: ELIZA
.br
to get the program going.

Eliza will go on until you type CTRL-D, or CTRL-X, or one of "BYE",
"GOODBYE".

Eliza contains a set of rules for responding to the sentence you type in.
If you want to extend the program, by giving it new rules, first type
 	: BYE
.br
which will cause SETPOP to be executed, so that you are then again talking to
POP11, and can define functions, give commands, etc.

You can then define new rules.
Here is an example of one of the rules:
.br
.ne 6
 	: NEWRULE BECAUSE;
 	:	IF	ITCONTAINS([BECAUSE])
 	:	THEN	[IS THAT THE REAL REASON?]
 	:	CLOSE
 	: END;

Notice that NEWRULE is a bit like FUNCTION. It is not allowed to have any
arguments, however.
If a rule produces any results when Eliza tries it, then the result will be printed out as the
reply, if not, Eliza tries another rule. There may be two rules both
capable of producing a response, but you cannot be sure which one Eliza will
find, since the rules are tried in a different order each time.

The list of rules that the program uses is FUNCTIONLIST. You can see the names of the
functions in it by typing:
 	: FUNCTIONLIST =>
.br
If you use NEWRULE to define some more rules, then FUNCTIONLIST will be
extended, as you can see by printing it out after defining some rules.
If you define a rule which has the same name as one already on the list, then
the original will be replaced by the later version.

Try defining some rules, using ITCONTAINS. Then run Eliza again, by typing
 	: ELIZA
.br
and see if your rules work. (You don't need to type LIB#ELIZA; again.)

If you want to ensure that ELIZA uses only the rules you have defined, and
not one of the standard ones, then you should do the following before
defining your own rules:
 	: [] -> FUNCTIONLIST;

This will make ELIZA forget about all the built in rules.

.mh
Auxiliary Functions Provided
----------------------------
.hm
Notice the use of the function ITCONTAINS, in the definition of the rule BECAUSE.
Several other functions are provided for you to use in rules, namely:
 	ITHASONEOF, ITMATCHES, ITSLIKEONEOF.

All of them assume that the sentence typed in by the user has already been
transformed so that "you" is replaced by "i", "mine" is replaced by
"yours", etc.
They also assume that the variable SENTENCE has as value the list of
input so transformed.

.sh
ITCONTAINS
----------
.hs
ITCONTAINS is defined thus:
.ne3
 	: FUNCTION ITCONTAINS(LIST);
 	: 	MATCH([== ^^LIST ==],SENTENCE])
 	: END;

The remaining testing functions will now be explained.

.sh
ITHASONEOF
----------
.hs
If you want to define a rule which detects whether
the person has typed in something referring to Eliza, you can use ITHASONEOF
something like this:
.tp4
 	: NEWRULE ME;
 	:	IF	ITHASONEOF([ME I MINE MY ELIZA])
 	:	THEN	[ARENT YOU GETTING A LITTLE PERSONAL?]
 	: END;

Or try a rule something like:
.tp 4
 	: NEWRULE TUTOR;
 	:	IF	ITHASONEOF([MAX MAGGIE STEVE AARON])
 	:	THEN	[DO YOU PREFER ME TO YOUR TUTORS?]
 	:	CLOSE
 	: END;

Try defining some rules. You can store them in a file, then LOAD them
in the usual way (but see the note on DEBUG, below). Make sure that you already have the ELIZA system
compiled before you load your files, otherwise POP11 will not recognise
NEWRULE and will give errors. If you forget this, and try loading a file
containing NEWRULE or typing in a rule, before you've done
LIB#ELIZA; then you'll find it best to leave POP11 and then
re-start.

.sh
ITMATCHES
---------
.hs
The functions ITMATCHES and ITSLIKEONEOF use the MATCH function, defined
in the MATCH demo. So you can use symbols
 	"?", "??", "=", "=="
.br
to control the matching. For example, if you wish to define a rule which
will respond to a sentence containing the phrase "SILLY FOOL" and respond
with a question in which the phrase is replaced by "STUPID PERSON", then
you could define:
.tp5
 	: NEWRULE SILLY;
 	:	VARS LIST1 LIST2;
 	:	IF	ITMATCHES([??LIST1 SILLY FOOL ??LIST2])
 	:	THEN	[WHY DO YOU SAY ^^LIST1 STUPID PERSON ^^LIST2 ?]
 	:	CLOSE
 	: END;

So if you later type to Eliza, something like:
 	: MY TUTOR SAID I AM A SILLY FOOL AFTER READING MY ESSAY
.br
Then, before trying any rules, Eliza will turn this into the list
 	[YOUR TUTOR SAID YOU ARE A SILLY FOOL AFTER READING YOUR ESSAY]
.br
then if the rule SILLY is tried, the variable LIST1 will match
 	[YOUR TUTOR SAID YOU ARE A]
.br
and LIST2 will match
 	[AFTER READING YOUR ESSAY]
.br
and the program will produce the response:
.in+8
[WHY DO YOU SAY YOUR TUTOR SAID YOU ARE A STUPID PERSON AFTER READING YOUR ESSAY ?]
.in-8

Notice that if you use "pattern variables" which are to be given a value in
the match, like LIST1 and LIST2, then you should declare the variables as local to the function,
as in the VARS declaration above.

.sh
ITSLIKEONEOF
------------
.hs
The function ITSLIKEONEOF is used to avoid writing things like
 	: 	IF	ITMATCHES([ .......])
 	:	OR	ITMATCHES([.......])
 	:	OR	ITMATCHES([.......])
 	:	THEN	......
.br
Instead you can put all the different patterns into a single list of patterns
and ITSLIKEONEOF will try them all, producing the result TRUE if one of the
patterns matches, otherwise FALSE. So, for example, you could define a rule
which looks out for sentences referring to the mather or father of the
user or Eliza, and causes a complaint to be produced as a reply:
.tp 8
 	: NEWRULE PARENT;
 	:	IF	ITHASONEOF([[ == MY FATHER ==]
 	:				[== MY MOTHER ==]
 	:				[== YOUR FATHER ==]
 	:				[== YOUR MOTHER ==]]
 	:	THEN	[LETS AGREE NOT TO DISCUSS OUR PARENTS FOR NOW]
 	:	CLOSE
 	: END;

.sh
DEBUGGING
---------
.hs
Normal error messages are switched off when Eliza runs. This is a nuisance if
you are trying out some new rules. So after loading some rules which you
wish to try out you should run eliza, then, before typing anything else,
type a line with just one word:
 	: DEBUG
.br
This will tell Eliza that you don't want your MISHAP messages suppressed.
If a SETPOP occurs and you try again, then you'll have to tell ELIZA at
the beginning of each run that you want DEBUG mode.
