Erfolgreiche ePaper selbst erstellen
Machen Sie aus Ihren PDF Publikationen ein blätterbares Flipbook mit unserer einzigartigen Google optimierten e-Paper Software.
<strong>10</strong> <strong>Endliche</strong> <strong>Automaten</strong><br />
<strong>10</strong>.1 Einführungsbeispiele<br />
Beispiel 1:<br />
Warenautomat<br />
Ein Flasche Cola kostet 1,50 €. Münzen zu 1 €<br />
und 50 ct werden angenommen. Cola und evtl.<br />
Restgeld werden ausgegeben. Auch der<br />
Rückgabeknopf funktioniert.<br />
Beispiel 2:<br />
erkennender Automat<br />
23<br />
55,782<br />
-0,554<br />
-444777<br />
+12,73849506<br />
-1<br />
0<br />
sind Beispiele für gültige Fließkomma - Konstanten<br />
ohne Exponent (real bzw. double)<br />
,89<br />
+<br />
34,4,5<br />
+250,<br />
sind in diesem Sinne keine gültigen Zeichenfolgen.<br />
Ein Automat soll eine Zeichenfolge daraufhin<br />
untersuchen, ob sie gültig ist.<br />
Der Versuche einer Programmierung mit if – then – Kaskaden wird schon bei diesen einfach gehaltenen<br />
Bespielen misslingen.<br />
Die Reaktion des <strong>Automaten</strong> auf eine weitere Eingabe (Geldstück oder Ziffer/Zeichen) hängt offensichtlich<br />
davon ab, was vorher geschah.<br />
Man muss also Zustände betrachten, die von der Eingabe verändert werden.<br />
Diese Übergänge kann man als Graph veranschaulichen.<br />
1
<strong>10</strong>.2 Zustandsdiagramme<br />
Beim Cola – Automat wird als Zustand angeben, wie viel Geld man eingeworfen hat:<br />
50<br />
<strong>10</strong>0 oder R<br />
Z O Ausg. Cola / 50<br />
<strong>10</strong>0<br />
Z 50<br />
50 oder <strong>10</strong>0 oder R<br />
Ausg. Cola / Cola + 50 / <strong>10</strong>0 Z <strong>10</strong>0<br />
An den Pfeilen notiert man die Eingaben (und die jeweiligen Ausgaben)<br />
Beim Fließkomma – Konstanten – Erkenner gibt man an, was bereits erkannt worden ist:<br />
+ / - Z + - Ziffer<br />
Z O Z Int Z Komma Z Real<br />
Ziffer Komma Ziffer<br />
Ziffer steht für 0,1,2,3,4,5,6,7,8,9 (eigentlich <strong>10</strong> Pfeile)<br />
50<br />
Ziffer Ziffer<br />
Für die Realisierung ist noch ein Fehlerzustand wichtig, der bei allen nicht erlaubten Eingaben aufgesucht wird<br />
und in dem der Prozess dann verbleibt.<br />
2
<strong>10</strong>.3 Definition<br />
Unter einem deterministischen endlichen <strong>Automaten</strong> versteht man ein Konstrukt bestehend aus<br />
a) einer (endlichen) Menge von Eingabezeichen (Eingabe-Alphabet),<br />
In den Beispielen sind das<br />
„<strong>10</strong>0“, „50“, „R“ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, +, -, Komma<br />
b) einer (endliche) Menge von Zuständen,<br />
In den Beispielen sind das<br />
Z0 , Z50, Z<strong>10</strong>0 Z0, Z+ - , ZInt , ZKomma , ZReal , ZFehler<br />
c) einer Überführungsfunktion, die für jeden Zustand und für jedes Eingabezeichen den Folgezustand<br />
angibt.<br />
Die Überführungsfunktion wird durch den Zustandsgraphen dargestellt; daraus kann man etwa ablesen:<br />
Z 50 , <strong>10</strong>0 Z O (+Ausgabe Cola) Z + - , 9 Z Int<br />
d) einem Anfangszustand Z 0 (im Zustandgraph durch einen Pfeil dargestellt),<br />
e) einer Menge von Endzuständen (Doppelkreise im Zustandsgraph)<br />
In den Beispielen sind das<br />
kein Endzustand vorhanden Z Int und Z Real<br />
f) einer (endliche) Menge von Ausgabezeichen (Ausgabe-Alphabet)<br />
In den Beispielen sind das<br />
Cola, 50, <strong>10</strong>0, nichts keine Ausgabe<br />
g) einer Ausgabefunktion, die für jeden Zustand und für jedes Eingabezeichen das Ausgabezeichen<br />
angibt.<br />
Aus dem Zustandsgraphen kann man etwa ablesen:<br />
Z<strong>10</strong>0 , 50 Cola keine Ausgabe<br />
3
<strong>10</strong>.4 Klassen von <strong>Automaten</strong><br />
Bei endlichen <strong>Automaten</strong> werden verschiedene Klassen unterschieden:<br />
Deterministischer (determinierter) endlicher<br />
Automat ohne Ausgabe: Akzeptor<br />
Deterministischer (determinierter) endlicher<br />
Automat mit Ausgabe: Übersetzer, Scanner<br />
Nichtdeterministischer (nichtdeterminierter)<br />
endlicher Automat ohne Ausgabe: Akzeptor<br />
Nichtdeterministischer (nichtdeterminierter)<br />
endlicher Automat mit Ausgabe: Übersetzer<br />
Deterministisch (determiniert) nennt man einen endlichen <strong>Automaten</strong>, wenn eine Eingabe einen<br />
eindeutigen Zustandsübergang aus einem Zustand bewirkt.<br />
Nichtdeterministisch (nichtdeterminiert) nennt man einen endlichen <strong>Automaten</strong>, bei dem spontane<br />
Zustandsübergänge ohne Eingaben möglich sind bzw. der Übergang von einem Zustand über eine<br />
Eingabe in einen neuen Zustand nicht eindeutig ist. Es handelt sich dann nicht um eine<br />
Überführungsfunktion, sondern allgemeiner um eine Relation.<br />
Nichtdeterministische <strong>Automaten</strong> ermöglichen es im Gegensatz zu deterministischen <strong>Automaten</strong>,<br />
grundsätzlich mit einem Ende - Zustand auszukommen. Dies ist für die theoretische Informatik<br />
eine bedeutsame Vereinfachung, vor allem, da <strong>Automaten</strong> leicht hintereinander geschaltet werden<br />
können.<br />
Bedeutung haben Nichtdeterministische <strong>Automaten</strong> vor allem in dem Zusammenhang, dass mit<br />
ihnen eine schnelle Übertragung einer regulären Grammatik in einen <strong>Automaten</strong> möglich ist. Sie<br />
lassen sich jedoch nicht ohne Weiteres auf einem Computer darstellen.<br />
Akzeptoren sind endliche <strong>Automaten</strong>, die sich entweder am Ende einer Eingabefolge in einem<br />
Ende - Zustand befinden und damit die Eingabefolge akzeptieren oder sich am Ende einer<br />
Eingabefolge nicht in einem Ende - Zustand befinden und damit die Eingabefolge nicht<br />
akzeptieren.<br />
Übersetzer oder Scanner sind endliche <strong>Automaten</strong>, die zusätzlich zum Akzeptieren Ausgaben<br />
erzeugen.<br />
Bei Akzeptoren entfallen natürlich Ausgabe-Alphabet und Ausgabefunktion.<br />
Demnach handelt es sich bei dem Cola – <strong>Automaten</strong> um einen „Übersetzer“, der Geld in Cola<br />
„umwandelt“ und bei dem Fließkomma – Konstanten – Erkenner um einen Akzeptor.<br />
Beide <strong>Automaten</strong> sind deterministisch.<br />
4
<strong>10</strong>.5 Aufgaben<br />
Entwerfen Sie für die folgenden Spracherkennungsprobleme <strong>Automaten</strong> (Akzeptoren). Notieren sie<br />
die Bestandteile a) – e) aus der Definition.<br />
An Stelle von c) zeichnen Sie den Übergangsgraphen.<br />
1) Alle Bitstrings, in denen eine gerade Anzahl von Einsen vorkommt.<br />
2) Alle Bitstrings, in denen keine zwei Einsen aufeinander folgen.<br />
3) Alle Bitstrings, die gerade Länge haben.<br />
4) Alle Bitstrings, die – interpretiert als Dualzahl – durch zwei teilbar sind.<br />
5) Bei der seriellen Datenübertragung kommen Fehler vor. Um eine gewisse Kontrolle zu<br />
ermöglichen, sendet man nach einer bestimmten Anzahl von Bits ein Kontrollbit. Man kann dieses<br />
z.B. so wählen, dass die Anzahl der Zeichen 1 im Datenwort immer gerade ist. Hat das Datenwort<br />
z.B. die Länge 4, so wird die Information 1<strong>10</strong> durch das Zeichen 0 ergänzt, während 0<strong>10</strong> durch 1<br />
vervollständigt wird. Es soll nun ein Automat angegeben werden, der die Korrektheit des<br />
übertragenen Wortes prüft.<br />
6) Bezeichner (in einer Programmiersprache) beginnen mit einem Buchstaben und dürfen nur<br />
Buchstaben und Ziffern enthalten. Geben Sie einen Akzeptor an, der prüft, ob es sich bei einer<br />
Zeichenkette um einen Bezeichner handelt.<br />
<strong>10</strong>.6 Überführungsfunktion als Tabelle<br />
beim Cola-<strong>Automaten</strong> bei dem Fließkomma – Konstanten – Erkenner<br />
50 <strong>10</strong>0 R<br />
Z0 Z50 Z<strong>10</strong>0 Z0<br />
Z50 Z<strong>10</strong>0 Z0 Z0<br />
Z<strong>10</strong>0 Z0 Z0 Z0<br />
Hier noch die Ausgabefunktion:<br />
50 <strong>10</strong>0 R<br />
Z0 Nichts Nichts Nichts<br />
Z50 Nichts Cola 50<br />
Z<strong>10</strong>0 Cola Cola+50 <strong>10</strong>0<br />
0,1,2,3,4,5,6,7,8,9 +, - Komma<br />
Z0 Z Int Z + , - ZFehler<br />
Z + , - Z Int ZFehler ZFehler<br />
Z Int Z Int ZFehler ZKomma<br />
ZKomma ZReal ZFehler ZFehler<br />
ZReal ZReal ZFehler ZFehler<br />
ZFehler ZFehler ZFehler ZFehler<br />
5
<strong>10</strong>.7 Implementation<br />
Eingabealphabet, Ausgabealphabet und Zustandsmenge<br />
In Delphi kann man diese Mengen als Aufzählungstypen darstellen:<br />
Warenautomat<br />
type<br />
tEingabe = (e50, e<strong>10</strong>0, eR);<br />
tAusgabe = (a50, a<strong>10</strong>0, aCola, aNichts, aCola50);<br />
tZustand = (z0, z50, z<strong>10</strong>0);<br />
Fließkomma – Konstanten – Erkenner<br />
type<br />
tEingabe = (e0, e1,.., e9, ePlus, eMinus, eKomma);<br />
tZustand = (z0, zPlusMinus, zInt, zKomma, zReal, zFehler);<br />
Überführungsfunktion und Ausgabefunktion<br />
Im Interface werden die Funktionen definiert:<br />
interface<br />
type tAutomat = class(tObject)<br />
Zustand :tZustand;<br />
Constructor Create;<br />
Destructor Destroy; override;<br />
function Ueberfuehrung (pZustand:tZustand; pEingabe:tEingabe) : tZustand;<br />
function Ausgabefunktion (pZustand:tZustand; pEingabe:tEingabe) :tAusgabe;<br />
end;<br />
für die Implementation gibt es zwei Möglichkeiten:<br />
a) die Tabelle der Überführungsfunktion als Array darstellen<br />
implementation<br />
function tAutomat.Ueberfuehrung (pZustand:tZustand; pEingabe:tEingabe) : tZustand;<br />
Const Tabelle: Array[tZustand, tEingabe] OF tZustand<br />
= ((z50,z<strong>10</strong>0,z0),(z<strong>10</strong>0,z0,z0),(z0,z0,z0));<br />
Begin<br />
Ueberfuehrung := Tabelle [pZustand,pEingabe];<br />
End;<br />
b) geschachtelte case – Anweisungen verwenden:<br />
implementation<br />
function tAutomat.Ueberfuehrung (pZustand:tZustand; pEingabe:tEingabe) : tZustand;<br />
Begin<br />
case pEingabe OF<br />
E50: case pZustand OF<br />
z0: Ueberfuehrung:=z50;<br />
z50: Ueberfuehrung:=z<strong>10</strong>0;<br />
z<strong>10</strong>0: Ueberfuehrung:=z0;<br />
end;<br />
E1: case pZustand OF<br />
z0: Ueberfuehrung:=z<strong>10</strong>0;<br />
z50,z<strong>10</strong>0: Ueberfuehrung:=z0;<br />
end;<br />
ERueck: Ueberfuehrung:=z0;<br />
6
End;<br />
End;<br />
End;<br />
Die Implementation der Ausgabefunktion erfolgt entsprechend.<br />
In einem Delphi – Programm werden die beiden Funktionen von Ereignisbehandlungsmethoden<br />
(bt50Click o. ä.) aufgerufen – immer zuerst die Ausgabefunktion aufrufen, da die<br />
Überführungsfunktion den Zustand ändert !! – der aktuelle Zustand wird gespeichert und aufgrund der<br />
Ausgabe werden entsprechende Reaktionen (Colaflasche kommt) programmiert.<br />
Beispiele: Colaautomat, Kaffeeautomat als Delphi – Projekte<br />
<strong>10</strong>.8 Pattern – Matching<br />
als Anwendung endlicher <strong>Automaten</strong><br />
Unter dem Problem des Pattern-Matching versteht man die Suche nach einem oder allen Vorkommen<br />
eines Suchwortes in einem Text.<br />
bzw.:<br />
Gesucht werden ein oder alle Vorkommen der Zeichenkette y in einer Zeichenkette x.<br />
Beispiel: Wir suchen das Suchwort „1<strong>10</strong>1“ im Text „1<strong>10</strong>0<strong>10</strong><strong>10</strong>1<strong>10</strong>11<strong>10</strong><strong>10</strong>0001<strong>10</strong>1<strong>10</strong><strong>10</strong><strong>10</strong>1“.<br />
Ein erster Ansatz („brute force“) wird den Beginn des Suchwortes an jeder Stelle des Textes<br />
vermuten und mit geschachtelten Schleifen arbeiten:<br />
for i := 1 to length(Text) do begin<br />
gefunden := true;<br />
for j := 1 to length(Suchwort) do<br />
if Text[i+j-1] Suchwort[j] then gefunden := false;<br />
if gefunden then Ausgabe(i-j);<br />
end;<br />
Der Aufwand des Verfahrens liegt dabei in der Größenordnung Länge(Text) * Länge(Suchwort).<br />
7
Wir konstruieren nun einen endlichen <strong>Automaten</strong> für die Suche nach „1<strong>10</strong>1“.<br />
Dazu notieren wir, wie viele passende Zeichen wir schon gefunden haben:<br />
0<br />
z0 z1 z2 z3<br />
1 1 0<br />
0 1<br />
0<br />
1 / (Ausgabe „gefunden“)<br />
Ein Programm mit diesem <strong>Automaten</strong> wird jedes Zeichen des Textes nur einmal vergleichen<br />
(Aufwand in der Größenordnung „Länge(Text)“) und zu dem jeweiligen Zustand wechseln.<br />
Aufgaben:<br />
1. Entwerfen Sie einen <strong>Automaten</strong> für das Suchwort „<strong>10</strong><strong>10</strong>11“<br />
2. In der Anlage finden sie ein Programm, das zu einem Suchwort einen <strong>Automaten</strong> erzeugt und<br />
für die Suche benutzt. Die Überführungstabelle wird in einem Memo-Feld dargestellt. Auch<br />
hierzu eine Aufgabe: Erweitern Sie das Programm dahingehend, dass auch überlappende<br />
Vorkommen des Suchwortes gefunden werden.<br />
3. Konstruieren Sie einen endlichen deterministischen <strong>Automaten</strong>, der das Wort „ANANAS“ in<br />
einem beliebigen Skript erkennt...<br />
4. Entwerfen Sie einen <strong>Automaten</strong>, der Wörter der Form „Donau*schaft“ erkennt.<br />
Bemerkungen zu den Aufgaben:<br />
Wenn es darum geht Wörter in einem Text zu finden, gibt es effizientere Algorithmen (Boyer - Moore)<br />
Wörter mit Wildcards wie „*“ lasssen sich auch als reguläre Ausdrücke formulieren. Reguläre<br />
Ausdrücke definieren reguläre Sprachen und diese kann man als endliche <strong>Automaten</strong> realisieren.<br />
8
<strong>10</strong>.9 Kellerautomaten<br />
Wie überprüft man, ob in einem Programm die „begin – end“ – Schachtelung (bzw. „{„ – „}“-<br />
Schachtelung) korrekt ist ? Wie stellt man fest, ob in einem Term jede geöffnete Klammer wieder<br />
geschlossen wird ?<br />
Beide Probleme sind auf das Erkennen einer Sprache L = { 0 n 1 n | n≥ 1 } zurückzuführen.<br />
Diese Sprache ist nicht regulär; sie kann von endlichen <strong>Automaten</strong> nicht erkannt werden, weil ein<br />
solcher Automat beliebig viele (n) Zustände haben müsste, und dort die Anzahl etwa der geöffneten<br />
Klammern zu speichern.<br />
Also benötigt man einen zusätzlichen Speicher, der in der Größe nicht begrenzt ist. Es gengt dabei,<br />
diesen Speicher in Form eines Kellers (Stack, Stapel) zu verwalten, bei dem nur an einem Ende<br />
Informationen eingefügt, gelesen und entfernt werden können.<br />
Definition<br />
Ein (nichtdeterministischer) Kellerautomat besteht aus:<br />
a) einer (endlichen) Menge E von Eingabezeichen (Eingabe-Alphabet),<br />
b) einer (endlichen) Menge Z von Zuständen,<br />
c) einer (endlichen) Menge K von Kellerzeichen (Keller-Alphabet),<br />
d) einer Überführungsrelation, die für einen Zustand z1 in Verbindung mit einem Eingabezeichen<br />
e und einem gelesenen Kellerzeichen k einen Folgezustand z2 und eine zu schreibende Folge von<br />
Kellerzeichen kW angibt.<br />
e) einem Anfangszustand Z 0 (im Zustandgraph durch einen Pfeil dargestellt),<br />
f) einem Anfangskellerzeichen k 0<br />
g) einer Menge L von Endzuständen (Doppelkreise im Zustandsgraph)<br />
Die Elemente der Überführungsrelation nennt man auch Anweisungen und schreibt sie in der Form:<br />
z1 e k z2 kW (KW ist ein Kellerwort – evtl. mehrere Kellerzeichen)<br />
Da es sich um eine Relation handelt, gibt es nicht für alle z1 e k eine Anweisung (der Automat stoppt<br />
in diesem Fall), und für manche z1 e k kann es mehrere Anweisungen geben.<br />
Der Automat stoppt auch, wenn der Keller leer ist.<br />
Das Eingabewort muss vollständig gelesen sein, damit es erkannt wird, und der Automat muss<br />
anschließend in einem Endzustand stoppen.<br />
9
Beispiel:<br />
Ein Kellerautomat, der die oben betrachtete Sprache L = { 0 n 1 n | n ≥ 1 } erkennt, bestehe aus<br />
a) dem Eingabe-Alphabet E = {0,1}<br />
b) der Zustandmenge Z = { z0, z1, z2}<br />
c) dem Keller-Alphabet K = {k0, k1},<br />
e) dem Anfangszustand z 0<br />
f) dem Anfangskellerzeichen k 0<br />
g) der Endzustandsmenge L = {z2}<br />
und<br />
d) der Überführungsrelation mit den Anweisungen<br />
z0 0 k0 z0 k1 k0<br />
z0 0 k1 z0 k1 k1<br />
z0 1 k1 z1 ε ε ist das leere Wort<br />
z1 1 k1 z1 ε<br />
z1 ε k0 z2 k0<br />
Der Erkennungsablauf für das Eingabewort 000111:<br />
Eingabe 0 0 0 1 1 1 ε<br />
Zustand z0 z0 z0 z0 z1 z1 z1 z2<br />
Keller k0 k1 k1 k1 k1 k1 k0 k0<br />
k0 k1 k1 k1 k0<br />
k0 k1 k0<br />
k0<br />
<strong>10</strong>
<strong>10</strong>.<strong>10</strong> Autoedit<br />
Kostenlos zu beziehen über http://www.genesis-x7.de/cgi-bin/genesis-x7/site.cgi?site=main&lang=de<br />
oder in Google „<strong>Automaten</strong> autoedit“ eingeben. (Benötigt MS-XML 4.0 – kann auf der selben Seite<br />
heruntergeladen werden)<br />
Unter dem Menupunkt „Help“ kann man als Sprache Deutsch einstellen.<br />
Der „Einführungsassistent“ lässt den Benutzer die Schritte zur Erstellung eines <strong>Automaten</strong><br />
beispielhaft durchlaufen.<br />
DEA – Deterministischer<br />
endlicher Automat<br />
NEA – Nichtdeterministischer<br />
endlicher Automat<br />
DKA – Kellerautomat<br />
Man kann – nach<br />
Festlegung von Typ und<br />
Alphabet – einen<br />
<strong>Automaten</strong> auch durch<br />
Zeichnen des<br />
Übergangsgraphen<br />
erzeugen:<br />
Zustände (der<br />
erste ist der<br />
Startzustand)<br />
Übergänge (Pfeile) durch Anklicken der beiden Zustände<br />
Labels (Beschriftungen der Übergänge durch<br />
Elemente des Alphabets)<br />
Der erstellte Automat kann auf Gültigkeit überprüft<br />
werden.<br />
Bei der Simulation kann man den <strong>Automaten</strong> eine<br />
Folge von Eingabezeichen abarbeiten lassen.<br />
Beim Exportieren wird auch gleich eine<br />
entsprechende Grammatik erzeugt<br />
11
<strong>10</strong>.11 JFLAP<br />
Download unter www.jflap.org<br />
(Auf meinem Rechner musste ich nach dem Auspacken von jflap.jar<br />
noch eine Batch-Datei erzeugen mit dem Inhalt<br />
javaw -classpath "JFLAP.jar" JFLAP<br />
um JFLAP starten zu können)<br />
<strong>Endliche</strong> <strong>Automaten</strong> gibt man grafisch ein<br />
Die Simulation findet man unter<br />
„Input“<br />
Unter „Convert to Grammar“ kann<br />
man die Eingabe einer passenden<br />
Grammatik üben oder sie sich<br />
gleich anzeigen lassen.<br />
12