You are on page 1of 22
CASL: un langage de spécifications axiomatiques Mare Aiguier Laboratoire de Méthodes Informatiques, Université Evry-Val-d’Essonne, Cours Monseigneur Roméro, F-91025 Evry codex, email: aiguier@lami.univ-evry.fr Draft d de.t du DEA, ve “Pinkormatique de Tuniversité d’Evry-val-d’Essonne. 1 Introduction Te langage de spécifications présenté dans ce cours est fondé sur la théorie des spécifications dites algébriques. Les spécifications algébriques sont un moyen de spécifier le comparte- ment d’un systeme via les structures de données qu’il manipule, Plus généralemenent, les spécifications algébriques appartiennent: & une famille de langage de spécifications dites dax- jiomatiques». Pour ce style de spécifications, le comportement se définit, alors en énongant: les propriétés (aussi appelées axiomes) que Pon attend de ce dernier, Dans le cadre qui nous intéresse, ces propriétés sont statiques, c’est-&dire, sont valident quelque soit Pétat courant du systéme. Usuellement, un formalisme de spécifications axiomatiques se caractérisent par une syntane, une sémantigue et un systéme formed: La syntaxe fournit les ragles de constructions du langage. De la méme maniére que pour un langage de programmation, la syntaxe un langage formel se caractérise par une partie fixe et une partie ou tout au moins dont la traduction dans un langage de programmation domné soit naturelle ou sans difficultés notoires, et de permettre en plus de contréler qu’A chaque étape d’implantation, les spécifications obtenues sont dcorrectes> vis-a-vis de leurs prédécesseurs (i.e, conservent le comportement). Le langage CASL (Common Algebraic Specification Language) est done un langage de spécifications axiomatiques dont le formalisme de base est la logique des prédicats du pre- mier ordre avec égalité. Au travers de ce langage, nous étudierons le moyen d’écrire des spécifications de logiciels dans un style axiomatique (ie. en énongant les propriétés que Pon attend du logiciel). Dans un premier temps, nous introduirons la syntaxe nous permettant déctire des spécifications éémentaires (je. sans structuration). Enfin, nous étendrons ce langage afin de permettre la structuration de spécifications par union, enrichissement: et paramétrisation. 2 Spécifications élémentaires en CASL Dans cette section nous allons donner la syntaxe permettant: de déclarer une spécifica- tion élémentaire (i.e. sans structuration). I existe une présentation de la syntaxe sous forme Pune grammaire BNF (cf. “CoFI Document: CASL /Summary” disponible A Padresse “http://www.brics.dk/Projects/CoF1/Documents/CASL/Summary/”). Ici, nous nous com tenterans dune description plus abstraite afin de faciliter la lecture des différents éléments de la syntaxe introduits. Succinctement, la déclaration dune spécification de base en CASI. a la forme générale suiv- ante: spec Nom de la specification = sort(s) . type(s) « op(s) « pred(s) . var(s) axiom(s)... end (Attention, Pordre imposé ici est totalement arbitraire. Le seul suivi par CASI est linéaire.) Les parties sort(s) et type(s) définissent: les types de données manipulés par le systéme A spécifier. La partie op(s) déclare les opérations associées & ces différents types de données précédemment décrits. La partie pred(s) déclare les prédicats. Enfin, la partie var(s) déclare les variables globales la spécification. L’ensemble de ces cing parties forme ce que Yona Phabitude Pappeler dans les formalismes de spécifications une signature, La derniére partie d'une spécification en CASL définit le comportement des opérations et des prédicats au moyen de formnles du premier ordre usuellement appelées aniomes. Dans la suite, pour illustrer toutes nos constructions, nous spécifierons a titre d’exemple le type de données des entiers nature muni de addition et de la relation binaire <. 2.1 Les signatures en CASL Comme on vient de le wir, en CASL une signature se définit en déclarant: des sortes, des types, des opérations et des prédicats. Comme on va Ie constater, ces parties ne sont pas indépendantes entre elles, dela méme maniére qu’elles ne sont: pas indépendantes de la partie axiomes. 2.1.1 Les sortes es sortes sont Jes noms des différents types de données manipulés par le systéme, En CASL, deux types de déclaration de sartes sont permises: 1. Déclaration simple = Dans une déclaration simple, on énonce simplement les noms de sortes de la fagon suivante: sort(s) 815 825-5 Sn oi chaque s; est une chaine de caractéres dénotant un nom de sorte. Exemple 1 Pour notre exemple sur les entiers naturels, nous avons alors : sort Nat 2. Déclaration contrainte - Dans une déclaration contrainte, nous associons en plus & chaque sorte un ensemble de constructeurs et éventuellement des observateurs et. des destructeurs (appelés plus génériquement selecteurs par les CASListes) dont la défini- tion est directe par rapport A ce constructeur (voir ci fuhs chaque fg (1 (2) Sin Aity eee 9 Ait Succinctement, une telle définition déclare J; (1 < i (?)5i, le symbole “?” signalant le cété partiel ou non des opérations fip, ainsi que de la liste des propriétés (appelées attributs par les CASListes) Aa,... , Az, Ces propriétés ne sont pas valides pour tous les types d’opérations. Elles ne peuvent: étre satisfaites que pour des opérations @arité 2 (ie. munies d’un profil de la forme s1 x s2 > ()s). Elles affectent (quand elles existent) aux opérations fp les propriétés suivantes: # Passociatinité f(x; f(y»2)) = f(U(@sy)s2) = dans ce cas fa, on écrit. assoc pour Pattribut concerné. © Ja commutativité f(x,y) = f(y,2) - dans ce cas la, on écrit comm pour Pattribut concerné. # Pidempotence (2,2) = 2- dans ce cas la, on écrit idem pour Pattribut: concemé. * existence d’un élément neutre t a droite et A gauche f(2,t) = f(t,2) = 2 - dans ce cas 1a, on écrit: unit ¢ pour Pattribut: concemé. Ici, ¢ est un terme clos defini uniquement a partir des opérations de la signature. Les différentes équations décrites cidessus sont satisfaites de fagon forte. Exemple 3 Pour notre exemple des entiers naturels, deur ans peuvent se présenter : (a) dans le cas oi la sorte Nat: a été déclarée de facon globale, les opérations de la signature se déclarent de la facon suivante: ops 0: Nat; succ : Nat > Nat +: Nat x Nat > Nat (8) dans le cas oii la sorte Nat a été définie par un type de données, comme les constructeurs ont déja été introduits, la partie op est alors réduite a la déclaration de Vopération +: op +: Nat x Nat > Nat Maintenant, il est naturel d’ajouter pour Vaddition les propriétés cidessus excepté Pidempotence. On substitue alors la définition de Vopération ++ dans les deux déclara- tions précédentes par la suivante: +: Nat x Nat — Nat, assoc, comm, unit 0 7 2. Par définition - OP, est de la forme: Filthy thay 8s ithyee sth $n) | CDS = bi of Uy, (1 < k (2)5: par Péquation forte: fi(vi, ct ms Exemple 4 [ci Vopération + pourrait se définar de la fagon suivante : Pram +(a,y: Nat) : Nat = x when y = 0 else suco(+(a,pred(y))) Attention, la spécification de Uaddition donnée ici est loin d’étre complete. En effet, son comportement nest pas préw en 0. 2.1.3 Les prédicats De la méme manire que pour les sortes et les opérations, les prédicats peuvent se déclarer aussi naturellement par déclaration et par définition (n’oublions pas que l’on peut toujours voir un prédicat comme une fonction de sorte codomaine dans les booléens). La syntaxe générale pour déclarer les prédicats est alors la suivante: pred(s) Predl;... ; Pred, oft chaque Pred; (1 sueo(x) < suce(y))) < (wy: Nat) => (@=0V (“1 (le signe V signifie le “ow'logique). 2.2 Les axiomes en CASL CASE est: un langage de spécification dont la logique de base est Ja logique des prédicats du premier ordre avec égalité. Les axiomes sont alors des formules définies sur ce langage. Ellles sont: donc des constructions inductives dont les premiers éléments syntaxiques sont les termes eux-mémes définis inductivement a partir des opérations du langages et un ensemble de variables. 2.2.1 Les variables Tes variables sont des éléments syntaxiques dénotant des valeurs génériques. En CASL, on déclare les variables de trois fagons : 1. globalement = dans ce casa on écrit: Vars U).-+ Yim 2815 Dray ++ 2Urmn £m oi chaque vj; (1 < i< net 1 (2)s est une opération de la signature et chaque t; est un terme bien-formé de sorte ;; «© terme conditionnel - t when ¢ else to tet! sont deux termes bien-formés de sorte set g une formule bien-formée. A chacune des étapes ci-dessus, le terme ¢ ainsi défini est: de sorte s. On le note alors t : s. 2.2.3 Les fornmles es formules se definissent inductivement par Jes constructions suivantes: © formules constantes - true et. false; © définissabilité - def tou test un terme bien formé. Cette formule est vraie sil”évaluation du terme t rend une valeur. © formules équationnelles elles sont de deux sortes: 1. existenticlle -t £#' oi t: s et t! +s sont deux termes bier-formés. La satisfaction Pune telle équation se fait de fagon existentielle; 2. forte -t=t oiit: s et tz sont deux termes bien-formés. La satisfaction d’une telle equation se fait de fagon forte. © formules prédicatives - p{try... stn) 08 ps1 % ... Sq est un prédicat et chagque f; : 5; (1 suad(z) < succty) Dans le cas oni le type Nat a été défini comme free, nous n’avons pas besoin de spécifier le fait que le prédicat < est un ordre. Ceci est une conséquence des ariomes ci-dessus en tullisant le raisonnement par induction sur ln structure des termes. Maintenand, dans le cas contraire, nous devons ajouter les aziomes supplémentaires suivants : © 2 2=y (antisymmetric) oe 2 liste; téte : liste elem; queue : liste ~ liste; @:: liste x liste ~ liste, assoc, unit nil; long : liste > nat; 0:->nat; +1: nat ~ nat téte(cons(e,!) queue(nil) = nil queue(cons(e, )) = 1 Q(nil,1) =1 Q(cons(e, 1,1") = cons(e, @(0,1’)) Long(nil) =0 Zong(cons(e,1)) = long(l) +1 ee nil <=> false €€ cons(e,i) => (e =e) V(“(e=e) AcE) vide?(D) <=> 1= nil Contrainte spec Liste d éléments = sortes elem free types nat | _ + U(nat); liste ::= nil | cons(téte : elem?, queue: liste) ops (I: liste @ I’: iste) : liste = ! when 1 = nil else cons(téte(2), queue(2)), assoc, unit nil; long({ : liste) : liste = 0 when = nil else long(queue(2)) +1 preds e:elem€ I: liste => -(1 = nil) \ ((e = téte(2)) V ((e = téte(0)) Ae € queve()))) vide?(: liste) <=> 1= nil axioms -(def téte(nil)) queue(nil) = nil 2.3.2 Les piles Sans contrainte spec Pile d’eléments = sortes pile, elem,nat ops pile_vide:~» pile empiler: elem x pile ~ pile sommet : pile—y?elem hauteur : pile nat O:>nat _ +1: nat ~ nat pred vide? : pile axioms depiler(pile_vide) = pile_vide Ve: elem, VP : pile, depiler(empiler(e, P)) = P =(def sommet(pile_vide)) Ve: elem, VP : pile, sommet(empiler(e, P)) =e =0 le hauteur epier(P) = hauteur(P) +1 vide(D) 2=> P= pile vide Contrainte spec Pile d’édéments = sortes elem free types nat :=0| _ +1(nat); ile == pile_vide | ener sone Liste pred vide?(P liste) <=> P = pil axiom -(def sommet(pile_vide)) — 2.3.3 Les files Sans contrainte uu spec File d’eléments = sortes file, elem,nat retirer : file> file premier : file —r?elem long: file > nat O:> nat _+1:nat — nat pred vide? : pile axioms retirer( file_vide) = file_vide Ve: elem, retirer(ajouter(e, file_vide)) = file_vide Ve,e’: elem, VF : file, retirer(ajouter(e,ajouter(¢, F))) = ajouter(e, retirer(ajouter(?, F))) Ve : elem, retirer(ajouter(e, file_vide)) = “(def premier( file_vide)) Ve,e : elem, VF: file,premier(ajouter(e, ajouter(e!, F))) = premier(ajouter(¢, F)) long( file_vide) = 0 Ve : elem, VF : file, longajouter(e, F) = long(F) +1 vide(F) <> F = file_vide Contrainte spec File d “éléments = sortes elem free types nat + U(nat); File ::= file_vide | ajouter(elem, iste) ops retirer : file file premier : file elem long F : file) : liste =0 when F = file_vide else longvetirer(F)) +1 pred vide?(F: liste) <=> F = file_vide axiom retirer(file_vide) = file_vide Ve: elem, retirer(ajouter(e, file_vide)) = file_vide Ve,e!: elem, VF: file, retiner(ajouter(e, ajouter(e’, F))) = ajouter(e,retirer(ajouter(¢, F))) Ve: elem, retirer(ajouter(e, file_vide)) = = (de f premier(file_vide)) Ve, e!: elem, VF: file, premier(ajouter(e, ajouter(e, F)) = premier ajouter(e!, F)) 3 Sous-typage et surcharge Test usuel en informatique comme en mathématique que certains types de données soient des sous-types d’autres types de données, c’est-tdire, il existe une relation d’inclusion 15 entre ces types A renommage prés (appelée usuellement plongement et caractérisée par une application injective entre ces deux ensembles). Bien entendu, cette relation de sous-typage peut s“étendre aux fonctions de la fagon suivante: si f : A> Best une application, @ CA et BC Dalas f est dite étre en relation de surcharge avec I’application g : C —> D definie par g(¢) = f(c) pour tout ce C. En CASL, il existe une construction permettant de spécifier une telle relation entre les sortes, de la signatures. Cette nouvelle construction permet. done de déclarer qu’une sorte est une sous-sorte d’une sorte donnée. Dans la partie sort(s), coci se déclare de deux fagons: ¢ simplement en énongant la relation de sous-typage A V’aide du symbole <. Dans ce casa on écrit : Sty yin <8 Une telle déclaration spécifie alors que les supports associés aux sortes 5; (1 (?)s est une opération de la signature et chaque t; est un terme bien-formé de sorte s} < si; © terme conditionnel - t when ¢ else toi tet! sont deux termes bien-formés de sorte et «tel qu’il existe une sorte s” satisfaisant A la relation 3,4’ < "et y une formule Dien-formées © coercion - # as s ot s est une sorte et # est un terme de type s! > s. Sa signification sémantique est alors une fonction partielle f Pun support de la sorte s’ vers un support de la sorte s qui projette, étant donnée une interprétation des variables du terme t, Vévaluation du terme ¢ dans la sorte s. En ce sens, on peut retraduire de fagon équivalente une telle construction par la définition de sorte suivante: s = {v: seu =#}. ‘A chacune des étapes ci-dessus, le terme t ainsi défini est de sorte sf pour n’importe quelle sarte s! telle que s! < s. On le note alors t: #. ‘Au niveau des formules, la répercussion se caractérise par l’ajout de formules atomiques de Ia forme: tes Dont la signification sémantique est que I’évaluation du terme t : # oi s < # rend une valeur de type s (c-i-d. I’évaluation de ¢ rend une valeur qui est pris dans le plongement du support de s dans le support de #. Exemple 12 Pour spécifier les sous-sortes Paire et Impaire on peut écrire les trois axiomes suavanits : 0€ Paire Ve: Nate x € Paire <=> suce(sucd(z)) € Paine Ve: Nate x € Impaire <=> -(z € Paire) 4 Structuration de spécifications De la méme fagon que pour les langages de programmation, dés que “on veut: spécifier un logiciel de taille réelle il est important que le langage de spécfication utilisé pour cette tache dispose de constructions permettant. de spécifier le comportement globale dun logiciel via la spécification des composants de spécifications (appelés usuellement modules de spécification) qui le compose, Pour cela, nous avons deux moyens de structurer les spécifications : de fagon ‘modulaire ou par paramétrisation, Dans le premier cas, on établit une hiérarchie arborescente entre les différents modules dont la signification sémantique d ‘une branche est la réutilisation de modules. Intuitivement, la réutilisation exprime le fait: qu’un module utilisé ne voit: pas son comportement altéré par un utilisateur. Dans le cas d’une approche axiomatique, le comportement de la partie utilisée peut-étre altéré de deux fagons: i 1. soit su-spécification lors de I“enrichissment des entiers naturels en piles d “entiers on peut par exemple vouloir spécifier une borne Maz sur la hanteur des piles de telle fagon & ce que tout nouvel ajout sur une pile pleine soit ignoré, On écrirait alors I’axiome suivant: hauteur(P) = Max => empiler(e, P) = P De lA, on déduit alors facilement la propriété suivante: hauteur(P) = Max => hauteur(empiler(e, P)) = hauteur(P) = hauteur(P) +1 2, soit par sous-spécification: toujours dans le cas de la spécification des piles d “éléments, on oublie de spécifier le comportement: de l‘opération hauteur sur la pile vide. On a alors dénoté un nouvel entier hauteur(pile_vide) que I’on ne sait pas ramené & un entier usuel. La parmétrisation permet quand a elle de spécifier le comportement générique d“un type de données en faisant une abstraction du comportement, complet dun de ses types. ceci permet une économie de développement dans le sens oi nous spécifions un type de données modulo tout parametre répondant au comportement abstrait, attendu par ce type de données. est le cas par exemple, lorsque nous spécifions des listes d’éléments. Le comportement des listes est indépendant des éléments qui les composent. 4.1 Modularité au sein des spécifications ‘Au sein du langage CASI plusieurs constructions liées a la structuration sont disponibles. Tei, nous en présentons deux: I’enrichissement et V’ union. 4.1.1 L’enrichissement Dans Ie cas de Ienrichisssment, I’arbre structuration est simplement linéaire. Usuellement, une étape d’enrichissement: consiste en Vajout de nouvelles sortes et de nouvelles operations, ainsi que ‘ajout d’axiomes pour caractériser le comportement des ces nouvelles opérations. On le note SP + ASP od SP est une spécification de base (3, Ax) et ASP = (AY, AA) est I’enrichissement. En général, AS = (AS, AF) n’est pas une signature. C“est seulement BUA = (SUAS, FUAF) qui lest. La spécification resultante SP!= SPU ASP denote V’enrichissment. On le notera SP + SP’, En CASL, la syntaxe pour une telle structuration est la suivante: SP, then ... then SP, ‘SP, est une spécification de base et chaque SP; pour 2 < i SPU (USP). Ri Ki 18 Exemple 13 On peut par exemple écrire la spécification des listes d“éléments comme un enrichissement de la spécification des entiers naturels , ona d'abord déclarer la spécifications des entiers naturels de la facon suivante : spec Entiers naturels free types nat «= 0 /_+1(nat); ops _ + _: nat x nat — nat ‘n:nat er +0=2 Va,y:natez+(y+1)=(z+y)+1 axioms end spec Liste d’éléments = Entiers naturels then free types liste ::= nil | cons(téte : elem’, queue : liste) ops (I: liste @ #: liste) : liste =U when 1 = nil else cons(téte(2), queve(|)), assoc, unit nibs Longl{t: liste) : liste = 0 when 1 = nil else long(queue(2)) +1 preds ¢: elem € 1: liste <=> —(1 = nil) A ((e = tete()) V (~(e = tete(!)) Ae € queue())) vide2(L: liste) <=> 1= nid axioms “(def téte(nil)) queue(nil) = nil La sémantique associée a une telle construction est alors la classe de tous les modéles de Ia spécification SP, U (LU) SP;) tels que leur “publi” sur Ja signature 3, U (()¥;) est un a Ki modéle de la classe des modéles associés a la spécification SPU (LJSP;). In’y a pas ia d’amnotations syntaxiques obligeant l’enrichissement d’étre conservative (c-ad., sans sur- spécification et sous-spécification) en CASL. Ceci vient du fait que cette contrainte est in- décidable en générale. Fle ne peut done étre vérifiée que manuellement. Elle consiste alors Aregarder quancun modéle n est perdu: tout modéle de la partie étendue a an moins pour réduction un modéle de la partie étendue. Cette condition est: moins forte que celle exprimée précédemment dans le sens oi elle n’établie qu’une conservation du comportement: de la spécification et non pas des modéles eux-mémes. En fait, cette derniéres condition n’a de sens que dans le cadre de spécifications dont les axiomes sont des clauses de Hames (voir le cours d‘option du DEA d’informatique de I’université pour plus @informations). 4.1.2 L’union L’union permet de mettre ensemble des spécifications pour en faire une plus grosse. En CASL, elle se définie de la fagon suivante: SP, and... and SP, ott chaque SP; (1 boo; _twedge_,_V _: boal x bool —» bool Va: bool ex false = false Vaea A true=2 axioms VOY: boolex\y=yhz Var bool e 2 V tru Ve! bool 2 false Va,y:boolervy =yVa end spec Ensemble d’ééments = Entiers naturels and Booléens then sort Elem free types Ens :=0) | ajouter(elem, Ens) ops retirer : Elem x Ens» Ens LL]: Ens > Nat _€_: Elem x Ens > Bool axioms tetirer(0) = 0 Vex’: Elem;E': Ens e retirer(c,ajouter(¢’,)) = E when e = ¢ else ajouter(¢,retirer(e, E)) [0] =0 Ve: Elem; \/: Ens |ajouter(e, B)| = \2]+1 ec0= false Ve,e': Elem;vE': Ens ee € ajouter(e’, E) = true when e =e! else e€ E Ve: Elem;\/E: Ens « ajouter(e, ajouter(¢’, B)) = ajouter(¢, B) when ¢ = ¢ else jouter(¢!,ajouter(e, E)) 4.1.3 Paramétrisation Ce type de structuration permet de spécifier le comportement d’un type de données en abstrayant certains des types de données qu ‘il utilise au simple comportement dont il a besoin pour se définir. Le comportement du type ainsi défini est alors générique. 20 Définition de spécifications génériques En CASL, la généricité s“obtient en associant une liste de parametres a la spécification que nous sommes en train de définir. Une spécification générique se déclare alors de la fagon suivante: spec Nom de la specification [N P,]...[N Pa] = sort(s) Chacun des IVP, est soit le nom soit le carps dune spécification. Exemple 15 Ce type de construction est trés utile pour déclarer des structures récursives comme les listes, les piles, les files, les arbres, etc. utilisées pour stocker des informations de méme nature mais dont le comportement importe peu. Par exemple, en reprenant notre exemple sur les listes, on abstrait le comportement des éléments en ne donnant aucune opéra- tion et done aucun aziome sur ces derniers. Maintenant, les éléments pourvaient étre aussi bien des entiers, des chaines de caractéres ou encore des listes d’éléments. C'est par une opération d ‘instantiation que l’on pourra traiter ces différents types de listes sans pour cela redéfinir une noweelle spécifieation. Les listes génériques se définissent alors par la spécifi- cation suivante : spec Elem = sort elem spec Liste d’éléments [Hlem| free types nat ::=0| _ +1 (nat); liste ::= nil | cons(téte : elem? queue: liste) ops (I: liste @ #: liste) : liste =U when 1 = nil else cons(téte(2), queue(|)), assoc, unit nibs long(t : liste) : liste = 0 when 1 = nil else long(queue(2)) +1 preds ¢: elem € 1: liste => -(I = nil) \ ((e = #te(I)) V (“(e = téte(1)) Ne € queue(D)) vide?({: liste) <=> = nil axioms “(def téte(nil)) queue(nil) = nil Instantiation des paramétres L’instantiation des paramétres consiste a définir un morphisme de signatures entre les signature des spécifications IVP; et la signature de leur instantation, Fn CASL, ceci se déclare via le mot clé fit de la fagon suivante: Nom de la spécification générique [VP fit morphisme de signature] 21 Le morphisme de signature se définie au moyen de “++” qui établie une comespondance point A point entre les différents éléments de la signature (c-érd., les sortes, les opérations et: les prédicats). Exemple 16 On peut par exemple instantier la spécification Elem par celle de Nat, Pour cela, nous devons simplement faire correspondre la sorte elem é la sorte nat. Liste d“éléments [Nat fit elem ++ nat]

You might also like