嘿我需要创建一个函数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).
答案 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/3
和sumNM(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可能会纠正这种情况,但我无法帮助您实现目标。