フレーム型知識表現の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 ley)))
       (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)))