
; PRIMES ist die Liste ALLER Primzahlen: (2 3 5 7 11 ...)
(define primes (cons-stream 2 (filter prime? odd-numbers)))

(define (prime? n) 
  (define (iter ps) 
    (cond ((> (square (head ps)) n) ;Ist n kleiner als das Quadrat der aktu-
                                    ;ellen Primzahl, dann ist n Primzahl !!!
              (debug "Akt. Primzahl:" n)
               t)
          ((divisible? n (head ps)) nil)  ;Ist n duch die aktuelle  Primzahl
                                          ;teilbar, ist n keine Primzahl !!!
          (else (iter (tail ps)))))       ;Ansonsten teste nchste Primzahl.
  (iter primes))

;---------------------------------------------------------------------------
; Man beachte, da sich PRIME? und PRIMES gegenseitig aufrufen. Das Funkti-
; oniert deshalb, weil in PRIMES immer gengend Primzahlen berechnet sind,
; um PRIME? zu bestimmen !!! 
;---------------------------------------------------------------------------


(define (filter pred stream)
  (cond ((empty-stream? stream) the-empty-stream)
        ((pred (head stream))
            (cons-stream (head stream)
                         (filter pred (tail stream))))
        (else (filter pred (tail stream)))))


(define (odd-number-gen x)
  (invariant (odd? x)) ; x mu ungerade sein
  (cons-stream x (odd-number-gen (+ 2 x))))

; ODD-NUMBERS reprsentiert ALLE ungeraden Zahlen, ab 3: (3 5 7 9 11 ...)
(define odd-numbers (odd-number-gen 3))

(define (number-gen n)
  (cons-stream n (number-gen (1+ n))))

; NAT-NUMBERS reprsentiert ALLE natrlichen Zahlen: (1 2 3 4 5 6 7 ...)
(define nat-numbers (number-gen 1)) 

;---------------------------------------------------------------------------
; Eher unwichtige Hilfsroutinen;

(define (square x) (* x x))

(define (divisible? x y)
  (zero? (remainder x y)))



