Laboratory Exercises For Computer Science 153

Eliza: An Example of Object-Oriented Design

Now that we have seen some implementation of object-oriented programming, it is time to develop our skills at solving problems from an object-oriented approach. To do this well, we need to disregard what we know about functional problem solving and look at problems from a completely different perspective. In object-oriented problem solving, we first identify the objects and classes or objects within a problem, and then we identify the relationships among those objects and classes.

This lab outlines a object-oriented solution to a problem based on a famous porgram called Eliza, developed by Joseph Weizenbaum.

Problem: Pattern matching and transformation rules occur frequently in symbolic computation. The following patterns and corresponding response templates can be used to generate ``conversations''.


Pattern     Response Template
---1 my singleWord ---2 me ---3 tell me about your singleWord
---1 i am ---2 i am sorry to hear you are ---2
---1 am i ---2 do you believe you are ---2
---1 you ---2 me --- 3 why do you think i ---2 you
---1 in what way


In this table, the blank spaces in a pattern, denoted by subscripted dashes, can be filled in with any sequence of words. Similarly, singleWord represents exactly one word in a sentence. For example, these patterns might generate the following ``conversation,'' where the responses are indented and in italics:

Sample Dialogue:

well my friend made me come here
    tell me about your friend
he says i am depressed
    i am sorry to hear you are depressed
i think i need help
    in what way
i wonder if you would help me learning to program Scheme
    why do you think i would help you
when i registered for the course i wondered am i crazy
    do you believe you are crazy

Each of these statements and responses follows the template/response patterns given. For example, in the first statement:

well my friend made me come here

the presence of the word my near the start of the sentence with the word me later on corresponds to the first pattern, with the following matches:

Pattern Element Words from this Sentence
---1 well
my my
singleWord friend
---2 made
me me
---3 come here

After identifying these pattern elements for the first pattern, the Eliza program uses the corresponding response template. In this case, the program prints "Tell me about your friend. The first four of these words come directly from the template. For the final word, singleWord in the template was matched with the word "friend" in the above analysis.

Work for this Lab

  1. Identify the patterns for each of the other sentences in the above "conversation". Then, for each pattern, write out which words correspond to which pattern elements, and use this analysis to explain each result printed by the Eliza program.

Goal of the Eliza Project:

Write a program to read responses from a user, apply a relevant pattern, and use the corresponding template to generate a response.

Historical Note: In 1966, Joseph Weizenbaum used this approach to write a program, called Eliza, which conversed by simply rearranging words and phrases following a reasonably large collection of patterns. In 1976, Weizenbaum noted he ``was startled to see how quickly and how deeply people conversing with [Eliza] became emotionally involved'' in the conversation. People shared their hopes and secrets, and they became annoyed if other people looked over their shoulders or otherwise interrupted. Even when they knew Eliza was a program, they often talked as if it were a close personal friend.

General User Interaction

In an overall session, a user will expect to type lines into the program and then to receive responses. While one might allow complex input, for the current purposes it suffices to limit each user statement to a single line and to ignore matters of capitalization and punctuation.

  1. Brainstorm to determine another pattern template and response. Show two examples to illustrate how your template and response might fit into a conversation.

Also, it seems reasonable for the user to quit by typing ``exit''. The program then should respond ``program terminated'' and stop. Within the current context, it seems natural to consider this interaction as another pattern/response pair, with a special final action.

An Object-Oriented Solution

The following remarks outline a solution to this problem. The discussion follows the general approach of object-oriented programming (OOP), although the discussion may not be strictly object-oriented in all respects.

Object-oriented programming (OOP) depends upon such concepts as objects and classes, inheritance, methods, and communication between objects. OOP focuses on data structures and adds functionality (or processing capability), while procedural languages traditionally begin with processes.

An analysis of this problem identifies the following major objects:

    input line -with 1 line for each user's input
6 patterns -each of which includes a template with text/words, wildcards, and singleword designators
6 responses -corresponding to the patterns, each includes a template with text/words, wildcards, and singleword designators
directory/table- which matches text/words with wildcards and singleword designators

In this analysis, patterns and responses may be identified fairly easily, as the most important nouns in the problem statement. Similarly, an input line represents the data which a user enters, and thus is a natural candidate as a class. The directory/table may require additional thought.

In particular, one expects a pattern will report when a line has an appropriate form, and one expects a response to print the corresponding result. However, the question arises as to how a response will know which words correspond to various blanks or single words in a pattern. One approach would be to combine a pattern and response into a single processing entity. While this is a viable alternative, it places a great deal of processing within a single object. Separating patterns and responses seems more in spirit with the nature of this problem, but then communication of word sequences is needed. One solution to this problem introduces a directory, which keeps track of which words go with which blanks and single words. In this approach, a pattern needs not know how blanks or word sequences will be used -- it just needs to identify what words correspond to which sequence. Similarly, a pattern need not know details of how the input line is divided into pieces -- it just needs to retrieve relevant word sequences for a response. A directory/table serves this communication purpose in a convenient way.

Once these objects are identified, we consider how the objects communicate during processing. For example, the following diagram shows a sequence of messages that might arise if an input line matches pattern 2.

Flow diagram for processing a line in Eliza, based on matching with
pattern 2

  1. The diagram shows 13 steps involved in processing a line that matches pattern 2. Write a sentence or two that explains what processing happens for each of these steps.

  2. Now consider processing that occurs in processing the line "i wonder if you would help me learning to program Scheme". Outline each of the steps involved.

  3. For each class in the solution of the problem, make a list of all operations or methods used in processing (at least following the above processing diagram).

Programing the Solution

Role of the Main Program: In this context, the main program performs two main tasks: creation of major objects and coordination of message passing.

Other tasks in processing are handled when individual objects respond to messages using the appropriate methods.

Programming Notes:

Coded Solutions: Programs following this object-oriented approach to the Eliza problem are available in both Scheme and C++:

  1. Review in some detail the Scheme version of the solution of this problem, copying the program to your account, loading it into Scheme, and running it with a conversation including the dialog at the beginning of this lab.

  2. Review the structure of the Scheme program.

    1. Identify various sections of the code, giving line numbers and description for each section. In xemacs, one can determine the line number of any line by pressing <control> and the lower-case letter x simultaneously, followed by a lower-case letter l.
    2. Note that the defintion of each class is accompanied by a brief comment of what the class does and by a sequence of test cases. The tests allow each class to be tested individually!
    3. Using your list of operations required for class lineDirectory (from step 5 above), use the test cases described in the file to describe how each class responds to each method. In other words, describe what is returned by the insert and find methods. Also, describe what the clear method does?
    4. Similarly, use test cases to describe how the other classes respond when each method is involked.

  3. Examine the structure of the main Eliza procedure to understand the main flow of processing. Then, expand the procedure to include the addtional pattern and response you suggested in step 2 above. Run the revised program, including tests of both the original user statements and the examples you suggested in step 2.

This document is available on the World Wide Web as

http://www.cs.grinnell.edu/~walker/courses/153.sp02/lab-oo-eliza.html

created January 17, 2000 by Henry Walker
last revised April 1, 2002
Valid HTML 3.2!
For more information, please contact Henry M. Walker at walker@cs.grinnell.edu.