Théorie des langages · C1 Fondements · Chapitre 2 · 5 h
Rappels mathématiques utiles
Ensembles et relations, induction structurelle, récurrence sur la longueur d'un mot, et la notion de fonction de transition dont dépendent les automates.
Le chapitre 1 a défini les objets ; celui-ci fournit les outils pour raisonner dessus. Ce ne sont pas des rappels décoratifs : sans induction ni récurrence, on ne peut prouver aucun théorème du cours, et sans la notion de fonction, on ne peut pas définir un automate. Ce chapitre est court parce qu'il suppose des bases acquises — mais il isole précisément les points que la théorie des langages sollicite sans cesse, et où l'imprécision se paie plus tard.
Ensembles, un rappel ciblé
Un langage est un ensemble ; les opérations du chapitre 1 sont des opérations d'ensembles. Trois points méritent d'être fixés, parce qu'ils reviendront tels quels.
L'inclusion signifie : tout élément de est élément de . Pour prouver , on prend un élément quelconque de et on montre qu'il est dans . Pour prouver une égalité , la méthode standard est la double inclusion : et . C'est ainsi qu'on démontrera l'équivalence de deux automates, ou d'un automate et d'une expression régulière.
Le cardinal est le nombre d'éléments de . Un ensemble peut être fini, infini dénombrable (ses éléments peuvent être énumérés en liste, comme ) ou non dénombrable. Cette distinction n'est pas anodine : elle est la clé d'un résultat surprenant vu plus bas.
L'ensemble des parties est l'ensemble de tous les sous-ensembles de . Si a éléments, en a . Retenez ce : il expliquera, au chapitre 4, pourquoi la déterminisation d'un automate peut faire exploser son nombre d'états.
Relations
Une relation sur un ensemble est un sous-ensemble de : elle dit quels couples sont « en relation ». Une relation peut être réflexive, symétrique, transitive.
Le cas important pour le cours est la relation d'équivalence : réflexive, symétrique et transitive à la fois. Une telle relation partitionne en classes d'équivalence — des paquets disjoints qui recouvrent tout , où deux éléments sont dans le même paquet exactement quand ils sont en relation. Cette idée, abstraite pour l'instant, sera l'outil exact de la minimisation d'un automate au chapitre 6 : on regroupera les états « indistinguables » en une seule classe.
L'induction structurelle
Beaucoup d'objets du cours sont définis inductivement : on donne des cas de base, puis des règles pour construire des objets plus gros à partir d'objets plus petits. Le mot lui-même se définit ainsi :
- base : est un mot ;
- règle : si est un mot et une lettre, alors est un mot.
Tout mot s'obtient par un nombre fini d'applications de la règle à partir de la base. Les expressions régulières (chapitre 5) et les grammaires (chapitre 7) sont définies exactement de la même manière.
Quand un objet est défini inductivement, on le raisonne par induction structurelle : pour prouver qu'une propriété vaut pour tous les objets, il suffit de la prouver sur les cas de base, puis de montrer qu'elle se transmet par chaque règle de construction. C'est le même principe que la récurrence sur les entiers, appliqué à la structure de l'objet plutôt qu'à un nombre.
La récurrence sur la longueur d'un mot
C'est le schéma de preuve le plus employé du cours, et celui de l'exercice. Pour établir qu'une propriété est vraie pour tout mot , on procède par récurrence sur :
- Base : on prouve — la propriété pour le mot vide, de longueur 0.
- Hérédité : on suppose vraie pour tout mot de longueur (hypothèse de récurrence), et on en déduit pour un mot quelconque de longueur , généralement écrit avec .
Comme tout mot a une longueur finie, ces deux étapes suffisent à couvrir tout entier. L'égalité du chapitre 1 est l'ingrédient qui fait fonctionner presque toutes ces récurrences.
Un point de méthode qui sépare les copies : le cas de base ne se néglige jamais. Oublier de traiter — parce qu'il « paraît évident » — est l'erreur classique, et souvent c'est précisément là que la propriété est la plus subtile à établir.
Quiz · 1 question
On veut prouver qu'une propriété P(u) est vraie pour tout mot u de Σ*, par récurrence sur |u|. Que doit contenir la preuve ?
- Uniquement l'hérédité : montrer que si P(w) est vraie, alors P(a·w) l'est — hérédité seule
- Le cas de base P(ε), et l'hérédité : de P(w) pour |w| = n, déduire P(a·w) pour |w|+1 — base + hérédité
- Vérifier P sur un grand nombre de mots choisis au hasard — tests
Réponse : Une preuve par récurrence sur la longueur exige DEUX étapes : le cas de base P(ε), sans lequel rien n'est ancré, et l'hérédité qui transmet la propriété d'un mot de longueur n à un mot de longueur n+1. L'hérédité seule ne prouve rien — elle « suppose » P(w) sans jamais l'avoir établie quelque part. Et tester sur des exemples, même nombreux, ne couvre qu'un nombre fini de cas : cela peut suggérer une propriété, jamais la démontrer sur Σ*, qui est infini.
La fonction de transition
Dernier outil, et le plus tourné vers la suite. Une fonction associe à chaque élément de (le domaine) un élément de (le codomaine). « Un », pas « au moins un » ni « au plus un » : à chaque entrée correspond exactement une sortie.
L'objet central du cœur du cours est la fonction de transition d'un automate, qu'on notera . Elle prendra un état et une lettre, et rendra un état :
Lue à voix haute : « depuis l'état , en lisant la lettre , on va dans l'état ». Toute la mécanique d'un automate déterministe (chapitre 3) tiendra dans cette fonction. Et c'est justement l'exigence de fonction — une seule sortie par entrée — qui distinguera le déterminisme du non-déterminisme : au chapitre 4, on relâchera cette contrainte, rendra un ensemble d'états, et l'on ne parlera plus de fonction au sens strict mais de relation. Toute la difficulté de la déterminisation viendra de ce basculement.
Quiz · 1 question
Un ensemble A a 5 éléments. Combien d'états, au maximum, l'automate déterminisé issu d'un automate à 5 états peut-il avoir — et où lit-on ce nombre ?
- 5 : la déterminisation ne change pas le nombre d'états — inchangé
- 25, car on considère les couples d'états — couples
- 2⁵ = 32, car les états du déterminisé sont les sous-ensembles de l'ensemble des états — ensemble des parties
Réponse : La déterminisation (chapitre 4) construit un automate dont les états sont les SOUS-ENSEMBLES de l'ensemble des états de départ. L'ensemble des parties d'un ensemble à n éléments en compte 2ⁿ — ici 2⁵ = 32. C'est exactement le 2ⁿ de l'ensemble des parties rappelé dans ce chapitre, et c'est lui qui explique l'explosion potentielle du nombre d'états lors de la déterminisation. En pratique on n'atteint presque jamais ce maximum, mais la borne est bien 2ⁿ.
À vous
L'exercice met la récurrence en pratique sur un objet concret : le miroir d'un mot. Vous définissez la fonction miroir par récursion sur la structure du mot — un cas de base pour , un cas récursif pour —, puis vous testez la propriété .
L'important est ce que la solution révèle : la structure de la fonction récursive est exactement celle de la preuve par récurrence. Définir par récursion et prouver par récurrence sont le même geste — celui que vous répéterez tout le reste de l'année.
Exercice de code
Définissez la fonction miroir par récursion sur la structure d'un mot, puis testez la propriété miroir(u·v) = miroir(v)·miroir(u). Les tests suggèrent — la solution vous donne la vraie preuve par récurrence, dont la structure calque exactement celle de la fonction.
Point de départ
// Le miroir d'un mot : miroir(abc) = cba. On le définit PAR RÉCURSION sur la
// structure du mot — exactement comme on le prouverait par induction.
//
// miroir(ε) = ε (cas de base)
// miroir(a · u) = miroir(u) · a (cas récursif : a est la 1re lettre)
//
// C'est la traduction en code d'une définition inductive. Le "cas de base" et
// le "cas récursif" sont exactement les deux cas d'une preuve par récurrence.
// ── À VOUS (1) : définir miroir par récursion ───────────────────────────────
function miroir(u) {
if (u === "") return ""; // cas de base : miroir(ε) = ε
// cas récursif : première lettre = u[0], reste = u.slice(1)
return ""; // à compléter avec miroir(u.slice(1)) et u[0]
}
// ── À VOUS (2) : vérifier une propriété par la pratique ─────────────────────
// PROPRIÉTÉ à établir : pour tous mots u, v : miroir(u·v) = miroir(v)·miroir(u)
// (l'ordre s'inverse !). Testez-la sur de nombreux couples : si elle tient
// partout, c'est bon signe — mais SEULE une preuve par récurrence la garantit.
function proprieteTient(u, v) {
return miroir(u + v) === miroir(v) + miroir(u);
}
// ── Vérification ────────────────────────────────────────────────────────────
console.log("miroir('abc') =", miroir("abc"), "(attendu cba)");
console.log("miroir('') =", "'" + miroir("") + "'", "(attendu ε)");
console.log("");
const mots = ["", "a", "ab", "abba", "aabb", "xyz"];
let toutesOk = true;
for (const u of mots) for (const v of mots) {
if (!proprieteTient(u, v)) { console.log("CONTRE-EXEMPLE : u=" + u + " v=" + v); toutesOk = false; }
}
console.log(toutesOk ? "La propriété tient sur tous les tests." : "Propriété fausse !");
Solution
function miroir(u) {
if (u === "") return "";
return miroir(u.slice(1)) + u[0]; // on renvoie le miroir du reste, PUIS
// la première lettre — qui passe au bout
}
// La propriété miroir(u·v) = miroir(v)·miroir(u) tient sur tous les tests.
// Les tests NE la prouvent PAS — ils ne couvrent qu'un nombre fini de cas.
// Voici la preuve, qui est le vrai objet du chapitre :
//
// ── Preuve par récurrence sur |u| ──────────────────────────────────────────
//
// On veut : ∀u ∀v, miroir(u·v) = miroir(v)·miroir(u).
// On raisonne par récurrence sur la longueur de u.
//
// BASE (|u| = 0, donc u = ε) :
// miroir(ε·v) = miroir(v) car ε·v = v
// = miroir(v)·ε car ε est neutre
// = miroir(v)·miroir(ε) car miroir(ε) = ε
// ✓ la propriété est vraie pour u = ε.
//
// HÉRÉDITÉ : supposons la propriété vraie pour tout mot de longueur n
// (hypothèse de récurrence). Soit u de longueur n+1 ; on l'écrit u = a·w
// avec a une lettre et |w| = n. Alors :
// miroir(u·v) = miroir(a·w·v)
// = miroir(w·v)·a (définition de miroir)
// = (miroir(v)·miroir(w))·a (hypothèse de récurrence sur w)
// = miroir(v)·(miroir(w)·a) (associativité)
// = miroir(v)·miroir(a·w) (définition de miroir, à rebours)
// = miroir(v)·miroir(u).
// ✓ la propriété se transmet de n à n+1.
//
// Par le principe de récurrence, elle est vraie pour TOUT u. CQFD.
//
// ── Ce qu'il faut retenir ───────────────────────────────────────────────────
// La STRUCTURE de la fonction récursive (cas de base ε, cas récursif a·w) est
// exactement la structure de la preuve (base ε, hérédité de w à a·w). Définir
// par récursion et prouver par récurrence, c'est le même geste. C'est le
// schéma de raisonnement de TOUT le cours — les automates, Kleene, le lemme
// de pompage s'en servent tous.
Ce que la suite en fait
Vous disposez maintenant du vocabulaire (chapitre 1) et des outils de preuve (ce chapitre). Le bloc II peut commencer, et c'est le cœur du cours.
Le chapitre 3 introduit l'objet vers lequel tout ce qui précède tendait : l'automate fini déterministe, entièrement bâti sur la fonction de transition définie ici. La double inclusion servira à prouver des équivalences, la récurrence sur la longueur à établir qu'un automate reconnaît bien le langage voulu, et le de l'ensemble des parties reviendra dès le chapitre 4 pour expliquer le coût de la déterminisation.
À retenir
Flashcards · 4 cartes
- Quelles sont les deux étapes d'une preuve par récurrence sur la longueur d'un mot ?
- La BASE — prouver P(ε), la propriété pour le mot vide — et l'HÉRÉDITÉ — supposer P vraie pour tout mot de longueur n, et en déduire P pour un mot de longueur n+1 (écrit u = a·w avec |w| = n). Comme tout mot a une longueur finie, ces deux étapes couvrent Σ* entier. Le cas de base ne se néglige jamais : c'est souvent là que la difficulté se cache.
- Comment prouve-t-on l'égalité de deux langages (ou l'équivalence de deux descriptions) ?
- Par DOUBLE INCLUSION : montrer A ⊆ B et B ⊆ A. Pour A ⊆ B, on prend un élément quelconque de A et on montre qu'il est dans B. C'est la méthode qui servira à prouver qu'un automate et une expression régulière décrivent le même langage (théorème de Kleene), ou qu'un AFD et un AFN sont équivalents.
- Qu'est-ce qu'une fonction de transition δ, et quel rôle joue-t-elle dans le cours ?
- δ : Q × Σ → Q associe à un état q et une lettre a un unique état δ(q,a) = q' : « depuis q, en lisant a, on va en q' ». C'est le cœur d'un automate déterministe. L'exigence « une seule sortie par entrée » DÉFINIT le déterminisme ; la relâcher (δ rend un ensemble d'états) donne le non-déterminisme du chapitre 4.
- Pourquoi le nombre 2ⁿ (ensemble des parties) est-il important pour la suite ?
- L'ensemble des parties d'un ensemble à n éléments compte 2ⁿ sous-ensembles. Or la déterminisation (chapitre 4) construit un automate dont les états sont les sous-ensembles des états de départ : d'où au plus 2ⁿ états, et l'explosion potentielle du nombre d'états. Le même 2ⁿ relie aussi une relation d'équivalence à la minimisation (chapitre 6), qui regroupe les états indistinguables en classes.
Exercices d'entraînement
Exercice 1
Récurrence sur la longueur
Pour un mot et un entier , on note la concaténation de copies de (avec ). Démontrer par récurrence sur que
Correction
Base () : , donc . Vrai.
Hérédité : supposons pour un donné. Alors , et comme les longueurs s'ajoutent à la concaténation (chapitre 1) : La propriété se transmet de à ; par récurrence, elle vaut pour tout .
Exercice 2
Involution du miroir
On admet la propriété . Démontrer par récurrence sur que pour tout mot .
Correction
Base () : , donc . Vrai.
Hérédité : soit avec une lettre et , en supposant . On a (car et la propriété admise). Donc La dernière égalité utilise l'hypothèse de récurrence. La propriété vaut donc pour tout .
Exercice 3
Parties et relation d'équivalence
- Un ensemble a éléments. Combien a-t-il d'éléments ?
- Sur , on pose lorsque . Est-ce une relation d'équivalence ? Combien a-t-elle de classes ?
Correction
- a éléments : chacun des éléments est, indépendamment, dans le sous-ensemble ou non.
- Oui : est réflexive (), symétrique () et transitive ( et ). Ses classes sont les ensembles de mots de même longueur : une classe par entier , donc une infinité dénombrable de classes. (C'est ce type de partition que la minimisation d'automate exploitera au chapitre 6.)