\subsection{Darstellung} Folgende Fragen müssen zur Definition eines Berechnungsmodells beantwortet werden: \begin{enumerate} \item Welche elementaren Operationen stehen zur Verfügung (um das Programm zusammenzustellen)? \item Wie funktioniert der Speicher? \item Wie funktioniert die Eingabe (und welches Alphabet verwendet sie)? \item Wie funktioniert die Ausgabe (und welches Alphabet verwendet sie)? \end{enumerate} Endliche Automaten haben keinen Speicher, mit Ausnahme des Zeigers (can be understood similarly to a program counter) Ein endlicher Automat mit dem Eingabealphabet $\Sigma = \{ a_1, \ldots, a_k \}$ darf nur den Operationstyp \texttt{select} verwenden. \begin{align*} \texttt{select } input & = a_1 \texttt{ goto } i_1 \\[-0.2cm] \vdots \\ input & = a_k \texttt{ goto } i_k \end{align*} Alternativ, falls $|\Sigma| = 2$ (typischerweise für $\alphabets{bool}$), kann man statt \texttt{select} auch \texttt{if\dots then\dots else} nutzen. Typischerweise werden solche Programme für Entscheidungsprobleme genutzt und die Checks sind dann: \begin{align*} \texttt{if } input = 1 \texttt{ then goto } i \texttt{ else goto } j \end{align*} Wir wählen eine Teilmenge $F \subseteq \{ 0, \ldots, m - 1 \}$, wobei $m$ die Anzahl Zeilen des Programms ist. Ist die Zeile auf der das Programm endet ein Element von $F$, so akzeptiert das Programm die Eingabe. Die Menge $F$ wird auch die \bi{vom Programm akzeptierte Sprache} genannt % Ein Programm $A$ arbeitet dann Buchstabe für Buchstabe das Eingabewort ab und springt so also kontinuierlich durch das Programm bis die Eingabe endet. Mit formaleren Begriffen ist das Eingabewort als \bi{Band} dargestellt, welches von einem \bi{Lesekopf}, der sich nur nach links oder rechts bewegen kann gelesen wird und die gelesene Eingabe dann dem \bi{Programm} weitergibt. Diese Notation wird jedoch heute kaum mehr verwendet (because \texttt{goto} bad, Prof. Roscoe would approve). Heute verwendet man meist einen gerichteten Graphen $G(A)$: \begin{itemize} \item Hat so viele Knoten (= \bi{Zustände}) wie das Programm $A$ Zeilen hat \item Wenn das Programm beim Lesen von Symbol $b$ von Zeile $i$ auf $j$ sprint, so gibt es in $G(A)$ eine gerichtete Kante $(i, j)$ von Knoten $i$ nach Knoten $j$ mit Markierung $b$. Sie wird als \bi{Übergangsfunktion} bezeichnet \item Jeder Knoten hat den Ausgangsgrad $|\Sigma|$ (wir müssen alle Fälle abdecken) \end{itemize} \begin{definition}[]{Endlicher Automat} Ist eine Quitupel $M = (Q, \Sigma, \delta, q_0, F)$: \begin{enumerate}[label=\textit{(\roman*)}] \item $Q$ ist eine endliche Menge von \bi{Zuständen} \item $\Sigma$ ist das \bi{Eingabealphabet} \item $\delta: Q \times \Sigma \rightarrow Q$ ist die \bi{Übergangsfunktion}. $\delta(q, a) = p$ bedeutet Übergang von Zustand $q$ nach $p$ falls in $q$ $a$ gelesen wurde \item $q_0 \in Q$ ist der \bi{Anfangszustand} \item $F \subseteq Q$ ist die \bi{Menge der akzeptierenden Zustände} \end{enumerate} \rmvspace \rmvspace \begin{multicols}{2} \begin{itemize} \item \bi{Konfiguration}: Element aus $Q \times \Sigma^*$ \item \bi{Startkonfiguration} auf $x$: $(q_0, x)$ \item \bi{Endkonfiguration}: Jede aus $Q \times \{ \lambda \}$ \end{itemize} \end{multicols} \rmvspace \rmvspace \begin{itemize} \item \bi{Schritt}: Relation auf Konfigurationen $\bigvdash{M}{} \subseteq (Q \times \Sigma^*) \times (Q \times \Sigma^*$ definiert durch $(q, w) \bigvdash{M}{} (p, x) \Leftrightarrow w = ax, a \in \Sigma \text{ und } \delta(q, a) = p$. Einfacher: Anwendung von $\delta$ auf die aktuelle Konfiguration \item \bi{Berechnung} $C$: Endliche Folge von Konfigurationen, $C_i \bigvdash{M}{} C_{i + 1}$. Auf Eingabe $x \in \Sigma^*$, $C_0$ Startkonfiguration und $C_n$ Endkonfiguration. Falls $C_n \in F \times \{ \lambda \}$, $C$ \bi{akzeptierende Berechnung}, $M$ \bi{akzeptiert Wort} $x$. Anderenfalls ist $C$ eine \bi{verwerfende Berechnung} und $M$ \bi{verwirft (akzeptiert nicht) das Wort} $x$ \item \bi{Akzeptierte Sprache} $L(M) = \{ w \in \Sigma^* \divides \text{$M$ akzeptiert das Wort } w \text{ und $M$ endet in Endkonfig.} \}$ \item $\mathcal{L}_{EA} = \{ L(M) | M \text{ ist ein EA}\}$ ist die Klasse aller Sprachen die von endlichen Automaten akzeptiert werden, auch genannt \bi{Klasse der regulären Sprachen} und für jede Sprache $L \in \mathcal{L}_{EA}$ gilt: $L$ regulär \end{itemize} \end{definition} Die Übergangsfunktion kann auch gut graphisch oder tabellarisch (wie eine Truth-Table) dargestellt werden. \begin{definition}[]{Reflexive und transitive Hülle} Sei $M = (Q, \Sigma, \delta, q_0, F)$ ein endlicher Automat. Die reflexive und transitive Hülle $\bigvdash{M}{*}$ der Schrittrelation $\bigvdash{M}{}$ von $M$ als $(q, w) \bigvdash{M}{*} (p, u) \Leftrightarrow (q = p \land w = u) \lor \exists k \in \N - \{ 0 \}$ so dass \begin{enumerate}[label=\textit{(\roman*)}] \item $w = a_1\ldots a_ku, a_i \in \Sigma$ für $i = 1, \ldots, k$ \item $\exists r_1, \ldots, r_{k - 1} \in Q$, so dass $(q, w) \bigvdash{M}{} (r_1, a_2 \ldots a_k u) \bigvdash{M}{} (r_2, a_3 \ldots a_k u) \bigvdash{M}{} \ldots (r_{k - 1}, a_k u) \bigvdash{M}{} (p, u)$ \end{enumerate} Wir definieren $\hat{\delta}: Q \times \Sigma^* \rightarrow Q$ durch \rmvspace \rmvspace \begin{multicols}{2} \begin{enumerate}[label=\textit{(\roman*)}] \item $\hat{\delta}(q, \lambda) = q \smallhspace \forall q \in Q$ \item $\hat{\delta}(q, wa) = \delta(\hat{\delta}(q, w), a) \forall a \in \Sigma, w \in \Sigma^*, q \in Q$ \end{enumerate} \end{multicols} \end{definition} Und $(q, w) \bigvdash{M}{*} (p, u)$ bedeutet, dass es eine Berechnung von $M$ gibt, die von der Konfiguration $(q, w)$ zu $(p, u)$ führt, während $\hat{\delta}(q, w) = p$ bedeutet einfach $(q, w) \bigvdash{M}{*} (p, \lambda)$, also falls $M$ im Zustand $q$ das Wort $w$ zu lesen beginnt, $M$ im Zustand $p$ endet. Also gilt $L(M) = \{ w \in \Sigma^* \divides (q_0, w) \bigvdash{M}{*} (p, \lambda) \text{ mit } p \in F \} = \{ w \in \Sigma^* \divides \hat{\delta}(q_0, w) \in F \}$ \inlinelemma $L(M) = \{ w \in \{ 0, 1 \}^* \divides |w|_0 + |w|_1 \equiv 0 \text{ mod } 2 \}$ Jeder EA teilt die Menge $\Sigma^*$ in $|Q|$ Klassen $\text{Kl}[p] = \{ w \in \Sigma^* \divides \hat{\delta}(q_0, w) = p \} = \{ w \in \Sigma^* \divides (q_0, w) \bigvdash{M}{*} (p, \lambda) \}$ und entsprechend $\bigcup_{p \in Q} \text{Kl}[p] = \Sigma^*$ und $\text{Kl}[p] \text{Kl}[q] = \emptyset \smallhspace \forall p \neq q \in Q$. \shade{Cyan}{Intuition}: Die Klassen sind Mengen, die hier Wörter mit gewissen Eigenschaften, die der EA bestimmt hat, wenn er in Zustand $q_i$ endet, enthalten. Diese Eigenschaften sind beispielsweise, dass alle Wörter, für die der EA in Zustand $q_i$ endet mit einer gewissen Sequenz enden, sie einen gewissen Zahlenwert haben, etc. In dieser Terminologie gilt dann $L(M) = \bigcup_{p \in F} \text{Kl}[p]$. Die Notation $|w|_i$ bedeutet die Länge der Buchstaben $i$ in $w$. Wir können $L(M)$ mit Klassen bestimmen und haben eine Äquivalenzrelation $x R_\delta y \Leftrightarrow \hat{\delta}(q_0, x) = \hat{\delta}(q_0, y)$ auf $\Sigma^*$. Man beweist die Korrektheit der gewählten Klassen oft mithilfe von Induktion über die Länge der Wörter. Wir beginnen mit der Länge an Wörtern der Länge kleiner gleich zwei und erhöhen dies dann während unseres Induktionsschrittes. Die Klassen bestimmen wir vor dem Beginn der Induktion auf und jede Klasse repräsentiert einen der Zustände. \begin{wrapfigure}[5]{l}{0.3\textwidth} \begin{tables}{ccc}{Zustand & 0 & 1} $q_0$ & $q_2$ & $q_1$ \\ $q_1$ & $q_3$ & $q_0$ \\ $q_2$ & $q_0$ & $q_3$ \\ $q_3$ & $q_1$ & $q_2$ \\ \end{tables} \end{wrapfigure} Haben wir einen EA mit nebenstehender Tabelle, so sind die Klassen für unseren EA $M$ sind $\class[q_0], \ldots, \class[q_3]$, definiert durch: \rmvspace \begin{align*} \class[q_0] & = \{ w \in \wordbool \divides |w|_0 \text{ und } |w|_1 \text{ sind gerade} \} \\ \class[q_1] & = \{ w \in \wordbool \divides |w|_0 \text{ ist gerade, } |w|_1 \text{ ist ungerade} \} \\ \class[q_2] & = \{ w \in \wordbool \divides |w|_0 \text{ ist ungerade, } |w|_1 \text{ ist gerade} \} \\ \class[q_3] & = \{ w \in \wordbool \divides |w|_0 \text{ und } |w|_1 \text{ sind ungerade} \} \end{align*} % Falls ein EA $A$ genügend anschaulich und strukturiert dargestellt ist, kann man die Sprache $L(A)$ auch ohne Beweis bestimmen. Idealerweise konstruieren wir einen EA so, dass wir die Menge aller Wörter aus $\Sigma^*$ so in Klassen aufteilen, sodass Wörter mit denselben Eigenschaften in derselben Klasse liegen und wir dann Übergangsfunktionen zu anderen Klassen finden, die nur einen Buchstaben aus $\Sigma$ zum Wort hinzufügen \inlineex Das Buch enthält einige zwei gute Beispiele (Beispiel 3.1 und 3.2) mit ausführlichen Erklärungen ab Seite 58 (= Seite 73 im PDF).