在逻辑编程方面,Prolog和miniKanren之间的主要技术差异是什么?

当我想阅读逻辑编程时,我总是绊倒两个“主要”的方式来做它现在:

> miniKanren,一种在The Reasoned Schemer年推出的小语言,目前由于core.logic流行。
> Prolog,第一个“大”逻辑编程语言。

我现在感兴趣的是:两者之间的主要技术差异是什么?他们在方法和实现上非常相似,或者他们对逻辑编程采用完全不同的方法吗?他们来自哪些数学分支,什么是理论基础?

首先,请允许我赞美你的罚款pw0n1e图标。

这是一个棘手的问题要回答,主要是因为有这么多变体的miniKanren和Prolog。 miniKanren和Prolog是真正的语言家族,这使得很难比较他们的功能,甚至如何在实践中使用。因此,请谨慎对待所有我要说的话:如果我说Prolog使用深度优先搜索,请注意许多Prolog实现支持其他搜索策略,并且替代搜索策略也可以在元数据解释器级别。然而,miniKanren和Prolog有不同的设计理念,并做出不同的权衡。

Prolog是符号人工智能编程的两种经典语言之一(另一种经典语言是Lisp)。 Prolog擅长实现基于符号规则的系统,其中声明性知识是用一阶逻辑编码的。该语言针对这些类型的应用程序的表达性和效率进行了优化,有时以牺牲逻辑纯度为代价。例如,默认情况下Prolog不使用统一中的“发生检查”。从数学/逻辑的角度来看,这个版本的统一是不正确的。然而,发生的检查是昂贵的,并且在大多数情况下,缺少发生的检查不是问题。这是一个非常务实的设计决策,Prolog使用深度优先搜索和使用cut(!)控制回溯。我确信这些决定在20世纪70年代的硬件上运行时是绝对必要的,今天在处理大问题时以及在处理巨大(通常是无限的)搜索空间时非常有用。

Prolog支持许多“非逻辑”或“非逻辑”特性,包括cut,assert和retract,使用is的算法的变量投影等等。许多这些功能使得更容易表达复杂的控制流,并操纵Prolog的全局事实数据库。 Prolog的一个非常有趣的特性是Prolog代码本身存储在事实的全局数据库中,并且可以在运行时查询。这使得编写解释器来修改解释下的Prolog代码的行为变得轻而易举。例如,可以使用改变搜索顺序的元解释器对Prolog中的广度优先搜索进行编码。这是一个非常强大的技术,在Prolog世界之外不是众所周知的。 “Prolog的艺术”详细描述了这种技术。

巨大的努力已经改进了Prolog实现,其中大部分基于Warren抽象机(WAM)。 WAM使用副作用模型,其中值被破坏性地分配给逻辑变量,这些副作用在回溯时被撤消。通过扩展WAM的指令,可以将许多功能添加到Prolog中。这种方法的一个缺点是,如果没有对WAM的充分理解,Prolog实现文件可能难以阅读。另一方面,Prolog实现者有一个共同的模型来讨论实现问题。在并行Prolog中已经进行了大量的研究,在20世纪90年代达到了安道尔的Prolog。至少有一些想法住在Ciao Prolog。 (Ciao Prolog充满了有趣的想法,其中许多远远超出了Prolog标准。)

Prolog有一个美丽的统一为基础的“模式匹配”的语法,导致非常简洁的程序。 Prologers喜欢他们的语法,就像Lispers爱他们的s表情。 Prolog也有一个大的标准谓词库。由于所有的工程已经使WAM快速,有非常有能力和成熟的Prolog实现。因此,许多大型的基于知识的系统已经完全在Prolog中编写。

miniKanren被设计为一个最小的逻辑编程语言,具有一个小的,易于理解的和容易hackable的实现。 miniKanren最初嵌入在Scheme,并在过去十年移植到几十种其他主机语言。最流行的miniKanren实现是Clojure中的“core.logic”,它现在有许多类似Prolog的扩展和一些优化。最近,miniKanren实现的核心已经进一步简化,导致了一个微小的“微内核”,称为“microKanren”。 miniKanren可以在这个microKanren核心之上实现。将microKanren或miniKanren移植到新的主机语言已成为程序员学习miniKanren的标准练习。因此,最流行的高级语言至少有一个miniKanren或microKanren实现。

miniKanren和microKanren的标准实现不包含突变或其他副作用,只有一个例外:一些版本的miniKanren使用指针等于比较逻辑变量。我认为这是一个“良性效应”,尽管许多实现通过在执行中传递计数器来避免甚至这种效果。还没有全球事实数据库。 miniKanren的实现哲学是受函数编程的启发:应该避免变异和效应,所有语言结构都应该尊重词汇范围。如果你仔细看看实现,你甚至可以发现几个单子。搜索实现是基于组合和操纵延迟流,再次不使用突变。这些实现选择导致非常不同于在Prolog中的权衡。在Prolog中,变量查找是恒定时间,但是回溯需要撤消副作用。在miniKanren中,变量查找更昂贵,但回溯是“自由的”。事实上,在miniKanren中没有回溯,由于如何处理流。

miniKanren实现的一个有趣的方面是代码本质上是线程安全的,并且至少在理论上是可平行的。当然,并行化代码而不使其慢慢不是微不足道的,因为每个线程或进程必须给予足够的工作来弥补并行化的开销。不过,这是一个miniKanren实现的领域,我希望会得到更多的关注和实验。

miniKanren使用出现的检查进行统一,并使用完全交错搜索而不是深度优先搜索。交织搜索比深度优先搜索使用更多的内存,但是在深度优先搜索将永远发散/循环的某些情况下可以找到答案。 miniKanren支持一些额外的逻辑运算符,例如conda,conduit和project。 conda和conduit可用于模拟Prolog的切割,并且项目可用于获取与逻辑变量关联的值。

conda,conduit和项目的存在以及轻松修改搜索策略的能力 – 允许程序员使用miniKanren作为嵌入式Prolog类语言。这对于Clojure的’core.logic’的用户尤其如此,其中包括许多类似Prolog的扩展。这种“务实的”使用miniKanren似乎占了miniKanren在工业中的大多数使用。希望向以Clojure或Python或JavaScript编写的现有应用程序添加基于知识的推理系统的程序员通常不会对在Prolog中重写整个应用程序感兴趣。在Clojure或Python中嵌入小型逻辑编程语言更有吸引力。嵌入式Prolog实现也可以用于此目的,大概。我怀疑miniKanren已经成为嵌入式逻辑语言的流行语言,因为它的核心实现非常简单,以及自“The Reasoned Schemer”发布以来的演讲,博客,教程和其他教育资料。

除了使用miniKanren作为一种务实的嵌入式逻辑编程语言,在精神上类似于Prolog,miniKanren被用于“关系”编程的研究。也就是说,在写程序中表现为数学关系而不是数学函数。例如,在Scheme中,append函数可以附加两个列表,返回一个新列表:函数调用(append'(a b c)'(d e))返回列表(a b c d e)。然而,我们可以将append看作三位置关系,而不是两个参数的函数。调用(appendo'(a b c)'(d e)Z)然后将逻辑变量Z与列表(a b c d e)相关联。当然,当我们将逻辑变量放在其他位置时,事情变得更有趣。调用(appendo X'(de)'(abcde))将X与(abc)相关联,而调用(appendo XY'(abcde))将X和Y与成对的列表相关联, )。例如X =(a b)和Y =(c d e)是一对这样的值。我们还可以写(appendo X Y Z),它将产生列表X,Y和Z的无限多个三元组,使得将X附加到Y产生Z.

append的这个关系版本可以很容易地在Prolog中表达,并且实际上在许多Prolog教程中显示。在实践中,更复杂的Prolog程序倾向于使用至少一些额外的逻辑特征,例如剪切,这抑制将所得到的程序视为关系的能力。相比之下,miniKanren被明确设计为支持这种风格的关系编程。更新版本的miniKanren支持符号约束求解(symbolo,numbero,absento,disequality约束,标称逻辑编程),以便更容易编写非平凡程序作为关系。在实践中,我从来不使用任何miniKanren的逻辑外功能,我把所有的miniKanren程序写成关系。最有趣的关系程序是Scheme的一个子集的关系解释器。这些解释器有许多有趣的能力,如生成一百万计划程序,评估到列表(我爱你),或简洁地生成quines(程序,评价自己)。

miniKanren做出了许多折衷,以实现这种关系型编程,这与Prolog所做出的权衡非常不同。随着时间的推移,miniKanren添加了更多的符号约束,真正成为一种符号导向的约束逻辑编程语言。在许多情况下,这些符号约束使得避免使用诸如conduit和项目的逻辑运算符变得实用。在其他情况下,这些符号约束是不够的。对符号约束的更好支持是miniKanren研究的一个活跃领域,以及如何编写更大和更复杂程序作为关系的更广泛的问题。

总之,miniKanren和Prolog都有有趣的功能,实现和使用,我认为值得学习两种语言的想法。还有其他非常有趣的逻辑编程语言,如Mercury,Curry和Gödel,每个都有自己的逻辑编程。

我将结束一些miniKanren资源:

主要的miniKanren网站:
http://minikanren.org/

我对关系编程和miniKanren的采访,包括与Prolog的比较:
http://www.infoq.com/interviews/byrd-relational-programming-minikanren

干杯,

– 将

http://stackoverflow.com/questions/28467011/what-are-the-main-technical-differences-between-prolog-and-minikanren-with-resp

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:在逻辑编程方面,Prolog和miniKanren之间的主要技术差异是什么?