Berechenbarkeitstheorie/Sätze und Zusammenhänge
Aus ProgrammingWiki
Wiki-Quelltext dieser Seite.
<language>Scheme</language>
<code id="4f79e5b49a28a" hidden>
(define start-timer #f)
(define stop-timer #f)
(define decrement-timer #f)
(let ([clock 0] [handler #f])
(set! start-timer
(lambda (ticks new-handler)
(set! handler new-handler)
(set! clock ticks)))
(set! stop-timer
(lambda ()
(let ([time-left clock])
(set! clock 0)
time-left)))
(set! decrement-timer
(lambda ()
(when (> clock 0)
(set! clock (- clock 1))
(when (= clock 0) (handler))))))
(define-syntax timed-lambda
(syntax-rules ()
((_ formals exp1 exp2 ...)
(lambda formals (decrement-timer) exp1 exp2 ...))))
(define-syntax time-ltd-task
(syntax-rules ()
((_ task ticks)
(let ((in-time #t))
(start-timer ticks (lambda () (set! in-time #f)))
(let ((res task))
(if in-time res "expired"))))))
;;; STREAMS - Implementation mit verzoegerter Evaluation (delay, force)
;; Selektoren
(define stream-car
(lambda (s)
(car (force s))))
(define stream-cdr
(lambda (s)
(cdr (force s))))
;; Konstruktoren
(define-syntax stream-cons
(syntax-rules ()
((_ x str) (delay (cons x str)))))
(define make-stream
(lambda (seed proc)
(letrec
((stream-builder
(lambda (n)
(delay (cons n (stream-builder (proc n)))))))
(stream-builder seed))))
;; Operationen mit streams
(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 str)
(delay
(cons
(f (stream-car str))
(stream-map f (stream-cdr str))))))
(define print-stream
(lambda (str items)
(if (<= items 0)
(begin
(display "...")(newline))
(begin
(write (stream-car str))
(display ", ")
(print-stream (stream-cdr str)(- items 1))))))
; nat_zahlen
; (display (stream->list nat_zahlen 20))
; nat_zahlen
; (display (stream->list (stream-map (lambda (i) (* 10 i)) nat_zahlen) 10))
;; --- Ende streams ---
;;; Aufzaehlbare Mengen
(define nat_zahlen (make-stream 0 (lambda (n) (+ n 1))))
(define menge-bis print-stream) ; angepasster Prozedurnamen
(define generiere_aufzaehlbare_menge
(lambda (f)
(stream-map f nat_zahlen)))
(define generiere_aufzaehlbare_wortmenge
(lambda (f)
(stream-map number->string (stream-map f nat_zahlen))))
</code>
==Aufzählbarkeit und Semi-Entscheidbarkeit==
...
Zur Implementierung der Ideen dieses Beweises benötigen wir ein Konzept der zeitlich beschränkten Berechnung: Beim Start einer Berechnungsaufgabe wird eine gewisse Anzahl von Ticks angegeben. Ist die betreffende Berechnung in dieser Zeit abgeschlossen, wird deren Ergebis zurück gegeben, anderenfalls "expired".
<code id="4f79e5b49a3a6" hidden>
(define fib
(timed-lambda (n) ; note the timed-lambda definition for decrement-timer invocations
(cond
((= n 0) 0)
((= n 1) 1)
(else
(+ (fib (- n 1)) (fib (- n 2)))))))
(define find-minimal-amount-of-time
(lambda (ticks)
(if (equal? (time-ltd-task (fib 10) ticks) "expired")
(find-minimal-amount-of-time (+ ticks 1))
ticks)))
</code>
<run id="4f79e5b49a5b4">
(time-ltd-task (fib 10) 200)
</run>
Verändern Sie die Zahl der Ticks, die zur Berechnung von <tt>(fib 10)</tt> zur Verfügung stehen, zu 150. Diese Zeit ist zu kurz, um das Ergebnis zu ermitteln.
Man kann das minimal erforderliche Zeitlimit (in Ticks) zur Berechnung von <tt>(fib 10)</tt> experimentell ermitteln. Bequemer ist der folgende Aufruf, der die gesuchte Anzahl ausgibt. Aufgrund der hier gewählten (unsichtbaren) Implementierung des Timer-Systems sind die Anzahl der erforderlichen Ticks Rechner- und Netz-unabhängig.
<run id="4f79e5b49a638">
(find-minimal-amount-of-time 1) ; mindestens 1
</run>
Im Gegensatz zu dem weiterhebenden Konzept der engines wird der Rest einer Berechnung im Falle nicht ausreichender Zeit nicht aufgehoben. Das ist für unsere Vorhaben hier auch nicht nötig.
==Abzählbarkeit und Aufzählbarkeit==
Paarungsfunktionen usw.
==Entscheidbarkeit und Aufzählbarkeit==
Satz: Eine Menge $M$, mit $M\subseteq A^*$, ist ''entscheidbar'' genau dann, wenn $M$ '''und''' $A^*\setminus M$ (Komplementmenge) ''aufzählbare'' Menge sind.
Wir wollen den Beweis des Teils "Wenn $M$ und $A^*\setminus M$ aufzählbare Mengen sind, dann ist $M$ eine entscheidbare Menge." mit einem ausführbaren Beispiel illustrieren.
<code id="4f7842e667e5b" hidden>
(define f
(lambda (n)
(number->string (+ (* 2 n) 1))))
(define g
(lambda (n)
(number->string (* 2 n))))
(define chi_M
(lambda (w)
(letrec
((helper
(lambda (i)
(cond
((string=? (f i) w) #t)
((string=? (g i) w) #f)
(else
(helper (+ i 1)))))))
(helper 0))))
</code>
Wir wählen für $f$ die Aufzählprozedur für die ungeraden Zahlen und für $g$ die Aufzählprozedur für die geraden Zahlen. Damit erzeugen wir die betrachteten Mengen $M$ und $A^*\setminus M$.
<code id="4f7842e667ec5">
(define M (generiere_aufzaehlbare_menge f))
(define A*-M (generiere_aufzaehlbare_menge g))
</code>
Von beiden Mengen schauen wir uns jeweils 10 Elemente an.
<run id="4f7842e667f39">
(menge-bis M 10)
(menge-bis A*-M 10)
</run>
Wie man sieht, haben wir es mit Mengen von Zahlwörtern zu tun.
Die Prozedure für $\chi_M$ wurde so konstruiert, wie im Beweis angegeben. Erproben Sie selbst einige Aufrufbeispiele mit selbstgewählten Wörtern aus $A^*$, also Wörtern natürlicher Zahlen.
<run id="4f7842e667f93">
(chi_M "9199")
</run>