TEACH ELIZA2                                 Steven Hardy, November 1981

This file follows directly  on from TEACH *  ELIZA which should be  read
before reading this.

To prevent the  conversation becoming  too predictable you  may want  to
make use of the ONEOF procedure  built into POP-11. Given a list,  ONEOF
picks an element  at random.  Thus the  'response' procedure  definition
could start:

    define response(list);
    vars x, y;
      if list matches [??x mother ??y] then
          oneof([[tell me more about your family]
                  [did you have a happy childhood]
                  [did your father and mother get on well]])
                      =>
      ...
    enddefine;

If you try this mechanism be sure to get all your brackets right!

    ---------------------------------------------------------------

Secondly, you could use ONEOF in a condition, thus:

    if oneof([[heads] [tails]]) = [heads]
    and list matches [??x mother ??y] then
        oneof([ ... ]) =>

    ---------------------------------------------------------------

Thirdly, you could get your program to 'remember' something typed in  by
the user (perhaps selected at  random) and later regurgitate at  random.
For example, 'doctor' could be modified thus:

    define doctor();
    vars problem, input;
        [good day - what is your problem] =>
        readline() -> problem;
        problem -> input;
        until input matches [??x bye ??y] do
            response(input);
            readline() -> input
        enduntil;
        [good bye] =>
    enduntil;

and then add an extra clause to response, thus:

    if oneof([[heads] [tails]]) = [heads] then
        [earlier you said ^^problem] =>

    -----------------------------------------------------------

You might find it helpful to include, and use, the following definition:

    define flip() -> result;
        if oneof([[heads] [tails]]) = [heads] then
            true -> result
        else
            false -> result
        endif
    enddefine;

You can then write:

    if flip() then
        [earlier you sad ^^problem] =>
    ....

    -----------------------------------------------------------

Finally, you will  have noticed  that your program,  unlike the  library
program ELIZA,  doesn't  do 'person  conversion'.  That is,  it  doesn't
change I to YOU or MY to YOUR. If the user says that her problem is:

    ? i hate my family

then DOCTOR might later respond:

    ** [earlier you said i hate my family]

instead of

    ** [earlier you said you hate your family]

One way  to  fix  this  would  be to  write  a  procedure  called,  say,
CHANGEPERSON and insert calls of it thus:

    define doctor();
    vars input, problem, newinput, x, y;
        [good day - what is your problem] =>
        readline() -> input;
        changeperson(input) -> problem;
        problem -> newinput;
        until newinput matches [??x bye ??y] do
            response(newinput);
            readline() -> input;
            changeperson(input) -> newinput
        enduntil
    enddefine;

You can model CHANGEPERSON on RESPONSE, here is an example:

    define changeperson(list) -> result;
    vars x, y;
        if list matches [??x i ??y] then
            [^^x you ^^y] -> result
        elseif list matches [??x my ??y] then
            [^^x your ^^y] -> result
        else
            list -> result
        endif
    enddefine;

    ------------------------------------------------------------

Notice the way we arrange  for a POP-11 procedure  to have a result.  We
modify the  first  line  of  the procedure  definition  to  include  '->
result'. This says the procedure has  a result. The procedure must  then
assign some value to  RESULT. The procedure  calling a procedure  with a
result can assign it to some variable, thus:

    changeperson(input) -> newinput;

The variable NEWINPUT will take as its value the RESULT of CHANGEPERSON.

    ------------------------------------------------------------

The only problem with this definition is that it will only make one change
- not all possible changes as desired. The solution to this problem will be
to make use of an UNTIL (or WHILE loop) - or perhaps several. See if you
can work out a way of doing this for yourself.

--- C.all/teach/eliza2 -------------------------------------------------
--- Copyright University of Sussex 1988. All rights reserved. ----------
