t-microkanren.scm 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. ;; import logic/microkanren.scm
  2. (define a-and-b
  3. (conj
  4. (call/fresh (lambda (a) (== a 7)))
  5. (call/fresh
  6. (lambda (b)
  7. (disj
  8. (== b 5)
  9. (== b 6))))))
  10. (define fives
  11. (lambda (x)
  12. (disj
  13. (== x 5)
  14. (lambda (a/c)
  15. (lambda ()
  16. ((fives x) a/c))))))
  17. (define appendo
  18. (lambda (l s out)
  19. (disj
  20. (conj (== '() l) (== s out))
  21. (call/fresh
  22. (lambda (a)
  23. (call/fresh
  24. (lambda (d)
  25. (conj
  26. (== `(,a . ,d) l)
  27. (call/fresh
  28. (lambda (res)
  29. (conj
  30. (== `(,a . ,res) out)
  31. (lambda (s/c)
  32. (lambda ()
  33. ((appendo d s res) s/c))))))))))))))
  34. (define appendo2
  35. (lambda (l s out)
  36. (disj
  37. (conj (== '() l) (== s out))
  38. (call/fresh
  39. (lambda (a)
  40. (call/fresh
  41. (lambda (d)
  42. (conj
  43. (== `(,a . ,d) l)
  44. (call/fresh
  45. (lambda (res)
  46. (conj
  47. (lambda (s/c)
  48. (lambda ()
  49. ((appendo2 d s res) s/c)))
  50. (== `(,a . ,res) out))))))))))))
  51. (define call-appendo
  52. (call/fresh
  53. (lambda (q)
  54. (call/fresh
  55. (lambda (l)
  56. (call/fresh
  57. (lambda (s)
  58. (call/fresh
  59. (lambda (out)
  60. (conj
  61. (appendo l s out)
  62. (== `(,l ,s ,out) q)))))))))))
  63. (define call-appendo2
  64. (call/fresh
  65. (lambda (q)
  66. (call/fresh
  67. (lambda (l)
  68. (call/fresh
  69. (lambda (s)
  70. (call/fresh
  71. (lambda (out)
  72. (conj
  73. (appendo2 l s out)
  74. (== `(,l ,s ,out) q)))))))))))
  75. (define call-appendo3
  76. (call/fresh
  77. (lambda (q)
  78. (call/fresh
  79. (lambda (l)
  80. (call/fresh
  81. (lambda (s)
  82. (call/fresh
  83. (lambda (out)
  84. (conj
  85. (== `(,l ,s ,out) q)
  86. (appendo l s out)))))))))))
  87. (define ground-appendo (appendo '(a) '(b) '(a b)))
  88. (define ground-appendo2 (appendo2 '(a) '(b) '(a b)))
  89. (define relo
  90. (lambda (x)
  91. (call/fresh
  92. (lambda (x1)
  93. (call/fresh
  94. (lambda (x2)
  95. (conj
  96. (== x `(,x1 . ,x2))
  97. (disj
  98. (== x1 x2)
  99. (lambda (s/c)
  100. (lambda () ((relo x) s/c)))))))))))
  101. (define many-non-ans
  102. (call/fresh
  103. (lambda (x)
  104. (disj
  105. (relo `(5 . 6))
  106. (== x 3)))))
  107. (define (test title val)
  108. (display title)
  109. (newline)
  110. (display val)
  111. (newline))
  112. (test "second-set t1"
  113. (let (($ ((call/fresh (lambda (q) (== q 5))) empty-state)))
  114. (car $)))
  115. (test "second-set t2"
  116. (let (($ ((call/fresh (lambda (q) (== q 5))) empty-state)))
  117. (cdr $)))
  118. (test "second-set t3"
  119. (let (($ (a-and-b empty-state)))
  120. (car $)))
  121. (test "second-set t3, take"
  122. (let (($ (a-and-b empty-state)))
  123. (take 1 $)))
  124. (test "second-set t4"
  125. (let (($ (a-and-b empty-state)))
  126. (car (cdr $))))
  127. (test "second-set t5"
  128. (let (($ (a-and-b empty-state)))
  129. (cdr (cdr $))))
  130. (test "who cares"
  131. (let (($ ((call/fresh (lambda (q) (fives q))) empty-state)))
  132. (take 1 $)))
  133. (test "take 2 a-and-b stream"
  134. (let (($ (a-and-b empty-state)))
  135. (take 2 $)))
  136. (test "take-all a-and-b stream"
  137. (let (($ (a-and-b empty-state)))
  138. (take-all $)))
  139. (test "ground appendo"
  140. (car ((ground-appendo empty-state))))
  141. (test "ground appendo2"
  142. (car ((ground-appendo2 empty-state))))
  143. (test "appendo"
  144. (take 2 (call-appendo empty-state)))
  145. (test "appendo2"
  146. (take 2 (call-appendo2 empty-state)))
  147. (test "reify-1st across appendo"
  148. (map reify-1st (take 2 (call-appendo empty-state))))
  149. (test "reify-1st across appendo2"
  150. (map reify-1st (take 2 (call-appendo2 empty-state))))
  151. (test "many non-ans"
  152. (take 1 (many-non-ans empty-state)))