Algorithme de McNaughton et Yamada
En informatique théorique , et notamment en théorie des automates finis , l' algorithme de McNaughton et Yamada est un algorithme pour calculer une expression régulière à partir d'un automate fini. Elle porte le nom de Robert McNaughton et Hisao Yamada , deux scientifiques américain et japonais qui ont décrit l'algorithme[1] . Cet algorithme est également appelé algorithme de Kleene.
On appelle également algorithme de McNaughton et Yamada un autre algorithme, donné dans le même article[1] , qui permet de construire un automate sans epsilon transitions à partir d'une expression régulière.
Principe
Étant donné un automate à n états, et dont les états sont numérotés de 1 à n , on donne une expression pour les langages composés des mots qui étiquettent les chemins de i à j , pour tout couple i , j . Cette expression est construite par récurrence au moyen d'une condition sur les chemins ; cette condition stipule que les chemins ne passent que par certains états autorisés. À chaque itération de l’algorithme, on fixe un nouvel état par lequel on s’autorise à passer. À la fin de l’algorithme, on obtient alors tous les chemins possibles.
Le fonctionnement de cet algorithme rappelle alors l’algorithme de Floyd-Warshall sur les graphes, où à chaque nouvelle étape, on s’autorise à passer par un nouveau sommet fixé.
Description
Soit
A
=
(
Q
,
F
,
I
,
T
)
{\displaystyle {\mathcal {A}}=(Q,{\mathcal {F}},I,T)}
un automate fini sur un alphabet
A
{\displaystyle A}
, donné par un ensemble fini d'états
Q
{\displaystyle Q}
, un ensemble
F
⊂
Q
×
A
×
Q
{\displaystyle {\mathcal {F}}\subset Q\times A\times Q}
de transitions, et des ensembles
I
,
T
⊆
Q
{\displaystyle I,T\subseteq Q}
d'états initiaux respectivement terminaux.
On note
L
p
,
q
{\displaystyle L_{p,q}}
l'ensemble des mots qui sont étiquettes de chemins de
p
{\displaystyle p}
Ã
q
{\displaystyle q}
. Le langage
L
{\displaystyle L}
reconnu par l'automate est l'ensemble
L
=
⋃
i
∈
I
⋃
t
∈
T
L
i
,
t
{\displaystyle L=\bigcup _{i\in I}\bigcup _{t\in T}L_{i,t}}
L'algorithme de McNaugthon et Yamada est une méthode pour calculer des expressions régulières pour les
L
p
,
q
{\displaystyle L_{p,q}}
.
On note
L
p
,
q
(
k
)
{\displaystyle L_{p,q}^{(k)}}
l'expression pour l’ensemble des mots qui étiquettent des chemins de
p
{\displaystyle p}
Ã
q
{\displaystyle q}
et dont tous les sommets intermédiaires sont inférieurs ou égaux Ã
k
{\displaystyle k}
. Les sommets de départ
p
{\displaystyle p}
et d’arrivée
q
{\displaystyle q}
ne sont pas intermédiaires, donc ils ne sont pas soumis à la contrainte d’être inférieurs ou égaux Ã
k
{\displaystyle k}
.
On construit les
L
p
,
q
(
k
)
{\displaystyle L_{p,q}^{(k)}}
par récurrence sur
k
{\displaystyle k}
, en commençant avec
k
=
0
{\displaystyle k=0}
, et en terminant avec
k
=
n
{\displaystyle k=n}
. Lorsque
k
=
n
{\displaystyle k=n}
, la contrainte sur
k
{\displaystyle k}
n’est plus une restriction, et
L
p
,
q
(
n
)
=
L
p
,
q
{\displaystyle L_{p,q}^{(n)}=L_{p,q}}
si
p
â‰
q
{\displaystyle p\neq q}
, et
ε
+
L
p
,
p
(
n
)
=
L
p
,
p
{\displaystyle \varepsilon +L_{p,p}^{(n)}=L_{p,p}}
.
Pour
k
=
0
{\displaystyle k=0}
, comme les sommets sont numérotés à partir de 1, la contrainte exprime simplement qu’il n’y a pas de sommet intermédiaire. Les seuls chemins sont des transitions de
p
{\displaystyle p}
Ã
q
{\displaystyle q}
(on ignore un chemin de longueur 0 en un état
p
{\displaystyle p}
).
On a donc
L
p
,
q
(
0
)
=
∑
(
p
,
a
,
q
)
∈
F
a
{\displaystyle L_{p,q}^{(0)}=\sum _{(p,a,q)\in {\mathcal {F}}}a}
Pour la récurrence, on considère un chemin de
p
{\displaystyle p}
Ã
q
{\displaystyle q}
dont les sommets intermédiaires sont plus petits que
k
{\displaystyle k}
. Deux cas sont alors possibles :
les sommets intermédiaires sont plus petits que
k
−
1
{\displaystyle k-1}
; alors l’étiquette est dans
L
p
,
q
(
k
−
1
)
{\displaystyle L_{p,q}^{(k-1)}}
;
le chemin passe par l’état
k
{\displaystyle k}
. On décompose alors le chemin en parties dont les sommets intermédiaires sont plus petits que
k
−
1
{\displaystyle k-1}
. Pour cela, on considère chaque occurrence du sommet
k
{\displaystyle k}
dans ce chemin : entre deux occurrences consécutives, les sommets intermédiaires sont plus petits que k-1. On a alors la formule
L
p
,
q
(
k
)
=
L
p
,
q
(
k
−
1
)
+
L
p
,
k
(
k
−
1
)
(
L
k
,
k
(
k
−
1
)
)
∗
L
k
,
q
(
k
−
1
)
{\displaystyle L_{p,q}^{(k)}=L_{p,q}^{(k-1)}+L_{p,k}^{(k-1)}(L_{k,k}^{(k-1)})^{*}L_{k,q}^{(k-1)}}
.
Il y a donc
n
+
1
{\displaystyle n+1}
étapes (
k
=
0
,
…
,
n
{\displaystyle k=0,\ldots ,n}
). Chacune des étapes demande le calcul de
n
2
{\displaystyle n^{2}}
expressions, et la taille des expressions elles-mêmes croît avec
k
{\displaystyle k}
. S’il est facilement programmable, l’algorithme est assez pénible à la main. Il est alors utile d’utiliser les règles qui permettent de simplifier des expressions régulières.
Pseudo-code
On va représenter les
L
(
k
)
{\displaystyle L^{(k)}}
(respectivement
L
{\displaystyle L}
) sous forme de matrices, dont le coefficient en
(
i
,
j
)
{\displaystyle (i,j)}
est
L
i
,
j
(
k
)
{\displaystyle L_{i,j}^{(k)}}
(respectivement
L
i
,
j
{\displaystyle L_{i,j}}
).
On a alors, pour
A
=
(
Q
,
F
,
I
,
T
)
{\displaystyle {\mathcal {A}}=(Q,{\mathcal {F}},I,T)}
un automate fini Ã
n
{\displaystyle n}
états sur l'alphabet
A
{\displaystyle A}
:
Fonction McNaughton-Yamada(
A
{\displaystyle {\mathcal {A}}}
)
L
:=
(
∑
(
p
,
a
,
q
)
∈
F
a
)
1
≤
p
,
q
≤
n
{\displaystyle L:=(\sum _{(p,a,q)\in {\mathcal {F}}}a)_{1\leq {\mathit {p}},{\mathit {q}}\leq n}}
\\à l'itération k de la boucle for, cette matrice représente
L
(
k
)
{\displaystyle L^{(k)}}
for
k
:=
1
{\displaystyle {\mathit {k}}:=1}
to
n
{\displaystyle {\mathit {n}}}
for
p
:=
1
{\displaystyle {\mathit {p}}:=1}
to
n
{\displaystyle {\mathit {n}}}
for
q
:=
1
{\displaystyle {\mathit {q}}:=1}
to
n
{\displaystyle {\mathit {n}}}
L
p
,
q
:=
L
p
,
q
+
L
p
,
k
(
L
k
,
k
)
∗
L
k
,
q
{\displaystyle L_{{\mathit {p}},{\mathit {q}}}:=L_{{\mathit {p}},{\mathit {q}}}+L_{{\mathit {p}},{\mathit {k}}}(L_{{\mathit {k}},{\mathit {k}}})^{*}L_{{\mathit {k}},{\mathit {q}}}}
R :=
∅
{\displaystyle \emptyset }
\\expression rationnelle à retourner
for
p
∈
I
{\displaystyle {\mathit {p}}\in I}
:
for
q
∈
T
{\displaystyle {\mathit {q}}\in T}
:
if
p
==
q
{\displaystyle {\mathit {p}}=={\mathit {q}}}
then
R := R +
ε
{\displaystyle \varepsilon }
+
L
p
,
p
{\displaystyle L_{p,p}}
\\on n'ajoute
ε
{\displaystyle \varepsilon }
qu'aux
L
p
,
p
{\displaystyle L_{p,p}}
où
p
∈
I
∩
T
{\displaystyle {\mathit {p}}\in I\cap T}
else
R := R +
L
p
,
q
{\displaystyle L_{p,q}}
retourner R
Fin Fonction
Exemples
Un premier exemple
L'automate
A
1
{\displaystyle {\mathcal {A}}_{1}}
considéré.
Appliquons l'algorithme de McNaughton et Yamada à l'automate
A
1
{\displaystyle {\mathcal {A}}_{1}}
représenté.
On va utiliser la représentation matricielle introduite dans la partie précédente. On a :
L
(
0
)
=
(
a
b
∅
b
)
{\displaystyle L^{(0)}={\begin{pmatrix}a&b\\\emptyset &b\end{pmatrix}}}
;
L
(
1
)
=
(
a
+
a
(
a
)
∗
a
b
+
a
(
a
)
∗
b
∅
b
+
∅
(
a
)
∗
b
)
=
(
a
+
a
∗
b
∅
b
)
{\displaystyle L^{(1)}={\begin{pmatrix}a+a(a)^{*}a&b+a(a)^{*}b\\\emptyset &b+\emptyset (a)^{*}b\end{pmatrix}}={\begin{pmatrix}a^{+}&a^{*}b\\\emptyset &b\end{pmatrix}}}
;
L
(
2
)
=
(
a
+
+
(
a
∗
b
)
(
b
)
∗
∅
a
∗
b
+
(
a
∗
b
)
(
b
)
∗
b
∅
b
+
b
b
∗
b
)
=
(
a
+
a
∗
b
+
∅
b
+
)
{\displaystyle L^{(2)}={\begin{pmatrix}a^{+}+(a^{*}b)(b)^{*}\emptyset &a^{*}b+(a^{*}b)(b)^{*}b\\\emptyset &b+bb^{*}b\end{pmatrix}}={\begin{pmatrix}a^{+}&a^{*}b^{+}\\\emptyset &b^{+}\end{pmatrix}}}
.
D'où
L
=
(
ϵ
+
a
+
a
∗
b
+
∅
ϵ
+
b
+
)
=
(
a
∗
a
∗
b
+
∅
b
∗
)
{\displaystyle L={\begin{pmatrix}\epsilon +a^{+}&a^{*}b^{+}\\\emptyset &\epsilon +b^{+}\end{pmatrix}}={\begin{pmatrix}a^{*}&a^{*}b^{+}\\\emptyset &b^{*}\end{pmatrix}}}
.
Le langage
L
(
A
1
)
{\displaystyle L({\mathcal {A}}_{1})}
reconnu par
A
1
{\displaystyle {\mathcal {A}}_{1}}
est alors dénoté par l'expression rationnelle
L
1
,
1
+
L
1
,
2
=
a
∗
+
a
∗
b
+
{\displaystyle L_{1,1}+L_{1,2}=a^{*}+a^{*}b^{+}}
. Après simplifications, on a
L
(
A
1
)
=
a
∗
b
∗
{\displaystyle L({\mathcal {A}}_{1})=a^{*}b^{*}}
, ce qui est bien le résultat attendu.
L'automate
A
1
{\displaystyle {\mathcal {A}}_{1}}
, avec les états numérotés dans l'ordre inverse.
Considérons maintenant le même automate, mais avec une numérotation différente des états.
L'algorithme appliqué à cet automate donne :
L
(
0
)
=
(
b
∅
b
a
)
{\displaystyle L^{(0)}={\begin{pmatrix}b&\emptyset \\b&a\end{pmatrix}}}
L
(
1
)
=
(
b
+
∅
b
a
)
{\displaystyle L^{(1)}={\begin{pmatrix}b^{+}&\emptyset \\b&a\end{pmatrix}}}
L
(
2
)
=
(
b
+
∅
a
∗
b
+
a
+
)
{\displaystyle L^{(2)}={\begin{pmatrix}b^{+}&\emptyset \\a^{*}b^{+}&a^{+}\end{pmatrix}}}
D'où
L
=
(
b
∗
∅
a
∗
b
+
a
∗
)
{\displaystyle L={\begin{pmatrix}b^{*}&\emptyset \\a^{*}b^{+}&a^{*}\end{pmatrix}}}
.
L
(
A
1
)
{\displaystyle L({\mathcal {A}}_{1})}
est alors dénoté par
L
2
,
2
+
L
2
,
1
=
a
∗
+
a
∗
b
+
{\displaystyle L_{2,2}+L_{2,1}=a^{*}+a^{*}b^{+}}
, soit exactement la même expression rationnelle que précédemment : pour cet exemple particulier, le choix du nouvel état autorisé à chaque étape ne change pas l'expression rationnelle obtenue en fin d'algorithme.
Un deuxième exemple, où la numérotation des états change le résultat
L'automate
A
2
{\displaystyle {\mathcal {A}}_{2}}
.
Donnons maintenant l'exemple présenté dans l'ouvrage de référence de Sakarovitch[2] . Appliquons maintenant l'algorithme à l'automate
A
2
{\displaystyle {\mathcal {A}}_{2}}
.
On a :
L
(
0
)
=
(
a
b
a
b
)
{\displaystyle L^{(0)}={\begin{pmatrix}a&b\\a&b\end{pmatrix}}}
L
(
1
)
=
(
a
+
a
∗
b
a
+
a
∗
b
)
{\displaystyle L^{(1)}={\begin{pmatrix}a^{+}&a^{*}b\\a^{+}&a^{*}b\end{pmatrix}}}
L
(
2
)
=
(
(
a
∗
b
)
∗
a
+
(
a
∗
b
)
+
(
a
∗
b
)
∗
a
+
(
a
∗
b
)
+
)
{\displaystyle L^{(2)}={\begin{pmatrix}(a^{*}b)^{*}a^{+}&(a^{*}b)^{+}\\(a^{*}b)^{*}a^{+}&(a^{*}b)^{+}\end{pmatrix}}}
L
=
(
ε
+
(
a
∗
b
)
∗
a
+
(
a
∗
b
)
+
(
a
∗
b
)
∗
a
+
(
a
∗
b
)
∗
)
{\displaystyle L={\begin{pmatrix}\varepsilon +(a^{*}b)^{*}a^{+}&(a^{*}b)^{+}\\(a^{*}b)^{*}a^{+}&(a^{*}b)^{*}\end{pmatrix}}}
.
D'où
L
(
A
2
)
=
L
1
,
1
=
ε
+
(
a
∗
b
)
∗
a
+
{\displaystyle L({\mathcal {A}}_{2})=L_{1,1}=\varepsilon +(a^{*}b)^{*}a^{+}}
.
L'automate
A
2
{\displaystyle {\mathcal {A}}_{2}}
, avec les états numérotés dans l'ordre inverse.
De même que pour le premier exemple, appliquons à nouveau l'algorithme en changeant la numérotation des états.
On a :
L
(
0
)
=
(
b
a
b
a
)
{\displaystyle L^{(0)}={\begin{pmatrix}b&a\\b&a\end{pmatrix}}}
L
(
1
)
=
(
b
+
b
∗
a
b
+
b
∗
a
)
{\displaystyle L^{(1)}={\begin{pmatrix}b^{+}&b^{*}a\\b^{+}&b^{*}a\end{pmatrix}}}
L
(
2
)
=
(
(
b
∗
a
)
∗
b
+
(
b
∗
a
)
+
(
b
∗
a
)
∗
b
+
(
b
∗
a
)
+
)
{\displaystyle L^{(2)}={\begin{pmatrix}(b^{*}a)^{*}b^{+}&(b^{*}a)^{+}\\(b^{*}a)^{*}b^{+}&(b^{*}a)^{+}\end{pmatrix}}}
L
=
(
(
b
∗
a
)
∗
b
∗
(
b
∗
a
)
+
(
b
∗
a
)
∗
b
+
(
b
∗
a
)
∗
)
{\displaystyle L={\begin{pmatrix}(b^{*}a)^{*}b^{*}&(b^{*}a)^{+}\\(b^{*}a)^{*}b^{+}&(b^{*}a)^{*}\end{pmatrix}}}
.
D'où
L
(
A
2
)
=
L
2
,
2
=
(
b
∗
a
)
∗
{\displaystyle L({\mathcal {A}}_{2})=L_{2,2}=(b^{*}a)^{*}}
: l'expression rationnelle obtenue pour le même langage est différente.
Notes et références
Bibliographie
(en) Robert McNaughton et Hisao Yamada, « Regular expressions and state graphs for automata » , IRE Trans. Electronic Computers , vol. EC-9, no 1,‎ janvier 1960 , p. 39-47 (DOI 10.1109/TEC.1960.5221603 ) .
(en) John E. Hopcroft, Rajeev Motwani et Jeffrey D. Ullman, Introduction to Automata Theory, Languages, and Computation , Pearson Addison Wesley, 2007 , 3e éd. , xvii+535 (ISBN 978-0-321-45536-9 et 0201441241 ) — Section 3.2.1 From DFA’s to Regular Expressions , p. 93-98 .
(en) Jacques Sakarovitch, Elements of automata theory, Cambridge University Press, 1er octobre 2009 , 782 p. (ISBN 978-0521844253 ) , p. 96
Articles connexes
Cet article est issu de
wikipedia . Text licence:
CC BY-SA 4.0 , Des conditions supplémentaires peuvent s’appliquer aux fichiers multimédias.