SICP問題3.77

元のintegral(教科書で定義)

(define int
  (cons-stream initial-value
               (add-streams (scale-stream integrand dt)
                            int)))

出力ストリームの第一要素より先を生成するよう要求された時だけ、被積分値を評価すべくforceするように再定義したintegral(教科書で定義)

(define (integral delayed-integrand initial-value dt)
  (define int
    (cons-stream initial-value
                 (let ((integrand (force delayed-integrand)))
                   (add-streams (scale-stream integrand dt)
                                int))))
  int)

dy/dt = f(y)を解くsolveの定義(教科書で定義)

(define (solve f y0 dt)
  (define y (integral (delay dy) y0 dt))
  (define dy (stream-map f y))
  y)

integers-starting-fromに良く似たintegralの定義(教科書で定義)

(define (integral integrand initial-value dt)
  (cons-stream initial-value
               (if (stream-null? integrand)
                   the-empty-stream
                   (integral (stream-cdr integrand)
                             (+ (* dt (stream-car integrand))
                                initial-value)
                             dt))))

ループのあるシステムで使うために、integrandを遅延引数としてとり、上のsolve手続きで使えるようにしたintegral手続き
※ integrand を delay しなければならない

(define (integral delayed-integrand initial-value dt)
  (cons-stream initial-value
               (let ((integrand (force delayed-integrand)))
                 (if (stream-null? integrand)
                     the-empty-stream
                     (integral (delay (stream-cdr integrand))
                               (+ (* dt (stream-car integrand))
                                  initial-value)
                               dt)))))

テスト
y(0) = 1, dy/dt=y の解 y=1での値を計算し e=\approx2.718の近似を得ることでsolve手続きが実証出来る

(stream-ref (solve (lambda (y) y) 1 0.001) 1000)
; 2.716923932235896

OK