Adloun

informatique (MP2I/MPI) · Chapitre 9 · Exercice de TD

Problème — Les mots bien parenthésés, ou deux définitions pour une famille

Ordres bien fondés et induction structurelle · niveau 3 (difficile)

Énoncé

On note l'ensemble inductif de mots sur engendré par : le mot vide appartient à ; si alors ; si alors .

  • Montrer par induction structurelle que tout mot de a autant de parenthèses ouvrantes que de fermantes, et que tout préfixe en a au moins autant d'ouvrantes.
  • Écrire un reconnaisseur en un passage, et prouver sa correction par un invariant.
  • Montrer la réciproque : tout mot vérifiant les deux conditions est dans .
  • Combien contient-il de mots de longueur ?

Corrigé

Notons et les nombres de parenthèses ouvrantes et fermantes de , et son solde.

1. La condition est nécessaire. On prouve simultanément, par induction structurelle sur la construction de :

Prouver les deux ensemble est indispensable : la seconde ne se déduit pas de la première.

Assertion, . Le seul préfixe est , de solde .

Règle . par hypothèse d'induction. Un préfixe de est (solde ), ou avec préfixe de (solde ), ou entier (solde ). Tous positifs.

Règle . . Un préfixe de est soit un préfixe de , de solde , soit avec préfixe de , de solde . C'est ici que sert, et c'est pourquoi les deux propriétés voyagent ensemble.

2. Le reconnaisseur. L'invariant est la propriété , lue de gauche à droite.


(* Renvoie true ssi s est bien parenthese. Complexite : Theta(|s|) en temps,
   Theta(1) en memoire. *)
let reconnait s =
  let n = String.length s in
  let rec aux i solde =
    (* INVARIANT : solde = s(s[0..i-1]), et tout prefixe deja lu a un solde >= 0 *)
    if solde < 0 then false
    else if i = n then solde = 0
    else aux (i+1) (if s.[i] = '(' then solde + 1 else solde - 1)
  in aux 0 0

Terminaison : variant , qui décroît de à chaque appel et reste positif. Correction : l'invariant est vrai à l'entrée (, solde ) ; il se conserve, le solde étant mis à jour selon la lettre lue ; à la sortie, ou bien un solde négatif a été rencontré et le mot est rejeté, ou bien et l'on teste . La fonction rend donc vrai exactement quand est vraie. Elle est récursive terminale : le compilateur OCaml en fait une boucle, et la mémoire reste constante.

3. La réciproque, par récurrence forte sur . Soit de solde nul dont tous les préfixes ont un solde positif ou nul.

Si , il est dans . Sinon, commence par — sans quoi son préfixe de longueur aurait un solde . Soit le plus petit indice tel que le préfixe ait un solde nul ; il existe, puisque entier convient. Écrivons avec .

Alors : la première lettre est , la dernière est car le solde passe de à à cette position, et le mot intérieur a un solde nul. Ses préfixes ont un solde positif ou nul, car un préfixe de donne le préfixe de , de solde par minimalité de — c'est le choix du plus petit qui fait tout le travail. De même , de longueur , vérifie les deux conditions.

Par hypothèse de récurrence forte, et ; les deux règles donnent puis .

Vérification exhaustive. Pour allant de à , on a engendré tous les mots de et, séparément, filtré tous les mots de longueur par le reconnaisseur. Les deux ensembles sont identiques à chaque longueur. La longueur met mots à l'épreuve.

4. Le dénombrement, mesuré :

longueur
mots de

Ce sont les nombres de Catalan . La récurrence se lit sur la décomposition de la question 3, qui est unique : avec et , d'où

Les cinq mots de longueur : ((())), (()()), (())(), ()(()), ()()().

Ce que le problème a vraiment établi. Deux définitions d'apparence sans rapport — l'une constructive par des règles, l'autre déclarative par une condition sur les soldes — décrivent la même famille. C'est la situation la plus fréquente en informatique : la première dit comment fabriquer, la seconde comment vérifier, et il faut les deux. Les mêmes nombres de Catalan compteront les arbres binaires au chapitre chap:arbres — et ce n'est pas une coïncidence : la décomposition unique est exactement la décomposition d'un arbre en sa racine, son fils gauche et son fils droit.

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre