SICP 読み (223) 4.3.3 amb 評価器の実装

ちょっと試験不足気味ですが先に進む。あと試験ドリブンなソレを止めていたんですが、そろそろきちんとヤラないとまずい。ちょっと体調不良なんで様子を見つつ進めてみる。ってか、中身に目を通さんと。

とりあえず

単純式なソレについて試験をでっち上げてみる。

#!/usr/bin/env gosh

(use test.unit)
(require "ch4-ambeval")

(define-test-suite "amb"

  ("self-eval"
   ("1"
    (let ((env (setup-environment)))
      (let ((succeed (lambda (value fail) value))
	    (fail (lambda () 'failed)))
	(assert-equal 1 ((analyze-self-evaluating 1) env succeed fail))
	)
      )
    )
   )

  ("quoted"
   ("(quote a)"
    (let ((env (setup-environment)))
      (let ((succeed (lambda (value fail) value))
	    (fail (lambda () 'failed)))
	(assert-equal 'a ((analyze-quoted '(quote a)) env succeed fail))
	)
      )
    )
   )

  ("variable"
   ("x"
    (let ((env (setup-environment)))
      (let ((succeed (lambda (value fail) value))
	    (fail (lambda () 'failed)))
	(eval-definition '(define x 1) env)
	(assert-equal '1 ((analyze-variable 'x) env succeed fail))
	)
      )
    )
   )

  ("lambda"
   ("(lambda () 1)"
    (let ((env (setup-environment)))
      (let ((succeed (lambda (value fail) value))
	    (fail (lambda () 'failed)))
	(let ((l ((analyze-lambda '(lambda () 1)) env succeed fail)))
	  (assert-equal 'procedure (car l))
	  (assert-equal '() (cadr l))
	  (assert-equal 1 ((caddr l) env succeed fail))
	  )
	)
      )
    )
   )
  )

lambda は analyze-sequence の試験をしてませんが、ある意味確認のためなんでスルー。analyze されたソレが analyze-lambda が戻すリストの caddr にセットされてる、という事はこれも手続きなんですが、試験な lambda では self-evaluating のみが戻る形、とゆー事で succeed 決めウチな試験をしています。
これは analyze-sequence な試験をして、ざっくり理解した後にきちんとした試験が必要。もう少し内容を精査してみますが、追記があるかどうかは微妙。

定義と代入

やはり試験を作るリキは無い。でも、analyze-if も analyze-sequence もとても面白い。失敗継続を持ち回っているのは分かったのですが、失敗した時にその前の失敗継続とゆーソレをどうやって知るんだろうか。
あと、上手に図示できないんですが、analyze-sequence が最終的に戻す手続きがとても面白い。ちょっとしかイメージできてないのだと思いますが凄い。ただ、実際に手続きが実行される時のナニが (以下略
(a b c d) という並びを評価したソレはこんなカンジでしょうか。

(let ((aa (lambda (env succeed fail)
	    (a env
	       (lambda (a-value fail2)
		 (b env succeed fail2))
	       fail))))
  (let ((cc (lambda (env succeed fail)
	      (aa env
		  (lambda (a-value fail2)
		    (c env succeed fail2))
		  fail))))
    (lambda (env succeed fail)
      (cc env
	  (lambda (a-value fail2)
	    (d env succeed fail2))
	  fail))))

げ。上記は間違ってるのか、と思ってたらビンゴっぽい。こりゃ凄い。って、まだ全部見えてないのにこんな事言って良いのだろうか。(を