Vous êtes sur la page 1sur 12

Table des matières

Avant-propos V
1 Introduction 11
1.1 Qu’est-ce que le cycle des logiciels ? 11
1.2 Qu’est-ce que le modèle en cascades ? 12
1.3 Qu’est-ce qui distingue l’analyse et la spécification de la conception ? 13
1.4 Pourquoi l’étape d’analyse et spécification est-elle importante ? 16
1.5 Que signifie «Méthodes formelles» ? 18
1.6 Qu’est-ce qu’un langage formel de spécification ? 20
1.7 Pourquoi y-a-t-il plusieurs notations et méthodes différentes ? 21
1.8 Quels sont les principaux bénéfices des spécifications formelles ? 23
1.9 À quelles étapes du cycle de vie les méthodes formelles peuvent-elles être
utilisées ? 25
1.10 Existe-t-il des exemples d’applications industrielles développées à l’aide de
méthodes formelles ? 27

Première partie Le langage Spec 30


2 Propositions, quantifications et CONCEPTS 32
2.1 Logique propositionnelle 33
2.2 Prédicats, formes propositionnelles et quantificateurs 37
2.3 La notion de CONCEPT 46
2.4 Quantificateurs généralisés 55
2.5 Les modules DEFINITION et quelques notions associées 63
2.6 Remarques concernant les clauses WHERE 72
2.7 Utilisation des CONCEPTS et modules DEFINITIONS pour l’analyse du problème 73
2.8 Convention Spec pour les identificateurs 75
2.9 Sommaire 75

3 Types abstraits de la bibliothèque Spec 84


3.1 Types de base 85
3.2 Ensembles 89
3.3 Séquences 97
3.4 Dictionnaires (MAPS) 104
3.5 Énumérations 113
3.6 Tuples 114
3.7 Unions 116
3.8 Sur la notion de valeur 117
3.9 Sommaire 118

4 Formalisation de modèles conceptuels UML 134


4.1 La notation UML 134
4.2 Les diagrammes de classes d’UML 135
4.3 Formalisation de diagrammes de classes : Un premier exemple 140
4.4 Un exemple utilisant l’héritage 145
4.5 Un exemple illustrant la notion d’entité associative 146
4.6 Heuristique pour la formulation en Spec de diagrammes UML 148
4.7 Sommaire 152

5 Spécifications fonctionnelles et pré/postconditions (module FUNCTION) 166


5.1 Rôle des spécifications fonctionnelles 166
5.2 Spécifications fonctionnelles abstraites 170
5.3 Les diverses formes de module Spec 171
5.4 Des exemples de modules FUNCTION 175
5.5 Fonctions définies de façon complète ou de façon partielle 186
5.6 Sommaire 187

6 Machines abstraites (module MACHINE) 200


6.1 Des machines pour les accumulateurs 200
6.2 Des machines pour les piles 206
6.3 Une version simplifiée d’une banque 210
6.4 Une version simplifiée d’un club vidéo 217
6.5 Un contrôleur de machine distributrice 222
6.6 Un contrôleur de four micro-onde 230
6.7 Formes générales des messages et des réponses 236
6.8 Les diverses formes d’envoi de messages 241
6.9 Sommaire 246

7 Types mutables et immuables (module TYPE) 254


7.1 Des exemples de types mutables 254
7.2 Des exemples de types immuables 278
7.3 Utilisation d’objets par opposition à utilisation de valeurs : L’exemple des piles 288
7.4 Types mutables et classes d’objets (module CLASS) 294
7.5 Sommaire 302
8 Éléments additionnels de Spec 320
8.1 Règles de portée des identificateurs 320
8.2 Spécification des cas spéciaux et exceptionnels 326
8.3 Envoi de messages multiples avec la clause FOREACH 329
8.4 La notion de générateur 331
8.5 Événements, messages temporels et délais 333
8.6 Quelques heuristiques pour le développement de spécifications fonctionnelles 336
8.7 Les différences/similitudes entre machine, type mutable et type immuable 340
8.8 Conclusion : limites de l’approche de modélisation abstraite 342

Deuxième partie Une méthode rigoureuse de développement 347


9 Vérification de la cohérence interne et de l’absence de biais de mise en
œuvre 348
9.1 Rôle des invariants 349
9.2 Obligations de preuves pour vérifier la cohérence d’une spécification 351
9.3 Vérification rigoureuse de la cohérence interne d’une spécification :
deux exemples 357
9.4 Les notions de biais de mise en œuvre et de spécification suffisamment abstraite 361
9.5 Deux versions de la banque 373
9.6 Sommaire 376
10 Vérification du raffinement d’une spécification 384
10.1 Comportement observable et simulation 385
10.2 La notion de fonction d’abstraction 391
10.3 Obligations de preuve liées au raffinement d’une spécification 400

Troisième partie Une étude de cas 431


11 Un système de gestion d’une bibliothèque universitaire 432
11.1 Description narrattive des besoins et des exigences 432
11.2 Cas d’utilisation et modèle conceptuel 434
11.3 Interface du système : diagramme de flux des messages et squelette du système 440
11.4 Spécification détaillée du système 445
11.5 Vérification de la cohérence interne et de l’absence de biais de mise en œuvre 455
11.6 Sommaire 465

Quatrième partie Autres méthodes de spécification 469


12 La notation OCL d’UML 470
12.1 Les éléments de base de la notation OCL 471
12.2 Correspondance entre expressions Spec et expressions OCL 478
12.3 Formalisation de contraintes sur des diagrammes de classes UML 480
12.4 Description formelle de types mutables 485
12.5 Sommaire 491

13 VDM et Z 393
13.1 VDM 393
13.2 Z 506
13.3 Sommaire : remarques et conclusions sur VDM et Z 522
14 Spécifications algébriques 529
14.1 Types abstraits de données 529
14.2 Langages de spécifications algébriques : Larch et ACT ONE 530
14.3 Un premier exemple : les piles 531
14.4 Spécifications Larch (LSL) de quelques types abstraits 537
14.5 Un exemple de langage d’interface Larch : LCL 553
14.6 Pourquoi parle-t-on de méthode algébrique ? 559
14.7 Sommaire 563
15 Conceptions et programmation par contrats et utilisation d'assertions 571
15.1 La notion de contrat 573
15.2 Trois langages qui supportent les assertions : Eiffel, Java et C 575
15.3 Quand et comment utiliser les assertions 584
15.4 Sommaire 591
Annexe A Syntaxe formelle de Spec 595
A.1 Éléments de la notation EBNF 595
A.2 Les identificateurs et constantes 596
A.3 Syntaxe EBNF de Spec 597
Annexe B Version Ada de quelques modules 604
B.1 Accumulateurs 604
B.2 Piles non bornées 606
B.3 Piles bornées 608
B.4 Four micro-ondes 612
Annexe C Version Java de quelques modules 615
C.1 Type mutable pour des accumulateurs 615
C.2 Type mutable pour des piles bornées 617
C.3 Type immuable pour des piles non-bornées 619
Bibliographie 622
Index 630
1
INTRODUCTION
Qu’est-ce que les méthodes
formelles ?

Ce chapitre définit ce que sont les méthodes formelles de spécification et de


modélisation et tente d’expliquer pourquoi leur utilisation est intéressante.
Les différents points sont introduits sous forme de questions et décrivent ce
qu’est une méthode formelle, une spécification formelle, les caractéristiques
et les avantages de ces méthodes, etc. Le chapitre se termine en présentant
quelques exemples d’applications industrielles ayant été développées à l’aide
de méthodes formelles.

1.1 QU’EST-CE QUE LE CYCLE DE VIE DES LOGICIELS ?


La production d’un logiciel complexe nécessite plusieurs étapes et s’étend
généralement sur une longue période de temps. Le cycle de vie d’un logiciel
«c’est la période de temps qui débute au moment de la définition et du
développement d’un produit logiciel et se termine lorsque le produit logiciel
n’est plus disponible pour utilisation.» (Définition de l’IEEE) [IEE91]
À l’intérieur du cycle global de vie d’un logiciel, la période qui nous intéresse
plus particulièrement est celle associée au développement du logiciel. Le
cycle de développement d’un logiciel est généralement décrit et représenté
par un modèle du cycle de vie, c’est-à-dire par une représentation idéalisée et
simplifiée des principales activités ayant lieu durant le processus de
développement. Un modèle du cycle de développement tente donc de décrire
ce qui est censé se passer durant le développement d’un produit logiciel :
12 Modélisation et spécification formelle des logiciels

x Qu’est-ce qui sera fait ?


x Dans quel ordre les différentes tâches seront-elles réalisées ?
x Quand le processus sera-t-il terminé ?
Un tel modèle est utile car il fournit un vocabulaire de base commun à
l’ensemble des participants (utilisateurs, clients, gestionnaires, ingénieurs
du logiciel, etc.), grâce auquel ils peuvent communiquer entre eux et (on
l’espère) mieux se comprendre. De plus, et c’est sûrement là l’un de ses rôles
les plus importants, un tel modèle sert à rendre visible le processus de
développement. En d’autres mots, cela permet de rendre explicite les
différentes étapes du processus de développement et aide à mieux voir les
relations entre les différentes phases de ce processus. Cela crée aussi un
cadre permettant de mieux contrôler et gérer le développement du produit
logiciel.

1.2 QU’EST-CE QUE LE MODÈLE EN CASCADES ?


Un modèle de cycle de développement souvent utilisé est celui dit en
cascades (waterfall). Ses deux principales caractéristiques sont qu’il
segmente le cycle de vie en une suite d’étapes consécutives et qu’il met
l’accent sur la nécessité de définir et de bien spécifier le logiciel avant de le
réaliser. Ce dernier aspect signifie qu’il faut donc produire un document
approprié de spécification avant d’aborder les étapes de conception et de
développement.
Plusieurs variantes du modèle en cascades existent, celles-ci utilisent des
noms différents pour les diverses phases ou groupent les activités à
l’intérieur des phases différemment. De même, de nombreux autres modèles
du cycle de développement ont aussi été proposés, par exemple, modèle
itératif, modèle incrémental, modèle en spirale, etc. [Pre97]. Nous nous
restreindrons, ici, au modèle en cascades, notre objectif étant simplement de
faire comprendre la distinction entre spécification et conception — puisqu’on
retrouve ces notions dans la plupart des modèles —, et ainsi de bien faire
saisir le rôle des spécifications.
Le modèle en cascades que nous utiliserons comme modèle de cycle de
développement comporte les diverses étapes indiquées plus bas. Notons
toutefois que seules les deux premières étapes seront vraiment abordées
dans le cadre de ce manuel.
1 Introduction : Qu'est-ce que les méthodes formelles ? 13

1. Analyse et spécification.
2. Conception architecturale.
3. Conception détaillée.
4. Codification.
5. Tests.
6. Livraison et installation.

1.3 QU’EST-CE QUI DISTINGUE L’ANALYSE ET LA


SPÉCIFICATION DE LA CONCEPTION ?
«Un élément important pour n’importe quel système est le développement
d’une spécification adéquate. La spécification est le premier document qui
décrit les fonctionalités requises du système à développer pour un client. [La
spécification] ne devrait décrire que ce que le système doit faire (quoi ?), et
non pas décrire comment cela devrait être fait. Elle joue deux rôles vitaux :
celui d’un document contractuel avec le client décrivant ses besoins et
exigences, et celui d’un document prescriptif à partir duquel le concepteur
devra produire une solution.» [CHJ86]
Intuitivement, on peut dire que l’étape d’analyse et de spécification vise à
répondre à la question : «Que fera le système ?» (QUOI ?) alors que l’étape de
conception vise à répondre à la question : «Comment le système sera-t-il
construit ?» (COMMENT ?)
Bien que la plupart des auteurs s’entendent pour dire que l’analyse répond à
la question QUOI ?, tous ne s’entendent pas sur ce que signifie ce QUOI.
Ainsi, on peut considérer qu’il existe plusieurs niveaux de QUOI ?, chaque
niveau étant ensuite réalisé par un COMMENT ? de niveau inférieur [Dav93] :
a) Les besoins et exigences des usagers ;
b) L’ensemble des solutions possibles (l’espace des solutions) ;
c) Une solution particulière ;
d) La structure interne de la solution choisie ;
e) La description des modules de la solution (interfaces et fonctionalités) ;
f) Les algorithmes ;
g) Le code final.
14 Modélisation et spécification formelle des logiciels

Dans ce qui suit, nous allons considérer que l’étape d’analyse et de


spécification porte sur les deux aspects suivants :
1. Analyse du problème = Analyser et comprendre le problème à
résoudre, les besoins et les exigences des usagers, les contraintes à
respecter. (Cela correspond aux niveaux a) et b).)
2. Description du produit = Décrire le logiciel qui satisfera aux besoins
et aux exigences et qui respectera les contraintes. (Cela correspond
au niveau c).)
Ces deux aspects ne sont pas nécessairement associés à des phases
temporelles distinctes du cycle de développement : en pratique, ils sont
généralement étudiés et décrits de façon concurrente pour, ultimement,
produire le «Document de spécification du logiciel» (DSL). Ce document — en
anglais, Software Requirements Specification ou SRS — représente le livrable
de la phase d’analyse et de spécification. Il vise à décrire le comportement du
logiciel (QUOI ?) qui satisfera les besoins et les exigences, les contraintes, de
même que le contexte dans lequel ce logiciel sera utilisé (l’environnement, le
domaine de l’application).
La conception (design), quant à elle est, selon l’IEEE, le «processus qui
consiste à définir l’architecture du logiciel, les composants, les modules, les
interfaces, les stratégies de test et les données qui feront en sorte que le
système logiciel va satisfaire ses spécifications.» [IEE91] Le processus de
conception vise donc à répondre aux questions suivantes :
• Comment le système sera-t-il construit ?
• Quelle sera sa structure interne ?
• Comment fonctionnera-t-il ?
On distingue généralement deux grandes composantes du processus de
conception :
1. La conception architecturale, qui vise à décrire l’architecture du logiciel,
donc qui vise à répondre aux questions suivantes :
• Quels sont les principaux composants logiciels (les principaux
modules) ?
• Comment sont-ils organisés et structurés ?
• Quelles sont les interfaces entre les divers composants logiciels ?
• Quelle sera l’organisation générale des données ?
1 Introduction : Qu'est-ce que les méthodes formelles ? 15

2. La conception détaillée, dont le rôle est de préciser, de façon claire et non


ambiguë, ce que fait chacun des modules identifiés lors de la conception
architecturale. Ici, on met donc l’accent sur les détails de traitement
(algorithmes) à l’intérieur de chacun des modules, de manière à ce que
chaque composant logiciel puisse ensuite être codé dans un langage de
programmation approprié. Les détails associés aux données ou à la base
de données doivent aussi être précisés.
On peut aussi présenter la différence entre analyse, spécification et
conception en fonction des points de vue pour lesquels ces descriptions sont
produites :
• Analyse et spécification : l’analyse et spécification décrit les concepts
et interfaces (externes) nécessaires pour utiliser le système (point de
vue de l’usager).
• Conception : la conception décrit les concepts et interfaces (internes
et externes) nécessaires pour construire le système (point de vue du
développeur).
C’est dans cet esprit qu’on dit souvent qu’une spécification vise à définir le
comportement d’un système ou d’un composant logiciel (spécification de
comportement). Plus précisément, une spécification cherche à décrire le
comportement observable du système spécifié, c’est-à-dire, ce qui est vu de
l’extérieur du système par un utilisateur ou par un client du système. Un tel
comportement est habituellement décrit en tenant compte des fonctions du
système : Quelles sont les opérations permises ? Quelles entrées utilisent ces
opérations ? Quelles sorties sont produites en fonction des entrées reçues ?
Quelles sont les exceptions ou les erreurs possibles ? C’est pour cette raison
que certains auteurs parlent aussi de spécifications fonctionnelles.
Notons que bien que l’on regroupe généralement analyse et spécification, par
opposition à conception, spécification et conception possèdent malgré tout
certaines affinités puisque les deux traitent de la solution : alors que
l’analyse vise à comprendre et à décrire le domaine du problème, la
spécification est le premier élément de description du domaine de la solution
; cette solution sera ensuite développée et raffinée par le processus de
conception puis réalisée, mise en oeuvre par les étapes subséquentes du
processus de développement.
16 Modélisation et spécification formelle des logiciels

1.4 POURQUOI L’ÉTAPE D’ANALYSE ET SPÉCIFICATION EST-


ELLE IMPORTANTE ?
Une spécification joue un rôle important dans le processus de
développement, car elle établit une forme de contrat entre ceux qui
développent un système et ceux qui l’utiliseront (et payerons pour) : les
usagers peuvent s’attendre à ce que le comportement du système soit celui
indiqué par la spécification, rien de moins, rien de plus ; de leur coté, les
développeurs ont l’obligation de fournir et de réaliser le système ayant le
comportement spécifié.
On dit d’une mise en oeuvre qui réalise le comportement décrit par une
spécification qu’elle satisfait cette spécification1. Le travail consistant à
s’assurer qu’une mise en oeuvre satisfait une certaine spécification fait
partie du processus de validation et de vérification : voir la figure 1.1.
Évidemment, l’objectif ultime est aussi de s’assurer que le système résultant
satisfait bien les besoins et les exigences du client.

Besoins et exigences

Validation

Spécification comportementale
(fonctionnelle) du système

Vérification

Structure interne
(architecture) Validation
du système

Vérification

Mise en oeuvre du système


(programme exécutable)

Figure 1.1 Place des spécifications dans le processus de développement

1
Il est clair qu’une spécification peut être satisfaite par plusieurs mises en oeuvre différentes. Cela sera abordé de manière formelle
au chapitre 10.
1 Introduction : Qu'est-ce que les méthodes formelles ? 17

On distingue généralement entre la validation et la vérification d’un système :


• Validation : Construit-on le bon produit ? (Are we building the right
product ?)
• Vérification : Construit-on le produit correctement ? (Are we building the
product right ?)
De façon générale, la validation consiste à s’assurer que le système rencontre
et satisfait les besoins et les exigences du client. On peut donc, au début du
cycle de développement, tenter de valider la spécification par rapport aux
besoins et aux exigences en utilisant des revues ou des inspections ou à
l’aide de prototypes ; on peut aussi, une fois le système complété, valider la
mise en oeuvre, par exemple, à l’aide de tests systèmes (tests fonctionnels).
De son côté, la vérification consiste à s’assurer, à chaque étape du
développement, que les éléments développés durant cette étape satisfont les
contraintes décrites à l’étape précédente [Pre97].
Évidemment, pour vérifier qu’une conception ou qu’une mise en œuvre
satisfait sa spécification, il est important que celle-ci soit claire, précise et la
plus complète possible. Le développement d’une spécification formelle
permet généralement d’obtenir une telle spécification. De plus, si on
interprète la validation comme le processus visant à montrer que les besoins
et les exigences sont bien comblés, alors le développement d’une
spécification formelle peut grandement aider à une telle validation, car le
travail de spécification oblige à bien comprendre le problème et à rendre
explicites le plus possible les contraintes et concepts sous-jacents. De plus,
il est aussi possible, à partir de certaines formes de spécification formelle,
d’obtenir rapidement un prototype du système à développer, ou encore de
générer automatiquement des jeux d’essai, deux aspects favorisant la
validation du système.
Un autre point important en faveur de la production de documents de
spécifications, formels ou non, est le fait que, règle générale, plus les erreurs
sont détectées tard dans le cycle de vie, plus les coûts de correction sont
élevés. Par expérience, on s’est aperçu que de nombreuses erreurs liées à la
compréhension du problème et à la formulation de la solution sont faites par
les développeurs, erreurs qui ne sont pas détectées avant que les tests soient
faits sur la mise en œuvre du système. Selon certaines études, 45 à 55% des
problèmes rencontrés lors des tests seraient en fait des erreurs dans la
compréhension du problème et dans la formulation de la solution. Or, si une
erreur faite par rapport à la spécification n’est détectée qu’au moment des
tests, la correction de cette erreur entraîne alors des coûts très élevés parce
18 Modélisation et spécification formelle des logiciels

que l’on doit alors corriger la spécification et, ensuite, refaire les étapes
subséquentes de développement — conception, mise en oeuvre, tests — qui
permettent de réaliser les modifications requises.
Des erreurs typiques au niveau des spécifications sont dues à des éléments
incorrects, des omissions, des inconsistances ou des ambiguïtés. La
production et la réalisation d’un document explicite de spécification (DSL)
permettent souvent, par simple inspection de ce document, de détecter
plusieurs de ces erreurs. Par exemple, des études ont démontré que des
revues ou des inspections des documents d’analyse et spécification
pouvaient détecter de 35 à 65% de ces erreurs. Lorsque la spécification est
formelle, d’autres types de vérification peuvent aussi être faits, par exemple,
la vérification de la cohérence interne de la spécification.
Dans les chapitres qui suivront, nous traiterons principalement du
développement de spécifications formelles pour des systèmes et composants
logiciels. L’aspect validation ne sera pas examiné comme tel ; par contre,
l’aspect vérification sera traité dans la deuxième partie (chapitres 9 et 10), où
nous discuterons d’une approche rigoureuse de développement.

1.5 QUE SIGNIFIE «MÉTHODES FORMELLES» ?


Voici diverses définitions de ce que sont les méthodes formelles :
«Les méthodes formelles utilisées dans le développement de systèmes
informatiques sont des techniques basées sur les mathématiques
pour décrire des propriétés de ces systèmes. De telles méthodes
formelles fournissent un cadre à l’intérieur duquel on peut spécifier,
développer et vérifier des systèmes informatiques d’une façon
systématique, plutôt que d’une façon ad hoc.» [Win90]
«Les méthodes formelles [...] consistent à utiliser les mathématiques
pour le développement de logiciels. Les principales activités [...] sont :
• l’écriture d’une spécification formelle ;
• la preuve de certaines propriétés de cette spécification ;
• la construction d’un programme en manipulant mathémati-
quement la spécification ;
• la vérification du programme à l’aide de raisonnements
mathématiques.» [Hal90]

Vous aimerez peut-être aussi