BuK/IIm10/BuK-Übung03 G2
Aus ProgrammingWiki
Wiki-Quelltext dieser Seite.
<language>Scheme</language>
<language>Scheme</language>
=Aufzählbarkeit und Entscheidbarkeit=
== Aufgabe ==
Zeigen Sie, dass <math>\wp(A^*)</math> für ein beliebiges Alphabet A eine überabzählbar unendliche Menge
ist.
==Lösung==
Wenn <math>\wp(A^*)</math> abzählbar unendlich wäre, so müsste eine bijektive Abbildung auf die natürlichen Zahlen erfolgen können.
Bijektiv bedeutet in diesem Fall, dass jedem Element aus <math>N</math> '''genau ein''' Element aus <math>\wp(A^*)</math> zugeordnet wird.
Die Menge <math>\wp(A^*)</math> wird über <math>A^*</math> gebildet. Unter der Annahme, dass <math>\wp(A^*)</math> abzählbar unendlich ist, müsste man also
zuerst die natürlichen Zahlen auf <math>A^*</math> abbilden können und anschließend <math>A^*</math> auf <math>\wp(A^*)</math>.
[[Datei:Abbildung.png]]
Für eine bijektive Abbildung von <math>N</math> auf <math>\wp(A^*)</math> müssten also alle drei Mengen gleichmächtig, im konkreten Fall also abzählbar unendlich sein.
Dass <math>N</math> abzählbar unendlich ist steht außer Frage. Dass <math>A^*</math> ebenfalls abzählbar unendlich ist, wurde in [[BuK/IIm10/BuK-Übung02 G2#Aufgabe 2| Übung 2]] nachgewiesen.
Wie kann nun die Mächtigkeit von <math>\wp(A^*)</math> bestimmt werden?
Die Potenzmenge ist folgendermaßen definiert: <math>\wp(X) := \{U | U \subseteq X\}</math>.
Die Menge <math>A^*</math> besteht aus den Wörtern <math>w_1, w_2, \dots, w_k</math>.
Daraus folgt, dass <math>\wp(A^*)</math> für jedes <math>w_i</math> aus <math>A^*</math> ein Element der Form <math>\{w_i\}</math> enthält.
Zusätzlich enthält <math>\wp(A^*)</math> aber unter Anderem auch <math>\{\}</math>. Das allein reicht aus, um sagen zu können <math>|\wp(A)| > |A|</math>.
Somit ist bewiesen, dass es keine bijektive Abbildung von <math>A</math> auf <math>\wp(A^*)</math> geben kann und somit auch keine von
<math>N</math> auf <math>\wp(A^*)</math>. Demzufolge ist <math>\wp(A^*)</math> eine überabzählbar unendliche Menge.
==Aufgabe==
Implementieren Sie eine Scheme-Prozedur chi-endlich, die eine natürliche Zahl n und
eine Liste L nimmt und entweder #t oder #f zurückgibt, je nachdem ob <math>n \in L</math> oder
<math>n \notin L</math> gilt.
Stellen Sie für den Entwurf von chi-endlich die erforderlichen Hilfsprozeduren bereit.
==Lösung==
<code id="4d9419c7bee51">
(define (chi-endlich n ls)
(cond
[(null? ls) #f]
[(= n (car ls)) #t]
[else (chi-endlich n (cdr ls))]))</code>
<run id="4d9419c7beeb5">(chi-endlich 5 '(1 19 7 23 6 12))</run>
<run id="4d941ca1c4377">(chi-endlich 5 '(1 19 7 23 5 6 12))</run>
==Aufgabe==
Schreiben Sie eine Scheme-Prozedur, die die Menge der Quadratzahlen aufzählt.
==Lösung==
Man sagt <math>f</math> zählt <math>M</math> auf, wenn gilt:
<math>M \subseteq A^*</math><br>
<math>f</math> ist eine totale Funktion der Form <math>f: N \mapsto M</math><br>
<math>f</math> ist surjektiv und berechnbar und deren Wertebereich ist <math>M = {f(0), f(1), \dots}</math><br>
Dabei ist <math>M</math> die Menge der Quadratzahlen. Die Funktion <math>f</math> muss also eine surjektive Abbildung der natürlichen Zahlen <math>N</math> auf die Menge <math>M</math> vornehmen und berechenbar sein.
Dazu benötigen wir die sogenannte Aufzählfunktion <math>g</math> für die Menge der Quadratzahlen.
<code id="4d94429a0e930">
(define g
(lambda (n)
(* n n)))
</code>
<math>f(n) = \begin{cases}g(n), & \text{wenn } g(n) \in M \\4, & \text{sonst}\end{cases}</math>
Die Menge <math>M</math> erzeugen wir mit Hilfe von Streams.
<code id="4d94429a0e9ca" hidden>
(define stream-car car)
(define stream-cdr
(lambda (s)
(force (cdr s))))
(define-syntax stream-cons
(syntax-rules ()
((_ head tail) (cons head (delay tail)))))
(define stream?
(lambda (s)
(and (pair? s)(promise? (cdr s)))))
(define make-stream
(lambda (seed proc)
(letrec
((stream-builder
(lambda (n)
(stream-cons n (stream-builder (proc n))))))
(stream-builder seed))))
(define *the-end-of-stream-tag*
(make-stream
"eos"
(lambda (str) str)))
(define stream-item
(lambda (str k)
(if (= k 0)
(stream-car str)
(stream-item (stream-cdr str) (- k 1)))))
(define stream->list
(lambda (str n)
(if (<= n 0)
'()
(cons
(stream-car str)
(stream->list (stream-cdr str) (- n 1))))))
(define stream-map
(lambda (f s)
(stream-cons
(f (stream-car s))
(stream-map f (stream-cdr s)))))
(define print-stream
(lambda (stm n)
(cond
((<= n 0) (display "...\n"))
(else
(display (stream-car stm))
(display ", ")
(print-stream (stream-cdr stm) (- n 1))))))
(define nat-stream
(lambda (start)
(stream-cons start (nat-stream (+ start 1)))))
(define natzahlen (nat-stream 0))
</code>
<code id="4d94429a0ea50">
(define quad-stream (stream-map g natzahlen))
</code>
Damit können wir <math>f</math> wie folgt implementieren:
<code id="4d94429a0ead6">
(define f
(lambda (n)
(if (chi-endlich (g n) (stream->list quad-stream (+ n 1)))
(g n)
4)))
</code>
<run id="4d94429a0ec96">(f 5)</run>
<run id="4d94429a0ed53">(f 3.789)</run>
==Aufgabe==
Schreiben Sie eine Scheme-Prozedur, die die Menge der Quadratzahlen relativ zur Menge
der natürlichen Zahlen semi-entscheidet.
Hinweis: Implementieren Sie eine Prozedur für die (allgemeingültige) <math>\chi^'_M</math> und wenden
Sie sie auf die Menge (stream) der natürlichen Zahlen an. Überlegen Sie sich vor dem
Aufruf genau, welche Ausgabe Sie erwarten.
==Lösung==
<math>\chi^'_M</math>
<code id="4d942a31af109">
(define chi-strich
(lambda (w m)
(if (string=? w (stream-car m))
#t
(chi-strich w (stream-cdr m)))))
</code>
<code id="4d94429a0eb5a">
(define quad-stream2
(stream-map (lambda (i) (number->string i)) quad-stream))
(define natzahlen2
(stream-map (lambda (i) (number->string i)) natzahlen))
(define quadRelZuNat
(lambda (i)
(if (chi-strich (number->string i) quad-stream2)
#t
(if (chi-strich (number->string i) natzahlen2)
#f
'fehler))))
</code>
<run id="4d94429a0edd4">(quadRelZuNat 4)</run>
Vorsich: Der folgende Aufruf stoppt nicht!
<run id="4d94429a0ee78">(quadRelZuNat 5)</run>
Um <math>\text{quadRelZuNat}</math> stoppen zu lassen verwenden wir weiter oben definierte Prozeduren.
<code id="4d94429a0ebbd">
(define quadRelZuNat2
(lambda (i)
(if (chi-endlich i (stream->list quad-stream (+ i 1)))
#t
(if (chi-strich (number->string i) natzahlen2)
#f
'fehler))))
</code>
<run id="4d94429a0ef1d">(quadRelZuNat2 5)</run>