这是一个不寻常的问题
虽然@Steven发现主要问题还有其他问题。也就是说,当两个人会做时,你有四个条款。 (编辑:由于缩进不正确,我误读了这个问题,正如下面的@Steven所提到的那样。“第四个子句”不存在。)您可以删除第一个和第四个:sumNM(0,0,0)
实际上与其他两个子句匹配(0 =毕竟),第四个条款是一个“任何事情”条款,可能根本就不存在。例如,sumNM(50,45,N)
产量N = 15
和sumNM(50,45,15)
统一一次,然后结束创建一个例外,因为N是未绑定的。为什么?因为最后的条款基本上通过了任何事sumNM(50,45,10000000)
也统一,这似乎显然是不真实的。但sumNM(_,_,_)
的意思是“任何三件事情都与sumNM/3
有关。” sumNM(N,C,B)
和sumNM(_,_,_)
之间没有区别:这就是为什么你得到单身变量警告。如果你发现这个令人惊讶的事情,那就表明对某个地方的变量的性质存在误解。
在这种情况下,如果你真的有排除它可能是最简单的(并导致更少的假选择点/解决方案)使用if/else构造。因此,我会推荐以下实现:
sumNM(N,M,S):-
(
N =< M
->
S is 0
;
A is N-M,
C is M+1,
sumNM(N,C,B),
S is B+A
).
请注意,此实现仍然只是部分正确!这就是现在的工作(并注意我们没有得到提示额外的解决方案,而无需使用切):
?- sumNM(50,45,15).
true.
?- sumNM(50,45,20000000).
false.
但是,这仍然没有:
?- sumNM(50,X,Y).
ERROR: =</2: Arguments are not sufficiently instantiated
的情况很可能被纠正通过使用clpfd,但我无法帮助你到达那里。
这很有效,谢谢。我想这对我来说很难在这里围绕序言逻辑。对递归函数先递增M,然后再将两个前面的函数加在一起,似乎是违反直觉的......在我之前,我认为你把这个总和加到目前的数字上。 – 2014-10-17 03:32:24
这也是一种可能的方法,但它需要另一个参数(称为累加器)。你可能想尝试一下,但目前的方法肯定没有错。 – Steven 2014-10-17 03:36:25
你是一个巫师,史蒂文。我只是想知道B如何在这里实例化。在我看来,例如,如果输入sumNM(5,1,S),它会运行sumNM(5,2,B),B仍然是空白的。为什么这个工作? – 2014-10-17 03:42:08