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

时间:2017-01-16 19:14:38

标签: recursion prolog number-theory

我发誓这不是一个功课问题。几十年来我没有上过课。曾几何时,我想出了一个可爱的分区函数递归公式:

         / 0 (k > n)
f(k, n) {  1 (k = n)
         \ p(k, n-k)+p(k+1, n) (k < n)

我想在prolog中尝试代表这一点。这是我能得到的:

partition(N, N, 1) :- !. %% http://stackoverflow.com/a/9582409

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

partition(K, N, A+B) :-
 X is K+1,
 Y is N-K,
 partition(X, N, A),
 partition(K, Y, B).

?- partition(1, 10, X).给了我这个:

  

X = 1 + 0 + 0 + 0 + 0 + 1 +(1 + 0 + 0)+(1 + 0 + 0 + 0 +(1 + 0))+(1 + 0 + 0 + 0 + 1+(1 + 0 + 0)+(1 + 0 + 0 + 1 +(1 + 0 + 1)))+(1 + 0 + 0 + 0 + 0 +(1 + 0)+(1 + 0 + 0 + 1)+(1 + 0 + 0 + 0 +(1 + 0)+(1 + 0 + 0 +(1 + 0)))+(1 + 0 + 0 + 0 + 1 +(1 + 0 + 0)+(1 + 0 + 0 + 1 +(1 + 0 + 1))+(1 + 0 + 0 + 0 +(1 + 0)+(1 + 0 + 0 +(1 + 0) )+(1 + 0 + 0 + 1 +(1 + 0 + 1)+(1 + 0 + 0 +(1 + 0)+(1 + 0 + 1 +(1 + 0 +(1 + 1)) )))))))?

令人欣慰的是,在上面的表达中确实有42个(?)。我希望X=42.注意问号。是的,还有更多的比赛(显然无限多)。第二个是:

  

X = 1 + 0 + 0 + 0 + 0 + 1 +(1 + 0 + 0)+(1 + 0 + 0 + 0 +(1 + 0))+(1 + 0 + 0 + 0 + 1+(1 + 0 + 0)+(1 + 0 + 0 + 1 +(1 + 0 + 1)))+(1 + 0 + 0 + 0 + 0 +(1 + 0)+(1 + 0 + 0 + 1)+(1 + 0 + 0 + 0 +(1 + 0)+(1 + 0 + 0 +(1 + 0)))+(1 + 0 + 0 + 0 + 1 +(1 + 0 + 0)+(1 + 0 + 0 + 1 +(1 + 0 + 1))+(1 + 0 + 0 + 0 +(1 + 0)+(1 + 0 + 0 +(1 + 0) )+(1 + 0 + 0 + 1 +(1 + 0 + 1)+(1 + 0 + 0 +(1 + 0)+(1 + 0 + 1 +(1 +(0 + 0)+(1 +1)))))))))?

1 个答案:

答案 0 :(得分:3)

  

我发誓这不是一个功课问题。几十年来我没有上过课。

冷静下来,即使是家庭作业,在你做出合理努力的情况下寻求帮助也没有问题(合理的当然是主观的,但我认为问题还可以)你自己,并且更多的是你的实现存在特定问题:)。

你的方法的问题在于你 - 在众多中 - 认为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.
  

是的,有更多的匹配(显然无限多)。

那是因为你的最后一个条款没有 guard 表示K < N,换句话说,Prolog会回溯,无论K和{ {1}}彼此相关,它总是可以选择最后一个子句(N除外,因为你放了一个剪切(K == N))。

您最好使用“ guard ”作为最后一个子句,否则可以在回溯时!调用它。所以完整的代码序列会读取如下内容:

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.

请注意K < N没有什么特别之处:它只是一个谓词:您也可以使用is/2调用它。它只是以这种方式定义,它也可以用作中缀运算符。

使用给定的子句,查询给出:

is(C,A+B)