我正在尝试将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
我该如何解决这个问题?我将非常感谢您提供的任何帮助。
答案 0 :(得分:4)
实现此目标的最简单方法之一是无需修改:
您可以使用-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
第二个选项是简单地组合您显示的查询,使它们不依赖于在任何情况下都不可移植的特定顶级功能:
?- 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),然后乘以而不是递归。