フレーム型知識表現のLispによる実装例


(defun fget (frame slot facet)
   (cdr (assoc facet 
         (cdr (assoc slot 
            (cdr (get frame 'frame)))))))

(putprop 'Henry
  '(Henry 
        (a-kind-of (value man))
     (height (value 1.78))
    (weight (value 75))
    (hobies (value jogging skiing))
    (licence (if-needed ask answer))
    (occupation (value teaching research)))
    'frame)

(defun extend (key a-list)
   (cond ((assoc key (cdr a-list)))
       (t 
        (cadr 
                  (rplacd 
                     (last a-list) 
                     (list (list key)))))))

(defun follow-path (path a-list)
   (cond ((null path) a-list)
       (t 
        (follow-path 
                    (cdr path) 
                    (extend (car path) a-list)))))

(defun fget-frame (frame)
   (cond ((get frame 'frame))
       (t 
        (setf (get frame 'frame) 
                      (list frame)))))

(defun fput (frame slot facet value)
   (let ((value-list 
               (follow-path 
                   (list slot facet) 
                   (fget-frame frame))))
    (cond ((member value value-list 
                        :test #'equal)
                nil)
        (t 
         (rplacd 
                     (last value-list) 
                     (list value))
                   value))))

(defun fremove (frame slot facet value)
   (let ((value-list 
              (follow-path 
                  (list slot facet) 
                  (fget-frame frame))))
    (cond ((member value value-list 
                        :test #'equal)
        (delete value value-list 
                        :test #'equal)
        t)
        (t nil))))

(defun fcheck (frame slot facet value)
   (cond ((member value 
                 (fget frame slot facet) 
                     :test #'equal)
                  t)
       (t nil)))

(defun fclamp (frame1 frame2 slot)
   (rplacd (fget-frame frame1)
        (list (follow-path 
                         (list slot) 
                         (fget-frame frame2))))
   slot)

(defun fget-v-d (frame slot)
   (cond ((fget frame slot 'value))
      ((fget frame slot 'default))))

(defun fget-v-d-p (frame slot)
   (cond ((fget frame slot 'value))
      ((fget frame slot 'default))
      (t 
       (mapcan
         #'(lambda (demon) 
                      (fucall demon frame slot))
        (fget frame slot 'if-needed)))))

(defun ask (frame slot)
   (print `(Please supply a value for the
       ,slot slot in the
       ,frame frame))
       (terpri)
       (let ((response (read)))
       (cond (response (list response))
          (t nil))))

(defun answer (&rest l)
   (print '(It has been abswered)))

(setf *print-length* 200)

(setf *print-level* 6)

(defun caluculate-weight (frame slot)
  (let ((heigh (fget-v-d frame 'height)))
    (cond (height (list (fput frame
                 'weight
                 'value
         (* 33 (car height))))))))

(putprop 'man
   '(man (a-kind-of (value human))
      (hobbies (if-removed report report) 
           (value music reading))
     (height (if-added caluculate-weight)))
     'frame)

(putprop 'human
     '(human (a-kind-of (value being))
         (place (value earth)))
     'frame)

(defun report (&rest l)
   (print '(The data has been removed)))

;;;
;;; (fget-classes 'Henry)
;;;      ===>(Henry man human being)
;;;
(defun fget-classes (start)
  (reverse (fget-classes1 (list start) nil)))

(defun fget-classes1 (queue classes)
  (cond ((null queue) classes)
     (t 
      (fget-classes1
      ;;;
      (append 
               (fget (car queue) 'a-kind-of 
                                 'value)
        (cdr queue))
        ;;;
        (cond ((member (car queue) classes)
           classes)
           (t 
            (cons (car queue) classes)
                      ))))))

;;;
;;; I-inheritannce
;;;
(defun fget-i (frame slot)
  (fget-i1 (fget-classes frame) slot))

(defun fget-i1 (frames slot)
  (cond ((null frames) nil)
     ((fget (car frames) slot 'value))
     (t 
      (fget-i1 (cdr frames) slot))))

;;;
;;; Z-inheritannce
;;;
(defun fget-z (frame slot)
  (fget-z1 slot (fget-calasses frame)))

(defun fget-z1 (slot classes)
  (cond ((null classes) nil)
     ((fget-v-d-p (car classes) slot))
     (t 
      (fget-z1 slot (cdr classes)))))

;;;
;;; N-inheritance
;;;
(defun fget-n (frame slot)
   (let ((classes (fget-classes frame)))
    (cond ((fget-n1 slot classes 'value))
       ((fget-n1 slot classes 'default))
       ((fget-n2 slot classes 'if-needed))
      (t nil))))

(defun fget-n1 (slot classes key)
   (cond ((null classes) nil)
      ((fget (car classes) slot key))
      (t 
       (fget-n1 slot (cdr classes) key))))

(defun fget-n2 (slot classes key)
   (cond ((null classes) nil)
      ((mapcan #'(lambda (demon) 
                (funcall demon 
                         (car classase) slot))
         (fget (car classes) slot key)))
      (t 
       (fget-n2 slot (cdr classes) key))))

;;;
;;;
;;;
(defun fput-p (frame slot facet value)
  (cond ((fput frame slot facet value)
      (mapcar #'(lambda (e)
       (mapcar #'(lambda (demon) 
                 (funcall demon frame slot))
           (fget e slot 'if-added)))
          (fget-classes frame))
      value)))

;;;
;;;
;;;
(defun remove-p (frame slot facet value)
   (cond ((fremove frame slot facet value)
       (mapcar #'(lambda (e)
        (mapcar #'(lambda (demon) 
                   (funcall demon frame slot))
           (fget e slot 'if-removed)))
           (fget-classes frame))
       value)))

;;;
;;;
;;;
(defun copy-frame (name1 name2)
  (let ((lst 
            (list 
               name2 
               (second (fget-frame name1)))))
   (putprop name2 lst 'frame)))