Was sind die minimalen Sprachmerkmale / -strukturen, die Turing komplett machen?
Was sind die minimalen Sprachmerkmale / -strukturen, die Turing komplett machen?
Antworten:
Ein Turing-Tarpit ist eine Art esoterische Programmiersprache, die bestrebt ist, Turing-vollständig zu sein und dabei so wenig Elemente wie möglich zu verwenden. Brainfuck ist vielleicht das bekannteste Tarpit, aber es gibt viele.
Iota und Jot sind funktionale Sprachen mit zwei bzw. drei Symbolen, basierend auf der SK (I) -Kombinatorrechnung .
OISC ( One Instruction Set Computer ) bezeichnet eine Art von Imperativberechnung, für die nur ein Befehl eines oder mehrerer Argumente erforderlich ist, normalerweise "subtrahieren und verzweigen, wenn sie kleiner oder gleich Null sind" oder "umkehren, subtrahieren und überspringen, wenn sie ausleihen". Die x86-MMU setzt den bisherigen Befehl um und ist damit Turing-komplett.
Im Allgemeinen benötigt eine imperative Sprache Folgendes, um vollständig zu sein:
Eine Form der bedingten Wiederholung oder des bedingten Sprungs (z. B. while
, if
+ goto
)
Eine Möglichkeit zum Lesen und Schreiben einer Speicherform (z. B. Variablen, Band)
Damit eine Lambda-Kalkül- basierte funktionale Sprache TC ist, benötigt sie:
Die Fähigkeit, Funktionen über Argumente zu abstrahieren (z. B. Lambda-Abstraktion, Zitat)
Die Fähigkeit, Funktionen auf Argumente anzuwenden (zB Reduktion)
Es gibt natürlich auch andere Betrachtungsweisen für Berechnungen, aber dies sind gängige Modelle für Turing-Tarpits. Beachten Sie, dass echte Computer keine universellen Turing-Maschinen sind, da sie keinen unbegrenzten Speicher haben. Streng genommen handelt es sich um „gebundene Speichermaschinen“. Wenn Sie ihnen weiterhin Speicher hinzufügen, nähern sie sich asymptotisch den Turing-Maschinen mit Strom. Sogar begrenzte Speichermaschinen und endliche Zustandsmaschinen sind für die Berechnung nützlich. Sie sind einfach nicht universell .
Genau genommen ist I / O für die Vollständigkeit des Turing nicht erforderlich. TC behauptet nur , dass eine Sprache kann berechnen Sie die gewünschte Funktion, nicht , dass es zeigt Ihnen das Ergebnis. In der Praxis hat jede nützliche Sprache eine Möglichkeit, irgendwie mit der Welt zu interagieren.
Aus praktischer Sicht: Wenn Sie alle Programme in einer Turing-vollständigen Sprache in Ihre Sprache übersetzen können, muss Ihre Sprache (soweit ich weiß) Turing-vollständig sein. Wenn Sie überprüfen möchten, ob eine von Ihnen entworfene Sprache vollständig ist, können Sie einfach ein Brainf *** an den YourLanguage-Compiler schreiben und nachweisen / demonstrieren, dass es alle zulässigen BF-Programme kompilieren kann.
Zur Verdeutlichung meine ich, dass Sie zusätzlich zu einem Interpreter für YourLanguage einen Compiler (in einer beliebigen Sprache) schreiben, der jedes BF-Programm in YourLanguage kompilieren kann (natürlich unter Beibehaltung der gleichen Semantik).
</sarcasm>
Ein System kann nur dann als vollständig angesehen werden, wenn es alles kann, was eine universelle Turingmaschine kann. Da die universelle Turing-Maschine in der Lage sein soll, jede berechenbare Funktion innerhalb eines bestimmten Zeitraums zu lösen, können Turing-Komplettsysteme dies auch tun.
Um zu überprüfen, ob Turing vollständig ist, können Sie eine Turing-Maschine darin implementieren. Mit anderen Worten, überprüfen Sie, ob Folgendes simuliert werden kann:
Dies sind die tatsächlichen Mindestanforderungen an ein System, die als vollständig angesehen werden können. Nicht mehr, nicht weniger. Wenn es keines davon auf irgendeine Weise simulieren kann, ist es nicht vollständig. Die von anderen vorgeschlagenen Methoden sind nur Mittel zum Zweck, da es mehrere Turing-Komplettsysteme gibt, die diese Funktionen nicht bieten.
Beachten Sie, dass es keine bekannte Möglichkeit gibt, ein echtes Turing-Komplettsystem zu erstellen. Dies liegt daran, dass es keine Möglichkeit gibt, die Grenzenlosigkeit des Bandes der Turing-Maschine im physischen Raum wirklich zu simulieren.
Eine Programmiersprache ist vollständig, wenn Sie damit rechnen können. Es gibt nicht nur eine Reihe von Funktionen, die eine vollständige Sprachwiedergabe ermöglichen. Daher sind die Antworten, die besagen, dass Sie Schleifen benötigen oder dass Sie Variablen benötigen, falsch, da es Sprachen gibt, die weder eine noch eine vollständige Sprachwiedergabe haben .
Alan Turing hat die Universal-Turing-Maschine entwickelt. Wenn Sie ein Programm übersetzen können, das für die Ausführung auf der Universal-Maschine entwickelt wurde, ist auch Turing vollständig. Dies funktioniert auch indirekt, so dass Sie sagen können, dass die Sprache X vollständig ist, wenn alle Programme für die vollständige Sprache Y für X übersetzt werden können, da alle universellen Turing-Maschinenprogramme in ein Y-Programm übersetzt werden können.
Die zeitliche Komplexität, die räumliche Komplexität, das einfache Eingabe- / Ausgabeformat und das einfache Schreiben von Programmen sind nicht in der Gleichung enthalten, sodass eine solche Maschine theoretisch alle Berechnungen durchführen kann, wenn die Berechnungen nicht durch Leistungsverlust oder durch die Sonne verschluckte Erde gestoppt werden.
Um die Vollständigkeit der Sprache zu beweisen, wird normalerweise ein Dolmetscher für jede nachweislich vollständige Sprache erstellt. Damit dies funktioniert, sind jedoch Ein- und Ausgabemethoden erforderlich, zwei Dinge, die für eine vollständige Sprache eigentlich nicht erforderlich sind. Es ist ausreichend, dass Ihr Programm seinen Status beim Start ändern kann und dass Sie den Speicher nach dem Anhalten des Programms überprüfen können.
Um eine erfolgreiche Sprache zu erstellen, muss sie jedoch mehr als nur vollständig sein. Dies gilt auch für Tarpits. Ich glaube nicht, dass BrainFuck ohne ,
und populär gewesen wäre .
.
Sie können nicht sagen, ob es eine Endlosschleife ausführt oder aufhört.
Erklärung: Bei einigen Eingaben ist es unmöglich in jedem Fall (mit einer anderen Turing-Maschine) zu sagen, ob das Ding eine Endlosschleife durchläuft oder irgendwann anhält, es sei denn, Sie führen es aus (was Ihnen eine Antwort gibt, wenn es anhält, aber nicht wenn es schleifen!).
Das bedeutet, dass Sie in der Lage sein müssen, eine möglicherweise unbegrenzte Menge an Daten zu speichern - es muss ein Äquivalent zum unendlichen Band geben, egal wie verworren! (Andernfalls gibt es nur eine begrenzte Anzahl von Zuständen, und Sie können dann überprüfen, ob Sie diesen Zustand zuvor durchlaufen haben, und schließlich aufhören). Im Allgemeinen können Turing-Maschinen die Größe ihres Zustands durch kontrollierbare Mittel vergrößern oder verkleinern.
Da die ursprüngliche Universal-Turing-Maschine von Turing ein unlösbares Anhalteproblem hat, muss auch Ihre eigene Turing-Komplettmaschine ein unlösbares Anhalteproblem haben.
Turing-Komplettsysteme können jedes andere Turing-Komplettsystem emulieren. Wenn Sie also einen Emulator für ein bekanntes Turing-Komplettsystem in Ihrem System erstellen können, beweist dies, dass Ihr System auch Turing-Komplettsystem ist.
Angenommen, Sie möchten beweisen, dass Snakes & Ladders vollständig ist, wenn Sie ein Brett mit einem sich unendlich wiederholenden Gittermuster (mit einer anderen Version oben und links) verwenden. Wenn Sie wissen, dass die Minsky-Maschine mit 2 Zählern vollständig ist (mit 2 unbegrenzten Zählern und 1 Zustand aus einer endlichen Zahl), können Sie eine entsprechende Karte konstruieren, bei der die X- und Y-Position auf dem Gitter der aktuelle Wert der 2 Zähler ist und der aktuelle Pfad ist der aktuelle Zustand. Knall! Sie haben gerade bewiesen, dass Snakes & Ladders Turing vollständig sind.
Eine notwendige Bedingung ist eine Schleife mit einer maximalen Iterationszahl, die nicht vor der Iteration bestimmt wird, oder eine Rekursion, bei der die maximale Rekursionstiefe nicht vor der Iteration bestimmt wird. Zum Beispiel reichen für ... in ... -Loops, wie Sie sie in vielen neueren Sprachen finden, nicht aus, um die Sprache vollständig zu machen (aber sie haben andere Mittel). Beachten Sie, dass dies nicht eine begrenzte Anzahl von Iterationen oder eine begrenzte Rekursionstiefe bedeutet, sondern dass die maximale Iteration und Rekursionstiefe im Voraus berechnet werden muss.
Beispielsweise kann die Ackermann-Funktion ohne diese Merkmale nicht in einer Sprache berechnet werden. Andererseits kann eine Menge hochkomplexer und sehr nützlicher Software geschrieben werden, ohne dass diese Funktionen erforderlich sind.
Andererseits kann mit jeder Iterationszahl und jeder vorausberechneten Rekursionstiefe nicht nur entschieden werden, ob ein Programm anhält oder nicht, sondern es wird anhalten.
Ich weiß, dass dies nicht die formal korrekte Antwort ist, aber wenn Sie das 'Minimum' aus 'Turing-complete' herausnehmen und 'Practical' wieder dorthin setzen, wo es hingehört, werden Sie die wichtigsten Merkmale erkennen, die eine Programmiersprache von einer unterscheiden Auszeichnungssprache sind
als nächstes kommen
Um diese Behauptungen zu testen, beginnen Sie mit einer Auszeichnungssprache, z. B. HTML. wir könnten ein HTML + nur mit Variablen oder nur mit Bedingungen erfinden (MS tat dies mit bedingten Kommentaren), oder eine Art Schleifenkonstrukt (das ohne Bedingungen wahrscheinlich so etwas wie enden würde <repeat n='4'>...</repeat>
). Wenn Sie einen dieser Schritte ausführen, wird HTML + erheblich leistungsfähiger als normales HTML, aber es ist dennoch eher ein Markup als eine Programmiersprache. Mit jedem neuen Feature machen Sie es weniger zu einer deklarativen als zu einer imperativen Sprache.
Das Streben nach Minimalität in Logik und Programmierung ist sicher wichtig und interessant, aber wenn ich n00bies Jung oder Alt beibringen müsste, was Programmieren ist und wie man Programmieren lernt, würde ich kaum mit der vollen Breite und Breite anfangen der theoretischen Grundlagen der Turing-Vollständigkeit. Die ganze Essenz des Kochens und Programmierens besteht darin, Dinge in der richtigen Reihenfolge zu tun und sie zu wiederholen, bis sie fertig sind, so wie es deine Mutter getan hat. das fasst es für mich zusammen.
Andererseits habe ich mein CS nie beendet.