I wonder if anybody else has ever needed, and thus coded, a predicate like membero
but for hash-maps. I can, of course, use (seq)
on a hash-map, but if it's already an LVar, it won't work.
If we call it keyvalo
, it'd work like:
(run* [q]
(fresh [m kv]
(== m {:a 2 :b 3})
(keyvalo kv m)
(== q kv)))
=> ([:a 2] [:b 3])
It can be defined as
(defn keyvalo [kv map]
(fresh [s]
(seqo s map)
(membero kv s)))
But I having a hard time trying to code a seqo
, which would succeed for (seqo [[:foo 3]] {:foo 3})
.
Thanks!
Easiest would be to
project
This is non-relational, which means that while
will give you a list for which
[:foo 1]
is a member (don't try this withrun*
),is going to throw an exception instead. But, this probably will still suffice for your purposes.
For example, we can invert a map now
But,
Note that a problem with
seqo
here is that the keys in the map have no order, whereas a sequence does. Therefore, for(seqo [[:a 1] [:b 2] [:c 3]] {:a 1 :b 2 :c 3})
to succeed, you would have test for any permutation of(seq {:a 1 :b 2 :c 3})
For the implementation I am using(seq {:a 1 :b 2 :c 3}) ;=> ([:a 1] [:c 3] [:b 2])
, for example. You could work around this with permutations, but that's likely not what you want for larger maps.