Prolog 写経記 その 11 head/2

宣言的・論理的な考え方を身につけたい!
でもでも,述語論理って書いてもそれが正しく書けたかどうか分からない!!
やっぱり実行可能なプログラミング言語を使うしか!!!!
そんなわけで (どんなわけで?),Prolog を写経しています.元ネタはこちら.

Prologユーティリティライブラリ

Prologユーティリティライブラリ

今日は head/2 を写経します.

解説

head(List, H)HList の最初の要素に具体化する.

ふむ.Java でいうと LinkedList#getFirst() みたいな.

モード

head(?, ?)

ふむふむ.

定義

では,こいつの定義を写経しませう.

head([H|_], H).

これは簡単だ.(^^;
でもでも,簡単すぎてこれが必要な理由が分からない...
まぁいいか.

注記

head/2 を空リストに適用すると失敗する.この述語は,後の処理で完全に具体化されるようなリストを,部分的に具体化することも出来る (最後の例参照).

うーみゅ...
最初に書いてあることはいいとして,その後がなんというか,部分的に具体化?
まぁいいや,最後の例で楽しみましょう.

では使用例を写経しませう.

2 ?- head([-1, 0, 1], First).

First = -1 ;

No
3 ?- head([sisngle], H).

H = sisngle ;

No
4 ?- head([], What).

No
5 ?- head(List, a), tail(List, [b, c, d]).

List = [a, b, c, d] ;

No

実は最後の例ではまだ写経していない tail/2 が使われています.
なので,先に tail/2 を写経しようかと思ったら,そっちにも同じ例が使われていました.つまり相互参照.
しょうがないのでこっそり tail/2 を写しちゃいました.心より恥じる.


ともあれ (JW),最後の例をまったりと眺めてみます.

head(List, a), tail(List, [b, c, d]).

最初の head/2 には第 1 引数ではなく,第2引数の方に具体的な値 (アトム) を渡しています.
そのため,注記に従って解読すると,List の最初の要素だけが a に具体化される... ということですか.でも残りの要素はまだ具体化されないまま.うーみゅ.
そして tail/2 により逆に List の最初の要素を除いた残りだけが具体化され,結果として List が完全に具体化される,と.
つまり,head/2 という一見なくても平気そうな述語がわざわざ紹介されている理由は,先頭の要素のみ具体化されたリストの全体に名前を付けることができるようになるから... なのか?
確信はないけど,きっとそういうことじゃなかろうか.


ということは,ですよ?
この間まで取り組んでいたフィジカルネタでは,リストや二分探索木を再帰的に扱う際に新たなリストや二分探索木を作り散らかしていたのですが,もしかしてもしかするともしかしなくても,部分的に具体化しながら再帰することも出来た... のか?
部分的に具体化... 奥が深いな.侮れん!!