1

这是我的代码:

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
4

1 回答 1

2

好吧,因为这个,你得到的答案不止一个:

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/2var/1/搞砸了,并且nonvar/1无法解决那个小问题。

于 2013-02-22T19:07:39.067 回答