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

Ex.1.19 の free-vars および bound-vars はヤッツケ。とりあえずできあがりは GitHub に反映しといて Ex.2.8 に着手。

とりあえず

occurs-free および occurs-bound と expression を定義なのか。expression は既存を流用。て、Ex.2.7 の定義を使うことに今気づいている次第ス。
つうことは lexical-adreess を使う前提で occurs-free? および occurs-bound? を書きかえになるのかな。

とりあえず

以下なカンジになってます。
lexical-address.scm

(add-load-path "../../define-datatype")
(load "define-datatype")

(define-datatype lexical-address lexical-address?
  (lit-exp
   (datum number?))
  (lex-info
   (id symbol?)
   (depth number?)
   (position number?))
  (free-info
   (id symbol?))
  (if-exp
   (test-exp lexical-address?)
   (true-exp lexical-address?)
   (false-exp lexical-address?))
  (lambda-exp
   (args list?)
   (body lexical-address?))
  (app-exp
   (rator lexical-address?)
   (rand lexical-address?)))

occurs-bound.scm

(add-load-path ".")
(load "lexical-address")

(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))))))

occurs-free.scm

(add-load-path ".")
(load "expression")

(define occurs-free?
  (lambda (var exp)
    (cases lexical-address exp
	   (var-exp (id) (eqv? id var))
	   (lambda-exp (id body)
		       (and (not (eqv? id var))
			    (occurs-free? var body)))
	   (app-exp (rator rand)
		    (or (occurs-free? var rator)
			(occurs-free? var rand))))))

parse-expression.scm

(add-load-path ".")
(load "lexical-address")

(define parse-expression
  (lambda (datum)
    (cond
     ((number? datum) (lit-exp datum))
     ((symbol? datum) (var-exp datum))
     ((pair? datum)
      (cond
       ((eqv? (car datum) 'if)
	(if-exp (parse-expression (cadr datum))
		(parse-expression (caddr datum))
		(parse-expression (cadddr datum))))
       ((eqv? (car datum) 'lambda)
	(lambda-exp (caadr datum)
		    (parse-expression (caddr datum))))
       (else
	(app-exp
	 (parse-expression (car datum))
	 (parse-expression (cadr datum))))))
     (else
      (eopl:error 'parse-expression
		  "Invalid concrete syntas ~s" datum)))))

test-occurs-bound.scm

(use gauche.test)
(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-end)

続きは明日の朝、なのかどうか。