据我所知,通过健全的统一,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 logic-programming swi-prolog warren-abstract-machine occurs-check
逻辑编程背后的常用数学理论禁止创建循环项,规定每次变量与项统一时都应进行发生检查。不幸的是,发生检查会非常昂贵,以至于使 Prolog作为一种编程语言变得不切实际。
但是,我运行了这些基准测试(Prolog 的基准测试)并发现 SWI Prolog 在打开和关闭发生检查 (OC) 之间存在相当小的差异(小于 20%):
OC 关闭::- set_prolog_flag(occurs_check, false).在.swiplrc(重新启动)
?- run_interleaved(10).
% 768,486,984 inferences, 91.483 CPU in 91.483 seconds (100% CPU, 8400298 Lips)
true.
?- run(1).
'Program' Time GC
================================
boyer 0.453 0.059
browse 0.395 0.000
chat_parser 0.693 0.000
crypt 0.481 0.000
fast_mu 0.628 0.000
flatten 0.584 0.000
meta_qsort 0.457 0.000
mu 0.523 0.000
nreverse 0.406 0.000
poly_10 …Run Code Online (Sandbox Code Playgroud) 是否存在差异检查?这在这里有效:
Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.7)
?- set_prolog_flag(occurs_check, true).
true.
?- dif(X,f(Y)), X = Y.
X = Y.
Run Code Online (Sandbox Code Playgroud)
但以上是不可行的,因为发生检查是一个全局标志,我得到以下信息:
SWI-Prolog console for thread 3
?- X=f(X).
false.
Run Code Online (Sandbox Code Playgroud) 根据维基百科:
为所有统一提供声音统一的实现是 Qu-Prolog 和 Strawberry Prolog 以及(可选地,通过运行时标志):XSB、SWI-Prolog和 Tau Prolog。
但是,当我这样做时,apropos(occur)它只会找到unify_with_occurs_check/2. 该男子页面没有提到“出现”要么。如何为 SWI-Prolog 中的所有统一启用发生检查?
我正在阅读的一篇论文如下:
Plaisted [3] 表明,可以使用一阶谓词演算语义编写形式上正确的 PROLOG 程序,并导出无意义的结果,例如 3 < 2。
它指的是 Prologs 在当时(1980 年代)没有使用发生检查的事实。
不幸的是,它引用的论文是在付费墙后面。我仍然希望看到这样的例子。直觉上,感觉就像省略发生检查只是将结构的范围扩大到包括循环结构(但根据作者的说法,这种直觉一定是错误的)。
我希望这个例子不是
smaller(3, 2) :- X = f(X).
Run Code Online (Sandbox Code Playgroud)
那会令人失望。