Aller au contenu principal

Automates finis et langages

Un algorithme est réalisé dans le but de résoudre un problème. Nous commençons donc logiquement par introduire une formalisation des problèmes en termes de langages, puis nous formalisons la notion d'algorithme par les automates finis.

Formalisation de la notion de problème​

Les seuls problèmes abordés ici seront les problèmes de décision. Ceux-ci admettent uniquement 2 réponses : oui ou non. Un problème de décision est donné par un ensemble EE d'instances, partitionné en l'ensemble EouiE_\text{oui} des instances positives et l'ensemble EnonE_\text{non} des instances négatives.

Nous définissons alors une instance d'un problème de décision qui pose la question pour un élément particulier xx de EE. Toute instance admet une réponse, qui est positive lorsque x∈Eouix \in E_\text{oui} et négative lorsque x∈Enonx \in E_\text{non}.

En informatique, il existe d'autres problèmes d'intérêt que les problèmes de décision. Cependant, tout problème peut s'exprimer sous la forme d'un problème de décision. Cette approche permet de définir une théorie du calcul dans un cadre simple et unique. C'est pourquoi nous nous plaçons dans ce cadre.

La notion de problème est indépendante de la notion d'algorithme. Un algorithme peut résoudre un problème, mais il ne le définit pas. Par ailleurs, un problème soluble l'est généralement par plusieurs algorithmes.

Les langages​

Un algorithme est déterminé pour résoudre un problème donné. Cependant, toute question qui lui est soumise est une instance de ce problème. Il est donc nécessaire de disposer d'un encodage des instances de problèmes afin de les fournir aux algorithmes. D'une façon générale, une instance d'un problème est représentée par une séquence de symboles.

Un alphabet est un ensemble fini et non vide de symboles, un alphabet est généralement désigné par Σ\Sigma.

Un mot sur un alphabet Σ\Sigma est une séquence finie de symboles de Σ\Sigma.

La longueur d'un mot ω=ω1...ωn\omega = \omega_1 ... \omega_n avec ωi∈Σ\omega_i \in \Sigma est définie par ∣ω∣=n|\omega|=n.

Le mot vide, noté ϵ\epsilon, est le mot de longueur nulle : ∣ϵ∣=0|\epsilon|=0.

La concaténation de deux mots ω=ω1...ωn\omega = \omega_1 ... \omega_n sur Σ\Sigma, et ω′=ω1′...ωk′\omega'=\omega'_1 ... \omega'_k sur Σ′\Sigma', est définie par le mot ω.ω′=ω1...ωnω1′...ωk′\omega . \omega'=\omega_1 ... \omega_n \omega'_1 ... \omega'_k sur Σ∪Σ′\Sigma \cup \Sigma'. La longueur de ω.ω′\omega . \omega' est donnée par ∣ω.ω′∣=∣ω∣+∣ω′∣=n+k|\omega . \omega'|=|\omega|+|\omega'| = n+k.

Un mot ω′\omega' est un facteur de ω\omega s'il existe deux mots uu et vv tels que ω=u.ω′.v\omega=u.\omega'.v. Un facteur ω′\omega' est propre si ω′≠ω\omega' \neq \omega (certains auteurs imposent aussi ω′≠ϵ\omega' \neq \epsilon). Nous appelons préfixe de ω\omega tout facteur ω′\omega' tel que u=ϵu=\epsilon, i.e. ω=ω′.v\omega=\omega'.v. Symétriquement, un suffixe de ω\omega est un facteur ω′\omega' tel que v=ϵv=\epsilon, i.e. ω=u.ω′\omega = u . \omega'.

Un langage sur un alphabet Σ\Sigma est un ensemble fini ou infini de mots sur Σ\Sigma, c'est-à-dire une partie de Σ∗\Sigma^\ast (ensemble de tous les mots sur Σ\Sigma).

Attention à ne pas confondre le langage vide ∅\emptyset, et le langage contenant uniquement le mot vide {ϵ}\{\epsilon\}.

Représentation d'un problème par un langage​

Chaque instance xx est modélisée par un mot ω\omega. L'ensemble EE des instances est alors représenté par le langage des mots qui les encodent. Notons que la description, et non pas la définition, de l'ensemble EouiE_\text{oui} des instances positives et de l'ensemble EnonE_\text{non} des instances négatives dépend de l'encodage choisi.

Automates finis​

Nous savons maintenant comment représenter un problème de décision par un langage sur un alphabet choisi : l'ensemble EE de ses instances xx, chacune d'elles représentée par un mot ω\omega sur cet alphabet. L'ensemble des instances positives EouiE_\text{oui} est lui aussi représenté par un langage LL, tout comme l'ensemble des instances négatives EnonE_\text{non} qui est représenté par le complémentaire de LL dans EE. Un algorithme qui résout un problème donné prend en entrée une instance particulière xx et doit décider si x∈Eouix \in E_\text{oui}, c'est-à-dire si ω∈L\omega \in L. Pour cela, l'algorithme doit lire certains symboles du mot ω\omega qui lui permettent de prendre sa décision. Un modèle d'algorithme ou modèle de calcul doit donc permettre de lire un mot ω\omega en entrée, de mémoriser certaines informations et de prendre des décisions pour in fine décider si ω∈L\omega \in L.

Nous introduisons maintenant les automates finis comme modèle de calcul. Un automate fini lit le mot d'entrée ω\omega, symbole par symbole, de gauche à droite et sans pouvoir revenir en arrière. L'automate est une machine à états qui en représentent la mémoire. L'état de l'automate change pour refléter l'information qu'il mémorise en fonction des symboles de ω\omega qu'il lit. Il possède certains états particuliers. Les états initiaux correspondent aux connaissances élémentaires qu'il possède avant de lire ω\omega. Les états accepteurs correspondent aux connaissances permettant de décider si ω∈L\omega \in L. C'est-à-dire que si, après avoir lu ω\omega, l'automate se trouve dans un état accepteur, alors ω\omega est accepté, c'est-à-dire ω∈L\omega \in L.

Un automate fini A=(Q,Σ,δ,I,F)A=(Q,\Sigma,\delta,I,F) est défini par :

  • QQ est un ensemble fini d'états
  • Σ\Sigma est l'alphabet de AA
  • δ⊆Q×(Σ∪{ϵ})×Q\delta \subseteq Q \times (\Sigma \cup \{\epsilon \}) \times Q est la relation de transition
  • I⊆QI \subseteq Q est l'ensemble des états initiaux
  • F⊆QF \subseteq Q est l'ensemble des états accepteurs

Exemple d'automate fini

Notons qu'en présence d'une transition étiquetée ϵ\epsilon l'automate change d'état sans lire aucun symbole du mot d'entrée. Nous en verrons les conséquences au chapitre 5.

Un automate fini A=(Q,Σ,δ,I,F)A=(Q,\Sigma,\delta,I,F) est complet si pour tout q∈Qq \in Q et pour tout s∈Σs \in \Sigma il existe q′∈Qq' \in Q tel que (q,s,q′)∈δ(q,s,q') \in \delta.

Un automate fini complet possède une transition pour chaque lettre de l'alphabet depuis tout état. Il peut donc traiter tout mot d'entrée entièrement, sans jamais être bloqué avant d'avoir lu l'intégralité du mot d'entrée. Cependant, cela ne suffit pas pour pouvoir programmer l'automate. Il faut de plus que celui-ci soit déterministe, c'est-à-dire que, connaissant l'état de l'automate et la lettre lue, il doit être possible de déterminer l'état suivant de manière unique.

Un automate fini A=(Q,Σ,δ,I,F)A=(Q,\Sigma,\delta,I,F) est déterministe si et seulement si

  • il possède un unique état initial : I={q0}I=\{q_0\}
  • il n'existe pas de transition étiquetée ϵ\epsilon : (Q×{ϵ}×Q)∩δ=∅(Q \times \{\epsilon\} \times Q) \cap \delta = \emptyset
  • et pour tout état q∈Qq \in Q, pour tout s∈Σs \in \Sigma, il existe au plus un état q′∈Qq' \in Q tel que (q,s,q′)∈δ(q,s,q') \in \delta

Langage accepté​

Un automate fini est appliqué à un mot d'entrée donné, encodé dans l'alphabet de l'automate. C'est-à-dire que l'automate, à partir d'un état initial, lit le mot d'entrée lettre à lettre et il franchit, pour chacune d'elles, une transition de même étiquette. Cela définit une exécution de l'automate fini.

Une exécution d'un automate fini A=(Q,Σ,δ,I,F)A=(Q,\Sigma,\delta,I,F) sur un mot d'entrée ω∈Σ∗\omega \in \Sigma^\ast est une séquence finie de transitions q0→a0q1→a1...qn→anqn+1q_0 \stackrel{a_0}{\rightarrow} q_1 \stackrel{a_1}{\rightarrow} ... q_n \stackrel{a_n}{\rightarrow} q_{n+1} de δ\delta, avec q0∈Iq_0 \in I et ω=a0a1…an\omega = a_0 a_1 \ldots a_n (les aia_i valant ϵ\epsilon ne contribuent pas au mot).

Un automate fini déterministe admet donc au plus une exécution pour tout mot d'entrée. A contrario, un automate fini complet (ayant au moins un état initial) admet au moins une exécution pour tout mot d'entrée. Finalement, un automate fini déterministe et complet admet exactement une exécution pour tout mot d'entrée.

Une exécution d'un automate fini pour un mot d'entrée ω\omega aboutit dans un état donné, ici qn+1q_{n+1}. C'est alors que l'automate rend une décision : soit qn+1∈Fq_{n+1} \in F est accepteur et alors ω\omega est accepté, soit au contraire qn+1∉Fq_{n+1} \notin F n'est pas accepteur et le mot ω\omega est rejeté.

Le langage accepté par un automate fini A=(Q,Σ,δ,I,F)A=(Q,\Sigma,\delta, I,F) est l'ensemble des mots ω\omega pour lesquels il existe une exécution de AA qui aboutit dans un état accepteur : L(A)={ω∈Σ∗∣∃q0∈I,∃qF∈F,  q0→ωqF}\mathcal{L}(A)=\{\omega \in \Sigma^\ast \mid \exists q_0 \in I, \exists q_F \in F, \; q_0 \stackrel{\omega}{\rightarrow} q_F\}.