Am Mittwoch, 14. August 2013 13:23:32 UTC+2 schrieb [email protected]:
>
>
> Thanks to Will's macro tutorial[1], I got an answer to my own question
> quickly than I expected:
>
> ╭────
> │ (define-syntax def-fact
> │   (syntax-rules ()
> │     ;; binary relations
> │     [(_ name t1 t2 (v1 v2) ...)
> │      (define (name t1 t2)
> │        (conde  [(== t1 v1) (== t2 v2)] ...))]
> │     ;; unary facts
> │     [(_ name t v ...)
> │      (define (name t)
> │        (conde  [(== t v)]
> │                ...))]))
> ╰────
>
> Which can be used for unary relations:
> ╭────
> │ (def-fact mano
> │   m
> │   "Abraham"
> │   "Ismael"
> │   "Isaac"
> │   "Jacob"
> │   "Benjamin")
> ╰────
>
> And for binary ones:
> ╭────
> │ (def-fact fathero
> │    f         c
> │   ("Abraham" "Ismael")
> │   ("Abraham" "Isaac")
> │   ("Isaac"   "Jacob")
> │   ("Jacob"   "Benjamin"))
> ╰────
>
> An I can run queries like:
> ╭────
> │ (run 2 (q)
> │      (mano q))
> ╰────
>
>
> I still need to see how to have it work for n-ary relations, but I am
> happy with this right now, since it is my first macro ever!
>

It is an old thread but the question seems to be still unanswered.

If you accept a bit more general notation with more parenthesis for the 
unary facts, you can use the following macro.

(define-syntax define-facts
  (syntax-rules ()
    ((_ (name a0 a1 ...) ((v00 v01 ...) (v10 v11 ...) ...))
     (define (name a0 a1 ...)
       (conde
         ((== a0 v00) (== a1 v01) ...)
         ((== a0 v10) (== a1 v11) ...)
         ...))))) 

But be careful. It works in Guile, MIT and Chez but fails in some other 
Schemes.

(define-facts (mano m)
  (("Abraham")
   ("Ismael")
   ("Isaac")
   ("Jacob")
   ("Benjamin")))

(run 2 (q)
  (mano q))  ;; => ("Abraham" "Ismael")

(define-facts (fathero f c)
  (("Abraham" "Ismael")
   ("Abraham" "Isaac")
   ("Isaac"   "Jacob")
   ("Jacob"   "Benjamin")))

(run* (q)
  (fathero "Abraham" q))  ;; => ("Ismael" "Isaac")

(define (grand-fathero gf gc)
  (fresh (f)
    (fathero gf f)
    (fathero f gc)))

(run* (q)
  (grand-fathero "Isaac" q))  ;; => ("Benjamin")

-- 
You received this message because you are subscribed to the Google Groups 
"minikanren" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/minikanren.
For more options, visit https://groups.google.com/d/optout.

Reply via email to