Ces ajouts syntaxiques ne sont pas encore utilises dans la construction des axiomes mais nous avons constate sur des exemples qu'elles simplient l'axiomatique en regroupant des paquets d'axiomes et simpliant les predicats d'etats et les preconditions.
5.6.2 Heritage
L'heritage de TAG est souhaitable pour construire incrementalement des specications, partager les axiomes et classer les specications en hierarchies de specialisation. Comme nous l'avons decrit dans la section 2.3.1,l'heritage est une notion complexe, qui couvre a la fois le sous- typage, le ranage, l'extension ou la redenition. Dans les approches theoriques [Bre91, CO88, PPP91], l'heritage est deni comme une inclusion de modeles satisfaisant les specications, munie d'un morphisme entre les signatures, plus ou moins forte selon qu'on considere des specications completes ou non, le sous-typage ou non. L'heritage peut aussi ^etre vu comme une inclusion de langages engendres par les automates. Dans un premier temps, nous nous s'attacherons a l'aspect fonctionnel des TAG. Nous souhaitons une relation pratique et veriable pour les actions suivantes:
- renforcer la contrainte,
- renforcer la precondition d'une operation,
- restreindre un type de la relation d'importationuse a un sous-type,
- restreindre le type du parametre formel.
Les deux derniers cas sont equivalents si la genericite est simulee par l'heritage. Dans ce cas, les prols des operations concernees seront substitues.
Nous souhaitons aussi que l'heritage impliquele sous-typage en respectant le principe de sub- stitution: \toute operation applicable au super-type est applicable au sous-type"5. Le contr^ole
de type et le polymorphisme ne seront pas etudies ici. Les solutions adoptees pour les classes for- melles peuvent ^etre adaptees aux TAG (voir section 6.5). Quatre cas d'heritage sont denombres pour les specications algebriques:
1. extension: specialisation d'une specication completement denie (e.g. Pixel inherit Point), 2. concretisation: specialisation d'une specication incomplete (e.g. Natural inherit Compa-
rable),
3. ranage: changement de representation (e.g. SetList inherit Set),
4. duplication: denition par renommage des sortes et des operations (e.g. HospitalQueue inherit FIFOQueue).
Contrairement aux classes, les axiomes sont pas aectes directement aux operations. Nous uti- liserons les termes generiques sous-specication et super-specication de la relation d'heritage. Les quatre cas ci-dessus se resument a deux situations: si la super-specication est niment engendree alors c'est uneextensionsinon c'est uneconcretisation. Les specications non -
niment engendrees correspondent aux classes abstraites des modeles a objets i.e. sans construc- teurs de base. Les solutions ci-dessous sont applicables pour une evaluation par valeur. Les axiomes relatifs a une operation sont mis dans une seule specication.
PLUSS [BGM87] separe specications completes et incompletes mais ne denit pas d'heri- tage de specications completes. OBJ [FGJM85] denit uniquement le sous-typage strict, par inclusion d'ensembles supports. La notion de sous-classe en GSBL [CO88] correspond a l'heri- tage bien que les auteurs distinguent denitions completes et incompletes de sortes ou m^eme d'operations. Le sous-typage d'OS/OP [Bre91] est une notion plus forte que la concretisation des TAG, car elle est denie sur des specications de classes completes, tandis que l'heritage d'OS/OP est equivalent a l'extension. Dans le langage NDL [PPP91], les auteurs separent sous-typage, heritage de specialisation et heritage d'implantation. La dierence entre les deux premiers porte uniquement sur une partie interface de classe, correspondant a des operations redenissables dans les sous-classes.
Heritaged'extension
Dans OS/OP, l'heritage est un morphisme de signature (renommage) de la specication anc^etre vers la specication heritiere et une inclusion de modeles. Notre denition est plus contraignante et plus proche de la notion de coercition de type [CW85], qui permet de reutiliser une operation denie dans une super-specication. Pour denir l'heritage d'extension, nous utilisons une fonction d'abstraction de la sous-specication vers la super-specication.
Denition5.6.5 (heritaged'extension)
Soientspec 1= ( TI 1 ;S 1 ;? 1 ;' 1 ;X 1 ;E 1)et spec 2= ( TI 2 ;S 2 ;? 2 ;' 2 ;X 2 ;E 2)deux specications TAG. spec
1 herite par extension de spec
2 si et seulement si il existe une fonction surjective f abst: T TI 1 !T TI 2 telle que 8t 1 2T TI 1 ; 9t 2 2T TI 2 f abst( t 1) = t 2 5
La preuve de l'heritage d'extension se fait en exprimant chaque generateur de la sous- specication commeune extension6des generateurs de la super-specication. Prenons un exemple:
un client de la banque est une personne ayant un numero de client. Une personne est modelisee en TAG par un automate a deux etats (A : anonymous, N: named). Un etat est ajoute dans l'automate du client, signalant la presence d'un identiant de client. Les specications TAG correspondantes sont les suivantes:
name : Person ! String
anonymous : ! Person
rename : Person String ! Person
equal : Person Person ! Boolean
A : Person ! Boolean
N : Person ! Boolean
// = f anonymous, rename g - deux generateurs //
// @ = f name g - operation definie sur l'etat N //
// S f Person, Boolean, Stringg // 8 p : Person; n : String
A1: A(anonymous) == true A2: A(rename(Self, n)) == false N1: N(anonymous) == false N2: N(rename(Self, n)) == true
name1: A(Self) == true ==> name(rename(Self, n)) == n name2: N(Self) == true ==> name(rename(Self, n)) == n equal1: equal(anonymous, p) == A(p)
equal2: equal(rename(Self, n), p) == N(p) AND equal(n, name(p))
anonymousC : ! Client
rename : Client String ! Client
setId : Client Nat ! Client
id : Client ! Nat
// f anonymousC, rename, setId g: trois generateurs //
// @ f id g: operations definies sur l'etat C // 8 p : Client; n,n's,s': String; i : Nat
C1: C(anonymousC) == false C2: C(rename(Self, n)) == C(Self) C3: C(setId(Self, i)) == true
id1: N(Self) == true ==> id(setId(Self, i)) == i id2: C(Self) == true ==> id(setId(Self, i)) == i
id3: C(Self) == true ==> id(rename(Self, n)) == id(Self)
Montrons maintenant que la specication des clients herite par extension de celle des per- sonnes. Soit la fonction d'abstraction suivante:
8 Self : Client, n,s : String, i : Nat,
absClient!Per son(anonymousC) = anonymous,
absClient!Per son(rename(Self, n)) = rename(absC lient!Per son(Self), n),
absClient!Per son(setId(Self, i)) = absClient!Per son(Self).
La fonction abs
Client!Per son est surjective, compte tenu de la contrainte et des precon-
ditions, car les generateurs ont les m^emes domaines de denition. L'evaluation du terme clos suivant est alors possible, via la fonction d'abstraction.
name(setId(rename(anonymousC, 'Ted'))) // name defini dans Person //
) name(abs
Client!Per son(setId(rename(anonymousC, 'Ted')))) // abstraction //
) name(abs
Client!Per son(rename(anonymousC, 'Ted'))) // application de abs //
) name(rename(abs
Client!Per son(anonymousC), 'Ted'))) // idem //
) name(rename(anonymous, 'Ted'))) // idem //
) 'Ted' // name1 //
QED.