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 :

  1. 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)}} ;
  2. 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}}
  

  
    
      
        
          
            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

  1. a et b McNaughton et Yamada 1960.
  2. (en) Jacques Sakarovitch, Elements of automata theory, Cambridge, Cambridge University Press, , 782 p. (ISBN 978-0-521-84425-3, BNF 42078268), p.96

Bibliographie

  • (en) Robert McNaughton et Hisao Yamada, « Regular expressions and state graphs for automata », IRE Trans. Electronic Computers, vol. EC-9, no 1,‎ , 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, , 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, , 782 p. (ISBN 978-0521844253), p. 96

Articles connexes

  • icône décorative Portail de l'informatique théorique