Reb*_*bin 4 logic clojure logic-programming minikanren clojure-core.logic
我一直在使用Clojure.logic 完成The Reasoned Schemer(TRS),并注意这里记录的差异.我到达了第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的结果?
正如你链接到的core.logic wiki页面所提到的,core.logic conde是TRS的condi.不同之处在于TRS conde按顺序尝试子句,同时condi对结果流进行交错.因此,core.logic版本将生成TRS中显示的所有结果,但在它们之间它将返回miniKanren永远不会到达的其他结果.
较长答案中的一个相关模式是,如果从每个第二个结果开始(()),则结果seq的子序列看起来像整个结果seq,并()附加在每个结果的前面.这是由于交错 - 在这个子序列上,()被选为结果的第一个元素,然后lolo递归地产生其余的元素.
| 归档时间: | 
 | 
| 查看次数: | 405 次 | 
| 最近记录: |