microkanren.scm 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. ;; Jason Hemann and Dan Friedman
  2. ;; microKanren, final implementation from paper
  3. (define (var c) (vector c))
  4. (define (var? x) (vector? x))
  5. (define (var=? x1 x2) (= (vector-ref x1 0) (vector-ref x2 0)))
  6. (define (walk u s)
  7. (let ((pr (and (var? u) (assp (lambda (v) (var=? u v)) s))))
  8. (if pr (walk (cdr pr) s) u)))
  9. (define (ext-s x v s) `((,x . ,v) . ,s))
  10. (define (== u v)
  11. (lambda (s/c)
  12. (let ((s (unify u v (car s/c))))
  13. (if s (unit `(,s . ,(cdr s/c))) mzero))))
  14. (define (unit s/c) (cons s/c mzero))
  15. (define mzero '())
  16. (define (unify u v s)
  17. (let ((u (walk u s)) (v (walk v s)))
  18. (cond
  19. ((and (var? u) (var? v) (var=? u v)) s)
  20. ((var? u) (ext-s u v s))
  21. ((var? v) (ext-s v u s))
  22. ((and (pair? u) (pair? v))
  23. (let ((s (unify (car u) (car v) s)))
  24. (and s (unify (cdr u) (cdr v) s))))
  25. (else (and (eqv? u v) s)))))
  26. (define (call/fresh f)
  27. (lambda (s/c)
  28. (let ((c (cdr s/c)))
  29. ((f (var c)) `(,(car s/c) . ,(+ c 1))))))
  30. (define (disj g1 g2) (lambda (s/c) (mplus (g1 s/c) (g2 s/c))))
  31. (define (conj g1 g2) (lambda (s/c) (bind (g1 s/c) g2)))
  32. (define (mplus $1 $2)
  33. (cond
  34. ((null? $1) $2)
  35. ((procedure? $1) (lambda () (mplus $2 ($1))))
  36. (else (cons (car $1) (mplus (cdr $1) $2)))))
  37. (define (bind $ g)
  38. (cond
  39. ((null? $) mzero)
  40. ((procedure? $) (lambda () (bind ($) g)))
  41. (else (mplus (g (car $)) (bind (cdr $) g)))))
  42. (define empty-state '(() . 0))
  43. (define (pull $)
  44. (if (procedure? $) (pull ($)) $))
  45. (define (take-all $)
  46. (let (($ (pull $)))
  47. (if (null? $) '() (cons (car $) (take-all (cdr $))))))
  48. (define (take n $)
  49. (if (zero? n) '()
  50. (let (($ (pull $)))
  51. (if (null? $) '() (cons (car $) (take (- n 1) (cdr $)))))))
  52. (define (reify-1st s/c)
  53. (let ((v (walk* (var 0) (car s/c))))
  54. (walk* v (reify-s v '()))))
  55. (define (walk* v s)
  56. (let ((v (walk v s)))
  57. (cond
  58. ((var? v) v)
  59. ((pair? v) (cons (walk* (car v) s)
  60. (walk* (cdr v) s)))
  61. (else v))))
  62. (define (reify-s v s)
  63. (let ((v (walk v s)))
  64. (cond
  65. ((var? v)
  66. (let ((n (reify-name (length s))))
  67. (cons `(,v . ,n) s)))
  68. ((pair? v) (reify-s (cdr v) (reify-s (car v) s)))
  69. (else s))))
  70. (define (reify-name n)
  71. (string->symbol
  72. (string-append "_" "." (number->string n))))