next up previous
Next: 課題 Up: ソフトウェア特論 講義資料 前向き推論,後ろ向き推論 Previous: 7 組み込み述語

8 名前無し変数の導入

ある述語を定義する場合に,名前のない変数で 定義してもよくすることを考えるとします. たとえば,memberは次のように定義します.

(<- (member ?item (?item . ?)))
(<- (member ?item (? . ?rest)) (member ?item ?rest))
これを処理するには,節の中に?があれば それを同じ変数に置き換えるということw すればよいので以下のように

(defmacro <- (&rest clause)
  `(add-clause ',(replace-?-vars clause)))

(defmacro ?- (&rest goals)
  `(top-level-prove ',(replace-?-vars goals)))

(defun replace-?-vars (exp)
  (cond
   ((eq exp '?) (gensym "?"))
   ((atom exp) exp)
   (t (cons
       (replace-?-vars (car exp))
       (replace-?-vars (cdr exp))))))
これにより,

[4]> (?- (member ? (1 2 3)))
?325 = 1;

?325 = 2;
?325 = 3;
No.

[5]> (?- (member ?x (1 2 3)))
?X = 1;

?X = 2;
?X = 3;
No.
という形になります. ここで,?の変数が入っていない場合にも consによってメモリを消費するので, 入っていない場合にはconsしない という具合にすれば効率がよいので 次のようにします.

(defun replace-?-vars (exp)
  (cond
   ((eq exp '?) (gensym "?"))
   ((atom exp) exp)
   (t (reuse-cons
       (replace-?-vars (car exp))
       (replace-?-vars (cdr exp))
       exp))))

(defun reuse-cons (x y x-y)
  (if
      (and (eql x (car x-y))
           (eql y (cdr x-y)))
      x-y
    (cons x y))
  )
(reuse-cons x y x-y)は x-yのcar が xで cdrがyと同じで あればconsせずにx-yをそのまま 使うというものです.
next up previous
Next: 課題 Up: ソフトウェア特論 講義資料 前向き推論,後ろ向き推論 Previous: 7 組み込み述語
generated through LaTeX2HTML. M.Inaba 平成18年5月21日