Prolog 匹配 vs miniKanren 统一

Posted

技术标签:

【中文标题】Prolog 匹配 vs miniKanren 统一【英文标题】:Prolog matching vs miniKanren unification 【发布时间】:2016-02-18 11:39:34 【问题描述】:

在 Prolog - 人工智能编程中,Bratko 在第 58 页说了以下内容。

“Prolog 中的匹配对应于所谓的逻辑统一。但是,我们避免使用统一这个词,因为在大多数 Prolog 系统中出于效率原因,匹配的实现方式与统一并不完全对应。适当的统一需要所谓的发生检查:给定的变量是否出现在给定的术语中?发生检查会使匹配效率低下。”

我的问题是 miniKanren 中的统一是否会受到这种效率损失,或者这个问题是如何解决的?

【问题讨论】:

【参考方案1】:

这里有几个误解。首先,在 Prolog 中也可以使用 ISO 谓词 unify_with_occurs_check/2 进行声音统一。

其次,默认情况下,可以在某些 Prolog 系统中为 all 统一启用此声音统一。例如,参见 SWI-Prolog 中的 occurs_check Prolog 标志。

第三,很容易构建启用发生检查的示例,使您的程序顺序放大比禁用检查更快

第四,使用术语匹配来描述省略发生检查的统一是一个非常糟糕的主意:匹配在函数式语言中意味着单向统一。在 Prolog 中,统一总是在各个方向上起作用,即使发生检查被禁用。

因此,对于问题的 Prolog 部分,如果您的 Prolog 系统支持,我强烈建议启用发生检查来测试您的程序。通常,发生检查的统一需要表示Prolog程序中的编程错误。出于这个原因,例如,您可以设置标志,使系统抛出一个异常,否则它会创建一个循环项。

【讨论】:

“需要发生检查的统一表示编程错误”:您可以更明确地说明这一点。我仍然需要看到一个需要循环术语的 Prolog 代码的一个很好的实际示例。你知道这样的例子吗? 一个相关问题:您能否展示或链接到实际示例,其中发生检查使程序更快,resp。慢点?我不得不承认我从未尝试过使用循环术语,而只是使用了香草统一(没有发生检查),因为我认为这无关紧要。 我曾经见过 Stefan Kral 对循环项的巧妙应用,他用循环项来表示图灵机的无限带(最初用0 填充),以Tape = [0|Tape] 开头,并从那里开始。有关 with 发生检查工作速度快数百倍的实际示例,请参阅 Ulrich Neumerkel 等人。 “Declarative Language Extensions for Prolog Courses”。 @Boris:无限树的“实用”示例是当前 SWI 中 CHR 的实现。 @Boris Coinduction 为循环项提供了一个很好的例子。参见例如github.com/LogtalkDotOrg/logtalk3/tree/master/examples/… 举几个例子。【参考方案2】:

在 Prolog 中,发生检查是可选的。在 SWI Prolog 中,您可以将其全局打开、关闭或配置 Prolog 以在发生检查成功时引发error(这对于调试旨在在关闭发生检查的情况下运行的程序非常有用)

另一方面,在 miniKanren 中,发生检查是非可选的

【讨论】:

以上是关于Prolog 匹配 vs miniKanren 统一的主要内容,如果未能解决你的问题,请参考以下文章

MiniKanren 有“非”运算符吗?

使用 clojure 的 core.logic / minikanren 查找相似的集合

“事实数据库”不是迷你看人的核心功能吗?

部分字典/记录统一?

visual prolog是啥编程软件?

miniKanren:如何定义#s和#u?