TP 4 : Algorithme CYK (Cocke-Younger-Kasami)
Solution
type grammaire = {
n_variables : int;
regles1 : (int * char) list;
regles2 : (int * int * int) list;
epsilon : bool
}
(* 6 *)
let g0 = {
n_variables = 5;
regles1 = [(0, 'b'); (1, 'a'); (2, 'b'); (4, 'a')];
regles2 = [(0, 1, 2); (0, 2, 1); (0, 3, 1); (1, 1, 4); (3, 1, 2)];
epsilon = false
}
(* 7 *)
let cyk g u =
let n = String.length u in
let k = g.n_variables in
let t = Array.make (n+1) [||] in
for i = 0 to n do
t.(i) <- Array.make_matrix n k false
done;
if g.epsilon then t.(0).(0).(0) <- true;
let rec aux = function
| [] -> ()
| (i, a)::q ->
for d = 0 to n - 1 do
if u.[d] = a then t.(1).(d).(i) <- true
done;
aux q
in
aux g.regles1;
for l = 2 to n do
for d = 0 to n - l do
let rec aux = function
| [] -> ()
| (i, j, k)::q ->
for p = 1 to l - 1 do
if d + p < n && t.(p).(d).(j) && t.(l-p).(d+p).(k)
then t.(l).(d).(i) <- true
done;
aux q
in
aux g.regles2
done
done;
t.(n).(0).(0);;
(* 8 *)
cyk g0 "aab";;
cyk g0 "aabb";;
cyk g0 "abaa";;
cyk g0 "aababa";;
(* 9 *)
type arbre = Vide | Un of int * char | Deux of int * arbre * arbre
let arbre_derivation g u : arbre option =
let n = String.length u in
let k = g.n_variables in
let t = Array.make (n+1) [||] in
for i = 0 to n do
t.(i) <- Array.make_matrix n k None
done;
if g.epsilon then t.(0).(0).(0) <- Some Vide;
let rec aux = function
| [] -> ()
| (i, a)::q ->
for d = 0 to n - 1 do
if u.[d] = a then t.(1).(d).(i) <- Some (Un (i, a))
done;
aux q
in
aux g.regles1;
for l = 2 to n do
for d = 0 to n - l do
let rec aux = function
| [] -> ()
| (i, j, k)::q ->
for p = 1 to l - 1 do
if d + p < n
then match t.(p).(d).(j), t.(l-p).(d+p).(k) with
| Some a1, Some a2 -> t.(l).(d).(i) <- Some (Deux (i, a1, a2))
| _ -> ()
done;
aux q
in
aux g.regles2
done
done;
t.(n).(0).(0);;
(* 10 *)
arbre_derivation g0 "aab";;
L'algorithme CYK permet de déterminer, par programmation dynamique, si un mot est généré par une grammaire non contextuelle.
Il permet aussi de trouver un arbre de dérivation pour ce mot, par analyse syntaxique ascendante (bottom-up : des feuilles à la racine).
L'algorithme prend en entrée une grammaire en forme normale de Chomsky, c'est-à-dire que toutes les règles sont de la forme ou ou , où , et .
On note les variables, où .
Équation de récurrence
Cette partie est à faire sur papier.
Soit . On veut savoir si . Pour cela, on va calculer, pour , et :
- À quelle condition a t-on ?
- Que vaut ?
- Que vaut ?
Pour avoir , il faut que avec et .
- En déduire une équation de récurrence pour .
- En déduire un algorithme en pseudo-code pour remplir le tableau . Quelle est sa complexité ?
Implémentation
On définit le type suivant :
type grammaire = {
n_variables : int;
regles1 : (int * char) list;
regles2 : (int * int * int) list;
epsilon : bool
}
Les variables sont numérotées de 0
à n_variables - 1
(int
) et les lettres sont des caractères (char
).
regles1
contient un couple pour chaque règle et regles2
contient un triplet pour chaque règle .
epsilon
est vrai si .
- Définir une variable
g0
représentant la grammaire suivante :
-
Écrire une fonction
cyk : grammaire -> string -> bool
qui prend en argument une grammaire et un mot et renvoie vrai si le mot est dans le langage de la grammaire, en utilisant l'algorithme CYK décrit en première partie. -
Justifier que
g0
engendre le langage et tester la fonctioncyk
sur quelques exemples.
Arbre de dérivation
On définit le type suivant pour modéliser un arbre de dérivation :
type arbre = Vide | Un of int * char | Deux of int * arbre * arbre
où :
Vide
correspond à une dérivation ,Un (i, a)
correspond à une dérivation ,Deux (i, j, k)
correspond à une dérivation .
On rappelle que le type option
est défini nativement en OCaml par :
type 'a option = None | Some of 'a
On adapte alors l'algorithme CYK avec t : arbre option array array array
où t[l][d][i]
contient un arbre de dérivation pour s'il en existe un, None
sinon.
- Écrire une fonction
arbre_derivation : grammaire -> string -> arbre option
qui prend en argument une grammaire et un mot et renvoie un arbre de dérivation pour ce mot si celui-ci est dans le langage de la grammaire ouNone
sinon.