381 lines
15 KiB
TeX
381 lines
15 KiB
TeX
\documentclass[a4paper,french]{article}
|
|
|
|
\title{Mathématiques pour l'informatique\\Automates finis}
|
|
\author{}
|
|
\date{Dernière compilation~: \today{} à \currenttime}
|
|
|
|
\usepackage{../cours}
|
|
|
|
\begin{document}
|
|
|
|
\maketitle
|
|
\tableofcontents
|
|
|
|
\clearpage
|
|
\section{Définitions}
|
|
|
|
Automate = fonction qui dépend d'un état et d'un changement d'état.
|
|
Par exemple ON / OFF, la machine est en état d'arrêt ou en état de marche.
|
|
|
|
Autre exemple~: téléphone.
|
|
|
|
\begin{tabular}{lll}
|
|
\toprule
|
|
Mode & Évènement & Nouvel état \\
|
|
\midrule
|
|
avion & appel émis & avion \\
|
|
avion & bouton téléphonie & téléphonie \\
|
|
\midrule
|
|
téléphonie & bouton décrocher & communication \\
|
|
téléphonie & bouton avion & avion \\
|
|
\midrule
|
|
communication & bouton raccrocher & téléphonie \\
|
|
\bottomrule
|
|
\end{tabular}
|
|
|
|
L'automate est sous un état, il a des entrées qui le font peut-être passer d'un état à un autre ou effectuer des actions.
|
|
|
|
Il faut en plus de cela définir un état initial (quel état avoir quand l'automate est mis en marche~?) et final (quel état avoir pour éteindre l'automate proprement~?)
|
|
|
|
Un nouvel état peut dépendre de l'état précédent ou pas.
|
|
On peut très bien trouver une action qui mette l'automate dans un état Y sans se soucier d'un autre état X dans lequel se trouve l'automate à un moment donné.
|
|
|
|
Un automate accepteur valide une suite d'entrée en fonction de certains critères.
|
|
Le changement d'état est interne à l'automate, et c'est une fois que toutes les entrées ont été analysées que la sortie se fait connaître.
|
|
|
|
Exemple~: déterminer si une suite de chiffres en entrée constitue un mois de l'année.
|
|
|
|
\begin{itemize}
|
|
|
|
\item \textbf{Mot}~:
|
|
Suite de \emph{symboles} issus de l'\emph{alphabet}. \\
|
|
Cas particulier~: le mot vide, noté $\varepsilon$.
|
|
On a du coup $x = x\varepsilon = \varepsilon x$.
|
|
|
|
\item \textbf{Alphabet}~:
|
|
Ensemble des \emph{symboles} utilisés en entrée de l'automate. \\
|
|
L'alphabet se note en général $\mathcal{A}$.
|
|
|
|
\item \textbf{Langage}~:
|
|
Ensemble de tous les mots pouvants être construits sur un alphabet donné. \\
|
|
On note $\mathcal{A}^*$ tous les mots y compris le mot vide.
|
|
On note $\mathcal{A}^+$ tous les mots sauf le mot vide.
|
|
|
|
On appelle \emph{langage reconnu} l'ensemble des mots que l'automate a validé.
|
|
|
|
\item \textbf{Langage complémentaire}~:
|
|
Le langage complémentaire est l'ensemble de mots qui n'appartient pas au langage reconnu par l'automate.
|
|
Si $L$ est le langage reconnu ($L \subseteq A^*$), alors $L'$ est le langage complémentaire, et $L' = A^* - L$.
|
|
|
|
\end{itemize}
|
|
|
|
\subsection{Notations}
|
|
|
|
\begin{itemize}
|
|
|
|
\item $A$ --- Alphabet
|
|
|
|
\item $Q$ --- États
|
|
|
|
\item $I$ --- États initiaux, avec $I \subseteq Q$
|
|
|
|
\item $T$ --- États terminaux, avec $T \subseteq Q$
|
|
|
|
\item $E$ --- Transitions \\
|
|
On note les transitions par un triplet $QAQ$.
|
|
|
|
\end{itemize}
|
|
|
|
L'automate est ainsi désigné par le quintuplet $< A, Q, I, T, E >$
|
|
|
|
Exemple~:
|
|
\begin{lstlisting}[gobble=8]
|
|
< {a, b, c, d, e},
|
|
{1, 2, 3, 4, 5, 6},
|
|
{1, 3, 6},
|
|
{6},
|
|
{(1,a,2), (1,a,4),
|
|
(2,a,2), (2,c,5), (2,d,5),
|
|
(3,b,2), (3,b,4),
|
|
(4,b,4), (4,c,5), (4,d,5),
|
|
(5,e,6)}
|
|
>
|
|
\end{lstlisting}
|
|
|
|
\subsection{Table de transitions}
|
|
|
|
Une table de transitions représente l'ensembe $E$.
|
|
Chaque ligne correspond à un état, chaque colonne à un symbole de l'alphabet.
|
|
|
|
Une table de transitions monte les transitions ($E$), l'alphabet ($A$, les colonnes de la table), les états ($Q$, les lignes de la table).
|
|
Il manque donc les ensembles $I$ et $T$, c'est-à-dire les états initiaux et terminaux.
|
|
On peut les représenter par des flèches ($\rightarrow$ pour l'ensemble $I$ et $\leftarrow$ pour l'ensemble $T$) sur le côté des lignes de la table (donc des états).
|
|
|
|
\begin{center}
|
|
\begin{tabular}{cc|c|c|c|c|c|}
|
|
\cline{3-7}
|
|
& & a & b & c & d & e \\
|
|
\cline{2-7}
|
|
$\rightarrow$ & \multicolumn{1}{|c|}{1} & 2,4 & & & & \\
|
|
\cline{2-7}
|
|
& \multicolumn{1}{|c|}{2} & 2 & & 5 & 5 & \\
|
|
\cline{2-7}
|
|
$\rightarrow$ & \multicolumn{1}{|c|}{3} & & 2,4 & & & \\
|
|
\cline{2-7}
|
|
& \multicolumn{1}{|c|}{4} & & 4 & 5 & 5 & \\
|
|
\cline{2-7}
|
|
& \multicolumn{1}{|c|}{5} & & & & & 6 \\
|
|
\cline{2-7}
|
|
$\rightarrow$ & \multicolumn{1}{|c|}{\multirow{2}{*}{6}} & & & & & \\
|
|
$\leftarrow$ & \multicolumn{1}{|c|}{} & & & & & \\
|
|
\cline{2-7}
|
|
\end{tabular}
|
|
\end{center}
|
|
|
|
\subsection{Graphe d'états}
|
|
|
|
Un graphe d'états est la représentation schématique d'un automate.
|
|
La table de transitions précédente est équivalent au graphe suivant~:
|
|
|
|
\begin{center}
|
|
\includegraphics[width=0.4\linewidth]{./img/graphe-etats-exemple.jpg}
|
|
\end{center}
|
|
|
|
\subsection{Types d'automates finis}
|
|
|
|
\subsubsection{Accessibilité}
|
|
|
|
\begin{itemize}
|
|
|
|
\item Un automate accessible ne contient que des états qui peuvent être atteints.
|
|
|
|
\item Un automate co-accessible ne contient que des états pouvant mener à un état terminal.
|
|
|
|
\item Un automate émondé est à la fois accessible et co-accessible.
|
|
|
|
\end{itemize}
|
|
|
|
\subsubsection{Automate standard}
|
|
|
|
\begin{itemize}
|
|
|
|
\item il n'y a qu'un seul état initial
|
|
|
|
\item aucune transition n'arrive sur cet état initial
|
|
|
|
\end{itemize}
|
|
|
|
\subsubsection{Automate déterministe}
|
|
|
|
\begin{itemize}
|
|
|
|
\item il n'y a qu'un seul état initial (automate standard)
|
|
|
|
\item pour tout état donné, il n'y a qu'une seule transition possible
|
|
|
|
\end{itemize}
|
|
|
|
Un automate non déterministe est plus difficile à mettre en \oe{}uvre en algorithmique qu'un automate déterministe.
|
|
En effet, en plus des pointeurs d'état et de symbole courant, il faudra maintenir une pile des opérations possibles.
|
|
|
|
\subsubsection{Automate complet}
|
|
|
|
Pour tout état, il y a toujours une transition sortante pour chaque symbole de l'alphabet.
|
|
Cela veut dire qu'à tout état il y a toujours une action à faire pour tout symbole reçu.
|
|
|
|
Un automate complet est forcément également déterministe.
|
|
|
|
\subsubsection{Automate minimal}
|
|
|
|
Un automate est minimal s'il contient le moins d'états possible.
|
|
Pour un alphabet donné et un langage reconnaissable donné, il existe un et un seul automate minimal.
|
|
|
|
\subsubsection{Automate asynchrone}
|
|
|
|
Un automate asynchrone contient au moins une transition $\varepsilon$.
|
|
|
|
\paragraph{Transitions $\varepsilon$}
|
|
|
|
Une transition $\varepsilon$ permet de changer d'état sans consommer de symbole.
|
|
Ou en d'autres termes, elle permet de mofidier l'état courant sans modifier le symbole courant.
|
|
|
|
\paragraph{Fermetures $\varepsilon$}
|
|
|
|
Une fermeture $\varepsilon$ est l'ensemblre des états qu'on peut atteindre en n'utilisant que des transitions $\varepsilon$.
|
|
|
|
\subsection{Manipulations d'automates}
|
|
|
|
\subsubsection{Complétion}
|
|
|
|
On crée un état ``poubelle'' qui va accueillir les transitions manquantes sur chaque état~:
|
|
|
|
\begin{enumerate}
|
|
|
|
\item ajout de l'état poubelle $P$
|
|
|
|
\item toutes les transitions existantes sont gardées
|
|
|
|
\item ajout d'une transition vers l'état poubelle $P$ pour toute transition absente de $E$
|
|
|
|
\item ajout des transitions $(P, x, P)$ pour tout $x$ de l'alphabet
|
|
|
|
\end{enumerate}
|
|
|
|
\subsubsection{Standardisation}
|
|
|
|
La standardisation passe par trois étapes~:
|
|
|
|
\begin{enumerate}
|
|
|
|
\item ajout d'un nouvel état initial $i$
|
|
|
|
\item ajout de cet état initial à la liste des états terminaux si nécessaire (reconnait le mot vide)
|
|
|
|
\item duplication à partir de $i$ de toutes les transitions partant d'un état initial
|
|
|
|
\end{enumerate}
|
|
|
|
\subsubsection{Émondage}
|
|
|
|
Se fait en deux temps, d'abord rendre l'automate \emph{accessible}, puis \emph{co-accessible}.
|
|
Cette deuxième étape supprime l'état poubelle d'un automate complet, ce qui en fera un automate non complet.
|
|
|
|
Rendre un automate accessible~:
|
|
|
|
\begin{enumerate}
|
|
|
|
\item $Q' = I$
|
|
|
|
\item $\forall p \in I, \text{marque}(p) = \text{à traiter}$
|
|
|
|
\item tant qu'il existe un sommet accessible depuis un état initial qui n'a pas encore été traité, on prend un de ces sommets et on ajoute à l'automate tous les états accessibles depuis le sommet
|
|
|
|
\item $\text{marque}(p) = \text{déjà traité}$
|
|
|
|
\item $I' = I \cap Q'$
|
|
|
|
\item $T' = T \cap Q'$
|
|
|
|
\item on ne garde de l'automate de départ que les états auxquels on a accédé, et les transitions associées
|
|
|
|
\end{enumerate}
|
|
|
|
Pour la deuxième étape, consistant à rendre l'automate co-accessible, on suit les mêmes étapes mais en partant des états terminaux, en remontant dans l'autre sens~:
|
|
|
|
\begin{enumerate}
|
|
|
|
\item $Q' = T$
|
|
|
|
\item $\forall p \in T, \text{marque}(p) = \text{à traiter}$
|
|
|
|
\item tant qu'il existe un sommet accessible depuis un état terminal qui n'a pas encore été traité, on prend un de ces sommets et on ajoute à l'automate tous les états accessibles depuis le sommet
|
|
|
|
\item $\text{marque}(p) = \text{déjà traité}$
|
|
|
|
\item $I' = I \cap Q'$
|
|
|
|
\item $T' = T \cap Q'$
|
|
|
|
\item on ne garde de l'automate de départ que les états auxquels on a accédé, et les transitions associées
|
|
|
|
\end{enumerate}
|
|
|
|
\subsubsection{Passage au langage complémentaire}
|
|
|
|
Il faut commencer par compléter l'automate s'il n'est pas complet, puis on inverse les états terminaux et non terminaux.
|
|
|
|
\subsubsection{Déterminisation}
|
|
|
|
Pour passer d'un automate non déterministe à un automate déterministe, on va dérouler toutes les étapes de l'automate de départ en partant des états initiaux.
|
|
S'il y a plusieurs états initiaux, on crée un nouvel état initial qu'on note comme l'ensemble des états initiaux de l'automate de départ.
|
|
Ensuite, pour chaque transition possible on recopie les transitions en partant du nouvel état courant vers un ensemble d'états de l'automate de départ.
|
|
Cela nous fait créer de nouveaux états, qu'on utilise comme état courant pour trouver les nouveaux états qu'on peut rejoindre.
|
|
|
|
\begin{enumerate}
|
|
|
|
\item création de l'état initial~: ensemble de tous les états initiaux de l'automate non déterministe de départ
|
|
|
|
\item repérage des lignes dans le tableau de transitions concernant les états initiaux déterminés précédemment
|
|
|
|
\item pour chaque transition de chacune de ces lignes, identification des états cibles, et renseignement des ensembles d'états cibles dans le nouveau tableau de transitions
|
|
|
|
\item retour à l'étape de repérage des états déterminés précédemment
|
|
|
|
\item identification des ensembles contenant au moins un état terminal dans l'automate de départ
|
|
|
|
\end{enumerate}
|
|
|
|
Algorithme~:
|
|
|
|
\begin{itemize}
|
|
\item $Q' \leftarrow \{I\}$ \\
|
|
$I' \leftarrow \{I\}$ \\
|
|
$\text{marque}(I) = \text{à traiter}$
|
|
|
|
\item $\text{tant que } \{e' \in Q' \,|\, \text{marque}(e') = \text{à traiter}\} \neq \oslash$ \\
|
|
$\text{choisir } p' \in Q' \,|\, \text{marque}(p') = \text{à traiter}$
|
|
|
|
\begin{itemize}
|
|
|
|
\item $\forall x \in A$ \\
|
|
Soit $q' = \{q \in Q \,|\, \exists \, p \in p', (p,x,q) \in E\}$ \\
|
|
$q' \notin Q' \implies (Q' \leftarrow Q' \cup \{q'\}, \text{marque}(q') = \text{à traiter})$ \\
|
|
$E' \leftarrow E' \cup \{(p',x,q')\}$
|
|
|
|
\item $\text{marque}(p') = \text{déjà traité}$
|
|
|
|
\end{itemize}
|
|
|
|
\item $T' = \{p' \in Q' \,|\, \exists \, p \in p', p \in T\}$
|
|
|
|
\end{itemize}
|
|
|
|
\subsubsection{Minimisation}
|
|
|
|
\paragraph{Définition}
|
|
|
|
Un automate minimal est celui qui contient le moins d'états possibles parmi tous les automates complets et déterministes correspondant au même langage.
|
|
|
|
Pour un langage donné, il n'y a qu'un seul automate minimal.
|
|
Pour prouver que deux automates reconnaissent le même langage, on peut donc les minimiser, ce qui rendra deux fois le même automate minimal.
|
|
|
|
Pour minimiser un automate, il faut qu'il soit~:
|
|
|
|
\begin{itemize}
|
|
|
|
\item déterministe
|
|
|
|
\item complet
|
|
|
|
\item accessible
|
|
|
|
\end{itemize}
|
|
|
|
\paragraph{Méthode}
|
|
|
|
On commence par partir du principe que tous les états sont identiques.
|
|
Puis on sépare les états qui n'ont pas les mêmes suffixes.
|
|
Au bout d'un moment, tous les états regroupés ne pourront plus ête séparés.
|
|
|
|
\begin{itemize}
|
|
|
|
\item Regroupement de tous les états en deux groupes~:
|
|
$N$ (états non terminaux) et $T$ (états terminaux).
|
|
|
|
\item Pour chaque groupe, séparation des états qui ont des suffixes différents.
|
|
|
|
\item Pour chaque groupe nouvellement obtenu, refaire l'étape précédente, de manière itérative, jusqu'à ce qu'aucun groupe ne peut être séparé~:
|
|
|
|
\begin{itemize}
|
|
|
|
\item soit parce qu'il n'a qu'un état
|
|
|
|
\item soit parce que tous ses états ont les mêmes suffixes
|
|
|
|
\end{itemize}
|
|
|
|
\end{itemize}
|
|
|
|
\subsubsection{Suppression des transitions $\varepsilon$}
|
|
|
|
\end{document}
|