如何在Prolog中将大因子的评估写入文件?

时间:2017-10-28 23:40:35

标签: prolog swi-prolog bignum prolog-toplevel

我正在尝试将factorial 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).

下一步:

?- open('Factorial.txt', write, Stream), write(Stream, $F), close(Stream).
ERROR: $F was not bound by a previous query

完成测试后,我确认只有这个程序才有效:

?- fact(1, 5772, 1, F).

为什么当我尝试输出大于5772的阶乘数时,我得到了这个:

ERROR: $F was not bound by a previous query

我该如何解决这个问题?我将非常感谢您提供的任何帮助。

2 个答案:

答案 0 :(得分:4)

选项1:将输出传输到文件

实现此目标的最简单方法之一是无需修改

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

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

选项2:运行写入文件

的顶层查询

第二个选项是简单地组合您显示的查询,使它们不依赖于在任何情况下都不可移植的特定顶级功能:

?- fact(1, 50 000, 1, F),
   open('Factorial.txt', write, Stream),
   write(Stream, F),
   close(Stream).

fact/2

的正确性

独立于所有这些,您对fact/2的定义不正确,因为它表示只有单个解决方案:

?- fact(N, F).
N = F, F = 1.

尝试定义这种关系,以便为这个所谓的最常见的查询提供正确的结果!

答案 1 :(得分:-3)

5772!是大约8 x 10 ^ 19205,所以我很惊讶你的PROLOG实现可以处理这么大的数字,虽然我并不感到惊讶它窒息500000!,这是大约10 ^ 2632341。更有可能的是,您的递归超过了最大PROLOG堆栈大小。

在任何一种情况下,这在PROLOG中都不太可行,因此请尝试在C或C ++中使用GNU多精度算术库(GMP),然后乘以而不是递归。