Types abstraits Abstraction Abstraction - motivations Abstraction = se libérer des détails, simplifier, généraliser Notion de type abstrait Spécification algébrique des TA En structures de données Modèle de la machine : ensemble de cellules mémoire Types de base : entiers, flottants, caractères, pointeurs Types composés : tableaux de T, n-tuples de T1, T2, … Types abstraits : indépendant de la représentation G. Falquet, CUI, Université de Genève 1 de 31 G. Falquet, CUI, Université de Genève Types et ensembles 2 de 31 Types et opérations Le même ensemble peut représenter des choses de différentes natures Un type de données est caractérisé par ses valeurs ET ses opérations Ensemble des nombres : 1. date (en nombre de jours depuis le 01.01.1900) 2. poids (en grammes) 3. durée (en jours) 4. longueur (en mètres) On n’a pas forcément besoin de connaître les valeurs Pour autant qu’on puisse en extraire l’information voulue par une opération nom_jour : date --> chaîne de caractères Mais les opérations sont différentes date – date OK nom_mois : date --> chaîne de caractères mois : date --> entier année : date --> entier date + date poids + poids ??? OK poids * poids ??? durée + durée OK Peu importe la représentation utilisée pour les valeurs de date : longueur * longueur OK nb. jours depuis 1.1.1900, nb. minutes depuis 1.1.1900, 3 entiers (J, M, A), etc. G. Falquet, CUI, Université de Genève 3 de 31 G. Falquet, CUI, Université de Genève 4 de 31 Représentation d’un objet complexe Représentations d’un graphe The Design and Analysis of Computer Algorithms Différentes représentations d’un graphe • Matrice booléenne Aho, Hopcroft, Ullman • Listes d’adjacence • Tableau des arcs • etc. Remarques Pour chaque représentation écriture de programmes différents p.ex. “trouver les tâches dépendant de T” Comment se libérer de la diversité des représentations ? G. Falquet, CUI, Université de Genève 5 de 31 G. Falquet, CUI, Université de Genève Signification des opérations 6 de 31 Conséquences Représentations identiques (deux entiers), mêmes opérations, sens différents Séparer • la définition (spécification) abstraite du type • son implémentation (str uctures de données et algorithmes) Opérations opération Comparer(a, b : Coordonnées) { retourner a.x = b.x et a.y = b.y } Comment définir abstraitement les opérations ? • approche orientée modèle • approche algébrique opération Comparer(a, b : Fraction) { retourne a.num * b.den = a.den * b.num } prodédure Additionner(a, b : Coordonnées) { c.x = a.x + b.x; c.y = a.y + b.y; retourner c } En programmation : procédure Additionner(a, b : Fractions) { sépararer • l’interface d’un type (partie publique) • son implémentation (partie privée) c.num = a.num*b.den + b.num*a.den; c.den = a.den*b.den; retourner c } => programmation modulaire, encapsulation, "data hiding", programmation OO G. Falquet, CUI, Université de Genève 7 de 31 G. Falquet, CUI, Université de Genève 8 de 31 Deux approches Types abstraits algébriques Spécification orientée modèle Présentation d’un TA = {signatures d’opérations} + {propriétés} Types "prédéfinis" : entier, réels, booléens, …, séquence, ensemble, fonction On ne dit rien sur la représentation des objets de ce type Construction d’une représentation par composition des types prédéfinis On définit le sens des opérations par des équations Opérations : plus abstrait (général) que des algorithmes spécification implicite par pré et post condition Spécification algébrique spécification explicite : opérations sur les représentations SORTES : noms donnés aux différents types de valeurs Approche algébrique PROFIL d’une opération : sor te des paramètres et du résultat Uniquement basée sur les opérations AXIOMES : équations qui spécifient le comportement des opérations Définition des propriétés des opérations par des équations (=) forme : expression == expression ou expression == expression ET … => expression == expression G. Falquet, CUI, Université de Genève 9 de 31 G. Falquet, CUI, Université de Genève SPECIFICATION Booléens 10 de 31 Utilisation des axiomes sortes bool 1. non vrai == faux; opérations 2. non non X == X; vrai : -> bool; // constante 3. vrai et X == X; faux : -> bool; // constante 4. faux et X == faux; non _ : bool -> bool; 5. vrai ou X == vrai; _et_ : bool, bool -> bool; 6. faux ou X == X; _ou_ : bool, bool -> bool; // notation infixée axiomes variables X, Y: bool; 1. non vrai == faux; (non vrai) ou faux // pour tout X et tout y == faux ou faux ==faux (par 1.) (par 6.) 2. non non X == X; 3. vrai et X == X; non (vrai et faux) 4. faux et X == faux; == non (faux) (par 3.) 5. vrai ou X == vrai; == non (non vrai) (par 1.) 6. faux ou X == X; etc. == vrai (par 2.) G. Falquet, CUI, Université de Genève 11 de 31 G. Falquet, CUI, Université de Genève 12 de 31 Exemple: Cercle Graphiquement elargir(C, er) SPECIFICATION Cercle SORTES entier, rationnel, cercle C er OPERATIONS cercle-unité : -> cercle tx // centre (0, 0), rayon 1 translater : cercle, entier, entier -> cercle ty elargir : cercle, entier -> cercle cercle-unité perimetre : cercle -> rationnel rayon : cercle -> entier centre-x : cercle -> entier // coordonnée x du centre centre-y : cercle -> entier // coordonnée y du centre G. Falquet, CUI, Université de Genève translater(cercle-unité, tx, ty) 13 de 31 G. Falquet, CUI, Université de Genève Axiomes 14 de 31 Axiomes (suite) VARIABLES X, Y, Z, DR: entier; C: cercle; Elargir ne modifie pas les coordonnées du centre centre-x(elargir(C, Z)) == centre-x(C) centre-y(elargir(C, Z)) == centre-y(C) Coordonnées du centre et rayon du cercle unité mais change le rayon centre-x (cercle-unité) == 0 centre-y (cercle-unité) == 0 rayon(elargir(C, Z)) == rayon(C)+Z rayon (cercle-unité) == 1 La translation modifie les coordonnées du centre L’élargissement ne doit pas donner un cercle de rayon négatif Précondition à l’application de l’opération : centre-x(translater(C, X, Y)) == centre-x(C)+X centre-y(translater(C, X, Y)) == centre-y(C)+Y PRE elargir(C, Z) == rayon(C) + Z >= 0 mais pas le rayon elargir(cercle-unité, -2) n’est pas défini ---> fonction partielle rayon(translater(C, X, Y)) == rayon(C) G. Falquet, CUI, Université de Genève 15 de 31 G. Falquet, CUI, Université de Genève 16 de 31 Exemples SPECIFICATION Naturels rayon(translater(elargir(cercle-unité, 12), 5, 7) UTILISE Bool == rayon(elargir(cercle-unité, 12) == rayon(cercle-unité) +12 SORTES nat == 1 + 12 == 13 OPERATIONS rayon(elargir(elargir(cercle-unité, 5), –8))pas défini car 0 : -> nat; // constante succ : nat -> nat; // successeur _+_ : nat, nat -> nat; elargir(elargir(cercle-unité, 5), –8) défini seulement si _–_ : nat, nat -> nat; _*_ : nat, nat -> nat; rayon(elargir(cercle-unité, 5)) + –8 >= 0 mais _^_ : nat, nat -> nat; _=_ : nat, nat -> bool; rayon(elargir(cercle-unité, 5)) == rayon(cercle-unité) + 5 == 6 et 6 + –8 pas >= 0 G. Falquet, CUI, Université de Genève 17 de 31 G. Falquet, CUI, Université de Genève AXIOMES (nat) 18 de 31 Tableaux VAR X, Y : nat; Un tableau est un ensemble d’éléments numérotés à partir de 0. 1. X + 0 == X; Les éléments n’ont aucune propriété particulière à satisfaire spécification Element 2. X + succ(Y) == succ(X + Y); 3. 0 – X == 0; 4. X – 0 == X; spécification Tableau(Element) 5. succ(X) – succ(Y) == X – Y; utilise Bool, Nat 6. X * 0 == 0; sortes tab 7. 8. X * succ(Y) == X + (X * Y); X ^ 0 == succ(0); opérations 9. X ^ succ(Y) == X * (X ^ Y); sortes elem // éviter de sortir des entiers naturels. init : elem -> tab; valeur elem // initialise le tableau avec une 10. 0 = 0 == vrai; _ [ _ ] : tab, nat -> elem; 11. succ(X) = 0 == faux; // accéder à un élément : a[i] 12. 0 = succ(X) == faux; _ [ _ ] ←_ : tab, nat, elem -> tab;// modifier un élément : a[i] ← x 13. succ(X) = succ(Y) == X = Y G. Falquet, CUI, Université de Genève 19 de 31 G. Falquet, CUI, Université de Genève 20 de 31 Tableaux: AXIOMES Exemple VAR A, B : tab; I : nat; X : elem (((init(a)[3]←b)[2]←c)[4]←b)[3] == ((init(a)[3]←b)[2]←c)[3] Le i-ème élément d’un tableau initialié avec X vaut X == (init(a)[3]←b)[3] == b 1. init(X)[I] == X Le i-ème élément vaut X après qu’on ait mis X dans le i-èeme élément ((((init(a)[3]←b)[2]←c)[3]←w)[4]←b)[3] 2. == (((init(a)[3]←b)[2]←c)[3]←w)[3] (A[I]←X)[I] == X == w Si on met X dans le j-ème élément, ça ne modifie pas les autres 3. I = J == faux => (A[J]←X)[I] == A[I] écriture simplifié : (A[J]←X)[I] == X si I = J, == A[I] sinon G. Falquet, CUI, Université de Genève 21 de 31 G. Falquet, CUI, Université de Genève Généricité 22 de 31 Démarche de développement Les éléments du tableau sont de la sorte elem définie dans la spécification spécification Element Spécification algébrique • définition des opérations et de leurs propriétés sortes elem • calculs formels (vérification de propriétés) • pas besoin d’algorithmes ni de structures de données Définition d’une classe Mais ils pourraient être de n’importe quelle sorte qui satisfait Element • spécification des méthodes (correspondant aux opérations) Implémentation • choix d’une structure de données (représentation) • choix des algorithmes et programmation des opérations On instancie la spécification Tableau en faisant spécification TableauNat = Tableau(Element → Nat avec elem → nat) spécification TableauBool = Tableau(Element → Booléen avec elem → bool) G. Falquet, CUI, Université de Genève 23 de 31 G. Falquet, CUI, Université de Genève 24 de 31 Implémentation avec un système à objets Exemple Cercle Objet (définition restreinte) = paire (identité, valeur) Variables d’instance (structure de données) identité: • invariable entier x // coordonnée x du centre entier y entier r // coordonnée y du centre // rayon valeur: • peut changer au cours du temps • composée de variables d’instance Opérations Implémenter // rayon : cercle -> entier Définir la structure interne (var iables d’instances) procedure rayon(Cercle c) { retourne c.r; Définir les algortithmes pour réaliser les opérations } // perimetre : cercle -> rationnel structure interne + algorithmes = type concret (ou classe) procedure perimetre(Cercle c) { retourne 2 * pi * c.r; } G. Falquet, CUI, Université de Genève 25 de 31 G. Falquet, CUI, Université de Genève Opérations (mutation) 26 de 31 Opération (construction) // translater : cercle, entier, entier -> cercle // cercle-unité : -> cercle procedure translater(Cercle c, entier dx, entier dy) { procédure cercle_unité { c.x ← c.x + dx; c ← new Cercle; c.y ← c.y + dy; c.x ← 0; <--- nouvel objet c.y ← 0: } c.r ← 1; // elargir : cercle, entier -> cercle retourne c procedure elargir(Cercle c, entier pr) { } c.r ← c.r + pr; Utilisation } w ← cercle_unité; w.elargir(6); a ← w.rayon; [[ a = 7 ]] G. Falquet, CUI, Université de Genève 27 de 31 G. Falquet, CUI, Université de Genève 28 de 31 Opérations (implémentation immuable) Propriétés de l’implémentation procedure translater(Cercle c, entier dx, entier dy) { z ← new Cercle; la correction (obligatoire): z.x ← c.x + dx; satisfaire la spécification du type abstrait (axiomes) z.y ← c.y + dy; représenter toutes les valeurs possibles (ou souhaitées) } ne représenter que les valeurs du TA procedure elargir(Cercle c, entier pr) { la complexité (mesure): z ← new Cercle; z.r ← c.r + pr; complexité en temps et espace de chaque opération } complexité en espace de la structure de données. Utilisation w1 ← cercle_unité; w2 ← w1.elargir(6); fournit un nouvel objet a ← w1.rayon; [[ a = 1 ]] b ← w2.rayon; [[ a = 1 et b = 7]] G. Falquet, CUI, Université de Genève 29 de 31 Autres propriétés simplicité (peu de code) : facile à vérifier, à corriger et à maintenir à jour. utilisabilité : interface du type = liste des procédues (méthodes) pas forcément de correspondance 1-1 entre opérations et méthodes design de l’interface en fonction de l’usage du type bon design : utilisation simple extensibilité et réutilisabilité : peut-on facilement définir d’autres types à partir de celui-ci ? par extension ou agrégation G. Falquet, CUI, Université de Genève 31 de 31 G. Falquet, CUI, Université de Genève 30 de 31