Reputation: 16399
I just read the primer for core.logic. It makes sense so far, but I'm not sure where to go to learn more.
Let's say I wanted to write my own constraint, sort of like the membero
shown in the primer. This one is called vectoro
and constrains things to be a vector.
(defn vectoro [s] ???)
(run* [q]
(conde
[(== q [1 2])]
[(== q :a)])
(vectoro q))
Now I want that to return [1 2]
. How do you write vectoro
? Is this documented anywhere?
Upvotes: 2
Views: 329
Reputation: 16194
There's a core.logic pred
macro that makes this easy:
(run* [q]
(== q [1 2])
(pred q vector?))
=> ([1 2])
(run* [q]
(== q '(1 2))
(pred q vector?))
=> ()
Here's how you might define a vectoro
function/contraint (but realize this is essentially the exact same thing pred
is doing):
(defn vectoro [a]
(project [a]
(== true (vector? a))))
project
is used to operate on the actual/concrete value of the logic variable (LVar
). We can then use the plain old predicate vector?
and require the result be true. This also works with your example program:
(run* [q]
(conde
[(== q [1 2])]
[(== q :a)])
(vectoro q))
=> ([1 2])
(run* [q]
(conde
[(== q '(1 2))]
[(== q :a)])
(vectoro q))
=> ()
Upvotes: 4
Reputation: 9426
To continue learning, I suggest looking for projects that use core.logic and seeing if their source code teaches you anything.
As for your specific question about vectoro
, the "project" function (as in "projection") will probably accomplish what you want, something along the lines of
(defn vectoro [s v]
(core.logic/project [v]
(core.logic/== s (vector? v)))
Upvotes: 1