Max*_*axB 8 prolog logic-programming swi-prolog warren-abstract-machine occurs-check
据我所知,通过健全的统一,SLD 解析不应该创建循环数据结构(这是正确的吗?)
如果是这样,理论上可以以不需要垃圾收集 (GC) 的方式实现 Prolog。但话又说回来,一个人可能不会。
对于基于 WAM 的 Prolog 实现来说,这是真的吗?
SWI-Prolog 是这样吗?(我相信它不是基于 WAM 的)当发生检查全局启用时,在 SWI-Prolog 中禁用 GC 是否安全?
具体来说:
:- set_prolog_flag(occurs_check, true).
:- set_prolog_flag(gc, false). /* is this safe? */
Run Code Online (Sandbox Code Playgroud)
循环项的创建远不是Prolog中唯一可以创建垃圾(如垃圾收集)的操作(同样值得注意的是,并非所有Prolog系统都对循环项提供全面支持,但大多数都支持某种形式的垃圾收集) .
例如,假设您的代码中有以下从数字到原子的调用序列:
...,
number_codes(Number, Codes),
atom_codes(Atom, Codes),
...
Run Code Online (Sandbox Code Playgroud)
这Codes是一个应该被垃圾收集的临时列表。另一个示例,假设您正在调用setof/3以获取您只对前两个感兴趣的结果的有序列表:
...,
setof(C, x(X), [X1, X2| _]),
...
Run Code Online (Sandbox Code Playgroud)
您刚刚创建了另一个临时列表。或者您忘记sub_atom/5并决定使用它atom_concat/3来检查原子的前缀:
...,
atom_concat(Prefix, _, Atom),
...
Run Code Online (Sandbox Code Playgroud)
第二个参数,您不关心的原子后缀(因此是匿名变量),是您刚刚创建的临时原子。但并非所有 Prolog 系统都提供原子垃圾收集器,这可能会导致长时间运行的应用程序出现问题。
但是即使您认为您已经仔细地编写了代码以避免创建临时术语,Prolog 系统在运行您的代码时仍然可能会产生垃圾。Prolog 系统为不同的目的使用不同的内存区域,并且操作可能需要在不同的内存区域之间制作内存段的临时副本,具体取决于实现。Prolog 系统可以用一种语言编写,例如 Java,最终可能会处理这些垃圾。但很可能它是用 C 或 C++ 编写的,并且在内部使用了某种垃圾收集。更不用说 Prolog 系统可能会占用一大块内存来证明查询,然后在查询终止后回收该内存。