.he 'PLANNER''Page %'
.fo 'Steven Hardy'- % -'November 1977'
.ce 2
The PLANNER programming language
================================
.sp
This handout briefly describes the programming language PLANNER
so that the reader can better understand the SHRDLU demo which describes
Terry Winograd's natural language understanding system.
.bb
The PLANNER language is syntactically similar to LISP
(a widely used AI programming language) it extends LISP in the way 
DATABASE
and PFUNCTIONS packages extend POP11;
though PLANNER goes much further.
.sp
.sp
As in DATABASE there are ADD and REMOVE functions in PLANNER, for example:
 	: (ADD '(B1 ISA BLOCK))
 	: (ADD '(B1 HASCOLOUR RED))
 	: (ADD '(B2 ISA BLOCK))
 	: (ADD '(B2 HASCOLOUR BLUE))
 	: (ADD '(B3 ISA PYRAMID))
 	: (ADD '(B3 HASCOLOUR RED))
 	: (ADD '(B3 ISON B2))
.br
The PLANNER version of LOOKUP is called GOAL, thus
 	: (GOAL '(?X ISA PYRAMID))
 	: (PRINT X)
 	** B3
.br
In  PLANNER lists are used to represent both programs and data, so there
has be to be an symbol to stop lists being 'evaluated' - that is what
the apostrophe is for in the above PLANNER commands. In POP11 syntax
the last two commands would look like:
.tp2
 	: GOAL([?X ISA BLOCK]);
 	: X =>
.br
.sp
Notice that when we execute
 	: (GOAL '(?X ISA BLOCK))
.br
there are two possible values for X - it might be either B1 or B2.
In POP11, LOOKUP just 'returns' the first value it finds when searching the
current 'context`;
of stored items;
PLANNER  remembers that it has a choice.
Let us suppose that B1 has been chosen and then
go on to execute:
 	: (GOAL '(^X HASCOLOUR BLUE))
.br
The treatment of this command marks an important difference between LOOKUP (in POP11)
and GOAL (in PLANNER).
In POP11 we would get a 'lookup error' since B1 is not coloured blue.
PLANNER, however, is cleverer - it resets its 'state of mind' to
that at the time it made its most recent decision 
(ie choosing B1 instead of B2) and tries another alternative.
This means that the program:
 	: (GOAL '(?X ISA BLOCK))
 	: (GOAL '(^X HASCOLOUR BLUE))
 	: (PRINT X)
.br
will print out
 	** B2
.br
even if B1 is initially chosen as the value of X.
.sp
Roughly, the above lines of PLANNER code correspond to the English
sentence
 	: TELL ME THE NAME OF A BLUE BLOCK
.br
Here is one of many PLANNER translations of:
.tp7
 	: TELL ME THE NAME OF A BLUE PYRAMID ON A RED BLOCK
 	: (GOAL '(?X ISA PYRAMID))
 	: (GOAL '(^X HASCOLOUR BLUE))
 	: (GOAL '(?Y ISA BLOCK))
 	: (GOAL '(^Y HASCOLOUR RED))
 	: (GOAL '(^X ISON ^Y))
 	: (PRINT X)
.br
.sp
We now consider in detail what happens when PLANNER executes
the above program.
First it finds a value for X such that X is a pyramid. It then checks
that X is coloured BLUE; if not PLANNER 'fails back'
to it`s most recent GOAL and chooses a new pyramid as the value of
X.
If there are no more pyramids (or there were none in the first place)
the whole program 'fails'.
.sp
Once a blue pyramid has been found PLANNER looks for a red block.
If it can't find one it 'fails back' to the previous GOAL (as before)
and tries a different blue pyramid (if one exists).
This does not, of course, make it any easier to find a red block
but PLANNER is not clever enough to know that.
.sp
Once a red block has been found PLANNER checks that it supports the
blue pyramid; if not it tries a different red block
(and if there are no more a new blue pyramid).
.sp
If PLANNER seems to be very stupid and wasteful in the way it satisfies
a series of GOALs you will understand why it is no longer used!
However, one advantage of PLANNER is that it is quite easy
to write programs - consider the following POP11 version of the
above PLANNER code:
 	: FOREACH [?X ISA PYRAMID] THEN
 	:   IF PRESENT([^X HASCOLOUR BLUE]) THEN
 	:	FOREACH [?Y ISA BLOCK]) THEN
 	:	    IF PRESENT([^Y HASCOLOUR RED])
 	:		AND PRESENT([^X ISON ^Y]) THEN
 	:			X =>
 	:	    CLOSE
 	:	CLOSE
 	:   CLOSE
 	: CLOSE
.br
.bb
PLANNER has extra ways of helping the programmer.
Suppose you are told that STEVE likes all
big, red blocks - how would you represent this item of information?
You could explicitly store that
 	: (STEVE LIKES B17)
.br
for each big, red block you know of but this would be wasteful
of memory - besides which what happens when a new block
is introduced into the world?
.sp
In PLANNER, you could represent this knowledge as
a so-called
'consequent theorem'.
Thus:
 	: (DEFTHEOREM T17 CONSE (STEVE LIKES ?X)
 	:	(GOAL '(^X ISA BLOCK))
 	:	(GOAL '(^X HASCOLOUR RED))
 	:	(GOAL '(^X HASSIZE BIG)))
.br
This 'theorem' (really just a function) is of type 'consequent', and for want of a better name, is called T17.
If you don't understand what consequent means you will understand why in
CONNIVER, a development of PLANNER, the name was changed to 'ifneeded method'!
.sp
Briefly, consequent theorems are used by the GOAL when it finds that a wanted
fact is not stored explicitly in the database.
It looks for a theorem with a pattern matching the one it is looking
for and runs one if it finds it.
If this runs to completion the wanted item is assumed to be
implicitly in the database.
If the first one fails, GOAL looks to see if there are any more with
the desired pattern. If all fail, the GOAL fails also.
.sp
This mechanism is very useful - as the following
translation of
 	: TELL ME IF STEVE LIKES ANYTHING SUPPORTING A PYRAMID
.br
shows:
 	: (GOAL '(STEVE LIKES ?X))
 	: (GOAL '(?Y ISA PYRAMID))
 	: (GOAL '(^Y ISON ^X))
 	: (PRINT (LIST 'YES '- X 'WHICH 'SUPPORTS Y))
.br
In POP11 syntax the above commands would look like:
 	: GOAL([STEVE LIKES ?X]);
 	: GOAL([?Y ISA PYRAMID]);
 	: GOAL([^Y ISON ^X]);
 	: [YES - ^X WHICH SUPPORTS ^Y] =>
.br
.bb
Notice that in the above example the function for showing that STEVE
likes something has been used to 
.ul
find
something that STEVE likes. This implies that the "^" prefix of PLANNER
is not identical to that of POP11's DATABASE.
In DATABASE, the "^" prefix means 'use the value of'; in PLANNER,
it means
'if the variable has a value use it, otherwise find a value'.
.bb
PLANNER contains various other useful features some of which are exhibited
in the following functions which represent some of the knowledge one needs to manipulate
toy blocks:
 	: (DEFTHEOREM SPC_FR conse (SPACEFOR ?X ON? Y)
 	:	(EITHER (EQUAL Y 'TABLE)
 	:		(GOAL '(CLEARTOP ^Y))))
.br
IE: there is space for X on Y if Y is the TABLE or if Y has a CLEARTOP.
.tp9
 	: (DEFTHEOREM CLR_TP conse (CLEARTOP ?X)
 	:	(PROG (TEMP)
 	:		(IF (GOAL '(?TEMP ISON ^X))
 	:			(GOAL '(^TEMP ISON TABLE))
 	:			(GOAL '(CLEARTOP ^X)))))
.br
IE: to make a block, say X, have a CLEARTOP see if it supports some
other block, say TEMP.
If it does, put TEMP on the TABLE and then check to see if X now has a CLEARTOP.
(The word "PROG" merely indicates that what follows is a bit of
program with local variables - in this case only TEMP).
 	: (DEFTHEOREM PUTON conse (?X ISON ?Y)
 	:	(GOAL '(SPACEFOR ^X ON ^Y))
 	:	(GOAL '(GRASPING ^X))
 	:	(GOAL '(HANDABOVE ^Y))
 	:	(GOAL '(EMPTYHAND) (USE LETGO)))
.br
IE: to put X on Y,
make sure there is SPACEFOR X on Y,
make sure your hand is GRASPING X,
make sure your hand is above Y,
and, finally, make sure your hand is empty (using the function called LETGO).
.sp
Notice the explicit 'advice' given to the PLANNER system in the last line
of the above function.
This ability to give advice is essential,
for in PLANNER there is no really clear distinction made between
checking if something happens to be true at the moment and making it true.
The above programs are inadequate in that they don't contain all the advice necessary
for the programs to run correctly. 
In particular, the various calls of GOAL with arguments matching the
pattern
(?X ISON ?Y)
might trigger the routine PUTON, unless advice is given to the contrary.
Later developments of PLANNER such as POPLER replaced
GOAL by two functions INFER and ACHIEVE.
.bb
To see how you might use some of the ideas of PLANNER in POP11
see the BLOCKSWORLD demo.
