我一直在使用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的结果?
答案 0 :(得分:6)
正如您链接到的core.logic wiki页面所述,core.logic的conde
是TRS的condi
。区别在于TRS的conde
按顺序尝试子句,而condi
则对结果流进行交错。因此,core.logic版本将生成TRS中显示的所有结果,但在它们之间它将返回miniKanren永远不会到达的其他结果。
较长答案中的一个相关模式是,如果从(())
开始采取每一秒结果,则结果seq的子序列看起来像每个结果前面加上()
的整个结果序号。这是由于交错 - 在这个子序列上,()
被选为结果的第一个元素,然后lolo
递归地产生其余的元素。