[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Method Selection Error revisited



Here is a code sample of the problem.  I am unable to decipher the problem,
though I suspect that it lies in the time at which my make-frame macro is expanded
.  Here is the code:


? 
(setq *INFO-ITEM*
      (pcl:defclass INFO-ITEM ()
                    ((time-tag :accessor time-tag
                               :initform (get-internal-real-time)))
                    (:documentation "The Generic Information Item holds only
time tag.")))

#<Standard-Class INFO-ITEM 3088594>
? (pcl:defmethod query ((item t) &rest therest)
               ; Create a list of the query, backward-chained results, and
justifications
               (list
                ; Retrieve the query using a specialized generic function
                (CLOS-retrieve item (car therest))
                ; Attempt to backward chain for more answers
                (CLOS-backward-chain item)
                ; Support hooks for a Truth Maintenance System
                (CLOS-support item)))

#<Standard-Method QUERY (T) 3707152>
? (pcl:defmethod store ((item t))
               ; Support hooks to Truth Maintenance System
               (list
                (CLOS-support item)
               ; Store the item using a specialized generic function
                (CLOS-index item)
               ; Forward-chain from the item
                (CLOS-forward-chain item)))

#<Standard-Method STORE (T) 3707972>
? ;;; Generic SUPPORT function does nothing but return nil
(pcl:defmethod CLOS-support ((item t))
               nil)

#<Standard-Method CLOS-SUPPORT (T) 3708684>
? ;;; Generic CLOS-forward-chain function does nothing but return the item
(pcl:defmethod CLOS-forward-chain ((item t))
               item)

#<Standard-Method CLOS-FORWARD-CHAIN (T) 3709452>
? ;;; Generic CLOS-backward-chain function does nothing but return the item
(pcl:defmethod CLOS-backward-chain ((item t))
               nil)

#<Standard-Method CLOS-BACKWARD-CHAIN (T) 3710220>
? ;;; Add a specific retrieval method for predicate-items.  Matches most of
functionality
;;;  of PC-RETRIEVE  backward-chaining in handled in CLOS-BACKWARD-CHAIN.
Returns a list
;;;  of pairs.  The car of each pair is a copy of the query form with variables
replaced.
;;;  the cadr is the varlist.
(pcl:defmethod CLOS-retrieve ((item t) vars)
               (declare (ignore vars))
               'generic-index)


#<Standard-Method CLOS-RETRIEVE (T T) 3710952>
? ;;; PC-item CLOS-BACKWARD-CHAIN method calls FROM-BACKWARD-CHAINING in ded
retriever.
(pcl:defmethod CLOS-backward-chain ((item t))
               'gener-back-chain)

#<Standard-Method CLOS-BACKWARD-CHAIN (T) 3687154>
? ;;; Add a specific storage method for predicate-items.  Matches most of the
functionality
;;;  of PC-STORE in the deductive retriever.  backward-chain is handled by the
;;;  CLOS-backward-chain function.
(pcl:defmethod CLOS-index ((item t))
;make sure pat isn't null.
               'generic-index)

#<Standard-Method CLOS-INDEX (T) 3687874>
? ;;; PC-item CLOS-forward-CHAIN method calls FROM-FORWARD-CHAINING in ded
retriever.
(pcl:defmethod CLOS-forward-chain ((item t))
               'gener-for-chain)

#<Standard-Method CLOS-FORWARD-CHAIN (T) 3688650>
? ;;;;;;
;;;;    PC-item Test cases 
;;;
;;
;

(store '(on sphere3 block2))
(NIL GENERIC-INDEX GENER-FOR-CHAIN)
? (store '(on triangle1 block1))
(NIL GENERIC-INDEX GENER-FOR-CHAIN)
? (store '(on block3 rhombus1))
(NIL GENERIC-INDEX GENER-FOR-CHAIN)
? (store '(on block2 rhombus2))



(NIL GENERIC-INDEX GENER-FOR-CHAIN)
? (defvar *FRAME-DataBase* (Make-hash-table))
*FRAME-DATABASE*
? (setf (gethash '*FRAME-NAMES* *FRAME-DataBase*) (make-hash-table))
#<An EQL HASH-TABLE with 0. entries>
? (setf (gethash '*SLOT-NAMES* *FRAME-DataBase*) (make-hash-table))

#<An EQL HASH-TABLE with 0. entries>
? (setq *FRAME-ITEM*
      (pcl:defclass FRAME-ITEM (INFO-ITEM)
                    ((database :reader database
                               :initform *FRAME-DATABASE*
                               :allocation :class)
                     (*FRAME-TYPE* :initform nil)
                     (*FRAME-NAME* :initform nil)
                     (FRAME-ID :accessor ID
                               :initform (gensym "FRAME")))
                    (:documentation "Frame Information Item")))


#<Standard-Class FRAME-ITEM 2769688>
? (defmacro make-frame (frame-name parents type &rest slot-args)
  (cond ((equal type :CLASS)
         (let ((par (append parents '(FRAME-ITEM))))
           `(let ((theframe (pcl:defclass ,frame-name ,par ,@slot-args)))
              (index-frame-name theframe ',frame-name)
              (pcl:defmethod CLOS-index ((item ,frame-name))
                item)
              theframe)))
        ((equal type :INSTANCE) 
         `(let ((theframe (pcl:make-instance ',parents ,@slot-args

                                             :*FRAME-TYPE* :INSTANCE

                                             :*FRAME-NAME* ',frame-name)))
            (index-frame-name theframe ',frame-name)
            (index-slot-names theframe)
            theframe))
        ((equal type :PATTERN) 
         `(let ((theframe (pcl:make-instance ',parents ,@slot-args

                                             :*FRAME-TYPE* :PATTERN

                                             :*FRAME-NAME* ',frame-name)))
            ; No need to index patterns
            theframe))
        (t nil)))

MAKE-FRAME
? ;;;
;;;  Frame-item interface methods
;;;

;;; Add a specific storage method for frame-items
(pcl:defmethod CLOS-index ((theframe frame-item))
               ; We already called the Make-frame function in the argument.
               theframe)

#<Standard-Method CLOS-INDEX (FRAME-ITEM) 3663770>
? (pcl:defmethod CLOS-retrieve ((theframe frame-item) vars)
               ; We already called the Make-frame function in the argument.
               (match-frame theframe :variables vars))
               

#<Standard-Method CLOS-RETRIEVE (FRAME-ITEM T) 3664668>
? ;;;;;;
;;;;    frame-item Test cases 
;;;
;;
;


(make-frame block () :class ((color)
                                    (len)
                                    (wid)
                                    (height)))

#<Standard-Class BLOCK 2747192>
? (store (make-frame block () :class ((color)
                                    (len)
                                    (wid)
                                    (height))))

(NIL GENERIC-INDEX GENER-FOR-CHAIN)
? 

--------------------- comments continue ---------------
As you can see, the result of calling STORE with a call to MAKE-FRAME is not
the execution of the method for FRAME-ITEMs, but is the GENERIC CLOS-index.
I suspect this is due to the fact that make-frame is a macro, and that what
store gets is not the result of the macro expansion, but the macro closure
itself, which is not a FRAME-ITEM, so the generic CLOS-index is called.  As
you can see, I can't make MAKE-FRAME into a function because DEFCLASS is a
macro, and when I try to pass arguments to it, they are quoted and are therefore
the names of the variables holding the values, rather than the values themselves.

Any help would be appreciated.  I suspect this may be a more CL-oriented question
than CLOS, but here it is.

thanks,

..........................................................................
Jeffrey Sullivan			  | University of Pittsburgh
jas@cadre.dsl.pittsburgh.edu		  | Intelligent Systems Studies Program
jasper@PittVMS.BITNET, jasst3@cisunx.UUCP | Graduate Student