首页 > 解决方案 > 如何在 ECLiPSe 中读取大型 Prolog 文件?

问题描述

我通过eclipse生成了一个大的路径文件。每行包含一个包含 27 个点的列表的子句。

$ wc -l snake_points.pl
240917 snake_points.pl

$ ls -lh snake_points.pl
-rw-rw-r-- 1 carl carl 72M Sep  6 02:39 snake_points.pl

$ head -n 1 snake_points.pl 
snake_points([(2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 2), (2, 1, 1), (2, 1, 0), (2, 2, 0), (2, 2, 1), (2, 2, 2), (1, 2, 2), (0, 2, 2), (0, 1, 2), (0, 0, 2), (0, 0, 1), (0, 1, 1), (0, 1, 0), (0, 2, 0), (0, 2, 1), (1, 2, 1), (1, 2, 0), (1, 1, 0), (1, 1, 1), (1, 1, 2), (1, 0, 2), (1, 0, 1), (1, 0, 0), (0, 0, 0)]).

但是,我无法将文件加载到内存中(即使有 8G 堆):

$ time eclipse -f snake_points.ecl -e 'halt.'
*** Overflow of the global/trail stack in spite of garbage collection!
You can use the "-g kBytes" (GLOBALSIZE) option to have a larger stack.
Peak sizes were: global stack 8388576 kbytes, trail stack 59904 kbytes

________________________________________________________
Executed in  128.05 secs   fish           external 
   usr time  122.92 secs  297.00 micros  122.92 secs 
   sys time    5.01 secs   37.00 micros    5.01 secs 

将此与swipl

$ time swipl -f snake_points.pl -g 'halt.'

________________________________________________________
Executed in   53.56 secs   fish           external 
   usr time   53.27 secs  272.00 micros   53.27 secs 
   sys time    0.28 secs   41.00 micros    0.28 secs 

两者都不令人印象深刻,但我希望 ECLiPSe 能够以合理的内存量完成。

这是预期的行为吗?可以做什么?

我知道解决方案可能是“使用数据库”或 EXDR,但这不应该能够有效地完成吗?

标签: prologeclipse-clp

解决方案


问题是您不仅在读取数据,还试图将其编译为带有 240917 个子句的单个谓词,而编译器确实不是为这种用法而构建的。

您可以改为从数据文件中逐一读取和断言子句,如下所示:

assert_from_file(File) :-
        open(File, read, S),
        repeat,
            read(S, Term),
            ( Term == end_of_file ->
                true
            ;
                assert(Term),
                fail
            ),
        !, close(S).

这会在有限的时间内加载您的数据

?- assert_from_file("snake_points.pl").
Yes (19.38s cpu)

然后您可以按预期调用生成的谓词

?- snake_points(X).
X = [(2, 0, 0), (2, 0, 1), (2, 0, 2), (2, 1, 2), (2, 1, 1), (2, 1, 0), (2, 2, 0), (2, 2, 1), (2, 2, 2), (1, 2, 2), (0, 2, 2), (0, 1, 2), (0, 0, 2), (0, 0, 1), (0, 1, 1), (0, 1, 0), (0, 2, 0), (0, ..., ...), (..., ...), ...]
Yes (0.04s cpu, solution 1, maybe more) ? ;

但是无论您要解决什么问题,这看起来都不是最有希望的方法...


推荐阅读