修正した。

S (式1) (式2) が S (式1') (式2') (式3) になることはありえない気がする。気がするだけなのが弱い。

結局、((式1) (式2) (式3)) みたいなの((式1)を簡約するとSになるようなやつ)には対応せず。つーか

(else (map expand-combinator-one seq))

(else (expand-combinator-one (map expand-combinator-one seq)))

にするだけで行けるやん?とか考えてたけど、 (K I) のような入力で無限ループになるだけだった。S / Kの評価で作りこめばいいのだろうけど、面倒だからあとでやるかも。toSKメソッドでバラしたものが出来るからとりあえずいーや。

SICPの4章のEval-Apply 相互再帰に似てきた気がする。
インタプリタみたいなのを作る上での黄金パターンなのかもしらん。

(define (apply-S p1 p2 p3 rest)
  (if (not (pair? p1))
        `(,p1 ,p3 ,(if (not (pair? p2)) `(,p2 ,p3) `(,@p2 ,p3)) ,@rest)
        `(,@p1 ,p3 ,(if (not (pair? p2)) `(,p2 ,p3) `(,@p2 ,p3)) ,@rest)))
 
(define (apply-K p1 p2 rest)
  (if (not (pair? p1))
          `(,p1 ,@rest)
          `(,@p1 ,@rest)))
 
(define (is-S-reduction? seq)
        (and (eq? (car seq) 'S) (not (null? (cdr seq))) (not (null? (cddr seq))) (not (null? (cdddr seq)))))
(define (is-K-reduction? seq)
        (and (eq? (car seq) 'K) (not (null? (cdr seq))) (not (null? (cddr seq)))))
 
(define beta-red-itr
  (lambda (seq)
    ;;(begin (display "---   ") (display seq) (newline)
        (cond
          ((not (pair? seq)) seq)
          ((and (not (pair? (car seq))) (null? (cdr seq))) (car seq))
          ((is-S-reduction? seq)
                (let ((p1 (cadr seq))
                          (p2 (caddr seq))
                          (p3 (cadddr seq))
                          (rest (cddddr seq)))
                        (beta-red-itr (apply-S (beta-red-itr p1)
                                         (beta-red-itr p2)
                                         (beta-red-itr p3)
                                         rest))))
          ((is-K-reduction? seq)
                (let ((p1 (cadr seq))
                          (p2 (caddr seq))
                          (rest (cdddr seq)))
                  (beta-red-itr (apply-K (beta-red-itr p1) p2 rest))))
          ((eq? (car seq) 'I)
                (beta-red-itr (cdr seq)))
          ((and (null? (cdr seq)) (symbol? (car seq))) (car seq))
          (else
                (map beta-red-itr seq)))))
    ;;)
(define (beta-reduction l)
  (let ((result (beta-red-itr l)))
        (if (and (pair? result) (null? (cdr result))) (car result) result)))