如何在Prolog中将大阶乘的求值写入文件?

如何在Prolog中将大阶乘的求值写入文件?,prolog,swi-prolog,bignum,prolog-toplevel,Prolog,Swi Prolog,Bignum,Prolog Toplevel,我试图将500000的阶乘计算导出到一个文件中,为此我编译了以下程序: fact(N, NF) :- fact(1, N, 1, NF). fact(X, X, F, F) :- !. fact(X, N, FX, F) :- X1 is X + 1, FX1 is FX * X1, fact(X1, N, FX1, F). 接下来我写: ?- fact(1, 500000, 1, F). 下一步: 完成测试后,我验证了只有该程序才能正常工作: ?- fac

我试图将500000的阶乘计算导出到一个文件中,为此我编译了以下程序:

fact(N, NF) :-
   fact(1, N, 1, NF).

fact(X, X, F, F) :-
   !.
fact(X, N, FX, F) :-
   X1  is X + 1,
   FX1 is FX * X1,
   fact(X1, N, FX1, F).
接下来我写:

?- fact(1, 500000, 1, F).
下一步:

完成测试后,我验证了只有该程序才能正常工作:

?- fact(1, 5772, 1, F).
为什么当我尝试导出大于5772的阶乘时,我会得到以下结果:

ERROR: $F was not bound by a previous query

我如何解决这个问题?如果您能提供任何帮助,我将不胜感激。

5772!大约是8 x 10^19205,所以我很惊讶您的PROLOG实现能够处理这么大的数字,尽管我并不惊讶它被500000阻塞了!,大约是10^2632341。更有可能的是,您的递归超过了PROLOG堆栈的最大大小

这两种情况在Prolog中都不太可能,所以尝试使用C或C++中的GNU多精度算术库(GMP),而不是重复地进行乘法运算。< /P>选项1:将输出管到文件中。 要实现这一点,最简单的方法之一是不进行任何修改:

您可以使用
-g
选项调用SWI Prolog,这样它不仅可以加载文件,还可以运行给定的Prolog目标。例如,如果将定义存储在
fact.pl
中,则可以运行:

swipl -g 'fact(1,50 000,1,F),portray_clause(F),halt' fact.pl
尝试以这样一种方式定义此关系,即它也会为这个所谓的最一般的查询提供正确的结果

提供的代码是正确的尾部递归代码,所以我看不出这个堆栈大小是如何限制的。。。请详细说明!您是否尝试过定义谓词而不是使用谓词?toplevel/shell/接口可能会遇到一些限制,即使计算运行得很好……正如@repeat所说,toplevel只记住“不太大”的术语 swipl -g 'fact(1,50 000,1,F),portray_clause(F),halt' fact.pl swipl -g 'fact(1,50 000,1,F),portray_clause(F),halt' fact.pl > fact.out ?- fact(1, 50 000, 1, F), open('Factorial.txt', write, Stream), write(Stream, F), close(Stream). ?- fact(N, F). N = F, F = 1.