好吧,因为这个,你得到的答案不止一个:
convertToD(A,0).
您在这里的意思是convertToD(0, 0)
,因为否则当您的意思是“convertToD 对于 0 是 0”时,您会说“convertToD 在任何东西和 0 之间都是真的”。这也是 Prolog 认为你有多个结果的原因。
经过一番思考并注意到一个问题,这个问题是 的副本,我明白你试图用第二个子句来完成什么。您要做的是在普通 Prolog 中模拟 clpfd 解决方案。使用 clpfd:
convertToD(succ(S), Y) :- numeral(S), Y0 #= Y-1, convertToD(S, Y0).
将其直接复制到 vanilla 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
无法解决那个小问题。