(ほぼ) 毎日淡々と Prolog を写経します.元ネタはこちら.
今日は
substitute/4
を写経します.
解説
substitute(X, Y, List1, List2)
は List1
中の要素 X
を Y
に換えた新しいリストを List2
として返す.
ふむ.Java でいうと... Collections#replaceAll(List, Object, Object)
でしょうか.
モード
substitute(?, ?, +, ?).
ふむ.元のリストだけはちゃんと与えなきゃいけないよ,と.
定義
では,こいつの定義を写経しませう.
substitute(X, Y, List1, List2) :-
conc(L1, [X | L2], List1),
conc(L1, [Y | L2], List2).
わーお,またしても conc/3
っすか!?
うーみゅ,要素の置換さえも連結で表現してしまうとは恐るべし.そうですか,宣言的ってこういう事ですか.
っていうか,これほどまでに conc/3
を使いまくっているのにまだ驚いてしまうということは,まだまだ conc/3
が身に付いていないということか...
心より恥じる.
ともあれ (JW),L1
と X
と L2
を連結したのが List1
で,L1
と Y
と L2
を連結したのが List2
ということですか.
ってことは,List1
中の全ての X
を Y
に置換する訳じゃないんだ...
注記
もし X
が List1
に 2 回以上現れると,バックトラックを通して複数の答えが見出される.
ちっ,ちゃんと書いてあったか.
つまり,Collections#replaceAll(List, Object, Object)
相当じゃない訳ね.
例
では使用例を写経しませう.
2 ?- substitute(a, b, [a, b, c], [b, b, c]).
Yes
3 ?- substitute(3, 7, [3, 2, 5, 3, 8, 2], L).
L = [7, 2, 5, 3, 8, 2] ;
L = [3, 2, 5, 7, 8, 2] ;
No
4 ?- substitute(X, Y, [l, i, s, t], [l, a, s, t]).
X = i
Y = a
Yes
5 ?- substitute(X, Y, [l, i, s, t], [l, i, s, t, s]).
No
ふーん.list
が last
ねぇ... つまらぬ.
そういう場合はやっぱりこうじゃないと♪
6 ?- substitute('Y', 'W', ['Y', a, d, a, 'A', k, i, k, o], L).
L = ['W', a, d, a, 'A', k, i, k, o]
Yes
心より恥じる.