Vers une prise en compte des contraintes en UML grâce à Z S. Dupuy LSR-IMAG, BP 72, 38402 SAINT MARTIN D’HERES CEDEX [email protected], Tél : 04 76 82 72 57, Fax : 04 76 82 72 87 [Catégorie Jeune Chercheur] Résumé : La prise en compte des relations statiques et dynamiques entre les acteurs et les objets du système est nécessaire à une spécification correcte, mais il ne faut pas négliger celle des contraintes de domaine ou de gestion qui constituent aussi des éléments de modélisation importants. Or les ateliers actuels supportent essentiellement la modélisation des relations et assez faiblement les contraintes. Il serait pourtant bénéfique de disposer d’outils permettant de les exprimer et de les valider. Pour permettre la validation des contraintes, nous proposons d’exploiter le potentiel de raisonnement des langages formels. Notre approche est basée sur l'expression des diagrammes UML et des contraintes dans un langage formel. Nous présentons ici la traduction d’un sous-ensemble du diagrammes de classes d’UML et de ses contraintes, écrites en OCL, vers Z. Les spécifications formelles ainsi obtenues peuvent être utilisées pour prouver la cohérence de l’ensemble de contraintes. Mais la prise en compte des contraintes ne peut se faire efficacement que si des outils la supportent. Pour la faciliter, nous proposons un outil intégrant l’expression des contraintes et automatisant la génération des spécifications formelles Z. L’idée centrale de cet outil est que tout le travail de modélisation doit être fait dans l’environnement UML. L’outil est basé sur un environnement industriel de modélisation UML complété par des formulaires contenant les contraintes. Mots-clé : UML, contraintes, OCL, Z, support outil Abstract : The static and dynamic relationships between the system actors and objects, but also the domain and business constraints must be taken into consideration in order to produce a consistent specification. Actual tools mainly support relationships and forget constraints. It is nevertheless necessary to have tools which enable to express and to validate them. In order to enable the validation of constraints, we propose to exploit the formal language power of reasoning. Our approach is based on the expression of the UML diagram and of its constraints in a formal language. We present here the translation of a subset of the UML class diagram and of its constraints into Z. The formal specifications obtained can be exploited to prove the consistency of the constraint set. But constraints can be taken into consideration efficiently only if tools support them. To facilitate this, we propose a tool which integrates constraints and automates the generation of Z formal specifications. The main point of this tool is that the whole modelling work should be done in the UML environment. The formal specifications are seen only when it is necessary. The tool could be based on an industrial UML modelling environment completed by forms containing the constraints. Key word : UML, constraints, OCL, Z, tool support 1 Introduction En modélisation des systèmes d’information (SI), il n’est plus nécessaire aujourd’hui d’insister sur l’importance de la prise en compte des relations statiques et dynamiques entre les acteurs et les objets du système, mais aussi de celle des contraintes de domaine ou de gestion nécessaires à une spécification correcte. Les ateliers de modélisation actuels insistent beaucoup sur l’apport de l’outil comme moyen d’évaluer l’impact de l’évolution des systèmes afin de conserver une spécification conforme aux applications développées. Cependant ils supportent essentiellement la modélisation des relations et assez faiblement l’expression des contraintes et la validation des cohérences que celles-ci sont sensées permettre. Nous étudions ici la faisabilité d’un outil intégrant cette prise en compte des contraintes dans un couplage fort à un environnement de spécification industriel. Nous proposons aussi un guidage afin que la validation des contraintes et de la spécification du système puisse être mieux maîtrisée. Nous avons fait le choix d’étudier nos propositions sur la notation UML [RATI97] reconnue industriellement comme une évolution « standardisée » des méthodes d’analyse orientées objet. Nous proposons qu’une modélisation UML et ses contraintes soient exprimées et couplées à des spécifications formelles. Cette démarche est limitée à ce jour à la modélisation des aspects statiques en vue d’aider à la validation de base de données (BD) traduisant la modélisation du SI. L’outil Rational Rose sur lequel nous implantons cette démarche permet effectivement la génération vers un certain nombre de systèmes de gestion de BD dont Oracle 8. Comme les précédentes notations (OMT, OOSE, OOA…), UML ne permet pas d'exprimer toutes les contraintes (comme par exemple, des clés sur les classes des objets). Plusieurs propositions ont donc été faites pour permettre d'intégrer l'expression de contraintes de domaine à UML. La première [OU98] propose d'étendre le méta-modèle d'UML pour ajouter à chaque classe une partie textuelle exprimant des contraintes. La deuxième prévoit d'ajouter en commentaires aux diagrammes, des contraintes exprimées dans un formalisme proche de la logique du premier ordre. Avec la notation UML, est apparu un langage d'expression de contraintes OCL (Object Constraints Language [WARM98]). Ce langage doit permettre d'exprimer les contraintes de façon précise et non ambiguë. Contrairement à la première proposition, cette approche a l’avantage de ne pas surcharger les notations graphiques. Mais OCL offre aujourd’hui une sémantique pauvre et ne possède pas de support outil permettant d’exploiter les contraintes ; en conséquence les contraintes exprimées peuvent être mutuellement incohérentes ou incohérentes avec le diagramme qu’elles annotent. De plus, il n’existe pas de guide méthodologique pour savoir où exprimer une contrainte afin de la rendre exploitable. Or pour bénéficier pleinement de l’enrichissement apporté par les contraintes en détectant d’éventuelles erreurs sans attendre l'implantation dans une base de données, il faut créer une ingénierie qui les intègre réellement. Nous proposons d’exploiter ici le potentiel de raisonnement des langages formels. Notre approche est basée sur l'expression concomitante des diagrammes UML et des contraintes dans un langage formel. Les concepts d’UML traduits en squelettes de spécifications formelles sont complétés par les contraintes. Dans cet article, la traduction d'un sous-ensemble du diagramme de classes UML en Z ([SPIV95]) est présentée. Elle aide à localiser les limites d’expression du diagramme de classes comme les « trous » des squelettes Z correspondant aux aspects qu’UML n’exprime pas. L’identification de ces « trous » permet de classer les contraintes. Cette classification est utilisée pour créer un guide méthodologique pour l’expression des contraintes sans connaissance des aspects formels qui ont conduit à sa définition. Notre but n’est donc pas de proposer une n-ième taxonomie de contraintes, mais de combiner des propriétés et des approches complémentaires : UML pour son aspect structurel et ses qualités en terme de représentation graphique, Z dans le cadre formel et les contraintes statiques selon les approches BD. Ces trois éléments combinés sont pertinents pour obtenir des SI plus cohérents et plus rigoureux. Mais la prise en compte de spécifications ou de contraintes ne peut se faire efficacement que si des outils la supportent afin de permettre les adaptations et ré-évaluations qu’imposent les évolutions de SI. Pour cela, nous proposons l’outil, RoZ, qui étend l’environnement Rational Rose en offrant la possibilité d’annoter les diagrammes de classes UML avec des contraintes. RoZ génère automatiquement les spécifications Z correspondant à un diagramme et à ses contraintes afin de vérifier leur cohérence en utilisant les outils de Z. Ainsi l’impact des évolutions sur la validation des contraintes est assuré grâce à une automatisation du processus de génération de spécifications formelles et de vérification. Nous décrivons au paragraphe 2 l'étude de cas qui illustre notre approche. Par facilité de compréhension, celle-ci est davantage orientée système automatique, mais permet de montrer l’impact des deux spécifications. Nous en proposons une modélisation en UML pour la partie statique. Le paragraphe 3 présente, sur cette étude de cas, les règles de traduction du sousensemble du diagramme de classes UML en Z. Il montre comment les contraintes du diagramme sont intégrées aux squelettes de spécifications Z. Dans le paragraphe 4, nous décrivons l'outil RoZ qui supporte à cette approche. 2 L'étude de cas du contrôleur d'accès 2.1 Description en langue naturelle Notre étude de cas concerne un contrôleur d'accès à des bâtiments. Il s’agit avant tout d’un exemple didactique illustrant chaque type de contraintes. Une description complète est donnée dans [LEDR97]. Nous ne présentons ici qu'un résumé de ce document. Un contrôleur d'accès doit être développé pour une entreprise. Chaque employé de l'entreprise a accès à un ensemble de bâtiments de l'entreprise. Un accès, pour un employé donné et pour un bâtiment donné, est autorisé sur la base de l'appartenance à un groupe. Chaque employé est membre d'un seul groupe et un groupe peut accéder à un ensemble restreint de bâtiments. Pour s'assurer que la politique d'accès décrite ci-dessus est respectée, chaque employé a une carte magnétique unique et toutes les portes des bâtiments sont équipées de lecteurs de cartes. A l'entrée ou à la sortie d'un bâtiment, l'employé doit insérer sa carte dans le lecteur. Si l'accès est autorisé, la porte est débloquée et l'accès est enregistré dans une base de données. 2.2 Spécification du contrôleur d'accès en UML Nous ne nous intéressons qu'à l'aspect statique du contrôleur d'accès. Nous utilisons donc un diagramme de classes UML dont nous ne présentons ici qu’une version simplifiée (figure 1). Quatre classes ont été identifiées : • les employés (les personnes) Une personne est caractérisée par son nom, son prénom, ses numéros de téléphone et le numéro unique de sa carte d’accès. • les groupes Un groupe a un nom et un code. • les bâtiments Un bâtiment a une adresse physique et un code. • les accès La classe « ACCES » qui sert à enregistrer les accès de chaque employé aux bâtiments, devrait en fait être un classe associative entre les classes « PERSONNE » et « BATIMENT ». Mais nous simplifions le diagramme en faisant de « ACCES » une classe qui est en relation avec « PERSONNE » et « BATIMENT ». Les attributs d’« ACCES » correspondent aux instants d’entrée et de sortie d’une personne dans un bâtiment. En plus de la relation représentée par « ACCES », il existe deux autres relations. La première, « Appartenir » entre « PERSONNE » et « GROUPE », est une association 1-n (une personne appartient à un seul groupe et un groupe a pour membres plusieurs personnes). La deuxième, « Acceder » entre « GROUPE » et « BATIMENT », est n-n : un groupe peut accéder à plusieurs bâtiments et un bâtiment peut être accessible à plusieurs groupes. BATIMENT 0..* Acceder 1 batimentcode adresse AccesBatiment 1..* 0..* GROUPE ACCES groupecode groupenom dateentree datesortie 1 Les personnes d'un même groupe ont le même préfixe téléphonique. 0..* PERSONNE Appartenir 0..* nom prenom tel numcarte AccesPersonne 1 Figure 1 : Contrôleur d’accès - Diagramme de classes A ce diagramme de classes, de nombreuses contraintes peuvent être ajoutées. Dans cet article, nous nous intéresserons seulement aux contraintes suivantes : 1. les clés des classes sont : le numéro de carte pour « PERSONNE », le code ou le nom du groupe pour « GROUPE », le code du bâtiment pour « BATIMENT » et la date d’entrée et la personne pour « ACCES » ; 2. pour toute personne, on doit connaître au moins un numéro de téléphone ; 3. pour tout accès, on doit connaître la date d’entrée ; 4. quand elle est définie, la date de sortie d’un accès est postérieure à la date d’entrée ; 5. seule la date de sortie du dernier accès peut être inconnue ; 6. les personnes d'un même groupe ont le même préfixe téléphonique ; 7. un accès peut être enregistré dans la base de données seulement si la personne est autorisée à entrer dans le bâtiment lié à l'accès. En UML, ces contraintes peuvent être écrites en notes du diagramme de classes comme nous le montrons pour la contrainte 6 (Figure 1). Quelle que soit la notation pour les exprimer (langue naturelle, OCL …), cette solution surcharge le diagramme. De plus, il n'existe pas de guide méthodologique pour savoir où une contrainte doit être ajoutée. Par exemple, on ne sait pas où écrire la dernière contrainte (7) car elle porte sur tout le diagramme. C'est pourquoi nous proposons un cadre permettant de considérer les contraintes de façon plus structurée. Il est basé sur l'expression du diagramme de classes UML et de ses contraintes en une spécification formelle Z. 3 3.1 Passage à une spécification formelle en Z Démarche L'approche proposée (figure 2) utilise la complémentarité des diagrammes UML et des contraintes annotant ces diagrammes pour produire une spécification formelle : 1. Dans un premier temps, un diagramme de classes UML est décrit dans un éditeur de diagrammes et complété par des annotations qui posent des contraintes sur les données. Les annotations doivent être écrites dans un formalisme utilisant la logique du premier ordre et la théorie des ensembles pour être exprimables en Z. En fait, elles peuvent être écrites en OCL. 2. Ce diagramme de classes est le point de départ d'un processus de traduction qui produit des squelettes de spécifications formelles Z. La traduction garantit l'équivalence sémantique entre le diagramme UML et la spécification formelle. Cette étape a déjà été beaucoup étudiée. Actuellement la plupart des travaux s’intéressent à intégrer les modèles orientés objet et les langages formels. Par exemple, des schémas de traduction ont été proposés pour la traduction de modèles objet en VDM ([LALE95]) , en B ([FACO96, LANO96]) ou en Z ([FRAN97, SHRO97]). Nous avons pour notre part déjà étudié l’intégration de spécifications formelles exprimées en Object-Z dans des spécifications OMT ([DUPU98]). Mais nous sommes revenus à une spécification en Z ([DUPU00]) afin de pouvoir intégrer des outils de preuve qui ne sont pas disponibles en Object-Z. 3. Les squelettes de spécifications formelles sont complétés par les contraintes ajoutées au diagramme de classes. Il existe de nombreuses classifications des contraintes d'intégrité qui distinguent généralement les contraintes statiques des contraintes dynamiques. Dans ce travail, nous ne nous intéressons qu'aux contraintes statiques. Des divers classifications ([AMGH94,DATE95,DELO82]), nous retiendrons qu'il existe trois types de contraintes d'intégrité statiques: les conraintes intra-objet portant sur un ou plusieurs attributs d'un objet ; les contraintes intra-classe qui portent sur plusieurs objets d’une classe et les contraintes inter-classes portant sur plusieurs classes de la base de données. Nous pouvons prendre en compte ces différents types de contraintes statiques, mais nous adoptons une classification différente afin de pouvoir guider l'écriture des contraintes dans une démarche de modélisation. 4. La spécification formelle est utilisée pour vérifier la cohérence des contraintes avec le diagramme grâce à un prouveur Z. On peut, par exemple, vérifier que les opérations ne violent pas les contraintes en calculant leur précondition ([LEDR98]). 5. Grâce au processus de traduction, les raisonnements effectués sur la spécification formelle peuvent être reportés dans le diagramme de classes UML et ses annotations. Problème initial 1 1 Contraintes en OCL ou Z Diagramme de classes UML 2 Squelette de spécifications formelles Z 3 Spécifications formelles Z 5 4 5 Vérifications Figure 2 : Démarche Cet article présente les trois premières étapes de cette approche et un outil les supportant. Il insiste plus particulièrement sur l'intégration des diverses contraintes dans les squelettes de spécification Z. Les règles de traduction du diagramme de classes d'UML vers Z ont été précisément décrites dans [DUPU00] et les deux dernières étapes de l'approche sont présentées dans [LEDR98]. 3.2 Spécification du contrôleur d'accès en Z Le passage du diagramme de classes d'UML à des spécifications formelles Z s'effectue suivant des règles de traduction. Nous ne présentons dans cet article que sous forme d'exemples celles nécessaires à l'étude de cas du contrôleur d'accès; c'est-à-dire celles concernant les classes, les associations et la vue globale de la base de données. Une description plus précise de ces règles est donnée en annexe. La traduction produit des squelettes de spécifications Z; elle met en relief les " trous" des spécifications Z résultant de cette traduction qui correspondent aux contraintes non exprimées en UML. Comme OCL tire ses origines de Z, il semble possible d'écrire les contraintes en OCL, puis de les reformuler en Z pour les intégrer aux squelettes de spécifications. Pour chaque type de contraintes, nous montrons comment une contrainte OCL peut être écrite en Z. Par soucis de concision, les autres contraintes sont seulement exprimées en Z, mais leur expression correspondante pourrait être facilement produite. 3.2.1 Classe Traduction en Z Une classe en UML joue deux rôles : celui de fabrique d'objets (générateur d'instances) et celui d'entrepôt d'objets. Elle peut donc être définie en intension (description des propriétés communes aux instances possibles) ou en extension (ensemble de toutes les instances existantes) [HALL94]. Toute classe donne donc lieu en Z à deux schémas. Un schéma est une structure de données composée de deux parties : les déclarations qui constituent le lexique des variables locales et les prédicats exprimant les contraintes sur ces variables. Pour la traduction d'une classe, le premier schéma, représentant l'intension de la classe, contient la déclaration des attributs. Il peut être considéré comme un enregistrement en Pascal. Contrairement à d'autres travaux ([FACO96, SHRO97, NGUY98]), nous avons choisi de ne pas ajouter de variable pour représenter l'identifiant d'un objet car cette notion n'est pas explicite dans une modélisation UML. Par exemple, le schéma d'intension de la classe " PERSONNE" a pour variables nom, prénom, tel et numcarte : L'extension de la classe est représentée par un autre schéma Z ayant une seule variable qui décrit l'ensemble des instances existantes. Pour la classe " PERSONNE" , on définit donc un schéma PersonneExt qui a une seule variable Personne déclarée comme un ensemble fini d'éléments ( ) de type PERSONNE. Le premier schéma doit être complété par la description des types des attributs. Les attributs « nom » et « prenom » sont de type NOM. NOM est déclaré comme un type donné c'est-à-dire qu'il correspond à une définition abstraite du type qui laisse une complète liberté pour son implantation. Comme NOM, TEL est un type donné. Le numéro de carte est un intervalle d'entiers. [NOM,TEL] NUMCARTE == 0..99999999 Le schéma PERSONNE peut maintenant être complété par les types des attributs. Mais comme une personne peut avoir plusieurs numéros de téléphone, l’attribut « tel » est multi-valué. Cela est décrit en Z par un ensemble fini d'éléments ( ) de type TEL : On peut exprimer de manière identique les autres classes « GROUPE » , « BATIMENT » et « ACCES ». D’où, pour « ACCES », la spécification Z suivante : [DATE] On peut noter que le schéma ACCES a trois attributs : date d'entrée, date de sortie qui apparaissent dans le diagramme UML et personne qui est un élément de la clé de « ACCES ». Contraintes sur les classes Les contraintes sur une classe peuvent concerner un seul objet ou les liens mutuels entre plusieurs objets. Les contraintes sur un objet sont une restriction des valeurs d'un ou plusieurs attributs. Dans le contrôleur d'accès, les contraintes 2, 3 et 4 sont respectivement des contraintes sur l'ensemble des numéros de téléphone d'une personne, les dates d'entrée et de sortie correspondant à un accès. Les restrictions sur les liens mutuels entre les objets existants d'une classe sont des contraintes sur l'extension de la classe. Pour illustrer ce type de contraintes, le contrôleur d'accès a la contrainte de clé (contrainte 1) et la définition de la date de sortie du dernier accès d'une personne (contrainte 5). Contraintes sur l'intension d'une classe Les contraintes sur l'intension d'une classe sont divisées en deux catégories : celles concernant un seul attribut et celles portant sur plusieurs attributs. Un exemple de contraintes sur un attribut est la contrainte 2 spécifiant que toute personne doit avoir au moins un numéro de téléphone. Cette contrainte peut être écrite directement dans le diagramme UML en précisant la cardinalité de « numtel » (numtel [1..n]) ou en exprimant en OCL que l'ensemble " tel" ne peut pas être vide : PERSON tel → notEmpty(); Cette contrainte est ré-écrite en syntaxe Z (∅ dénote l'ensemble vide) pour compléter le squelette du schéma d'intension PERSONNE : tel ≠ ∅ De même, nous pouvons écrire des contraintes sur les attributs d’ « ACCES ». Certaines dates peuvent rester indéfinies. Pour pouvoir exprimer cela en Z, il faut distinguer un des éléments du type Date comme étant l'élément indéfini : dateindefinie : DATE On peut alors spécifier que la date d'entrée ne doit pas être indéfinie (contrainte 3). On restreint la valeur de dateentree par la contrainte suivante : dateentree ≠ dateindefinie Enfin, la contrainte 4 (quand elle est définie, la date de sortie est postérieure à la date d’entrée) porte sur plusieurs attributs de « ACCES ». Pour pouvoir l’exprimer, il faut compléter la définition du type DATE par une relation d'ordre total non-réflexive DateLt. Deux dates d1 et d2 peuvent être comparées si d1 et d2 ne sont pas égales : (d1,d2) ∈ DateLt signifie que d1 est avant d2. La contrainte 4 exprime que si la date de sortie d'un accès est définie, la date d'entrée correspondant à cet accès doit précéder la date de sortie : datesortie ≠ dateindefinie Þ (dateentree,datesortie) ∈ DateLt En ajoutant au schéma ACCES l'expression de ces contraintes, on obtient le schéma suivant : Contraintes sur l'extension de la classe Les contraintes sur l'extension d'une classe concernent les liens mutuels entre les objets d'une même classe. Ainsi deux objets d'une classe doivent avoir des valeurs distinctes pour leurs attributs clés. La contrainte de clé (contrainte 1) est un exemple typique des contraintes sur l'extension d'une classe. La clé de « ACCES » étant composée de la personne qui accède au bâtiment et de la date d'entrée de cet accès, on écrit en OCL que deux accès doivent avoir une personne ou une date d'entrée distincte : ACCES ForAll (a1,a2) | a1 <> a2 implies a1.personne <> a2.personne or a1.dateentree <> a2.dateentree); Cette contrainte peut facilement être traduite dans une expression Z équivalente : ∀a1,a2 : Acces | a1≠a2 • a1.personne ≠ a2.personne ∨ a1.dateentree ≠ a2.dateentree Mais les contraintes sur les objets d'une classe ne se limitent pas aux contraintes de clé. Par exemple, le fait que la date de sortie peut être inconnue seulement pour le dernier accès (contrainte 5), est une contrainte sur l'ensemble des accès liés à une personne. On spécifie que si a1 et a2 sont deux accès différents, s'ils correspondent à la même personne, et si a1 précède a2 alors la date de sortie de a1 ne peut pas être indéfinie : ∀a1,a2 : Acces | a1≠a2 ∧ a1.personne = a2.personne ∧ (a1.dateentree,a2.dateentree) ∈ DateLt • a1.datesortie ≠ dateindefinie Après ajout de ces contraintes, on obtient le schéma AccesExt suivant : 3.2.2 Association Traduction en Z Les associations relient deux ou plusieurs classes non nécessairement distinctes. Une association est caractérisée par son nom et les contraintes de cardinalités sur chacun de ses rôles. Nous choisissons de formaliser une association en spécifiant chacun de ses rôles. Par exemple, pour la relation « Appartenir » entre « PERSONNE » et « GROUPE » , on spécifie les deux rôles « GroupeDePersonne » et « PersonneDeGroupe » . On déclare chacun des rôles comme étant une fonction; puis on précise dans les prédicats, que la relation lie les objets existants des classes (définition des domaine et codomaine du premier rôle qui sert à spécifier les cardinalités minimales) ; enfin on exprime le lien qui existe entre les rôles. Dans notre exemple, le troisième prédicat exprime que l'on construit PersonneDeGroupe en inversant GroupeDePersonne : Contraintes sur les associations Les contraintes sur les associations correspondent à des restrictions sur des objets liés par une association. Dans notre étude de cas, une contrainte lie tous les membres d'un groupe : ils ont le même préfixe téléphonique (contrainte 6). En OCL, l'expression de cette contrainte nécessite d'ajouter au type " TEL" une opération " prefixe" qui renvoie le préfixe d'un numéro de téléphone donné. De plus, comme les associations ne sont pas des objets de première classe en OCL, il faut choisir la classe dans laquelle la contrainte est écrite. Ici la contrainte 6 est écrite dans le contexte de la classe " GROUPE" . L'expression OCL de cette contrainte signifie que si p1, p2 sont deux personnes d'un groupe, tous les numéros de téléphone t1 de p1 ont le même préfixe que les numéros de téléphone t2 de p2 : GROUPE self.GroupeDePersonne → forAll (p1,p2 | (forAll t1 : p1.tel , t2 : p2.tel | t1.prefixe = t2.prefixe) En Z, cette contrainte est écrite dans le schéma de l'association " Appartenir" . Il n'est pas donc nécessaire de choisir son contexte, précisé de facto par le schéma, mais il faut ajouter que les deux personnes ont le même groupe (GroupeDePersonne(p1) = GroupeDePersonne(p2)). Une autre différence est la définition de préfixe. En Z, un type PREFIXE représentant l'ensemble des préfixes téléphoniques et une fonction prefixe qui retourne le préfixe d'un numéro de téléphone donné sont introduits. La contrainte sur les numéros de téléphone s'écrit alors : ∀p1,p2 : Personne | GroupeDePersonne(p1) = GroupeDePersonne(p2) • ∀t1 : p1.tel • ∀t2 : p2.tel • prefixe(t1) = prefixe(t2) En ajoutant cette contrainte au schéma AppartenirRel, on obtient le schéma Z suivant : 3.2.3 Base de données Traduction en Z Une fois que toutes les classes et les associations ont été spécifiées, il faut les grouper pour obtenir une vue globale de la base de données modélisée. Pour cela, on utilise un nouveau schéma Z qui inclut tous les schémas des associations (se référant eux-mêmes aux extensions des classes). Pour notre étude de cas, on a le schéma CtlAccesBD suivant : Contraintes sur la base globale Ces contraintes mettent des restrictions mutuelles sur plusieurs associations. Le contrôleur d'accès a une seule contrainte (contrainte 7) portant sur plusieurs associations. Elle exprime qu'un accès peut être enregistré dans la base de données seulement si la personne est autorisée à entrer dans le bâtiment lié à l'accès. En OCL, on choisit le contexte de " ACCES" pour l'écrire. Son expression signifie que les bâtiments dans lesquels le groupe d'une personne, qui correspond à un accès donné, a le droit d'entrer, incluent, le bâtiment lié à cet accès. ACCES self.personne.GroupeDePersonne.BatimentDeGroupe → includes(self.BatimentDAcces) L'expression Z de cette contrainte complète le schéma de la base de données globale " CtlACcesBD" : 3.2.4 Bilan Nous avons présenté comment passer automatiquement des concepts de classe, d'association et de vue d'UML à Z. Les règles de traduction pour l'héritage et l'agrégation sont présentées en détail dans [DUPU00]. Les squelettes de schémas Z obtenus par traduction peuvent être complétés par des contraintes statiques. Le tableau ci-dessous résume les différents types de contraintes statiques présentées ci-dessus et comment elles sont intégrées aux spécifications Z. Il est actuellement étendu pour ajouter les contraintes concernant l'héritage. Contraintes sur Schéma Z Un attribut d'un objet Intension de la classe Plusieurs attributs d'un objet Intension de la classe Liens mutuels entre objets d'une même classe Extension de la classe Liens mutuels entre objets d'une même association Association Liens mutuels entre objets de différentes associations Vue ou diagramme Cette classification des contraintes est la base d'un guide méthodologique pour compléter un diagramme de classes avec des contraintes. Elle définit le contexte le mieux approprié à l’expression de celles-ci. Elle peut être utilisée pour l'écriture de contraintes, en langue naturelle ou en OCL, sans connaissance particulière des aspects formels qui ont conduit à sa définition. Dans cette section, nous avons montré que ces contraintes statiques peuvent être exprimées en OCL avant d'être reformulées pour leur intégration dans les squelettes Z. Pour chaque type de contraintes, nous avons montré comment l'expression Z correspondante pouvait être produite. 4 L'environnement RoZ La traduction d’un diagramme de classes et de ses contraintes en Z est implantée dans l’outil RoZ. RoZ est basé sur un environnement de modélisation UML complété par des formulaires contenant les contraintes. 4.1 Mise en œuvre L'outil RoZ est une extension de l'environnement Rational Rose [RATI96] qui fait la transition entre le monde d'UML et celui de Z. Rose est utilisé pour construire des modèles UML qui sont complétés par des annotations formelles. Le point principal est que tout le travail de modélisation (diagrammes et annotations) est réalisé dans Rose pour être le plus proche possible de l'environnement de travail habituel des concepteurs. Des spécifications Z sont alors générées automatiquement à partir d'un diagramme de classes et de ses annotations (figure 3). Diagramme UML Script Spécification Z Formulaires contenant les contraintes en Z Fichier Latex Environnement Rose Figure 3 : Principes de l'outil ROZ Les annotations sont exprimées dans des formulaires. Un formulaire doit contenir toutes les informations nécessaires pour compléter les squelettes de spécifications Z. Chaque formulaire correspond à un type de contraintes défini précédemment. Il est attaché à l'élément du diagramme de classes qu'il complète. En Rose, un formulaire pré-défini est associé à chaque élément de l'application. Nous aurions aimé pouvoir modifier ces formulaires afin d'y ajouter les champs dont nous avions besoin pour le passage à des spécifications formelles. Mais cela n'étant pas possible, nous nous contentons d'utiliser les formulaires standards de Rose. A partir d'un diagramme de classes et de ses annotations, RoZ utilise les scripts de Rose pour générer un fichier contenant les spécifications formelles Z au format Latex. Le format Latex a été choisi pour pouvoir appliquer les outils de vérification de type et les outils de preuve de Z. Pour des raisons de simplicité, les contraintes sont actuellement écrites en syntaxe Z. Mais les formalismes d’OCL et de Z étant très proches, les contraintes pourraient être écrites en OCL puis traduites automatiquement en Z en vue de leur intégration dans les squelettes de spécifications. 4.2 Application au contrôleur d'accès Nous avons exprimé le diagramme de classes du contrôleur d'accès dans l'environnement Rose (figure 4). On peut noter que pour permettre le passage en Z, le diagramme doit être complet : on doit connaître le type des attributs, le nom des rôles des associations et leurs cardinalités. En particulier pour l'attribut « tel », il est important de préciser qu'il s'agit d'un attribut multi-valué. RoZ ne permet pas actuellement d’écrire cela en UML, mais en utilisant la notation Latex de Z pour les ensembles finis (\finset). Figure 4: Diagramme de classes dans Rose Le reste des informations nécessaires pour compléter les squelettes de spécifications Z doit être exprimé dans les formulaires standards de Rose. Nous avons choisi de réserver le champ « Documentation » de chaque formulaire à l'expression des contraintes. Pour les contraintes sur une classe, nous nous servons du champ « Documentation » du formulaire de la classe pour celles sur les objets de la classe et du champ « Documentation » du formulaire des attributs pour celles sur les attributs. Pour les contraintes portant sur plusieurs attributs il faut choisir un des formulaires des attributs. Par exemple, pour la classe « ACCES », le formulaire de la classe (figure 5) contient la contrainte de clé (contrainte 1) et celle spécifiant que la date de sortie reste indéfinie seulement pour le dernier accès (contrainte 5). Les contraintes sur les dates d'entrée et de sortie sont écrites dans le formulaire de « date-entree » (figure 5). Figure 5 : Formulaire de “ACCES” et de “dateentree” Cela n'est pas suffisant pour fournir toutes les informations nécessaires à la génération automatique des spécifications Z concernant « ACCES ». En particulier, la déclaration des types s’effectue dans un fichier qui doit être inclus lors de la génération de Z. De plus, le cas de la classe « ACCES » illustre un autre problème qui nécessite actuellement de modifier directement les spécifications Z. Il concerne la clé importée : la clé d' « ACCES » est constituée de la date d'entrée et de la personne. Pour ajouter automatiquement au schéma de l'intension de « ACCES » la variable personne, on doit savoir que personne fait partie de la clé. Or cette information n'est pas exprimable dans les formulaires actuels. Deux solutions sont envisageables pour éviter de modifier directement les spécifications Z. La première consiste à ajouter un attribut « personne » à la classe « ACCES ». Cet attribut sera traduit en Z comme tout autre attribut. La deuxième solution serait de pouvoir exprimer dans le formulaire les éléments de la clé. Comme pour les classes, le champ « Documentation » des relations sert à exprimer les contraintes sur les associations. Nous avons choisi dans l'étude de cas du contrôleur d'accès de spécifier que tous les membres d'un groupe ont le même préfixe téléphonique. La déclaration du type PREFIXE et de la fonction prefixe sont faites dans le fichier de déclaration des types et la contrainte est écrite dans le formulaire de « Appartenir » (figure 6). Enfin on exprime les contraintes sur la base de données globale dans le formulaire du diagramme de classes (figure 6). Ici on représente la contrainte suivante : un accès peut être enregistré que si la personne est autorisée à entrer dans le bâtiment lié à l'accès. Figure 6 : Formulaires de “Appartenir” et du diagrammes de classes RoZ tire donc avantage de la structure des champs « Documentation ». Mais comme cette structure ne correspond pas exactement à notre classification (il n’y a pas de formulaire spécifique aux contraintes sur plusieurs attributs), nous avons dû l’adapter. De façon identique à l’expression des contraintes, on peut écrire dans les formulaires le corps des opérations en Z. On peut ainsi générer automatiquement les schémas Z correspondant aux opérations du diagramme de classes. 4.3 Comparaison avec d’autres outils Divers environnements couplant différents types de spécifications ont été proposés. Certains se basent sur des méta-outils comme GraphTalk ([FREI97, NGUY98]). Un méta-outil est un outil destiné à construire d’autres outils. D’autres, comme le nôtre, proposent d’étendre des outils existants. En particulier, l’outil Rose a déjà permis de faire le lien entre UML et VDM++ ([IFAD]) et UML et Z ([HEAD]). L’utilisation d’un méta-outil permet de construire exactement l’environnement désiré. Mais son développement est beaucoup plus long que l’extension d’un environnement existant et reste souvent au niveau de prototype. De plus, l’utilisation d’un environnement « standard » permet de rester proche des habitudes de travail des concepteurs de SI. Une autre comparaison peut être faite sur la façon de coupler les types de spécifications. [FREI97] et [HEAD] proposent des environnements de multi-modélisation dans lesquels les différents types de spécifications sont disponibles dans le même environnement de modélisation. On développe donc en parallèle les spécifications semi-formelles et formelles. Dans cette approche, il est nécessaire de bien connaître les différents formalismes, en particulier pour pouvoir ajouter des contraintes aux spécifications formelles. L’autre approche consiste à générer automatiquement les spécifications formelles dans un fichier . L’avantage est de disposer d’un fichier qui peut être utilisé par les outils des langages formels. C’est ce qui est proposé dans [FRAN97]. Mais cet article ne précise pas comment compléter les spécifications formelles du fichier. Notre proposition va plus loin en proposant d’effectuer tout le travail de modélisation (diagrammes et contraintes) dans l'environnement standard graphique d’UML. On ne voit alors des spécifications formelles que le strict minimum nécessaire à leur exploitation. Le niveau d’exploitation ultérieure de la spécification formelle (preuves etc) obtenue dépend alors du niveau de maîtrise du langage formel. En effet, il n'est pas nécessaire de connaître en détail le langage formel cible pour produire une documentation enrichie de spécifications formelles. Par contre, il faut une bonne maîtrise des spécifications formelles pour effectuer la vérification ultérieure à l'aide d'un outil d'aide à la preuve de Z par exemple. 5 Conclusion L’approche exposée permet de prendre en compte les contraintes statiques sur un diagramme de classes UML. Elle consiste à générer des spécifications formelles Z à partir du diagramme de classes UML et de leurs contraintes : UML fournit la structure des schémas Z et les contraintes fournissent des détails. Nous utilisons la complémentarité des diagrammes UML et des contraintes pour obtenir automatiquement des spécifications formelles. Nous obtenons ainsi dans une seule vue tous les éléments de la modélisation. Cette complémentarité permet ensuite d’exploiter la précision des spécifications formelles pour analyser la modélisation. Grâce à la traduction en Z, une classification des contraintes a été identifiée. Elle est la base d’un guide méthodologique pour exprimer les contraintes, guide qui a été implanté dans l’outil RoZ. Ce guide permet de concrétiser l’idée que tout le travail de modélisation doit rester homogène avec l’environnement de modélisation : le diagramme est décrit dans un éditeur graphique complété par des formulaires contenant les contraintes. Il importe de noter que le fait de gérer toute la modélisation dans l’environnement UML permet de ne pas avoir des versions divergentes entre les spécifications en UML et celles en Z. En effet, toute modification des spécifications s'effectue au niveau de l'environnement UML à partir duquel les spécifications formelles correspondantes sont regénérées automatiquement. Par ailleurs, la gestion à l’intérieur du modèle UML de la spécification Z permet de tester la validité de celle-ci par incréments de modèles et doit aussi permettre une prise en compte facilitée de la complexité des SI. Il est maintenant important d’aider les concepteurs à écrire des modèles plus précis en leur facilitant en particulier l’écriture des contraintes. Dans l’outil RoZ, les contraintes sont actuellement écrites au format Latex de Z. Cette solution n’est pas satisfaisante car elle nécessite une bonne connaissance de Z et de son format Latex. Mais une prochaine version de l'outil devrait permettre une expression des contraintes en OCL, et leur traduction automatique en Z. Nous aurions ainsi un outil facilement utilisable pour un concepteur connaissant UML et OCL. Cependant pour des raisons identiques à celles qui nous ont fait renoncer à Object-Z comme langage de spécification formelle, OCL ne peut pas être une fin en soi tant que son environnement n’offre pas d’outils puissants de vérification du niveau de ceux langages formels plus anciens. Son rôle, prévu par ses auteurs, est celui d’interface pour faciliter l’expression des contraintes. Pour améliorer encore l’interface, RoZ pourrait aussi proposer des contraintes prédéfinies dont l’utilisateur aurait juste à préciser le domaine d’application. Chaque classe proposerait ainsi une contrainte de clé pour laquelle l’utilisateur aurait à spécifier le ou les attributs clés. L’écriture en Z de la contrainte pourrait ensuite être générée automatiquement par RoZ. Nous avons exposé ici essentiellement une démarche d’outillage de la spécification de SI. Au delà de l’extension de ces outils et de l’amélioration de leur convivialité qui conditionnent leur utilisation effective, il faut aussi maintenant les expérimenter plus largement dans une démarche d’analyse des SI. Il faudrait en particulier permettre de présenter dans l’atelier la portée de chaque contrainte afin de mieux maîtriser l’impact de toute évolution de spécification ou de contraintes. Ce travail est encore loin du transfert industriel. Néanmoins nous pensons qu’il peut contribuer à une meilleure intégration des contraintes dans la tâche de modélisation produisant ainsi des spécifications plus précises et plus utiles. Références [AMGH94] Y. Amghar, A ; Flory, Contraintes d’intégrité dans les bases de données orientées objet, Ingénierie des systèmes d'information, volume 2, numéro 5, 1994 [DATE95] C. Date, An Introduction to Database Systems, Sixth Edition, Addison-Wesley, 1995 [DELO82] C. Delobel, M. Adiba, Base de données et systèmes relationnels, Dunod Informatique, 1982 [DUPU98] S. Dupuy, Y. Ledru et M. Chabre-Peccoud. Translating the OMT dynamic model into Object-Z. Dans 11th Z User Meeting, LNCS,Berlin, Springer, Septembre 1998. [DUPU00] S. Dupuy, Y. Ledru et M. Chabre-Peccoud, Vers une intégration utile de notations semi-formelles et formelles : une expérience en UML et Z, L'Objet numéro spécial sur « les méthodes formelles pour les systèmes à objets », 2000, à paraître [FACO96] P. Facon, R. Laleau, Des modèles d'objets aux spécifications formelles ensemblistes, Ingénierie des systèmes d'information, volume 4, numéro 2, 1996 [FRAN97] R.B. France, J.-M. Bruel, M.M. Larrondo-Petrie, An Integrated Object-Oriented and Formal Modeling Environment, Journal of Object Oriented Programming, Novembre/Décembre 1997 [FREI97] J.C. Freire, Ingénierie des Systèmes d'Informations: Une Approche de MultiModélisation et de Méta-Modélisation, Thèse de doctorat : Université Joseph Fourier, Grenoble, 1997 [HALL94] A. Hall, Specifying and Interpreting Class Hierarchies in Z, Dans Proc. of the 8th Z User Meeting, Cambridge, Angleterre, Juin 1994 [HEAD] Headway Software, RoZeLink 1.0 http://www.calgary.shaw.wave.ca./headway/index.htm [IFAD] IFAD, the Rose-VDM++ Link http://www.ifad.dk/Products/rose-vdmpp.htm [LALE95] R. Laleau, N. Nadj-Rabia, Génération automatique de spécifications VDM à partir d’un schéma conceptuel de données, Dans Actes du 13ème congrès INFORSID, Grenoble, France, Juin 1995 [LANO96] K. Lano, H. Houghton, P. Wheeler, Integrating Formal and Structured Methods in Object-Oriented System Development, dans Formal Methods and Object technology, Chapitre 7, 1996 [LEDR97] Y. Ledru, Etude de cas : Système de contrôle d’accès (version 1.1), Avril 1997 http://www.lsr.imag.fr/LesPersonnes/YvesLedru/Contrôle_Acces/ [LEDR98] Y. Ledru, Identifying pre-conditions with the Z-EVES theorem prover, Dans Proc. of the 13th Int. Conf. On Automated Software Engineering, IEEE, 1998 [NGUY98] H.P. Nguyen, Dérivation de Spécifications Formelles B à Partir de Spécifications Semi-Formelles, Thèse de doctorat CNAM, Décembre 1998 [SHRO97] M. Shroff et R. France, Towards a formalization of UML class structures in Z, Dans Proc. of the 21th Int. Computer Software and Applications Conference – COMPSAC’97, IEEE, 1997 [SPIV95] J.M. Spivey, La notation Z, Prentice-Hall International, 1995 [OU98] Y. Ou, On Using UML Class Diagram for Object-Oriented Database Design – Specification of Integrity Contraints, Dans « UML »’98 Beyong the Notation, Mulhouse, France, Juin 1998 [RATI96] Rational Software Corporation, Rational Rose – Extensibility Guide, 1996 [RATI97] Rational Software Corporation, UNIFIED MODELING LANGUAGE – notation guide version 1.1, Septembre1997 [WARM98] J. Warmer, A. Kleppe, The Object Constraints Language, Addison-Wesley, 1998 Annexe Règles de traduction d’UML vers Z Proposition 1 : Classe Chaque classe « CCC » donne lieu à : • un schéma-type de nom CCC contenant la déclaration des attributs • un schéma CccExt définissant l'ensemble des objets de la classe Il comprend une seule variable Ccc définissant l'ensemble des objets existants (Ccc : CCC). Proposition 2 : Attribut Chaque attribut « a » d'une classe « CCC » donne lieu à : • la déclaration d'un type Ta si Ta n'est pas déjà défini • la déclaration d'une variable a de type Ta dans le schéma CCC (a :Ta). Proposition 3 : Association binaire Chaque association binaire A entre deux classes « CCC1 » et « CCC2 » donne lieu à un schéma décrivant chacun des rôles « R1 » et « R2 » de l'association sous forme de fonctions F1 et F2. Pour des raisons de simplicité, on commence toujours par spécifier un rôle monovalué, s'il existe. Dans cette proposition, on suppose que s'il existe un rôle monovalué, il s'agit de « R1 ». Les cardinalités des rôles sont spécifiées de la façon suivante: • cardinalité minimale Si la cardinalité minimale est au moins 1 entre les classes « CCC1 » et « CCC2 », cela signifie que tout objet de « CCC1 » doit participer à l'association. Il y a alors égalité entre les objets existants de « CCC1 » et les objets de « CCC1 » participant à l'association (dom F1 = Ccc1). Sinon (si la cardinalité minimale vaut 0) tous les objets existants de « CCC1 » ne participent pas à l'association : si « R1 » est monovalué, on ajoute un prédicat de la forme ran F1 Ccc1 ; si le prédicat est (ran F1) Ccc1. • cardinalité maximale La cardinalité maximale est en fait exprimée par les fonctions. Une fonction de type CCC1 CCC2 exprime qu’à un élément de CCC1 correspond un seul élément de CCC2 (cardinalité maximale 1) et CCC1 CCC2 exprime qu'à un élément de CCC1 correspondent plusieurs éléments de CCC2. « R2 » est spécifié à partir de « R1 » : • si « R1 » et « R2 » sont monovalués, « R2 » est défini par : R2 = {c2 : ran R1 ; c1 : dom R1 | c2 = R1(c1) @ c2 • si « R1 » est monovalué et « R2 » multi-valué, « R_2 » est défini par : R2 = {c2 : ran R1 • c1} c2 { c1 : dom R1 | c2 = R1(c1) c1} } si « R1 » et « R2 » sont multivalués, « R2 » est défini par : R2 = {c2 : (ran R1) c2 { c1 : dom R1 | c2 \in R1(c1) c1} } Proposition 4 : Vue Une vue partielle ou globale d'un diagramme est représentée par un schéma Z incluant les schémas des associations de cette vue.