prolog tutorial
prolog プログラムをスクリプトとして実行したい場合は、少し面倒?
比較的メインの実行系?
like(X, Y)
という問い合わせ(Qurey)で、述語? によって定義されている 事実(Fact) が列挙される。
複数の事実が定義されている場合、REPL上では続けて ;
を入力することで、他の候補を表示することができる。
「述語(verb?)」という言葉は LPN では登場しないが、これは Rule に当たるのか?
あるいは、LPNでも今後「述語」に対応する語が出てくるのか。
Prolog は複数の事実を用いて、ひとつの事実を表すことができます。これを 規則 (rule) といいます。一般に規則は次のような形をとります。
規則(Rule) != 述語(verb?)。述語は Prolog の語彙に含まれているのかいないのか、LPNを読む必要がありそう。一旦、「述語」という語用は取り扱いを保留。
「事実」の定義はひとかたまりにしないと、warningが出る模様。
born_in(major_zero, england).
born_in(naked_snake, america).
like(major_zero, tee).
like(naked_snake, coffee).
はOKだが
born_in(major_zero, england).
like(major_zero, tee).
born_in(naked_snake, america).
like(naked_snake, coffee).
は warning が出る
Warning: Clauses of born_in/2 are not together in the source-file
Warning: Earlier definition at /file/hoge.pl:2
Warning: Current predicate: like/2
Warning: Use :- discontiguous born_in/2. to suppress this message
Prolog では大文字始まりの値は特別な意味を持つ。
変数は「規則」の定義や「問い合わせ(Query)」に利用できる。
like_coffee(X) :- like(X, coffee).
like_tea(X) :- like(X, tea).
british_gentlemen(Who) :- like_tea(Who), born_in(Who, england).
という「事実」が定義されていたとして、以下のように問い合わせれば、その規則を満たす Who としてどのような候補がいるのかが出力される。
?- british_gentlemen(Who).
Who = major_zero.
問い合わせの際、「変数」を用いずに具体的な値を指定すれば、その値がその「規則」を満たしいているかどうかが出力される。
?- british_gentlemen(major_zero).
true.
?- british_gentlemen(naked_snake).
false.
?- british_gentlemen(sigint).
false.
?- british_gentlemen(para_medic).
false.
最終的には LPN か。
規則の定義に用いる事実は、規則を定義した後に定義しても良い
fly(X) :- airplane(X).
airplane(jet_plane).
airplane(helicopter).
?- fly(jet_plane).
true.
?- fly(helicopter).
true.
?- fly(bycicle).
false.
Prolog では、2 つのパターンともに変数を含んでいる場合のマッチングをユニフィケーション (unification) と呼び、片方のパターンだけに変数が含まれる場合のマッチングを パターンマッチング (pattern matching) として区別します
unification と pattern matching の区別
Prolog で p(a, b) と書いた場合、a は b の p なのか、それとも a の p が b なのか、はっきりしないことがあります。たとえば、father(taro, ichiro). の場合、太郎は一郎の父親なのか、それとも太郎の父親が一郎なのか、はっきりわからないのです。
英語では前者を taro is father of ichiro と書きますので、Prolog でも father_of(taro, ichiro) と _of をつけて表すことが多いようです。
ポーランド記法的な命名慣習、という印象
規則を定義するとき、満たすべき事実や規則が複数ある(and条件)場合は、 ,
区切りで満たすべき事実や規則を記述する
british_gentlemen(Who) :- like_tee(Who), born_in(Who, england).
いくつかの規則や事実の内、一部を満たせば良い(or条件)場合は、それぞれ満たすべき事実・規則の組み合わせごとに、規則を定義する
fly(X) :- airplane(X).
fly(X) :- superman(X).
airplane(jet_plane).
airplane(helicopter).
superman(taro).
Prolog では「英大文字かアンダーラインで始まる文字列」が変数として扱われますが、その他に、アンダーライン一文字のみの、「無名変数」と呼ばれる特殊な変数があります。
この無名変数が使われるのは、「節のなかに一つしかなく、その値がなんであろうが構わない」という場合です。
例えば、再帰処理の停止条件として「ある引数が 0 ならば真」というような節を定義することがありますが、その場合、他の引数は何であろうと関係がありませんので、それらは無名変数にできるわけです。
concat([], Xs, Xs).
concat([X | Xs], Ys, [X | Ls]) :- concat(Xs, Ys, Ls).
?- concat([a,b,c], [d,e,f], Ls).
Ls = [a, b, c, d, e, f].
?- concat([a, b, c], Ls, [a, b, c, d, e]).
Ls = [d, e].
?- concat(X, Y, [a, b, c]).
X = [],
Y = [a, b, c] ;
X = [a],
Y = [b, c] ;
X = [a, b],
Y = [c] ;
X = [a, b, c],
Y = [] ;
リストを結合させる規則を一度定義すると、その規則を用いて逆にリストを分解したり、結合後のリストを作るためにあり得るリストの組み合わせを出力できる