我正在完成一项由两部分组成的家庭作业。 第一个是编写Prolog程序,检查某个对X,Y是否属于http://en.wikipedia.org/wiki/Triangular_number。例如:(2,3)= true; (4,10)= true等等。
第一个解决方案使用'普通'递归,我已经解决了这个问题:
triangle(0, 0).
triangle(X, Y) :- X > 0, Y > 0, A is X - 1, B is Y - X, triangle(A, B).
第二部分是使用尾递归/累加器,使用三角形/ 3谓词来解决这个问题。 虽然我在另一个分配中使用了累加器,其中使用非常明显,所以我对如何使用累加器有一个大概的想法,我很清楚如何在这种情况下使用它。
所以,我不是在寻找算法,我宁愿自己解决这个问题,而是更多关于如何在这种情况下应用累加器的实用建议。
答案 0 :(得分:3)
开头始终是相同的,即前三行基本上是您为每个尾递归谓词编写的(对于列表谓词,使用[]
而不是0
。
从那里你可以继续进行很多改变:
triangle_t(X, Y) :- triangle_t(X, 0, Y).
triangle_t(0, Y, Y).
triangle_t(X, Acc, Y) :-
X > 0,
A is X - 1,
AccX is Acc + X,
triangle_t(A, AccX, Y).
以下是大型X的一些统计信息:
64 ?- time(triangle(1000000,500000500000)).
% 4,000,000 inferences, 0.50 CPU in 0.52 seconds (96% CPU, 8012769 Lips)
true.
65 ?- time(triangle_t(1000000,500000500000)).
% 3,000,001 inferences, 0.41 CPU in 0.44 seconds (92% CPU, 7396405 Lips)
true.
所以,虽然你自己的谓词基本上已经是尾递归(因为递归调用是最后要做的事情),带累加器的版本仍然会节省一些时间,因为你不需要检查Y > 0
。如果在triangle_t
谓词中引入此行,它们将再次具有完全相同的运行时特性:
67 ?- time(triangle_t(1000000,500000500000)).
% 4,000,001 inferences, 0.53 CPU in 0.53 seconds (100% CPU, 7541432 Lips)
true.
另请注意,您现在可以使用谓词生成第n个三角形数字。