• Aucun résultat trouvé

Sémantique de fUML : un modèle d’exécution

sémantique fUML pour la vérification de procédés

3.1 Foundational UML (fUML)

3.1.3 Sémantique de fUML : un modèle d’exécution

Le modèle d’exécution de fUML est lui-même un modèle, écrit en fUML, qui spécifie comment les modèles fUML sont exécutés. Du fait que cette forme de spécification conduit à de gros diagrammes difficiles a lire, du pseudo-code Java est utilisé pour définir le modèle d’exécution (au lieu de diagramme d’activités fUML). Le modèle d’exécution définit : la sémantique d’exécution de tous les éléments de modélisation de fUML, un moteur d’exécution, et son environnement. La structure des packages pour définir la sémantique des éléments de modélisation est la même

Package UML Inclus dans fUML ? Modélisation de la structure Classes X Components Composite Structures Deployments Modélisation du comportement Actions X Activities X Common Behaviors X Interactions State Machines Use Cases

Table 3.1 – Paquage UML inclus dans le sous-ensemble fUML

que la structure de la syntaxe abstraite (elle inclut les mêmes packages et sous-packages). Additionnellement, le modèle d’exécution inclut un package appellé Loci, afin de représenter le moteur d’exécution ainsi que son environnement. Ainsi, le modèle d’exécution incorpore les packages suivants :

Loci. Ce package spécifie le moteur d’exécution et son environnement. Classes. Ce package définit la sémantique structurelle de fUML.

CommonBehaviors, Activities, Actions. Ces packages définissent la sémantique comportementale de fUML.

Ces définitions permettent donc de définir une machine virtuelle basique pour l’exécution de modèles fUML. Par modèle fUML, nous entendons un modèle UML comprenant seulement des éléments de modélisation inclus dans le sous-ensemble sélectionné par fUML.

Moteur d’exécution et environnement d’exécution

Comme le montre la figure 3.2, le package Loci contient les classes Locus, Executor, et ExecutionFactory représentant un moteur d’exécution pour fUML. L’Executor fournit l’abs-traction de base pour exécuter un modèle fUML. Il fournit l’interface basique pour évaluer des valeurs et exécuter des comportements (ex. une activité) de manière synchrone ou asynchrone. Chacune des exécutions prend place dans un Locus spécifique. Un Locus peut être vu comme une abstraction d’un ordinateur physique ou virtuelle, capable d’exécuter des modèles fUML. Chacun des objets et liens créés pendant ou avant l’exécution lui sont associés.

Le modèle d’exécution est basé sur le visitor pattern [96] pour instancier la syntaxe. En utilisant ce patron, chacune des méta classes abstraites a un visiteur correspondant dans le modèle d’exécution (nommé *Execution et *Activation, ex. CallBehaviorAction ‘æ CallBehaviorActionActivation). Toutes les classes visiteurs dans le modèle d’exécution sont descendantes, directement ou indirectement de la classe racine SemanticVisitor. L’Executor utilise ces visiteurs afin d’instancier l’équivalent comportemental de l’élément. Afin d’instancier l’élément du visiteur, l’Executor utilise une instance de la classe ExecutionFactory fournie à l’exécution par le Locus. L’ExecutionFactory maintient l’ensemble des comportements primitifs qui peuvent être appelés. Dans fUML, ces comportements primitifs sont définis comme des instances de OpaqueBehavior. Pour chacune des instances d’OpaqueBehavior représentant un

comportement primitif, l’ExecutionFactory possède une instance OpaqueBehaviorExecution équivalente. L’ExecutionFactory contient aussi les instances des SemanticStrategy afin de gérer les points de variations de sémantique de UML (ex. ordonnancement des évènements LIFO ou FIFO, etc).

Additionnellement, le modèle d’exécution contient un package appellé Library qui contient la Foundational Model Library, une libraire d’éléments définie par l’utilisateur qui peut être référencée dans un modèle fUML. Elle définit les types primitifs tels que booleen, integer, string,

unlimited natural et les comportements primitifs sur ceux-ci tels que OR, XOR, AND, NOT sur

le type booleen.

Afin de configurer l’environnement d’exécution, il est nécessaire d’instancier cet ensemble d’objets à l’intérieur du modèle d’exécution pour fournir l’environnement initial d’exécution. Sémantique opérationnelle de fUML

La sémantique adoptée par le modèle d’exécution de fUML est basée sur le principe d’offre et de consommation de jetons de type contrôles ou objets entre les différents constituants de l’activité (les noeuds et les arcs tels que présentés dans la section2.1.4), similairement aux réseaux de Petri colorés [131].

Afin d’exécuter un modèle fUML, le moteur d’exécution suit la procédure suivante :

1. Provision des entrées de l’activité (ActivityParameterNode). Avant que l’exécution de l’activité démarre, les valeurs des paramètres d’entrées de l’activité sont fournies.

2. Identification des noeuds activables. Dans un second temps, les noeuds activables sont identifiés par le moteur d’exécution : les noeuds initiaux (InitialNode), les paramètres d’entrées de l’activité (ActivityParameterNode), et tous les noeuds (ActivityNode) qui n’ont aucun arc entrant.

3. Envoi d’un jeton de contrôle aux noeuds activables. Une fois les noeuds activables identifiés, des jetons de contrôle leur sont envoyés.

4. Exécution des noeuds de l’activité.

(a) Vérification si le noeud est prêt à être exécuté. Quand un noeud de l’activité reçoit un jeton, le moteur d’exécution détermine si tous les prérequis sont remplis afin de démarrer son exécution. Plus précisément, le moteur vérifie, par exemple, si un jeton de contrôle est disponible sur tous ses arcs entrants, et dans le cas d’une action, si des jetons de données sont disponibles sur ses pins d’entrées.

(b) Consommation des jetons. Si un noeud est prêt à être exécuté, c’est-à-dire, si tous les jetons de contrôles et de données sont disponibles, le noeud consomme ces jetons qui lui sont offerts. Ainsi, les jetons sont retirés des arcs entrants et un jeton est ajouté dans le noeud.

(c) Execution du comportement du noeud. Après que les jetons soient consommés par le noeud, le comportement du noeud est exécuté. Le comportement est différent selon le type de noeud qui s’exécute. Par exemple, un noeud de décision (DecisionNode) choisira un chemin parmi ses arcs sortants, alors qu’une action pourrait produire des jetons de données et les placer sur ses pins de sorties.

(d) Envoi des jetons aux noeuds suivants. Quand le comportement du noeud a terminé de s’exécuter, un jeton de contrôle est inséré sur chacun des arcs sortants, et, dans le cas d’une action avec des pins, des jetons de données sont produits sur les arcs de sortie de ses pins.

(e) Exécution des autres noeuds de l’activité. Du fait qu’après l’exécution d’un noeud, des jetons ont été propagés sur ses arcs sortants, de nouveaux noeuds pourraient être

Figure 3.2 – Loci package du modèle d’exécution de fUML [189]

prêt à s’exécuter. Ainsi, les étapes “a” à “d” sont effectuées pour les noeuds ayant reçu des jetons.

5. Provision des sorties de l’activité. Quand aucun autre noeud ne peut être exécuté, ou qu’un noeud ActivityFinalNode a été exécuté, l’exécution de l’activité est terminée et les valeurs présentes sur les noeuds de sorties de l’activité sont renvoyées.

Un des points importants de la sémantique d’exécution de fUML et qu’elle possède un concept implicite d’exécution concurrente de threads. Par défaut, les noeuds de l’activité sont ou peuvent être exécutés de façon concurrente. Ainsi, les jetons peuvent être produits et consommés de façon parallèle à travers les arcs d’entrées et de sorties des noeuds. Cependant, la spécification fUML

Figure 3.3 – Interactions entre les éléments du diagramme d’activité

ne contraint pas à ce que les exécutions soit réellement parallèles, de manière physique. En effet, elle ne spécifie pas précisément comment implémenter le parallélisme. N’importe quelle exécution séquentiellement ordonnée ou partiellement parallèle est valide, à partir du moment que les contraintes du modèle fUML exécuté, en terme de création, terminaison et synchronisation soient respectées. L’implémentation de référence de fUML développé par la “ModelDriven Community” [242] utilise seulement un seul thread pour exécuter les modèles. En essence, cette implémentation ne peut pas exécuter deux noeuds réellement en même temps, mais produit toujours des traces d’exécution légale envers la spécification et le modèle exécuté.