Clojure.logic 与 The Reasoned Schemer 的区别

Posted

技术标签:

【中文标题】Clojure.logic 与 The Reasoned Schemer 的区别【英文标题】:Clojure.logic difference with The Reasoned Schemer 【发布时间】:2013-07-07 01:47:56 【问题描述】:

我一直在使用 Clojure.logic 处理 The Reasoned Schemer (TRS) 并关注 differences documented here。我到达了第 3 章的第 24 帧,TRS 报告了这一点

(run 5 [x]
  (lolo '((a b) (c d) . x)))

应该产生

'(()
  (())
  (() ())
  (() () ())
  (() () () ())

现在,我实现了 `lolo as

(defn lolo
  "Succeeds if l is a list-of-lists."
  [l]
  (conde
   ((emptyo l) s#)
   ((fresh [a]
           (firsto l a)
           (listo a)) (fresh [d]
                             (resto l d)
                             (lolo d)))
   (s# u#)))

这会产生以下奇怪的结果:

'(()
  (())
  ((_0))
  (() ())
  ((_0 _1)))

这基本上意味着我的 lolo 正在生成泄漏出新变量的解决方案。如果我继续前进,试图看到一个模式,我会得到

'(()
  (())
  ((_0))
  (() ())
  ((_0 _1))
  (() (_0)
  ((_0) ())
  (() () ())
  ((_0 _1 _2)))

但我在迷雾中看不清楚,希望能对此有所了解。这是我lolo的一个错误吗?它是 clojure.logic 中的错误吗? TRS 中的求解器和 clojure.logic 中的求解器之间存在合理的区别吗?我如何解释或使用结果?如何在心理上预测 clojure.logic 的结果?

【问题讨论】:

【参考方案1】:

正如您链接到的 core.logic wiki 页面上所述,core.logic 的 conde 是 TRS 的 condi。不同之处在于 TRS 的 conde 按顺序尝试子句,而 condi 交错结果流。所以 core.logic 版本会产生 TRS 中显示的所有结果,但在它们之间,它会返回 miniKanren 永远无法处理的其他结果。

您较长的答案中的一个相关模式是,如果您从(()) 开始每隔一个结果取一个结果,那么结果序列的子序列看起来就像在每个单独结果前面加上() 的整个结果序列。这是由于交错 - 在这个子序列上,() 被选为结果的第一个元素,然后 lolo 递归生成其余部分。

【讨论】:

以上是关于Clojure.logic 与 The Reasoned Schemer 的区别的主要内容,如果未能解决你的问题,请参考以下文章

ES各种错误解决

大教堂与集市(The Cathedral and the Bazaar)读书笔记

StatusCode: 415, ReasonPhrase: '不支持的媒体类型'

如何访问JsonPath数组结果的值(空手道断言)

调整 Informix 查询(Cisco 呼叫数据代理状态)

坚强与柔情——The Fiddler