Prolog中的总和数达N-M

时间:2014-10-17 02:52:12

标签: recursion prolog

嘿我需要创建一个函数countNM(N,M,S),它将所有数字相加到N-M(如果N等于或小于M,则返回0)。我已经解决了这个问题,当我在头脑中完成它时,我的意义是有道理的,但有些东西是未经实例化的......

sumNM(0,0,0).
sumNM(N,M,S):-
    N=<M,
    S is 0.
sumNM(N,M,S):-
    N>M,
    A is N-M,
    B is S+A,
    C is M+1,
    sumNM(N,C,B).

2 个答案:

答案 0 :(得分:1)

问题在于

B is S+A,

此时,S未绑定,导致算术表达式失败。

除此之外,这个表达背后的逻辑也是错误的。你所说的是,少一个数(B)的总和等于总和(S)加上当前数(A)。这应该是另一种方式。

您可以使用以下代码替换最后一个谓词:

sumNM(N,M,S):-
    N>M,
    A is N-M,
    C is M+1,
    sumNM(N,C,B),
    S is B+A.

这里我们首先计算总和B,然后我们向它添加A,得到总和S.

答案 1 :(得分:1)

这是一个不寻常的问题。

虽然@Steven发现了主要问题但还存在其他问题。也就是说,当两个人做时,你有四个条款。 (编辑:由于不正确的缩进,我误读了这个问题,正如@Steven在下面提到的那样。&#34;第四条&#34;不存在。)你可以删除第一个和第四个:{ {1}}实际匹配其他两个子句(毕竟0 =&lt; 0),第四个子句是&#34;任何事情都是&#34;可能不应该存在的条款。例如,sumNM(0,0,0)产生sumNM(50,45,N)N = 15统一一次,然后结束创建异常,因为N未绑定。为什么?因为最后一句基本上传递了任何东西sumNM(50,45,15)也统一,这看起来显然是不真实的。但sumNM(50,45,10000000)表示&#34;任何三件事都与sumNM(_,_,_)相关。&#34; sumNM/3sumNM(N,C,B)之间没有区别:这就是为什么你要获得单例变量警告的原因。如果你发现这一点令人惊讶,那就表明对某些变量的性质存在误解。

在这样的情况下,你确实有一个排除它可能是最简单的(并导致更少的虚假选择点/解决方案)使用if / else结构。因此,我建议采用以下措施:

sumNM(_,_,_)

请注意,此实现仍然只是部分正确!这现在有效(并且注意我们不会被提示提供其他解决方案,而不必使用切割):

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.

使用clpfd可能会纠正这种情况,但我无法帮助您实现目标。