我正在写一个谓词来添加两个向量。这就是我想出的:
add( [], [], 0 ).
add( [A], 0, A ).
add( [A], [B], C ) :- C is A + B.
add( A, B, C ) :- add( B, A, C ).
add( [H1|T1], [H2|T2], WYNIK ) :- X is H1 + H2, add( T1, T2, Y ), append( [X], Y, WYNIK ).
前四行工作得很好,但我不能让最后一行工作 - 我做错了什么?
答案 0 :(得分:3)
按此顺序,最后一行永远不会运行。这一行:
add( A, B, C ) :- add( B, A, C ).
将与其上方尚未处理的任何内容统一。
答案 1 :(得分:1)
正如杰夫所说,问题在于:
add( A, B, C ) :- add( B, A, C ).
一般来说,这是一条表达你想要成真的规则,但这并不能帮助你解决目标。此规则的查询add(1,2,X)
会导致子查询add(2,1,X)
,这会导致子查询add(1,2,X)
:SLD resoltuion可以永久地花在此分支上(如果它没有其他更高优先级的规则,没有任何地方,它没有发现规则没有取得进展。您应该只使用具有条件的此类规则(例如strictlylessthan (B,A)
),以确保该规则仅在可以执行有用工作时适用。这些规则的问题是Prolog不是真正的声明性语言的原因。
要重新获得可交换性,你需要添加rul:
add (0, [A], A).
您的添加谓词有点奇怪:add([1],0,1)
为真,add([1],[0],1)
为真,但add([0],1,1)
不是,add([1],[0],[1])
也不是add
。从计算的角度来看,{{1}}是完全有意义的,但它真的是你想要的吗?