prolog - 如何在 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,但这不应该能够有效地完成吗?
解决方案
问题是您不仅在读取数据,还试图将其编译为带有 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) ? ;
但是无论您要解决什么问题,这看起来都不是最有希望的方法...
推荐阅读
- html - 如何使用 VBA 取消选中 IE 上的框并编辑 HTML
- javascript - 如何使网站仅在某些浏览器中运行?
- javascript - 量角器在测试中加载或引用 3rd 方 JS 库
- android - SQLiteOpenHelper 获取数据库锁定
- mongodb - 在 mongoDB 中计算文档的最佳方法
- php - 同一页面上的多个简码不起作用
- javascript - 用于在字母数字字符串之间仅允许单个空格和单个连字符的正则表达式
- regex - 用于验证电子邮件本地部分 ORACLE 的正则表达式
- javascript - Vue路由器动态道具
- android - 解压密码保护 Zip 文件很慢,如何让它变快?