Gibt es eine Reihe von Programmiersprachenkonstrukten in einer Programmiersprache, damit diese als vollständig betrachtet werden können?
Nach allem , was ich aus Wikipedia entnehmen kann , muss die Sprache die Rekursion unterstützen oder anscheinend in der Lage sein, ohne anzuhalten. Ist das alles was es zu tun gibt?
Antworten:
Ich dachte immer , dass rekursive Funktionen genagelt. Hier ist, was den gesamten Satz von berechenbaren Funktionen definiert; es ist der kleinste Satz von Funktionen, die resp. geschlossen gegen:μ
Überprüfen Sie den obigen Link für Details; Sie sehen, dass dies zu einer sehr kompakten Programmiersprache führt. Es ist auch schrecklich zu programmieren - kein kostenloses Mittagessen. Wenn Sie eine davon fallen lassen, verlieren Sie die volle Kraft, sodass es sich um ein Minimum an Axiomen handelt.
Sie können diese wörtlich in grundlegende syntaktische Elemente für WHILE-Programme übersetzen , und zwar
0
_ + 1
x
_; _
for ( x to 0 ) do _ end
while ( x != 0 ) do _ end
quelle
while
Schleife in 6 mit der Konstanten Null verglichen wird, können Variablen nur durch Regel 2 inkrementiert werden, und es gibt keine negativen Konstanten, von denen aus zu beginnen ist (Regel 1). Diewhile
Schleife in 6 ist entweder nicht eingegeben (x = 0) oder unendlich ( x> 0, und der Schleifenkörper kann ihn nicht verringern._ - 1
und ich kann mir keinen Weg vorstellen, das ohne umzusetzenfor
. Danke, dass du das verstanden hast! (Was ist "besser" - einschließlich_ - 1
oderfor
? Hmm.)Ja, um als Turing vollständig eingestuft zu werden, muss eine Programmiersprache in der Lage sein, alle Berechnungen durchzuführen, die von einer Turing-Maschine durchgeführt werden können. Man könnte also sagen, als Mindestanforderung müssen Sie in der Lage sein, eine universelle Turing-Maschine - oder einen Interpreter für jede andere vollständige Turing-Sprache - darin zu implementieren.
Nein. Beispielsweise ist eine Sprache, in der die einzige zulässige Operation die Rekursion ist (dh die einzige mögliche Funktion, die Sie schreiben können, ist
f(x) = f(x)
, dass Turing nicht vollständig ist, da Sie nur Programme darin schreiben können, die niemals enden. Wie ich bereits sagte, eine Sprache, in der Turing vollständig ist muss in der Lage sein, jede Berechnung zu implementieren, die von einer Turing-Maschine ausgeführt werden kann.Außerdem muss eine Sprache keine Rekursion unterstützen, wie Sie denken. Nur eine uneingeschränkte Möglichkeit, Loops auszudrücken. Das kann eine Rekursion sein, aber auch eine while-Schleife oder ein goto. Eine Sprache, die überhaupt keine Funktionen hat, kann immer noch vollständig sein. Und wieder sind Schleifen oder rekursive Funktionen keine ausreichende Bedingung. Sie brauchen immer noch eine Möglichkeit, unterschiedlichen Code abhängig von einer Bedingung auszuführen und neue Werte aus alten zu berechnen (andernfalls wären alle Schleifen / Rekursionen entweder unendlich oder würden überhaupt nicht ausgeführt).
Ob es nur eine minimale Anzahl notwendiger und ausreichender Operationen gibt, so dass jede Sprache, die diese Operationen unterstützt, vollständig ist und jede Sprache, die dies nicht tut: Nein, gibt es nicht (es sei denn, Sie definieren "Operation" so vage , dass es bedeutungslos wird):
Wie ich bereits sagte, gibt es beispielsweise Turing-vollständige Sprachen, die keine rekursiven Funktionen (oder überhaupt keine Funktionen) unterstützen. Diese können immer noch vollständig sein, wenn sie eine
goto
Anweisung oderwhile
Schleife haben (und eine Möglichkeit, beliebige Datenmengen zu speichern). Eine Sprache mit rekursiven Funktionen muss jedoch weder vollständigwhile
nochgoto
vollständig sein.goto
Wäre also nicht in der Menge der notwendigen ausreichenden Operationen, aber es gibt Sprachen, die nicht mehr vollständig sind, wenn Sie entfernengoto
. Somit gibt es keine solche Menge.quelle
goto
, andere jedoch nicht, und behaupten anscheinend, dass dies nichtgoto
Teil einer Reihe von Operationen sein kann, die für die Turing-Vollständigkeit erforderlich sind , da einige es verwenden und andere nicht . Mein Punkt ist, dass diesgoto
einfach eine syntaktische Methode zum Implementieren einer bestimmten allgemeineren Operation ist, z. B. eines Sprungs. Wenn Sie sich einfach von bestimmten Kontrollstrukturen entfernen, nähern Sie sich meiner Meinung nach einer Reihe von Operationen, die zumindest auf die Vollständigkeit der Kontrolle hindeuten.Es gibt verschiedene Einzelanweisungen, die zur Erstellung vollständiger Sprachen führen. Das typische Beispiel ist "subtrahieren und verzweigen wenn Null". Diese sind im Zusammenhang mit der Assembler-Programmierung bekannt. Weitere Informationen finden Sie im Wikipedia-Artikel .
Dies führt zu einer Charakterisierung: Eine Sprache ist genau dann vollständig, wenn sie die Operationen des Abrufens und Speicherns von ganzen Zahlen im Speicher simulieren und die Operation "Subtrahieren und Verzweigen, wenn Null" ausführen kann.
quelle
Dies ist keine allgemeine Antwort auf Ihre Frage, aber nach dem strukturierten Programmiersatz ist nur die Fähigkeit erforderlich, eine Auswahl (z. B.
if
in C / C ++) und eine Wiederholung (z. B.while
in C / C ++) durchzuführen. Edit: Wie Dave Clarke in den Kommentaren hervorhob, erfordert das Theorem der strukturierten Programmierung auch eine Abfolge. Ich habe dies anfangs nicht aufgelistet, da ich davon ausgegangen bin, dass der Leser verstehen würde, dass grundlegende Blöcke anderer Anweisungen, wie diejenigen, die später zum Lesen und Schreiben in den Speicher usw. erwähnt wurden, ebenfalls erforderlich sind. Es ist natürlich besser, explizit zu sein; Sie müssen auch in der Lage sein, diese Dinge zu tun.Da beide über einen bedingten Sprungbefehl (z. B.
JNZ
in x86) implementiert werden können, reicht dies auch für die Turing-Äquivalenz aus.Beachten Sie, dass andere Dinge erforderlich sind, z. B. die Fähigkeit, eine unbegrenzte Anzahl von Symbolen (z. B. Bits ... 0 oder 1) in einen externen Speicher zu schreiben. In diesem Sinne entsprechen echte Computer nicht Turing, da keiner von ihnen unendlich viel Speicherplatz hat. Das Turing - Modell ist jedoch immer noch nützlich, da die Speicherkapazität in der Regel sehr groß ist und obwohl jedes Problem, das ein echter Computer lösen kann, durch einen deterministischen endlichen Automaten gelöst werden kann, ist die Verwendung dieses Berechnungsmodells nicht besonders nützlich (da das Anzahl der Staaten wäre absurd groß).
Beachten Sie, dass dies nicht unbedingt im Widerspruch zu der Antwort von sepp2k steht. Dies ist eine andere Art, über dieselbe Frage nachzudenken.
BEARBEITEN:
Beachten Sie auch, dass Sie nicht wirklich beide
if
undwhile
in C / C ++ benötigen . Sie können simulieren ,if
indem Siewhile
wie folgt vor :Der folgende Code ist immer äquivalent:
Nun ... die Konstruktion sollte funktionieren und möglich sein, wenn Sie vorsichtig sind. Beachten Sie auch, dass Sie bei rekursiven Funktionen eventuell auch eine Auswahl benötigen. Da rekursive Funktionen ohne Auswahl keine Basisfälle implementieren können, würde jede rekursive Funktion zu einer unendlichen Rekursion führen.
BEARBEITEN:
Bezüglich Ihrer Frage, ob die Fähigkeit, ein Programm zu schreiben, das nicht anhält, für Turing-Äquivalenz ausreicht, lautet die Antwort nein. es ist notwendig, aber nicht ausreichend. Wir können das Problem des Anhaltens für Programme lösen, die in einer Sprache geschrieben sind, die keine Programme ausdrücken kann, die nicht angehalten werden können. Die Antwort lautet "Das Programm hält an" für alle Instanzen. Wir können jedoch eine Sprache definieren, in der die Maschine aufgrund der einzigen Anweisung in eine Endlosschleife eintritt ... eine solche Sprache ist nicht Turing-äquivalent.
quelle
Die Kombinatoren und wobei und reichen aus, um einen (geschlossenen) Lambda-Term, also eine berechenbare Funktion, auszudrücken. Siehe diese Wikipedia-Seite für Details.K ( S x y z ) = ( x z ( y z ) ) ( K x y ) = xS K (S x y z)=(x z (y z)) (K x y)=x
Tatsächlich ist der Lambda-Term eine ausreichende Basis, um alle Lambda-Terme auszudrücken. Siehe später auf derselben Wikipedia-Seite .X=λx.((x S) K)
quelle
Die Sprachkonstrukte sind austauschbar
Es gibt keine festgelegten Mindestkriterien dafür, welche Konstrukte von einer Programmiersprache nativ bereitgestellt werden müssen. Wenn es einige seltsame Konstrukte gibt, die irgendwie verschlungen werden können, um ein Turing-vollständiges System auszudrücken, dann sind diese Konstrukte anscheinend "genauso geeignet" wie alle anderen.
Um dies zu beweisen - eine Sprache, die nur eine Operation "Subtrahieren und Verzweigen, wenn Null" bereitstellt, ist Turing abgeschlossen; Es gibt Turing vollständige Sprachen, die kein separates Konstrukt "substract und branch if zero" bieten, dh, es gibt kein Konstrukt oder eine Menge von Konstrukten, die obligatorisch sind.
Die Auswirkungen jedes TP-complete-Sprachkonstrukts können durch die Konstrukte jeder anderen TP-complete-Sprache nachgebildet werden.
quelle