Varianten des Turingmaschinen-Konzeptes I: Varianten der Programmstruktur Bedingte und iterative Anweisungen Bedingte Anweisungen Bedingte Anweisung = Testinstruktion + Operationsinstruktion (i, t, f, j) Interpretation: Falls im Programmzustand i der Test t positiv ausgeht, führe die Operation f aus und gehe in den Nachfolgezustand j (if-then-Anweisung). Programm aus bedingten Anweisungen Wir setzen über die zugrundegelegte Testmenge Test voraus: Test ist eindeutig: ∀s ∈ S ∃≤1t ∈ Test (t(s) = 1) Test ist vollständig: ∀s ∈ S ∃t ∈ Test (t(s) = 1) (Dies gilt offensichtlich für die Tests der Basis-Turingmaschinen.) (Deterministisches) Programm P = {Ii : i ≤ n} aus bedingten Anweisungen: Zu jedem Nicht-Stoppzustand i und zu jedem Test t gibt es genau eine mit i und t beginnende Instruktion (i, t, f, j) in P . Man kann zeigen, dass bei vollständigem und eindeutigem Testsatz und beim Vorhandensein einer neutralen Operation, übliche Programme und Programme mit bedingten Anweisungen äquivalente Konzepte sind. Bemerkung: Bei nichtvollständigen oder nichteindeutigen Testmengen arbeitet man i.a. mit bedingten Anweisungen vom if-then-else -Typ (i, t, f− , j− , f+ , j+ ) und fordert, dass es zu jedem Zustand i höchstens eine mit i beginnende Instruktion gibt. Bei Turingmaschinen besteht der Kern einer bedingte Anweisung aus 3 Komponenten: • Test • Druckbefehl • Bewegungsbefehl (i, a, a0, B, j) BEISPIEL: Das Verfahren zur Addition zweier Zahlen lässt sich mit einem Programm aus bedingten Anweisungen wie folgt beschreiben: Z 0 1 1 2 2 3 4 × Γ b 1 b 1 b 1 1 → Γ b 1 1 1 b b b × Bew R R L L R R S × Z 1 1 2 2 3 4 5 Wir haben hier das Programm in Tabellenform (Turing-Tafel) dargestellt, wobei die Zeilen den einzelnen Anweisungen entsprechen. Nicht benötigte Anweisungen wurden weggelassen (und sind als Endlosschleifen (i, a, a, S, i) hinzuzufügen). SATZ: Das Turingmaschinenkonzept und das Konzept der Turingmaschine mit bedingten Anweisungen sind äquivalent. D.h. zu jeder TM M = (B, P ) gibt es eine äquivalente TM M 0 = (B, P 0), deren Programm P 0 aus bedingten Anweisungen besteht, und umgekehrt. BEWEIS durch wechselseitige schrittweise Simulation. D.h. jeder Anweisung I der zu simulierenden Maschine M1 werden endlich viele Anweisungen I1, ..., Ik der simulierenden Maschine M2 so zugeordnet, dass die Ausführung von I durch Ausführung (einer Teilfolge) von I1, ..., Ik simuliert wird. P −→ P 0: (i, a, j) ∈ P −→ (i, a0, a, S, j) (für alle a0 ∈ Γ) (i, B, j) ∈ P −→ (i, a0, a0, B, j) (für alle a0 ∈ Γ) (i, ta, j, k) ∈ P −→ (i, a, a, S, k) & (i, a0, a0, S, j) (für alle a0 ∈ Γ \ {a}) P 0 −→ P : Idee: In jedem P 0-Zustand i finde (1) heraus, welcher Buchstabe a auf dem Arbeitsfeld steht, und (2) simuliere dann die Instruktion (i, a, a0, B, j). (Γ = {a0, ..., an}) ad (1): (i, ta0 , z(i, a0, −), z(i, a0, +)) (z(i, al , −), tal+1 , z(i, al+1, −), z(i, al+1, +)) (l = 0, ..., n − 1) ad (2): (z(i, a, +), a0, z(i, a, ×)) & (z(i, a, ×), B, j) Iterative Anweisungen (Schleifen) n-fache Iteration Iter(f, n) = f n einer Operation f : Iter(f, 0)(s) = f 0(s) = s Iter(f, n + 1)(s) = f n+1(s) = f (f n(s)) = f (Iter(f, n)(s)), Iteration von f nach einem Test t: Itert(f )(s) = f ns (s), wobei ns das kleinste n mit t(f n(s)) = 1 ist, falls solch ein n existiert und Itert(f )(s) ↑ andernfalls. D.h. f wird so oft ausgeführt, bis t erstmals positiv ist. Dabei wird vor jeder Ausführung von f getestet, ob t gilt. Ist t bereits zu Beginn positiv, wird also f nie ausgeführt. Turingoperatoren (TOs): Sei B eine Turing-Basismaschine mit Bandalphabet Γ und Speicher S = BI × Z. Die T uringoperatoren (TO) P : S → S über B sind induktiv wie folgt definiert: Ein Turigoperator P über einerTuring-Basismaschine B mit Bandalphabet Γ ist eine spezielle partielle Funktion P : S → S (d.h. eine möglicherweise nicht überall definierte Speichertransformation). (Speicher S = BI × Z) Die Turingoperatoren sind induktiv wie folgt definiert. (Die Definition hängt nur von Γ nicht von B ab. B wird erst benötigt, wenn wir die von einem TO P berechnete (partielle) Funktion definieren.) 1. R, L, S und alle a ∈ Γ sind Turingoperatoren (über B), wobei R(f, z) = (f, z + 1) & L(f, z) = (f, z − 1) & S(f, z) = (f, z) a(f, z) = (f(a,z) , z) (Die Turingoperatoren dieser Gruppe entsprechen gerade den elementaren Operationen.) 2. Sind P1 und P2 TOs, so auch P1 P2 , wobei P1 P2 (f, z) = P2 (P1 (f, z)) (Sprechweise: erst P1 , dann P2“) ” 3. Ist P ein TO und a ∈ Γ, so ist auch [P ]a ein TO, wobei [P ]a (f, z) = Iterta (P )(f, z). (Sprechweise: iteriere P so lange, bis a erstmals auf dem Arbeitsfeld ” steht“) Die von einem TO P über B = (Σ, T, Γ, n) berechnete partielle Funktion resP : (Σ∗)n → T∗: resP (w) ~ = out(P (in(w)) ~ BEISPIEL: Das in den vorhergehenden Beispielen beschriebene Vorgehen zur Addition zweier natürlicher Zahlen wird durch den Turingoperator P = R[R]b1[L]bRbRb beschrieben. BEISPIELE von TOs (Erläuterungen s. Skript): Rechtsoperatoren: Ra = [R]a und Raa = RaR[RaR]aL Linksoperatoren: La = [L]a und Laa = LaL[LaL]aR Kopieroperator: K = R0RbbR1L01R[0Rbb1L01R]b Löschoperator: Er = R[bR]b Transportoperator: T = R0L1RR1R0bR[0L1R1R0bR]bL1Lb SATZ. Jede von einem TO berechnete partielle zahlentheoretische Funktion lässt sich auch von einer TM berechnen. Da Ein/Ausgabe bei TOs und TMs gleich definiert ist, genügt es fologendes Lemma zu zeigen. LEMMA. Zu jedem TO P über B gibt es eine Turingmaschine M = (B, P 0) mit Startzustand αM und einzigem Stoppzustand ωM , sodass M die Startkonfiguration (αM , (f, z)) in die Stoppkonfiguration (ωM , P (f, z)) überführt, falls P (f, z) ↓, und sonst nicht terminiert. Beweis des Lemmas: Tafel Konservative Rechnungen Bei dem von uns gewählten Turingmaschinenmodell dürfen die Eingaben während der Rechnung im Speicher zerstört werden. Dies erweist sich als Nachteil, wenn man Maschinen, die auf dieselbe Eingabe zugreifen, hintereinanderschalten möchte. Bei konservativen Rechnungen vermeidet man dieses Problem, indem man verlangt, dass die Eingaben (sowie das Band links der Eingaben) erhalten bleiben und die Ausgabe (durch ein Blank getrennt) hinter die Eingaben geschrieben wird. Weiter werden alle Zwischenwerte gelöscht, d.h. am Ende der Rechnung steht lediglich die Ausgabe rechts der Eingaben. Wir präzisieren dieses Konzept hier für den Fall von Turingoperatoren zur Berechnung arithmetischer Funktionen. Der Turingoperator P über der Basismaschine T B(Σ1, Σ1, Γ, n) berechnet die partielle Funktion ϕ : Nn → N konservativ, falls für m ~ ∈ Db(ϕ) P (. . . v b m ~ b . . . ) = (. . . v b m ~ b ϕ (m) ~ b ...) ↑ ↑ und für m ~ 6∈ Db(ϕ) P (. . . v b m ~ b . . . )↑ . ↑ Man beachte, dass wir hier die Ausgabefunktion abweichend definieren: Am Ende der Rechnung steht der Kopf vor der ersten Eingabe, nicht vor der Ausgabe! Für Turingoperatoren sind das konservative Berechnungsmodell und das übliche Berechnungsmodell äquivalent. Wir zeigen hier zunächst nur eine (die einfache) Richtung. LEMMA. Jede von einem TO P konservativ berechnete n-stellige partielle zahlentheoretische Funktion ϕ : Nn → N lässt sich auch von einem TO P 0 (im üblichen Sinn) berechnen. BEWEIS. P 0 arbeitet wie P , muss lediglich am Ende der Rechnung von P das Arbeitsfeld hinter die Eingaben vor das Ausgabewort verlegen, um die unterschiedlichen Ausgabefunktionen anzupassen: P 0 = P RbbLLb.