Wenn Sie Automaten angeben, tun Sie dies immer in Form eines Zustandsgraphen. Andere Formen der Darstellung (z.B. als Liste von Übergängen) werden nicht gewertet, da sie sehr viel aufwändiger zu korrigieren sind. Vergessen Sie nicht, im Zustandsgraph Start- und Endzustände zu markieren.
FSK3-1 Konstruktion von NFAs (2 Punkte)
Verwenden Sie in dieser Aufgabe nur NFAs ohne ε-Übergänge
a) Geben Sie einen NFA an, der die folgende Sprache L über dem Alphabet Σ={a,b} akzeptiert:
L={uvw∣v,w∈Σ∗,v∈{bab,aa}}
Wörter dürfen nicht auf pfad stehen, nur Buchstaben
z0 kein Endzustand weil mindestens ein Wort drin sein muss
Beispielname für z0: ""
z1 Endzustand Variablenname mit mindestens einem Buchstaben
Beispielname für z1: “a” und danach rekursiv eventuell : “asdf123”
z2 kein Endzustand weil nur Unterstrich
Beispielname für z2: ”_” → nicht erlaubt
z3 ist ein Endzustand, da unterstrich am Anfang aber danach Zeichen folgt
Beispielname für z3: “_a” danach rekursiv “_asdf123”
c) Sei n eine natürliche Zahl, Σn={0,…,n} und
Note
Ln={w∈Σn∗∣i∈Σn,#i(w)=i}
Das heißt, die Sprache L enthält genau die Wörter w, für die gilt: Es gibt eine Zahl i∈{0,…,n} sodass das Wort w das Symbol i genau i-mal enthält.
Z.B. ist 2012323∈L3, da dieses Wort genau 1-mal das Symbol 1 enthält. Ebenso ist 20311233∈L3, da dieses Wort genau 2-mal das Symbol 2 enthält. Hingegen ist 0112223∈/L3.
Geben Sie für jedes n einen NFA An an, der Ln erkennt. Beschreiben Sie ausnahmsweise An nicht durch einen Zustandsgraph, sondern geben Sie die Zustandsmenge, Start- und Endzustände und Übergänge (in Abhängigkeit von n) explizit an. Geben Sie außerdem den Zustandsgraph von A3 an.
Gedankengang:
2012323∈L3 weil alle jede Ziffer kommt weniger als 2 mal vor L3={0,1,2}
0112223∈/L3 weil die 2 drei-mal vorkommt 3∈/L3
Summary
Definition des NFA An
Für die Definition eines Nichtdeterministischen Endlichen Automaten (NFA), der die Sprache Ln erkennt, gehen wir wie folgt vor:
Zustandsmenge:
Die Zustandsmenge Q von An besteht aus allen möglichen Zählerkonfigurationen für jedes Symbol in Σn, die angeben, wie oft jedes Symbol bis zu einem bestimmten Punkt im Wort erschienen ist. Zusätzlich gibt es einen besonderen Startzustand q0 und Fehlerzustände für unerlaubte Symbolzählungen.
Jeder Zustand q in Q kann durch ein Tupel (c0,c1,…,cn) repräsentiert werden, wobei ci die Anzahl des Symbols i in Σn ist, das bis jetzt gelesen wurde. Jedes ci kann Werte von 0 bis n annehmen, wobei Werte größer als n zu einem Fehlerzustand führen.
Startzustand:
Der Startzustand ist q0=(0,0,…,0), was bedeutet, dass noch kein Symbol gelesen wurde.
Akzeptierende Zustände:
Ein Zustand (c0,c1,…,cn) ist ein akzeptierender Zustand, wenn genau eine der Zählungen ci=i ist und alle anderen cj (für j=i) kleiner als j sind. Das heißt, genau ein Symbol i kommt genau i-mal vor, und kein anderes Symbol kommt öfter vor, als es seine Ziffer erlaubt.
Übergänge:
Von jedem Zustand (c0,c1,…,cn) gibt es einen Übergang zum Zustand (c0,c1,…,ci+1,…,cn) beim Lesen des Symbols i. Wenn ci+1>n, führt der Übergang in einen Fehlerzustand.
Fehlerzustände:
Fehlerzustände werden erreicht, wenn eine Zählung ci größer als n wird. Alle Übergänge von Fehlerzuständen führen wieder in Fehlerzustände.
Zustandsgraph für A3
Für den speziellen Fall von n=3 erstellen wir einen Zustandsgraphen:
Zustände: Jeder Zustand ist ein Tupel (c0,c1,c2,c3), wobei jedes ci von 0 bis 3 reichen kann. Zustände, in denen ci>i sind nicht Teil unseres Automaten.
Akzeptierende Zustände: Zustände wie (0,1,0,0), (0,0,2,0) und (0,0,0,3).
Startzustand: (0,0,0,0)
Übergänge: Basierend auf der obigen Beschreibung.
Lassen Sie uns eine detaillierte grafische Darstellung des Nichtdeterministischen Endlichen Automaten A3 erstellen, der die Sprache L3 erkennt. Diese Visualisierung wird die Zustandsmenge, akzeptierende Zustände, Startzustand und Übergänge für n=3 enthalten. Beachten Sie, dass ich zur Vereinfachung nur relevante Teile des Automaten zeige, da die vollständige Darstellung sehr umfangreich wäre.
Hier ist die grafische Darstellung von A3:
Zustandsgraph von A3
Zustände:
Jeder Zustand ist ein Tupel (c0,c1,c2,c3), wobei ci die Anzahl der Male darstellt, dass das Symbol i gelesen wurde. Nur diejenigen Zustände, bei denen keine ci die Bedingung ci>i erfüllt, sind gültig.
Fehlerzustände sind solche, bei denen mindestens ein ci>i.
Startzustand:
Der Startzustand ist (0,0,0,0).
Akzeptierende Zustände:
(0,1,0,0): Symbol 1 kommt genau einmal vor.
(0,0,2,0): Symbol 2 kommt genau zweimal vor.
(0,0,0,3): Symbol 3 kommt genau dreimal vor.
Übergänge:
Von jedem Zustand (c0,c1,c2,c3) gibt es Übergänge zu (c0+1,c1,c2,c3), (c0,c1+1,c2,c3), (c0,c1,c2+1,c3) und (c0,c1,c2,c3+1) beim Lesen der entsprechenden Symbole 0, 1, 2, bzw. 3. Übergänge, die zu ungültigen Zuständen führen, werden nicht gezeigt.
FSK3-2 Entfernen von ϵ-Übergängen und Potenzmengenkonstruktion (2 Punkte)
a) Sei A1 der folgende NFA über dem Alphabet {a,b,c}:
Geben Sie einen NFA A1′ ohne ϵ-Übergänge mit L(A1′)=L(A1) an. Verwenden Sie den Algorithmus zum Entfernen von ϵ-Übergängen aus der Vorlesung. Geben Sie die Zwischenschritte Ihrer Berechnung an. Das erlaubt uns, Ihnen für Folgefehler Teiilpunkte zu geben.
Alle Knoten die von z0 ausgehend mit dem leeren Wort erreicht werden können sind Startzustände und müssen behandelt werden. Dies ist nur bei z1 der Fall.
Muss mit einem Zeichen aus Σ beginnen und dann nur noch Epsilon Ketten. Kann von jedem Knoten Anfangen nicht nur von Startzuständen.
ϵ - Übergänge implizieren nicht das ϵ in der Sprache ist
z0→az2z2→ϵz3z3→ϵz0z0→ϵz1
Kann vereinfacht werden zu:
z0→az2z0→az3z0→az0z0→az1
Da der Pfad mit mit z0→az2 beginnt, darf z0→ϵz1 zu z0→az1 vereinfacht werden
Die Suche wird wesentlich beschleunigt, wenn wir A2 in einen DFA umwandeln. Verwenden Sie deshalb die Potenzmengenkonstruktion, um einen DFA A2′ mit L(A2′)=L(A2) zu konstruieren. Geben Sie außer dem Zustandsgraph von A2′ auch die Rechenschritte an, die Sie bei der Potenzmengenkonstruktion ausgeführt haben. Das erlaubt uns, Ihnen bei Folgefehlern noch Teilpunkte zu geben.
Ich werde den Inhalt des Bildes, das eine Textseite zum Thema Tokenizer zeigt, in Markdown-Format umwandeln, wobei mathematische Ausdrücke in LaTeX (mit $ für Inline und $$ für Display-Modus) und Code in Code-Blöcke eingefügt werden.
FSK3-3 Tokenizer
Aufgabenstellung
Ein Einsatzgebiet für endliche Automaten sind Tokenizer. Diese werden verwendet, um den Quelltext einer Programmiersprache in syntaktische Einheiten (Tokens) zu zerlegen. Ein Token ist beispielsweise ein Schlüsselwort, ein Bezeichner oder ein Operator.
Zum Beispiel wird das Programm
if (x==y) {z=x;}
zerlegt in
"if" "(" "x" "==" "y" ")" "{" "z" "=" "x" "}" ";"
In dieser Aufgabe erstellen wir einen Tokenizer, indem wir die möglichen Tokens als reguläre Sprache auffassen.
a) Um alle Schritte sinnvoll per Hand rechnen zu können, arbeiten wir mit einem reduzierten Alphabet (Σ statt Σ oder {}, weniger Buchstaben aus dem Alphabet, nur eine Ziffer, …):
Σ = \{a, x, o, [, ], -, '\,'\}
Um das erste Token aus einem String zu identifizieren, wird A vom Anfang des Strings aus laufen gelassen. Wenn der Lauf nie in einen Endzustand kommt, meldet der Tokenizer einen Fehler. Ansonsten wird die letzte Position, in welcher der Automat in einem Endzustand war, als Token-Ende genommen.
Zum Beispiel ist bei Eingabe ′==aa[′ der Lauf
q0→=q2→=q2→aqm→aqm→[qm
Da q2 akzeptierend ist (aber qm nicht), ist das erkannte Token ′==′.
Notieren Sie bei folgenden Strings die Zustände, die A bei Verarbeitung dieser Strings annehmen wird (die Läufe) und geben Sie je die Ausgabe des Tokenizers an. Bezüglich der Ausgabe reicht es, sofern der Tokenizer keinen Fehler zurückgibt, nur das erste erkannte Token anzugeben.
b) Bestimmen Sie asymptotisch (in O-Notation), wie viele Schritte der Tokenizer Automat braucht, um ein Token aus einem String der Länge n zu extrahieren
O(n), da die Verarbeitung von einem Zeichen ( O(1) ) ist und zweimal über den String gelaufen werden muss: Einmal zur Verarbeitung des Strings und einmal bei der Suche nach dem letzten Zustand, der ein Endzustand ist. (Man kann sich den jeweils letzten Endzustand natürlich auch merken, dann muss man nur einmal über den String laufen. Das ändert aber an der asymptotischen Laufzeit nichts.)
c) Um mehrere Tokens zu extrahieren, wird das gefundene Token von dem String entfernt und wieder von vorne ein Token gesucht. Wenn der verbleibende String leer ist, ist der Tokenizer fertig.
Beispiel: Bei der oben genannten Eingabe aa[ mit dem ersten Token , ist der Reststring nach dem Entfernen aa[, das zweite Token dann also aa.
Zerlegen Sie mit diesem Algorithmus den String a=“ax0”aa[0]=a in alle Tokens.
d) Tatsächlich müssen wir den String nicht verändern, sondern, wenn ein Token gefunden wurde, nur den Automaten an der nächsten Position im String starten. Wir „kürzen“ den String also in O(1). Wie viele Schritte brauchen wir dann asymptotisch, um alle Tokens aus einem String der Länge n zu finden?
Hinweis
Es ist nicht O(n). Man könnte das Verfahren aber optimieren, um eine Laufzeit von O(n) zu erreichen
Um alle Tokens in einem String der Länge n zu finden, indem wir einen Automaten verwenden, der an jeder Position im String startet, betrachten wir die folgenden Schritte:
Initialisierung: Der Automat startet an der Position 0 im String.
Durchlauf: Für jede Position i im String (von 0 bis n−1) startet der Automaten neu und versucht, ein Token zu erkennen.
Token-Erkennung: Sobald ein Token erkannt wird, wird der Automat an der nächsten Position im String gestartet. Die Länge des erkannten Tokens kann variieren.
Ende: Der Prozess endet, wenn der Automat an einer Position kein Token mehr erkennen kann oder das Ende des Strings erreicht ist.
Analyse der Laufzeit:
In jedem Schritt startet der Automat neu und durchläuft den Teilstring, der beginnt an der aktuellen Position bis zum Ende des Strings. Die maximale Anzahl von Schritten, die der Automat in einem Durchlauf machen kann, ist proportional zur Länge des Strings, also O(n) für jeden Startpunkt.
Da der Automat an jeder von n Positionen im String startet, beträgt die Gesamtzahl der Schritte n×O(n)=O(n2).
Optimierung (Zusatz)
Optimierung:
Um die Laufzeit auf O(n) zu optimieren, können wir folgende Techniken anwenden:
Überlappende Durchläufe vermeiden: Anstatt den Automaten jedes Mal von vorne zu starten, können wir den verbleibenden Teil des Strings nach dem Erkennen eines Tokens weiterverarbeiten. Dies bedeutet, dass der Automat direkt an der Stelle fortsetzt, an der das letzte Token endete.
Vorverarbeitung des Strings: Durch die Verwendung von Datenstrukturen wie Suffixbäumen oder Suffixarrays können wir die Suche nach Tokens effizienter gestalten, da diese Strukturen es ermöglichen, schnell zu überprüfen, ob ein bestimmter Teilstring ein gültiges Token ist.
Durch die Anwendung dieser Optimierungen können wir die Anzahl der benötigten Schritte auf O(n) reduzieren, was eine effiziente Lösung für das Problem darstellt.
FSK3-4 Umgedrehte Sprache (0 Punkte)
Aufgabenstellung
Sei T die Funktion, die aus einem NFA A=(Z,Σ,δ,S,E) einen NFA T(A)=(Z,Σ,δ0,E,S) erzeugt, wobei p∈δ0(q,a)⇔q∈δ(p,a).
w=ϵ: Die Definition von δ liefert sofort δ(q,ϵ)={q}=δ′(q,ϵ)
Schritt:
a1⋅…⋅an→a1⋅…⋅an+1:
qg.d.w. g.d.w. g.d.w. g.d.w. ∈δ^(p,an+1⋅…⋅a1)∃z∈Z:z∈δ(p,an+1)∧q∈δ^(z,an⋅…⋅a1)∃z∈Z:z∈δ(p,an+1)∧z∈δ′^(q,a1⋅…⋅an)∃z∈Z:p∈δ′(z,an+1)∧z∈δ′^(q,a1⋅…⋅an)p∈δ′^(q,a1⋅…⋅an+1)(Definition von δ^)(mit IH)(Definition von δ′)(Definition von δ′)
Der gegebene Beweis zeigt die Äquivalenz der Sprachen eines nichtdeterministischen endlichen Automaten (NFA) A und seines transformierten Automaten T(A). Die Transformation besteht darin, die Übergangsfunktion δ so zu ändern, dass sie Wörter rückwärts akzeptiert. Hier wird gezeigt, dass das Rückwärtslesen eines Wortes in A dem Vorwärtslesen in T(A) entspricht.
Der Beweis nutzt eine Induktion über die Länge eines Wortes w und verwendet eine umgekehrte Übergangsfunktion δ′, die im rückwärts transformierten Automaten T(A) verwendet wird. Der Hauptansatz besteht darin, die Äquivalenz der Übergänge zwischen den Zuständen in A und T(A) für alle Zustände q,p∈Z und alle Wörter w∈Σ∗ zu zeigen.
Basisfall
Der Basisfall betrachtet das leere Wort ϵ. Die Übergangsfunktion δ eines jeden NFA definiert, dass δ(q,ϵ)={q}. Da δ′ analog definiert ist, gilt auch δ′(q,ϵ)={q}. Damit ist der Basisfall bestätigt: Für das leere Wort bleibt man im gleichen Zustand, sowohl in A als auch in T(A).
Induktionsschritt
Im Induktionsschritt wird die Behauptung von Wörtern der Länge n auf Wörter der Länge n+1 erweitert. Wir betrachten ein Wort an+1⋅…⋅a1. Der Beweis geht davon aus, dass der Übergang von einem Zustand p zu einem Zustand q in A mittels des Wortes an+1⋅…⋅a1 einem Übergang in T(A) entspricht, wenn das Wort a1⋅…⋅an+1 betrachtet wird. Durch die Induktionshypothese und die Definition der Übergangsfunktion δ′ wird gezeigt, dass diese beiden Übergänge äquivalent sind.
Zusammenfassung des Beweises
Der Beweis schließt mit dem Nachweis, dass ein Wort w von A akzeptiert wird, wenn und nur wenn das rückwärts gelesene Wort w von T(A) akzeptiert wird. Dies geschieht durch den Zusammenhang der anfänglichen und endgültigen Zustände und deren Erreichbarkeit über die Übergangsfunktionen δ und δ′.
Durch diesen Beweis wird etabliert, dass L(T(A))={w∣w∈L(A)} gilt. Dies bedeutet, dass die Sprache von T(A) genau aus den umgekehrten Wörtern der Sprache von A besteht, was zeigt, dass das Rückwärtslesen der Wörter in A äquivalent zum Vorwärtslesen in $T(A) ist.
×
MyUniNotes is a free, non-profit project to make education accessible for everyone.
If it has helped you, consider giving back! Even a small donation makes a difference.
These are my personal notes. While I strive for accuracy, I’m still a student myself. Thanks for being part of this journey!