La proximite semantique des classes est dicile a mesurer. Nous denissons 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 prols 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 signicatif de notre point de vue, car les methodes des dierentes classes formelles sont issues des operations d'un unique TAG. Nous avons envisage une comparaison sur les prols des methodes pour prendre en compte un eventuel renommage, mais le resultat ne s'est pas avere payant (bon nombre de methodes dierentes ont le m^eme prol, deux methodes representatant la m^eme operation ont en general un prol (specique) dierent., 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. Enn, 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 dierencies 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
denie 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 specication 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 denie. 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 specication 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 denis 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
dierents de ceux associes a l'operationgetOutde l'axiomatique algebrique. La question a se
poser est "peut-on specier de facon plus abstraite?". Oui sicontentsest deni en fonction de oldState et getIn. Mais, puisque nous avons choisi une option par mono-generateur, toutes
les operations denies pour la classe sont secondaires, elles se decrivent a partir de la structure.
observateurs
Les observateurs sont denis 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 denition 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 prols et d'axiomes:
{ La compatibilite est semantique lorsque seul le receveur varie. Si les axiomes peuvent ^etre unies, 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 denie avec le plus petit prol 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 denie avec le plus petit prol commun. Il y a union des axiomes.
{ Il y a surcharge lorsque seuls les noms de methode sont identiques. Le plus grand prol 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 prol est identique.
Dans notre cas, la comparaison porte uniquement sur les methodes de m^eme nom, ce qui simplie 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 denition 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 denir 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. Enn 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 redenition 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 denies par la relation d'equivalence opi
opj
,dom(op
i) = dom(opj).
Dans les experimentations realisees, ces criteres sont veries. 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.