INF3143 Modélisation et spécification formelles des logiciels Hiver 2017 Alexandre Terrasa Département d informatique, UQÀM
Expression des contraintes en UML 2
Exprimer des contraintes avec UML Dans le diagramme de classes: contraintes structurelles classes, interfaces, héritage, relations, navigabilité, cardinalité contraintes de type type des propriétés, paramètres, retours contraintes de visibilité public, privé, protected, package 3
Limite par l exemple Diagramme de classes Université employés * 1 1 Professeur nom: String salaire: Integer professeur 1 * * Cours sigle: String 4
Limite par l exemple Code source valide et acceptable Professeur p1 = new Professeur() p1.nom = Alexandre p1.salaire = 100000000 Code source valide mais inacceptable Professeur p2 = new Professeur() p2.nom = p2.salaire = -10 5
Limite par l exemple Diagramme d objets valide et acceptable p1:professeur u1:université p2:professeur u2:université c1: Cours c2: Cours 6
Limite par l exemple Diagramme d objets valide et inacceptable p1:professeur u1:université p2:professeur u2:université c1: Cours c2: Cours 7
Exercice Écrivez deux diagrammes d objets un valide et acceptable un valide mais inacceptable parent 0..1 Répertoire * nom: String 8
Solution (exemple valide et acceptable) r1:répertoire nom= r1 r2:répertoire nom= r2 r3:répertoire nom= r3 r4:répertoire nom= r4 r5:répertoire nom= r5 r6:répertoire nom= r6 9
Solution (exemple valide mais inacceptable) r1:répertoire nom= r1 Répertoire r1 = new Répertoire( r1 ) r1.parent = r1 10
Un besoin: exprimer des contraintes sémantiques Contrainte sémantique du modèle condition à respecter restriction assertion Exemples: le solde du compte doit toujours être positif un livre ne peut pas être emprunté par deux personnes différentes en même temps une personne ne peut pas être professeur et chargée de cours en même temps 11
Contraintes en UML Dans le diagramme de classe texte entre accolades: {condition} langage naturel: {solde toujours positif} ou OCL: {solde >= 0} Dans un document annexe au diagramme en OCL 12
Contraintes dans le diagramme de classes Directement dans la classe Étudiant nom: String {nom.size() > 0} moyenne: Real {moyenne >= 0.0} Dans une note nom: String moyenne: Real Étudiant {nom.size() > 0 and moyenne >= 0.0} 13
Contraintes dans le diagramme de classes Sur les relations Personne propriétaire {xor} Compte Corporation propriétaire 14
Contraintes dans un document OCL Diagramme de classes nom: String moyenne: Real Étudiant {nom.size() > 0 and moyenne >= 0.0} Dans le fichier annexe context Étudiant inv: nom.size() > 0 inv: moyenne >= 0.0 15
OCL Object Constraint Language 16
Object Constraint Language Expression de contraintes pour UML langage formel en lien avec un diagramme de classes depuis UML 1.1 Contraintes de comportement (le QUOI) respect de la spécification contraintes de sémantique et non d implémentation 17
OCL pour faire quoi? Spécifier des contraintes d état invariants de classes pré-conditions sur des opérations post-conditions sur des opérations Formuler les contraintes sur les objets au niveau du diagramme de classes Utiliser des contraintes ensemblistes 18
Langage naturel vs OCL Langage naturel accessible ambigu, imprécis OCL (langage formel) précis, non-ambigu interprétable par des outils 19
Langage de programmation vs OCL Langage de programmation faible niveau d abstraction mode opérationnel (COMMENT) Langage formel abstrait mode descriptif (QUOI) 20
OCL Logique et syntaxe 21
Logique propositionnelle Issue de la logique mathématique logique basée sur les propositions on parle aussi d assertions énoncés vrais ou faux Exemples d assertions solde > 0 resultat = solde 22
Opérateurs logiques Opérateur unaire sur un booléen not négation Opérateurs binaires sur des booléens and et logique or ou logique xor ou exclusif implies implication logique 23
Opérateur not Négation de la proposition not true = false A true false not A false true 24
Opérateur and, or, xor Pour combiner des propositions A B A and B A or B A xor B true true true true false true false false true true false true false true true false false false false false 25
Opérateur implies Opérateur d implication logique Si A est vrai alors B est vrai aussi. Raccourci pour not A or B A B A implies B true true true true false false false true true false false true 26
Opérateur implies Exemples SI le ciel est couvert ALORS on ne voit pas le soleil SI l alarme incendie sonne ALORS on doit utiliser l escalier 27
Opérateur if-then-else-endif Opérateur logique if A then B else C endif Si A est vrai alors l expression vaut B Si A est faux alors l expression vaut C 28
Opérateurs mathématiques Opérateurs arithmétiques sur les entiers et réels: - unaire (comme dans -10) + addition, - soustraction * multiplication, / division Opérateurs de comparaison: = égalité et <> différence < et <=, > et >= 29
Précédence des opérateurs Par ordre de précédence: if-then-else-endif not et - unaire * et / + et - <, >, <= et >= = et <> and or xor implies 30
Types fondamentaux OCLAny ancêtre de tous les types Boolean true, false Integer 1 ; -3 ; 12 ; 42 Real 1,5 ; 3,14 ; -10.3 String Hello World! OCLVoid null ; invalid Et les collections que nous verrons plus tard... 31
Opérations sur les types fondamentaux Integer, Real =, <>, <=, >=, +, -, *, / Boolean and, or, not, xor, =, <>, implies, if <expr> then else endif String concat(string), size(), tolower(), toupper() substring(start, end) Le premier caractère d une string est à l index 1! 32
Opérations sur tous les types allinstances(): retourne l ensemble de toutes les instances d une classe ocltype(): retourne le type d un objet oclistypeof(<type>): retourne vrai si l objet est du type spécifié ocliskindof(<type>): retourne vrai si l objet est du type spécifié ou un de ses sous-types 33
Opérateurs d appel Opérateur. pour accéder aux propriétés des objets self.name self.getname() Opérateur -> pour appeler les méthodes sur les collections OCL self.étudiants->size() Opérateur :: pour référer aux propriétés d une classe Étudiant::nom 34
OCL Contraintes 35
Contexte d une contrainte Une contrainte est toujours associée à un élément du modèle classe, interface attribut ou opération relation Syntaxe: context <élément> 36
Représentation du contexte en OCL Diagramme de classes nom: String moyenne: Real Étudiant {moyenne >= 0.0} renommer(string): void En OCL context Étudiant inv: moyenne >= 0.0 37
Exemples de contextes Sur une classe context Étudiant Sur un attribut context Étudiant::nom Sur une opération context Étudiant::setNom(nom: String): void 38
Invariant Contrainte à respecter en tout temps (prédicat) inv [<nom>]: <expression_logique> Exemple context Étudiant inv: moyenne >= 0.0 context Cours inv: sigle.size() >= 3 39
Accéder aux propriétés des objets Objet désigné par le contexte: self Exemple dans le context Étudiant nom self.nom renomer( nouveau_nom ) self.renomer( nouveau_nom ) 40
Exercice 1 université * 1 Professeur nom: String 1 professeur * Université 1 * Cours sigle: String coef: Real université Exprimer les contraintes OCL: Le nom d un professeur ne peut être nul Le sigle d un cours fait toujours 3 caractères Le coefficient d un cours est entre 0.0 et 100.0 Un professeur doit travailler dans l université qui dispense le cours pour l enseigner 41
Solution 1 context Professeur inv: nom <> null context Cours inv: sigle.size() = 3 inv: coef >= 0.0 and coef <= 100.0 inv: universite = professeur.universite 42
Pré-condition, post-condition Contrainte vérifiée avant ou après l appel d une opération pré-condition avant l appel post-condition après l appel Prédicat de spécification état avant et après un appel comportement attendu de l opération 43
Pré-condition Prédicat sur l état du système avant l appel d une opération pre [<nom>]: <expression_logique> Doit être vrai juste avant l exécution de l opération 44
Vérifier une pré-condition Vérifier que l état avant est respecté: context Etudiant::inscrire() pre: estinscrit = false 45
Post-condition Prédicat sur l état du système après l appel d une fonction post [<nom>]: <expression_logique> Doit être vrai juste après l exécution de l opération 46
Vérifier une post-condition Peut accéder à certaines valeurs spécifiques result valeur retournée par l opération <nom_attribut>@pre valeur de l attribut avant l appel context Etudiant::inscrire() post: estinscrit = true 47
Exemple solde: Real Compte getsolde(): Real créditer(montant: Real) débiter(montant: Real) context Compte::créditer(montant: Real) pre: montant > 0.0 post: solde = solde@pre + montant context Compte::getSolde(): Real post: result = solde 48
Exercice 2 Donnez un exemple de pré-condition et post-condition pour MyInteger::diviserPar() value: Integer MyInteger diviserpar(diviseur: MyInteger): MyInteger 49
Solution 2 context MyInteger::diviserPar (diviseur: MyInteger): MyInteger pre: diviseur.value <> 0 post: result.value = value / diviseur.value value: Integer MyInteger diviserpar(diviseur: MyInteger): MyInteger 50
Body Contrainte sur le résultat de la requête body : <requête> Exemple context Compte::getSolde(): Real body: self.solde 51
Exercice 3 Exprimer les contraintes: valeurs est toujours strictement supérieur à 0 ajoute prend un paramètre toujours supérieur ou égal à 0 ajoute incrémente le nombre de valeurs et additionne valeur à somme moyenne retourne la moyenne de somme sur valeurs Compteur valeurs: Integer somme: Integer ajoute(valeur: Integer) moyenne(): Integer 52
Solution 3 context Compteur inv: valeurs > 0 context Compteur::ajoute(valeur: Integer) pre: valeur >= 0 post: valeurs = valeurs@pre + 1 and somme = somme@pre + valeur context Compteur::moyenne(): Integer body: somme / valeurs 53
Définition let Pour déclarer une variable au sein d un énoncé let <declaration> = <requete> in <expression> <déclaration> aura la valeur de <requête> lorsqu utilisé dans <expression> context Étudiant inv: let nblettres = nom.size() in nblettres > 0 54
Définition def Pour déclarer une variable globale def : <declaration> = <requete> context Étudiant def: nblettres = nom.size() inv: nblettres > 0 55
Contrainte d initialisation Contrainte sur la valeur initiale d un attribut init : <requête> Exemple context Étudiant::moyenne: Real init: 0.0 56
Contrainte de dérivation Contrainte sur un attribut dérivé derive : <requête> Exemple context Étudiant::age : Integer derive: Date::current() - datenaissance 57
Exercice 4 Diagramme de classes Assuré valeurvehicule(): Integer 1 0..1 Permis points: Integer retirerpoints(p: Integer) 1 0..1 Assurance Véhicule categorie: String valeur: Integer 1 0..1 catégorie: String valeur: Integer 58
Exercice 4 Contraintes à implémenter en OCL assurance.vehicule.valeur ou 0.0 Assuré valeurvehicule(): Integer 1 0..1 1 0..1 Assuré doit avoir des points sur son permis pour avoir une assurance init à 6 Permis points: Integer retirerpoints(p: Integer) retire p points auto ou moto Assurance catégorie: String valeur: Integer 1 0..1 Véhicule catégorie: String valeur: Integer <= valeur assurance = catégorie de l assurance 59
Solution 4 context Assuré inv: assurance <> null implies permis.points > 0 context Permis::points: Integer init: 6 context Permis::retirerPoints(p: Integer) pre: p > 0 post: points = points@pre - p context Assuré::valeurVehicule(): Integer body: if assurance <> null then assurance.vehicule.valeur else 0 endif context Assurance inv: categorie = auto or categorie = moto context Vehicule inv: categorie = assurance.categorie and valeur <= assurance.valeur 60
Conclusion Le diagramme de classes seul est parfois insuffisant pour exprimer la spécification Une solution: OCL langage formel basé sur la logique mathématique expression des contraintes sémantiques spécifier des contraintes d état invariants de classes pré-conditions sur des opérations post-conditions sur des opérations 61
Ressources http://www.omg.org/spec/ocl/ http://laurent-audibert.developpez.com/cours- UML/?page=object-constraint-langage-ocl Tremblay, G - Modélisation et spécification formelle de logiciels - Loze-Dion Editeurs Inc., 2004 (chap 12) 62