• Aucun résultat trouvé

Clôture et réduction

5.5 Domaine de fragmentation des diagrammes de tranches

5.5.3 Clôture et réduction

←− fusion i j 0 0 [0..i[ [i..n[ [0..i[ [0..j[ [i..n[ [j..n[ ⊥

Figure5.5 :On obtient le diagramme de droite à partir de celui de gauche en fissionnant le sommetien les sommetsiet j. Inversement, on obtient le diagramme de gauche à partir de celui de droite en fusionnant les sommetsiet jen le sommeti.

Sur les diagrammes, les cas précédents se traduisent par une duplication d’arc pour la du-plication de tranche, et par une dudu-plication de sommet pour la dudu-plication de borne. La fission d’une borne nécessite l’ajout dans le diagramme des sommets associés aux bornes produites de la fission. Puis pour chaque arc allant vers ou partant du sommet initial, on crée un des arcs al-lant vers ou partant de chacun des sommets dupliqués. Enfin, on ajoute également des arcs entre toute paire de sommets fissionnés en les associant à⊥. Ces arcs représentent effectivement tous des fragments vides. Les ajouter brise l’acyclicité du graphe. La fusion à l’inverse supprimera tout arc entre les sommets fusionnés et fusionnera les arcs entrants et sortants. La figure 5.5 illustre la fission et la fusion, la figure 5.6 donne l’algorithme de la fission et la figure 5.7 celui de la fusion.

En général, la fission génèrera plus d’arcs que nécessaire. Mais seul l’algorithme utilisant la fission et la fusion sait lesquels sont intéressants : à ce niveau d’abstraction, nous n’avons pas de moyen de savoir lesquels conserver. Certains arcs ne serviront qu’à réaliser des compositions, d’autres seront conservés tels quel, et d’autres devront être supprimés. Une implémentation ef-ficace voudra éviter de générer trop de fissions de tranches qui peuvent être coûteuses dans les domaines abstraits et utiliser une évaluation paresseuse de la fission.

5.5.3 Clôture et réduction

Rappelons que si on tient à ce que les diagrammes de tranches soient transitivement réduits c’est parce que si un arc du diagramme peut s’obtenir par transitivité c’est que la tranche associée à cet arc peut s’obtenir par composition. Or un fragment qui peut être obtenu par composition n’apporte aucune précision supplémentaire à la fragmentation : ce que l’on sait sur la tranche composée, on le sait déjà sur les tranches composantes.

Cependant il est utile de temporairement oublier cette contrainte et de considérer des graphes qui ne sont pas transitivement réduits. Après une composition ou une décomposition, le dia-gramme n’est jamais réduit, comme le montrait la figure 5.1.

Quoi qu’il en soit, si après avoir terminé de travailler avec un diagramme on se retrouve dans une situation où le graphe n’est pas réduit, on cherchera à retirer les arcs en trop. Pour le faire sans perdre d’information, il faudra auparavant être sûr que toute l’information acquise sur la variable associée à l’arc que l’on retire ne sera pas perdue, c’est à dire que toute information sur la tranche composée est bien déjà contenue dans les tranches composantes.

Entrées:D=(B,T) un diagramme sur (B,),b∈BetB0 ⊆ Bun ensemble de bornes équivalentes pourvérifiantB∩B0={b}

B ← B∪B0

Pour chaqueb0 ∈B0faire

Pour chaque(b,bs)∈Dfaire

SiT(b,bs)est>ou⊥alors

T(b0,bs) ← T(b,bs)

sinon

Choisir une nouvelle variable de synthèset

Fission deT(b,bs) ent

T(b0,bs) ← t

Pour chaque(bp,b)∈Dfaire

SiT(bp,b)est>ou⊥alors

T(bp,b0) ← T(bp,b)

sinon

Choisir une nouvelle variable de synthèset

Fission deT(bp,b) ent

T(bp,b0) ← t

Pour chaqueb1,b2∈B02faire

T(b1,b2) ← ⊥

Entrées:D=(B,T) un diagramme sur (B,),B0 ⊆Bun ensemble de bornes équivalentes pouretb∈B0

Pour chaqueb0∈B0/{b}faire

Pour chaque(b0,bs)∈Dfaire

SiT(b0,bs)n’est ni>ni⊥alors

SiT(b,bs)est défini et n’est ni>ni⊥alors

Fusion deT(b0,bs) dansT(b,bs) Supression deT(b0,bs)

sinon

T(b,bs) ← T(b0,bs)

T(b0,bs) 8

Pour chaque(bp,b0)∈Dfaire

SiT(bp,b0)n’est ni>ni⊥alors

SiT(bp,b)est défini et n’est ni>ni⊥alors

Fusion deT(bp,b0) dansT(bp,b) Supression deT(bp,b0)

sinon

T(bp,b) ← T(bp,b0)

T(bp,b0) 8

Pour chaqueb1,b2∈B02faire

SiT(b1,b2)n’est ni>ni⊥alors

Supression deT(b1,b2)

T(b1,b2) 8

B ← B/(B0/{b})

Dans cette section, nous définirons deux opérations. La première est une généralisation de la composition et permet de construire un arc dans le graphe qui peut être obtenu par transitivité. Durant cette construction, on tâchera de donner à la nouvelle tranche le maximum d’information connue à son sujet. La second est l’opération inverse. Elle consiste à déconstruire un arc en le retirant du graphe tout en récupérant toute l’information accumulée à son propos.

Avant de détailler ces deux opérations et afin de mieux les comprendre il faut observer le lien qu’elles ont avec le problème de la réduction des valeurs abstraites. Les domaines abstraits ont déjà leurs propres réductions. Mais un domaine abstrait n’a aucune connaissance des frag-mentations et ne peut être capable de dériver des propriétés impliquées par les singularités d’un diagramme. Considérons par exemple le diagramme suivant.

n i j 0 ∈ [0,4] ∈[2,5] ∈[1,6] ∈ [3,4]

Nous utiliserons ce diagramme en conjonction avec le domaine abstrait des intervalles. A coté de chacun des arcs figure un intervalle de valeurs possibles pour les cellules de chacune des tranches. Ce diagramme représente une caractéristique souvent rencontrée : il y a différentes ma-nières de construire une même tranche. Ici, la tranche [0..n[ peut être produite par la composition de [0..i[ et [i..n[ aussi bien que par la composition de [0..j[ et [j..n[. Si on pose la question « que sait t-on de [0..n[ » on pourra répondre en utilisant aussi bien l’une que l’autre des possibilités.

Construisons la tranche [0..n[ dans ce diagramme. On compose d’abord les tranches [0..i[ et [i..n[ du premier chemin en [0..n[. L’algorithme de composition va informer le domaine abstrait que l’on veut une nouvelle variable dont les propriétés sont celles vérifiées par ces deux tranches à la fois. On fait la même chose pour les tranches [0..j[ et [j..n[ du second chemin. Mais cette fois ci, puisque il y a déjà une tranche [0..n[, l’algorithme de composition va devoir fusionner le résultat des deux compositions. La fusion va permettre de dire au domaine abstrait que la tranche [0..n[ possède à la fois les propriétés de la première et de la seconde composition.

Pour le domaine abstrait, l’intervalle pour la tranche [0..n[ se calculera avec des unions pour les compositions et une intersection pour la fusion :

([0,4]t[2,5]) u ([1,6]t[3,4]) = [0,5]u[1,6] = [1,5]

Dans notre exemple, l’intervalle obtenu pour la tranche [0..n[ est optimal. En outre, l’intervalle obtenu peut servir à renforcer celui des quatre tranches originales. En effet, chacune de ces quatre tranches est incluse dans [0..n[ et hérite donc des propriétés calculées sur [0..n[.

n i j 0 ∈ [0,4] ∈[2,5] ∈[1,6] ∈ [3,4] ∈ [1 , 5]

Pour signifier au domaine abstrait qu’il doit renforcer les propriété des quatre tranches avec la tranche nouvellement construite, on utilise la seconde opération, la déconstruction. On va dé-construire la tranche [0..n[, c’est à dire la retirer du diagramme tout en transférant ses propriétés aux tranches qui la composent.

Pour déconstruire on suit l’exact procédé inverse de celui utilisé par la construction. Il y avait deux chemins pour construire [0..n[, il y a les deux même chemins pour la déconstruire. On com-mence donc par fissionner la tranche [0..n[ en deux pour obtenir deux tranches identiques. Puis on décompose chacune de ces deux tranches le long des deux chemins. Enfin, on peut fusion-ner les produit de la décomposition avec les tranches originales. Les deux premières opérations permettent de demander au domaine abstrait quatre variables correspondant aux tranches origi-nales mais avec les propriétés de la tranche [0..n[. La fusion quant à elle permet effectivement de transmettre cette propriété aux tranches originales.

Les intervalles des tranches [0..i[ et [j..n[ deviennent respectivement [1,4] et [1,5] tandis que tranches [i..n[ et [0..j[ restent inchangées.

n i j 0 ∈ [1,4] ∈[2,5] ∈[1,5] ∈ [3,4]

En utilisant la construction et la déconstruction on peut partiellement calculer une réduction de la valeur abstraite. Nous donnerons ici une version peu efficace des deux algorithmes, puis nous proposerons des pistes d’optimisations possibles.

Clôture

La construction est une opération qui consiste à ajouter un arc entre deux sommets lorsqu’il existe au moins un chemin entre ces deux sommets. Pour le moment, réaliser cette construction ne sera pas différent de construire tous les arcs obtenus par transitivité, c’est à dire de calculer la clôture transitive du diagramme.

Pour récupérer un maximum d’information il sera nécessaire que tout chemin permettant d’obtenir un arc à construire soit pris en compte. Le nombre de chemins entre deux sommets étant généralement exponentiel, il faudra réutiliser une astuce similaire à celle utilisée dans les

Entrées:D=(B,T) un diagramme surB,

Pourn de1à|B|faire

Pour(i,j)∈D et(j,k)∈Dfaire

Composer les arcs (i,j) et (j,k) en (i,k)

Figure5.8 :Algorithme de clôture.

algorithmes de recherche de chemin dans un graphe qui permet de ne pas considérer plusieurs fois le même sous chemin.

L’algorithme de base est similaire à celui du calcul du nombre de chemins dans un graphe par exponentiation de la matrice d’adjacence. Soit Ala matrice d’adjacence du graphe,Ai,j le coefficient sur lai-ème ligne et la j-ème colonne contient 1 s’il y a un arc (i,j) dans le graphe, 0 sinon. AlorsAnest la matrice telle que leAni,j est le nombre de chemins distincts et de longueur exactementnallant deià jdans le graphe. Le calcul deAn+1à partir deAn,

An+1

i,j =(An+1×A)i,j= ΣkAni,k×Ak,j

s’interprète en termes de graphes : pour chaque sommetk, les chemins de longueurn+1 allant deià jen ayantkcomme avant dernier sommet sont les chemins de longueurnallant deiàk

augmentés de l’arc (k,j) s’il existe. En outre, le nombre de chemins de longueurn+1 est égal à la somme pour tous les sommetskdu nombre de ces chemins.

Nous allons utiliser une méthode similaire, à ceci près qu’au lieu de compter les chemins, nous allons les construire. A chaque itération de l’algorithme, nous allons construire un nouveau diagramme dont les tranches sont les composées d’une tranche du diagramme original, et d’une tranche de l’itération précédente. Autrement dit, à l’itérationn, on obtiendra toutes les tranches produites par composition dentranches. Sur un diagramme sans cycle, le chemin le plus long ne peut excéder en longueur le nombre de sommets. La figure 5.8 donne cet algorithme.

L’algorithme est inefficace car il va calculer plusieurs fois les mêmes compositions. A l’ité-rationnil va non seulement calculer les compositions dentranches, mais également celles de moins dentranches, et donc refaire le travail des itérations précédentes. Sans optimisation, la complexité de cet algorithme estO(|B|4), la boucle interne itérant au pire pour chaque triplet de sommet du graphe.

Réduction

La réduction est l’exact inverse de la clôture. Chaque arc (i,k) peut potentiellement être dé-composé en deux arcs (i,j) et (j,k), si jvérifiei jk.

Construction et déconstruction

Les algorithmes présentés construisent et déconstruisent tous les arcs de la clôture transitive d’un graphe. Comme annoncé en introduction de cette section, on aura besoin par la suite de deux cas particulier de ces algorithmes : construire et détruire un unique arc. Ces problèmes ne sont pas plus simples : pour construire ou déconstruire un arc, il faudra toujours considérer tous les arcs intermédiaires.

Entrées:D=(B,T,) un diagramme

Pourn de1à|B|faire

Pouri,j,k∈B tels que i≺ j≺kfaire

Décomposer les arcs (i,k) en (i, j) et (j,k)

Figure5.9 :Algorithme de réduction.

Pour passer de la clôture et de la réduction à la construction et déconstruction, il faut modifier les algorithmes en deux points.

1. D’abord, on peut ignorer tout sommet et arc du graphe qui ne soit pas « entre » ces deux points. Autrement dit, dans les boucles interne des deux algorithmes, on se restreindra aux sommetsi, jetkqui sont effectivement encadrés par les deux extrémitési0,k0de l’arc à construire. Si on veut construire ou déconstruire l’arc (i0,k0) on prendra des triplets de sommets vérifianti0i≺ j≺k k0.

2. Il faudra également supprimer toute construction intermédiaire utile à l’algorithme. La construction ne doit construire que l’arc demandé, tandis qu’on exigera de la décons-truction qu’elle réduise effectivement le diagramme entre les deux sommets de l’arc à déconstruire.

Optimisations

Il y a plusieurs améliorations possibles des algorithmes précédents. Par exemple, composer une fois pour toutes les arcs autour des sommets de degré entrant et sortant égal à 1. Ou bien, mémoriser les compositions déjà réalisées pour ne pas réaliser deux fois les même. Ou encore, ignorer les parties du graphe qui ne sont pas entre deux sommets où divergent et se rejoignent plusieurs chemins.

En effet, les précédents algorithmes effectuent plusieurs fois les mêmes compositions ou les mêmes décompositions. C’est parfois nécessaire : entre deux compositions identiques, on peut avoir acquis plus d’information sur les tranches composantes et il est alors nécessaire de re-produire une nouvelle fois la composition. Sur certains diagrammes en revanche, il est possible de trouver un ordre d’itération des compositions ou des décompositions, de sorte qu’il ne soit pas nécessaire de refaire deux fois la même opération. Considérons par exemple le diagramme suivant.

n

k

i j l

0

Dans ce diagramme, on peut construire la tranche [0..k[ par composition de [0..i[ et [i..k[ et par composition de [0..j[ et [j...k[. Ensuite, on peut construire [0..n[ par composition de [0..k] et [k..n[ et par composition de [0..l[ et [l..n[. Toute autre composition est inutile. Cela est dû au fait qu’il y a une hiérarchie. On peut réduire le losange 0,i,j,ken l’arc (i,k). En effet, une fois l’arc

i,kconstruit, il sera par la suite inutile de calculer toute composition avec les quatre tranches qui ont servi à sa composition. On obtient alors un autre losange 0,k,l,nqu’on peut réduire à son tour.

Tous les diagrammes ne sont pas hiérarchiques de cette manière. Le diagramme suivant par exemple, ne peut être vu comme une imbrication de losanges.

n

k l

i j

0

Néanmoins, supposons qu’un diagramme de cette forme est inclus dans un autre, connecté par un arc entrant sur la borne inférieure et un arc sortant sur la borne supérieure. Il est alors possible comme avec les losanges de commencer par clore cette partie du diagramme avant de clore le reste.

Ceci nous donne une idée générale d’optimisation à réaliser. On identifie la hiérarchie dans un diagramme, et on clôt les uns après les autres les différents niveaux de la hiérarchie. Pour construire cette hiérarchie, il faut identifier les différents intervalles. Ces intervalles seront définis par les paires de sommets constituant leur borne inférieure et supérieure et sont telles qu’aucun chemin ne sort ou n’entre dans la composante sans passer par ces bornes. De cette manière, on réduit significativement le nombre de transformations élémentaires à réaliser.