【问题标题】:Recursively defined function of two integers in Prolog (partition function)Prolog中两个整数的递归定义函数(分区函数)
【发布时间】:2017-01-16 19:14:37
【问题描述】:

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

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

我想尝试在序言中表示这一点。这是我所能得到的:

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

【问题讨论】:

  • Prolog 不会在您的 partition(K, N, A+B) 子句头中评估 A+B。这只是 Prolog 中的一个术语。你需要partition(K, N, R) :- ... , R is A + B.

标签: recursion prolog number-theory


【解决方案1】:

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

冷静点,就算是功课,只要你做了合理的努力,寻求帮助是没有问题的(合理当然是主观的,但我觉得问题没问题)您自己,更重要的是您的实施存在特定问题:)。

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

然而,有一个谓词可以评估表达式树并使用大多数人都同意的“语义”。那就是is/2 谓词。所以现在你可以简单地修改为:

分区(K,N,C):- X是K+1, Y 是 N-K, 分区(X,N,A), 分区(K,Y,B), C 是 A+B。

是的,还有更多匹配项(显然更多)。

那是因为您的最后一个子句没有 guard 表示 K &lt; N,换句话说,Prolog 将 回溯,无论 KN 与彼此,它总是可以选择最后一个子句(K == N 除外,因为你在那里放置了一个切口 (!))。

你最好在最后一个子句中使用“guard”,否则在回溯时如果K &lt; N 可以调用它。所以完整的代码序列应该是这样的:

分区(N,N,1):-!。 %% http://stackoverflow.com/a/9582409 分区(K,N,0):- K > N。 分区(K,N,C):- K X是K+1, Y 是 N-K, 分区(X,N,A), 分区(K,Y,B), C 是 A+B。

请注意,is/2 没有什么特别之处:它只是一个谓词:您也可以使用 is(C,A+B) 来调用它。它只是以这样一种方式定义的,它也可以用作中缀运算符。

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

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

【讨论】:

  • 为什么是is(C, A+B) 而不是更传统的C is A + B
  • @lurker:我在底部添加了一个注释,表明两者是等价的。目的是不要让 OP 认为 is/2 在 Prolog 中是特别的东西。它只是一个将语义附加到函子的谓词。
  • 他们已经有了,例如X is K+1,所以我混入is(C, A+B) 可能会增加而不是减少混乱(OP 可以合理地思考,“为什么在这种情况下会有所不同?”)
  • @lurker:嗯,好点。甚至没有注意到is 的用法(太习惯了)。我已经更新了答案并将注释写反了。
  • @Lori:Prolog 可以对同一个查询给出多个答案:函数具有每个输入元组有一个答案的属性,但谓词可以有多个答案。 Prolog找到一个答案后,您可以询问是否还有更多。 Prolog 说 no:答案只有一个。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2023-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多