Prolog初学者 - 反向输出列表

时间:2014-12-14 10:28:42

标签: list prolog reverse fibonacci

我是Prolog的初学者,我正在寻找一种方法来反转此代码的输出。

fib(N, F) :- fib(N, 0, [1], F).
fib(0, _, A, A).
fib(N, A, [B|Bs], F) :- N1 is N - 1, Sum is A + B, fib(N1, B, [Sum,B|Bs], F).

代码计算N值的斐波纳契数,并将结果打印在F

例如fib(4,X).生成X=[5,3,2,1,1]。我想要的是X=[1,1,2,3,5](反向输出)。

我似乎无法将其带入此格式,并保留其尾递归属性。

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

如果您只想在结尾处反转列表,请使用reverse/2

fib(N, F) :- fib(N, 0, [1], FRev), reverse(FRev, F).

如果要以相反的顺序构建列表,则必须重新考虑这些子句。一种解决方案是使用last/2append/3将新元素放在累加器的末尾,而不是放在它前面。


在返回第一个解决方案后,Prolog尝试找到第二个解决方案,您可能会收到错误:

?- fib(5, F).
F = [8, 5, 3, 2, 1, 1] ;
ERROR: Out of global stack

这种情况发生的原因是因为目标fib(0, ...) Prolog使用第一个规则,但创建了一个选择点,它稍后会回溯到它。从那时起,堆栈中充满了目标:fib(-1,...)fib(-2,...)等。这些都不会满足。您应该在fib/4的第一个子句中放置一个cut运算符:

fib(0, _, A, A):-!.

因此不会尝试使用第二条规则重新fib(0,...)

?- fib(5, F).
F = [8, 5, 3, 2, 1, 1].