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?
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))
=> ()