我尝试在core.logic
中做这样的事情(defn count-different-elements-in-list [coll]
(count (set coll)))
这适用于整数很好
(should= 1 (count-different-elements-in-list '(1 1 1)))
(should= 2 (count-different-elements-in-list '(1 1 2)))
(should= 3 (count-different-elements-in-list '(1 3 2)))
但是现在我正在尝试使用core.logic来解决一些问题而且它会变得很混乱
(run* [a b c]
;;the variables get values between 1 and 3
(fd/in a b c (fd/interval 1 3))
;; in the list there should only be 2 different values
(== 2 (count-different-elements-in-list '(a b c))))
但问题出现了,b c不会作为值传递给函数。它们作为变量传递。有三个变量count-different-elements-in-list返回总是3,core.logic找不到解决方案(空列表)。
但我正在寻找这个结果。
([1 1 2] [1 2 1] [2 1 1]
[1 1 3] [1 3 1] [3 1 1]
[2 2 1] [2 1 2] [1 2 2]
[2 2 3] [2 3 2] [3 2 2]
[3 3 1] [3 1 3] [1 3 3]
[3 3 2] [3 2 3] [2 3 3])
答案 0 :(得分:3)
您需要将core.logic/project
逻辑变量转换为非关系目标,例如普通函数count-different-elements-in-list
。遗憾的是,您不能project
有限域逻辑变量,如a
,b
和c
,它们不受单个值的限制。 (见:this question)
在您拥有的示例中,您可以为生成的范围和fd/in
换出fd/interval
和membero
。这将删除无约束的有限域变量,保持整数的范围约束,并允许投影。
(def interval (vec (range 1 4)))
(run* [a b c]
(membero a interval)
(membero b interval)
(membero c interval)
(project [a b c]
(== 2 (count-different-elements-in-list (list a b c)))))