EoPL 読んでた記録の確認とその記録 (8)

Ex.2.8 です。ちょっとカン違いしてたのですが、以下は #t なんですね。

> (occurs-bound? 'x '(lambda (y) y))

occurs-bound? は以下なカンジ。

(define occurs-bound?
  (lambda (var exp)
    (cases lexical-address exp
	   (lit-exp (datum) #f)
	   (lex-info (id depth position) #t)
	   (free-info (id) #f)
	   (if-exp (test-exp true-exp false-exp)
		   (or (occurs-bound? var test-exp)
		       (occurs-bound? var true-exp)
		       (occurs-bound? var false-exp)))
	   (lambda-exp (id body)
		       (or (occurs-bound? var body)
			   (and (eqv? var id)
				(occurs-free? var body))))
	   (app-exp (rator rand)
		    (or (occurs-bound? var rator)
			(occurs-bound? var rand))))))

以下な試験にパスしてるんだけど良いのだろうか。とりあえずこれでヨシとして free-vars および bound-vars を云々してみます。
test-occurs-bound.scm

(add-load-path ".")
(load "occurs-bound")
(load "parse-expression")

(test-start "occurs-bound")
(test-section "occurs-bound")
(test* "not bound"
       #f
       (occurs-bound? 'x (parse-expression 5)))

(test* "not bound (2)"
       #f
       (occurs-bound? 'x (parse-expression 'x)))

(test* "not bound (2)"
       #f
       (occurs-bound? 'x (parse-expression 'y)))

(test* "not bound (3)"
       #f
       (occurs-bound? 'x (parse-expression '(lambda (y) x))))

(test* "not bound (3)"
       #f
       (occurs-bound? 'x (parse-expression '(if (null? x) 1 2))))

(test* "not bound (3)"
       #f
       (occurs-bound? 'x (parse-expression '(if (null? y) x 2))))

(test* "not bound (3)"
       #f
       (occurs-bound? 'x (parse-expression '(if (null? y) 1 x))))

(test* "lambda exp (occurs-bound)"
       #t
       (occurs-bound? 'x (parse-expression '(lambda (x) x))))

(test* "lambda exp (not-bound)"
       #f
       (occurs-bound? 'x (parse-expression '(lambda (x) y))))

(test* "lambda exp (occurs-bound)"
       #t
       (occurs-bound? 'x (parse-expression '(lambda (y) y))))

(test* "app exp (occurs-bound)"
       #t
       (occurs-bound? 'x (parse-expression '((lambda (x) x) y))))

(test* "app exp"
       #t
       (occurs-bound? 'x (parse-expression '((lambda (y) y) x))))

(test* "app exp (not-bound)"
       #f
       (occurs-bound? 'x (parse-expression '((lambda (x) y) y))))

(test-end)

test-occurs-free.scm

(use gauche.test)
(add-load-path ".")
(load "occurs-free")
(load "parse-expression")

(test-start "occurs-free")
(test-section "occurs-free")
(test* "literal"
       #t
       (occurs-free? 'x (parse-expression 5)))

(test* "variable"
       #t
       (occurs-free? 'x (parse-expression 'x)))

(test* "variable"
       #t
       (occurs-free? 'x (parse-expression 'y)))

(test* "if exp"
       #t
       (occurs-free? 'x (parse-expression '(if (null? x) 1 2))))

(test* "if exp (2)"
       #t
       (occurs-free? 'x (parse-expression '(if (null? y) x 2))))

(test* "if exp (3)"
       #t
       (occurs-free? 'x (parse-expression '(if (null? y) 1 x))))

(test* "lambda exp"
       #f
       (occurs-free? 'x (parse-expression '(lambda (x) x))))

(test* "lambda exp"
       #t
       (occurs-free? 'x (parse-expression '(lambda (x) y))))

(test* "lambda exp"
       #t
       (occurs-free? 'x (parse-expression '(lambda (y) x))))

(test* "app exp"
       #t
       (occurs-free? 'x (parse-expression '((lambda (x) x) y))))

(test* "app exp"
       #t
       (occurs-free? 'x (parse-expression '((lambda (y) y) x))))

(test* "app exp (not-bound)"
       #t
       (occurs-free? 'x (parse-expression '((lambda (x) y) y))))

(test-end)

なんとなく実装てきに微妙感満点なのですがorz
とりあえずここでエントリ投入します。追記はできないと思われます。