Probleme – Émonder une grammaire, et décider si son langage est vide
Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 30 — Grammaires non contextuelles
Énoncé
- Écrire l'algorithme qui calcule les symboles productifs, et prouver qu'il est correct.
- Même chose pour les symboles accessibles.
- En déduire un algorithme qui décide si , et donner sa complexité.
- Comparer avec la même question pour un automate.
Corrigé
1. Les productifs. Un symbole est productif s'il dérive au moins un mot de terminaux. On calcule l'ensemble par point fixe croissant :
P <-- ensemble vide
répéter
pour chaque règle A --> alpha
si tous les non-terminaux de alpha sont dans P
alors ajouter A à P
jusqu'à ce que P ne change plus
Un terminal compte pour productif : la condition « tous les non-terminaux de sont dans » est vraie pour une règle entièrement terminale, ce qui amorce le calcul.
Terminaison. Variant : , où est l'ensemble des non-terminaux. Chaque tour qui change quelque chose fait croître strictement, et est borné. Il y a donc au plus tours.
Correction, dans les deux sens.
- Tout élément de est productif : par récurrence sur le tour où il est ajouté. Si entre au tour par la règle , chaque non-terminal de était déjà dans , donc dérive un mot de terminaux par hypothèse de récurrence ; on les concatène.
- Tout symbole productif finit dans : par récurrence sur la hauteur du plus petit arbre de dérivation d'un mot de terminaux à partir de . Si cet arbre a pour racine , chacun des non-terminaux de a un sous-arbre strictement plus petit, donc entre dans avant .
2. Les accessibles. Un symbole est accessible s'il apparaît dans une forme dérivée du symbole initial. C'est un simple parcours de graphe depuis (chapitre chap:parcours), dans le graphe où l'on met un arc de vers chaque non-terminal figurant dans un membre droit d'une règle de . La correction est celle du parcours : on atteint exactement les sommets reliés à par un chemin.
3. Décider la vacuité. si et seulement si le symbole initial n'est pas productif. C'est immédiat : est l'ensemble des mots de terminaux dérivant de , donc il est non vide exactement quand est productif.
Complexité. Écrit naïvement, le calcul de fait tours, chacun parcourant toutes les règles : , où est la taille totale de la grammaire. On descend à en tenant, pour chaque règle, un compteur des non-terminaux encore manquants et une file des symboles nouvellement productifs — c'est la même technique que le tri topologique.
Un exemple mesuré. Sur
le calcul donne et l'ensemble des accessibles . La grammaire émondée est , , et son langage est — identique à celui de départ. Deux non-terminaux sur quatre étaient inutiles, pour deux raisons différentes.
4. La comparaison avec les automates. Elle est exacte, et instructive.
| Automate | Grammaire | |
|---|---|---|
| Utile en aval | état co-accessible | symbole productif |
| Utile en amont | état accessible | symbole accessible |
| Calcul | parcours, direct et transposé | point fixe, puis parcours |
| Vacuité | co-accessible ? | productif ? |
| Coût |
La vacuité est décidable des deux côtés, et pour la même raison : dans les deux cas, il suffit d'un calcul de point fixe sur un ensemble fini. C'est une bonne occasion de mesurer ce que « décidable » veut dire concrètement : la question porte sur une infinité de mots, et l'on y répond par un calcul fini, dont on sait borner la durée à l'avance.
Ce qui, en revanche, sépare les deux mondes. Pour les automates, on décide aussi l'équivalence et l'universalité. Pour les grammaires non contextuelles, ni l'une ni l'autre n'est décidable, non plus que l'ambiguïté. La vacuité est presque la seule question qui reste calculable — et c'est déjà la plus utile, car c'est elle qui repère les règles mortes d'une grammaire de compilateur.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.