现代Prolog编译器是否会自动优化occurs检查,当它';安全吗?

现代Prolog编译器是否会自动优化occurs检查,当它';安全吗?,prolog,unification,occurs-check,Prolog,Unification,Occurs Check,编辑:此问题假设您启用了发生检查。这不关你的事 30年前有一大堆关于在安全的情况下自动优化occurs检查的论文(大约90%的谓词,在典型的代码库中)。提出了不同的算法。现代Prolog编译器(如SWI-Prolog)是否会执行类似的操作(当启用“发生”检查时)?他们喜欢什么算法 例如,在编译如下谓词时,他们是否会删除occurs检查: less(0, s(_)). less(s(X), s(Y)) :- less(X, Y). (从下面的讨论中)除非您特别要求SWI Prolog: 通过在

编辑:此问题假设您启用了发生检查。这不关你的事

30年前有一大堆关于在安全的情况下自动优化occurs检查的论文(大约90%的谓词,在典型的代码库中)。提出了不同的算法。现代Prolog编译器(如SWI-Prolog)是否会执行类似的操作(当启用“发生”检查时)?他们喜欢什么算法

例如,在编译如下谓词时,他们是否会删除occurs检查:

less(0, s(_)).
less(s(X), s(Y)) :- less(X, Y).

(从下面的讨论中)

除非您特别要求SWI Prolog:

  • 通过在本地使用而不是
    =
    。(请注意,这意味着头部统一不受影响,即仍然运行而不进行检查-我认为?)
  • 通过在设置标志时全局打开发生检查:
    set\u prolog\u标志(发生检查,true)
这是个问题吗?我不这么认为

考虑一下在其他编程语言(或者甚至在Prolog中)中使用断言的相关案例:我衷心推荐它

当您开发时,您将启用这些“开关”,以在运行时以一定的CPU成本验证约束。一旦你确定你的程序可以运行(通过构造、prrof和测试),你就可以“关闭它们”。您的程序和任何调用方(可能是恶意的、混乱的或有缺陷的)之间的接口仍可能受到检查的保护,以便执行接口契约


发生检查的情况与此类似:如果您怀疑循环数据结构可能发生并导致问题,请打开“发生检查”。编写您的程序代码,以便一切正常(并且您确信它正常工作,最好是通过构造和验证)。然后再次将其关闭。

当occurs check标志设置为“true”时,有多种优化方法可以优化occurs检查。这对于在普通情况下实现合理的统一是必要的。典型的优化是检测头部的线性:

linear(Head) :-
   term_variables(Head, Vars),
   term_singletons(Head, Singletons),
   Vars == Singletons.
在这种情况下,调用子句时可以省略occurs检查。我们可以对
less/2
示例进行测试,看头部是否为线性。结果表明,两个头都是线性的:

?- linear(less(0, s(_))).
true.

?- linear(less(s(X), s(Y))).
true.
因此,Prolog系统可以完全忽略谓词
less/2
的发生检查,但仍然可以产生良好的统一。例如,在检查中间代码时,可以在Jekejeke Prolog中看到这种优化。使用的指令为unify\u linear:

?- vm_list(less/2).

less(0, s(A)).
  0  unify_linear _0, 0
  1  unify_linear _1, s(A)
less(s(X), s(Y)) :-
   less(X, Y).
  0  unify_linear _0, s(X)
  1  unify_linear _1, s(Y)
  2  goal_last less(X, Y)
与指令unify_项相反,指令unify_linear不执行发生检查,即使发生检查标志设置为true


里图·查达;David A.Plaisted(1994年)“在prolog中无需检查统一的正确性”。逻辑编程杂志。18 (2): 99–122. .

什么也很流行,在变量内部使用区别,比如“新鲜”和“过时”变量。“新鲜”变量通常不需要进行发生检查

可以动态地进行区分。以下是一些结果,动态区分(“新鲜度”)也可以与一些静态分析(“线性”)相结合:

上图显示了基于引用计数的启发式结果。下面的文章讨论使用一位,即将变量标记为未绑定或新的未绑定

重新审视发生检查问题-啤酒,1988

问题假定启用了occurs检查,当然(否则,没有要删除的内容):“(当启用occurs检查时)?“@MaxB Aie。。。太晚了。SWI-Prolog本身不会更改ISO标志。在“sto(术语)一节中,建议参见ISO/IEC 13211-1序言:第1部分-通用核心的7.3.3,了解sto和NSTO的详细讨论