リストのリストを持つ関数を作成しようとしています。これは、内側のリストと外側のリストの合計を乗算します。これまでのところ、リストを合計できます。X = (結果) を返す関数 sumlist([1..n],X) を作成しました。しかし、別の関数をその関数で有効に動作させることはできません。 is と = の両方を試しましたが、役に立ちませんでした。
3 に答える
これはあなたが意味するものですか?
prodsumlist([], 1).
prodsumlist([Head | Tail], Result) :-
sumlist(Head, Sum_Of_Head),
prodsumlist(Tail, ProdSum_Of_Tail),
Result is Sum_Of_Head * ProdSum_Of_Tail.
ここsumlist/2
で、SWI-Prolog ビルトインです。
使用例:
?- prodsumlist([[1, 2], [3], [-4]], Result).
Result = -36.
「内側のリストと外側のリストの合計を乗算する」という部分はあまり明確ではありませんが、[L1,...,Ln]
数値のリストのリストが与えられたS1*..*Sn
場合Si
、Li
(ごとにi
)。
plus
私は と の存在をmult
それらの明白な意味で仮定します (例えば、 が に等しいplus(N,M,R)
場合に正確に成立します)。最初に、が の要素の合計である場合にのみ成立するような述語が必要です。が空の場合、明らかに:R
N+M
sum
sum(L,S)
S
L
L
S
0
sum([],0).
L
が空ではなく の形式である場合、 に の要素の合計を加えたもの[N|L2]
でS
なければなりません。言い換えると、(S2 を の要素の合計にするために) との両方が必要です。あれは:N
S2
L2
sum(L2,S2)
L2
plus(N,S2,S)
sum([N|L2],S) :- sum(L2,S2), plus(N,S2,S).
p
同じようにして、探している述語を見つけることができます。それが成立するのは、 through where and for allの積であるp(L,R)
場合に限られます。が空の場合、次のようにする必要があります:R
S1
Sn
L=[L1,...,Ln]
sum(Li,Si)
i
L
R
1
p([],1).
L
が空ではなく の形式[LL|L2]
である場合、 は の要素の和である 'S'と のリストの和の積である 'P' のR
積でなければなりません。はすでにあるので、これにより次のことが得られます。LL
L2
S
sum(LL,S)
p([LL|L2],R) :- sum(LL,S), p(L2,P), mult(S,P,R).
追加したいことの 1 つは、これらの述語を、命令型プログラミングや関数型プログラミングで慣れ親しんだ関数と見なすのは、おそらくあまり良い考えではないということです。sumlist([1,..,n],X)
を返すのはそうではありませんX = (result)
。真であるような(result)
値です。これには、少し異なる考え方が必要です。「p(X) が成立するような X を計算するにはどうすればよいか」と考える代わりに、「P(X) はいつ成立するのか?」と考える必要があります。そして答えを使って (「q(X) か r(X) なら!」) 節 (と) を作ります。X
sumlist([1,...,n],X)
p(X) :- q(X)
p(X) :- r(X)
これはKaarelの答えを書き直したものです(とにかくそれが意図です!)が、末尾再帰です。
prodsumlist(List, Result) :-
xprodsumlist(List,1,Result).
xprodsumlist([],R,R).
xprodsumlist([Head|Rest],Sofar,Result) :-
sumlist(Head, Sum_Of_Head),
NewSofar is Sofar * Sum_Of_Head,
xprodsumlist(Rest, NewSofar, Result).