mops.lisp is
            an implementation of a simple hierarchical frame memory, such as that
            used for implementing Schank's Memory
            Organization Packets (MOPs).
A frame is a very general data structure, useful for representing different kinds of knowledge, including concepts, abstractions, indices, and so on. This package provides the basic functionality of frames, for use and extension by other packages.
A frame represents a concept. Each frame has
- a name,
- a list of immediate abstractions, and
- a list of slots.
The slots give information about attributes of name} and have 
            roles, e.g., color with fillers, 
            e.g., grey. Fillers are
            often the names of other frames.
Here are examples of three very different concepts being represented, a concrete object, an abstraction, and an event involving the object:
| clyde-1
        absts: elephant
        slots:
            name = Clyde
            age = 15 | 
| elephant
        absts: mammal
        slots:
        color = grey | 
| event-1
        absts: event
        slots:
            actor = clyde-1
            action = ingest
            object = peanuts-1 | 
The chain of links from a frame to its immediate abstractions, and from the immediate abstractions of their abstractions, and so on, forms an abstraction hierarchy. For example, we might have the hierarchy "clyde is an elephant, an elephant is a mammal, a mammal is an animal, and an animal is a thing."
Using the code in
            mops.lisp, the
            simple examples above could be defined as follows:
(definstance clyde-1 (m-elephant) :age 15 :name clyde)
        (defmop m-elephant (m-mammal) :color grey)
        (definstance event-1 (m-event)
        :actor clyde-1
        :action m-ingest
        :object peanuts-12)
            
            A frame can have more than one abstraction, e.g., if
            clyde-1 performed in a circus, we might write:
(defmop clyde-1 (elephant circus-performer) ...)
MOP Functions
The following briefly describes the functions defined in mops.lisp.
(defmop name abstractions role1 filler1 role2 filler2 ...) => name
        (definstance name abstractions role1 filler1 role2 filler2 ...) => name
        (add-frame name :type type :abstractions abstractions :slots slots)
        (add-instance name slots) => name
            
            defmop defines a MOP abstract concept. definstance
            defines an instance of a MOP. add-instance is
            the function for adding an instance
            that code such as a parser would call
            to make instances on the fly.
The name can be any Lisp symbol. abstractions should be a list of names of other MOPs. Each role should be a symbol, and by convention, keywords are used. For instances, filler is either a number, string, or name of a MOP or instance. For MOPs, the full form of a filler is a list of the form (:filler value :constraint constraint). The value can be a number, string, or name of a MOP or instance, and is a default value to be inherited by instances of this MOP. The constraint can be a MOP and is a type-constraint. Both :filler value and :constraint constraint are optional. The form (:filler value) can be given as just value, as in instances.
For example, to define an elephant, with default color grey and color constrained to be some instance of color:
(defmop m-elephant (m-animal)
            :color (:filler grey :constraint m-color))
            
            The core underlying function is add-frame. This is used by the other functions to construct the internal frame structure and insert it into the abstraction hierarchy. It takes a name for the MOP or instance plus the following keyword parameters:
- :type -- either :mop or :instance.
- :abstractions -- a list of names of MOPs
- :slots -- a list of slot forms, which are lists of the form (role filler) where role and filler are as described above.
(mop-p name) => true or false
        (instance-p name) => true or false
            
            mop-p and instance-p
            test if name names a MOP or MOP instance, respectively.
            
(find-instances name slots) => list of instances
Returns all instances of name with slots
            whose fillers are equal to or specializations of the corresponding
            fillers in slots. slots has the form (role1
            filler1 role2 filler2 ...). Example call:
            
            
(find-instances 'animal (list :color gray))
(frame-of name) => frame or nil
        (->frame name) => frame
            
            These both return the internal frame for a name. -> will create one if it doesn't exist.
(absts-of name) => list of names
        (slots-of name) => list of slots
        (all-absts-of name) => list of names
            
            absts-of and slots-of
            return the abstractions and slots explicitly defined for 
            a MOP. 
            all-absts-of returns the linearization
            of all the
            abstractions of name, including name}, with no
            duplicates, sorted by specificity, with the most specific item first.
            
(abstp abst spec) => true or false
abstp returns true if abst is
            either eql to or some abstraction of spec.
            Non-frames, such as numbers and strings, are abstractions of
            themselves.
(slot-role slot) => slot name
        (slot-filler slot) => slot filler
        (role-filler name role) => filler
        (inherit-filler name role) => filler
        (<- name role1 role2 ...) => filler
            
            These are the basic functions for accessing fillers of
            slots in a frame. slot-role and slot-filler
            operate on the slot objects returned by slots-of.
            More commonly, you use role-filler to get the filler, if
            any, of role in the frame name. inherit-filler
            is like role-filler but searches the abstraction hierarchy.
            <- -- not to be confused with backward chaining -- does
            a sequence of inherit-filler's. For example (<- 'event-1
            :actor :age) would get the age of the actor of event-1.
(clear-memory)
        (show-frame name)
        (show-memory [name stream slots-p]) 
            
            clear-memory erases all frames from memory.
            show-frame displays a MOP in
            readable form.
            show-memory shows all the frames in memory, in tree form.
            If name is given, only that MOP and its children are shown.
            If stream is given, output is to that stream, rather than
            *standard-output*. 
            If slots-p is true, the slots of each frame are shown.