\section{Les automates}

Dans cette partie, nous parlerons des automates et plus particulièrement, nous
allons parler des automates sans \(\varepsilon\)-transition (des automates
utilisent des \(\varepsilon\)-transitions, comme ceux de
\textit{Thompson}~\cite{thompson1968programming}, qui sont utilisés par nos
ordinateurs). Pour autant, les automates que nous verrons ne sont pas limités
par le manque de ces transitions.

\subsection{Définition}

Comme dit précédemment, un automate est un objet mathématique reconnaissant un
langage. On notera \(M \in AFN(\Sigma, \eta)\) l'automate qui a pour transition
des valeurs dans \(\Sigma\), des valeurs \og{}d'état\fg{} dans \(\eta\). Et
\(AFN(\Sigma, \eta)\) l'ensemble des automates finis non déterministes de
valeur de transition dans \(\Sigma\) et de valeur d'état dans \(\eta\). On
écrira \(L(M)\) pour désigner le langage qu'il reconnait. Un automate est un
tuple qu'on peut écrire de cette forme \(M = (Q, I, F, \delta)\) avec~:

\begin{align*}
    Q & \subseteq \eta \quad \text{L'ensemble des états qui constituent
    l'automate}                                                                \\
    I & \subseteq Q \quad \text{L'ensemble des états initiaux}          \\
    F & \subseteq Q \quad \text{L'ensemble des états finaux}            \\
    \delta:~ & Q \times \Sigma \to 2^Q \quad \text{La fonction de transition}
\end{align*}

Un automate peut se représenter à l'aide d'un graphe orienté, valué,
particulier. Par exemple si on veut représenter \(M = (\{q_1, q_2, q_3, q_4,
q_5\}, \{q_1\},\{q_2, q_3\}, \delta)\) avec \(M \in AFN(\Sigma, \eta)\),
\(\Sigma = \{0, 1\}\), \(\eta = \{q_1, q_2, q_3, q_4, q_5\}\) et \(\delta\)
défini comme ceci~:

\begin{align*}
    \delta(q_1, 0) & = \{q_2, q_4\} & \delta(q_3, 1) & = \{q_4\} \\
    \delta(q_1, 1) & = \varnothing  & \delta(q_4, 0) & = \{q_5\} \\
    \delta(q_2, 0) & = \varnothing  & \delta(q_4, 1) & = \{q_3\} \\
    \delta(q_2, 1) & = \varnothing  & \delta(q_5, 0) & = \{q_4\} \\
    \delta(q_3, 0) & = \{q_3\}      & \delta(q_5, 1) & = \{q_5\} \\
\end{align*}

\begin{figure}[H]
    \centering
    \captionsetup{type=figure,justification=centering}
    \begin{tikzpicture}
        \tikzset{
            ->,
            >=stealth',
            node distance=3cm,
            every state/.style={thick},
            initial text=$ $,
        }
        \node[state, initial] (q1) {$q_1$};
        \node[state, accepting, right of=q1] (q2) {$q_2$};
        \node[state, above of=q2] (q4) {$q_4$};
        \node[state, accepting, right of=q2] (q3) {$q_3$};
        \node[state, right of=q4] (q5) {$q_5$};

        \draw   (q1) edge[above] node{0} (q4)
        (q1) edge[below] node{0} (q2)
        (q4) edge[bend right, below] node{1} (q3)
        (q4) edge[above] node{0} (q5)
        (q3) edge[above] node{1} (q4)
        (q3) edge[loop right] node{0} (q3)
        (q5) edge[bend right, above] node{0} (q4)
        (q5) edge[loop right] node{1} (q5);
    \end{tikzpicture}
    \caption{
        Exemple de représentation graphique d'un automate.
    }\label{fig:automata}
\end{figure}

Dans la Figure~\ref{fig:automata}, on peut voir que les états initiaux (dans
cet automate n'y a qu'un seul initial~; \(q_1\)) ont une petite flèche qui
pointe sur eux et que les états finaux ont un double contour. Et que les
transitions sont symbolisées par des flèches entre les états et que ces flèches
sont labellisées.

% \vphantom{}

% On parlera de l'inverse de l'automate \(M\) noté \(\overleftarrow{M}\) qui peut
% être défini de cette façon~:

% \begin{gather*}
%     \overleftarrow{M} = (Q, F, I, \delta') \quad \text{avec} \\
%     M = (Q, I, F, \delta) \notag \\
%     \forall (p, q) \in Q^2 ~|~ q \in \delta(p, a) \Rightarrow p \in \delta'(q, a) \notag
% \end{gather*}

% Donc si on veut représenter l'inverse de l'automate représenté dans la
% Figure~\ref{fig:automata}, ça nous donnerait ceci~:

% \begin{figure}[H]
%     \centering
%     \captionsetup{type=figure,justification=centering}
%     \begin{tikzpicture}
%         \tikzset{
%             ->,
%             >=stealth',
%             node distance=3cm,
%             every state/.style={thick},
%             initial text=$ $,
%         }
%         \node[state, accepting] (q1) {$q_1$};
%         \node[state, initial below, right of=q1] (q2) {$q_2$};
%         \node[state, above of=q2] (q4) {$q_4$};
%         \node[state, initial below, right of=q2] (q3) {$q_3$};
%         \node[state, right of=q4] (q5) {$q_5$};

%         \draw   (q4) edge[above] node{0} (q1)
%         (q2) edge[below] node{0} (q1)
%         (q3) edge[bend left, below] node{1} (q4)
%         (q5) edge[above] node{0} (q4)
%         (q4) edge[above] node{1} (q3)
%         (q3) edge[loop right] node{0} (q3)
%         (q4) edge[bend left, above] node{0} (q5)
%         (q5) edge[loop right] node{1} (q5);
%     \end{tikzpicture}
%     \caption{
%         Exemple de représentation graphique de l'inverse de l'automate de la
%         Figure~\ref{fig:automata}.
%     }\label{fig:automata_invserse}
% \end{figure}

% On voit bien que l'apparence de l'automate ne change pas les transitions sont
% juste inversées et les états initiaux sont devenus finaux et inversement.

\vphantom{}

On peut aussi étendre la fonction de transition \(\delta\) de manière qu'elle
ait comme signature~:

\[
    \delta: Q \times \Sigma^* \to 2^Q
\]

En la définissant récursivement de telle sorte~:

\begin{align*}
    \delta(q, \varepsilon) & = \{q\}                                                                       \\
    \delta(q, a \cdot w)   & = \bigcup_{q' \in \delta(q, a)} \delta(q', w) \quad \text{avec}~ a \in \Sigma
\end{align*}

\begin{example}
    Voici donc quelques exemples si on prend l'automate utilisé pour la
    représentation graphique (Figure~\ref{fig:automata})~:

    \begin{align*}
        \delta(q_1, 00)           & = \{q_5\}                                \\
        \delta(q_1, 11)           & = \varnothing                            \\
        \delta(q_1, \varepsilon)  & = \{q_1\}                                \\
        \delta(q_1, 00 \cdot 1^n) & = \{q_5\} \text{ avec } n \in \mathbb{N}
    \end{align*}
\end{example}

\vphantom{}

\begin{definition}
    Un automate est dit \textit{standard} quand il ne possède qu'un seul état
    initial non ré-entrant, aussi défini comme ceci~:

    \begin{gather*}
        M = (Q, \{i\}, F, \delta) \quad \text{avec} \\
        \forall p \in Q, \forall a \in \Sigma ~|~ i \notin \delta(p, a) \notag \\
        M \in AFN(\Sigma, \eta) \notag
    \end{gather*}
\end{definition}

\begin{definition}
    Un automate est \textit{homogène} lorsque, pour tous les états, les
    transitions allant vers cet état ont la même valeur. En d'autres termes,
    quand il respecte cette propriété~:

    \begin{gather*}
        M = (Q, I, F, \delta) \quad \text{avec} \\
        \forall (p, q, r) \in Q^3, \exists (a, b) \in \Sigma^2 ~|~ q \in \delta(p, a) \land q \in \delta(r, b) \Longrightarrow a = b \notag \\
        M \in AFN(\Sigma, \eta) \notag
    \end{gather*}
\end{definition}

\begin{definition}
    Un automate est qualifié d'\textit{accessible} lorsqu'en partant des
    initiaux, on peut arriver sur tous les états qui le composent. C'est-à-dire
    qu'il valide cette condition~:

    \begin{gather*}
        M = (Q, I, F, \delta) \quad \text{avec} \\
        \forall p \in Q, \exists w \in \Sigma^* ~|~ p \in \bigcup_{i \in I} \delta(i, w) \notag \\
        M \in AFN(\Sigma, \eta) \notag
    \end{gather*}
\end{definition}

\begin{definition}
    Un automate est considéré comme \textit{coaccessible} dès que, de tous les
    états, on peut arriver à un état final. Ceci veut dire qu'il atteste de
    cette particularité~:

    \begin{gather*}
        M = (Q, I, F, \delta) \quad \text{avec} \\
        \forall p \in Q, \exists w \in \Sigma^* ~|~ F \cap \delta(p, w) \neq \varnothing \notag \\
        M \in AFN(\Sigma, \eta) \notag
    \end{gather*}
\end{definition}

\begin{definition}
    Un automate est dit \textit{déterministe} quand tous ses états vont au
    maximum à un état par symbole et que l'automate ne possède qu'un seul état
    initial. Autrement dit qu'il valide cette propriété~:

    \begin{gather*}
        M = (Q, I, F, \delta) \quad \text{avec} \\
        |I| = 1 \land \forall q \in Q, \forall a \in \Sigma, | \delta(q, a) | \leq 1\\
        M \in AFN(\Sigma, \eta) \notag
    \end{gather*}

    On parlera de \textit{déterministe complet} lorsque tous ses états vont sur
    un état par symbole. C'est-à-dire qu'il respecte cette condition~:

    \begin{gather*}
        M = (Q, I, F, \delta) \quad \text{avec} \\
        |I| = 1 \land \forall q \in Q, \forall a \in \Sigma, | \delta(q, a) | = 1\\
        M \in AFN(\Sigma, \eta) \notag
    \end{gather*}
\end{definition}

\begin{example}
    Donc, l'automate représenté sur la Figure~\ref{fig:automata} est standard,
    non homogène, accessible et coaccessible. Car il possède bien un unique
    état initial (\(q_1\)), mais \(q_3\), \(q_4\) et \(q_5\) ne respecte pas la
    propriété pour être homogène, parce qu'ils ont des transitions allant vers
    eux avec des valeurs différentes. De plus, tous ses états sont accessibles
    depuis l'état initial. Et son inverse est, lui-même aussi, accessible et il
    n'est pas déterministe.
\end{example}

\begin{definition}
    Nous parlerons de sous-automate pour parler d'une \og{}région\fg{} d'un
    automate. \(N\) est un sous automate de \(M\) qu'on notera \(N \subseteq
    M\), s'il vérifie cette propriété~:

    \begin{gather*}
        N = (Q', I', F', \delta') \quad \text{avec} \\
        Q' \subseteq Q \land I' \subseteq Q' \land F' \subseteq Q' \\
        \delta' \text{ est une restriction de } \delta, \delta': Q' \to 2^{Q'}\\
        M = (Q, I, F, \delta) \land (M, N) \in (AFN(\Sigma, \eta))^2 \notag
    \end{gather*}
\end{definition}

Les automates pouvant être représentés à l'aide de graphes, on peut étendre les
propriétés sur les graphes aux automates. Par exemple, on pourra parler des
composantes fortement connexes d'un automate. Autrement dit, en partant de
n'importe quel état, on peut arriver à tous les autres états. Ainsi, ça veut
dire qu'un automate fortement connexe vérifierait ceci~:

\begin{gather*}
    M = (Q, I, F, \delta) \quad \text{avec} \\
    \forall (p, q) \in Q^2, \exists w \in \Sigma^* ~|~ q \in \delta(p, w) \notag \\
    M \in AFN(\Sigma, \eta) \notag
\end{gather*}

\begin{definition}
    Une autre notion qui est présente sur les graphes que nous allons adapter
    sur les automates est la notion de \textit{hamac}. Nous dirons qu'un
    automate est un \textit{hamac} lorsqu'il est standard, accessible et
    coaccessible (nous gardons le nom \textit{hamac} pour une raison de
    compréhension). Ceci veut dire qu'il peut être décrit comme ceci~:

    \begin{gather*}
        M = (Q, I, F, \delta) \quad \text{avec} \\
        standard(M) \land accessible(M) \land coaccessible(M) \\
        M \in AFN(\Sigma, \eta) \notag
    \end{gather*}
\end{definition}

\begin{definition}
    Une autre idée empruntée au graphe est la notion d'\textit{orbite}. Nous
    dirons qu'un sous-automate est une \textit{orbite}, si pour tout couple
    d'état \(i\) et \(t\), il existe un mot non vide permettant d'aller de
    \(i\) à \(t\). Aussi défini comme ceci~:

    \begin{gather*}
        \mathcal{O} = (Q, I, F, \delta) \quad \text{avec} \\
        \forall (p, q) \in Q^2, \exists w \in \Sigma^* \setminus \{\varepsilon\} ~|~ q \in \Sigma(p, w) \\
        \mathcal{O} \subseteq M \land M \in AFN(\Sigma, \eta)
    \end{gather*}

    \noindent Dans la même idée, nous parlerons d'\textit{orbite maximale}
    lorsque l'orbite n'est incluse dans aucune orbite différente. En d'autres
    termes, que l'orbite est fortement connexe sans prendre les chemins
    triviaux
    (mot vide).
\end{definition}

\begin{definition}
    Nous noterons \(In(\mathcal{O})\) et \(Out(\mathcal{O})\) respectivement
    l'ensemble des portes d'entrée et l'ensemble des portes de sortie de
    l'orbite \(\mathcal{O}\). Qui sont définies de cette façon~:

    \begin{gather*}
        In(\mathcal{O}) = \{p \in Q' ~|~ \exists a \in \Sigma, \exists q \in Q
        \setminus Q', p \in \delta(q, a)\} \cup I'\\
        Out(\mathcal{O}) = \{p \in Q' ~|~ \exists a \in \Sigma, \exists q \in Q
        \setminus Q', q \in \delta(p, a)\} \cup F'\\
        \text{avec} \\
        \mathcal{O} = (Q', I', F', \delta') \land M = (Q, I, F, \delta) \\
        \mathcal{O} \subseteq M \land M \in AFN(\Sigma, \eta)
    \end{gather*}
\end{definition}

\begin{definition}
    Avec ceci, on peut définir ce qu'est une \textit{orbite stable}. Une orbite
    est dite \textit{stable} quand pour toutes les sorties, il existe une
    transition vers toutes les entrées. C'est-à-dire que l'orbite vérifie
    ceci~:

    \begin{gather*}
        \forall q \in Out(\mathcal{O}), \exists a \in \Sigma ~|~ \delta(q, a) \cap In(\mathcal{O}) \neq \varnothing \\
        \text{avec} \\
        \mathcal{O} = (Q, I, F, \delta) \subseteq M \land M \in AFN(\Sigma, \eta)
    \end{gather*}

    \noindent On la qualifiera même de \textit{fortement stable} lorsqu'en
    supprimant toutes les transitions de portes des sorties vers les portes
    d'entrée, les orbites maximales de l'orbite sont stables et
    \textit{fortement stables}.
\end{definition}

\begin{definition}
    De même, on dira qu'une orbite est \textit{transversale} si toutes les
    entrées viennent des mêmes états et que toutes les sorties vont aux mêmes
    états. Autrement dit, que l'orbite valide cette propriété~:

    \begin{gather*}
        \forall (p, q) \in (Out(\mathcal{O}))^2, (\bigcup_{a \in \Sigma} \delta(p, a)) \cap Q \setminus Q' = (\bigcup_{a \in \Sigma} \delta(q, a)) \cap Q \setminus Q' \\
        \forall (p, q) \in (In(\mathcal{O}))^2, \{r \in Q \setminus Q' ~|~ \exists a \in \Sigma, p \in \delta(r, a)\} = \{r \in Q \setminus Q' ~|~ \exists a \in \Sigma, q \in \delta(r, a)\} \\
        \text{avec} \\
        \mathcal{O} = (Q', I', F', \delta) \subseteq M = (Q, I, F, \delta) \land M \in AFN(\Sigma, \eta)
    \end{gather*}

    \noindent Elle sera même \textit{fortement transversale} lorsqu'en
    supprimant toutes les transitions de portes des sorties vers les portes
    d'entrée, les orbites maximales de l'orbite sont transversales et
    \textit{fortement transversales}.
\end{definition}

\subsection{Fonction sur les automates}

Une des fonctions sur les automates est \(accept\) qui vérifie si le mot est
reconnu par l'automate. C'est-à-dire que si on prend le chemin décrit par le
mot donné en argument, on arrive sur un ou plusieurs états finaux. Elle a alors
pour signature~:

\[
    accept: AFN(\Sigma, \eta) \times \Sigma^* \to \mathbb{B}
\]

Elle peut être définie simplement comme ceci~:

\begin{align*}
    accept(M, w) = (\bigcup_{p \in I} \delta(p, w)) \cap F \neq \varnothing
\end{align*}

Une autre fonction sur les automates est \(homogenize\) qui renvoie l'automate
homogène qui reconnait le même langage que l'automate donné. Elle a ainsi comme
signature~:

\[
    homogenize: AFN(\Sigma, \eta) \to AFN(\Sigma, ((\Sigma \cup \{\varepsilon\}) \times \eta))
\]

Elle peut être définie de cette façon~:

\begin{gather*}
    homogenize(M) = N \quad \text{avec}                                                          \\
    \forall (p, q) \in Q^2, \exists a \in \Sigma ~|~ p \in \delta(q, a) \Rightarrow (a, p) \in Q' \\
    \forall (p, q) \in Q^2, \forall a \in \Sigma ~|~ p \notin \delta(q, a)
    \Rightarrow (\varepsilon, p) \in Q' \\
    \forall p \in I, \forall a \in \Sigma \cup \{\varepsilon\} ~|~ (a, p) \in Q' \Rightarrow (a, p) \in I' \\
    \forall p \in F, \forall a \in \Sigma \cup \{\varepsilon\} ~|~ (a, p) \in Q' \Rightarrow (a, p) \in F' \\
    \forall (p, q) \in Q, \exists a \in \Sigma, \forall b \in \Sigma \cup \{\varepsilon\} ~|~ (b, q) \in Q', p \in \delta(q, a) \Rightarrow (p, a) \in \delta'((b, q), a) \\
    M = (Q, I, F, \delta) \in AFN(\Sigma, \eta) \\
    N = (Q', I', F', \delta') \in AFN(\Sigma, ((\Sigma \cup \{\varepsilon\})
    \times \eta))
\end{gather*}

On remarque bien que par construction l'automate résultant est homogène, parce
que les états sont devenus un couple entre leur valeur et leur transition
entrante. Ce qui fait que toutes les transitions vers l'état \((a, p)\) ont
tous pour valeur \(a\).

\subsection{Conclusion}

Comme nous venons de voir, les automates sont des outils pour reconnaitre des
mots d'un langage. L'une de leurs grandes forces est leur simplicité. Toutes
les opérations sur les automates peuvent donc être automatisées. Ce qui fait
que cet objet est très intéressant dans le monde de l'informatique. En
revanche, l'un de ses points faibles est que pour nous humain, il est difficile
de représenter un automate autrement que par une représentation graphique.
Contrairement aux expressions régulières. Il serait alors intéressant de
pouvoir convertir une expression régulière en automate. On pourrait se poser la
question \og{}est-ce-que c'est toujours possible de convertir une expression
régulière en automate\fg{}, la réponse est oui, car selon le théorème de
Kleene~\cite{Kleene1951RepresentationOE}, toute expression régulière peut être
représentée par un automate fini. Nous allons voir un algorithme pour faire
cette conversion dans la prochaine section.
