2

我正在尝试实现memberoin的反面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]))
()
4

2 回答 2

2

您不需要第二种模式,即[_ [head]. 这导致 core.logic 引擎的搜索空间出现新分支,因此导致 2 输出。最后一个模式 ie[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)))
于 2013-05-04T07:02:07.257 回答
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)])))
于 2016-12-14T09:01:08.813 回答