你能用Scala进行逻辑编程吗?

时间:2010-04-17 19:32:55

标签: scala programming-languages prolog language-features logic-programming

我在某处读过像Scala中匹配/案例功能支持的模式匹配实际上是从Prolog这样的逻辑语言中借用的。

您是否可以使用Scala优雅地解决连接图问题等问题? 例如https://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_15.html

11 个答案:

答案 0 :(得分:12)

不,你不能这样做,除非你真的创建了一个逻辑引擎,这种方式会破坏整个目的。

此外,由于许多原因,模式匹配本身完全不适用于此。例如,考虑基本查询本身:path(1, 5, P)。在Scala的模式匹配中,1,5和P是输出。您无法提供可用于生成输出的输入。

使用Prolog,这就像假设1和5是固定的,P可能具有哪些可能值?现在就是模式匹配的工作方式。

编辑: 使用Scala 2.10,模式匹配现在被编译为像for-comprehensions一样的中间操作,然后进一步优化默认转换。但是,可以定义自己的类来处理模式匹配,我已经看到它用于实现prolog登录 - 虽然我找不到链接,抱歉。

答案 1 :(得分:6)

请参阅http://kanren.sourceforge.net/,了解功能和逻辑编程如何相距甚远的详细信息。流结构是理解两种范式如何结合在一起的关键。通过将标准函数“提升”为流/逻辑格式,它们可以表现出与Prolog非常相似的解决问题的行为。

您还应该查看解析器组合器。有了正确的组合器,就可以实现高效的Prolog类解决方案。

答案 2 :(得分:6)

我知道我迟到但是正在寻找:kanren我发现了这个[死链接]还有这个:http://code.google.com/p/scalalogic/

我只是在研究这个话题,对它只有非常暗淡的理解但是这些链接无论如何都可能有一些兴趣。

答案 3 :(得分:6)

Haskell和函数式编程语言一直是Scala灵感的直接来源。从这些语言继承的应用程序之一是域特定语言(DSL)的开发。在Haskell中有很多用于逻辑编程(Prolog)的DSL。将这样的DSL库移植到Scala应该是非常可能的,如果尚未发生的话。

答案 4 :(得分:4)

Scala不是一种逻辑编程语言,但您确实可以在Scala中为逻辑编程定义DSL。请注意,Scala从函数式编程中借鉴了许多概念 - 它可以而且应该以函数式使用。功能和逻辑编程都是声明性的,但有很大不同。您可以阅读更多here

答案 5 :(得分:4)

Styla是一个用Scala编写的相当完整的Prolog解释器, 源自Kernel Prolog(参见Fluents:Prolog for Reolog for 中外部物体的均匀反射与互操作 CL'2000)。

真正开源的(Apache许可证)代码托管在:

http://code.google.com/p/styla/

它的设计考虑了简单性和可扩展性 - 希望 对于尝试新的Prolog扩展的人来说,它会很有用 或替代逻辑编程语言。

Styla使用Java中没有的一些Scala好东西:

  • 高阶函数,地图,折叠,案例类等。
  • 组合分析器 - “穷人的DCG”
  • Scala之间优雅的隐式转换 列表,数组,序列等。
  • Scala的任意长度整数和小数(带有 自然语法,与Java相反)
  • Scala的“”“......”“”字符串 - 用于正则表达式和嵌入 直接在Scala类中的Prolog代码
  • Scala中提供的一些IO抽象 将文件操作视为迭代器 - 原始的Fluents的自然匹配 源自Styla的基于Java的Kernel Prolog

(文字摘自:http://groups.google.com/group/comp.lang.prolog/browse_thread/thread/4cd835d2c82fce02/505688d4b0be5528

答案 6 :(得分:4)

对你的问题的传统答案将概述逻辑变量不能直接用假定一切都是值的语言建模。

然而,有一种相对较新的方法可将逻辑变量映射到功能结构。在具体案例中,将close-Prolog逻辑语言Curry 转换为Haskell。在这种方法中,非常异常的是逻辑变量是用惰性建模的。有关更多信息,请参阅KiCS2: A new compiler from Curry to Haskell。也许lazy val可以用于此目的。

答案 7 :(得分:3)

刚刚在Scala中找到了一个很好的Prolog实现。不幸的是我没有时间去尝试,所以我的印象只是基于查看可在此处找到的源代码:

https://github.com/sonoisa/Prolog-in-Scala/blob/master/PrologInScalaSample.scala

以上指出了几个测试程序。 Prolog解释器是用Scala编写的,Prolog子句可以嵌入Scala编写的Scala对象中。我不完全理解它背后的魔力,下面是一个如何编写tak函数的示例:

tak('X, 'Y, 'Z, 'A) :- (
 'X =< 'Y, CUT, 'Z === 'A)
tak('X, 'Y, 'Z, 'A) :- (
 'X1 is 'X - 1,
 'Y1 is 'Y - 1,
 'Z1 is 'Z - 1,
 tak('X1, 'Y, 'Z, 'A1),
 tak('Y1, 'Z, 'X, 'A2),
 tak('Z1, 'X, 'Y, 'A3),
 tak('A1, 'A2, 'A3, 'A)
)

我猜它是通过延续进行回溯并且有自己的回溯 实施可变环境和统一。

如果您查看代码,例如unifyTerm,您会看到它 大量使用模式匹配,这使得Scala变得特别 实现逻辑引擎的立场。

最好的问候

答案 8 :(得分:1)

模式匹配对于逻辑编程并不直接有用,因为doesn't unify variables

答案 9 :(得分:1)

您还可以查看scampi(Scala中的约束编程解算器):https://bitbucket.org/pschaus/scampi/wiki/Home Jacop CP Solver还有一个scala API。

答案 10 :(得分:0)

我发现此http://yieldprolog.sourceforge.net/是类似Prolog的系统实现方法的来源,而不是未记录的源代码或加密库。

但是我几天前才对Scala感兴趣,因此在users.scala上问了同样的问题: https://users.scala-lang.org/t/yield-prolog-unification-and-coroutines-in-scala/4433

应该可以用语言实现统一的回溯,而生成器函数可以在函数执行过程中返回并保留计算。通过使用协程或绿色线程,可以在回溯链中产生部分解决方案,从而达到相同的效果。