Gibt es Mindestkriterien für die Vollständigkeit einer Programmiersprache?


55

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?


6
Vielleicht sollte Ihre Frage lauten: "Gibt es eine minimale Anzahl von Programmierkonstrukten ...?", Da die Antwort lautete: "Alle berechenbaren."
Dave Clarke


@ DaveClarke, danke, ich habe das aktualisiert. Ich finde, dass Ihr Kommentar die Frage etwas aufwirft, obwohl ich davon ausgehe, dass meine Sprache schlecht ist. Ich wollte fragen, ob es einige Operationen gibt, die, wenn eine Sprache berechnet werden könnte, äquivalent wären.
Khanzor

Antworten:


45

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:μ

  1. Die konstante Funktion0
  2. Die Nachfolgerfunktion
  3. Parameter auswählen
  4. Funktionsaufbau
  5. Primitive Rekursion
  6. Der -Operator (suche das kleinste so dass ...)xμx

Ü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

  1. Die Konstante 0
  2. Inkrementierung _ + 1
  3. Variabler Zugriff x
  4. Programm- / Anweisungsverkettung _; _
  5. Countdown-Schleifen for ( x to 0 ) do _ end
  6. While-Schleifen while ( x != 0 ) do _ end

1
Ich denke, es ist offensichtlich, dass Sie die 5. Regel in der Sprache nicht fallen lassen können . Da die whileSchleife 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). Die whileSchleife in 6 ist entweder nicht eingegeben (x = 0) oder unendlich ( x> 0, und der Schleifenkörper kann ihn nicht verringern.
MSalters

1
@MSalters Ich denke du hast recht; Für die Simulation, die ich anscheinend im Sinn hatte, brauchen wir _ - 1und ich kann mir keinen Weg vorstellen, das ohne umzusetzen for. Danke, dass du das verstanden hast! (Was ist "besser" - einschließlich _ - 1oder for? Hmm.)
Raphael

20

Gibt es eine Reihe von Berechnungen, die in einer Programmiersprache ausgeführt werden müssen, damit sie als vollständig angesehen werden können?

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.

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?

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 gotoAnweisung oder whileSchleife haben (und eine Möglichkeit, beliebige Datenmengen zu speichern). Eine Sprache mit rekursiven Funktionen muss jedoch weder vollständig whilenoch gotovollständig sein. gotoWäre also nicht in der Menge der notwendigen ausreichenden Operationen, aber es gibt Sprachen, die nicht mehr vollständig sind, wenn Sie entfernen goto. Somit gibt es keine solche Menge.


Der einzige Teil, bei dem ich nicht sicher bin, ist Ihre Antwort auf die minimalen erforderlichen Operationen. Sie scheinen Ihre Definition von Operationen auf Kontrollstrukturen zu beschränken, die einen viel engeren Geltungsbereich als gewünscht zu haben scheinen und über Ihre eigenen Anforderungen hinaus, sie nicht "so vage zu definieren, dass [sie] bedeutungslos werden".
Joshua Drake

@ JoshuaDrake Ich bin nicht sicher, was du meinst. Ich beschränke Operationen nicht auf Kontrollstrukturen. Es ist nur so, dass ich in meinem Counter-Beispiel nicht über Operationen spreche, die keine Kontrollstrukturen sind, weil sie für das Beispiel nicht relevant sind. Eigentlich nenne ich "eine Möglichkeit, beliebige Datenmengen zu speichern" - das ist kaum eine Kontrollstruktur.
2.

Sie weisen darauf hin, dass einige Sprachen Turing-Vollständigkeit unterstützen goto, andere jedoch nicht, und behaupten anscheinend, dass dies nicht gotoTeil 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 dies gotoeinfach 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.
Joshua Drake

@JoshuaDrake Ich glaube nicht, dass die Verwendung von "jump" anstelle von "goto" uns an den Punkt bringt, an dem wir eine ausreichende und notwendige Menge an Operationen definieren können. Es ist wahrscheinlich richtig, dass jede Sprache eine Art Sprungoperation benötigt (und wenn es sich nur um Funktionsaufrufe handelt), aber ich glaube nicht, dass Sie in der Lage sind, weitere Operationen zu finden, um dies zu erreichen. Zum Beispiel hat die Lambda-Rechnung zwei Operationen: Anwendung (dh unsere Sprungoperation) und Abstraktion (dh das Erzeugen von Funktionen) ...
sepp2k

1
@JoshuaDrake Ich glaube nicht, dass der Artikel behauptet, dass jede Turing-vollständige Sprache diese Operationen haben muss. Zumal es diese Aussage ausdrücklich auf prozedurale Sprachen beschränkt. Abgesehen von einer Form von goto (dh Funktionsanwendung) hat der Lambda-Kalkül nichts davon. Ich denke, "Minimum" bedeutet hier nur, dass Sie in einer Sprache, die nur diese Funktionen enthält, keine von ihnen entfernen können, ohne die Vollständigkeit von Turing zu verlieren. Nicht, dass es keinen anderen minimalen Satz von Operationen gibt, der ebenfalls ausreicht, um die Vollständigkeit zu gewährleisten.
SEPP2K

14

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.


13

Dies ist keine allgemeine Antwort auf Ihre Frage, aber nach dem strukturierten Programmiersatz ist nur die Fähigkeit erforderlich, eine Auswahl (z. B. ifin C / C ++) und eine Wiederholung (z. B. whilein 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. JNZin 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 ifund whilein C / C ++ benötigen . Sie können simulieren , ifindem Sie whilewie folgt vor :

bool C;
// some code that sets C
if(C) { /* some other code /* }
// rest of the program

Der folgende Code ist immer äquivalent:

bool C;
// some code that sets C
bool C2 = C;
while(C2) { /* some other code /* C2 = false; }
// rest of the program

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.


13

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 ) = xSK(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)


5

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.