Es ist bekannt, dass eine Maschine mit einem einzelnen Stapel als nur unbegrenztem Speicher nicht vollständig ist, wenn sie nur von der Oberseite des Stapels lesen kann. Ich möchte eine Maschine, die (etwas) leistungsfähiger als eine Stapelmaschine ist, aber immer noch nicht vollständig ist. (Ich frage mich, ob es eine nicht-Turing-vollständige Maschine gibt, die nicht deterministische Pushdown-Automaten mit einer einzigen polynomiellen Verlangsamung deterministisch simulieren kann.) Die harmloseste (unkomplizierte) Erweiterung, die mir in den Sinn kam, war eine (einzelne) Vorwärtsbewegung Iterator lesen.
Lassen Sie mich die Implementierungsdetails näher erläutern, um zu verdeutlichen, was ich unter einem Forward-Read-Iterator verstehe. Eine einfach verknüpfte Liste kann zum Implementieren eines Stapels verwendet werden. Lassen Sie die Liste durch einen Zeiger implementiert werden pTop
, der entweder Null ist oder auf einen SList
Knoten zeigt. Ein SList
Knoten besteht aus einem Nutzlastfeld value
und einem Zeigerfeld pNext
, wobei pNext
entweder Null ist oder auf einen SList
Knoten zeigt. Lassen Sie den Vorwärtslese-Iterator durch einen Zeiger implementiert werden pRead
, der entweder Null ist oder auf einen SList
Knoten zeigt. Die Zeiger pTop
und pRead
können nicht direkt aufgerufen werden, sondern können nur über die folgenden Methoden verwendet werden:
Push(val)
Erstellt einen neuenSList
Knotenn
mitn.value = val
undn.pNext = pTop
und setztpTop = &n
.Pop()
bricht ab, wennpTop == 0
oderpRead == pTop
. Andernfalls liestval = pTop->value
undpTopNext = pTop->pNext
gibt es denSList
Knoten frei, auf den es zeigtpTop
, setztpTop = pTopNext
und gibt ihn zurückval
.ReadBegin()
setztpRead = pTop
.ReadNext()
bricht ab wennpRead == 0
. Andernfalls liestval = pRead->value
, setztpRead = pRead->pNext
und kehrt es zurückval
.ReadFinished()
gibttrue
ifpRead == 0
undfalse
andernfalls zurück.
quelle
pTop == 0
undpRead == 0
. Eine Methode,ReadCancel()
die setzt,pRead = 0
könnte auch eine gute Idee sein, da sonst der Abbruch vonPop()
forpRead == pTop
ärgerlich sein könnte.Antworten:
Ihr Modell ist leider Turing-komplett.
Mit dem folgenden Algorithmus können Sie eine Warteschlange in Ihrer Datenstruktur simulieren. Es wurden 3 neue Stapelsymbole eingeführt:d,x,y .
Enqueue(val)
ist einfachPush(val)
.Für
Dequeue()
:ReadBegin()
.ReadBegin()
.pTop
ist einReadNext()
bis etwas anderes als zurückgegeben wirdPop()
.ReadNext()
wird als Ergebnis von zurückgegebenDequeue
.Der Beweis ist unkompliziert. Überprüfen Sie den Versionsverlauf auf eine kompliziertere Version und reduzieren Sie sie zunächst auf eine bidirektionale Version.
quelle
Ihr Modell ist Turing vollständig (im Gegensatz zu dem, was ich zuvor gedacht habe). In der Antwort von user23013 finden Sie eine Skizze des Beweises (das Wesentliche ist, dass Sie eine Warteschlange simulieren können und Warteschlangenautomaten Turing vollständig sind).
Es gibt verschiedene Möglichkeiten, Ihr Modell zu schwächen, damit es mit linear gebundenen Automaten oder niedriger gleichwertig ist.
Ginsburg, Greibach & Harrison [1] geben eine Maschine namens "Stack Automaton" an, bei der es sich um einen PDA mit zwei zusätzlichen Funktionen handelt: 1. Der Eingabekopf kann sich nach links und rechts bewegen (damit zuvor gesehene Teile der Eingabe gescannt werden können). 2. Der Lese- / Schreibkopf auf dem Stapel kann den Stapel im schreibgeschützten Modus durchsuchen, aber das Drücken und Knallen erfolgt immer noch nur oben. Beachten Sie hier den Hauptunterschied zu Ihrem Modell, der mich früher verwirrt hat: Der Stapel hat nur einen Kopf / Zeiger, mit dem er sich auf und ab bewegen kann, während Ihr Stapel zwei hat, was ausreicht, um Ihr Modell Turing vollständig zu machen. Sie geben auch ein anderes Modell [2] an, bei dem die Eingabe nur von links nach rechts gelesen werden kann, das zusätzliche schreibgeschützte Stapelscannen jedoch weiterhin verfügbar ist.
In Abbildung 2 von [1] geben sie das Containment an (bewiesen in Abschnitt 5 desselben, möglicherweise mit einigen Teilen in [2]), und in nichtdeterministischen Zwei-Wege-Stapelautomatensprachen sind streng enthaltenR . Sie entsprechen jedoch nichtdeterministischen linear gebundenen Automaten, sodass sie kontextsensitive Sprachen erkennen.
Zweiwege- und nichtdeterministische Stapelautomaten und deterministische Zweiwegestapelautomaten scheinen gleichwertig zu sein, jedoch macht das Ändern des Eingabekopfs in Einweg einen signifikanten Unterschied. Die Menge der nichtdeterministischen Einweg-Stapelautomatensprachen ist eine strikte Teilmenge der kontextsensitiven Sprachen (ich kann noch nicht genau sagen, wo) und die Menge der deterministischen Einweg-Stapelautomaten (die Ihrem Modell entsprechen) ) Languages ist eine strikte Teilmenge der Menge nichtdeterministischer Einweg-Stapelautomatensprachen.
Ein schwächerer Typ, der darunter liegt, sind nicht löschende Stapelautomaten, die nur in den Stapel schreiben können.
Hopcroft & Ullman zeigen, dass die Sprachen, die von nicht löschenden deterministischen Stapelautomaten erkannt werden, entsprechenDSPACE(nlogn) und nicht löschbare nichtdeterministische Stapelautomaten entsprechen DSPACE(n2) .
Nachtrag
Nach einigem Hin und Her deuten diese Vorlesungsfolien darauf hin, dass deterministische Stapelautomaten in einer Richtung, die nicht gelöscht werden können, streng schwächer sind als die Version in zwei Richtungen. Erkennen Sie also etwas weniger alsDSPACE(nlogn) .
Ich habe auch weitere Hopcroft & Ullman [4,5] -Papiere gefunden, die vielleicht ein paar weitere Hinweise liefern, aber an diesem Punkt scheinen sie tangential zu sein. [5] beweist zumindest einige Äquivalenzen einiger Stapelautomaten mit LBAs.
Verweise
quelle
pRead
ist. (wie ich es verstehe)pTop
undpRead
sind zwei getrennte Zeiger. Sie können bei einreihenpTop
und aus dem Verkehr ziehen (indem Sie nach oben gehen und alles unten ignorieren)pRead
? (Wenn es in beide Richtungen ist.)