Adloun

Probleme – La grammaire de balisage du programme, de bout en bout

Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 30 — Grammaires non contextuelles

Énoncé

On étudie complètement , .

Corrigé

1. La non-ambiguïté. Introduisons la hauteur .

Lemme. Tout vérifie et tout préfixe de vérifie . Tout vérifie , et tout préfixe propre et non vide de vérifie .

Preuve du lemme, par induction mutuelle. Pour : hauteur nulle partout. Pour : la concaténation de deux mots de hauteur nulle, dont les préfixes restent positifs. Pour : le a initial monte à , les préfixes de y ajoutent une quantité positive, et seul le b final redescend à .

La non-ambiguïté suit. Soit , non vide. Sa première lettre décide la règle : si c'est c, la seule règle possible est et ; si c'est a, la seule règle possible est . Il reste à montrer que la coupure entre et est unique : d'après le lemme, la partie est le préfixe de qui ramène à zéro pour la première fois, et cette position est déterminée par seul. Chaque nœud de l'arbre étant ainsi forcé, l'arbre est unique.

Le décompte machine confirme : les mots de longueur au plus ont chacun exactement un arbre d'analyse.

2. L'analyseur qui construit l'arbre. Le type inductif est la grammaire :


type arbre =
  | Feuille                        (* S -> c     *)
  | Bloc of arbre * arbre          (* S -> T S, avec T -> a S b *)

exception Echec

(* Analyse mot et rend son arbre. Leve Echec si mot n'est pas dans L(S).
   INVARIANT : a l'appel de s (), pos designe le debut d'un mot de L(S) ;
               au retour, pos designe la position juste apres ce mot.
   VARIANT : n - !pos decroit strictement a chaque appel de lire. *)
let arbre_de mot =
  let n = String.length mot in
  let pos = ref 0 in
  let lire c = if !pos < n && mot.[!pos] = c then incr pos else raise Echec in
  let rec s () =
    if !pos < n && mot.[!pos] = 'a' then
      let dedans = t () in Bloc (dedans, s ())
    else (lire 'c'; Feuille)
  and t () =
    lire 'a'; let a = s () in lire 'b'; a
  in
  let a = s () in
  if !pos <> n then raise Echec;
  a

(* Le mot se relit depuis l'arbre : c'est le test d'ALLER-RETOUR. *)
let rec vers_mot = function
  | Feuille -> "c"
  | Bloc (d, suite) -> "a" ^ vers_mot d ^ "b" ^ vers_mot suite

Terminaison. Chaque appel de t consomme au moins un caractère avant de rappeler s : le variant décroît strictement. Il n'y a pas de récursivité à gauche, et c'est ce qui rend l'analyseur possible.

Correction. L'invariant écrit au-dessus du code : le choix de règle est déterminé par le caractère courant — a force , tout le reste force —, ce qui est exactement le contenu de la démonstration de non-ambiguïté.

L'aller-retour. vers_mot (arbre_de w) = w doit être vrai pour tout du langage. Exécuté sur les mots reconnus de longueur au plus : aucun échec. C'est le test qui vaut le plus cher pour son prix : il éprouve d'un coup l'analyseur et la structure de l'arbre.

Les arbres obtenus :


  c          arbre c                      profondeur 1
  acbc       arbre T(c).c                 profondeur 3
  aacbcbc    arbre T(T(c).c).c            profondeur 5
  acbacbc    arbre T(c).T(c).c            profondeur 4
  aaacbcbcbc arbre T(T(T(c).c).c).c       profondeur 7

Noter les deux mots de longueur : même longueur, arbres de profondeurs et . L'un imbrique, l'autre juxtapose.

3. Le dénombrement. Notons le nombre de mots de de longueur , et celui de . Les deux règles donnent

On sait déjà que les longueurs sont congrues à modulo . Posons . Alors , et la première relation devient

qui est exactement la récurrence de Catalan. Donc .

Vérifié de deux façons : par énumération exhaustive de tous les mots sur trois lettres jusqu'à la longueur , qui donne mots pour ; et par la récurrence poussée jusqu'à , qui donne .

Pourquoi Catalan, encore. Parce qu'un mot du langage est un arbre : les blocs sont les nœuds, le c final est la fin d'une liste de fils. Le langage de balisage et les arbres binaires sont deux écritures du même objet — c'est ce que la remarque du chapitre appelle « une grammaire non contextuelle est une définition inductive ».

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.