• Aucun résultat trouvé

2.4 Modèle de publication par l’exemple

2.4.2 Instances canoniques

La production du document canonique de la requête DQL suppose que l’instance proposée à l’utilisateur permette la construction et l’interprétation de ce document canonique. Il existe (au moins) deux possibilités :

1. l’utilisateur saisit, au fur et à mesure de la création de son exemple, des valeurs qui sont ensuite provisoirement insérées dans l’instance afin de pouvoir déterminer la requête DQL corres- pondante ;

2. le système de publication propose à l’utilisateur des valeurs prédéfinies pour la construction de son exemple.

Le premier cas se ramène à un problème d’interface et nous y revenons dans la section suivante. Le second cas pose le problème de la préparation d’une instance permettant la construction d’un document canonique pour toutes les requêtes envisageables sur le schéma du graphe.

Définition 13 (Instance canonique). Une instance GI d’un schéma S est uneinstance canonique si,

pour toute requête q sur S, il existe un document canonique de q sur GI.

Une instance est canonique si elle est complète, minimale et non ambiguë. La complétude assure que toutes les navigations envisageables par rapport au schéma sont possibles. La minimalité et la non-ambiguïté servent à interpréter le document canonique comme une requête.

Reprenons l’instance relationnelle de la figure 2.3, en considérant que la table Film ne contient que le n-uplet correspondant à Kagemusha. Supposons qu’un utilisateur souhaite produire un programme de publication montrant un film avec l’ensemble de ses acteurs. Il n’est pas possible de produire un document canonique pour ce programme sur une telle instance, puisque aucun rôle du film Kage- musha n’est représenté dans la table Rôle. Il sera donc impossible de produire ce programme par l’exemple et l’instance n’est pas canonique.

Si, au lieu de Kagemusha, on place dans la table Film le n-uplet correspondant à Van Gogh, on peut cette fois produire un exemple du programme de publication donnant un film, son metteur en scène et ses acteurs. Voici cet exemple :

Van Gogh, 1990, mis en scène par Maurice Pialat Avec :

En revanche, l’instance contenant uniquement le film Van Gogh est insuffisante pour construire un exemple de la requête de publication qui affiche un film, les acteurs de ce film et pour chaque acteur les films que cet acteur a éventuellement lui-même mis en scène. Dans cette instance en effet Jacques Dutronc n’a réalisé aucun film. Or l’association liant un artiste à un film en tant que réalisateur existe et il faut donc envisager qu’un utilisateur souhaite l’inclure dans la construction de son document dès qu’il est en situation (autrement dit dès qu’il manipule un nœud de type Artiste). Une telle instance n’est donc toujours pas canonique.

Enfin prenons comme dernière hypothèse la même instance que celle de la figure 2.3 dans la- quelle, cette fois, le seul film est Impitoyable. Cette instance permet la construction du document canonique donnant un film, ses acteurs et les films réalisés par ces acteurs. Le voici :

Impitoyable, 1992, mis en scène par Clint Eastwood Avec :

- Clint Eastwood, né en 1930, dans le rôle de William Munny également réalisateur du film <<~Impitoyable~>>

On peut constater que ce document est rendu possible par la présence d’un cycle dans le graphe de données, correspondant au cycle Film → Réalisateur → Acteur → Film dans le schéma du graphe. La taille du cycle dans l’instance est proportionnelle à la taille du cycle dans le schéma. Avec les deux nœuds Eastwood et Impitoyable, le cycle est de taille minimale (deux arêtes). Un inconvénient est que la faible taille du cycle amène l’utilisateur qui crée son exemple à retrouver plusieurs fois le même nœud, comme le montre le cas ci-avant où on retrouve deux fois aussi bien Eastwood que Impitoyable. Cela ne pose pas de problème pour la génération de la requête, mais peut être troublant en donnant l’impression d’un manque de généralité du document canonique.

Il est possible de généraliser l’instance à des cycles plus longs, toujours de taille k × n, où n est la taille du cycle dans le schéma du graphe. La figure 2.4 montre un cycle minimal (à gauche) et une généralisation à un cycle de taille k × n (à droite).

Jeremiah Johnson Impitoyable

Clint Eastwood Woody Allen

Maris et femmes

réalise role réalise

Sidney Pollack Robert Redford

...

role

a. Cycle minimal (2 arêtes) b. Cycle de taille k*2

F. 2.4 – Création de cycles dans une instance canonique

Notez que la présence d’un cycle dans le schéma du graphe impose un cycle également dans le graphe de données : dans le cas d’un chemin qui ne serait pas un cycle, on laisserait les deux nœuds extrêmes sans « correspondant » et on couperait donc la possibilité de prolonger un document- exemple à partir de ces nœuds.

La construction d’une instance canonique doit simplement s’assurer que cette propriété est véri- fiée. Dans le cas où on se limite à créer des cycles de taille minimale, l’algorithme de construction est trivial : il suffit d’instancier un nœud pour chaque type de nœud dans V et d’instancier ensuite une arête entre ces nœuds pour chaque type d’arête dans E. Nous donnons ci-après un algorithme un peu plus sophistiqué qui prend en compte le facteur k de développement de chaque cycle.

L’algorithme maintient un tableau global nodesrpour chaque type de nœud r du schéma. Chaque

tableau nodesrcontient les instances engendrées par l’algorithme de création de l’instance, dénotées

nodesr[1], nodesr[2], etc.

L’algorithme transmet incrémentalement un chemin de la forme r1.e1.r2.e2. · · · .rn, ri ∈ V et ei ∈ E,

augmenté à chaque appel récursif et représentant les nœuds et arêtes créés par l’empilement des appels. Nous utilisons deux fonctions auxiliaires sur les chemins :

1. dist(path, r) renvoie le nombre d’étapes depuis la première occurrence d’un nœud de type r dans le chemin ;

2. nb(path, r) renvoie le nombre d’occurrences d’un nœud de type r dans le chemin .

L’algorithme prend en entrée un nœud N, le type e de l’arête à créer et le chemin des nœuds et arêtes créés depuis l’appel initial. K indique la taille minimale souhaitée pour tout cycle.

C (N, e, path)

Input : N ∈ VI, un nœud, e un type d’arête tel que N est une instance de initial(e), pathle chemin.

begin

// On prend le type du nœud terminal de l’arête. r:= terminal(e)

// Si on n’a jamais rencontré r dans le chemin : on prend le premier nœud de r if (r < path) then ir:= 1

// Si la première occurrence de r dans le chemin est à distance supérieure à K : // pas de risque de trop petit cyle, donc on prend le premier nœud de r également else if (dist(path, r) ≥ K) then ir:= 1

// Sinon il faut utiliser une instance de r non encore présente dans le chemin else ir := nb(r, path) + 1

// Maintenant irdésigne l’instance de nodesrà utiliser if (nodesr[ir] existe) GI+ = N e → nodesr[ir] ; GI+ = nodesr[ir] e−1 → N // Fin : pas d’appel récursif nécessaire

else

// Instancier un nouveau nœud nodesr[ir] et créer l’arête nodesr[ir] := new(r) ; GI+ = N

e

→ nodesr[ir] ; GI+ = nodesr[ir] e−1

→ N

// Maintenant il faut des appels récursifs, un pour chaque chemin possible à partir de nodesr[ir]

path:= path + e.r

for each e in E tel que initial(e)= r et terminal(e) , N C(nodesr[ir], e, path)

end for end if end

L’algorithme C doit être appelé pour chaque composante connexe du schéma du graphe, en prenant n’importe quel type de nœud relation dans chaque composante comme point initial de création de l’instance du graphe.

Cet algorithme de construction fabrique une instance canonique abstraite, les valeurs des nœuds n’ayant pas de signification. En pratique il est sans doute préférable de le mettre en œuvre en s’ap- puyant sur une instance réelle, afin d’obtenir des valeurs de nœuds intuitives pour l’utilisateur. Il n’est cependant pas garanti de trouver une instance canonique dans une instance réelle : en reprenant l’exemple de la figure 2.4, l’absence de Eastwood dans l’instance réelle ne permet plus de trouver de cycles pour K > 2.