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

うーん。頭痛い。今週は週のアタマからハードな週でしてスデに週末気分。朝起きて今日は金曜日じゃないんだったっけ、って思うのは随分久しぶりだな。
で、頭痛と言いつつ現実からトウヒしてみたログを以下に。

Conditionals and sequences

って直前エントリ見てみると_定義と代入_とか言いつつ if だの sequence だのな話が展開されてるぞ。何考えてるんだ。微妙ですがエントリは修正せずに置いとこう。
で、何が言いたいか、とゆーとアレです。条件分岐とか並びというソレ達は、手続きを実行する部分をきちんと理解しないと試験は作れないな、という事ッス。
ただ、単純な試験なら作成は可能。例えば

  ("if"
   ("simple (consequent)"
    (let ((env (setup-environment)))
      (let ((succeed (lambda (value fail) value))
	    (fail (lambda () 'failed)))
	(assert-equal 1 ((analyze-if '(if true 1 2)) env succeed fail))
	)
      )
    )

   ("simple (alternative)"
    (let ((env (setup-environment)))
      (let ((succeed (lambda (value fail) value))
	    (fail (lambda () 'failed)))
	(assert-equal 2 ((analyze-if '(if false 1 2)) env succeed fail))
	)
      )
    )
   )

  ("begin"
   ("simple"
    (let ((env (setup-environment)))
      (let ((succeed (lambda (value fail) value))
	    (fail (lambda () 'failed)))
	(assert-equal 3 ((analyze-sequence 
			  (begin-actions '(begin 1 2 3))) env succeed fail))
	)
      )
    )
   )

みたいな。一応試験としては成立しているんだとは思いますが微妙っちゃ微妙。ただ、定義されている手続きを見るに上記の simple (consequent) な試験で言えば analyze-if で戻った手続きは true を analyze-variable した結果戻った手続きを呼び出す形になっていて、それは succeed を true を lookup した結果と fail を渡して呼び出す、と。
analyze-if が戻す succeed な手続きは

(lambda (pred-value fail2)
  (if (true? pred-value)
      (cproc env succeed fail2)
      (aproc env succeed fail2)))

となってて、pred-value は #t なので if-consequent が戻す手続きが呼び出される、という事になる、と。上記の試験によれば cproc に渡される succeed な手続きは

(lambda (value fail) value)

なので 1 が戻ってくる、というのがざっくりした話の顛末になるのか。alternative な if はほぼ同様なのでスルーとして、sequence はどうなるのかなぁ。

sequences

analyze-sequence は begin だとその中身のリストのみが渡される模様。まずそれらが analyze されたリストが procs に。上記の begin な試験だと analyze-self-evaluating が戻す手続きが三つほど格納されているはず。その car と cdr が loop に渡される。
ちなみに loop に渡されるリストの要素が一つだけだった場合はその手続きがそのまんま戻る格好になってるんで (以下略
試験のケースだとこれがどうなるか、というと最初に loop に渡される first-proc は便宜的に

(lambda (env succeed fail) (succeed 1 fail))

で rest-procs が

((lambda (env succeed fail) (succeed 2 fail))
 (lambda (env succeed fail) (succeed 3 fail)))

とすると (実際に lambda が analyze された結果は違うはず)、次の loop に渡される first-proc は

(lambda (env succeed fail)
  ((lambda (env succeed fail) (succeed 1 fail))
   env
   (lambda (a-value fail2)
     ((lambda (env succeed fail) (succeed 2 fail)) env succeed fail2))
   fail))

で、rest-procs は

((lambda (env succeed fail) (succeed 3 fail)))

となって次の loop に渡される first-proc は

(lambda (env succeed fail)
  ((lambda (env succeed fail)
     ((lambda (env succeed fail) (succeed 1 fail))
      env
      (lambda (a-value fail2)
	((lambda (env succeed fail) (succeed 2 fail)) env succeed fail2))
      fail))
   env
   (lambda (a-value fail2)
     ((lambda (env succeed fail) (succeed 3 fail)) env succeed fail2))
   fail))

となって rest-procs は '() になるんで analyze-sequence が戻すのは上記の試験ではこの first-proc に渡される手続きになるはず。succeed 沢山ありますが、それぞれ束縛される手続きは異なっている。これはこれは、という感じ。中身がもっと複雑な手続きだった場合、面白そうですが現時点ではこれはスルー。(を

で、現実トウヒの結果、頭痛が若干治まってきたのでエントリ投入後に頭痛のタネな作業を再開してみます。(何