2014-10-17 82 views
-1

嘿我需要做一个函数countNM(N,M,S),它将所有数字加起来为N-M(如果N等于或小于M,则返回0)。我已经工作了和我有什么是有意义的,当我通过它在我的脑海工作,但事情是未初始化...Prolog中最大为N-M的总数

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). 

回答

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.

+0

这很有效,谢谢。我想这对我来说很难在这里围绕序言逻辑。对递归函数先递增M,然后再将两个前面的函数加在一起,似乎是违反直觉的......在我之前,我认为你把这个总和加到目前的数字上。 – 2014-10-17 03:32:24

+0

这也是一种可能的方法,但它需要另一个参数(称为累加器)。你可能想尝试一下,但目前的方法肯定没有错。 – Steven 2014-10-17 03:36:25

+0

你是一个巫师,史蒂文。我只是想知道B如何在这里实例化。在我看来,例如,如果输入sumNM(5,1,S),它会运行sumNM(5,2,B),B仍然是空白的。为什么这个工作? – 2014-10-17 03:42:08

1

这是一个不寻常的问题

虽然@Steven发现主要问题还有其他问题。也就是说,当两个人会做时,你有四个条款。 (编辑:由于缩进不正确,我误读了这个问题,正如下面的@Steven所提到的那样。“第四个子句”不存在。)您可以删除第一个和第四个:sumNM(0,0,0)实际上与其他两个子句匹配(0 =毕竟),第四个条款是一个“任何事情”条款,可能根本就不存在。例如,sumNM(50,45,N)产量N = 15sumNM(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,但我无法帮助你到达那里。

+0

你对第一个条款是正确的,我没有打扰提及它。但是没有第四个条款。最后一行是第三个子句的一部分,由于缩进不正确,它看起来像是第四个子句。除此之外,这是一个完全有效的答案。 – Steven 2014-10-17 06:08:21

+0

好的。编辑问题。 – 2014-10-17 06:26:44