Aller au contenu principal

TD 4 : grammaires

Exercice 1​

Lemme d'Arden : A∗.BA^\ast.B est une solution de X=A.X∪BX = A.X \cup B (et si AA ne contient pas ϵ\epsilon, cette solution est unique).

  • En pratique, il faut choisir la variable qui sera éliminée en premier. Ici, on va remplacer X2X_2 par sa valeur dans X1X_1 (on se permet de confondre les singletons avec leur élément par concision) :
X1=b.X1∪b.(a.X0∪{a,b}.X1)∪ϵX1={b,ba,bb}.X1∪ba.X0∪ϵ\begin{aligned} X_1 &= b.X_1 \cup b.(a.X_0 \cup \{a, b\}.X_1) \cup \epsilon \\ X_1 &= \{b, ba, bb\}.X_1 \cup ba.X_0 \cup \epsilon \end{aligned}

D'après le lemme d'Arden, on a : X1={b,ba,bb}∗.(ba.X0∪ϵ)X_1 = \{b, ba, bb\}^\ast . (ba.X_0 \cup \epsilon).

On remplace dans X0X_0 : X0=(a∪b.{b,ba,bb}∗.ba).X0∪b.{b,ba,bb}∗∪ϵX_0 = (a \cup b.\{b, ba, bb\}^\ast .ba).X_0 \cup b.\{b, ba, bb\}^\ast \cup \epsilon.

Encore une fois, avec le lemme : X0=(a∪b.{b,ba,bb}∗.ba)∗.(b.{b,ba,bb}∗∪ϵ)X_0 = (a \cup b.\{b, ba, bb\}^\ast.ba)^\ast . (b.\{b, ba, bb\}^\ast \cup \epsilon).

Et on termine en remplaçant X0X_0 et X1X_1 dans X2X_2.

  • On veut montrer que Σ∗\Sigma^\ast est toujours solution si AA contient le mot vide.

Si AA contient ϵ\epsilon, alors A.Σ∗=Σ∗A.\Sigma^\ast = \Sigma^\ast ; de plus, BB est inclus dans Σ∗\Sigma^\ast, donc A.Σ∗∪B=Σ∗A.\Sigma^\ast \cup B = \Sigma^\ast.

Donc Σ∗\Sigma^\ast est bien solution de l'équation X=A.X∪BX = A.X \cup B.

  • Pour prouver le lemme, il faut montrer que A∗.BA^\ast.B est bien une solution, puis l'unicité (ce qu'on va faire en montrant qu'elle est la plus petite et la plus grande).

  • Montrons d'abord que A∗.BA^\ast.B est une solution de X=A.X∪BX = A.X \cup B :

A∗.B=(ϵ∪A.A∗).B=B∪A.A∗.BA^\ast.B = (\epsilon \cup A.A^\ast).B = B \cup A.A^\ast.B

Or le produit de langages est associatif, donc A∗.B=A.(A∗.B)∪BA^\ast.B = A.(A^\ast.B) \cup B.

  • Toute solution SS contient A∗.BA^\ast.B. Montrons par récurrence sur nn que An.B⊆SA^n.B \subseteq S : on a A0.B=B⊆A.S∪B=SA^0.B = B \subseteq A.S \cup B = S, et si An.B⊆SA^n.B \subseteq S, alors An+1.B=A.(An.B)⊆A.S⊆SA^{n+1}.B = A.(A^n.B) \subseteq A.S \subseteq S. Donc A∗.B=⋃nAn.B⊆SA^\ast.B = \bigcup_n A^n.B \subseteq S.

  • Dans le cas où AA ne contient pas le mot vide, toute solution SS est incluse dans A∗.BA^\ast.B. Soit ww un mot de SS le plus court possible tel que ww n'est pas dans A∗.BA^\ast.B. ww est dans S=A.S∪BS = A.S \cup B, donc ww est :

    • soit dans BB (impossible, car B⊆A∗.BB \subseteq A^\ast.B) ;
    • soit dans A.SA.S.

Donc w=u.vw = u.v avec uu dans AA et vv dans SS. Comme u≠ϵu \neq \epsilon, ∣v∣<∣w∣|v| < |w|, donc vv est dans A∗.BA^\ast.B par minimalité de ww. Donc ww est dans A.A∗.BA.A^\ast.B, donc dans A∗.BA^\ast.B : contradiction.

  • On construit l'automate en créant un état par variable plus un état final, et on crée les transitions pour chaque règle (cf. cours).

Exercice 2​

L'intuition naïve qu'on pourrait avoir serait "d'inverser" les membres droits de chaque règle. Cependant, cette méthode génère en fait le miroir du langage de la grammaire de départ.

À partir d'une grammaire linéaire droite GG, on peut obtenir un automate fini AA qui accepte le langage de la grammaire. Ensuite, on calcule l'automate A′A' qui accepte le langage miroir, ce qui permet d'obtenir une grammaire linéaire droite G′G'. Enfin, on inverse "naïvement" G′G' et on obtient une grammaire linéaire gauche G′′G'' de même langage que GG (on peut bien sûr effectuer l'opération inverse).

On peut aussi convertir en automate fini puis inverser les états initiaux et finaux du résultat, ainsi que toutes les transitions. FH : cette transformation correspond au calcul de l'automate miroir dans la solution ci-dessus. C'est une étape de la construction, mais elle ne répond pas totalement à la question.

Parenthèse sur un arbre de dérivation pour une grammaire régulière​

S→aS∣bTT→aT∣bS∣ϵ\begin{aligned} S &\rightarrow aS \mid bT \\ T &\rightarrow aT \mid bS \mid \epsilon \end{aligned}

Pour la dérivation S⇒aS⇒abT⇒abS \Rightarrow aS \Rightarrow abT \Rightarrow ab :

     S
/ \
a S
/ \
b T
|
eps

S→S+S∣xS \rightarrow S + S \mid x

On peut avoir deux suites de dérivations différentes, mais le même arbre :

  1. S⇒S+S⇒x+S⇒x+xS \Rightarrow S + S \Rightarrow x + S \Rightarrow x + x
  2. S⇒S+S⇒S+x⇒x+xS \Rightarrow S + S \Rightarrow S + x \Rightarrow x + x
       S
/ | \
S + S
| |
x x

S⇒S+S⇒S+S+S⇒…S \Rightarrow S+S \Rightarrow S+S+S \Rightarrow \ldots Dans ce cas, on peut choisir de remplacer le premier ou le deuxième SS par S+SS + S, ce qui donne deux arbres distincts pour le même mot : la grammaire est ambiguë.

En remplaçant le deuxième, on trouve l'arbre suivant :

       S
/ | \
S + S
| / | \
x S + S
| |
x x

Exercice 3​

On est en présence d'une grammaire non linéaire (à cause de la première règle, qui mène à A1BA1B avec deux symboles non terminaux).

  1. Grammaire de départ, où l'on remplace le facteur A1BA1B par une variable (d'après les règles de AA, A1B→0A1B∣1BA1B \rightarrow 0A1B \mid 1B) :
S→A1BA1B→0A1B∣1BB→0B∣1B∣ϵ\begin{aligned} S &\rightarrow A1B \\ A1B &\rightarrow 0A1B \mid 1B \\ B &\rightarrow 0B \mid 1B \mid \epsilon \end{aligned}

En renommant A1BA1B en A′A' :

S→A′A′→0A′∣1BB→0B∣1B∣ϵ\begin{aligned} S &\rightarrow A' \\ A' &\rightarrow 0A' \mid 1B \\ B &\rightarrow 0B \mid 1B \mid \epsilon \end{aligned}

Finalement, en supprimant la variable inutile :

S→0S∣1BB→0B∣1B∣ϵ\begin{aligned} S &\rightarrow 0S \mid 1B \\ B &\rightarrow 0B \mid 1B \mid \epsilon \end{aligned}

Il faut garder à l'esprit que les grammaires hors contexte ne sont pas toutes équivalentes à des grammaires linéaires.

Exercice 4​

Conversion de langages en grammaires.

  1. {anbn∣n≥0}\{a^n b^n \mid n \geq 0\} : S→aSb∣ϵS \rightarrow aSb \mid \epsilon

  2. {anbm∣m≤n}\{a^n b^m \mid m \leq n\} : S→aS∣aSb∣ϵS \rightarrow aS \mid aSb \mid \epsilon

    D'ailleurs, cette grammaire est ambiguë : S⇒aS⇒aaSb⇒aabS \Rightarrow aS \Rightarrow aaSb \Rightarrow aab, mais aussi S⇒aSb⇒aaSb⇒aabS \Rightarrow aSb \Rightarrow aaSb \Rightarrow aab, qui correspondent à deux arbres différents : on a deux façons différentes de construire aabaab.

  3. {wwR}\{w w^R\} : S→aSa∣bSb∣ϵS \rightarrow aSa \mid bSb \mid \epsilon, qui n'est pas ambiguë.

  4. Les mots de Dyck : S→SS∣(S)∣[S]∣{S}∣ϵS \rightarrow SS \mid (S) \mid [S] \mid \{S\} \mid \epsilon, qui est ambiguë.

  5. Variante avec les parenthèses imbriquées dans l'ordre {}\{\}, puis ()(), puis [][] :

S→SS∣{T}∣ϵT→TT∣(U)∣ϵU→UU∣[ ]∣ϵ\begin{aligned} S &\rightarrow SS \mid \{T\} \mid \epsilon \\ T &\rightarrow TT \mid (U) \mid \epsilon \\ U &\rightarrow UU \mid [\,] \mid \epsilon \end{aligned}

Exercice 5​

S→S+S∣S∗S∣0∣1S \rightarrow S + S \mid S * S \mid 0 \mid 1
  1. Cette grammaire est hors contexte.

  2. On exhibe deux arbres différents qui génèrent le même mot (cf. la parenthèse de l'exercice 2).

    Problème : il est difficile d'évaluer l'expression (arithmétique) car on ne sait pas quel arbre choisir (la priorité de ∗* sur ++ n'est pas imposée).

  3. On peut se baser sur l'expression régulière ({0,1}{+,∗})∗{0,1}(\{0,1\}\{+,*\})^\ast\{0,1\} : on trouve S→0+S∣1+S∣0∗S∣1∗S∣0∣1S \rightarrow 0+S \mid 1+S \mid 0*S \mid 1*S \mid 0 \mid 1.

  4. On ajoute la règle S→(S)S \rightarrow (S). Il n'y a pas de grammaire régulière qui décrit ce nouveau langage, car ce n'est pas un langage régulier (il faut compter les parenthèses ouvrantes non fermées).