为什么我的clojure.core.logic非成员函数返回两个值?

时间:2013-05-04 03:37:31

标签: clojure clojure-core.logic

我正在尝试在membero中实现clojure.core.logic的反面,但它返回两个值而不是一个。否则,它可以正常工作(当值在列表中时返回任何内容,而在不在列表中时返回任何内容)。

(defne nonmembero
  "A relation where l is a collection, such that l does not contain x"
  [x l]
  ([_ ()])
  ([_ [head]]
     (!= x head))
  ([_ [head . tail]]
     (!= x head)
     (nonmembero x tail)))

示例运行:

user> (run* [x] (nonmembero 1 [2 3 4 5]))
(_0 _0)
user> (run* [x] (nonmembero 1 [2 3 1 4 5]))
()

2 个答案:

答案 0 :(得分:2)

您不需要第二种模式,即[_ [head]。这导致core.logic引擎的搜索空间中的新分支,从而导致2输出。最后一个模式,即[head . tail]足以处理列表中只有一个元素的情况。现在您的解决方案变为:

(defne nonmembero
  "A relation where l is a collection, such that l does not contain x"
  [x l]
  ([_ ()])
  ([_ [head . tail]]
     (!= x head)
     (nonmembero x tail)))

答案 1 :(得分:0)

上面的代码有问题。它找到了以下

的解决方案
(run* [q](== q 1)(nonmembero q [1 2 3]))  =>  (1)

以下给出了预期结果

(run* [q](== q 1)(nonmembero2 q [1 2 3]))  => ()

其中nonmembero2是

(defn nonmembero2
  [x l]
  (fresh [h t]
    (conde
      [(== l ())]
      [(conso h t l)
       (!= x h)
       (nonmembero2 x t)])))