为什么core.logic的输出会重复相同的值?

zca*_*ate 5 clojure minikanren clojure-core.logic

我在core.logic中试过这个

(require [clojure.core.logic :as l])

(l/run* [q]
  (l/fresh [a b c]
    (l/membero a [1])
    (l/membero b [4 5])
    (l/membero c [1 2])
    (l/== q [a b])))

期待结果 [1 4] [1 5]

但它确实如此 [1 4] [1 4] [1 5] [1 5]

然后我开始玩它并发现:

(require [clojure.core.logic :as l])

(l/run* [q]
  (l/fresh [a b c]
    (l/membero a [1])
    (l/membero b [4 5])
    (l/membero c [1 1 1 1 1 1 1 1])
    (l/== q [a b])))
 ;; => ([1 4] [1 4] [1 4] [1 5] [1 4] [1 4] [1 5] [1 4] [1 5] [1 4] [1 5] [1 5] [1 5] [1 5])
Run Code Online (Sandbox Code Playgroud)

哪里有[1 5]穿插[1 4]

怎么了?这个重复的东西应该是一个特征还是一个bug?

Ank*_*kur 4

这是因为逻辑变量的使用c不是必需的,因为它没有与q. 如果你删除c那么你会得到想要的结果。基本上,您需要了解替换在 core.logic 中的工作原理,以了解为什么会因为c.

在较高层次上,该过程就像在树中搜索解决方案,在这种情况下,向量中的每个元素都会membero导致c搜索树中的一个节点,这会导致重复结果,因为对于由c可能值引入的每个节点都会导致正确的结果asc未在统一中使用(l/== q [a b])