左から右にリストの積を取得するにはどうすればよいですか? 例えば:
?- product([1,2,3,4], P).
P = [1, 2, 6, 24] .
1つの方法は、ファンクターをオーバーロードして3つの引数を使用することだと思います:
product([H|T], Lst) :- product(T, H, Lst).
ここからどこへ行けばいいのかわからない。
左から右にリストの積を取得するにはどうすればよいですか? 例えば:
?- product([1,2,3,4], P).
P = [1, 2, 6, 24] .
1つの方法は、ファンクターをオーバーロードして3つの引数を使用することだと思います:
product([H|T], Lst) :- product(T, H, Lst).
ここからどこへ行けばいいのかわからない。
ここにあるライブラリ(ラムダ)を使用できます: http : //www.complang.tuwien.ac.at/ulrich/Prolog-inedit/lambda.pl
:- use_module(library(lambda)).
:- use_module(library(clpfd)).
product(L, R) :-
foldl(\X^Y^Z^(Y = []
-> Z = [X, [X]]
; Y = [M, Lst],
T #= X * M,
append(Lst, [T], Lst1),
Z = [T, Lst1]),
L, [], [_, R]).
@Mike_Hartl のアドバイスに感謝します。コードは非常にシンプルです。
product([], []).
product([H | T], R) :-
scanl(\X^Y^Z^( Z #= X * Y), T, H, R).
リストのコピーのように見えますが、処理された最後の要素を掛けるだけです。一番左の要素を 1 から始めましょう。
product(L, P) :-
product(L, 1, P).
product([X|Xs], A, [Y|Ys]) :-
Y is X * A,
product(Xs, Y, Ys).
product([], _, []).
ライブラリ (clpfd) を使用する場合:
:- [library(clpfd)].
product([X|Xs], A, [Y|Ys]) :-
Y #= X * A,
product(Xs, Y, Ys).
product([], _, []).
機能します(整数のみ)「後方」
?- product(L, [1,2,6,24]).
L = [1, 2, 3, 4].
おそらく非常に汚い解決策です(私はPrologが初めてです):
product([ListHead|ListTail], Answer) :-
product_acc(ListTail, [ListHead], Answer).
product_acc([ListHead|ListTail], [AccHead|AccTail], Answer) :-
Product is ListHead * AccHead,
append([Product, AccHead], AccTail, TempList),
product_acc(ListTail, TempList, Answer).
product_acc([], ReversedList, Answer) :-
reverse(ReversedList, Answer).
したがって、基本的に最初に、アキュムレータリストである追加の「変数」Acc を持つ別の述語を呼び出します。
そこで、元のリストから head (最初の番号) を取り出し、それを Accumulator リストに入れます。
次に、常に元のリストからヘッド (最初の数値) を取得し、アキュムレータ リストのヘッド (最初の数値) で乗算します。
次に、アキュムレータの先頭と末尾を乗算して得た新しい数値を追加する必要があります。
次に、元のリストが空になるまで同じ述語を再度呼び出し、最後に明らかに逆にする必要があります。
そしてそれはうまくいくようです
?- product([1,2,3,4], L).
L = [1, 2, 6, 24].
?- product([5], L).
L = [5].
?- product([5,4,3], L).
L = [5, 20, 60].
私の説明が明確でない場合は申し訳ありません。お気軽にコメントください。