Prolog-将列表与列表列表相乘

时间:2013-02-11 23:51:56

标签: list prolog multiplication

我正在尝试使用这两个谓词模拟矩阵与向量的乘积:

eva([], [], []).
eva([A|A1], [W], [Res|R1]) :-
    vectormultiplication(A, W, Res),
    eva(A1, W, R1).

vectormultiplication([A], [W], [A*W]).
vectormultiplication([A|A1], [W|W1], [A*W|Out1]) :-
    vectormultiplication(A1, W1, Out1).

如果eva中的[A|A1]是矩阵(或列表列表),[W]是向量(列表),[Res|R1]是结果产品。 vectormultiplication应该将列表中的每个列表与向量W相乘。但是,这种策略只会产生错误的反应。有什么迹象表明我在这里做错了阻止我得到所需的产品吗?我目前正在使用SWI Prolog版本5.10

2 个答案:

答案 0 :(得分:2)

嗯,你的第一个问题是你认为A*W本身会做任何事情。在Prolog中,这只是创建表达式A*W,与*(A,W)foo(A, W)没有区别 - 如果不涉及is/2,则不会进行实际的算术减少。这是我在快速浏览中看到的唯一真正的问题。

答案 1 :(得分:2)

除了丹尼尔(+1)所证明的另外两个问题:这里有一个清理过的来源

eva([], _, []).  % here [] was wrong
eva([A|A1], W, [Res|R1]) :- % here [W] was wrong
    vectormultiplication(A, W, Res),
    eva(A1, W, R1).

vectormultiplication([A], [W], [M]) :-
    M is A*W.
vectormultiplication([A|A1], [W|W1], [M|Out1]) :-
    M is A*W,
    vectormultiplication(A1, W1, Out1).

试验:

?- eva([[1,2],[3,5]],[5,6],R).
R = [[5, 12], [15, 30]]

处理清单时,如果可以的话,使用maplist是值得的

eva(A, W, R) :-
    maplist(vectormultiplication1(W), A, R).

vectormultiplication1(W, A, M) :-
    maplist(mult, A, W, M).

mult(A, W, M) :-
    M is A*W.

注意我改变了vectormultiplication1的参数顺序,因为该向量是该循环中的“常量”,而maplist附加的参数是“展开”。