2013-09-26 45 views
2

我尝试做这样的事情在core.logicClojure的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)))) 

但是问题出在这里,abc没有得到pas sed作为函数的值。它们作为变量传递。有三个变量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]) 

回答

3

您需要core.logic/project逻辑瓦尔成非关系的目标,像正常功能count-different-elements-in-list。不幸的是,您不能限制为单个值的有限域逻辑变量,如a,bc。 (见:this question

在你有例如,可以换出fd/infd/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))))) 
+0

没有得到它,但通过在结果中应用count-different-elements-in-list函数解决了问题。学习clojure需要时间。 – daniel

+0

约束中使用的正常函数,如'count-different-elements-in-list',在core.logic中被视为非关系目标。我已经达到了我的知识水平,所以我不能真正解释它。 – Jared314

+0

举一个例子给它另一个镜头。它有助于为您解决问题吗? – Jared314