我在某处读到,Scala 中的匹配/大小写功能所支持的模式匹配实际上是从 Prolog 等逻辑语言中借来的。
你能用 Scala 优雅地解决像 Connected Graph 问题这样的问题吗?例如https://web.archive.org/web/20100214144956/https://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_15.html
我在某处读到,Scala 中的匹配/大小写功能所支持的模式匹配实际上是从 Prolog 等逻辑语言中借来的。
你能用 Scala 优雅地解决像 Connected Graph 问题这样的问题吗?例如https://web.archive.org/web/20100214144956/https://www.csupomona.edu/~jrfisher/www/prolog_tutorial/2_15.html
不,你不能这样做,除非你真的创建了一个逻辑引擎,这违背了整个目的。
此外,由于许多原因,模式匹配本身完全不适合这一点。例如,考虑基本查询本身:path(1, 5, P)
. 在 Scala 的模式匹配中,1、5 和 P 是输出。您不能提供可用于产生输出的输入。
使用 Prolog,这就像假设 1 和 5 是固定的,那么 P 可以取什么值?这就是模式匹配的工作原理。
编辑: 使用 Scala 2.10,模式匹配现在被编译为像 for-comprehensions 这样的中间操作,然后进一步优化默认翻译。但是,可以定义自己的类来处理模式匹配,我已经看到它用于实现 prolog 登录——虽然我找不到链接,抱歉。
Haskell 和函数式编程语言一直是 Scala 的直接灵感来源。从这些语言继承的应用之一是领域特定语言 (DSL) 的开发。Haskell 中有很多用于逻辑编程(Prolog)的 DSL。将这样的 DSL 库移植到 Scala 应该是完全可能的,如果这还没有发生的话。
请参阅http://kanren.sourceforge.net/,了解有关函数式编程和逻辑编程如何相差无几的详细信息。流结构是理解这两种范式如何结合的关键。通过将标准函数“提升”为流/逻辑格式,它们可以表现出看起来很像 Prolog 的问题解决行为。
您还应该查看解析器组合器。有了正确的组合器,就可以实现高效的类似 Prolog 的求解能力。
我知道我迟到了,但搜索回复:kanren 我发现了这个 [死链接] 还有这个:http ://code.google.com/p/scalalogic/
我只是在研究这个话题,对它的理解很模糊,但无论如何链接可能会引起一些兴趣。
对您的问题的传统答案将概述逻辑变量不能直接用假定一切都是值的语言建模。
然而,有一种相对较新的方法可以将逻辑变量映射到功能结构。在具体情况下,接近 Prolog 的逻辑语言 Curry curry被翻译为 Haskell。这种方法非常不寻常的是逻辑变量是用惰性建模的。有关更多信息,请参阅KiCS2:从 Curry 到 Haskell 的新编译器。也许lazy val
可以用于此目的。
Styla 是一个相当完整的用 Scala 编写的 Prolog 解释器,源自 Kernel Prolog(请参阅 Fluents: A Refactoring of Prolog for Uniform Reflection and Interoperation with External Objects in CL'2000)。
真正开源(Apache 许可)的代码托管在:
http://code.google.com/p/styla/
它的设计考虑到了简单性和可扩展性——希望它对尝试新的 Prolog 扩展或替代逻辑编程语言的人有用。
Styla 使用了一些 Java 中没有的 Scala 好东西:
(文字取自:http ://groups.google.com/group/comp.lang.prolog/browse_thread/thread/4cd835d2c82fce02/505688d4b0be5528 )
Scala 不是一种逻辑编程语言,但您确实可以为 Scala 中的逻辑编程定义 DSL。请注意,Scala 借鉴了函数式编程的许多概念——它可以而且应该以函数式风格使用。函数式和逻辑式编程都是声明式的,但差别很大。你可以在这里阅读更多。
刚刚在 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 置于实现逻辑引擎的特殊位置。
最好的祝福
模式匹配本身对于逻辑编程并不直接有用,因为它不统一变量。
您还可以查看scampi(Scala 中的约束编程求解器):https: //bitbucket.org/pschaus/scampi/wiki/Home Jacop CP Solver 也有一个 scala API。
我发现这个http://yieldprolog.sourceforge.net/作为类似 Prolog 的系统实现方法的来源,而不是未记录的源代码或神秘库。
但我几天前才对 Scala 感兴趣,所以在 users.scala 上问了同样的问题: https ://users.scala-lang.org/t/yield-prolog-unification-and-coroutines-in-scala /4433
实现统一回溯的语言应该是可用的生成器函数,它可以在函数执行过程中返回并保留计算。可以通过使用协程或绿色线程来实现相同的效果,它们在回溯链接中产生部分解决方案。