Recursion 在Prolog中求和到N-M的数

Recursion 在Prolog中求和到N-M的数,recursion,prolog,Recursion,Prolog,嘿,我需要做一个函数countNMN,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). 问题就在眼前 B is S+

嘿,我需要做一个函数countNMN,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).

问题就在眼前

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。

这是一个不寻常的问题

虽然@Steven发现了主要问题,但还有其他问题。也就是说,你有四个子句,两个就行了。编辑:正如下面@Steven提到的,由于缩进不当,我误读了这个问题。第四条不存在。您可以删除第一个和第四个:sumNM0,0,0实际上与其他两个子句0=<0匹配,而第四个子句是一个可能根本不应该存在的anything-goes子句。例如,sumNM50,45,N产生N=15,sumNM50,45,15统一一次,然后由于N未绑定而创建异常。为什么?因为最后一条基本上通过了任何东西。SUMNM50410000000也统一了,这显然是不真实的。但是sumNM_uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。sumNMN,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,X,Y).
ERROR: =</2: Arguments are not sufficiently instantiated

这种情况可能可以通过使用来纠正,但我无法帮助您达到目的。

这很有效,谢谢。我想我很难在这里理解序言逻辑。运行递归函数时,首先递增M,然后将前面的两个函数相加,这似乎违反直觉。。。在我开始思考之前,先求和,然后加上当前的数字。这也是一种可能的方法,但它需要另一个称为累加器的参数。你可能想把它作为一种练习来尝试,但目前的方法肯定没有错。史蒂文,你是个巫师。我只是想知道B在这里是如何实例化的。在我看来,例如,如果您输入sumNM5,1,S,它将运行sumNM5,2,而B仍然为空。为什么这样做?在调用sumNM5,2,B之前,B确实仍然为空,但在调用完成后,它将有一个值。sumNM5,2,B将依次调用sumNM5,3,B,这将调用sumNM5,4,B,这将调用sumNM5,5,B,这将S在该点统一为0。在那之后,每一级递归将把它们的当前值加到这个和B上,这是它们自己的和S。关于第一个子句,你是对的,我没有提到它。但是,没有第四条。最后一行是第三句的一部分,由于缩进不当,它看起来就像第四句。除此之外,这是一个完全正确的答案。很好。编辑问题。
?- sumNM(50,X,Y).
ERROR: =</2: Arguments are not sufficiently instantiated