Reputation: 6958
...and how can I avoid it?
(run* [q]
(featurec q {:a 1})
(featurec q {:a 2})))
returns
((_0
:-
(clojure.core.logic/featurec _0 {:a 2})
(clojure.core.logic/featurec _0 {:a 1})))
which I understand to mean that the _0
map must contain at least the :a 1
key-value pair AND the :a 2
key-value pair. This seems contradictory as :a
can't map to both 1
and 2
unless we used MultiMaps. I can't read it as :a 1
OR :a 2
because the constraints I specify are a conjunction. I would have imagined that the result should be ()
because the constraints are contradictory; there is no value for q
that can satisfy these constraints.
I must be reading the result incorrectly.
Upvotes: 2
Views: 138
Reputation: 3659
Yes, it's contradictory. But it's what it is: There's no map that can unify with {:a 1}
and {:a 2}
at the same time.
run*
, all
, fresh
all introduce a conjunction (AND) among its constraints. If you want a disjunction (OR) you could introduce a conde
.
Perhaps your question is: Why core.logic isn't being able to "see" the contradiction and return an empty result set? I don't know exactly. But maybe it has to do with the fact that even if we remove one of the constraints, we don't get a "grounded" result:
(run* [q]
(featurec q {:a 1}))
;=> ((_0 :- (clojure.core.logic/featurec _0 {:a 1})))
It reads as: anything, as far as it's a map which includes the [:a 1]
entry. And I think that's the correct result.
Upvotes: 1