J'ai vu cette question , et j'étais curieux de savoir quel était le lemme de pompage ( Wikipedia didn pas beaucoup).
Je comprends que c'est fondamentalement une preuve théorique qui doit être vraie pour qu'une langue soit dans une certaine classe, mais au-delà, je ne comprends pas vraiment.
Quelqu'un veut-il essayer de l'expliquer à un niveau assez granulaire d'une manière compréhensible par les non-mathématiciens/doctorants en science-fiction?
Le lemme de pompage est une preuve simple pour montrer qu'un langage n'est pas régulier, ce qui signifie qu'une machine à états finis ne peut pas être construite pour lui. L'exemple canonique est la langue (a^n)(b^n)
. C'est le langage simple qui est n'importe quel nombre de a
, suivi du même nombre de b
. Donc les cordes
ab
aabb
aaabbb
aaaabbbb
etc. sont dans la langue, mais
aab
bab
aaabbbbbb
etc. ne le sont pas.
Il est assez simple de créer un FSM pour ces exemples:
Celui-ci fonctionnera jusqu'à n = 4. Le problème est que notre langage n'a imposé aucune contrainte à n, et les machines à états finis doivent être, enfin, finies. Peu importe le nombre d'états que j'ajoute à cette machine, quelqu'un peut me donner une entrée où n est égal au nombre d'états plus un et ma machine échouera. Donc, s'il peut y avoir une machine construite pour lire ce langage, il doit y avoir une boucle quelque part pour garder le nombre d'états fini. Avec ces boucles ajoutées:
toutes les chaînes de notre langue seront acceptées, mais il y a un problème. Après les quatre premiers a
, la machine perd le compte du nombre de a
qui ont été entrés car elle reste dans le même état. Cela signifie qu'après quatre, je peux ajouter autant de a
que je veux à la chaîne, sans ajouter de b
, et toujours obtenir la même valeur de retour. Cela signifie que les chaînes:
aaaa(a*)bbbb
avec (a*)
représentant un nombre quelconque de a
, seront tous acceptés par la machine même s'ils ne sont évidemment pas tous dans la langue. Dans ce contexte, nous dirions que la partie de la chaîne (a*)
peut être pompé. Le fait que la machine à états finis soit finie et n ne soit pas limitée, garantit que toute machine qui accepte toutes les chaînes du langage DOIT avoir cette propriété. La machine doit boucler à un moment donné et au moment où elle boucle, la langue peut être pompée. Par conséquent, aucune machine à états finis ne peut être créée pour cette langue et la langue n'est pas régulière.
N'oubliez pas que les expressions régulières et les machines à états finis sont équivalentes , puis remplacez a
et b
par des balises Html d'ouverture et de fermeture qui peuvent être imbriquées les unes dans les autres, et vous pouvez voir pourquoi il n'est pas possible d'utiliser des expressions régulières pour analyser Html
C'est un appareil destiné à prouver qu'une langue donnée ne peut pas appartenir à une certaine classe.
Considérons le langage des parenthèses équilibrées (signifiant les symboles '(' et ')', et incluant toutes les chaînes qui sont équilibrées dans le sens habituel, et aucune qui ne le sont pas). Nous pouvons utiliser le lemme de pompage pour montrer que ce n'est pas régulier.
(Une langue est un ensemble de chaînes possibles. Un analyseur est une sorte de mécanisme que nous pouvons utiliser pour voir si une chaîne est dans la langue, donc il doit être capable de faire la différence entre une chaîne dans la langue ou une chaîne à l'extérieur Une langue est "régulière" (ou "sans contexte" ou "contextuelle" ou autre) s'il existe un analyseur régulier (ou autre) qui peut la reconnaître, en distinguant les chaînes de la langue de celles qui ne le sont pas la langue.)
LFSR Consulting a fourni une bonne description. Nous pouvons dessiner un analyseur pour une langue régulière comme une collection finie de cases et de flèches, les flèches représentant les caractères et les cases les reliant (agissant comme des "états"). (Si c'est plus compliqué que cela, ce n'est pas un langage normal.) Si nous pouvons obtenir une chaîne plus longue que le nombre de cases, cela signifie que nous avons parcouru une case plus d'une fois. Cela signifie que nous avions une boucle, et nous pouvons parcourir la boucle autant de fois que nous le voulons.
Par conséquent, pour un langage régulier, si nous pouvons créer une chaîne arbitrairement longue, nous pouvons la diviser en xyz, où x est les caractères dont nous avons besoin pour arriver au début de la boucle, y est la boucle réelle et z est tout ce que nous besoin de rendre la chaîne valide après la boucle. L'important est que les longueurs totales de x et y soient limitées. Après tout, si la longueur est supérieure au nombre de boîtes, nous avons évidemment parcouru une autre boîte en faisant cela, et donc il y a une boucle.
Ainsi, dans notre langage équilibré, nous pouvons commencer par écrire n'importe quel nombre de parenthèses gauches. En particulier, pour un analyseur donné, nous pouvons écrire plus de parens gauche qu'il n'y en a de boîtes, et donc l'analyseur ne peut pas dire combien il y a de parens gauche. Par conséquent, x est une certaine quantité de parens gauche, et cela est fixe. y est également un certain nombre de parens gauches, et cela peut augmenter indéfiniment. On peut dire que z est un certain nombre de parens droits.
Cela signifie que nous pourrions avoir une chaîne de 43 parens gauche et 43 parens droite reconnue par notre analyseur, mais l'analyseur ne peut pas le dire à partir d'une chaîne de 44 parens gauche et 43 parens droit, ce qui n'est pas dans notre langue, donc l'analyseur ne peut pas analyser notre langue.
Étant donné que tout analyseur régulier possible a un nombre fixe de cases, nous pouvons toujours écrire plus de parens gauche que cela, et par le lemme de pompage, nous pouvons ensuite ajouter plus de parens gauche d'une manière que l'analyseur ne peut pas dire. Par conséquent, le langage de parenthèse équilibrée ne peut pas être analysé par un analyseur régulier et n'est donc pas une expression régulière.
C'est une chose difficile à obtenir en termes simples, mais fondamentalement, les expressions régulières doivent avoir une sous-chaîne non vide qui peut être répétée autant de fois que vous le souhaitez tandis que le nouveau mot entier reste valide pour la langue.
En pratique, le pompage des lemmes ne suffit pas pour PROUVER une langue correcte, mais plutôt comme un moyen de faire une preuve par contradiction et de montrer qu'une langue ne rentre pas dans la classe des langues (régulière ou sans contexte) ) en montrant que la lemme de pompage ne fonctionne pas pour elle.
Fondamentalement, vous avez une définition d'une langue (comme XML), qui est un moyen de savoir si une chaîne de caractères donnée (un "mot") est membre de cette langue ou non.
Le lemme de pompage établit une méthode par laquelle vous pouvez choisir un "mot" dans la langue, puis lui appliquer quelques modifications. Le théorème stipule que si la langue est régulière, ces changements devraient produire un "mot" qui est toujours de la même langue. Si la Parole que vous proposez n'est pas dans la langue, alors la langue n'aurait pas pu être régulière en premier lieu.
Le lemme de pompage simple est celui des langages réguliers, qui sont, entre autres, les ensembles de chaînes décrits par les automates finis. La principale caractéristique d'une automatisation finie est qu'elle n'a qu'une quantité finie de mémoire, décrite par ses états.
Supposons maintenant que vous ayez une chaîne, qui est reconnue par un automate fini, et qui est suffisamment longue pour "dépasser" la mémoire de l'automatisation, c'est-à-dire dans laquelle les états doivent se répéter. Ensuite, il y a une sous-chaîne où l'état de l'automate au début de la sous-chaîne est le même que l'état à la fin de la sous-chaîne. Puisque la lecture de la sous-chaîne ne change pas l'état, elle peut être supprimée ou dupliquée un nombre arbitraire de fois, sans que l'automate soit le plus sage. Ces chaînes modifiées doivent donc également être acceptées.
Il existe également un lemme de pompage un peu plus compliqué pour les langues sans contexte, où vous pouvez supprimer/insérer ce qui peut intuitivement être vu comme des parenthèses correspondantes à deux endroits de la chaîne.
En termes simples, je pense que vous avez presque raison. C'est une technique de preuve (deux en fait) pour prouver qu'une langue est PAS dans une certaine classe.
Par exemple, considérons un langage régulier (regexp, automates, etc.) avec un nombre infini de chaînes. À un certain moment, comme l'a dit Starblue, vous manquez de mémoire car la chaîne est trop longue pour l'automate. Cela signifie qu'il doit y avoir un morceau de la chaîne que l'automate ne peut pas dire combien de copies vous en avez (vous êtes dans une boucle). Donc, n'importe quel nombre de copies de cette sous-chaîne au milieu de la chaîne, et vous êtes toujours dans la langue.
Cela signifie que si vous avez un langage qui n'a PAS cette propriété, c'est-à-dire qu'il y a une chaîne suffisamment longue avec PAS DE sous-chaîne que vous pouvez répéter n'importe quel nombre de fois et être toujours dans la langue, alors la langue n'est pas régulière.
Par exemple, prenez cette langue L = anbn.
Essayez maintenant de visualiser l'automate fini pour la langue ci-dessus pour certains n.
si n = 1, la chaîne w = ab. Ici, nous pouvons faire un automate fini sans boucle si n = 2, la chaîne w = a2b2. Ici, nous pouvons faire un automate fini sans boucle
si n = p, la chaîne w = apbp. Essentiellement, un automate fini peut être supposé avec 3 étapes. Premier étage, il prend une série d'entrées et entre dans le deuxième étage. De même, de l'étape 2 à l'étape 3. Appelons ces étapes x, y et z.
Il y a quelques observations
Ainsi, les états finis de l'automate pour l'étape y devraient être capables de prendre les entrées 'a' et 'b' et aussi ne devraient pas prendre plus de a et b qui ne peuvent pas être dénombrés.
La conception de la scène y est donc purement infinie. Nous ne pouvons le rendre fini qu'en mettant des boucles et si nous mettons des boucles, l'automate fini peut accepter des langages au-delà de L = anbn. Donc, pour ce langage, nous ne pouvons pas construire un automate fini. Ce n'est donc pas régulier.
Par définition, les langues régulières sont celles reconnues par un automate à états finis. Considérez-le comme un labyrinthe: les états sont des pièces, les transitions sont des couloirs à sens unique entre les pièces, il y a une pièce initiale et une pièce de sortie (finale). Comme l'indique le nom "automate à états finis", il existe un nombre fini de pièces. Chaque fois que vous voyagez le long d'un couloir, vous notez la lettre écrite sur son mur. Un mot peut être reconnu si vous pouvez trouver un chemin de la pièce initiale à la pièce finale, en passant par des couloirs étiquetés avec ses lettres, dans le bon ordre.
Le lemme de pompage dit qu'il existe une longueur maximale (la longueur de pompage) pour laquelle vous pouvez vous promener dans le labyrinthe sans jamais retourner dans une pièce que vous avez traversée auparavant. L'idée est que, comme il n'y a que peu de pièces distinctes dans lesquelles vous pouvez marcher, au-delà d'un certain point, vous devez soit sortir du labyrinthe, soit traverser vos pistes. Si vous parvenez à parcourir un chemin plus long que cette longueur de pompage dans le labyrinthe, alors vous faites un détour: vous insérez un (au moins un) cycle sur votre chemin qui pourrait être supprimé (si vous voulez que votre traversée du labyrinthe se reconnaître un mot plus petit) ou répété (pompé) indéfiniment (permettant de reconnaître un mot super long).
Il existe un lemme similaire pour les langues sans contexte. Ces langages peuvent être représentés comme des mots acceptés par les automates pushdown, qui sont des automates à états finis qui peuvent utiliser une pile pour décider des transitions à effectuer. Néanmoins, comme il y a un nombre fini d'états stilla, l'intuition expliquée ci-dessus se perpétue, même à travers l'expression formelle de la propriété peut être légèrement plus complexe .