Recursion Prolog中两个整数的递归定义函数(配分函数)

Recursion Prolog中两个整数的递归定义函数(配分函数),recursion,prolog,number-theory,Recursion,Prolog,Number Theory,我发誓这不是家庭作业问题。我已经几十年没上课了。从前,我为配分函数想出了一个可爱的递归公式: / 0 (k > n) f(k, n) { 1 (k = n) \ p(k, n-k)+p(k+1, n) (k < n) ?-分区(1,10,X)。给出了以下信息: 1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+0+0+1+0+0

我发誓这不是家庭作业问题。我已经几十年没上课了。从前,我为配分函数想出了一个可爱的递归公式:

         / 0 (k > n)
f(k, n) {  1 (k = n)
         \ p(k, n-k)+p(k+1, n) (k < n)
?-分区(1,10,X)。
给出了以下信息:

1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+0+1+0+1+0+0+0+0+0+1+0+0+0+0++++0+0++0++++++0+++++++1(1(1+0+0+0+0+0+0+0+0+0+++++++++++0++++0+++0++++++++++++0))+,(1(1(1+++++++++++++++0))(1+0+0+1+(1+0+1)+(1+0+0+(1+0)+(1+0+1+)(1+0+)(1+1))?

令人欣慰的是,上述表达式(?)中确实有42个。我希望
X=42。
注意问号。是的,有更多的匹配(显然无限多)。第二个是:

1+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+0+0+1+0+0+0+0+0+0+0+0+0+1+0+1+0+0+0+0+0+1+0+0+0+0++++0+0++0++++++0+++++++1(1(1+0+0+0+0+0+0+0+0+0+++++++++++0++++0+++0++++++++++++0))+,(1(1(1+++++++++++++++0))(1+0+0+1+(1+0+1)+(1+0+0+)(1+0+1+)(1+(0+0)+(1+1)()))

我发誓这不是家庭作业问题。我已经几十年没上课了

冷静下来,即使这是家庭作业,如果你自己做了合理的努力(合理当然是主观的,但我认为这个问题是可以的),寻求帮助也没有问题,更重要的是,你的实施存在一个具体的问题:)

您的方法的问题是,您(在许多人中)认为Prolog将语义附加到函子上对于Prolog来说,
+
不是加号,也不是加在一起,
+
只是一个符号,它不计算它

然而,有一个谓词计算表达式树,并使用大多数人同意的“语义”。这就是
is/2
谓词。因此,现在您只需将其修改为:

partition(K, N, C) :- X is K+1, Y is N-K, partition(X, N, A), partition(K, Y, B), C is A+B. 请注意,
is/2
没有什么特殊之处:它只是一个谓词:您也可以用
is(C,a+B)
调用它。它的定义方式是,它也可以用作中缀运算符

对于给定的子句,查询将给出:

?- partition(1, 10, X).
X = 42 ;
false.

Prolog不会在
分区(K,N,A+B)
子句头中计算
A+B
。这只是序言中的一个术语。您需要
分区(K,N,R):-,R是A+B。
为什么
是(C,A+B)
而不是更传统的
C是A+B
?@潜伏者:我在底部添加了一条注释,说明两者是等效的。这样做的目的是为了不让OP误以为
is/2
在Prolog中是特殊的。它只是一个将语义附加到函子上的谓词。它们已经有了,例如,
X是K+1
,所以我混入
is(C,a+B)
可以增加而不是减少混淆(OP可以合理地想,“为什么在这种情况下它是不同的?”)@潜伏者:嗯,好的观点。甚至没有注意到
用法(太习惯了)。我已经更新了答案并写了相反的注释。@Lori:Prolog可以在同一个查询中给出多个答案:函数的属性是每个输入元组有一个答案,但谓词可以有多个答案。在Prolog找到一个答案后,您可以询问是否还有更多答案。序言说不:答案只有一个。
partition(N, N, 1) :- !. %% http://stackoverflow.com/a/9582409

partition(K, N, 0) :- K > N.

partition(K, N, C) :-
    K < N,
    X is K+1,
    Y is N-K,
    partition(X, N, A),
    partition(K, Y, B),
    C is A+B.
?- partition(1, 10, X).
X = 42 ;
false.