Rob N
Rob N

Reputation: 16399

How to write your own simple constraint function in core.logic?

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

Answers (2)

Taylor Wood
Taylor Wood

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

exupero
exupero

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

Related Questions