Prolog中的阶乘列表

时间:2015-04-13 20:28:04

标签: list prolog factorial

我在解决以下问题时遇到了麻烦......

可以在Prolog中将因子描述为:

factorial(0, 1).
factorial(N, F) :-
   N1 is N - 1,
   factorial(N1, F1),
   F is N * F1.

我需要扩展此代码,以便返回所有先前的因子列表,直到N。但它只返回第一个阶乘(1),然后返回错误:ERROR: Out of local stack。这是我的代码:

insertList(H, L, [H|L]) :-
   !.

factorial(0, 1, [1]).
factorial(N, F, L) :-
   N1 is N - 1,
   factorial(N1, F1, L),
   F is N * F1,
   insertList(F, L, [F|L]). 

list_factorial(X, L) :-
   factorial(X, F, L).

我做错了什么?

4 个答案:

答案 0 :(得分:1)

以下是纯 的实现:

:- use_module(library(clpfd)).

list_factorial([1], 0).
list_factorial(Zs0, N) :-
   length(Zs0, N),
   N #> 0,
   list_n_fac(Zs0, 1, 1).

list_n_fac([], _, _).
list_n_fac([Z1|Zs], N0, Z0) :-
   Z1 #= Z0 * N0,
   N1 #= N0 + 1,
   list_n_fac(Zs, N1, Z1).

示例查询:

?- list_factorial(Zs, 8).
Zs = [1,2,6,24,120,720,5040,40320].

这是最常见的查询:

?- list_factorial(Zs, N).
(  N = 0, Zs = [1]
;  N = 1, Zs = [1]
;  N = 2, Zs = [1,2]
;  N = 3, Zs = [1,2,6]
;  N = 4, Zs = [1,2,6,24]
;  N = 5, Zs = [1,2,6,24,120]
...

答案 1 :(得分:0)

最小修正,表明主要问题

insertList(H, L, [H|L]):- !.

factorial(0, 1, [1]).
factorial(N, F, Fs):- N1 is N-1, factorial(N1, F1, L), F is N * F1, insertList(F, L, Fs). 

list_factorial(X, L):- factorial(X, F, L).

但是如果在返回第一个解决方案后请求回溯,它将循环。您可以添加建议的测试@false ...否则,另一个定义可能是

factorials(N, L) :-
    N > 0 -> L = [F,G|Fs], M is N-1, factorials(M, [G|Fs]), F is G*N ; L = [1].

答案 2 :(得分:0)

另一种解决方案是:

factorial(0,1) :- !.
factorial(N,F) :- 
    N>0, N1 is N - 1, factorial(N1,F1), F is N * F1.

list_factorial(N,L) :-
    N>1, !, N2 is N-1, list_factorial(N2,L2), factorial(N,F), append(L2,[F],L). 
list_factorial(N,[F]) :- factorial(N,F). 

如果N大于0,我会使用测试更改factorial,因为您不能使用负数的阶乘,而只能使用切割来获得一个解决方案。

答案 3 :(得分:-1)

你让我安装了SWI-prolog haha​​。

list_fact(N,M,A):- A is N * M.
list_fact(N,M,A):- N1 is N + 1, M1 is N * M, list_fact(N1,M1,A).

呼叫

list_fact(1,1,A).

这很简单。第一个规则将下一个阶乘计算为N * M. 第二个规则进行递归调用,其中N = N + 1,M =在规则1中计算的前一个因子。