最も簡単なのはproject
(run* [q]
(fresh [m]
(== m {:foo 1 :bar 2}) ; m is an LVar
(project [m] ; but when bound values are projected
(membero q (seq m))))) ; seq can be used
;=> ([:foo 1] [:bar 2])
(defn keyvalo [kv m] (project [m] (membero kv (seq m))))
これは非リレーショナルです。
(run 1 [q] (membero [:foo 1] q))
;=> (([:foo 1] . _0))
メンバーのリストが表示されます[:foo 1]
( でこれを試さないでくださいrun*
)。
(run 1 [q] (keyvalo [:foo 1] q))
;=> IllegalArgumentException Don't know how to create ISeq from: clojure.core.logic.LVar
代わりに例外をスローします。しかし、これはおそらくあなたの目的には十分でしょう。
たとえば、マップを反転できます
(run* [q] (== (partial-map {:foo q}) {:foo 1 :bar 2}))
;=> (1)
(run* [q] (== (partial-map {q 1}) {:foo 1 :bar 2}))
;=> ()
しかし、
(run* [q] (keyvalo [:foo q] {:foo 1 :bar 2}))
;=> (1)
(run* [q] (keyvalo [q 1] {:foo 1 :bar 2}))
;=> (:foo)
ここでの問題seqo
は、マップ内のキーには順序がないのに対し、シーケンスには順序があることに注意してください。したがって、 forを成功させるには、 For the implementation I am using の(seqo [[:a 1] [:b 2] [:c 3]] {:a 1 :b 2 :c 3})
順列をテストする必要があります。順列を使用してこれを回避できますが、それは大規模なマップでは望ましくない可能性があります。(seq {:a 1 :b 2 :c 3})
(seq {:a 1 :b 2 :c 3}) ;=> ([:a 1] [:c 3] [:b 2])