(書きかけ)
当サイトはほぼPrologのみで動作しています。
Prologとは、一階述語論理のサブセットをモデルに作られたプログラミング言語です。
Prologのプログラムは、あるいは宣言的に読むこともできるし、あるいは手続き的に読むこともできます。宣言的に読むとは、宣言型プログラムとして読む、つまり、記述された知識表現を元に、論理的な根拠を処理系が自動的に明らかにするプログラムにとして読むということです。手続き的に読むとは、手続き型プログラムとして読む、つまり、記述された指示にしたがい、解を得る操作を順次行うプログラムとして読むということです。このどちらの読み方も可能であるという意味で、Prologのプログラムには柔軟な二重意味性があります。
ここではその詳細は説明せず、個人的な使い方メモを記しています。
用語
- term
- 項。Prologのプログラム記述構造の基本単位。定数、変数、複合項、文字列のいずれか。
- constant
- 定数。アトム、数値のいずれか。
- atom
- アトム。任意のシンボル。形式が変数とかぶる場合にはシングルクォートで囲う。SWI-Prologでは漢字をそのまま使用することができる。漢字はその他の処理系でもシングルクォートで囲えば使えることが多い。
- number
- 数値。整数や実数(浮動小数点)など。
- variable
- 変数。変数は任意の項と単一化(ユニフィケーション)できる。形式は先頭が大文字またはアンダーバー。
- compound
- 複合項。ファンクタひとつと引数からなる構造体。functor(attribute1, attribute2...) のような形式をしている。書き方にはほかに前・中・後置記法なども定義できる。
- list
- リスト。任意数の要素からなり、各要素間順序関係のある列。実体は2項複合項の入れ子で実現されているらしい。要素のないリストは空リストと呼び、atomicとして判定される。
- string
- 文字列。ダブルクォートで囲うと文字列になる。他の処理系ではダブルクォートで囲うと1文字分ずつに分けた文字コードのリストが得られる場合が多い。
項のグループとして、atomicがある。アトム、整数、実数と空のリストが該当する。
- functor
- ファンクタ。複合項の名前となっているアトム。
- attribute
- 複合項の引数。任意の項を取る。
- arity
- アリティ。複合項の引数の数。
- resolution
- 融合、あるいは導出。証明過程で副目標を述語定義と同一と判定するアルゴリズム。
- inference
- 推論。Prologによる推論は導出原理による。
- unify
- 単一化する。項同士が等しくなるように操作する。unification: 単一化。
- instantiate
- 具体化する。変数を定数と単一化する。instantiation: 具体化。
- BackTracking
- 後戻り。Prologは解を求める過程で、自動的に効率的な深さ優先しらみつぶし探索を行う。探索は、失敗したら後戻りをし、解を探し続けることでなされる。
-
Prologのプログラムの形式
Prologのプログラムは、以下のような形式で記述される。
述語は複合項、あるいはアトムの形式で書かれた「節」という単位で書かれる。節の末尾にはピリオドが必須。ひとつの述語に複数の節が対応する。(なお、ファンクタとアリティを同じくするすべての節がひとつの述語を構成する。つまり、ファンクタが同じでもアリティが異なれば別の述語を構成する。そのため、各述語はファンクタのうしろにスラッシュを挟んでアリティを添えた 述語/2 のような形式で示される。)
論理包含(中置演算子 「:-」。これは 「ネック」と呼ばれる)を用い、規則を記述することができる。ネックを用いない節による記述を事実と呼び、用いる節による記述を規則と呼んで区別する。論理包含の向きは一般的な命題論理式とは逆向き(←、第2形式)である。Prologはエルブランの定理を改良した導出原理による効率のよい推論を行うため、規則はホーン節の形式でなければならない。左辺は原子論理式 (literal) 1項のみを置くことができ、右辺は原子論理式を連言 (コンマで示される disjunction、すなわち論理積演算子) で結合した連言結合である。ホーン節は、右辺の論理積が真となるような各変数の組み合わせから、左辺の原子論理式がその論理的帰結 (logical consequence) として導かれることを示す。
組込述語
基本的な述語
以下で X = Y や \+ X のように、中置、前置の形で示された = や \+ も述語である。本来 =(X, Y) や \+(X) のような形式の述語を便宜のため糖衣構文化してあるもの。
- X = Y
- XとYを単一化する。
- X == Y
- XとYが等しい。
- X ; Y
- 論理和
- \+ X
- 否定
- !
- カット。常に成功した上、後戻りをできなくする。実行の効率を上げ、メモリを節約することができるが、後戻り計算に必要な情報は破棄される。適切な使用シーンは3つ。目標に対する正しい方向に入ったことが確定する地点に使う場合。目標を直ちに失敗させたい場合。別の解の生成を停止したい場合。
- true
- 成功する。
- fail
- 失敗する。後戻りを強制する用途で多用する。また、カット(!)と組み合わせて「, !, fail.」とすることで、失敗の確定を宣言することができる。
- repeat
- 再試行時も必ず成功する。trueの場合は再試行時に素通りされ、これ以前の部分が実行されるが、repeatは後戻りをすべて跳ね返し、先で失敗している間は繰り返し処理ができる。カットに到達すると脱出できる。
termの識別
- var/1
- succeeds if X is currently an un-instantiated variable.
変数が具体化されていない。
- nonvar/1
- succeeds if X is not a variable, or already instantiated.
Xが変数でない、またはすでに具体化されている。
- atom/1
- is true if X currently stands for an atom. 変数がアトムをあらわす。
- number/1
- is true if X currently stands for a number. 変数が数値をあらわす。
- integer/1
- is true if X currently stands for an integer. 変数が整数をあらわす。
- string/1
- 変数が文字列をあらわす。
- is_list/1
- 変数がリストである。
- float/1
- is true if X currently stands for a real number. 変数が実数をあらわす(SWI-Prologでは倍精度浮動小数点数)。
- atomic/1
- is true if X currently stands for a number or an atom. 変数がアトムか実数か空のリストをあらわす。
- compound/1
- is true if X currently stands for a structure. 変数が複合項をあらわす。
- ground/1
- succeeds if X does not contain any un-instantiated variables. 変数の内容がすべて具体化されている。
- random(L,H,X).
- Get random value between L and H.
LとHの間の乱数(どうやら整数のみ?)はX。
- between(L,H,X).
- Get all values between L and H.
LからHまでの間の整数を順にXに得る。
- succ(X,Y).
- Add 1 and assign it to X.
X = Y + 1になる。
構造分解
- functor/3
- functor(T, F, N); FはTのファンクタで、NはFのアリティ。
- arg/3
- arg(N, Term, A); AはTermのN番目の引数。
- =../2
- X =.. Y; 「univ」と呼ばれる述語。Xは複合項、Yはファンクタを先頭、2番めから引数を格納したリスト。
- name(A, L)
- Atomic Aと文字列Lとを変換。文字列Lが数値として解釈できる場合、Aは数値になる。
全解収集(高階述語)
- findall/3
- findall(X, P, L); LはPの解Xのすべてのリスト。
Example
| ?- findall(X, member(X, [1,2,3,4]), Results).
Results = [1,2,3,4]
yes
| ?- findall(X, (member(X, [1,2,3,4]), X > 2), Results).
Results = [3,4]
yes
| ?- findall(X/Y, (member(X,[1,2,3,4]), Y is X * X), Results).
Results = [1/1,2/4,3/9,4/16]
yes
| ?-
- setoff/3
- setoff(X, P, L); LはPの解Xのすべてのリストだが、他の変数の値毎に出力され、重複が取り除かれる。
事実節が以下の通りに定義されているとすると、
age(peter, 7).
age(ann, 5).
age(pat, 8).
age(tom, 5).
age(ann, 5).
Example
| ?- setof(Child, age(Child,Age),Results).
Age = 5
Results = [ann,tom] ? ;
Age = 7
Results = [peter] ? ;
Age = 8
Results = [pat]
(16 ms) yes
| ?-
入れ子にすると
Example
| ?- setof(Age/Children, setof(Child,age(Child,Age), Children), AllResults).
AllResults = [5/[ann,tom],7/[peter],8/[pat]]
yes
| ?-
結果にAgeを含めないために Age^ を付加できる
Example
| ?- setof(Child, Age^age(Child,Age), Results).
Results = [ann,pat,peter,tom]
yes
| ?-
- bagof/3
- setof/3に似ているが、ソートされず、重複が取り除かれない。
Example
| ?- bagof(Child, age(Child,Age),Results).
Age = 5
Results = [ann,tom,ann] ? ;
Age = 7
Results = [peter] ? ;
Age = 8
Results = [pat]
(15 ms) yes
| ?-
findallとの違い
Example
| ?- findall(Child, age(Child,Age),Results).
Results = [peter,ann,pat,tom,ann]
yes
| ?-
算術述語
- +(X, Y, Z), -(X, Y, Z), *(X, Y, Z), //(X, Y, Z), /(X, Y, Z)
- XとYを[加算, 減算, 乗算, 除算(余りを切り捨て), 除算]したものがZと等しい。
- Z is X
- 数式Xの計算結果をZに単一化する。
- X =:= Y
- 数式Xと数式Yの計算結果が等しければ成功する。
- X =\= Y
- 数式Xと数式Yの計算結果が等しくなければ成功する。
- X < Y, X> Y, X =< Y, X>= Y
- 各種比較演算
数式内で使える演算子や関数
- -X
- 前置演算子マイナス
- X + Y, X - Y, X * Y, X/Y
- 四則演算
- X//Y
- 商、結果は整数。
- X mod Y
- 余り
- succ(X).
- Add 1.
X + 1
- abs(X).
- Get absolute value of X.
Xの絶対値
- max(X,Y).
- Get largest value between X and Y
XとYで大きい方
- min(X,Y).
- Get smallest value between X and Y
XとYで小さい方
- integer(X)
- Xの整数(小数点以下の処理の方法は定まっていない? SWI-Prologでは四捨五入)
- round(X).
- Round a value near to X
四捨五入
- truncate(X).
- Convert float to integer, delete the fractional part
Xの小数点以下切り捨て
- floor(X).
- Round down
床関数。
- ceiling(X).
- Round up
天井関数。
- sqrt(X).
- Square root
平方根。
同様に sin, cos, tan, asin, acos, atan, atan2, sinh, cosh, tanh, asinh, acosh, atanh, log, log10, exp, pi, などがある。ほかにもビット演算など。
節に対する述語
- listing
- 登録されているすべての節を出力し、常に成功する。
- listing/1
- 変数で指定される記号を述語としてもつ節を出力し、成功する。
- consult/1
- 変数で指定されるファイルを読み込み、節として登録し、成功する。ファイルがみつからなければ失敗する。SWI-Prologでは同じファイルに対し繰り返しconsult/1を行ってもメモリは上書き更新される(reconsult/1と同じ動作をする)。
リスト処理述語
- nth0(要素位置, リスト, 該当要素)
- 「リスト」の「要素位置」(先頭を0とする)の要素を「該当要素」に単一化する。
- member(要素, リスト)
- 「要素」が「リスト」に含まれる場合に真。
- append(リスト1, リスト2, 連結結果)
- 「リスト1」と「リスト2」を連結したものが「連結結果」に単一化する。
- last(リスト, 末尾の要素)
- 「リスト」の末尾の要素が「末尾の要素」に単一化する。
- reverse(元のリスト, 反転したリスト)
- 「元のリスト」の順序を反転したものが「反転したリスト」に単一化する。
Babilejo