エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

Prolog の append がとてもユーティリティ

リスト操作は append で、だいたいどうにかなるこということがわかりました。

% 先頭の要素を取得する
head(List, Head) :- append([Head], _, List).

% 末尾の要素を取得する(標準装備でした)
% last(List, Last) :- append(_, [Last], List).

% 先頭の要素を除いたリストを取得する
tail(List, Tail) :- append([_], Tail, List).

% 末尾の要素を除いたリストを取得する
init(List, Init) :- append(Init, [_], List).

% 指定した位置で分割した二つのリストを取得する
split_at(N, List, [Prefix, Suffix]) :- append(Prefix, Suffix, List), length(Prefix, N), !.

% 指定した位置までの要素のリストを取得する
take(N, List, Prefix) :- split_at(N, List, [Prefix, _]).

% 指定した位置までの要素を除いたリストを取得する
drop(N, List, Suffix) :- split_at(N, List, [_, Suffix]).

% 先頭から条件が成立する要素のリストとその後続のリストに分割する
break(Predicate, [Head|Tail], [[Head|Prefix], Suffix]) :- call(Predicate, Head), break(Predicate, Tail, [Prefix, Suffix]), !.
break(_, Suffix, [[], Suffix]).

% 先頭から条件が成立する要素のリストを取得する
take_while(Predicate, List, Prefix) :- break(Predicate, List, [Prefix, _]).

% 先頭から条件が成立する要素を除いたリストを取得する
drop_while(Predicate, List, Suffix) :- break(Predicate, List, [_, Suffix]).

% 指定した要素を繰り返す無限リストを取得する
repeat(Element, List) :- append([Element], List, List), !.

% 指定した要素を指定した回数繰り返したリストを取得する
replicate(N, Element, List) :- append([Element], List, List1), append(List, [_], List1), length(List, N), !.

% 指定した有限リストを繰り返す無限リストを取得する
cycle(Finite, Infinite) :- append(Finite, Infinite, Infinite), !.

% リストを左方向に回転
rotate_left(N, List, Rotated) :- append(L, R, List), append(R, L, Rotated), length(L, N), !.

% リストを右方向に回転
rotate_right(N, List, Rotated) :- append(L, R, List), append(R, L, Rotated), length(R, N), !.

% 文字列 String を文字 Char で分割した文字列のリストを取得する
split(Char, String, [S|SS]) :- append(S, [Char|Rest], String), split(Char, Rest, SS), !.
split(_, String, [String]).