;;;============================================================================ ;;; Grundlegende Prozeduren fuer das Arbeiten mit unendlichen Datenstroemen ;;; ;;;============================================================================ ;;; Implementierung von "collect" fuer unendliche Stroeme ;; Funktionsweise muss nicht verstanden werden. (define (foldr function start-value list) ; (* -> ** -> **) -> ** -> (list *) -> ** ; "akk" auf Listen (if (null? list) start-value (function (car list) (foldr function start-value (cdr list))))) (define (variablen generatoren) (map car generatoren)) (define (let-bauen-schritt variable rest-ausdruck) `(let ((,variable (car tupel)) (tupel (cdr tupel))) ,rest-ausdruck)) (define (glattabb-bauen-schritt element rest) `(glattabb (lambda (,(car element)) ,rest) ,(cadr element))) (define (generiere-strom-von-tupeln generatoren) (define schluss `(cons-strom (list ,@(variablen generatoren)) der-leere-strom)) (foldr glattabb-bauen-schritt schluss generatoren)) (define (q-ausdruck->q-prozedur q-ausdruck q-vars) `(lambda (tupel) ,(foldr let-bauen-schritt q-ausdruck q-vars))) (define-macro collect (lambda (q-ergebnis q-generatoren q-einschraenkung) (let ((q-vars (variablen q-generatoren))) `(abb ,(q-ausdruck->q-prozedur q-ergebnis q-vars) (filter ,(q-ausdruck->q-prozedur q-einschraenkung q-vars) ,(generiere-strom-von-tupeln q-generatoren)))))) ;;;============================================================================ ;;; Realisierung von unendlichen Stroemen (define der-leere-strom '()) (define leerer-strom? null?) (define-macro cons-strom (lambda (a b) `(cons ,a (delay ,b)))) (define (kopf strom) (car strom)) (define (rest strom) (force (cdr strom))) ;;;============================================================================ ;;; Strom-Prozeduren (define (zahlen-von n) (cons-strom n (zahlen-von (+ n 1)))) (define alle-zahlen (zahlen-von 0)) (define (n-tes-strom n s) (if (= n 0) (kopf s) (n-tes-strom (- n 1) (rest s)))) (define (add-stroeme s1 s2) (cond ((leerer-strom? s1) s2) ((leerer-strom? s2) s1) (else (cons-strom (+ (kopf s1) (kopf s2)) (add-stroeme (rest s1) (rest s2)))))) (define (glattabb f s) (glaetten (abb f s))) (define (glaetten s) (akk verzahnen der-leere-strom s)) (define (verzahnen s1 s2) (if (leerer-strom? s1) (force s2) (cons-strom (kopf s1) (verzahnen (force s2) (delay (rest s1)))))) (define (akk op e s) (if (leerer-strom? s) e (op (kopf s) (delay (akk op e (rest s)))))) (define (append-stroeme s1 s2) (if (leerer-strom? s1) s2 (cons-strom (kopf s1) (append-stroeme (rest s1) s2)))) (define (abb proz strom) (if (leerer-strom? strom) der-leere-strom (cons-strom (proz (kopf strom)) (abb proz (rest strom))))) (define (filter praed strom) (cond ((leerer-strom? strom) der-leere-strom) ((praed (kopf strom)) (cons-strom (kopf strom) (filter praed (rest strom)))) (else (filter praed (rest strom))))) (define (fuer-jedes proz strom) (if (leerer-strom? strom) 'fertig (begin (proz (kopf strom)) (fuer-jedes proz (rest strom))))) (define (gen-intervall a b) (if (> a b) der-leere-strom (cons-strom a (gen-intervall (+ a 1) b)))) ;;; die ersten anzahl Elemente des Stroms als Liste zurueckgeben (define (erste-elemente-zurueckgeben anzahl strom) (if (= anzahl 0) '() (cons (kopf strom) (erste-elemente-zurueckgeben (- anzahl 1) (rest strom))))) ;;; =========== TESTEN ============== (define (primzahl-summe-paare n) (collect (list i j (+ i j)) ((i (gen-intervall 1 n)) (j (gen-intervall 1 (- i 1)))) (primzahl? (+ i j)))) (define (aufzaehler endlicher-strom) (if (leerer-strom? endlicher-strom) endlicher-strom (cons (kopf endlicher-strom) (aufzaehler (rest endlicher-strom))))) (define zahl-paare (glattabb (lambda (i) (abb (lambda (j) (list i j)) alle-zahlen)) alle-zahlen))