Prolog 写経記 その 17 length/2

(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.

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

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


昨日写経した last/2 ですが...
すでに「その 5」で写経済みでした.(;_;)
ぢぐじょー,完全に忘れてたよ... 心より恥じる.
しかも,全然面白くないやつを... 無念だ.


次行きますよっ!! 次,次!!
今日は length/2 を写経します.
これは使ったことはあるけどまだ写経していません.間違いない.

解説

length(List, L) はリスト List の長さを返す.すなわち LList1 の要素の数に具体化する.

ふむ.Java でいうと List#size() ですね.

モード

length(?, ?)

ふーん.
リストの長さを返すだけじゃなくて,ある長さのリストを返すことも出来る... のか?
怪しい...

定義

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

length([], 0).
length([_|List], L) :-
	length(List, L1),
	L is L1 + 1.

簡単♪

注記

いくつかの Prolog では length/2 は組み込み述語となっている.その組み込み述語は length(+, ?) として実現されており,最後の例に示すような,List が具体化されていない呼び出しは不可能である.

そういえば,これまでに何度か length/2 を使ってきましたが,特に定義しなくても使えましたね.
最後の例が不可能... 後でチェックしませう.

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

1 ?- [util].
ERROR: (c:/develop/workspaces/swi/util.swi:86):
        No permission to modify static_procedure `length/2'
ERROR: (c:/develop/workspaces/swi/util.swi:87):
        No permission to modify static_procedure `length/2'

Yes

ぐはぁっ...
どうやら組み込み述語は上書きできないようです... 無念だ.
しょうがないので length2 に名前を変更しますた.

3 ?- length2([june, july, august], X).

X = 3 

Yes
4 ?- length2(mon, tue, wed, thur, fri, 5).

No
5 ?- length2([[]], Y).

Y = 1 

Yes
6 ?- length2(L, 2), member(x1, L), member(x2, L).

L = [x1, x2] 

Yes

ふーん.
なんか,うまくいっているように見えなくもありませんが... ちょっと怪しい.
ちょっと意地悪してみるテスト.

7 ?- length2(L, 2), member(x1, L), member(x2, L).

L = [x1, x2] ;

L = [x2, x1] ;

返ってきません.(^^;
無限ループにいっちゃったっぽいです.ダメじゃん.
やっぱりリストの長さを求めることに専念した方がいいんじゃない?
つまり length(+, ?)


そんなわけで (どんなわけで?),組み込み述語の lnegth/2 をお試ししませう.

8 ?- length([june, july, august], X).

X = 3 

Yes
9 ?- length(mon, tue, wed, thur, fri, 5).

No
10 ?- length([[]], Y).

Y = 1 

Yes
11 ?- length(L, 2), member(x1, L), member(x2, L).

L = [x1, x2] ;

L = [x2, x1] ;

No

おぉっ!?
なんか,完璧じゃないですか.ちゃんと length(?, ?) で機能している...
やるな SWI-Prolog 組み込み length/2
でも,不自然な使い方をするのはやめた方が無難な感じ.