BuK/IIm10/BuK-Kreativaufgabe11 G1

Aus ProgrammingWiki

Wiki-Quelltext dieser Seite.

<language>Scheme</language>
<language>Scheme</language>
= Gödelisierung und µ-rekursive Funktionen =
== Aufgabe ==
Sei <math>h: S^{*} \rightarrow N_{0}</math> eine Gödelisierung von <math>S^{*}</math>, d.h. <math>h</math> ist injektiv, total und berechenbar. <math>h(S*)</math> ist entscheidbar und <math>h^{-1} : h(S^{*}) \rightarrow S^{*}</math> ist berechenbar.

Dann können die Wörter aus <math>S^{*}</math> vermöge <math>h</math> gödelgeordnet werden, so dass <math>w_{i} \prec w_{j} \Leftrightarrow h(w_{i}) < h(w_{j})</math>, für alle <math>w_{i},w_{j} \in S^{*}</math> und <math>w_{i} \neq w_{j}</math>.

Die folgende µ-rekursive Funktion liefert die Folge der Gödelnummern <math>h(w_{0}), h(w_{1}), . . . </math> in aufsteigender Form.

<math>g(1) = \mu f(n, i) = \begin{cases}
  \text{das kleinste } n \in N_{0}, \text{ mit } 1- p(0, n) = 0 & , \text{wenn}\\
  & \text{(1) so ein n existiert und}\\
  & \text{(2) }1-p(0,m) \text{ f\"ur alle } m <= n \text{ definiert ist} \\

  \text{undefiniert} & , \text{sonst}
\end{cases}</math>

Für <math>i \geq 1</math> gilt:

<math>g(i + 1) = \mu f(n, i) = \begin{cases}
  \text{das kleinste }n \in N_{0} \text{, mit }1 - p(g(i) + 1, n) = 0 &\text{, wenn} \\
   & \text{(1) so ein }n\text{ existiert und}\\
   & \text{(2) }1 - p(g(i) + 1,m)\text{ f\"ur alle }m \leq n\text{ definiert ist}\\
  \text{undefiniert} &\text{, sonst}\\
\end{cases}</math>

Die zur Definition von <math>g</math> verwendete zahlentheoretische Funktion <math>p</math> ist

<math>p(r, y) =\begin{cases}
  1 & \text{, wenn }y \geq r\text{ und }y\text{ ist G\"odelnummer}\\
  0 & \text{, sonst}
\end{cases}</math>

Illustrieren Sie die folgenden Aussagen durch den Einsatz selbst entwickelter Scheme-
Prozeduren. Wählen Sie exemplarisch <math> S = {a, b}</math> und die Verschlüsselung im 3er-System,
mit <math>a \rightarrow 1,  b \rightarrow 2</math> als Gödelisierung h mit <math>h(w) =
\Sigma ^{\|w\|-1}_{i=0} a_{i}*3^{i}</math> mit <math>a_{i} \in \{1,2\}</math>. Das Wort
aba erhält dann die Gödelnummer <math>h(aba) = 1*3^{2}+2*3^{1}+1*3^{0} = 16</math>. Nicht jede natürliche
Zahl ist Gödelnummer eines Wortes aus <math>S^{*}</math>: Beispielsweise ist <math>10 = 1 * 3^{2} + 0 * 3^{1} + 1 * 3^{0}</math>
keine.

<math> p: N_{0} \times N_{0} \rightarrow \{0,1\}</math> ist ein total berechenbares Prädikat. (Hinweis: Hierzu benötigen Sie eine Scheme-Prozedur für ein total berechenbares Prädikat, das feststellt, ob eine gegebene Zahl y Gödelnummer ist, d.h. y muss in der Form <math> \Sigma ^{n}_{i=0} a^{i}*3^{i}</math> mit <math>a_{i} \in \{1,2\}</math> darstellbar sein.)

<math>g: N \rightarrow N_{0}</math> wächst streng monoton und ist total. (Hinweis: Verwenden Sie eine Scheme-Prozedur zur Berechnung der ersten 10 Gödelnummern.)

Mit Hilfe der Funktion <math>k : N \rightarrow S^{*}, k(n) = h^{-1}(g(n))</math> kann man das <math>n</math>-te Wort in der gödelgeordneten Folge der Wörter aus <math>S^{*}</math> bestimmen. <math>k</math> ist total und injektiv. Die zugehörige Umkehrfunktion <math>k^{-1} : S^{*}  \rightarrow N</math> liefert somit auch wieder die Gödelisierung mit <math>k^{-1}(w_{n}) = h(n)</math>.



== Lösung ==
Die Lösung für die Funktion <math>h</math> lautet:
<code>
(define h (lambda (s)
  (letrec
    ((h-rekursiv (lambda (lst i gdlnummer)
      (cond
        ((equal? lst '()) gdlnummer)
         ((equal? (car lst) #\a) (h-rekursiv (cdr lst) (+ i 1) (+ gdlnummer (* 1 (expt 3 i)))))
         ((equal? (car lst) #\b) (h-rekursiv (cdr lst) (+ i 1) (+ gdlnummer (* 2 (expt 3 i)))))))))
      
  (h-rekursiv (string->list s) 0 0))))</code>
<run>(h "abbababba")</run>

Die Umkehrung der Funktion <math>h</math>, also <math>h^{-1}</math>, lautet:
<code>
(define hinvers (lambda (i)
  (letrec
    ((hinvershelp (lambda (i lst)
      (let ((num (floor (/ i 3))) (mod (modulo i 3)))
        (cond 
          ((and (= 0 num) (= 0 mod)) lst)
           ((= 1 mod) (hinvershelp num (cons #\a lst)))
           ((= 2 mod) (hinvershelp num (cons #\b lst))))))))
  (list->string (reverse (hinvershelp i '()))))))
</code>
<run>(hinvers 12850)</run>

Um heruaszufinden ob eine Zahl eine gültige Gödelnummer zu dem gegebenen System ist, kann die Funktion <math>h?</math> verwendet werden:
<code>
(define h? (lambda (n)
  (cond
    ((< n 3) #t)
     ((= 0 (modulo n 3)) #f)
     (else (h? (floor (/ n 3)))))))
</code>
<run>
(h? 12850)
</run>
<run>
(h? 14304)
</run>

Lösung für Funktion <math>g</math>
<code>
(define g (lambda (n)
  (letrec
    ((g-rekursiv (lambda (s i) 
       (if (p s i) i (g-rekursiv s (+ 1 i))))))
     (if (= n 1) (g-rekursiv 0 1) 
         (let ((n_p (+ 1 (g (- n 1))))) (g-rekursiv n_p n_p))))))
</code>
<run>

</run>

die zahlentheoretische Funktion <math>p</math>, ist nur eine Erweiterung von h? mit der zusätzlichen Bedingung, dass y größer gleich r sein muss:
<code>
(define p (lambda (r y)
  (cond
    ((and (>= y r) (h? y)) #t)
    (else #f))))
</code>
<run>
(p 8 14)
</run>
<run>
(p 7 9)
</run>

Funktion <math>k</math> muss nicht extra implementiert werden, da diese aus <math>h^{-1}</math>(also hinvers) und <math>g(n)</math> besteht:
<run>
(hinvers (g 7))
</run>

In Scheme sieht die Funktion <math>k^{-1}</math> so aus:
<code>
(define kinvers
  (lambda (wort)
    (letrec 
      ((kinvershelp (lambda (temp gVonN i)
         (cond
            ((= temp i) gVonN)
             ((h? i) (kinvershelp temp (+ 1 gVonN) (+ 1 i)))
             (else (kinvershelp temp gVonN (+ 1 i)))))))
      (kinvershelp (h wort) 0 0))))
</code>
<run>
(kinvers "abbababba")
</run>