The ALPINE System

This help file describes how to use the Alpine system for both
generating and using abstractions.  Alpine is implemented on top of
the Prodigy problem solver, so you will need to load both the Prodigy
system and Alpine.  Once you have both systems loaded, you can execute
the abstraction commands within Prodigy.  The command 'abs-solve'
first constructs an abstraction hierarchy and then attempts solve a
problem using the hierarchy.  Alpine first does some preprocessing of
the domain before execution and then constructs a problem-specific
abstraction hierarchy before problem solving begins.  To force the
system to perform the proprocessing, use the 'abs-create' command.
Also, to turn on or off the abstraction trace information, use the
abs-text command.  The trace is turned on by default.  All of these
commands are described in Prodigy's help facility.

Before the abstraction module can be used, the following variables 
must be initialized: *AXIOMS, *VARIABLE-TYPING*, *VARIABLE-EXPANSION*,
*PRIMARY*, *SINGLE-HIERARCHY*.  The meaning of each variable is 
described below.  You can set them all to nil, but you may not get
any abstraction of the problem domain.

*AXIOMS*

This variable is used to state the axioms of a problem domain.  The
form of the axioms is:  (a . (b c d ...)).  This is interpreted as 
if a holds, then b, c, d, ... all follow.  The axioms should only be
used to state invariant conditions, which means that they hold in
every state of a problem space.  Note that you must use unique
variable names for the variable in different axioms.  This is to avoid
equating two variable that are not related. 

Here are the axioms used in the STRIPS domain:

(setq *AXIOMS* 
      '(
        ;; If two boxes are next to each other then they must be in
        ;; the same room.
	((next-to <box.1-1> <box.2-1>) . ((inroom <box.1-1> <room.1-1>)
					  (inroom <box.2-1> <room.1-1>)))
        ;; If the robot is next to a box it must be in the same room
        ;; as the box.
	((next-to robot <box.1-2>) . ((in-room <box.1-2> <room.1-2>)
				      (in-room robot <room.1-2>)))
	;; If the robot is next to a door then it must be in one of
        ;; the rooms next to the door.  Note the use of the static 
	;; predicate 'connects' to map the door to the rooms.
	((next-to robot <door.1-3>) . ((connects <door.1-3> <room.x-3> <room.y-3>)
				       (in-room robot <room.x-3>)))
	;; If the door is not closed, then it is open.
	((~ (statis <door.1-4> closed)) . ((statis <door.1-4> open)))
	;; If the door is not open, then it is closed.
	((~ (statis <door.1-5> open)) . ((statis <door.1-5> closed)))
	))


*VARIABLE-TYPING*

This variable is used to define the types of the variables and
constants.  You can set this variable to nil and the system will treat
everything as the same generic type.  Doing this will not cause any
problems, but the system may not be able to make useful distinctions
between predicates that have different argument types.  

There are two pieces of typing information: isa and isa-instance. 
The isa conditions define the type hierarchy and the isa-instance
defines the instances in the hierarchy.  In addition to specifying
these relations, you must also type each of the variables in the
operator definitions.  This is done by preceeding the variable with
the type followed by a '.'.  For example, to define the variable <x>
as type box, you would replace <x> with <box.x>.  Note that a
restriction on the typing is that things can only be defined as the
types on the leaf nodes.  Thus, in the example below, you should not 
define either variables or constants as type object.  

The form of this specification is: (isa x y) and (isa-instance z x).
The first condition specifies that the type x is of type y.  The type
'type' is defined by the system and is the root of the type hierarchy.
The second condition specifies that the constant z is of type x.

(setq *VARIABLE-TYPING* '(
			  (isa 'robot 'type)
			  (isa 'box 'object)
			  (isa 'door 'object)
			  (isa 'object 'type)
			  (isa 'room 'type)
			  (isa 'loc 'type)
			  (isa 'status 'type)
			  (isa-instance 'open 'status)
			  (isa-instance 'closed 'status)
			  (isa-instance 'robot 'robot)
			  (isa-instance 'box.a 'box)
			  (isa-instance 'box.b 'box)
			  (isa-instance 'box.c 'box)
			  (isa-instance 'box.d 'box)
			  (isa-instance 'box.e 'box)
			  (isa-instance 'box.f 'box)
			  (isa-instance 'room.uni 'room)
			  (isa-instance 'room.mys 'room)
			  (isa-instance 'room.ram 'room)
			  (isa-instance 'room.hal 'room)
			  (isa-instance 'room.pdp 'room)
			  (isa-instance 'room.clk 'room)
			  (isa-instance 'room.ril 'room)
			  (isa-instance 'door.unimys 'door)
			  (isa-instance 'door.mysram 'door)
			  (isa-instance 'door.ramhal 'door)
			  (isa-instance 'door.myspdp 'door)
			  (isa-instance 'door.pdpclk 'door)
			  (isa-instance 'door.mysclk 'door)
			  (isa-instance 'door.ramclk 'door) 
			  (isa-instance 'door.clkril 'door)
			  ))

*PRIMARY*

This variable is used to specify the primary effects of the operators.
The system uses this information both in constructing the abstractions
and it generates a set of search control rules that enforce the
primary effects during problem solving.  The form of the specification
is (a . (b c d...)), where a is a literal and b c d ... are operators
that have a as a primary effect.  

(setq *PRIMARY* '(
      ((next-to robot <box>) . (GOTO-BOX))
      ((next-to robot <door>) . (GOTO-DOOR))
      ((at robot <loc.x> <loc.y>) . (GOTO-LOC))
      ((next-to <box.1> <box.2>) . (PUSH-BOX))
      ((next-to <box> <door>) . (PUSH-TO-DOOR))
      ((at box <loc.x> <loc.y>) . (PUSH-TO-LOC))
      ((in-room robot <room>) . (GO-THRU-DOOR))
      ((in-room <box> <room>) . (PUSH-THRU-DOOR))
      ((statis <door> open) . (OPEN-DOOR))
      ((statis <door> closed) . (CLOSE-DOOR))
      ))

*SINGLE-HIERARCHY* 

This variable can be used to generate a single abstraction hierarchy
for the entire problem domain.  Simply set this condition to a list of
all the possible uninstantiated top-level goals and the system will
then construct the appropriate hierarchy.

(setq *SINGLE-HIERARCHY* nil)


*VARIABLE-EXPANSION*

This variable can be used to force the system to treat every instance
of a literal as a separate type.  Simply set the variable to 't' to
enable this feature.  However, this is an experimental feature of the
system that may or may not work.  Use at your own risk.

(setq *VARIABLE-EXPANSION* nil)
