我一直在使用Clojure.logic来研究The Reasoned Schemer (TRS)并注意differences documented here。我到达了第3章的第24帧,TRS报告

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

应该产生
'(()
  (())
  (() ())
  (() () ())
  (() () () ())

现在,我将`lolo实现为
(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)))

这基本上意味着我的大佬正在生产泄漏出新变量的解决方案。如果我继续前进,尝试观察模式,我会
'(()
  (())
  ((_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递归生成其余的元素。

关于合理计划者的Clojure.logic差异,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17548484/

10-11 19:21