@comment(Hey, EMACS, this is -*- SCRIBE -*- input)
@make(6001)
@set(chapter=1)
@set(page=1)

@PageHeading(even,
	     left "@Value(Page)",
	     right "6.001")

@PageHeading(odd,
	     left "Problem Set 6",
	     right "@Value(Page)")

@begin(center)
MASSACHUSETTS INSTITUTE OF TECHNOLOGY
Department of Electrical Engineering and Computer Science
6.001 Structure and Interpretation of Computer Programs

Problem Set 6
@end(center)
@blankspace(0.25 in)

@begin(format)
Issued: 25 October 1983@>Due: 2 November 1983
@end(format)

@begin(format)
Reading Assignment: Sections 3.2 and 3.3

@blankspace(0.25 in)
@begin(center)
@b[Exercises]
@end(center)

Write up and turn in the following exercises from the text:

@end(format)
@begin(itemize)
Exercise 3-3

Exercise 3-10

Exercise 3-13

@end(itemize)

@blankspace(0.25 in)

@begin(center)
@b[LABORATORY ASSIGNMENT: The Adventure Game]
@end(center)

We will study the idea of simulating a world with objects characterized by
state in the context of a simplified version of the "Adventure" game, a
"Dungeons & Dragons" style game which has been available on many computers,
and which has provided an interesting waste of time for many computer lovers.
The idea is that the user is placed, as a character, in an imaginary world
inhabited by other (usually imaginary) characters. The user plays the game
by wandering through the imaginary world, visiting various places.

The user plays by issuing commands to the computer which have the effect of
moving him around in the imaginary world and which perform acts in the
imaginary world, like picking up an object. The computer simulates his move
and responds, allowing him to make legal moves and rejecting illegal ones.
It is illegal to, say, walk through walls, (unless you have "wall-transparency
powers!"). If a move is legal, the computer will update its model of the world
and allow the next move to be considered.

@paragraph(The essential  system -- places and persons)
In order to get going, we need to establish the structure of our imaginary
world. It has an "ontology" -- the objects which exist and the ways they relate
to each other. The simulator for the world is contained in two files which can
be found at the end of the problem set. The first @a[adventure.scm] contains
procedures to create places, people, things and various other useful procedures
that you will not need to modify. The second @a[ps6.scm] is an initial data
base defining a particular world with various familiar and unfamilar places
represented, and with four people, WMS and HAL, a TROLL and a DEAN. (The
procedures defining the last two are incomplete and will be finished as part
of this laboratory.) Both files will be loaded with the @a[load-problem-set]
command.

Once these files are loaded, we will be able to find out where WMS and HAL are
and to walk them around the maze:
@begin(programexample)
==> ((wms 'place) 'name)
WMS-OFFICE

==> ((hal 'place) 'name)
HAL-OFFICE

==> ((wms 'go) 'down)
WMS moved from WMS-OFFICE to COMPUTER-LAB
NIL

==> ((hal 'go) 'south)
HAL moved from HAL-OFFICE to BLDG-36
NIL

==> ((hal 'go) 'up)
HAL moved from BLDG-36 to COMPUTER-LAB
HAL says - Hi, WMS
NIL

==> (wms 'look-around)
HAL
NIL

==> (hal 'look-around)
WMS
NIL

@end(programexample)

@paragraph(Message Passing)
The way that we communicate with WMS and other objects in our system is called
@a[message passing]. In our example (WMS 'GO) returned a procedure that 
accepted the direction that we wanted WMS to go in. We could imagine basing
all of our procedure calls on message passing. If we did this, adding two 
things together might look like
@begin(programexample)
   ((1 '+) 2)

   ((poly1 '+) poly2)
@end(programexample)
Note that the addition procedure returned by @a[(1 '+)] and the one returned
by @a[(poly1 '+)] don't have to be the same. In the first case, we presumably
would get a procedure that would add an integer to the number "1" and in the
second case we would get a procedure that would add a polynomial to POLY1.
Thus, an advantage of message passing is that it provides a simple way of
implementing generic operations. In fact, programming languages such as
Smalltalk [1] and Actors [2] are based entirely on message passing.

The following three procedures create the three types of objects that our 
system initially knows about:
@begin(programexample)
	(make-place name)
	(make-thing name)
	(make-person name place threshold-for-moving)
@end(programexample)
Like all of us, after being in a place for a while a person will get bored
and move on to a new place. The third argument to MAKE-PERSON is the number
of clock intervals that the person will remain in his current place before
moving. Before triggering the clock, let's explore the properties of our
world a bit more.

First, let's create a COMPUTER-MANUAL and place it in the COMPUTER-LAB
(where HAL and WMS now are).
@begin(programexample)
==> (define computer-manual (make-thing 'computer-manual))
COMPUTER-MANUAL

==> ((computer-lab 'appear) computer-manual)
([LAMBDA-PROCEDURE 170128] [PROCEDURE ME] [PROCEDURE ME])
@end(programexample)
Next, we'll have HAL look around.
@begin(programexample)
==> (hal 'look-around)
COMPUTER-MANUAL
WMS
NIL
@end(programexample)
The manual looks useful, so HAL picks it up and adds it to his possessions.
@begin(programexample)
==> ((hal 'take) computer-manual)
HAL took COMPUTER-MANUAL
NIL
@end(programexample)
If HAL leaves, the manual goes with him.
@begin(programexample)
==> ((hal 'go) 'down)
HAL moved from COMPUTER-LAB to BLDG-36
NIL

==> (hal 'list-possessions)
COMPUTER-MANUAL
NIL
@end(programexample)
WMS had also noticed the COMPUTER-MANUAL; he follows HAL and snatches the
manual away.
@begin(programexample)
==> ((wms 'go) 'down)
WMS moved from COMPUTER-LAB TO BLDG-36
WMS says - Hi, HAL
NIL

==> ((wms 'take) computer-manual)
WMS took COMPUTER-MANUAL
Yaaaah! HAL is upset!
NIL

==> (wms 'list-possessions)
COMPUTER-MANUAL
NIL

==> (hal 'list-possessions)
NIL
@end(programexample)
The people, places and things in our world have many other features built in.
For example, in response to the message 'MOVE, people go to a new place
randomly chosen from the neighbors of their present location -- provided that
their restlessness is greater than threshold; this is how the clock in our
system manipulates people who do not have "free-will". Other features could
readily be added; building such programs is often a good deal of fun. For
the rest of this laboratory, we'll concentrate on a few aspects of the world
we have built.

@paragraph(Problem 1)
Define a new character -- yourself. Place yourself initially in the DORMITORY
with a high enough threshold (say, 100) so that you have "free-will" and will
not be moved by the clock. Also create a new thing, LATE-HOMEWORK, and place
it also in the DORMITORY. Pick up the LATE-HOMEWORK, find out where HAL is
using the message 'CURRENT-POSITION, and move yourself to HAL's location. Try
to convince HAL to TAKE the homework even though its late. Can you find a
way to do this that does not leave @a[you] upset? Make a list of your
definitions and actions.

(Use the editor to enter your definitions in your modifiable file. Notice
that because the Adventure model works by mutation of data, it is possible
to get your SCHEME into an inconsistent state while debugging. If this
happens and if you have been careful about the order in which you  have
entered your procedures in the file @a[ps6.scm], you can re-initialize
by reloading this file.)

@paragraph(Problem 2)
Draw an environment diagram (see Section 3.2 of the Notes) for the procedure
object that was created when you defined your new character in Problem 1.
Don't draw the complete environment diagram for DORMITORY.

@paragraph(Problem 3)
PLACE, PERSON, and THING objects have one thing in common -- they all accept
the messages 'TYPE and 'NAME. In addition to these two basic messages, each
object supports a set of specialized messages. For example, a PLACE object
supports the message 'APPEAR. For each of the three types of objects that
are defined, produce a table of the messages they support and the function
of the messages. For each type of object, say whether each of its messages
is optional or mandatory. For example, PLACE must support 'APPEAR, because
PERSON objects depend on 'APPEAR. However, a PERSON object does not have to
support 'LOOK-AROUND, because no other type of object depends on
'LOOK-AROUND.

@paragraph(Problem 4)
Let's now add a new object to our world -- a TROLL who normally lives in a
DUNGEON concealed under the EGG-ATRIUM. The TROLL is a PERSON with rather
simple needs. After a certain number of clock intervals, the 
TROLL gets hungry and leaves his DUNGEON to wander around the world 
seeking food. He will eat the first person he runs into, unless that person
can offer him the one food he likes better -- a PIZZA. When he's finished
eating, the TROLL returns to his DUNGEON. Thus suppose some
poor soul BILL is in BLDG-10 when the hungry TROLL comes along:
@begin(programexample)
==> (bill 'current-position)
BLDG-10

==> (troll 'move)
TROLL moved from EGG-ATRIUM to BLDG-10
TROLL says - Hssss--s! I'm going to eat you, BILL!!
Aarrr--gh!
TROLL eats BILL, belches, and returns to DUNGEON
NIL

==> (bill 'current-position)
HEAVEN
@end(programexample)
On the other hand if BILL had been carrying a PIZZA, the incident above
would have had a happier ending:
@begin(programexample)
==> (bill 'current-position)
BLDG-10

==> (bill 'list-possessions)
PIZZA
NIL

==> (troll 'move)
TROLL moved from EGG-ATRIUM to BLDG-10
TROLL says - Hssss--s! I'm going to eat you, BILL!!
BILL says - Take this pizza instead, please!
TROLL says - OK, thanks! - and returns to DUNGEON
NIL

==> (bill 'list-possessions)
NIL
@end(programexample)
An incomplete version of a procedure MAKE-TROLL is included in your file.
Specifically, the sub-procedure EAT-PERSON needs to be completed. If the 
SELECTED-PERSON has a pizza among his possessions, then the
SELECTED-PERSON should lose the pizza (which should also be removed from
the list of objects at the current place). Otherwise, the SELECTED-PERSON
should be UNQUEUE'd from the queue (which is the way the CLOCK keeps
track of who's alive in our world) and sent to HEAVEN. In either case, the
TROLL should then be removed from the current place and reestablished in 
the DUNGEON with his hunger temporarily satisfied by being reset to 0.
Along the way, feel free to make the TROLL and his victim engage in any
dialog you feel is appropriate. Add a procedure to actually
make the TROLL and install him in the DUNGEON. Test your work by reloading
@a(ps6.scm) and exercising it as above.

@paragraph(Problem 5)
Finally, let's add still one more character to our menagerie -- an officious
DEAN who is paranoid on the subject of beer on campus. When he can no longer
control himself, the DEAN wanders about; any beer he finds, he smashes. 
A procedure MAKE-DEAN is included in your package. To complete it, you need
to write a simple procedure WHO-HAS-BEER which, given a PLACE, will return
a list of the PERSONs at that PLACE who have BEER among their possessions;
if there are no such PERSONs, WHO-HAS-BEER should return NIL. Add a procedure
to actually make the DEAN and install him in the DEAN-OFFICE. Test your
work as above.

@paragraph(Problem 6)
There are many ways in which our world might become the scene for an 
interesting game. For example, add a new place SNACK-BAR to the set of places,
which one can get to from BLDG-10 by going 'EAST and from which one can
return to BLDG-36 by going 'WEST. (Due to a serious miscalculation by the
Admissions Office, MIT in our world 
has so many students that the Campus Patrol has
had to make some Institute corridors one-way.) Define things BEER and PIZZA
and cause them to 'APPEAR in the SNACK-BAR. Add expressions to the CLOCK
procedure to cause the DEAN and the TROLL to 'MOVE when CLOCK is invoked.
Your goal is to get from the DORMITORY to the SNACK-BAR, pick up both BEER
and PIZZA, and get back to the DORMITORY for a party without losing your
possessions or being eaten by the TROLL. Alternate your moves with calls
to (CLOCK) to move the other PERSONs in our world. The difficulty of the
game can be altered by changing the HUNGER and OFFICIOUSNESS thresholds of the
TROLL and DEAN. Have fun!

@paragraph(References)
If you are interested in programming languages based on message passing you
might enjoy reading the following articles:

[1] Xerox Learning Research Group, "The Smalltalk-80 System", Byte Magazine,
Vol. 6, No. 8 (August 1981), p. 36;

[2] Hewitt, C., "Viewing Control Structures as Patterns of Passing Messages",
A. I. Journal, Vol. 8, No. 3 (June 1977), pp. 323-364.   