TIB: Kontextfreie Sprachen und Kellerautomaten (Lernziele KE7 2/3, Update 2)
Update 2: Einzel- und Mehrschrittrelationen, sowie Überführungsfunktion genauer erklärt.
Großes Update: Fehlerbeseitigung und langes Beispiel zum Beweisverfahren Sprache zu Automat(en) zu Grammatik zu Sprache (Lernziel 4).
Lernziel 3
Wie sind Kellerautomaten und die von ihnen akzeptierte Sprache definiert?
Noch einmal zur Auffrischung: alle Sprachen, die ein endlicher Automat akzeptiert sind regulär. Haben wir aber eine nicht reguläre Sprache, von was wird sie dann akzeptiert? Ein schönes Beispiel gab es (schon wieder) im Buch von Dirk W. Hoffmann mit der Sprache:
Wir brauchen also einen Automaten, der unsere Sprache akzeptiert. Mit dem Pumping Lemma für reguläre Sprachen sehen wir sofort, dass sie nicht regulär ist. Auch wenn wir es versuchen, so gelingt es uns nicht einen endlichen Automaten für diese Sprache zu bestimmen. Wir schaffen das immer nur für eine endliche Teilmenge der Sprache (durch akzeptierende Zustände für jedes Wort aus der Sprache) und wir wissen ja, dass jede endliche Sprache auch regulär ist weil wir im schlimmsten Fall einfach nur einen akzeptierenden Zustand für jedes Wort bauen müssen. Zwar ist das bei einer endlichen Teilmenge unserer Sprache nicht notwendig; der endliche Automat kommt nur mit einem akzeptierenden Zustand aus, das Prinzip sollte aber klar geworden sein. Jeder akzeptierende Zustand fungiert also als eine Art "Speicher".
Was müssen wir also tun um einen Automaten zu bekommen, der diese Sprache akzeptiert? Wir müssen uns irgendwo die Anzahl der merken und sie mit der Anzahl der vergleichen können. Wir brauchen also irgendeinen "unendlichen" Speicher, da wir ja auch etvl. ein unendlich langes Wort haben. Hier helfen uns die Zustände unseres endlichen Automaten nicht weiter, denn er ist... nunja... endlich. 😉
Wir erweitern unseren endlichen Automaten einfach, so dass wir noch genau die kontextfreien Sprachen mit ihm akzeptieren/semi-entscheiden können.
Während in der Literatur häufig mit einem -Tupel gearbeitet wird, hat das Skript eigene Vorstellungen und verwendet ein -Tupel zur Definition eines Kellerautomaten. Zusätzlich zu den üblichen Dingen werden auch noch das Kellerstartsymbol $ und die Menge der Endzustände definiert. Ist vielleicht auch gar nicht schlecht, denn die Wikipedia sieht das ähnlich. Ich echauffiere mich also in den letzten Zügen des Skripts nicht über dasselbe. 😉 Wollen wir also formal definieren:
Kellerautomat
mit
endliches Eingabealphabet
endliches Kelleralphabet
Kellerstartsymbol und Markierung für Eingabeende
als Anfangszustand
Endzustände
Zustandsübergangsfunktion
Kommen wir nun zur Zustandsübergangsfunktion . Ich würde sagen, dass ich ein paar Beispiele gebe anstatt vollständig formal zu bleiben:
Im Zustands , lese aus der Eingabe, nimm vom Kellerstapel, wechsle in den Zustand und schiebe auf den Kellerstapel.
Im Zustands , lese aus der Eingabe, nimm vom Kellerstapel, wechsle in den Zustand und lege nichts in den Kellerstapel. Damit wurde das Zeichen aus dem Keller gelöscht. Lag zu diesem Zeitpunkt nicht auf dem Stapel, kann die Übergangsfunktion nicht angewandt werden.
Im Zustands , lese nichts von der Eingabe, nimm nichts vom Kellerstapel, bleibe im Zustand und lege nichts in den Kellerstapel.
Mittels und sowie werden die Einzel- und Mehrschrittrelationen bezeichnet.
Vom Zustands mit dem Wort auf dem Eingabeband und im Keller, kann man in einem Schritt den Zustand erreichen, wobei dann nur noch auf dem Eingabeband und im Keller steht.
Vom Zustands mit dem Wort auf dem Eingabeband und im Keller, kann man in Schritten den Zustand erreichen, wobei dann auf dem Eingabeband und im Keller steht.
Vom Zustands mit dem Wort auf dem Eingabeband und im Keller, hat man nach dem letzten, möglichen Berechnungsschritt den Zustand erreicht, wobei dann nichts auf dem Eingabeband und nichts im Keller steht.
Damit sind wir auch schon fast durch. Es gibt jedoch drei Dinge, die noch wichtig sind: der Automat hat zwei Wege eine Sprache zu erkennen
1. mittels Endzustand (wir landen in einem Endzustand)
Formal:
"Für ein Wort über dem Alphabet ", ausgehend vom Startzustand , während wir das Eingabewort und die Markierung für das Eingabeende auf dem Band haben ($) kommen wir nach endlich vielen Schritten zum Endzustand , während auf dem Eingabeband der Kopf über dem Eingabeende $ ist und irgendwas () im Keller steht"
2. mittels leerem Keller (wir landen zwar nicht einem Endzustand, aber der Keller ist leer)
Formal:
"Für ein Wort über dem Alphabet ", ausgehend vom Startzustand , während wir das Eingabewort und die Markierung für das Eingabeende auf dem Band haben ($) kommen wir nach endlich vielen Schritten zum beliebigen Zustand , während auf dem Eingabeband der Kopf über dem Eingabeende $ ist und der Keller leer ist ()"
Und die Definition des Determinismus einer Kellermaschine:
Ein Kellerautomat ist determiniert, wenn:
es zu jedem Eingabezeichen und jedem obersten Kellerzeichen maximal ein Zustandsübergang gibt.
Antwort zum Lernziel: die Kellerautomaten bestehen aus einem Eingabe- und einem Kelleralphabet, einem Kellersymbol und der Markierung für das Eingabeende sowie Anfangs- und Endzuständen und der Zustandsübergangsfunktion. Die von ihnen akzeptierte Sprache wird definiert als die Worte, die a) den Automaten entweder in einen Endzustand bringen wenn das Ende des Eingabewortes erreicht ist, wobei egal ist, was im Keller steht oder b) der Keller leer ist wenn das Ende des Eingabewortes erreicht ist, wobei es egal ist, in welchem Zustand sich der Automat zu diesem Zeitpunkt befindet.
Und das sind genau die kontextfreien Sprachen, die die Typ-2-Grammatiken erstellen können. Wie wir zu einer kontextfreien Grammatik einen Kellerautomaten basteln, zeigen wir im nächsten Abschnitt, indem wir die Produktionsregeln der Grammatik in die Übergänge unseres Kellerautomaten codieren.
Lernziel 4
Wie zeigt man, dass Kellerautomaten genau die kontextfreien Sprachen erkennen?
Ich würde hier noch ein paar Kleinigkeiten in eure Erinnerung rufen bevor wir mit den Kellerautomaten richtig loslegen. Das liegt u.a. daran, dass wir bei den vorher betrachteten Sprachen eine Äquivalenz zwischen TM und NTM hatten (wir können eine NTM durch eine TM simulieren indem wir einfach alle möglichen Berechnungspfade der NTM durchlaufen), bei den Kellerautomaten hier aber strikt trennen müssen. Nichtdeterministische Kellerautomaten sind eben nicht äquivalent zu deterministischen. Letztere spielen aber eine große Rolle, so dass wir noch später auf sie zurück kommen werden.
Um also zu zeigen, dass ein Kellerautomat genau die kontextfreien Sprachen erkennt, müssen wir zu einer kontextfreien Grammatik einen Kellerautomaten angeben, der mit seinen zwei Akzeptanzmethoden (leerer Keller und Endzustand) ein Wort genau dann akzeptiert wenn das Wort mittels der kontextfreien Grammatik abgeleitet werden kann. Es muss also gelten:
Um zu zeigen, dass wir alle kontextfreien Sprachen durch Kellerautomaten erkennen lassen können, müssen wir das Regelschema der kontextfreien Grammatiken in ein Zustandsübergangsschema für Kellerautomaten umwandeln. Nur ein Problem haben wir: Die Frage welche Ersetzung (d.h. die Rückumwandlung der Ableitung) zu machen ist, müssen wir beantworten und tun das mit unserem Nichtdeterminismus, indem wir aus mehreren in Frage kommenden Ersetzungen einfach eine raten!
Ich würde sagen, dass wir auch hier direkt mit einem Beispiel starten und eine kontextfreie Grammatik in einen Kellerautomaten überführen.
Grammatik zum Automat mit einem Zustand: kontextfreie Grammatik mit den Regeln
soll überführt werden in einen Kellerautomaten , der die gleiche Sprache akzeptiert.
Ja, das ist die Dyck-Sprache. Geklaut aus dem Buch von Dirk W. Hoffmann. Sehr einfaches und leicht verständliches Beispiel. Wie kommen hier mit nur einem Zustand aus und können den Kellerspeicher so effizient nutzen. Nun müssen wir erstmal des Automaten festlegen.
Kelleralphabet
(unser Kelleralphabet besteht also aus Elementen des Terminal- und des Nonterminalalphabets.
Zustände
Die Regel wird zu . In unserem Fall sind das:
Dazu brauchen wir auch noch Regeln für die Terminalzeichen (), so dass nur mit der Verarbeitung weitergemacht werden soll wenn das oberste Zeichen im Keller mit dem eingelesenen Zeichen übereinstimmt:
Zusätzlich müssen wir das Kellerstartsymbol durch ersetzen um loszulegen:
Achtung: wir haben hier ein Beispiel gezeigt, dass die Sprache mittels leerem Keller akzeptiert und nicht mittels Endzuständen! Das ist der Automat, der raus kommt ( ist das Kellerendzeichen und ist unser leeres Wort , bzw. beliebiges Zeichen):
Download: Dyck-Sprache JFLAP Datei
Der Automat ist nichtdeterministisch angelegt, d.h. es existieren mehrere Berechnungspfade für eine Eingabe. Das werdet Ihr sehen wenn Ihr den Automaten laufen lasst. Es geht uns beim Nichtdeterminismus ja nur darum mindestens einen Berechnungspfad zu haben, der durchläuft. Dass andere evtl. scheitern ist uns in diesem Sinne egal. Die Regeln beim Automaten bedeuten folgendes:
(1) Wenn auf dem Eingabeband ein Zeichen (ein Zeichen nicht aus dem Alphabet) steht und das oberste Zeichen im Keller das Kelleranfangszeichen ist, ersetze es im Keller mit .
(2) Wenn auf dem Eingabeband ein Zeichen und im Keller ein steht, so ersetze im Keller mit . Damit ist der Keller leer, es ist unsere "Endbedingung". Nicht vergessen: der Keller wird erst dann geleert (auf gesetzt) wenn wir fertig mit dem Einlesen (es steht auf dem Eingabeband) und am Ende im Keller nur ein stand, d.h. dass wir einen korrekten Berechnungspfad hatten und damit das Wort richtig abgeleitet wurde.
(3) Wenn auf dem Eingabeband ein Zeichen steht und das oberste Zeichen im Keller das Zeichen ist, ersetze es im Keller mit .
(4) Wenn auf dem Eingabeband ein Zeichen steht und das oberste Zeichen im Keller das Zeichen ist, ersetze es im Keller mit .
(5) Wenn auf dem Eingabeband ein Zeichen steht und das oberste Zeichen im Keller das Zeichen ist, ersetze es im Keller mit .
Spätestens jetzt habt Ihr ein Fragezeichen über dem Kopf. Oder Ihr nickt. Oder ihr fragt euch, warum ich um den heißen Brei herumrede. Habt Ihr gemerkt? Welche Regel von den letzten drei wird nun angewendet wenn auf dem Eingabeband das Zeichen eines leeren Wortes steht und das oberste Zeichen im Keller das Zeichen ist? Wird da nun ein oder draus? Tja, das genau ist der Nichtdeterminismus. Es kann alles sein. Und wenn wir den falschen Pfad wählen, können wir evtl. nie aus der Berechnung raus. Und wisst Ihr was? Es ist uns egal! Hauptsache es existiert ein Pfad, das reicht uns.
Nun kommen die wichtigsten Regeln:
(6) Wenn auf dem Eingabeband das Zeichen steht und das oberste Zeichen im Keller ebenfalls ist, ersetze es im Keller mit .
(7) Wenn auf dem Eingabeband das Zeichen steht und das oberste Zeichen im Keller ebenfalls ist, ersetze es im Keller mit .
(8) Wenn auf dem Eingabeband das Zeichen steht und das oberste Zeichen im Keller ebenfalls ist, ersetze es im Keller mit .
(9) Wenn auf dem Eingabeband das Zeichen steht und das oberste Zeichen im Keller ebenfalls ist, ersetze es im Keller mit .
Wir leeren mit diesen Regeln also unseren Keller. Es fällt euch wahrscheinlich schwer, zu verstehen was der Automat tut. Ich würde sagen, wir probieren ihn an einem kleinen Beispiel aus.
Funktionsweise: Wenn wir z.B. den Automaten mit der Eingabe laufen lassen, so passiert folgendes:
Ich habe nicht alle Pfade aufgemalt, sondern nur einen korrekten Pfad bis zum Ende durchgezeichnet. Die mit beschrifteten Pfade führen zu einer weiteren Berechnung (die evtl. auch in einem Ergebnis münden kann). Nach Anwendung der Regel und in der zweiten Ableitung gibt es für die Symbolkombination oder keinen weiteren Übergang und wir haben einen undefinierten Automatenzustand.
Bei den zwei weiteren Pfaden geht es jedoch weiter. Um den Keller zu leeren müssen wir als erstes Kellerzeichen und erstes Bandzeichen eines der vier Klammern haben. Da wir immernoch bei als Eingabe sind, müssen wir es schaffen auf das Hilfsband eine öffnende Klammer zu bekommen, was durch Anwendung der Regel 3 gut funktioniert. Bei den anderen drei Pfaden führt einer wieder in die Sackgasse, da wir keinen Folgezustand für die Symbolkombination oder haben und die beiden anderen zu weiteren Berechnungspfaden.
Der für uns spannende Pfad wird durch Regel 3 verfolgt: es wird mit Regel 8 anschließend ein Zeichen auf dem Hilfsband gelöscht und wir lesen das nächste Zeichen, unsere schließende Klammer oder ein und suchen für die Symbolkombination oder die nächsten, passenden Regeln. Es kommen wieder vier Berechnungspfade in Frage, die wir nun nicht weiter verfolgen. Sonst wäre die Grafik riesig geworden.
Mit Anwendung der Regel 2 ersetzen wir das im Keller durch und können nun die einzig passende Regel für die Symbolkombination anwenden um das nächste Zeichen (wir haben keins mehr) auf dem Eingabeband einzulesen und im Keller zu löschen.
Für Die Symbolkombination haben wir wieder vier mögliche Regeln, die passen könnten. Aber nur Regel 2 führt uns zu einem leeren Keller beim erreichen des Eingabeendes. Und damit haben wir einen Pfad erfolgreich gefunden.
Wir haben hier zeigen können, dass wir mit nur einem Zustand auskommen. Daher sollte der wichtige Satz
Für jeden Automaten, der eine Sprache mittels Endzustand akzeptiert, existiert ein Automat, der die mittels leerem Keller akzeptiert und umgekehrt (Vorsicht: das gilt nicht für deterministische Kellerautomaten!).
nicht vergessen werden!
Wie konstruieren wir denn aus einem Automaten mit mehreren Zuständen einen mit nur einem Zustand? Ganz einfach:
1. Aus dem Automaten mit mehreren Zuständen wird eine kontextfreie Grammatik erzeugt (nach Rechenberg ist das immer möglich, hat aber keine praktische Bedeutung und wird deshalb in der Literatur ausgelassen. Tatsächlich habe ich in vier Büchern, die ich zur Hand habe den Weg anhand eines konkreten Beispiels nicht gefunden. Wer etwas findet, bitte Info an mich. Mit dem JFLOP könnt Ihr einen Automaten in eine Grammatik wandeln, evtl. schreibe ich das Verfahren einfach nochmal hierhin)
2. Aus der kontextfreien Grammatik wird mit dem oben angegebenen Verfahren ein Automat mit nur einem Zustand erstellt
That's it.
Zusammengefasst: Wir können also zu einer kontextfreien Sprache eine kontextfreie Grammatik angeben. Diese Sprache erkennt auch ein Kellerautomat mittels leerem Keller. Auch ein Automat mit Endzustand tut dies. Wir können sogar einen Automaten angeben, der nur mit einem Zustand auskommt, da die Mächtigkeit des Automaten nur von seinem Keller kommt.
Noch eine Kleinigkeit, die hier von Bedeutung ist: was ist unter einem normalisierten Automaten zu verstehen ist? Dieser spielt bei bei der Konvertierung von Automat zu Grammatik eine große Rolle (hier ist ein gutes Dokument der Fakultät für Informatik der Uni Illionois, die etwas mehr Details dazu hat, als ich hier wiedergebe):
1. Es gibt nur einen akzeptierenden Endzustand
Das tun wir, indem wir einen neuen Endzustand einführen und einen -Übergang von den anderen Zuständen dorthin zeichnen
2. Vor der Akzeptanz wird der Keller geleert
Das kann man tun, indem man vor dem Endzustand in einen Zustand geht und alles bis zum Kellerendzeichen ($) aus dem Keller schmeißt.
3. Beim Übergang wird entweder ein Zeichen aus dem Keller entnommen oder eines hineingelegt, aber nicht beides
Hier gibt es zwei Fälle: a) Übergänge, die ein Element aus dem Keller nehmen und ein neues hinein legen und b) Übergänge, die nichts tun. Beide können wir mit neuen Zuständen und Übergängen simulieren. Fall a) handeln wir ab, indem wir zwei neue Zustände einführen: einer entnimmt das Zeichen, geht in einen temporären (neuen) Folgezustand über, dann wird ein Zeichen hineingelegt und der eig. Folgezustand eingenommen. Fall b) behandelt wir noch einfacher: wir basteln uns zwei neue Übergänge. Einer nimmt das Zeichen, geht in den temporären (neuen) Folgezustand und der nächste legt es wieder zurück. Fertig.
Das war jetzt alles wahrscheinlich bisschen viel und verwirrend. Vielleicht hilft eine kurze Übersicht des Beweisverfahrens?
Beweisverfahren
Sprache
Kellerautomat
normalisierter Kellerautomat
Grammatik
Sprache und Kellerautomat mit nur einem Zustand .
Damit schließt sich der Kreis. Wir zeigen der Vollständigkeit halber im letzten Schritt auch noch, dass wir mit dem oben genannten Verfahren aus der erzeugten Grammatik einen Automaten (nach dem oben gezeigten Verfahren) ableiten können, der nur einen einzigen Zustand hat und das Wort mittels leerem Keller akzeptiert.
Wollen wir den ganzen Spaß noch einmal an der Sprache vom Anfang des Beitrags durchspielen:
Beispiel:
Sprache zu Kellerautomat
Dieser Automat erkennt die Sprache mit einem leeren Keller.
Kellerautomat zu normalisiertem Kellerautomat
Dieser Automat erkennt die Sprache mittels Endzustand. So sieht er aus:
Wie wir sehen, haben wir einfach nur einen neuen Endzustand eingeführt. Der folgende Automat erkennt also das Wort in einem Endzustand und hat auch noch einen leeren Keller. Also optimale Bedingungen. Damit ist er soweit normalisiert (bis auf den Punkt mit den Überführungsbedingungen: die tun immer noch zwei Schritte gleichzeitig (Push und Pop). Da sie uns aber bei der Grammatik nicht stören, war hier etwas faul, sorry!).
Normalisierter Kellerautomat mit Endzustand zu Grammatik
Nun wandeln wir die Zustandsübergänge des Automaten in die Regeln für die Grammatik um. Wir kümmern uns zunächst um alle Regeln, die etwas aus dem Keller entnehmen (nicht vergessen, im Bild ist unser )
1.
Jetzt wird es haariger. Was machen wir mit den verbliebenen Regeln? Problem hierbei: wir nehmen was aus dem Keller und legen gleichzeitig was drauf. Erinnert Ihr euch an die Kriterien für die Normalisierung? Nunja, eine haben wir hier nicht erfüllt: Nr. 3. Aber das macht erstmal nichts, wir generieren einfach ein paar Regeln mehr nach folgendem Muster:
2. , wobei und alle Zustände im Automaten sind. Wir müssen also alle Zustandskombinationen abgrasen, was uns zur folgenden, langen Liste an Regeln führt:
Regel
Regel
3. Nun werden die Zustandskombinationen noch umbenannt in , unnötiges gestrichen (man kann sich einen Abhängigkeitsgraphen malen um unnötige Zustände besser zu identifizieren, wie z.B. in diesem Beitrag gezeigt) und der Startzustand hinzugefügt. Am Ende haben wir dann die folgenden Regeln für unsere Grammatik:
Wir könnten hier sogar noch oder streichen und kommen auf
Grammatik zu Kellerautomat mit nur einem Zustand
Da wir nun unsere Grammatik haben, können wir nach dem Verfahren von oben (erstes Beispiel bei Lernziel 4) uns einen schönen Automaten mit nur einem Zustand basteln, der die Worte unserer Sprache mit leerem Keller akzeptiert. Das sind die Zustandsübergänge, die wir aus der Grammatik ableiten können:
Fehlen uns noch die Regeln für die Terminale und die Ersetzung des Kellerzeichens durch erste Ableitung wenn wir fertig sind:
Nachdem wir alles zusammengefügt haben, kommt der folgende Automat heraus:
Grammatik zu Sprache
Letzter Schritt nochmal aus der Grammatik die ableitbare Sprache zu basteln:
Damit ist der Kreis geschlossen und wir sind da, wo wir angefangen haben. Und ich hoffe, dass ich mich nirgendwo vertippt habe... 😉
Antwort zum Lernziel: zu jedem nichtdeterministischen Kellerautomat, der eine Sprache mittels Endzustand erkennt kann man einen nichtdeterministischen Kellerautomaten angeben, der dieselbe Sprache mittels leerem Keller (ohne Endzustand) erkennen kann. Und das sogar mit nur einem einzigen Zustand. Das liegt daran, dass die Ausdrucksstärke nur vom Keller und nicht von den Zuständen des Automaten kommt.
Dieser Automat kann weiter normiert werden, so dass man beim Erreichen des Endzustands einen leeren Keller hat und die Überführungsfunktionen entweder etwas auf den Stack legen oder nur etwas wegnehmen. Dazu werden die Überführungsfunktionen, die diese Kriterien nicht erfüllen durch neue, temporäre Zustände und neue Regeln ersetzt.
Der normierte Automat lässt sich dann einfacher in eine kontextfreie Grammatik umwandeln, das die gleiche Sprache erzeugt wie der normierte Automat. Dazu werden die Überführungsrelationen des Automaten in Ableitungsregeln für die Grammatik umgewandelt, ein Abhängigkeitsgraph gezeichnet und unnötige Zustände und Relationen mit seiner Hilfe gestrichen, so dass sich die Menge der Ableitungen auf ein Minimum verkürzt.
Am Ende hat man eine minimale Grammatik, aus der man zum einen die Sprache ableiten, als auch wieder einen Automaten mit nur einem einzigen Zustand erzeugen kann, der die von der Grammatik erzeugte Sprache mittels leerem Keller akzeptiert.
Sie können zum Ende springen und ein Kommentar hinterlassen. Pingen ist im Augenblick nicht erlaubt.
September 13th, 2015 14:42
Vielen Dank für all ihre Arbeit. Bei der Definition des Kellerautomaten hat sich ein kleiner Fehler eingeschlichen, das Kellerstartsymbol wird mit $ nicht mit § bezeichnet.
MfG
Niklas
September 14th, 2015 10:55
Hallo Niklas,
wo steht denn noch "§"? Habe nichts im Text gefunden.