EoPL reading (26) 1.3.1 Free and Bound Variables
昨晩のナニを一日ネカせて再度試験を一から確認してみます。
と言いつつ、ut って不足あるな、と思ってたりして ...
# これって occurs free も同様
再度 occurs bound の定義を以下に。
- 式 E は (lambda (y) E') な式
- E' において x が occurs bound である
- 又は x と y が同じ変数であり、y が E' において occurs free である
という記述になっている。又リストである場合にはいずれかの要素が occurs bound である事、という条件か。てーコトは
test (occurs-bound? 'x '((lambda (x y) (+ x y)) x z)) should return #f, expects #f ==> ERROR: GOT #t test (occurs-bound? 'y '((lambda (x y) (+ x y)) x y)) should return #f, expects #f ==> ERROR: GOT #t test (occurs-bound? 'x '((lambda (x y) (+ x y)) x y)) should return #f, expects #f ==> ERROR: GOT #t
上記は occurs bound 認定でないと駄目ですな。ちなみに上記は occurs free も真のはず。あるいは以下も
test (occurs-bound? 'x '((lambda (x y z) (((lambda (x) x) +) x y z) a b x)) should return #f: expects #f => got #t
occurs bound ですな。何の試験をしたかったのか今となっては謎。あ、成程。occurs free の試験を丸ごとコピーしてその逆書いたんだ。試験として微妙と言わざるを得ませんな。最終的に以下なカンジに。
<ex.1-22>---------------------------------------------------------------------- test (occurs-bound? 'z '((lambda (a b) (+ a b)) x y)) should return #f, expects #f ==> ok test (occurs-bound? 'y '((lambda (a b) (+ a b)) x y)) should return #f, expects #f ==> ok test (occurs-bound? 'x '((lambda (a b) (+ a b)) x y)) should return #f, expects #f ==> ok test (occurs-bound? 'x '((lambda (x y z) (((lambda (x) x) +) x y z) a b x)) should return #t, expects #t ==> ok test (occurs-bound? '+ '((lambda (x y z) (((lambda (x) x) +) x y z) a b x)) should return #f, expects #f ==> ok test (occurs-bound? 'a '((lambda (x y z) (((lambda (x) x) +) x y z) a b x)) should return #f, expects #f ==> ok test (occurs-bound? 'b '((lambda (x y z) (((lambda (x) x) +) x y z) a b x)) should return #f, expects #f ==> ok test (occurs-bound? 'y '((lambda (x y z) (((lambda (x) x) +) x y z) a b x)) should return #t, expects #t ==> ok test (occurs-bound? 'z '((lambda (x y z) (((lambda (x) x) +) x y z) a b x)) should return #t, expects #t ==> ok
なんか微妙。試験の品質悪いな。もう少し頭をヒヤす方向で次の問題に行きます。(を
Exercise-1.23
これって cond な条件分岐に (eqv? (car exp) 'if) な分岐が加われば良いのでしょうけれど、どうなれば良いのかな。
こんなカンジ?
((eqv? (car exp) 'if) (or (occurs-free? var (cadr exp)) (occurs-free? var (cddr exp))))
でもこのケイスって、いきなり if が出てきたら、、、って思ったら occurs free なのか。リストが扱えるようになったからこうした syntax のナニが可能になったのか。
で、ちょっとへろへろなので微妙ですが、以下の試験をでっち上げてみました。
(test-section "ex.1-23") ;; E is of the form (lambda (y) E'), where y is not different from x (test* "(occurs-free? 'x '(lambda (x) (if (= x 1) #f #t))) should return #f" #f (occurs-free? 'x '(lambda (x) (if (= x 1) #f #t))) ) ;; E is of the form (lambda (y) E'), where y is different from x ;; but x doesn't occurs free in E' (test* "(occurs-free? 'x '(lambda (y) (if (= x 1) #f #t))) should return #t" #t (occurs-free? 'x '(lambda (y) (if (= x 1) #f #t))) ) ;; E is of the form (lambda (y) E'), where y is not different from x (test* "(occurs-free? 'x '(lambda (x) (if (= y 1) #f #t))) should return #f" #f (occurs-free? 'x '(lambda (x) (if (= y 1) #f #t))) ) ;; E is of the form (lambda (y) E'), where y is different from x ;; but x doesn't occurs free in E' (test* "(occurs-free? 'x '(lambda (y) (if (= y 1) #f x))) should retuen #t" #t (occurs-free? 'x '(lambda (y) (if (= y 1) #f x))) ) ;; E is of the form (lambda (y) E'), where y is different from x ;; but x doesn't occurs free in E' (test* "(occurs-free? 'x '(lambda (y) (if (= y 1) x #f))) should retuen #t" #t (occurs-free? 'x '(lambda (y) (if (= y 1) x #f))) )
で、以下を追加して
((eqv? (car exp) 'if) (or (occurs-free? var (cadr exp)) (occurs-free? var (cddr exp))))
試験動かしたら以下。
make Testing occurs-bound ... passed. Testing occurs-free ... failed. discrepancies found. Errors are: test (occurs-free? 'x '(lambda (y) (if (= y 1) #f x))) should retuen #t: expects #t => got #<error "pair required, but got 1"> test (occurs-free? 'x '(lambda (y) (if (= y 1) x #f))) should retuen #t: expects #t => got #<error "pair required, but got 1"> $
これ、SICP の self-evaluating? な述語が必要そげ。以下な実装で試験パス。
(define occurs-free? (lambda (var exp) (define (self-evaluating? s) (or (number? exp) (string? exp) (eq? #t exp) (eq? #f exp))) (cond ((null? exp) #f) ((self-evaluating? exp) #f) ((symbol? exp) (eqv? exp var)) ((eqv? (car exp) 'lambda) (and (not (let f ((l (cadr exp))) (cond ((null? l) #f) ((eqv? (car l) var) #t) (else (f (cdr l)))))) (occurs-free? var (cddr exp)))) ((eqv? (car exp) 'if) (or (occurs-free? var (cadr exp)) (occurs-free? var (cddr exp)))) (else (or (occurs-free? var (car exp)) (occurs-free? var (cdr exp)))))))
なんか試験が微妙です。今日は体調微妙なんで早めに寝ます。
げ
なんだこれわ
(define occurs-free? (lambda (var exp) (define (self-evaluating? s) (or (number? exp) (string? exp) (eq? #t exp) (eq? #f exp)))
試験パスしてる事にびっくり。(を
だめだ。やっぱ疲れているみたい。今度こそもう寝ます。