ガウディ本やってるついでにPrologをやってみた。
・・・と言えるほど暇ではないはずなんですが、やりました。
とりあえず簡単な基礎文法を書いていきます。
今日やって今日書いてという感じでやっているので間違い勘違いはあるかもしれません。
・記号
英小文字(a,b,…,z)の後に0文字以上の英数字かアンダースコア(_)を続けたもの。
・変数
英大文字(A,B,…,Z)かアンダースコア(_)の後に0文字以上英数字を続けたもの。
・リスト
[要素1, 要素2, 要素3, …]と書いたもの。要素が0個の[]はnilと書くこともできます。
・述語
関係を表すもの。たとえば「taro」と「ichiro」があったとすると
father_of(taro,ichiro).
のように書いて「taro」が「ichiro」の父親であるという関係を表すことができます。
一般には述語は
述語(引数1, 引数2, …).
のように書きます。
・事実
先ほどのfather_of(taro, ichiro).のようなものを事実といいます。
事実は「正しい関係」を表すものです。
ところで、ここで
mather_of(hanako,ichiro).
と「ichiro」の母が「hanako」であるという事実をつけ加えてみましょう。
さらにここで「ichiro」の両親はだれか、という質問をPrologにまたやってもらうことにします。
その時、規則というものを用います。
・規則
もともと存在する述語を用いて新たな述語を定義します。
いいかえると新しい述語Pを既存の述語Qを用いて「PならばQ」で表します。たとえば、上の両親を表す「parents_of(,)」という述語を作る場合、次のようにします。
parents_of(X,Y) :- father_of(X,Y). parents_of :- mather_of(X,Y).
またこの規則と変数を用いることで子供を
child_of(X,Y) :- parents_of(Y,X).
のように定義することもできます。
ここでたとえば、「taro」の息子の父親はだれか、という質問をするとしましょう。(明らかですが。)
その答えをPrologに出してもらいましょう。その時、さっき定義した「father_of(,)」と「child_of(,)」だけを用いて行おうとすると、「,」が連言(and)であることを用いて
child_of(X,taro) ,father_of(Y,X).
のように書けば、PrologがYに「taro」の息子の父親がだれかを出力してくれます。
この規則という概念を用いると、再帰的な定義もできることが分かります。
たとえば先祖という述語は次のように定義できます。
ancestor_of(X, Y) :- parent_of(X, Y). ancestor_of(X, Y) :- parent_of(Z, Y) ,ancestor_of(X, Z).
これでここまでで基礎文法は終わり、ですかね。
実際のリスト処理とか探索とか言語処理とかは完全に無視って感じですけど。
また機会があればやろうかなと思います。