我正在尝试在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]))
()
答案 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)])))