我想将两个列表相乘,其中我将左侧列表与每个元素相乘 正确的清单。
例如:
?- multLists([3,4,2], [4,7,8], R).
R = [[12,16,8],[21,28,14],[24,32,16]].
为此,我编写了一个辅助谓词,它接受一个列表并将其相乘 用一个标量:
multListElem([], _, _).
multListElem([H|T], Result, Elem) :-
multListElem(T, W, Elem),
Z is H*Elem,
Result = [Z|W].
但现在,当我跑?- multListElem([1,2,3], X, 3).
时
我明白了:
1 ?- multListElem([1,2,3], X, 3).
X = [3, 6, 9|_G1840].
奇怪的尾巴是什么_G1840
?
答案 0 :(得分:5)
错误在于:multListElem([],_,_)
。当第一个列表为空时,结果为空,因此您必须编写multListElem([],[],_).
使用列表时,可以使用类似的功能惯用法 maplist:
multLists(L1, L2, R) :-
maplist(mult_one_list(L1), L2, R).
mult_one_list(L1, Elem, R) :-
maplist(mult_2_numbers(Elem), L1, R).
mult_2_numbers(V1, V2, R) :-
R is V1 * V2.
maplist
将第一个参数应用于每个列表的每个元素(作为参数传递给它)。
答案 1 :(得分:3)
你的基本情况留下未实例化的尾巴:改为
multListElem([],[],_).
它会起作用。
@ Joel76已经解决了你的问题,并使用maplist暴露了一种更好的方法。如果你有lambda.pl可用,这是一个解决问题的紧凑公式
?- maplist(\A^B^maplist(\X^Y^(Y is X*A), [3,4,2], B), [4,7,8], R).
R = [[12, 16, 8], [21, 28, 14], [24, 32, 16]].
编辑当然正确的界面是
multLists(L1, L2, R) :-
maplist(\A^B^maplist(\X^Y^(Y is X*A), L1, B), L2, R).
@false指出它很难理解但很容易修复的第二个错误:
multLists(L1, L2, R) :-
maplist(\A^maplist(\X^Y^(Y is X*A), L1), L2, R).
我称之为功能的第一个错误:非常有用,lambda与闭包一起使用,然后声明A
...只是我的2美分......