Prolog 写経記 その 14 insert_n/4
(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.
- 作者: ボグダンフィリピッチ,中島誠,伊藤哲郎
- 出版社/メーカー: 海文堂出版
- 発売日: 1990/08
- メディア: 単行本
- 購入: 4人 クリック: 33回
- この商品を含むブログ (68件) を見る
insert_n/4
を写経します.解説
insert_n(N, X, List1, List2)
は要素X
をList1
のN
番目の位置に挿入した新しいリストをList2
として返す.
ふむ.Java でいうと List#add(int, Object)
みたいな.
モード
insert_n(?, ?, ?, ?)
ふむ.まぁ例によって.
定義
では,こいつの定義を写経しませう.
insert_n(N, X, List1, List2) :- conc(L1, L2, List1), length(L1, L), N is L + 1, conc(L1, [X|L2], List2).
基本的な発想はいつも通りですね.
リストを X
とその左の要素からなるリスト (L1
),右の要素からなるリスト (L2
) に分けて,
L1
とL2
を連結したリストがList1
.L1
,X
,L2
を連結したリストがList2
.
ということですね.
その上で,L1
の長さは N - 1
ってことを示すのが
length(L1, L), N is L + 1,
の部分.
こういうのはやっぱりこうなるんですね.ってことなら,フィジカルネタでおいらがやったこともそんなに手続き的というわけでもないのだろうか?
注記
以下の例は
insert_n
がそれぞれ初期設定された引数の違いによってどのように適用できるかを示している.バックトラック時に無限ループに陥るのを避けるため,List1
は少なくとも部分的に具体化されている必要がある.
例によって無限ループの危険性がある,と.らじゃあ.
例
では使用例を写経しませう.
2 ?- insert_n(3, 4/5, [1/2, 2/3, 4/4], L). L = [1/2, 2/3, 4/5, 4/4] ; No 3 ?- insert_n(N, b, [_, _, _], [a, b, c, d]). N = 2 ; No 4 ?- insert_n(P, X, [4, 6], [2, 4, 6]). P = 1 X = 2 ; No
2 番目の例が List1
を「部分的に具体化」した例ですね.
これを全く具体化せずに呼び出してみると...
5 ?- insert_n(N, b, L, [a, b, c, d]). N = 2 L = [a, c, d] ;
...
別の解を求めるためのセミコロンを入力した後,きっちり無限ループになって返ってきません.(^^;