• Aucun résultat trouvé

4.2 La composition dynamique et extensibilité

4.2.4 La résolution

L’objectif de cette phase est d’effectuer une réécriture du graphe où les interférences ont été mar- quées. Les règles de réécriture nécessaire pour la résolution des problèmes sont déjà fournies pour les connecteurs de base. Toutefois nous avons évoqué précédemment que les designer pourront utiliser des connecteurs en dehors de cette liste prédéfinies sous condition qu’ils fournissent la description comportementale des nouveaux connecteurs. Dans la section suivante, nous détaillons tout d’abord le mécanisme de résolution classique (défini statiquement) et ensuite nous présentons le cas d’extension du mécanisme de résolution pour considérer de nouveaux connecteurs.

4.2.4.1 Résolution classique par réutilisation des règles prédéfinies

L’objectif de cette étape est de gérer les interférences se produisant lors de la composition de plusieurs graphes représentants des instances des entités d’adaptation. Cette résolution est conforme à la logique de résolution qui a été définie statiquement. C’est à partir des nœuds ⊗ (ajoutés durant l’étape de détection) que le mécanisme de gestion des interférences construira sa solution. Ces nœuds ⊗ seront remplacer par des nœuds de type W hiteBoxEntity. Notre mécanisme mettra en ouvre la logique qui a été définie par le Super-Designer pendant la phase de conception. Donc le comportement mis en place par cette résolution va être consistant avec la logique définie en amont. Basiquement, l’algorithme pour résoudre ces interférences parcourt l’ensemble de tous les nœuds ⊗ dans l’objectif de faire tourner sur chacun d’eux le moteur de transformation de graphe. Ce processus peut être décrit plus formellement par l’algorithme 3.

Algorithm 3 InterferenceResolution (Graph G) LFus est la liste de nœud de type ⊗

k: le nombre d’élément dans la liste LFus for m = 0 to k do

if OU TArc(⊗m) = 2 then Node ni= sucesseurs(⊗m) Node nj= sucesseurs(⊗m) Rewriting(ni, nj)

else

if INArc(⊗m) = 2 then

Node ni= predecesseurs(⊗m) Node nj= predecesseurs (⊗m) Rewriting(ni, nj)

end if end if end for

La fonction Rewriting prend comme entrée les deux nœuds successeurs au nœud ⊗ (respective- ment les deux nœuds prédécesseurs) et propose de les connecter autrement à travers l’application d’une règle de réécriture de graphe. Ceci est rendu possible grâce à la connaissance de la sémantique des connecteurs. En effet, si nous avons plusieurs connecteurs à la sortie d’un nœud (respectivement à l’entrée d’un nœud), le mécanisme de réécriture produira un connecteur final à partir duquel nous retrouvons tous les comportements spécifiés par l’ensemble de connecteurs de départ (avant la résolu- tion). Cet objectif a été fixé par le Super designer à travers les règles fournies. Ces dernières permettent de réécrire toutes les combinaisons possibles des connecteurs deux à deux. L’algorithme 4 décrit le déroulement de la fonction Rewriting.

Algorithm 4 Rewtriting (Node ni, Node nj) Rule R=SelectRule(type(ni),type(nj)) if R is NU LL then De f aultSolution() else Apply(R) end if

Le choix de la règle de réécriture (SelectRule) à appliquer pour résoudre une interférence se base sur le type des nœuds passés en entrée. À chaque couple de connecteurs est associé au moins une règle de réécriture. Plusieurs règles peuvent être proposées décrivant différentes configurations de ces deux connecteurs (par exemple les connecteurs partagent un nœud, etc.). La règle sélectionnée sera par la suite appliquée par le moteur de transformation de graphe. L’application d’une règle de réécriture pourra résoudre le problème définitivement ou bien partiellement. Une résolution partielle propose la réécriture de deux connecteurs en propageant le nœud ⊗ vers les arcs sortant de ces nœuds. Cela ajoutera de nouveaux nœuds ⊗ et nécessitera par la suite l’application d’autres règles de réécriture (par exemple la règle de réécriture de deux IF illustrée par la figure A.4 dans Annexe A). Dans le cas où le Super Désigner n’a pas prévu une règle de réécriture pour résoudre le problème, une solution par défaut va être appliquée (De f aultSolution). C’est le cas par exemple lorsque un port possède deux liaisons n’utilisant pas de connecteurs et sont en conflits ; la solution par défaut consiste alors à ajouter un connecteur PAR entre les deux liaisons (règle A.1 dans Annexe A). Ceci garantit également la propriété de symétrie de l’opération de réécriture (la réécriture de chacun de ces connecteurs a été définie comme symétrique). L’application d’une règle de réécriture selon l’approche que nous avons choisit (SPO) nécessite la recherche du sous-graphe L dans GT. La complexité de cette opération sera alors fortement liée à la complexité du moteur de transformation choisi par le Super Designer pendant la conception.

Une fois que les interférences de type 1 − n ont été résolues, nous enchaînons par la résolution du deuxième type d’inférence (type n − 1). Il s’agit des problèmes d’accès concurrents à un port d’une en- tité logicielle. La solution que nous avons proposée précédemment consiste à réécrire ces connecteurs pour ne garder qu’un seul appel à ce port. Chaque connecteur simple de type n − 1 implémente une logique de déclenchement qui sera utilisée pour le calcul de la logique de déclenchement du connec- teur complexe. Le principe de réécriture de graphe va être également utilisé dans cette résolution mais cette fois ci pour déterminer quelle logique de déclenchement doit être mise en ouvre (c’est à dire comment réécrire les connecteurs de base pour avoir la logique de déclenchement souhaitée).

FIGURE4.13 – Un exemple de résolution des interférences de type n − 1

La figure 4.13.a illustre un exemple d’interférence de type n − 1. Dans cet exemple, il y a 4 arcs en- trants vers le port Energy_Warning. Il s’agit d’une interférence d’ordre 3. Chaque instance des entités d’adaptation exprime une logique de déclenchement de cette alarme. La réécriture de ces connecteurs produira le graphe (figure 4.13.c) qui définit la logique de déclenchement de ce port où il y avait un problème d’accès concurrent.

4.2.4.2 Résolution avec une modélisation comportementale des nouveaux connecteurs

Nos règles de réécriture expriment une nouvelle manière d’interconnecter les connecteurs dans le cas d’une interférence. L’utilisation d’un connecteur non connu a priori active un autre processus de résolution qui sera décrit dans cette section. Nous détaillons toutes les phases qui mènent à la génération d’une règle de réécriture pour tout nouveau connecteur et par conséquent l’extension du mécanisme de composition pour supporter ultérieurement l’utilisation de ce connecteur. Une fois que la règle de réécriture a été générée, le processus de résolution reste le même que celui qui a été détaillé dans la section 4.2.4.1.

L’algorithme 5 met en œuvre le processus d’extension du mécanisme de résolution des in- terférences qui a été décrit dans la section 3.3.3. La première opération est la composition des automates dont l’un parmi eux correspond à un nouveau connecteur. La fonction AutomComposition implémente une stratégie donnée de composition (synchrone, parallèle, etc.). L’automate obtenu sera l’entrée de la fonction Trans f orm qui produira l’équation régissant le comportement de cet automate sous forme de combinaisons de connecteurs de base. Nous avons vu qu’une règle de

Algorithm 5 CompositionExtension (Node NewCi, Node ni) FusAutom=AutomComposition(autom(NewCi), autom(nj)) Eq= Trans f orm(FusAutom)

RHS= EquationToGraph(Eq)

Rule= createRule(NewCi, Node ni,RHS) addRule(Rule)

réécriture est définie par (L, R). Le sous-graphe L correspond à l’interférence qui a été identifiée entre les connecteurs NewCi et ni. Pour avoir une règles valide, il faudra compléter la partie R de la règle. Pour cela, la fonction EquationToGraph a comme paramètre l’équation Eq qui servira essentiellement à la génération du sous-graphe R. À ce stade, nous avons obtenu les deux parties de la règle qui sera créée par la fonction createRule. La règle obtenue Rule sera ajoutée à la base de règles du mécanisme qui sera par la suite capable de résoudre ce nouveau cas d’interférence. Durant la phase de la conception statique du mécanisme de composition, nous avons évoqué que les règles de réécriture fournies par le Super-Designer devront être validées par rapport à des propriétés. L’algorithme que nous venons de détailler n’inclut pas explicitement cette phase de vé- rification. En effet, la fonction AutomComposition englobe cette phase de validation en faisant du model-checking [JGP00]. Cette approche nécessite un modèle du système à partir duquel la satis- faction des formules est vérifiée (ces formules représentent des propriétés requises). La machine de Mealy synchrone est un des modèles pertinent pour appliquer les techniques de model-checking. Ces formules peuvent être décrites à l’aide d’une logique formelle interprétées par des automates tel que CTL [JGP00]. Il s’agit d’un langage formel basé sur la logique du premier ordre où les assertions liées aux comportements attendus sont facilement exprimés. Nous nous intéressons particulièrement à la propriété de symétrie qui a été détaillée durant la phase de conception statique du mécanisme de composition. La composition d’automates parallèles ou synchronisés garantit par définition cette propriété ; il n’est donc pas nécessaire de la prouver de nouveau pour la règle de réécriture obtenue.

Jusqu’à présent nous avons détaillé toutes les opérations au niveau de la représentation abstraite qu’est le graphe. Ceci est rendu possible grâce à deux transformations : de l’application en cours d’exécution vers le graphe et du graphe vers l’application à l’exécution.