我正在尝试创建一个具有列表列表的函数,它将内部列表的总和与外部列表相乘。到目前为止,我可以总结一个列表,我已经创建了一个函数 sumlist([1..n],X),它将返回 X = (result)。但是我无法获得另一个函数来有效地使用该函数,我已经尝试过 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/2SWI-Prolog 内置在哪里。
使用示例:
?- prodsumlist([[1, 2], [3], [-4]], Result).
Result = -36.
“它将内部列表的总和与外部列表相乘”的部分并不是很清楚,但我相信你的意思是,给定一个[L1,...,Ln]数字列表列表,你想要计算(对于每个)。S1*..*SnSiLii
plus我假设和的存在mult具有明显的含义(例如,当等于plus(N,M,R)时恰好成立)。首先,我们需要这样的谓词,当且仅当是 的元素之和时才成立。如果为空,显然必须是:RN+Msumsum(L,S)SLLS0
sum([],0).
如果L不是空的而是 的形式[N|L2],那么我们有S必须N加上S2中的元素的总和L2。换句话说,我们必须同时拥有sum(L2,S2)(让 S2 成为 的元素之和L2)和plus(N,S2,S)。那是:
sum([N|L2],S) :- sum(L2,S2), plus(N,S2,S).
以同样的方式,您可以找出p您正在寻找的谓词。我们希望p(L,R)当且仅当R它是S1through Snwhere L=[L1,...,Ln]and sum(Li,Si)for all的产物时才成立i。如果L为空,则R必须为1:
p([],1).
如果L不是空的,而是 的形式[LL|L2],那么我们有它R必须是“S”的乘积,“S”是 的元素之LL和,“P”是 中的列表之和的乘积L2。因为S我们已经有了sum(LL,S),所以这给了我们以下内容。
p([LL|L2],R) :- sum(LL,S), p(L2,P), mult(S,P,R).
我想补充的一件事是,将这些谓词视为您可能习惯于命令式或函数式编程的函数可能不是一个好主意。sumlist([1,..,n],X)返回的情况并非如此X = (result);(result)是这样的一个值,X这sumlist([1,...,n],X)是真的。这需要稍微不同的心态。而不是思考“我如何计算 X 使得 p(X) 成立?” 你一定会想“P(X) 什么时候成立?” 并使用答案(“好吧,如果 q(X) 或 r(X)!”)构成从句 ( p(X) :- q(X)and p(X) :- r(X))。
Here is a rewrite of Kaarel's answer (that's the intention anyway!) but tail-recursive.
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).