我正在尝试使用这两个谓词模拟矩阵与向量的乘积:
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
答案 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附加的参数是“展开”。