http://www.geocities.jp/m_hiroi/xyzzy_lisp/abclisp23.html

変数のユニフィケーションについてリンク先で勉強。

リンク先コードで私が理解できた範囲のコメントを記述。

変数の統合は色々なパタンを考えると意外と難しそう。

 

 

; unify.l : ユニフィケーション
;
;           Copyright (C) 2003 Makoto Hiroi
;
 
;
; 要素はパターン変数か
(defun variablep (pattern)
  (and (symbolp pattern)
       (char= #\? (char (string pattern) 0))));束縛変数だった
variablep
 
(defun add-binding (var value binding)
  (cons (cons var value) binding));束縛変数のkeyとvalueを追加
add-binding
 
;
; ユニフィケーション
;
(defun unify (pattern datum binding)
  (cond ((variablep pattern);束縛変数一つだったら
         (unify-variable pattern datum binding));束縛変数がいままで出てきたものだったらvalueにしてからこの関数に帰ってくる
        ((variablep datum)
         (unify-variable datum pattern binding));同じく束縛変数をvalueにしてからこの関数に帰ってくる
        ((and (atom pattern) (atom datum))
         (unify-atoms pattern datum binding));アトムになったので普通に変数として比較
        ((and (consp pattern) (consp datum))
         (unify-pieces pattern datum binding));まだリストなのでアトムになるまで分解していく
        (t 'fail)))
unify
 
 
;
; アトムとのユニフィケーション
;
(defun unify-atoms (pattern datum binding)
  (if (equal pattern datum) binding 'fail));比較したアトムが同じなら駄目
unify-atoms
 
 
;
; リストのユニフィケーション
;
(defun unify-pieces (pattern datum binding)
  (let ((result (unify (car pattern) (car datum) binding)));ここでcar patternとcar datumで一つのアトムにまで分解する作業を続ける
    (if (eq result 'fail)
        'fail
        (unify (cdr pattern) (cdr datum) result))));アトムの分解が終わったのでリストの次へ移動する
unify-pieces
 
 
;
; 変数とのユニフィケーション
;
(defun unify-variable (pattern datum binding);関数の呼び出し場所でこの関数のpatternは束縛変数一個になることが保証
  (let ((value (assoc pattern binding)));でてきた束縛変数が今まで出てきたものと同じか調べる
    (if (and value
             (not (eq pattern (cdr value))));今まで出てきた束縛変数と同じだった
        (unify (cdr value) datum binding);束縛変数を具体的な値にして再度unifyを実行
        (if (insidep pattern datum binding);束縛変数が残りのリストで出てこないことをチェック
            'fail
            (add-binding pattern datum binding)))));出てこなかったので追加
unify-variable
 
 
;
; datum の中に var があるか
;
(defun insidep (var datum binding)
  (unless (eq var datum);変数の統合が目的なので同じ束縛変数は無視する
    (inside-sub-p var datum binding)))
insidep
 
 
;
; insidep 本体
;
(defun inside-sub-p (var datum binding);この関数はチェックしか行わなわず他の関数と関係を持たない
  (cond ((eq var datum) t);同じ変数ならユニフィケーションする意味がない
        ((atom datum) nil);nilまで分解したのでnilを返す
        ((variablep datum);datumがアトムにまで分解されこれが束縛変数だった
         (let ((value (assoc datum binding)));datumは束縛変数になっているので探す
           (if value
               (inside-sub-p var (cdr value) binding))));束縛変数に対応するvalueを返す
        (t
         (or (inside-sub-p var (car datum) binding);datumをアトムになるまで分解しリストの残り全部と変数を照合する
             (inside-sub-p var (cdr datum) binding)))))
inside-sub-p
 

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2012年08月11日 19:04