• Aucun résultat trouvé

La proximite semantique des classes est dicile a mesurer. Nous de nissons un critere statique simple pour mesurer la proximite deux classes C

i et C j: (eq7:4:3) 1? jK(C i) \K(C j) j jK(C i) [K(C j) j

ou K(C) represente le comportement complet, en termes d'operations du TAG de la classeC

(i.e. sans les methodes primitives autres que les selecteurs de champ).

Le comportement complet se calcule comme la construction des pro ls par l'algorithme de la gure 60 a ceci pres qu'on ne rajoute pas de nouveaux noeuds dans la hierarchie. Se pose alors le probleme du non respect de la condition d'unicite de la retraction pour les operations secondaires. Par exemple, comparons les classes MMDLift,MBLift,BLLift,TLLiftetOOOLift

de la gure 65.

MMDLift MBLift BLLift TLLift OOOLift

MMDLift - 0 13/21 13/21 7/14

MBLift 0 - 13/21 13/21 7/14

BLLift 13/21 13/21 - 2/16 10/17

TLLift 13/21 13/21 2/16 - 10/17

OOOLift 7/14 7/14 10/17 10/17 -

Plus la valeur est proche de zero, plus le regroupement est interessant (e.g.MMDLift-MBLift (0)etBLLift-TLLift(0.125)).

Le critere est base sur les noms des methodes. Ce qui est signi catif de notre point de vue, car les methodes des di erentes classes formelles sont issues des operations d'un unique TAG. Nous avons envisage une comparaison sur les pro ls des methodes pour prendre en compte un eventuel renommage, mais le resultat ne s'est pas avere payant (bon nombre de methodes di erentes ont le m^eme pro l, deux methodes representatant la m^eme operation ont en general un pro l (speci que) di erent., etc.).

Restructurationdes classes pro ches

Si les sous-classes d'une classe sont proches alors elles sont regroupees puis restructurees. Lorsqu'il s'agit d'heritage simple, grouper les classes terminales dans leur super-classe commune est susant. En heritage multiple, il faut chercher la plus petite super-classe commune a toutes les classes terminales concernees.

La technique de restructuration est similaire a celle de la structuration des classes for- melles. Une structure triviale est exhibee, contenant un sous-aspect par classe jointe. Puis les sous-aspects equivalents sont representes exclusivement par des sous-aspects disjoints. En n, le concepteur realise plusieurs changements de representation jusqu'a aboutir a la structure la plus simple possible, avec preuve des representations. La determination d'une structure commune aux sous-aspects comprend des equivalences ou inclusions de structures, des homonymies, des valeurs par defaut (0, nil)), une inclusion de contrainte. Le bon sens du concepteur guide bien evidemment la restructuration.

Par exemple, examinons les sous-classes deINTERMEDIATELiftet deONFLOORLift.Les selec-

teurs de champ des sous-classes deINTERMEDIATELiftsont equivalents mais la contrainte varie.

Les cas sont di erencies par le selecteur de champ isUp. Un premier regroupement des sous-

aspects fBMLift, BTLiftg,fMBLift, MMDLiftg,fMTLift, MMULiftg,fTMLift, TBLiftgest

possible car les structures sont equivalentes et les contraintes complementaires. Ensuite, nous changeons la structure par rel^achement du type de oldState. La separation des cas se fait

en utilisant le selecteur d'etat isUp. La contrainte est reduite car la methode leveln'est pas

de nie ici.

INTERMEDIATELift

inherits from ONLift

aspect : lift

eld selectors constraint

oldState : INTERMEDIATELift ?! ONLiftFLOOR bottomLevel(Self) < topLevel(Self) offset : INTERMEDIATELift ?! IntegerGt1 AND 0 <= weight(Self) isUp : INTERMEDIATELift ?! Boolean

Le cas des sous-classes deONFLOORLiftest un peu plus complexe. ONFLOORLift

inherits from ONLift

aspect : lift

eld selectors constraint

isInstalled : ONFLOORLift ?! Boolean bottomLevel : ONFLOORLift ?! Integer

requires: isInstalled(Self) == true

topLevel : ONFLOORLift ?! Integer bottomLevel(Self) < topLevel(Self)

requires: isInstalled(Self) == true

capacity : ONFLOORLift ?! RealGt1 AND 0 <= weight(Self)

requires: isInstalled(Self) == true

contents : ONFLOORLift ?! List[Weightable] AND bottomLevel(Self) <= level(Self) oldState : ONFLOORLift ?! INTERMEDIATELift AND level(Self) <= topLevel(Self)

requires: isInstalled(Self) == false

bottomLevel*, topLevel* capacity*, chgCapacity* weight* limits

Lift*

ONLift*

OOOLift INTERMEDIATELift ONFLOORLift

oldState

bottomLevel, topLevel

getIn, getOut, chgCapacity, isIn weight, stop, restart, arrived

capacity, chgCapacity bottomLevel, topLevel bottomLevel, topLevel capacity, chgCapacity weight, repaired getOOO

weight, isOverloaded, up, down

oldState, isStopped, isUp, offset

capacity, isInstalled, contents, oldState

Figure 66 : Schema d'utilisation restructure du typeLift

7.5 Etape 3: Ecriture des extensions

Une fois la hierarchie achevee, le concepteur ecrit les extensions selon la methode de la section 6.2.6. Il peut s'inspirer de la speci cation algebrique, si elle a ete construite.

A partir de chaque operation du TAG, le concepteur ecrit les axiomes dans les classes ou une extensions correspondant a cette operation est de nie. Deux alternatives existent : soit le concepteur ecrit d'abord les extensions des classes terminales puis par comparaison de methodes il generalise les comportement communs, soit il commence par les extensions des classes abs- traites et ane si necessaire les descriptions dans les sous-classes. La comparaison de methodes est etudiee dans la section 7.5.1.

Nous preferons la seconde option car l'ecriture des axiomes d'une methode (selecteur de champ ou extension) correspondant a un constructeur du TAG est souvent remise en cause par la restructuration des classes. De plus la comparaison et l'union de methodes n'etant pas triviales, il vaut mieux les eviter. Par contre la conformite des classes avec le TAG est plus dicile a montrer lorsque sa speci cation algebrique existe.

generateursdebase

Si le modele des classes formelles contient des metaclasses, les generateurs de base deviennent des methodes de classe des classes correspondant aux etats initiaux, sinon ce sont des methodes

generales, uniques dans le systeme.

ONFLOORLift

class methods

;; install : build an initial lift

install : Integer Integer RealGt1 ?! ONFLOORLift

var: Xbot : Integer,Xtop: Integer,Xcap: RealGt1

install(Xbot, Xtop, Xcap) == newONFLOORLift(bottomLevel = Xbot, topLevel = Xtop, capacity = Xcap, contents = newEmptyList(), isInstalled = false)

generateurs

Les generateurs non recursifs de nis dans une classe deviennent des extensions. Tandis que les generateurs recursifs sont exprimes a partir de la methodecopy.

ONFLOORLift

extensions

;; down : gets down Xd levels

down : ONFLOORLift IntegerGt1 ?! INTERMEDIATELift

var: Xd : IntegerGt1

requires: Xd <= level(Self) - bottomLevel(Self) == true & isOverloaded(Self) == false down(Self, Xd) == newINTERMEDIATELift, oldState = Self, offset = Xd,

isStopped == false, isUp == false)

constructeurssecondaires

Les constructeurs secondaires sont des extensions exprimees si possible en fonction des extensions issues des generateurs plut^ot que des methodes primitives.

ONFLOORLift

extensions

;; getOut : a weightable gets outside the cage getOut : ONFLOORLift Weightable ?! ONFLOORLift

var: Xw : Weightable

requires: isIn(Self, Xw) == true

getOut(Self, Xw) == copy(Self, contents = remove(contents(Self),Xw))

Remarque: Le lecteur attentif aura remarque que les axiomes de la methode getOut sont

di erents de ceux associes a l'operationgetOutde l'axiomatique algebrique. La question a se

poser est "peut-on speci er de facon plus abstraite?". Oui sicontentsest de ni en fonction de oldState et getIn. Mais, puisque nous avons choisi une option par mono-generateur, toutes

les operations de nies pour la classe sont secondaires, elles se decrivent a partir de la structure.

observateurs

Les observateurs sont de nis a partir de la structure abstraite. Par exemple, ONFLOORLift

extensions

;; bottomLevel : bottom level of the lift bottomLevel : ONFLOORLift ?! Integer

isInstalled(Self) == true ==> bottomLevel(Self) == bottom(Self)

isInstalled(Self) == false ==> bottomLevel(Self) == bottomLevel(oldState(Self))

INTERMEDIATELift

extensions

;; bottomLevel : bottom level of the lift (bottomLevel3:, bottomLevel5:) bottomLevel : INTERMEDIATELift ?! Integer

bottomLevel(Self) == bottomLevel(oldState(Self))

Les methodes privees commeisInne se trouvent pas dans la partie interface (features) de

la classe racine, ni des sous-classes. La description complete des classes se trouvent en annexe C.6.

7.5.1 Comparaison et generalisation de methodes

Si la comparaison de methodes est indecidable, une de nition axiomatique est plus faci- lement comparable. Six criteres permettent de comparer les methodes: nom, nombre de pa- rametres, noms et types des parametres type resultat, categorie (observateur, constructeur, primitif, secondaire), axiomes. Le niveau de compatibilite est fonction des variations de pro ls et d'axiomes:

{ La compatibilite est semantique lorsque seul le receveur varie. Si les axiomes peuvent ^etre uni es, la methode est mise dans la super-classe, (exemple:topLevelSTO PPED Lift,

limitsLift). Dans le cas contraire, la methode reste abstraite mais une optimisation sera

de degager une sous-partie commune. Exemple:l ev el

O NFLO O RLiftest une extension dans

TLLiftet un selecteur de champ dans MLLift.

{ La compatibiliteest de resultat si le receveur et le resultat varient. La methode est de nie avec le plus petit pro l commun.Exemple:r estar t

STO PPED Lift,

ar r iv ed

INTERMED IATELift).

Il y a union des axiomes.

{ La compatibilite est de parametre lorsque le receveur et soit le type soit le nombre de parametres varie. La methode commune doit suivre la regle de sous-typage. La methode est de nie avec le plus petit pro l commun. Il y a union des axiomes.

{ Il y a surcharge lorsque seuls les noms de methode sont identiques. Le plus grand pro l est exhibe pour la methode principale a partir duquel les autres methodes sont exprimees. C'est par exemple le cas pour les selecteurs de champ conditionnels qu'on ne veut pas mettre dans une methode de creation.

{ La compatibilite de renommage est explicite. Il semble laborieux de comparer toutes les methodes, m^eme si le pro l est identique.

Dans notre cas, la comparaison porte uniquement sur les methodes de m^eme nom, ce qui simpli e la generalisation du comportement. De plus le cas de surcharge n'est pas possible puisqu'il s'agit des methodes d'un m^eme sous-type. Detaillons les cas ou pr ofil(op

subclass) < pr ofil(op

super class). Comme pour la restructuration des classes, une de nition par defaut est

donnee par union disjointe des axiomes et le concepteur doit exhiber une representation plus adequate. Les conditions communes aux axiomes deviennent des preconditions de la methode. Les preconditions communes a toutes les methodes sont ajoutees a la contrainte.

Class 1 Class 2

Super

axiom1 : cond1 ==> op(Self, X1,...,Xn) == u1 axiom2 : cond2 ==> op(Self, X1,...,Xn) == u2

op : Class1 T1 ... Tn -> R’ op: Class2 T1 ... Tn -> R’’

op: Class T1 ... Tn -> R

Figure 67 : Abstraction de methodes

7.6 Validation du ranement

Le fait de pouvoir de nir les methodes secondaires est en soi une premiere etape de valida- tion. La validation du ranement regroupe un ensemble de mesure qui permettent d'evaluer l'inter^et de cette methode de ranement selon la structure des types de donnees decrits, de mesurer la qualite des hierarchies de classe obtenues et les optimisations envisageables. Plus qu'une metrication rigoureuse, nous donnons quelques indices et criteres qui nous semblent important. En n la validation concerne la conformite entre le TAG et les classes formelles qui en decoule.

7.6.1 Domaine d'application de la methode

Selon la forme du TAG, la methode rigoureuse ou l'approche intuitive sera plus adaptee. Nous donnons ici quatre mesures statiques pour evaluer si l'approche constructive est la plus adaptee.jsjdesigne la cardinalite de l'ensemble s.

1. Le nombre d'etats est important.

2. Il existe un taux minimal R@ d'operations partielles. j@j

jF j

> R@

dans la pratique, R@= 0:4 semble susant.

3. Il existe un taux minimalde rede nition des methodes sur plusieurs etats RK, (dom(op) = fk2K;9k

0

2K;g2(k;op;g) = k 0

gc'est-a-dire que le schema d'utilisation comporte

plusieurs niveaux intermediaires .

P op2@ jdom(op)j j@j > RK  dans la pratique, RK  = 1:5 semble susant.

4. Le schema d'utilisationest equilibre(nombre de niveaux intermediaires vis-a-vis du nombre de classes terminales Rbal = 1=3).

C K > Rbal

ou C est le nombre de classes d'equivalences de nies par la relation d'equivalence opi 

opj

,dom(op

i) = dom(opj).

Dans les experimentations realisees, ces criteres sont veri es. Dans l'exemple de l'ascenseur, les valeurs obtenues sont (1) = 23, (2) 12=18 = 2=3 > 0:4, (3) 70=23 > 12=6 et (4) 5=11 > 1=3.

7.6.2 Evaluation du resultat