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.