Manuals

 Brainfuck
 Turing 2bit

Die Turing-Maschine (einfaches Alphabet)

Über den ersten Computer der Welt wird viel gestritten. Die einen meinen es ist der Abakus, der bereits 1000 Jahre v. Chr. verwendet wurde um Handelsgeschäfte im mittleren Osten zu erleichtern, oder es wäre Konrad Zuses Z1 die ein Opfer des zweiten Weltkrieges wurde bevor sie fertig gestellt werden konnte. Andere glauben der Erfinder des ersten Computers wäre Alan Turing mit seiner Arbeit im Bletchley Park, ebenfalls während des zweiten Weltkrieges. Er und sein Team aus weiteren namhaften Mathematikern bauten die Collosus-Maschine um den Enigma Code zu entschlüsseln - was ihnen auch gelang, und nach einheliger Meinung, die Wende im zweiten Weltkrieg, zu Gunsten der Alliierten, herbei führten. Doch daß stimmt nicht ganz. Die Collosus-Maschine war einerseites genial und zuverlässig im Entschlüsseln des Enigma-Codes. Dieser Code wurde vom deutschen Oberkommando der Marine verwendet, die Aufträge und Positionen ihrer U-Boote verschlüsselt zu funken. Ein richtiger Computer war die Collosus nicht, sie kannte nur dieses Programm zum entschlüsseln des Codes. Vor der Collosus entwickelte Turing die Turing-Maschine mit der man jedes erdenkliche Mathematische Problem lösen könne - die Berechenbarkeitsmaschine. Und in der Theorie gelang es ihm - sie funktionierte bereits. Ihm kam jedoch der Krieg zuvor bevor er mit dem Bau beginnen konnte. Die Collosus ist eines der Werke an denen bereits Teile der Turing-Maschine verbaut wurden die Turing sich erdacht hatte. Der Bau der eigentlichen Turing-Maschine konnte nie vollendet werden da Alan an einigen Details scheiterte und sich 1954 das leben nahm.
Die Turing Maschine war in der Theorie der erste programmierbare Computer vor Konrad Zuses Z1. Im wesentliche besteht Sie aus einem Endlosband mit Einsen und Nullen die durch einen Lese- und Schreibkopf verändert werden können - eine Art Arbeitsspeicher. Das eigentlichen Programm ist aufgeteilt in Register. Diese Register sind durchnummeriert von 1 bis, wenn man will, unendlich.

Beispiel:

Arbeitsspeicher / Endlosband
...00011101111000...
Die Position des Lese/Schreibkopfs im Endlosbands ist fett dargestellt.

Register
1     2
				10R2  11L2  usw.
				01R2  01L3
Jedes Register besteht aus zwei Regeln zum Verhalten was geschehen soll wenn der Lesekopf entweder eine Eins oder eine Null liest. Im Beispiel steht im 1. Register, in der ersten Zeile was geschehen soll wenn der Lese/Schreibkopf eine 1 liest. Er soll dann auf diese Position im Endlosband eine 0 schreiben, dann nach rechts fahren und mit dem 2. Register fortfahren. Die zweite Zeile des 1. Registers beinhaltet das Verhalten bei einer 0. Es soll eine 1 auf diese Position geschrieben werden und den Lese/Schreibkopf nach Rechts verschieben. Danach mit dem 2. Register fortfahren.
Der Lese/Schreibkopf brauch sich in seiner Position nicht unbedingt in einer Richtung verschieben, er kann auf seiner gegenwärtigen Position mit dem Steuerzeichen S (Stopp) stehen bleiben. Der Anfang und das Ende eines Programms wird immer mit der ersten 1 im Endlosband begonnen und beendet. Da die Daten in einer Turing-Maschine, mit einfachem Alphabet, offensichtlich binär, also sprich mit nur zwei Zuständen dargestellt werden, müssen wir die Umrechnung von Hand erledigen. Eine drei wird z.B. durch drei hintereinander folgenden einsen dargestellt und abgeschlossen durch eine 0. Die darauf folgende vier wird wiederum mit vier aufeinander folgenden Einsen dargestellt, wiederum mit einer 0 abgeschlossen.
Aus diesem, zugegebenermaßen, simplen anwenden von Regeln auf Daten in einem Endlosband kann nunmehr jedes erdenkliche Programm ausgedacht werden. Eine Addition zum Beispiel das aus 111011110 uns 1111111100 errechnet. Also 3+4 = 7. Solch ein Programm würde folgendermaßen aussehen:

Arbeitsspeicher / Endlosband
...0001110111100000...

				Register
				1     2     3     4     5

				11R1  11R2  10L4  11L4  11S5
				01R2  00L3  00S3  00R5  00S5
Die Position des Lese/Schreibkopfs im Endlosbands ist wiederum fett dargestellt. Das aktive Register ist ebenfalls fett dargestellt. Das erste Register arbeitet sich vor bis zur zweiten Zahl im Endlosband und übergibt dann an das zweite Register und löscht die 0 die die zwei Zahlen getrennt hat.
...0001111111100000...

				1     2     3     4     5
				11R1  11R2  10L4  11L4  11S5
				01R2  00L3  00S3  00R5  00S5
Jetzt haben wir zwar aus zwei Zahlen eine gemacht, allerdings macht 3+4=8 keinen Sinn. Der restliche Code wird sich bis zur nächsten 0 vorarbeiten und dort die letzte eins der zweiten Zahl entfernen und sich wieder bis nach vorne zum Ausgangspunkt bewegen.

...0001111111100000...

				1     2     3     4     5
				11R1  11R2  10L4  11L4  11S5
				01R2  00L3  00S3  00R5  00S5
Im nächsten Schritt wird das Programm eine 0 im Endlosband vorfinden und den Lese/Schreibkopf nach Links auf die letzte 1 verschieben, dann mit Register 3 fortfahren.
...0001111111000000...

				1     2     3     4     5
				11R1  11R2  10L4  11L4  11S5
				01R2  00L3  00S3  00R5  00S5
Die letzte 1 der zweiten Zahl ist gefunden. Sie wird durch eine 0 ersetzt. Die zweite Zeile des Registers ist in diesem Fall unwichtig, da wir ja wissen das diese Zahl nur eine 1 sein kann, und somit nie ausgeführt wird. Deswegen enthält es den Platzhalter 00S3. Wenn 0 dann schreibe 0 und bleib bei Register 3. Bei Verwendung dieses Codes würde normalerweise das Programm sich in eine Endlosschleife stürzen aus der sie nie wieder heraus kommt. Die einfachste programmierbare Rechenmaschine der Welt würde sich >aufhängen<. Also das gab es auch schon 1937 wie 1995, 1998, 2000 usw.. Jedoch hatte Alan Turing dies voraus gesehen und dieses auf der Stelle treten ausgenutzt. Wiederholt sich dieses auf der Stelle treten von Register und Lese/Schreibkopf, so ist dies die Abbruchbedingung eines jeden Turing Programms, des einfachen Alphabets.
...0001111111000000...

				1     2     3     4     5
				11R1  11R2  10L4  11L4  11S5
				01R2  00L3  00S3  00R5  00S5
Das vierte Register sucht nun bis zur ersten 0 und übergibt dann an das fünfte Register das in der ersten Zeile wieder unseren bekannten Platzhalter enthält und beendet das Programm indem es am Ausgangspunkt auf der Stelle tritt.

Das Programm zum inkrementieren einer Zahl würde so aussehen.
...0001111111000000...

				1     2     3
				11R1  11L2  11S3
				01L2  00R3  00S3
Das Endlosband zeigt eine 7 aus der wir eine 8 machen wollen. Das erste Register sucht die letzte 0 der Zahl. Überschreibt diese mit 1 und gibt an das zweite Register weiter. Dieses geht ganz nach links zur ersten 0 und übergibt dann an Register 3. Dieses tritt auf der Stelle und erfüllt somit die Abbruchbedingung.
...00011111111000000...

				1     2     3
				11R1  11L2  11S3
				01L2  00R3  00S3
Das Programm ist beendet und hat die Zahl 7 um eins auf 8 inkrementiert. Das alles hat eigentlich nur das erste Register gemacht. Die letzten zwei Register waren nur zum einleiten der Abbruchbedingung notwendig.
Das nächste Programm ist nur gering komplexer und dekrementiert eine Zahl.
1     2     3     4
				11R1  10L3  11L3  11S4
				00L2  00S2  00S4  00S4
Auch in diesem Beispiel verrichten nur die ersten zwei Register effektiv Arbeit. Die letzten beiden Register leiten nur die Abbruchbedingung ein.
Ein um einiges komplexeres Programm ist die Multiplikation zweier Zahlen die die zuvor gezeigten Programme des Inkrementieren und Dekrementieren voraussetzt. Um eine Zahl zu multiplizieren bedienen wir uns eines Tricks der in diesem Buch noch öfters zur Anwendung kommt.
Die erste Zahl dient als Zähler während die zweite Zahl der Multiplikand ist. Wir addieren solange 6 mit dem letzten Ergebnis und dekrementieren bei jedem Schritt den Zähler bis dieser 0 erreicht hat.

a) Zähler 3, Ergebnis 0
b) Zähler 2, Ergebnis 6
c) Zähler 1, Ergebnis 12
d) Zähler 0, Ergebnis 18

In Pascal würde der Code so aussehen:
multiplikand := 6;
				repeat
				ergebnis := ergebnis + multiplikand;
				dec(zaehler);
				until zaehler = 0;
In Turing würde das ganze um einiges komplizierter aussehen was allerdings den Rahmen dieses Buches sprengen würde und auch nicht besonders interessant wäre im Kopf von einem Register ins nächste zu springen bis das Programm nach 387 Takten endlich zwei Zahlen miteinander multipliziert hat.
Das einfache Alphabet der Turing-Maschine ist auch eine sehr abgespeckte Version der eigentlichen Maschine die nicht nur mit Registern arbeitet, sondern auch mit States, in denen mehrere Register stehen können. Sie hat zudem noch ein größeres Alphabet in der a, b, c, x, y, z, $ und # darin vorkommen. Damit lässt sich, wie man sich vorstellen kann, so einiges mehr berechnen und lässt einen wirklich daran glauben das die Turing-Maschine Turing-Complete ist und man damit jedes erdenkliche mathematische Problem lösen kann.

von Thilo Hardt


hardtware Copyright 1998-2010, hardtware.de. All rights reserved.
Impressum Witze