@@ -156,7 +156,6 @@ accumulator-functions in Redex.
156156
157157Now α equivalence is straightforward:
158158
159-
160159@code-from-file["code/mon-aft.rkt "
161160 #rx"determines whether e_1 and e_2 are α equivalent "
162161 #:exp-count 3 ]
@@ -165,6 +164,7 @@ Now α equivalence is straightforward:
165164@; -----------------------------------------------------------------------------
166165@section{Extending a Language: @racket[any ]}
167166
167+
168168Suppose we wish to extend @racket[Lambda] with @racket[if ] and Booleans,
169169like this:
170170@;%
@@ -178,7 +178,7 @@ like this:
178178 (if e e e)))
179179))
180180@;%
181- Guess what? @racket[(term (fv (lambda (x y) (if x y false ))))] doesn't
181+ Guess what? @racket[(term (sd (lambda (x y) (if x y false ))))] doesn't
182182 work because @racket[false ] and @racket[if ] are not covered.
183183
184184We want metafunctions that are as generic as possible for computing such
@@ -187,45 +187,11 @@ equivalences.
187187
188188Redex contracts come with @racket[any ] and Redex patterns really are over
189189Racket's S-expressions. This definition now works for extensions that don't
190- add binders:
191- @;%
192- @(begin
193- #reader scribble/comment-reader
194- (racketblock
195- (module+ test
196- (test-equal (SD? sd1) #true ))
197-
198- (define-metafunction SD
199- sd : e -> e
200- [(sd e) (sd/a e ())])
201-
202- (module+ test
203- (test-equal (term (sd/a x ())) (term x))
204- (test-equal (term (sd/a x (y z x))) (term (K 2 )))
205- (test-equal (term (sd/a ((lambda (x) x) (lambda (y) y)) ()))
206- (term ((lambda (K 0 )) (lambda (K 0 )))))
207- (test-equal (term (sd/a (lambda (x) (x (lambda (y) y))) ()))
208- (term (lambda ((K 0 ) (lambda (K 0 ))))))
209- (test-equal (term (sd/a (lambda (z) (lambda (x) (x (lambda (y) z)))) ()))
210- (term (lambda (lambda ((K 0 ) (lambda (K 2 ))))))))
211-
212- (define-metafunction SD
213- sd/a : e (x ... ) -> e
214- [(sd/a x (x_1 ... x x_2 ... ))
215- ;; bound variable
216- (K n)
217- (where n ,(length (term (x_1 ... ))))
218- (where #false (in x (x_1 ... )))]
219- [(sd/a (lambda (x) e) (x_rest ... ))
220- (lambda (sd/a e (x x_rest ... )))
221- (where n ,(length (term (x_rest ... ))))]
222- [(sd/a (e_fun e_arg) (x_rib ... ))
223- ((sd/a e_fun (x_rib ... )) (sd/a e_arg (x_rib ... )))]
224- [(sd/a any_1 (x ... ))
225- ;; free variable or constant
226- any_1])
227- ))
228- @;%
190+ add binders:
191+
192+ @code-from-file["code/common.rkt "
193+ #rx"define-extended-language SD Lambda "
194+ #:exp-count 6 ]
229195
230196@; -----------------------------------------------------------------------------
231197@section{Substitution}
@@ -234,49 +200,6 @@ The last thing we need is substitution, because it @emph{is} the syntactic
234200equivalent of function application. We define it with @emph{any } having
235201future extensions in mind.
236202
237- @;%
238- @(begin
239- #reader scribble/comment-reader
240- (racketblock
241- ;; (subst ([e x] ...) e_*) substitutes e ... for x ... in e_* (hygienically)
242-
243- (module+ test
244- (test-equal (term (subst ([1 x][2 y]) x)) 1 )
245- (test-equal (term (subst ([1 x][2 y]) y)) 2 )
246- (test-equal (term (subst ([1 x][2 y]) z)) (term z))
247- (test-equal (term (subst ([1 x][2 y]) (lambda (z) (lambda (w) (x y)))))
248- (term (lambda (z) (lambda (w) (1 2 )))))
249- (test-equal (term (subst ([1 x][2 y]) (lambda (z) (lambda (w) (lambda (x) (x y))))))
250- (term (lambda (z) (lambda (w) (lambda (x) (x 2 )))))
251- #:equiv =α/racket)
252- (test-equal (term (subst ((2 x)) ((lambda (x) (1 x)) x)))
253- (term ((lambda (x) (1 x)) 2 ))
254- #:equiv =α/racket))
255-
256- (define-metafunction Lambda
257- subst : ((any x) ... ) any -> any
258- [(subst [(any_1 x_1) ... (any_x x) (any_2 x_2) ... ] x) any_x]
259- [(subst [(any_1 x_1) ... ] x) x]
260- [(subst [(any_1 x_1) ... ] (lambda (x) any_body))
261- (lambda (x_new)
262- (subst ((any_1 x_1) ... )
263- (subst-raw (x_new x) any_body)))
264- (where x_new ,(variable-not-in (term any_body) (term x)))]
265- [(subst [(any_1 x_1) ... ] (any ... )) ((subst [(any_1 x_1) ... ] any ) ... )]
266- [(subst [(any_1 x_1) ... ] any_*) any_*])
267-
268- (define-metafunction Lambda
269- subst-raw : (x x) any -> any
270- [(subst-raw (x_new x_) x_) x_new]
271- [(subst-raw (x_new x_) x) x]
272- [(subst-raw (x_new x_) (lambda (x) any ))
273- (lambda (x) (subst-raw (x_new x_) any ))]
274- [(subst-raw (x_new x_) (any ... ))
275- ((subst-raw (x_new x_) any ) ... )]
276- [(subst-raw (x_new x_) any_*) any_*])
277-
278- ))
279- @;%
280-
281-
282- }
203+ @code-from-file["code/common.rkt "
204+ #rx"substitutes e [.][.][.] for x [.][.][.] in e_[*] "
205+ #:exp-count 3 ]
0 commit comments