Prolog 写経記 その 13 insert_last/3
(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.
- 作者: ボグダンフィリピッチ,中島誠,伊藤哲郎
- 出版社/メーカー: 海文堂出版
- 発売日: 1990/08
- メディア: 単行本
- 購入: 4人 クリック: 33回
- この商品を含むブログ (68件) を見る
insert_last/3
を写経します.解説
insert_last(X, List1, List2)
は要素X
をリストList1
の最後に挿入した新しいリストをList2
として返す.
ふむ.Java でいうと List#add(Object)
みたいな.
モード
insert_last(?, ?, ?)
ふむふむ.
と書いてあるのだけど,実際は違うんじゃないかと思う今日この頃.
違うってのは言い過ぎかもしれないけれど,本当はこういう事なんじゃなかろうか?
insert_last(+, +, +) insert_last(+, +, -) insert_last(+, -, +) insert_last(-, +, +) insert_last(-, -, +)
これで全部じゃないかもしれないけれど.
ともあれ (JW),こういう組み合わせを把握しておかないと,insert/4
みたいに無限ループに陥ることもあるわけで...
でもでも,こういうのを全部挙げてたらきりがないよなぁ.
定義
では,こいつの定義を写経しませう.
insert_last(X, List1, List2) :- conc(List1, [X], List2).
なんというか...
手抜きに感じるのは私だけ? (^^;
いや,決して手抜きなんて事はないんでしょうけど...
なんか拍子抜けだなぁ.
っていうか,conc/3
って List1
の要素数分だけ再帰するんだよね.たった一つ要素を付け加えるのに要素数分再帰するってなんかいやーん.末尾再帰最適化してくれると信じて気にしないのが吉ですかそうですか.
注記
List2 が具体化され X が具体化されていない場合,insert_last/3 は与えられたリストの最後の要素を返す.つまり last/2 と同じ働きをする.
らじゃあ.
例
では使用例を写経しませう.
2 ?- insert_last(circle, [square, triangle], L). L = [square, triangle, circle] Yes 3 ?- insert_last(X, _, [a-c, c+b, d-a, a+b]). X = a+b Yes
ふむ.
最後の例では第 2 引数を無名変数にしているけれど,ちゃんとした変数にしても大丈夫なはず.
4 ?- insert_last(X, Y, [a, b, c]). X = c Y = [a, b] Yes
ふむ.
特にどうという事もないわけなので,しょうがないから例によっていぢわる.
5 ?- insert_last(X, Y, Z). X = _G308 Y = [] Z = [_G308] ; X = _G308 Y = [_G393] Z = [_G393, _G308] ; X = _G308 Y = [_G393, _G399] Z = [_G393, _G399, _G308] ; X = _G308 Y = [_G393, _G399, _G405] Z = [_G393, _G399, _G405, _G308] ; X = _G308 Y = [_G393, _G399, _G405, _G411] Z = [_G393, _G399, _G405, _G411, _G308] ; ・ ・ ・
やはり.
もう一つ.
6 ?- insert_last(a, X, Y). X = [] Y = [a] ; X = [_G378] Y = [_G378, a] ; X = [_G378, _G384] Y = [_G378, _G384, a] ; X = [_G378, _G384, _G390] Y = [_G378, _G384, _G390, a] ; X = [_G378, _G384, _G390, _G396] Y = [_G378, _G384, _G390, _G396, a] ; ・ ・ ・
やはり.
最後に.
7 ?- insert_last(X, [a, b, c], Y). X = _G365 Y = [a, b, c, _G365] ; No
あら?
これはちょっと予想外.こっちも延々繰り返すかと思ったのですが.
ともあれ (JW),ちゃんと動く引数の組み合わせは「モード」で「本当はこういうこと」と書いた通りでよさげ.