Przeglądaj źródła

macros for convenience and reification.

that's it. now i really want to know when those `pair?` calls are
needed. that's something i'd like to have an instarepl for, or maybe an
environment more like learnable programming? or maybe paper will do.
we'll see.
Lucas Stadler 12 lat temu
rodzic
commit
3bc4b5be8d
1 zmienionych plików z 111 dodań i 7 usunięć
  1. 111 7
      scm/mukanren.scm

+ 111 - 7
scm/mukanren.scm

@ -94,15 +94,119 @@
94 94
95 95
;; 5 utilities
96 96
97
(define (expand n s)
98
  (if (> n 1)
99
    (cond
100
      ((null? s) s)
101
      ((procedure? (cdr s)) `(,(car s) . ,(expand (- n 1) ((cdr s)))))
102
      (else `(,(car s) . ,(expand (- n 1) (cdr s)))))
97
#|
98
(define (expand-deferred s)
99
  (if (procedure? s)
100
    (expand-deferred (s))
101
    s))
102
103
(define (expand-once s)
104
  (if (procedure? s)
105
    (s)
103 106
    s))
104 107
108
(define (expand n s)
109
  (if (and (> n 1) (not (null? s)))
110
    `(,(expand-deferred (car s)) . ,(expand (- n 1) (expand-once (cdr s))))
111
    (expand-deferred s)))
112
105 113
(expand 5 (fives-and-sixes empty-state))
106 114
107 115
(define (run n g)
108
  (expand n (g empty-state)))
116
  (expand n (g empty-state)))
117
|#
118
119
(define-syntax Zzz
120
  (syntax-rules ()
121
    ((_ g) (lambda (s/c) (lambda () (g s/c))))))
122
123
(define-syntax conj+
124
  (syntax-rules ()
125
    ((_ g) (Zzz g))
126
    ((_ g0 g ...) (conj (Zzz g0) (conj+ g ...)))))
127
128
(define-syntax disj+
129
  (syntax-rules ()
130
    ((_ g) (Zzz g))
131
    ((_ g0 g ...) (disj (Zzz g0) (disj+ g ...)))))
132
133
(define-syntax conde
134
  (syntax-rules ()
135
    ((_ (g0 g ...) ...) (disj+ (conj+ g0 g ...) ...))))
136
137
(define-syntax fresh
138
  (syntax-rules ()
139
    ((_ () g0 g ...) (conj+ g0 g ...))
140
    ((_ (x0 x ...) g0 g ...)
141
     (call/fresh (lambda (x0) (fresh (x ...) g0 g ...))))))
142
143
;(run 1 (fresh (x y z) (≡ x 7) (≡ y 8) (disj (≡ x z) (≡ y z))))
144
145
;; 5.2 from streams to lists
146
147
(define (pull $) (if (procedure? $) (pull ($)) $))
148
149
(define (take-all $)
150
  (let (($ (pull $)))
151
    (if (null? $) '() (cons (car $) (take-all (cdr $))))))
152
153
(define (take n $)
154
  (if (zero? n) '()
155
    (let (($ (pull $)))
156
      (cond
157
        ((null? $) '())
158
        (else (cons (car $) (take (- n 1) (cdr $))))))))
159
160
(take 10 ((fresh (x y z) (≡ x 7) (≡ y 8) (disj+ (≡ x z) (≡ y z) (≡ x y))) empty-state))
161
162
;; 5.3 recovering reification
163
164
(define (mK-reify s/c*)
165
  (map reify-state/1st-var s/c*))
166
167
(define (reify-state/1st-var s/c)
168
  (let ((v (walk* (var 0) (car s/c))))
169
    (walk* v (reify-s v '()))))
170
171
(define (reify-s v s)
172
  (let ((v (walk v s)))
173
    (cond
174
      ((var? v)
175
       (let ((n (reify-name (length s))))
176
         (cons `(,v . ,n) s)))
177
      ((pair? v) (reify-s (cdr v) (reify-s (car v) s)))
178
      (else s))))
179
180
(define (reify-name n)
181
  (string->symbol
182
    (string-append "_." (number->string n))))
183
184
(define (walk* v s)
185
  (let ((v (walk v s)))
186
    (cond
187
      ((var? v) v)
188
      ((pair? v) (cons (walk* (car v) s)
189
                       (walk* (cdr v) s)))
190
      (else v))))
191
192
(mK-reify (take 10 ((fresh (x y z) (≡ x 7) (≡ y 8) (disj+ (≡ x z) (≡ y z) (≡ x y))) empty-state)))
193
194
(mK-reify (take 100 (fives-and-sixes empty-state)))
195
196
;; 5.4 recovering the interface to scheme
197
198
(define (call/empty-state g) (g empty-state))
199
200
(define-syntax run
201
  (syntax-rules ()
202
    ((_ n (x ...) g0 g ...)
203
     (mK-reify (take n (call/empty-state
204
                         (fresh (x ...) g0 g ...)))))))
205
206
(define-syntax run*
207
  (syntax-rules ()
208
    ((_ (x ...) g0 g ...)
209
     (mK-reify (take-all (call/empty-state
210
                           (fresh (x ...) g0 g ...)))))))
211
212
(run 10 (y x z) (≡ x 7) (disj+ (≡ y 8) (≡ y 18) (≡ y 28)) (≡ z 9))