3

私は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は値として関数に渡されません。それらは変数として渡されます。3 つの変数がある場合、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])
4

1 に答える 1

4

core.logic/project通常の function のように、変数を非リレーショナル ゴールに論理化する必要がありますcount-different-elements-in-list。残念ながら、単一の値に制約されていない 、、などprojectのドメイン ロジック変数を有限化することはできません。(参照:この質問)abc

あなたが持っている例では、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)))))
于 2013-09-26T04:07:30.047 に答える