読者です 読者をやめる 読者になる 読者になる

差分リストやループ

Prologで差分リストや末尾再帰の述語を書く場合、たいてい以下のようなイデオムを利用する。

  • 差分リスト
% たどる
diff_list(List, ResultList) :- diff_list_sub(List, [ResultList, []]).
diff_list_sub([Head | Rest], [Result, Tail]) :-
        <Headを何かしてXにする>
        [Result, Appender1] = [[X | Appender1], Appender2],
        diff_list_sub(Rest, [Appender2, Tail]), !.
diff_list_sub(_, _, [Tail, Tail]).
% すべてをたどる
diff_list_traverse(List, ResultList) :- diff_list_traverse_sub(List, [ResultList, []]).
diff_list_traverse_sub([Head | Rest], [Result, Tail]) :-
        diff_list_traverse_sub(Head, [Result, Appender]),
        diff_list_traverse_sub(Rest, [Appender, Tail]), !.
diff_list_traverse_sub([], [Tail, Tail]).
diff_list_traverse_sub(X, [[Y | Appender], Appender]) :- <Xを何かしてYにする>.
  • 末尾再帰
tail_recursive(List, Result) :- tail_recursive_sub(List, <initial value>, Result).
tail_recursive_sub([], Accumulator, Accumulator).
tail_recursive_sub([Head | Rest], Accumulator, Result) :-
        <AccumulatorとHeadを何かしてNextAccumulatorにする>
        tail_recursive_sub(Rest, NextAccumulator, Max).

prologではこのようなコードをLispやほかの言語のように汎用化、部品化できないのだろうか。毎回同じようなコードを記述するのはつらい。