这是我的代码:
numeral(0).
numeral(succ(X)) :- numeral(X).
convertToD(A,0).
convertToD(succ(S), Y) :- numeral(S), Y1 is Y-1, convertToD(S, Y1).
为什么这会给我这样的输出?
convertTo(succ(succ(0)), N).
N = 0 ;
ERROR: convertTo/2: Arguments are not sufficiently instantiated
答案 0 :(得分:2)
嗯,你得到的答案不止一个:
convertToD(A,0).
你在这里的意思是convertToD(0, 0)
,因为你的意思是“convertToD在任何和0之间是正确的”,当你的意思是“convertToD为0为0”时这也是Prolog认为你有多重结果的原因。
在给了它一些思考并注意到a question this question is a duplicate of之后,我看到你试图用第二个条款完成的事情。你要做的是在普通的Prolog中模拟clpfd解决方案。使用clpfd:
convertToD(succ(S), Y) :- numeral(S), Y0 #= Y-1, convertToD(S, Y0).
将其简单地复制到香草Prolog中,我们会在这里获取您的代码,但不会发生的是所有魔法clpfd带来的。如果没有clpfd,很难创建一个适用于任何实例化组合的谓词,并且永远不会循环。有一点有帮助的是最后移动算法:
convertToD(succ(S), Y) :- numeral(S), convertToD(S, Y1), succ(Y1, Y).
这为我们提供了一个具有所有理想属性的谓词,除了它在这里循环:
?- convertToD(X, 3).
X = s(s(s(0))) ;
^CAction (h for help) ? abort
我与when/2
和var/1
/ nonvar/1
混淆了这一点,并且无法解决这个小问题。