			  A Memory Operator for Soar
			      Paul S. Rosenbloom
			       January 24, 1990

The Memory operator provides the ability to memorize arbitrary objects --
graph structures with loops, lattices, and multi-attributes.  A relatively
simple and efficient version of datachunking is used to accomplish this.

To use it, you must first load in the file "memory.soar".  The next step is to
specify the set of primitive symbols upon which the data chunking is to be
based (all data chunking must be based on primitive symbols).  The default set
of symbols is (goal problem-space state operator object name), but this can be
changed by using the function define-known-symbols, for example:

    (define-known-symbols
        '(class instance name subclass isa mammal cat dog morris))

The next step is to generate and select an instance of the memory operator.
The operator takes two arguments: ^learn and ^cue.  The value of ^learn should
be the identifier of the object to be learned.  The value of ^cue should be
the identifier of a cue object that appropriately restricts the situations in
which the learned object is to be retrieved.  Here is a simple example that
uses the revised symbols above.

    (operator x4 ^name memory ^learn o5 ^cue o6)
       (class o5 ^name mammal ^subclass o8 o7)
          (class o7 ^name dog ^isa o5)
          (class o8 ^name cat ^isa o5 ^instance o9)
             (instance o9 ^name morris ^isa o8)
       (instance o6 ^isa o10)
          (class o10 ^name cat)

When the operator is selected, all objects that were previously learned for
the same cue (or for any cue which contains a subset of its structure) are
retrieved as values of the ^recalled attribute (with parallel preferences).
If the object to be learned is not among those that were retrieved, it is then
learned.  The result is a chunk which tests the cue and generates the object
to be learned.

    (SP P120 ELABORATE
       (GOAL <G1> ^OPERATOR <X1>)
       (OPERATOR <X1> ^NAME MEMORY ^CUE <O1>)
       (INSTANCE <O1> ^ISA <O2>)
       (CLASS <O2> ^NAME CAT)
     -->
       (INSTANCE <X4> ^ISA <X5> + ^NAME MORRIS +)
       (CLASS <X5> ^INSTANCE <X4> + ^ISA <X3> + ^NAME CAT +)
       (CLASS <X3> ^SUBCLASS <X5> + <X5> &, <X2> &, <X2> + ^NAME MAMMAL +)
       (CLASS <X2> ^ISA <X3> + ^NAME DOG +)
       (OPERATOR <X1> ^RECALLED <X3> &, <X3> +))

If the operator has no cue, then the effective cue is the absence of a cue.
If the operator has no object to be learned, only retrieval of previously
learned objects occurs.

To make it easy to experiment with the memory operator, the file
"interface.soar" can be loaded.  The main thing this file does is define two
functions -- define-learn-structure and define-cue-structure -- which set up
the initial information about the structure to be learned and the cue.  The
following calls were used to define the example above.

    (define-learn-structure
      '((class <o1> ^name mammal ^subclass <o2> <o2> & ^subclass <o3> <o3> &)
        (class <o2> ^name dog ^isa <o1>)
        (class <o3> ^name cat ^isa <o1> ^instance <o4>)
        (instance <o4> ^name morris ^isa <o3>))
    )

    (define-cue-structure
      '((instance <o5> ^isa <o6>)
        (class <o6> ^name cat))
    )

Once these structures are defined, doing a (run-task) will cause an
appropriate instance of the memory operator to be created and selected, and
for the object to be learned.  Either of the structures can be null, in which
case the appropriate response occurs (as described above).

The file "example.soar" loads in "memory.soar" and "interface.soar", and then
defines the known symbols, the learn structure, and the cue structure for this
example.  To try things out, just load the file, and execute (run-task).
