In core.logic
of function, I see the below definition for clojure.core.logic/everyg
.
A pseudo-relation that takes a coll and ensures that the goal g succeeds on every element of the collection.
What exactly a pseudo-relation
means in this context?
Here's a good explanation of relational (and non-relational): What does non-relational mean in practice for core.logic? Another bit of background is everyg
was renamed from everyo
in this commit because the o
suffix should only used for relations.
One property of relational goals is that they can contribute answers when all/some/none of their inputs are non-ground. conso
is relational and so we can ask what are the values that satisfy the relation where l
is a
prepended to d
, where all variables are fresh:
(run* [a d l] (conso a d l))
=> ([_0 _1 (_0 . _1)])
This tells us a
(_0
) is fresh, d
(_1
) is fresh, and l
((_0 . _1)
) is a
prepended to d
. While none of these values are ground, we can still see the relationship between them in the answer.
The same is not true for everyg
:
(run* [g coll] (everyg g coll)) ;; Don't know how to create ISeq from: clojure.core.logic.LVar
everyg
can't tell us what the relationship between g
and coll
is, nor can it tell us what g
or coll
might be if we supply either ground value:
(run* [coll] (everyg succeed coll)) ;; throws
(let [coll (repeatedly 3 lvar)] ;; throws too
(run* [g]
(everyg g coll)))
While everyg
itself isn't a relation, you can pass it a goal g
and coll
of fresh and/or ground variables:
(let [coll (cons 1 (repeatedly 2 lvar))] ;; 1 prepended to two fresh logic vars
(run* [q]
(== q coll)
(everyg #(fd/in % (fd/domain 0 1)) coll)))
=> ((1 0 0) (1 1 0) (1 0 1) (1 1 1))
This example will give the same answers regardless of the position of the everyg
goal, which is another property of relational goals.
And we can pass the conso
relation to everyg
with all fresh logic variables and still see the relationship in the answer, exactly as it was above with the conso
example:
(run* [a d q]
(everyg #(conso a d %) [q]))
=> ([_0 _1 (_0 . _1)])
So with some caveats, everyg
can be used relationally which is why I think it's considered pseudo-relational rather than non-relational.