;; lib/minikanren/tests/defrel.sx — Prolog-style relation definition macro.

(defrel
  (my-membero x l)
  ((fresh (d) (conso x d l)))
  ((fresh (a d) (conso a d l) (my-membero x d))))

(mk-test
  "defrel-defines-membero"
  (run* q (my-membero q (list 1 2 3)))
  (list 1 2 3))

(defrel
  (my-listo l)
  ((nullo l))
  ((fresh (a d) (conso a d l) (my-listo d))))

(mk-test
  "defrel-listo-bounded"
  (run 3 q (my-listo q))
  (list
    (list)
    (list (make-symbol "_.0"))
    (list (make-symbol "_.0") (make-symbol "_.1"))))

;; Multi-arg relation with arithmetic.

(defrel
  (my-pluso a b c)
  ((== a :z) (== b c))
  ((fresh (a-1 c-1) (== a (list :s a-1)) (== c (list :s c-1)) (my-pluso a-1 b c-1))))

(mk-test
  "defrel-pluso-2-3"
  (run*
    q
    (my-pluso (list :s (list :s :z)) (list :s (list :s (list :s :z))) q))
  (list (list :s (list :s (list :s (list :s (list :s :z)))))))

(mk-tests-run!)
