我在Prolog中有两个谓词,第一个确实返回两个列表的正确点积(向量w / e)...第二个是当你列出一个列表列表(矩阵)时将返回一个列表。当我尝试传递诸如([1,2],[[3,4],[5,6],[7,8]], X)
之类的任何内容时,第二个失败。任何精通Prolog的人都会看到我的错误?我有点卡住,因为跟踪和prolog本身只是一直返回失败。
getDotProd([],[],0.0).
getDotProd([H1|T1],[H2|T2], N):-
getDotProd(T1,T2,N1),
N is N1 + (H1 * H2).
vecTimesMatrix(_,[[]],[]).
vecTimesMatrix([List], [MH|Mtail],[N]):-
N is getDotProd(List, MH, _),
vecTimesMatrix(List, Mtail, N).
目前为止更新了代码:
getDotProd([],[],0.0).
getDotProd([H1|T1],[H2|T2], N):-
getDotProd(T1,T2,N1),
N is N1 + (H1 * H2).
vecTimesMatrix([],[[]],[]).
vecTimesMatrix([List], [MH|Mtail],[N]):-
getDotProd(List, MH, N),
vecTimesMatrix(List, Mtail, N).
答案 0 :(得分:1)
您的代码中存在几个问题。首先,您定义getDotProd/4
和getDotProd/3
谓词。第一个是拼写错误。即getDotProd/3
谓词的基本情况有一个重复的参数,它应该是:
getDotProd([], [], 0).
其次,在第二个谓词vecTimesMatrix/3
中,您有一个目标,即对内置谓词is/2
的调用,这将导致异常:
N is getDotProd(List, MH, _)
您无法在标准Prolog上定义自己的功能。您需要用以下内容替换该目标:
getDotProd(List, MH, N)
还有其他问题,但这可以帮助您取得进展。
答案 1 :(得分:1)
您剩下的问题出在vecTimesMatrix
谓语中:
vecTimesMatrix([],[[]],[]).
vecTimesMatrix([List], [MH|Mtail],[N]):-
getDotProd(List, MH, N),
vecTimesMatrix(List, Mtail, N).
的问题:
[List]
给出,这意味着单个元素(List
)的列表。在条款中对getDotProd
和vecTimesMatrix
的后续调用表明这应该只是List
。[N]
。所以第三个参数永远不会“构建”一个列表。此外,对vecTimesMatrix
的递归调用具有N
作为其第三个参数,并且该参数已经被先前查询实例化为getDotProd
作为向量{{1}的点积。和vectory List
。从逻辑上讲,递归调用应该说 MH
的矢量积List
是最终产品的尾部。Mtail
,但事实并非如此。在整个递归过程中,[]
始终保持原样。因此,List
代替[]
而不是_
(它将保留其值,但在基本情况下你并不关心它。)[[]]
,但这不是空列表的正确形式。这实际上是一个由一个元素组成的列表,该元素是空列表。实际上,即使第二个参数是“列表列表”,空列表仍然是[]
。将所有内容放在一起(并使用下划线而不是驼峰的情况重命名每个事实上的约定的谓词):
get_dot_prod([], [], 0.0). % Dot product of empty vectors is 0.0
% (Dot prod of vectors of unequal length
% is not defined and will fail)
get_dot_prod([H1|T1], [H2|T2], N) :- % N is dot product of [H1|T1] [H2|T2] if...
get_dot_prod(T1, T2, N1), % N1 is dot product of T1 T2, and
N is N1 + (H1 * H2). % N is N1 + (H1*H2) [evaluated]
vec_times_matrix(_, [], []). % Product of any vector with
% empty matrix is empty
vec_times_matrix(List, [MH|Mtail], [N|Ntail]):-
% [N|Ntail] is List x [MH|Mtail] if...
get_dot_prod(List, MH, N), % N is dot product of List and MH, and
vec_times_matrix(List, Mtail, Ntail). % Ntail is List x Mtail
这将产生:
| ?- vec_times_matrix([1,2],[[1,0],[0,1]], M).
M = [1.0,2.0] ? a
no
| ?- vec_times_matrix([1,2],[[1,0],[0,1],[1,1]], M).
M = [1.0,2.0,3.0] ? a
(1 ms) no
我在上面的代码中添加了注释,以简单的方式说明如何考虑prolog谓词逻辑,这有助于定义它们。正如已经指出的那样,序言“谓词”并不充当“功能”。它描述了成功或失败的实体之间的逻辑关系。
一旦你学会思考prolog如何思考(关系),你会发现它更有乐趣。 :)