3

我想将两个列表相乘,我将左侧列表乘以右侧列表的每个元素。

例如:

?- 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什么?

4

2 回答 2

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将第一个参数应用于每个列表的每个元素(作为参数传递给它)。

于 2013-01-12T08:29:04.887 回答
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 美分......

于 2013-01-12T08:41:05.813 回答