En informatique , l' algorithme de Cocke-Younger-Kasami (également appelé CYK ou CKY ) est un algorithme d'analyse syntaxique pour les grammaires hors contexte , publié par Itiroo Sakai en 1961. Cet algorithme porte le nom de certains de ses redécouvreurs : John Cocke , Daniel Younger, Tadao Kasami et Jacob T. Schwartz . Il utilise une approche d'analyse syntaxique ascendante et la programmation dynamique .
La version standard de CYK ne fonctionne qu'avec des grammaires hors contexte données sous forme normale de Chomsky (CNF). Cependant, toute grammaire hors contexte peut être transformée algorithmiquement en une grammaire CNF exprimant le même langage .
L'importance de l'algorithme CYK tient à sa grande efficacité dans certaines situations. En utilisant la notation grand O , le temps d'exécution de CYK dans le pire des cas est de
Forme standard
L' algorithme de programmation dynamique exige que la grammaire hors contexte soit mise sous forme normale de Chomsky (CNF), car il teste les possibilités de diviser la séquence courante en deux séquences plus courtes. Toute grammaire hors contexte qui ne génère pas la chaîne vide peut être représentée en CNF en utilisant uniquement des règles de production des formes suivantes :
Algorithme
Sous forme de pseudocode
L'algorithme en pseudocode est le suivant :
Soit l'entrée une chaîne I de n caractères : a₁ … aₙ . Soit la grammaire r symboles non terminaux R₁ … Rₙ , avec R₁ comme symbole de départ . Soit P [ n , n , r ] un tableau de booléens. Initialisez tous les éléments de P à faux. Soit back [ n , n , r ] un tableau de listes de triplets pointant vers l' arrière . Initialisez tous les éléments de back à la liste vide.pour chaque s = 1 à n pour chaque unité de production R v → un ensemble s P [ 1 , s , v ] = vraipour chaque l = 2 à n -- Longueur de l'intervalle pour chaque s = 1 à n - l + 1 -- Début de l'intervalle pour chaque p = 1 à l - 1 -- Partition de l'intervalle pour chaque production R a → R b R c si P [ p , s , b ] et P [ l - p , s + p , c ] alors définir P [ l , s , a ] = vrai, ajouter <p,b,c> à l'arrière [ l , s , a ] Si P [n, 1 , 1 ] est vrai, alors I appartient au langage et retourner à l'origine . En remontant le parcours, on peut facilement construire tous les arbres d'analyse syntaxique possibles de la chaîne. Sinon, retourner « n'appartient pas au langage ».
CYK probabiliste (pour trouver l'analyse syntaxique la plus probable)
Permet de retrouver l'analyse syntaxique la plus probable étant donné les probabilités de toutes les productions.
Soit l'entrée une chaîne I composée de n caractères : a₁ … aₙ . Soit la grammaire r symboles non terminaux R₁ … Rₙ , avec R₁ comme symbole initial . Soit P [ n , n , r ] un tableau de nombres réels. Initialisez tous les éléments de P à zéro. Soit back [ n , n , r ] un tableau de triplets pointant vers l' arrière . Pour chaque s = 1 à n, pour chaque unité de production R <sub>v</sub> → a<sub> s</sub>, définir P [ 1 , s , v ] = Pr( R<sub> v</sub> → a <sub> s </sub> ) . Pour chaque l = 2 à n , la longueur de l'intervalle est définie pour chaque s = 1 à n - l + 1 , le début de l'intervalle est défini pour chaque p = 1 à l - 1 , la partition de l'intervalle est définie pour chaque production R <sub> a</sub> → R <sub> b</sub> R <sub> c </sub> . La probabilité de partitionnement est calculée comme suit : P [ p , s , b ] * P [ l - p , s + p , c ]. Si cette probabilité est supérieure à P [ l , s , a ] , alors P [ l , s , a ] = probabilité de partitionnement et l'intervalle [ l , s , a ] = <p, b, c> est défini .Si P [n, 1 , 1 ] > 0, alors trouver l'arbre d'analyse syntaxique en remontant le parcours et retourner l'arbre d'analyse syntaxique ; sinon, retourner « n'appartient pas au langage ».
En prose
En termes informels, cet algorithme considère chaque sous-chaîne possible de la chaîne d'entrée et définit
Exemple

Voici un exemple de grammaire :
NP\ VP}}\\{\ce {VP}}&\ {\ce {->VP\ PP}}\\{\ce {VP}}&\ {\ce {->V\ NP}}\\{\ce {VP}}&\ {\ce {->eats}}\\{\ce {PP}}&\ {\ce {->P\ NP}}\\{\ce {NP}}&\ {\ce {->Det\ N}}\\{\ce {NP}}&\ {\ce {->she}}\\{\ce {V}}&\ {\ce {->eats}}\\{\ce {P}}&\ {\ce {->with}}\\{\ce {N}}&\ {\ce {->fish}}\\{\ce {N}}&\ {\ce {->fork}}\\{\ce {Det}}&\ {\ce {->a}}\end{aligned S ⟶ NP vice-président vice-président ⟶ vice-président PP vice-président ⟶ V NP vice-président ⟶ mange PP ⟶ P NP NP ⟶ Dét N NP ⟶ elle V ⟶ mange P ⟶ avec N ⟶ poisson N ⟶ fourchette Dét ⟶ un {\displaystyle {\begin{aligned}{\ce {S}}&\ {\ce {->NP\ VP}}\\{\ce {VP}}&\ {\ce {->VP\ PP}}\\{\ce {VP}}&\ {\ce {->V\ NP}}\\{\ce {VP}}&\ {\ce {->eats}}\\{\ce {PP}}&\ {\ce {->P\ NP}}\\{\ce {NP}}&\ {\ce {->Det\ N}}\\{\ce {NP}}&\ {\ce {->she}}\\{\ce {V}}&\ {\ce {->eats}}\\{\ce {P}}&\ {\ce {->with}}\\{\ce {N}}&\ {\ce {->fish}}\\{\ce {N}}&\ {\ce {->fork}}\\{\ce {Det}}&\ {\ce {->a}}\end{aligned}}}
La phrase « elle mange un poisson avec une fourchette » est maintenant analysée à l'aide de l'algorithme CYK. Dans le tableau suivant,
Pour plus de clarté, la table CYK pour P est représentée ici sous la forme d'une matrice bidimensionnelle M contenant un ensemble de symboles non terminaux, tel que soit dans , et seulement si . Dans l'exemple ci-dessus, étant donné qu'un symbole de départ S est dans , la phrase peut être générée par la grammaire.
Extensions
Générer un arbre d'analyse syntaxique
L'algorithme décrit ci-dessus est un module de reconnaissance qui détermine uniquement si une phrase appartient à la langue. Il est facile de l'étendre en un analyseur syntaxique qui construit également un arbre d'analyse , en stockant les nœuds de l'arbre comme éléments du tableau, au lieu du booléen 1. Le nœud est lié aux éléments du tableau qui ont servi à le produire, afin de construire la structure arborescente. Un seul nœud de ce type par élément du tableau est nécessaire si l'on ne doit produire qu'un seul arbre d'analyse. Cependant, si l'on souhaite conserver tous les arbres d'analyse d'une phrase ambiguë, il est nécessaire de stocker dans l'élément du tableau la liste de toutes les manières d'obtenir le nœud correspondant lors de l'analyse. Ceci est parfois réalisé à l'aide d'une seconde table B[n,n,r] de pointeurs de retour . Le résultat final est alors une forêt partagée d'arbres d'analyse possibles, où les parties communes aux arbres sont factorisées entre les différentes analyses. Cette forêt partagée peut être commodément lue comme une grammaire ambiguë ne générant que la phrase analysée, mais avec la même ambiguïté que la grammaire originale, et les mêmes arbres d'analyse jusqu'à un renommage très simple des non-terminaux, comme l'a montré Comme l'ont souligné et Leiß (2009) , l'inconvénient de toutes les transformations connues en forme normale de Chomsky est qu'elles peuvent entraîner une augmentation indésirable de la taille de la grammaire. La taille d'une grammaire est la somme des tailles de ses règles de production, la taille d'une règle étant égale à un plus la longueur de son membre droit.Analyse syntaxique des grammaires hors contexte non CNF
Analyse syntaxique des grammaires hors contexte pondérées
Il est également possible d'étendre l'algorithme CYK pour analyser des chaînes de caractères à l'aide de grammaires hors contexte pondérées et stochastiques . Les poids (probabilités) sont alors stockés dans la table P au lieu de booléens ; ainsi, P[i,j,A] contient le poids minimal (probabilité maximale) que la sous-chaîne de i à j puisse être extraite de A. D'autres extensions de l'algorithme permettent d'énumérer toutes les analyses d'une chaîne par poids croissant (probabilité décroissante).
Stabilité numérique
Lorsqu'on applique l'algorithme probabiliste CYK à une longue chaîne de caractères, la probabilité de séparation peut devenir très faible en raison de la multiplication de nombreuses probabilités. On peut remédier à ce problème en sommant les logarithmes des probabilités au lieu de les multiplier.
L'algorithme de Valiant
Le temps d'exécution de CYK dans le pire des cas est de
En utilisant l' algorithme de Coppersmith-Winograd pour multiplier ces matrices, on obtient un temps d'exécution asymptotique dans le pire des cas de