chickadee » mini-kanren » project

(project (x ...) goal0 goal ...)syntax

Extracts the value of zero or more logic variables into lexical variables of the same name, and executes the goals within the body of the project call.


;; The following code will fail because `+` is not relational.
(run 1 (q)
  (fresh (a b)
    (== a 1)
    (== b 2)
    (== q (+ a b))))

; => Error: (+) bad argument type - not a number: #(a)

;; However, if we use project to get the values of the logic variables,
;; we can use those directly.
(run 1 (q)
  (fresh (a b)
    (== a 1)
    (== b 1)
    (project (a b)
      (== q (+ a b)))))

; => (3)

project can be though of as an escape hatch to break out of miniKanren. It will give you the values of the variables, but it only works if the variables are grounded. In the above example, if the logic variable b is not ground, then the b inside the body of project will not be lexically bound to anything, and will still be a fresh logic variable.

In most cases it is advised to avoid project when you can. It can be a powerful tool for debugging the values of logic variables when writing miniKanren code; however, excessive use will lead to extremely non-relational code that will be hard to work with in miniKanren.