Conception Formelle en PVS

publicité
Conception Formelle en PVS
Roland Atoui
Xavier Dumas
Sébastien Jardel
Laurent Vendredi
Chef de projet : Mr Pierre Castéran
1
Remerciements : Nous tenons à remercier particulièrement Monsieur César Munoz, le
professeur P.Y. Gloess ainsi que le professeur Pierre Castéran pour leur aide précieuse et
constructive tout au long de ce projet.
Résumé
La conception formelle de systèmes informatiques est une démarche relativement jeune dans le
monde de la science. Plusieurs technologies ont été développées pour la modélisation de systèmes
sûrs. Nous nous intéressons dans ce document à l'étude de l'une d'entre elles : La technologie
PVS (Prototype Verication System). L'initiation à cet outil a pour objectif de regarder si les
notions de développement de programmes prouvés et de ranement sont en adéquation avec
PVS. Nous poursuivons cette étude par une évaluation de PBS permettant la transcritpion d'une
machine abstraite B en théorie PVS. Enn, nous testons le prouveur de théorème de PVS en
résolvant les obligations de preuves générées pour en apprécier son ecacité.
Table des matières
1 Présentation de PVS
3
2 PBS : de B à PVS
5
1.1
2.1
2.2
Le langage PVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1 Un langage fortement typé . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2 Trois types de langage . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Introduction à la méthode B . . .
2.1.1 Survol du langage . . . . .
2.1.2 Les obligations de preuves
L'outil PBS . . . . . . . . . . . .
2.2.1 Les machines PBS . . . .
2.2.2 Sémantique et validité des
2.2.3 Le ranement . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
. . . . . . . . .
machines PBS
. . . . . . . . .
3 Le Prouveur PVS
3.1
3.2
3.3
Introduction au prouveur PVS . . . . .
3.1.1 Rappel sur la déduction naturelle
3.1.2 Le prouveur . . . . . . . . . . . .
Le déroulement d'une preuve . . . . . .
3.2.1 Exemples de preuves . . . . . . .
Le prouveur : PVS versus Atelier B . . .
3.3.1 Exemple . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
3
4
5
5
7
7
8
11
14
20
20
20
21
21
21
27
29
4 Conclusion
39
Bibliographie
41
A Installation
42
B Le langage PVS
43
A.1 PVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
A.2 PBS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
B.0.1 Les Mots Clés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
B.1 Le Prouveur PVS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
42
42
43
43
TABLE DES MATIÈRES
2
B.1.1 Commandes de haut et bas niveau . . . . . . . . . . . . . . . . . . . . .
B.1.2 Les stratégies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
C Exemples PBS
C.1 Dispenser . . . . . . . . . . . . . . . . . . . . . . . .
C.1.1 La Machine PVS : Dispenser . . . . . . . . .
C.1.2 La Théorie PVS : Dispenser . . . . . . . . . .
C.1.3 Preuves des TCCs de la théorie Dispenser . .
C.2 Ens : spécication d'un tableau . . . . . . . . . . . .
C.2.1 La Machine PVS de Ens1 . . . . . . . . . . .
C.2.2 La Théorie PVS de Ens1 . . . . . . . . . . . .
C.2.3 Preuves des TCCs de la théorie Ens1 . . . . .
C.3 CtxMenu . . . . . . . . . . . . . . . . . . . . . . . .
C.3.1 La Machine PBS de CtxMenu . . . . . . . . .
C.3.2 La théorie PVS de CtxMenu . . . . . . . . .
C.3.3 Preuves des TCCs de la théorie CtxMenu . .
C.4 CtxDistributeur . . . . . . . . . . . . . . . . . . . . .
C.4.1 La Machine PBS de CtxDistributeur . . . . .
C.4.2 La théorie PVS de CtxDistributeur . . . . . .
C.4.3 Preuves de la théorie PVS de CtxDistributeur
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
44
45
48
48
48
50
52
52
52
53
54
55
55
56
58
59
59
60
61
Chapitre 1
Présentation de PVS
PVS est un système de vérication, développé par l'équipe méthode formelle du SRI Inter-
national. Il a été présenté en 1992 par [OSRSC99a].
PVS est un langage de spécication intégré avec un prouveur de théorème. Dans ce chapitre,
nous nous attachons à l'apprentissage de PVS. Nous regardons, dans un premier temps, la
syntaxe du langage que fournit PVS. Nous essayons ensuite de comprendre comment fonctionne
le système. Nous clôturons ce chapitre en nous intéressant au prouveur de PVS.
1.1 Le langage PVS
PVS est un langage de spécication, il va donc générer des obligations de preuve, qui devront être prouvées par la suite. Trés utilisés dans la vérication, les langages de spécication
permettent de valider un logiciel au niveau de la sécurité de code.
PVS comme tout langage s'appuie sur des principes et sur des mots clés, dans les parties
qui suivent, nous décrirons les grandes lignes du manuel de référence du langage [OSRSC99a].
(Cette description proposera également un parallèle avec la méthode B, ce qui permettra de
mieux introduire le coeur du projet qui est la capacité de PVS à traduire les notions abordées
dans le cours de B. )
1.1.1 Un langage fortement typé
PVS s'appuie sur la logique d'ordre supérieur (HOL : Higher Order Logic). La logique d'ordre
supérieur est plus étendue que celle du premier ordre. Elle permet d'utiliser les variables dans
les expressions en tant que fonctions et prédicats.
PVS repose sur l'utilisation des types. Le type d'une variable peut être nat, int, etc... Il peut
également être un type construit par l'utilisateur, ou déjà déni dans la librairie PVS, on peut
par exemple construire une fonction puis la dénir comme type. Nous le verrons par la suite il
existe un moyen de préciser si un type est vide ou non. La cohérence de chaque type doit être
vérier, c'est le rôle que joue le typechecking de PVS.
3
CHAPITRE 1. PRÉSENTATION DE PVS
4
1.1.2 Trois types de langage
Dans ce projet nous avons rencontré 3 types de langage :
Le langage B de la méthode B
Le langage PVS basé sur la logique d'ordre supérieur
Le langage PBS qui décrit une machine B en PVS
Le langage B est un un langage de spécication mettant en jeu une machine abstraite, plusieurs ranements (déterminisation, fonctions totales) pour ainsi arriver à une implantation et
une implémentation en C ou ADA générée par l'atelier B.
Le langage PVS est un autre langage de spécication logique utilisant de nombreuses notions
mathématiques
Le langage PBS est l'intermédiaire entre une machine B et la théorie PVS. Le chier PBS
(machine PBS) est le chier d'entrée de l'outil PBS. Avec ce chier PBS que l'on implémente,
l'outil PBS génère automatiquement une théorie PVS correspondante.
Chapitre 2
PBS : de B à PVS
Plusieurs méthodes, notations et outils destinés au développement de logiciels sûrs existent.
Nous nous intéressons ici à l'élaboration d'un logiciel à l'aide d'une méthode formelle (B) imbriquée dans une logique d'un système de vérication (PVS). Le système nous permettant de
réaliser ceci est PBS mis au point par César A. Muñoz.
Ce chapitre est destiné à initier le lecteur à ce système. Nous introduisons en premier lieu la
méthode B, avant de décrire les possibilités de PBS. Nous nissons en donnant les limitations
et les perspectives d'évolution de ce logiciel.
2.1 Introduction à la méthode B
B est une méthode formelle pour le développement logiciel qui a été mise au point par Jean
Raymond Abrial dans les années 80. Elle fournit un langage uniforme (le langage B) qui
est utilisé pour l'écriture d'une machine abstraite, pour spécier, concevoir et implémenter des
systèmes. La méthode B se base sur la logique du premier ordre.
Le but de ce document n'étant pas de faire un cours sur cette méthode, nous survolons
rapidement son langage et sa méthodologie. Pour plus de détails à son sujet, nous vous renvoyons
au cours de B de Christine Paulin [Pau01].
2.1.1 Survol du langage
La méthode B comporte trois étapes importantes :
L'écriture d'une machine abstraite.
L'écriture d'un ou plusieurs ranements.
L'implantation.
Chaque machine abstraite et chaque ranement doivent être contrôlés par la vérication de
quelques propriétés appelées obligation de preuves.
Elles doivent vérier que :
Une instanciation pour les paramètres, les ensembles et les constantes satisfaisant les
contraintes existe.
5
CHAPITRE 2. PBS : DE B À PVS
6
L'état initial satisfait l'invariant.
[S0 ]I avec S0 l'état initial et I l'invariant.
L'invariant est préservé par les opérations.
I ⇒ [S]I avec S une substitution quelconque.
La structure d'une machine abstraite
Elle ressemble typiquement à celle de la gure 2.1.
MACHINE nom
SETS EN S1 ,...,EN S2
VARIABLES x1 ,...,x2
INVARIANT I
INITIALIZATION S0
OPERATIONS
...
END
/*
/*
/*
/*
/*
/*
nom de la machine */
nom des ensembles */
nom des variables */
propriété */
substitution */
substitutions */
Fig. 2.1 Structure d'une Machine Abstraite
Le ranement
Le ranement est une technique utilisée au cours du processus de développement logiciel
pour transformer un modèle abstrait en modèle plus concret. Comme pour les machines abstraites, le ranement doit vérier :
l'invariant dans l'initialisation des variables
dans les opérations
dans les inclusions
vérier la cohérence des invariants entre la machine abstraite et son ranement.
L'implantation
L'implantation est un cas particulier du ranement, c'est la dernière étape. Sa structure
générale est représentée à la gure 2.2
IMPLEMENTATION nomI
REFINES nom
...
END
/* nom de la machine d'implantation */
/* nom de la machine ranée */
Fig. 2.2 Structure d'une Machine d'implantation
CHAPITRE 2. PBS : DE B À PVS
7
2.1.2 Les obligations de preuves
C'est certainement la notion la plus délicate à aborder. Après l'écriture de chaque machine il
est nécessaire de vérier les proriétés énoncées (cf section 2.1.1) : Selon les substitutions que l'on
rencontre dans une machine, les formules peuvent changer. Le but n'étant pas d'être exhaustif
sur ce point, nous montrons seulement l'allure d'une preuve devant vérier que l'invariant reste
vrai après une substitution du type var1 ← nom_operation(var2 ) = P RE P T HEN S EN D
I ⇒ ∀(var1 , var2 )P ⇒ [S]I
Un cas plus délicat est celui des propriétés provenant d'un ranement. Il faut dans ce cas
tenir compte des propriétés de la machine qu'elle rane.
En reprenant l'exemple de la substitution de la forme P RE P1 T HEN S1 EN D On imagine
un ranement où cette substitution devient P RE P2 T HEN S2 EN D alors la formule à verier
devient
Inv1 ∧ Inv2 ∧ P1 ⇒ (P2 ∧ [S2 ](¬[S1 ]¬Inv2 ))
Avec Inv1 Inv2 les invariants respectifs de la machine abstraite et du ranement.
2.2 L'outil PBS
PBS est un support pour la méthode B en PVS. PVS n'a pas de méthodologie particulière
de construction de logiciel.
L'article de César Muñoz [Muñ99] montre comment une machine abstraite B peut être supportée par PVS. PBS est implémenté en Ocaml, il utilise les lexers et les parser des librairies
ocamllex et ocmlyacc fournies par le langage. PBS fonctionne comme un compilateur, il prend
en entrée un chier m.pbs contenant une machine PBS et génère la théorie PVS associée comme
le montre la gure 2.3
deep and shallow embedding (plongement en surface/profondeur) Il y a deux ap-
proches pour l'enchassement d'un langage spécialisé d'une méthodologie vers un langage de
spécication général supporté par un prouveur de théorème :
Le plongement en profondeur (deep embedding).
Le plongement en surface (shallow embedding).
Muñoz préconise cette dernière. Ainsi, il ne traduit pas la machine abstraite en PVS, mais
ajoute la notation de PBS comme une couche sur le langage de PVS.
La contribution de ses travaux pointe vers deux directions. D'un coté, PVS est mis en valeur
grâce à la méthodologie de B et de l'autre le langage B est enrichi d'un langage de spécication
fortement typé et d'un prouveur de théorème puissant (PVS).
CHAPITRE 2. PBS : DE B À PVS
8
Fig. 2.3 Fonctionnement de PBS
2.2.1 Les machines PBS
Avant d'aller plus loin, il est important de dénir deux choses :
Une machine PBS
Une théorie PVS
Une machine PBS est un chier dont l'extension est .pbs, c'est le chier d'entrée du système
PBS comme le montre le gure 2.3. Une théorie PVS est le chier de sortie du système PBS
et le chier d'entrée du système PVS. Notons que le passage d'une machine abstraite B à
une machine PBS se fait manuellement. Par abus de langage, nous appelerons un chier PBS
machine PBS.
Les machines abstraites de B en PVS Le langage de spécication de PVS est basé sur
la logique d'ordre supérieur (Higher-Order Logic : HOL) mise en valeur grâce à un système
fortement typé. Le typage est tellement expressif que le typechecking est indécidable. Le typechecking génère des obligations de preuves que l'utilisateur doit résoudre. Cette tâche peut être
eectuée en utilisant les diérentes procédures de décision et les outils de preuves automatiques
fournis par le système.
Nous rappelons que PVS est structuré en théories. Une théorie peut être paramétrée. Elle
comporte des déclarations de constantes (tels que les types non-interprétés, variables, contantes
abstraites), dénitions (tels que les types, les sous-types, fonctions, prédicats) et objets logiques
(tels que les axiomes, théorèmes, conjectures). Une théorie PVS peut utiliser d'autres théories
grâce à un mécanisme d'importation.
PVS n'impose pas de style de spécications particulières, elles peuvent être axiomatiques,
déclaratives et algorithmiques.
On peut faire des machines PBS qui sont syntaxiquement similaires aux machines abstraites B
modulo quelques spécications dues aux particularités de PVS. La diérence entre une machine
CHAPITRE 2. PBS : DE B À PVS
9
abstraite B et une machine PBS et que cette dernière est basée sur la logique d'ordre supérieur
et la théorie des types de PVS. Nous allons illustrer les diérences à travers un exemple concret.
Prenons l'exemple du compteur de la machine abstraite B de la gure 2.4, son équivalent
en PBS est représenté à la gure 2.5.
MACHINE Counter(maxi)
CONSTRAINTS
maxi : NAT1
VARIABLES
value
INVARIANT
value : NAT & value <= maxi
INITIALISATION
value := 0
OPERATIONS
reset =
BEGIN
value := 0
END;
next =
PRE
value < maxi
THEN
ANY val
WHERE val : NAT & val <= maxi & val > value
THEN
value := val
END
END
END
Fig. 2.4 Machine Abstraite B Counter
Les diérences
Ces machines sont très proches syntaxiquement, on note toutefois les diérences suivantes :
Les variables et les paramètres doivent être explicitement typés.
CHAPITRE 2. PBS : DE B À PVS
counter [maxi:posnat]: MACHINE
BEGIN
PVS
`IMPORTING finite_sets@top'
VARIABLES
value : `nat'
INVARIANT
`value <= maxi'
INITIALIZATION
value := 0
OPERATIONS
reset =
value := 0
next =
PRE
`value < maxi'
THEN
ANY val : nat
WHERE `val <= maxi AND val > value'
THEN
value := val
ENDANY
END
END counter
Fig. 2.5 Machine PBS Counter
10
CHAPITRE 2. PBS : DE B À PVS
11
Les expressions sont déclarées entre quotes.
L'exemple de compteur etant minimaliste, il ne permet pas de mettre en valeur toutes les
diérences qui existent, nous allons tout de même essayer de les enumérer.
Les mots clés
Certains mots clés sont remplacés par d'autres. Le mot clé SETS désignant la partie d'une
machine abstraite où l'on déclare les ensembles est remplacé par TYPES dans une machine
PVS.
Certains mots clés du langage B ne sont tous simplement pas représentables, comme
CONSTRAINTS, CONCRETE_VARIABLES, CONCRETE_CONSTANTS. Cela
peut sembler gênant au premier abord, mais ne constitue pas de diculté particulière. En
général, on peut simuler ces mots dans les machines PVS.
Les limitations
Il n'est pas possible d'exprimer les notions de SEES, USES, PROMOTES, EXTENDS.
Une des dicultés principales vient du fait qu'en PVS, les fonctions sont totales. Néanmoins,
il est possible de représenter des fonctions partielles en utilisant des sous-types et des types
dépendants. Dans la théorie de type, les fonctions ne sont pas interprétées comme des relations
binaires mais comme des objets calculables.
2.2.2 Sémantique et validité des machines PBS
Une machine PBS est transcrite en théorie PVS, où les paramètres et les types de la machine
deviennent paramètres et types de la théorie. L'état de la machine PBS est encodé de façon
fonctionnel dans PVS.
Les variables de la machine dénissent un enregistrement de type appelé type général, chaque
champ correspond à une variable de la machine. Dans le langage PVS, le type général est écrit
à l'aide de crochet et du symbole dièse [# ... #]. Si l'on reprend l'exemple du compteur, le
système PBS génère la théorie PVS de la gure 2.6 .
Le type général de la machine contient value qui est la seule variable de la machine.
counter_Type : TYPE = [#
value:nat
#]
L'invariant de la machine est exprimé dans la théorie PVS comme un sous-type du type
général. La dépendance mutuelle entre les variables données par les contraintes sont générées
par un mécanisme de type dépendant de PVS.
counter : TYPE = { self: counter_Type |
value(self) <= maxi AND value(self)>=0 }
L'initialisation des champs du type général se fait entre (# et #)
CHAPITRE 2. PBS : DE B À PVS
%%% counter.pvs -- File generated by PBS
%% Theory: Counter Machine
counter [ maxi:posnat ]: THEORY
BEGIN
%% PVS Commands
IMPORTING finite_sets@top
%% General Type
counter_Type : TYPE = [#
value:nat
#]
%% Invariant Type
counter : TYPE = { self: counter_Type |
value(self) <= maxi AND value(self)>=0 }
%% Initialization
init : counter =
LET self =
(#
value := 0
#) IN
self
%% Operations
reset(self:counter) : counter =
LET self =
self WITH [
value := 0
] IN
self
12
CHAPITRE 2. PBS : DE B À PVS
13
next(self:counter |
value(self) < maxi) : counter =
LET self =
LET val = choose! (val:nat) :
( val <= maxi AND val > value(self) ) IN
LET self =
self WITH [
value := val
] IN
self
IN
self
END counter
Fig. 2.6 Théorie PVS Counter
init : counter =
LET self =
(#
value := 0
#) IN
self
Tandis que l'aectation d'une variable dans une opération (autrement dit une substitution)
se fait avec la construction W IT H [ ... ] comme le montre l'exemple de compteur :
reset(self:counter) : counter =
LET self =
self WITH [
value := 0
] IN
self
Une opération de machine est traduite par une fonction en PVS. Cette fonction reçoit un
paramètre supplémentaire avec l'enregistrement d'état satisfaisant l'invariant et la précondition.
Les substitutions généralisées sont interprétées comme une expression PVS, mais PVS ne
supporte pas les substitutions suivantes :
WHILE P DO S INVARIANT I VARIANT V. La sémantique de cette substitution
est celle des boucles en langages de programmation impérative. Le mécanisme de fonction
récursive fourni par le langage est mieux adapté pour la notation des machines PBS.
SELECT P THEN S. Si P est un prédicat et S est une substitution généralisée, la
sémantique informelle est que S s'applique si P est vraie. Cette substitution n'est pas
CHAPITRE 2. PBS : DE B À PVS
14
gérée par PVS car elle a besoin d'un contrôle explicite de l'exécution qui n'est pas fourni
par PVS. La plupart du temps, elle peut être simulée par un mécanisme conditionnel de
PVS.
Obligations de preuves
Les obligations de preuves sont également générées du fait de l'existence de paramètres,
ensembles et constantes satisfaisant les contraintes. Une obligation de preuve en PVS est communément appelée Type Correctness Condition abrégée en TCC. Seules les TCCs générées
par PVS sont à démontrer avec l'aide du prouveur interactif de PVS. Nous développerons ce
sujet dans le chapitre suivant. Attardons nous plutôt sur le principe de ranement exploité par
PBS pour générer des théories PVS.
2.2.3 Le ranement
Comme dans le cas du ranement en B, le ranement de PVS hérite des paramètres, des
propriétés constantes de la machine abstraite.
En PVS, le ranement se fait par l'utilisation du mot clé IMPORTING. PVS se comporte
comme un langage de programmation orienté objet. En eet on peut redénir et surcharger des
fonctions, dénir un espace de nom, redénir des opérateurs. Ainsi le mécanisme d'importation
peut être associé à la notion de réutilisabilité et modularité des langages de programmation :
diviser pour mieux régner.
Chaque théorie peut être considérée comme une classe que l'on peut raner en y ajoutant de
nouvelles fonctionnalités, ou en l'incorporant dans une autre classe. On peut ainsi partir d'une
théorie totalement abstraite pour arriver à une théorie complexe mettant en jeu diérentes
théories. Le ranement entre la méthode B et PVS semble donc très similaire. Nous allons
regarder en détail comment PBS met cela en ÷uvre.
La diérence syntaxique principale réside dans le fait que le ranement de la machine PBS
possède deux invariants :
INVARIANT : contraint les variables locales du ranement avec les variables locales
de la machine ranée.
REFINE_INVARIANT : contraint les variables de la machine ranée avec les variables locales déclarées dans le ranement.
La gure 2.7 représente le ranement du compteur en B. Sa transcription en machine PBS
est représentée à la gure 2.8. Analysons la théorie PVS que génère PBS qui se trouve à la
gure 2.9.
Nous avons trouvé une diculté lors de l'implémentation du ranement counter. Nous en
avons longuement discuté avec Monsieur Munoz ainsi que Monsieur Castéran. En eet, l'atelier
B utilise une sémantique relationnelle alors que PVS utilise une sémantique fonctionnelle. Ainsi
l'atelier B garde dans sa sémantique toutes les valeurs possibles alors que PVS en détermine
CHAPITRE 2. PBS : DE B À PVS
MACHINE counterRef(maxi)
REFINES counter
VARIABLES
value
INITIALISATION
value := 0
OPERATIONS
next =
value := value + 1
END
Fig. 2.7 Ranement B de Counter
counterRef [maxi:posnat]: REFINEMENT OF counter
BEGIN
VARIABLES
value_ref : `nat'
REFINE_INVARIANT
`value_ref <= value'
INITIALIZATION
value_ref := 0
OPERATIONS
next =
value_ref := `value_ref + 1'
END counterRef
Fig. 2.8 Ranement de la Machine PBS de Counter
15
CHAPITRE 2. PBS : DE B À PVS
16
une directement. Ainsi
valuer ef = value
n'est pas prouvable en PVS. Une des solutions serait d'utiliser la même sémantique relationnelle
qu'en B dans la prochaine version de PBS.
CHAPITRE 2. PBS : DE B À PVS
%%% counterRef.pvs -- File generated by PBS
%% Theory: CounterRef Refinement
counterRef [ maxi:posnat ]: THEORY
BEGIN
%% Refinement Importing
IMPORTING counter[maxi]
%% General Type
counterRef_Type : TYPE = [#
value_ref:nat
#]
%% Invariant Type
counterRef : TYPE = counterRef_Type
%% Refinement Type
counterRef_Ref_Type : TYPE = [#
counterRef:counterRef,
counter:counter
#]
counterRef_Ref : TYPE = { self_ref: counterRef_Ref_Type |
value_ref(counterRef(self_ref)) <= value(counter(self_ref)) }
%% Initialization
init : counterRef =
LET self =
(#
value_ref := 0
#) IN
self
init_ref : counterRef_Ref =
(#
counterRef := counterRef.init,
counter := counter.init
#)
17
CHAPITRE 2. PBS : DE B À PVS
18
%% Operations
next(self:counterRef) : counterRef =
LET self =
self WITH [
value_ref := value_ref(self) + 1
] IN
self
next_ref(self_ref:counterRef_Ref |
value(counter(self_ref)) < maxi) : counterRef_Ref =
(#
counterRef := counterRef.next(counterRef(self_ref)),
counter := counter.next(counter(self_ref))
#)
END counterRef
Fig. 2.9 Théorie PVS du ranement de Counter
La structure reste similaire à celle de la théorie du compteur. On retouve la partie General
Type, Invariant Type, Initialization, et Operations. Regardons les diérences notables. La théorie
PVS de Counter est importée :
IMPORTING counter[maxi]
La machine PVS n'ayant pas d'invariant (INVARIANT), on s'aperçoit tout de même que
PBS génère un invariant :
counterRef : TYPE = counterRef_Type
La partie Renement Type est plus délicate à comprendre :
counterRef_Ref_Type : TYPE = [#
counterRef:counterRef,
counter:counter
#]
counterRef_Ref : TYPE = { self_ref: counterRef_Ref_Type |
value_ref(counterRef(self_ref)) <= value(counter(self_ref)) }
Elle comprend deux parties. La première est la déclaration d'un type counterRef_Ref_Type
qui est un enregistrement de type contenant deux champs :
Une variable counterRef appartenant à counterRef
Une variable counter appartenant à counter
CHAPITRE 2. PBS : DE B À PVS
19
C'est cet enregistrement de type qui permet de faire le collage entre les variables des deux
théories.
La seconde partie est plus classique, elle déclare un ensemble de variables de type counterRef_Ref_Type respectant la propriété de l'invariant du ranement. counterRef_Ref est donc
un sous-type de counterRef_Ref_Type.
Il est ensuite initialisé :
init_ref : counterRef_Ref =
(#
counterRef := counterRef.init,
counter := counter.init
#)
De la même manière, l'opération next_ref met à jour l'opération next et son ranement
à jour. C'est ce qui apparaît dans les deux champs, mais au préalable il faut que la valeur de
value de counter qui est une variable de self_ref soit inférieure à maxi.
next_ref(self_ref:counterRef_Ref |
value(counter(self_ref)) < maxi) : counterRef_Ref =
(#
counterRef := counterRef.next(counterRef(self_ref)),
counter := counter.next(counter(self_ref))
#)
Conclusion
PBS à toute les capacités pour introduire de manière clair les machines abstraites B et leur
ranement en PVS. Certaines traduction reste toutefois délicates, et une bonne connaissance
de PVS est nécessaire. Une évolution possible pour ce logiciel serait de se rapprocher un peu
plus de certaines notions de B, car la transcription d'une machine abstraite B à une machine
PVS conduit parfois à une perte de certaines restrictions dénies en B.
Chapitre 3
Le Prouveur PVS
Nous avons vu précédemment que PBS générait une théorie PVS. Nous nous intéressons
donc dans cette partie à la résolution des obligations de preuves engendrées par PVS de ces
chiers. Le but est d'évaluer la puissance du prouveur PVS et le comparer ainsi à celui de
l'Atelier B. Enn nous discutons sur l'utilité d'un outil tel que PBS à l'aide de nos résultats.
3.1 Introduction au prouveur PVS
Le premier chapitre montre comment utiliser le prouveur de PVS. Nous entrons dans les
détails grâce à des exemples dans cette partie, mais avant cela il est impératif de faire un rappel
sur la déduction naturelle.
3.1.1 Rappel sur la déduction naturelle
La déduction naturelle est un formalisme pour décrire des preuves de calcul de prédicats
proposée par Gentzen en 1935 pour eectuer des preuves intuitionnistes : c'est à dire dont le
raisonnement se rapproche au maximum du raisonnement mathématique. Mais cette approche
était assez dicile pour produire une preuve syntaxique en arithmétique. Ceci a conduit Gentzer
à développer un formalisme plus adapté et symétrique : le calcul des séquents.
Une suite de formules à gauche séparés par le symbole ` et une suite de formules à droite :
A1 , A2 , ..., An ` B1 , B2 , ..., Bn
Les Ai sont des formules appelées hypothèses ou antécédents et les Bi sont les formules
appelées conclusions ou conséquents. Chaque formule peut apparaître plusieurs fois dans chaque
ensemble.
Les virgules à gauche du séquent peuvent être remplacées par des conjonctions et les virgules à
droite par des disjonctions.
Le symbole ` peut s'interprêter comme une implication dont le symbole est ⇒.
A1 ∧ A2 ∧ ... ∧ An ⇒ B1 ∨ B2 ∨ ... ∨ Bn
20
CHAPITRE 3. LE PROUVEUR PVS
21
On peut traduire ce séquent par :
En supposant que toutes les hypothèses soient vraies alors au moins une des conclusions est
vraie.
Il existe plusieurs règles principales pour la manipulation des séquents et leur simplication.
Ces règles sont présentées dans le guide de référence du prouveur de PVS [SORSC99]. Les
séquents procurent une grande lisibilité et des opérations de simplication assez ecaces.
3.1.2 Le prouveur
Voici comment sont décrits les séquents dans le prouveur de PVS. Les antécédents sont
numérotés par des entiers négatifs et les conséquents par des entiers positifs. On remarque que
ces numéros sont entourés par des crochets [ ] ou des accolades { }. Ces deux notations ont une
signication. En eet, [ ] signient que la règle appliquée au but courant n'a modié en rien le
séquent et les accolades indiquent qu'il y a eu au contraire un changement dans la formule ou
alors qu'un nouveau but plus simple a été créé.
Pour démontrer un théorème, il y a trois possibilités :
Soit de se ramener à la trivialité TRUE à droite du séquent, soit à FALSE à gauche du
séquent
Soit arriver au même terme à droite et à gauche du séquent. Dans ces trois cas, le théorème
est démontré.
Sinon on peut arriver à un contre exemple ou alors on ne peut tous simplement pas prouver
le théorème correspondant.
Le prouveur PVS se constitue ainsi par un arbre de preuves contenant lui-même des feuilles
et sous-feuilles chacunes représentant une formule à prouver. Le séquent est prouvé si toutes les
feuilles de l'arbre ont été démontrées.
Le prouveur PVS contrairement à d'autres langages de spécications ayant un prouveur
intégré, met en avant la facilité d'utilisation en ligne de commande du buer Emacs et la
lisibilité e la construction de preuves tout au long de la démonstration plutôt que l'ecacité de
l'exécution. En eet la philosophie de PVS est basée sur le 80 - 20.
3.2 Le déroulement d'une preuve
Nous exploitons dans cette section quelques exemples que nous avons vu en cours de B.
3.2.1 Exemples de preuves
On peut eectuer tous les types de preuves en PVS très facilement avec les puissantes
commandes associées. Il existe principalement deux types de preuves :
les preuves par induction
les preuves itératives
CHAPITRE 3. LE PROUVEUR PVS
22
En eet, les preuves par inductions sont très simples à mettre en oeuvre car il existe une
commande très puissante pour ces démonstrations. Les preuves par prédicat sont très faciles à
démontrer et en général on essaye de se ramener au même terme de part et d'autre du séquent
dans ce genre de démonstration. On peut biensûr eectuer les preuves de nombreuses manières.
Soit en utilisant les commandes de bas niveau pour avoir un contrôle total sur le déroulement
de la démonstration ou bien des stratégies et règles très évoluées résolvant automatiquement
certaines preuves.
Nous allons voir quelques exemples dont le premier est une démonstration très simple sur
les prédicats et le deuxième une preuve sur une théorie dénissant un compteur. Eectuons les
preuves de la théorie suivante :
propositions: theory
begin
A, B , C : bool
prop: theorem (A ⊃ (B ⊃ C )) ∧ (A ⊃ B ) ∧
A ⊃ C
end propositions
On a déclaré 3 booléens A, B, C et on veut prouver le THEOREM. On commence par vérier
s'il y a des erreurs de syntaxes (M − xparse). Il n'y en a aucunes. On continue par vérier la
sémantique (Mx typecheck) ; aucune obligation de preuve n'est générée. On se positionne sur la
ligne contenant le THEOREM et on exécute (Mx prove).
On obtient :
prop :
|------{1} (A IMPLIES (B IMPLIES C)) AND (A IMPLIES B) AND A IMPLIES C
On exécute la commande
(f latten)
pour simplier les conjonctions et disjonctions selon les règles de séquent. Ce qui nous donne :
Trois hypothèses sont apparues (valeurs négatives entre accolades).
La commande a enlevé les conjonctions AND et a placé les diérentes parties de la proposition
en antécédent, car dans un séquent, les conjonctions de tous les antécédents doivent satisfaire
les disjonctions des conséquents. On a donc une forme équivalente au séquent initial.
CHAPITRE 3. LE PROUVEUR PVS
23
prop :
{-1} (A IMPLIES (B IMPLIES C))
{-2} (A IMPLIES B)
{-3} A
|------{1} C
Maintenant on peut essayer de simplier en utilisant la commande
(split)
qui va découper l'antécédent -1 en 3 buts :
prop.1 :
{-1} C
[-2] (A IMPLIES B)
[-3] A
|------[1] C
On va commencer par C.
C satisfait bien C donc la prop.1 est vériée. On va maitenant vérier B qui correspond au
deuxième sous-goal d'où vérier :
prop.2 :
[-1] (A IMPLIES B)
[-2] A
|------{1} B
[2] C
On peut encore découper l'antécédent [-1] par
(split)
Cela nous donne :
B satisfait bien B. Il reste le A à satisfaire pour le deuxième sous-goal de la proposition 2 :
CHAPITRE 3. LE PROUVEUR PVS
24
{-1} B
[-2] A
|------[1] B
[2] C
prop.2.2 :
[-1] A
|------{1} A
[2] B
[3] C
On voit bien que A satisfait A donc on n'a rien à faire. La proposition 2 est alors vériée.
Il nous reste le sous-goal 3 concernant le A du de la proposition de départ à satisfaire :
prop.3 :
[-1] (A IMPLIES B)
[-2] A
|------{1} A
[2] C
which is trivially true.
This completes the proof of prop.3.
Q.E.D.
Ce qui est aussi vérié auomatiquement puisque c'est trivial. Le THEOREM est donc vérié.
Nous allons commencer par dénir en pvs la théorie counter équivalente de la machine counter
que nous avions développée avec l'atelier B : un compteur qui incrémente la variable "value"
de 1 à chaque opération "next".
Cette machine prenait en paramètre un entier positif : "maxi" qui était la valeur maximale que
le compteur pouvait atteindre. Si la valeur de "value" est supérieur à "maxi" nous réinitialisons
le compteur à 0. On veut aussi que le paramètre fournit en argument de la théorie soit un entier
CHAPITRE 3. LE PROUVEUR PVS
25
naturel supérieur à 0 ; donc on ajoute un invariant dans la clause ASSUMPTION qui assure
que "maxi" est toujours supérieur à 0.
Maintenant nous devons ajouter un invariant sur la variable "value". C'est à dire dans la
clause "THEOREM" et vérier que les préconditions et postconditions "value< maxi" sont
toujours respectées. D'où la dénition de "Theocounter".
Ce simple programme ne contient qu'un seul "THEOREM".
le fait est que PVS nous permet de dénir ce même programme de plusieurs façon :
En ajoutant des THEOREM, LEMMA
En utilisant le typage de PVS
La première méthode réduit le nombre d'obligations générées et augmente la lisibilité de la
théorie. Mais l'utilisateur devra quand même prouver ces théorèmes. De plus les preuves mettant
en jeu l'induction ne seront pas simpliées.
La deuxième méthode consiste à créer des types complexes dans lesquels on exprime directement les contraintes et théorèmes que l'on veut vérier. L'avantage de cette méthode est que
toutes les obligations de preuves sont générées dans les TCCs dans lesquels certaines inductions
ont déjà été simpliées.
Une méthode alternative aux deux précédentes lorsque les théorèmes deviennnent illisibles est
d'utiliserle mot clé JUDGEMENT dans lequel on va introduire les théorèmes à vérier comme
dans la méthode un tout en gardant l'avantage de la méthode deux. En eet JUDGEMENT
se comporte comme s'il faisait partie d'un typage.
£
¤
counter maxi: nat : theory
begin
assuming
inv: assumption 0 < maxi
endassuming
value: var nat
next(value): nat =
(if value < maxi then value + 1 else 0 endif)
Theocounter: theorem (value < maxi ⇒ next(value) ≤ maxi)
end counter
CHAPITRE 3. LE PROUVEUR PVS
26
Nous vérions maintenant que ce programme est syntaxiquement correct par la commande
(Mx pa) ou (Mx parse).
La vérication ne génère pas d'erreur ; nous pouvons passer au "typechecking" : c'est à
dire vérier si la sémantique est correcte (bonne dénition des types, sous-types, sous-types
prédicats, dépendances des types)
Ici, la théorie est relativement simple et aucun TCC (typecheck condition ou obligation de
preuve lié au typecheck) n'est généré.
On peut nalement essayer de prouver le "THEOREM". On place le curseur devant "Theocounter" et on exécute la commande (Mx pr) ou (Mx prove).
On obtient le prompt suivant :
Theocounter :
|------{1} FORALL (value: nat): (value < maxi => next(value) <= maxi)
Nous allons essayer de prouver 1. Pour simplier 1 on remarque le quanticateur FORALL
que l'on peut réduire par la commande
(skolem!)
. En eet le FORALL va être remplacé par une constante de la forme x !1 ce qui nous donne :
Rule? (skolem!)
Skolemizing,
this simplifies to:
Theocounter :
|------{1} (value!1 < maxi => next(value!1) <= maxi)
Le FORALL a disparu et laisse place à la constante value !1. Maintenant on remarque
l'implication qui peut être réécrite ; en eet, cela veut dire que
1 ⇔ value!1 < maxi| − − − − − − − − − −next(value!1) <= maxi)
On a la commande (atten) qui eectue cette simplication :
CHAPITRE 3. LE PROUVEUR PVS
27
Rule? (flatten)
Applying disjunctive simplification to flatten sequent,
this simplifies to:
Theocounter :
{-1} value!1 < maxi
|------{1} next(value!1) <= maxi
On se retrouve avec un antécédent -1 et un conséquent 1 On peut remarquer que l'on retrouve
dans 1 la fonction "next" Pour pouvoir lire sa dénition et retrouver une partie de l'antécédent
-1, on va déplier la fonction avec la commande (expand "next") :
Rule? (expand "next")
Expanding the definition of next,
this simplifies to:
Theocounter :
[-1] value!1 < maxi
|------{1} (IF value!1 < maxi THEN 1 + value!1 ELSE 0 ENDIF) <= maxi
On a donc l'antécédent que l'on retrouve dans le conséquent. Maintenant il ne reste que
des propositions logiques. Il existe une commande qui permet de nir la preuve gràce à ces
propositions logiques et des procédures de décisions sur l'arithmétique, les égalités et inégalités.
On va donc utliser une stratégie qui correspond à la commande (ground) qui applique elle-même
la commande (prop) pour les propositions logiques (IF THEN etc ...)
Rule? (ground)
Applying propositional simplification and decision procedures,
Q.E.D.
La preuve est réussie ; nous avons terminé la preuve du THEOREM donc cette théorie est
vériée et conrme la spécication exacte.
3.3 Le prouveur : PVS versus Atelier B
Tout d'abord la méthode B utilise une interface graphique pour construire les machines,
ranement, implémentation et les preuves. PVS utilise l'éditeur emacs.
Les preuves en PVS sont plus lisibles que celles générées par l'Atelier B car seule l'information intéressante pour l'utilisateur est achée ; tout le reste est caché. De plus les
CHAPITRE 3. LE PROUVEUR PVS
28
simplications sont très souples et automatisées, les expansions ne sont pas automatiques
comme avec l'Atelier B. Enn on peut cacher, eacer des hypothèses, les réacher pour
améliorer la lisibilité.
Avec l'atelier B, le prouveur sur les prédicats utilise la logique de premier ordre basée sur
la logique de Hoare alors que PVS utilise la logique d'ordre supérieur qui utilise la règle
des séquents et une logique basée sur la déduction naturelle. Le prouveur PVS permet de
créer une stratégie pouvant résoudre des obligations de preuves basées sur la logique de
hoare. Le nombre de commande du prouveur PVS est réduit
En B il existe énormément de commandes pour eectuer les preuves. PVS lui n'en possède
nalement qu'assez peu.
Il existe en B un prouveur automatique de forces diérentes : 0, 1 ou 2. Plus la force
augmente, et plus les preuves sont poussées et plus le temps utilisé est long. Ainsi une la
terminaison n'est pas assurée.
En PVS il n'y a pas de prouveur automatique mais il existe des commandes très puissantes
comme GRIND ou INDUCT-AND-SIMPLIFY qui peuvent prendre des arguments et
preuvent à elles seules démontrer une grande partie des obligations de preuves.
Le typechecking en B eectue la vérication de syntaxe mais en PVS c'est le parser qui
eectue cette tache. Même si le typechecking fait appel au parser, sa fonction principale
est de vérier la sémantique et le bon typage des théories.
Or, dû au typage fort du langage PVS et la dénition de types poussées grâce au logique d'ordre supérieure, le typechecking en PVS est parfois indécidable ce qui ajoute des
preuves supplémentaires à démontrer dans les TCCs.
Le B qui n'utilise que la logique du premier ordre est un langage très faiblement typé ; le
typechecking est donc totalement automatique et ne génère aucune obligation de preuves.
Lors du typechecking en PVS, on retrouve toutes les obligations de preuves de B générées
par le prouveur. En PVS elles sont regroupées en TCC dans la forme non expansée alors
qu'on les retrouve sous forme de PO expansée en B.
Un point important est qu'en B les preuves peuvent boucler et donc ne jamais terminer.
En PVS les preuves ne bouclent pas car l'utilisateur à beaucoup plus de contrôle sur le
déroulement et la construction de la démonstration.
Dans les stratégies en eet la dernière commande est la commande (FAIL) ou (SKIP)
décidant si les commandes précédentes ont échoué de quitter la preuve ou de ne rien
faire. Les commandes et règles sont eectuées de manières atomiques. Si une commande
échoue en PVS le prouveur nous ramène dans un état précédent stable en indiquant l'échec
de la commande ou alors il ne fait rien en indicant que rien n'a changé par la dernière
commande.
PVS permet une plus grande souplesse pour eectuer les preuves de plusieurs manières
diérentes. Il y a une notion de ranement dans les preuves pour essayer de simplier
au maximum les commandes utilisées et ainsi aboutir à une preuve généralisée que l'on
pourra transformer en stratégie.
PVS nous donne plus d'information sur le déroulement des preuves et une arbre de preuves
peut être généré et enregistré dans un chier ps.
Les preuves en B sont très diciles à prouver alors qu'en PVS une bonne maîtrise des
obligations de preuves permet de les résoudre très facilement. (cf : théorème de fermat).
CHAPITRE 3. LE PROUVEUR PVS
29
B permet d'écrire des axiomes considérées comme justes mais qui ne sont pas prouvées
par l'atelier B alors que PVS oblige la démonstration de tous les théorèmes et accroît
ainsi la abilité des théories.
PVS fournit des commandes de très bas niveau pour contrôler totalement le déroulement
de la preuve de la manière la plus mathématique possible.
PVS, une assez bonne expérience dans les preuves permet de résoudre pratiquement tous
les théorèmes.
En PVS, le fait d'utiliser les commandes de bas niveau augmente la abilité et l'absence
de bug dans les théories.
Le nombre de preuves en PVS est doublé ou triplé par rapport aux PO en B.
Le ranement en B utilises des règles plus strictes qu'en PVS qui nalement peut être
réduite à la clause IMPORTS et les techniques de programmation objet.
3.3.1 Exemple
Illustrons ces remarques par un exemple : Comparons les obligations de preuves en B et en
PVS en prenant la théorie compteur comme référence mais cette fois-ci générée par l'outil PBS
(cf gure 2.5) :
Lors du typechecking de la machine abstraite de la gure 2.4 en B, nous pouvons lire sur le
terminal la sortie suivante :
L'atelier B eectue le typechecking de la machine B de manière totalement automatisée
(typechecking décidable contrairement à PVS). En eet elle commence par charger la machine,
vérier le nom de la machine et la validité des diérentes clauses ainsi que les opérations. Elle
enregistre enn les données collectées de la machine. A la n du typechecking, si aucune erreur
n'est détectée, l'atelier B génère automatiquement les obligations de preuves.
On observe que l'atelier B a procédé en deux étapes : La génération de preuves liées à
l'initialisation ; c'est à dire vérier que l'invariant est respectée à l'initialisation. Ensuite l'atelier
B génère les obligations de preuves associées aux opérations de la machine Counter ; c'est à dire
que l'invariant est respectée avant et après chaque opération.
On peut remarquer que l'atelier B automatise certaines preuves comme en PVS. En eet,
l'initialisation étant très simple pour cette machine, les 4 obligations de preuves générées sont
automatiquement démontrées.
De même pour l'opération reset qui ressemble à une initialisation, les 5 obligations de preuves
sont prouvées automatiquement.
Enn pour l'opération next, l'atelier B a généré 5 obligations de preuves tout comme pour
l'opération reset. Cette fois-ci, les 5 obligations de preuves ont aussi été démontrées de manières
triviales.
CHAPITRE 3. LE PROUVEUR PVS
Type Checking machine Counter
Loading referenced machines
Checking names clashes
Checking CONSTRAINTS clause
Checking SEES clause
Checking SETS clause
Checking PROPERTIES clause
Checking ABSTRACT_CONSTANTS clause
Checking VARIABLES clause
Checking CONCRETE_VARIABLES clause
Checking INCLUDES clause
Checking USES clause
Checking EXTENDS clause
Checking promotions
Checking INVARIANT clause
Checking gluing invariant
Checking ASSERTIONS clause
Checking INITIALISATION clause
Checking operation reset
Checking operation next
Normalizing Counter
Saving data of component Counter
End of Type checking
30
CHAPITRE 3. LE PROUVEUR PVS
Generating proof obligations of Machine Counter
Initialisation :
....
proof obligations:
0
obvious proof obligations: 4
reset :
.....
proof obligations:
0
obvious proof obligations: 5
next :
.....
proof obligations:
0
obvious proof obligations: 5
0 proof obligations generated
14 obvious proof obligations generated
Generation complete
31
CHAPITRE 3. LE PROUVEUR PVS
32
Nous avons nalement obtenu 14 obligations de preuves générées automatiquement par l'atelier B et toutes prouvées automatiquement par le prouveur en force 0.
Dans la théorie PVS, on ne peut plus utiliser les théorèmes pour les obligations de preuves car
on part d'une machine PVS qui ne permet pas d'introduire cette notion. Toutes les obligations
de preuves se retrouvent donc dans les TCCs.
Après le typechecking en pvs, le prouveur a généré 4 TCCs. Si on regarde en détails ces TCCs,
on remarque que l'on obtient une obligation de preuve pour l'initialisation, une obligation de
preuve pour l'opération reset et deux obligations de preuves pour l'opération next.
Si on exécute la commande
Mx pr
les deux premières obligations de preuves sont démontrées automatiquement ; il nous reste deux
preuves à éectuer pour l'opération next.
Regardons les obligations de preuves générées par l'atelier B. Rappellons les règles de correction d'une machine abstraite :
correction de l'instanciation lors de l'inclusion de machines
correction des assertions
les initialisations doivent respecter l'invariant
les opérations doivent respecter l'invariant
Dans la machine B, toutes les 14 obligations de preuves étant prouvées automatiquement, ces
obligations de preuves sont cachées par l'atelier B.
Regardons ce que nous donne PVS :
Les 4 obligations de preuves de l'atelier B pour l'initialisation sont regroupées dans un seul
TCC. Avec PVS 4.0 l'obligation de preuve liée à l'initialisation nous demande de vérier l'invariant correspondant au type de la variable. PVS 3.2 ne demande pas cette vérication et nous
simplie donc la tâche. Nous utiliserons PVS 3.2 qui est plus stable que PVS 4.0.
Les TCCs sont données dans le format lisp agrémenté de code PVS. Le premier TCC nous
demande de prouver que "value<=maxi". l'atelier B lui nous demande de prouver que value est
un entier et qu'il est inférieur ou égal à maxi.
Le deuxième TCC concerne l'opération reset et nous demande de vérier que quelque soit la
valeur du compteur, elle est inférieure ou égale à maxi et que lorsque l'on appelle reset sa valeur
devient nulle. Pour cela PVS génère un quanticateur universel FORALL qui parcourt toutes
les valeurs possibles du compteur et cherche à vérier si la variable respecte bien les invariants
dans tous ses états.
CHAPITRE 3. LE PROUVEUR PVS
33
% Subtype TCC generated (at line 25, column 4) for
% LET self = (# value := 0 #) IN self
% expected type counter
% unchecked
init_TCC1: OBLIGATION (LET self = (# value := 0 #) IN self)`value <= maxi;
% Subtype TCC generated (at line 34, column 4) for
% LET self = self WITH [value := 0] IN self
% expected type counter
% unchecked
reset_TCC1: OBLIGATION
FORALL (self: counter):
(LET self = self WITH [value := 0] IN self)`value <= maxi;
Alors que l'atelier B a généré 5 obligations de preuves pour vérier si l'opération reset vérie
toujours l'invariant, PVS grâce au quanticateur a réduit les obligations de preuves à un seul
TCC.
Les troisième et quatrième TCCs concernent l'opération next. Elles vérient que le compteur
est bien aecté à une variable dans tous ses états et qu'elles vérient l'invariant. L'atelier
B a généré 5 obligations de preuves pour ces mêmes démonstrations. Encore une fois le fait
PVS permette de décrire les obligations de preuves comme du code PVS permet d'avoir des
obligations de preuves compactes et moins nombreuses à l'aide notamment des quanticateurs
qui vérient le bon environnement de chaque état.
Ainsi PVS a réduit énormément le nombre d'obligations de preuves générées ; de 14 on est
passé à 4. En revanche PVS nous demande plus de preuves manuelles, même si pour ces TCCs
un (GRIND) sut.
Comme nous l'avons dit précédemment PVS est basé surtout sur la lisibilité et l'ecacité de
la construction de preuves et non sur l'ecacité de leur exécution. Pour la machine abstraite
PVS génère les mêmes obligations de preuves que l'atelier B de manière plus lisible et plus
concis. Dans les deux cas les preuves sont démontrées trivialement.
Comparons maintenant le ranement counter :
Nous recommençons les mêmes opérations que précédemment. PVS nous indique que 4 TCCs
ont été générées et un subsumed ce qui veut dire qu'un des TCCs a pu être regroupé avec un
autre. Finalement nous obtenons 3 TCCs dont un est démontré automatiquement
CHAPITRE 3. LE PROUVEUR PVS
% Subtype TCC generated for
% LAMBDA (val: nat): (val <= maxi AND val > value(self))
% expected type p: (nonempty?[nat])
% unchecked
next_TCC1: OBLIGATION
FORALL (self: counter | self`value < maxi):
nonempty?[nat](LAMBDA (val: nat): (val <= maxi AND val > self`value));
% Subtype TCC generated (at line 42, column 4) for
% LET self =
%
LET val =
%
choose! (val: nat): (val <= maxi AND val > value(self))
%
IN LET self = self WITH [value := val] IN self
% IN self
% expected type counter
% unchecked
next_TCC2: OBLIGATION
FORALL (self: counter | self`value < maxi):
(LET self =
LET val = choose! (val: nat):
(val <= maxi AND val > self`value) IN
LET self = self WITH [value := val] IN self
IN self)`value
<= maxi;
REFINEMENT CounterRef(maxi)
REFINES Counter
VARIABLES
value
INITIALISATION value := 0
OPERATIONS
next =
value := value + 1
END
34
CHAPITRE 3. LE PROUVEUR PVS
35
Generating proof obligations of Refinement CounterRef
Initialisation :
..
proof obligations:
0
obvious proof obligations: 2
next :
.......
proof obligations:
4
obvious proof obligations: 3
reset :
...
proof obligations:
0
obvious proof obligations: 3
4 proof obligations generated
8 obvious proof obligations generated
Generation complete
Normalizing...
No previous proof method interactive file
No previous PO file
Merging...
Done
Proving CounterRef
Proof pass 0, still 4 unproved PO
clause next
++++
End of Proof
Initialisation
next
reset
TOTAL for CounterRef
Proved
Proved
Proved
Proved
0
4
0
4
Unproved
Unproved
Unproved
Unproved
0
0
0
0
CHAPITRE 3. LE PROUVEUR PVS
36
Avec l'atelier B nous obtenons 12 Obligations de preuves dont 8 démontrées automatiquement.
Il reste 4 obligations de preuves liées à l'opération next à démontrer. Comme on peut le constater
une preuve automatique avec la force 0 sut pour tout démontrer.
Comme on peut le voir la lecture des preuves de l'atelier B est moins agréable à lire que celles
de PVS. On est amené à eectuer un "dd" pour isoler le but et rendre plus lisible les obligations
de preuves.
Les preuves en B utilisent les Hypothèses pour pouvoir prouver les PO. Chaque nouvelle
hypothèse est ajoutée dans la liste et ainsi de suite on déduit et on simplie les preuves jusqu'à
sa correction.
CHAPITRE 3. LE PROUVEUR PVS
37
Hypothèses
"`Component constraints'" &
maxi: INTEGER &
0<=maxi &
maxi<=2147483647 &
not(maxi = 0) &
maxi<=999 &
maxi+1<=1000 &
btrue &
1<=maxi &
"`Previous components invariants'" &
value$1: INTEGER &
0<=value$1 &
value$1<=2147483647 &
value$1<=maxi &
"`Component invariant'" &
value = value$1 &
"`next preconditions in previous components'" &
1+value$1<=maxi &
CounterRef.next.4
Les 4 obligations de preuves de l'atelier B permettent de vérier que l'opération "next" vérie
bien l'invariant :
Vérier que lorsque value est incrémenté, value reste toujours un entier inférieur ou égal
à maxi.
PRI > go(next.1)
"`next preconditions in this component'" &
value$1+1<=maxi &
"`Check operation refinement - ref 4.4, 5.5'" &
=>
value$1+1: INTEGER
CHAPITRE 3. LE PROUVEUR PVS
38
Vérier value+1 est >= 0
PRI > go(next.2)
"`next preconditions in this component'" &
value$1+1<=maxi &
"`Check operation refinement - ref 4.4, 5.5'" &
=>
0<=value$1+1
Vérier value+1 est <= 2147483647
PRI > go(next.3)
"`next preconditions in this component'" &
value$1+1<=maxi &
"`Check operation refinement - ref 4.4, 5.5'" &
=>
value$1+1<=2147483647
Vérier que value < value+1
PRI > go(next.4)
"`next preconditions in this component'" &
value$1+1<=maxi &
"`Check operation refinement - ref 4.4, 5.5'" &
=>
value<=value$1
PVS étant fortement typé, il n'a pas besoin de vérier 1, 2 et 3 qui est déchargé automatiquement. Par contre il vérie que dans la machine counter l'opération next vérie l'invariant et
que l'opération du ranement satisfasse aussi l'invariant.
2 TCCs susent pour cela.
Nous remarquons donc que PVS génère toutes les obligations générées par B mais demande
plus de contrôle sur la démonstration des obligations de preuves car les TCCs sont décrites par
du code PVS et non basées comme en B sur les substitutions, les prédicats et la théorie des
ensembles.
Chapitre 4
Conclusion
PVS est un langage de spécication très performant tant au niveau de la description des
théories utilisant la logique d'ordre superieur qu'au niveau des preuves. Il possède les mêmes
qualités qu'un langage de programmation orienté objet avec en plus la possibilité de dénir des
règles et théorèmes faisant de la théorie un modèle prouvé mathématiquement.
La puissance du typage est un des grands atouts de ce langage de spécication qui ore
ainsi de nombreuses possibilités et expressions de besoins dicilement exprimables en B.
Au niveau des preuves, la lisibilité et la simplicité des commandes donnent beaucoup d'aisance dans la fabrication de preuves et la démonstration mathématique ardus. On arrive ainsi
à généraliser les théories grâce à la générécité (TYPE, TYPE+) ainsi que les preuves avec la
dénition de nouvelles stratégies.
L'utilisation que nous avons fait de PBS montre quelques facettes de cet outil, mais ne reète
en rien toutes ses possibilités. L'élaboration d'une machine plus complexe devient vite dicile
lorsque l'on n'a pas une idée assez précise du code de la théorie qui doit être générée. Il en ressort
donc qu'il faut une bonne maîtrise du langage PVS. Cela dit, PBS permet d'exprimer facilement
des machines abstraites B simple en théories PVS. Le ranement est également très bien géré
par PBS. Son intérêt étant de prouver les obligations de preuves de B plus facilement en utilisant
la puissance de PVS. Cette double modélisation cahier des charges vers B ; B vers PBS et PBS
vers PVS augmente les risques de mauvaises interprétations et à terme des spécications non
conformes. Toutefois cette double modélisation demande plus d'eort pour l'utilisateur et une
erreur dans le chier PVS généré peut venir soit de la spécication PBS, soit de la machine B
auquel cas il faut tout recommencer. PBS essaye ainsi de pallier aux défaillances de la méthode
B (des outils développés pour la méthode B) c'est à dire au niveau des preuves mais aussi
fusionne les qualités de ces deux langages de spécications.
Finalement, PVS est très bien adapté pour la conception de systèmes sûrs. Sans posséder un
lexique aussi large que celui de B, PVS donne la possibilité d'interpréter quasiment toutes les
notions de la méthode B. Cela donne à PVS un caractère plus souple, avec plus de contrôle, de
puissance et de abilité, mais moins que Coq. Une amélioration de PVS serait la possibilité de
générer un code exécutable pour arriver à une implémentation nale mais aussi implémenter et
39
CHAPITRE 4. CONCLUSION
mettre en place la composition de machines.
40
Bibliographie
[Muñ99]
C. Muñoz. PBS : Support for the B-method in PVS. Technical Report SRI-CSL99-01, SRI International, February 1999.
[OS93]
Sam Owre and Natarajan Shankar. Abstract datatypes in PVS. Technical Report
SRI-CSL-93-9R, Computer Science Laboratory, SRI International, Menlo Park,
CA, December 1993. Extensively revised June 1997 ; Also available as NASA
Contractor Report CR-97-206264.
[OS97]
Sam Owre and Natarajan Shankar. The formal semantics of PVS. Technical
Report SRI-CSL-97-2, Computer Science Laboratory, SRI International, Menlo
Park, CA, August 1997.
[OSRSC99a] S. Owre, N. Shankar, J. M. Rushby, and D. W. J. Stringer-Calvert. PVS Language
Reference. Computer Science Laboratory, SRI International, Menlo Park, CA,
September 1999.
[OSRSC99b] S. Owre, N. Shankar, J. M. Rushby, and D. W. J. Stringer-Calvert. PVS System Guide. Computer Science Laboratory, SRI International, Menlo Park, CA,
September 1999.
[Pau01]
Christine Paulin. Introduction à la méthode b. Technical Report 1, Laboratoire de
Recherche en Informatique, Université Paris-Sud, 2001. http ://www.lri.fr/ paulin/B/.
[SORSC99]
N. Shankar, S. Owre, J. M. Rushby, and D. W. J. Stringer-Calvert. PVS Prover Guide. Computer Science Laboratory, SRI International, Menlo Park, CA,
September 1999.
41
Annexe A
Installation
A.1 PVS
1. Dans le .bashrc rajouter :
export CMULISP_HOME=/usr
2. Créer un répertoire et y mettre l'archive (car lorsqu'il extrait, il ne créé pas directement
de répertoire)
3. Ouvrir le chier BDD/ix86-Linux/Makele puis enlever -lbsd
4. Télécharger le patch à http ://www.cs.ru.nl/ tews/pvs-4-0-patch-makele-quote
5. Renommer le patch pvs-4-0-patch-makele-quote.patch
6. Exécuter la commande :
patch -p 1 < pvs-4-0-patch-makefile-quote.patch
7. Il vous demande quel chier entrer : Makele.in
8. Puis ./congure
9. et make
N'oubliez pas qu'il faut un interpréteur lisp (si vous avez emacs c'est bon).
A.2 PBS
Assurez vous simplement que Ocaml est installé, puis refaire l'étape 2 de l'installation de
PVS et lire le README après extraction de l'archive.
42
Annexe B
Le langage PVS
B.0.1 Les Mots Clés
Dans cette section nous ne détaillons bien evidemment pas tous les mots clés.
BEGIN et END sont les deux mots clés qui marquent le début de la théorie PVS.
BEGIN se placera juste aprés la ligne de déclaration de la théorie, c'est à dire le nom de
la théorie et la liste des paramètres.
IMPORTING est un mot clé associé soit à une librairie soit à une autre théorie. L'utilisateur pourra alors utiliser des fonctions, des types déclarés dans la librairie ou la théorie
TYPE, TYPE+ permettent la généricité en PVS, la variable devant laquelle ils sont
placés pourra être de n'importe quel type (nat, list..). La diérence entre ces deux types
est que TYPE+ est forcément non vide ce qui n'est pas le cas pour TYPE.
ASSUMING permet de contraindre les variables devant lesquelles il est placé.
LEMMA, THEOREM,CONJECTURE sont les mots clés qui vont introduire les
obligations de preuve. Ce sont les principaux, mais il en existe d'autre. Les obligations
introduites par LEMMA permettent en général de prouver les obligations introduites par
THEOREM. Pour CONJECTURE, elle peuvent soit être prouvées et elles deviennent
alors THEOREM, soit démontrées fausses elles sont donc rejetées, soit on ne peut les
prouver elles restent CONJECTURE.
MACRO. Il permet de simplier et de rendre plus lisible le code.
RECURSIVE permet d'introduire la récursivité en PVS.
B.1 Le Prouveur PVS
Nous introduisons dans cette section les principaux axes du guide d'utilisation du Prouveur
de PVS [SORSC99]. Nous commencerons par décrire quelques commandes et leur utilité, puis
nous donnerons un aperçu du genre de stratégie que nous propose PVS pour la résolution de
preuves.
43
ANNEXE B. LE LANGAGE PVS
44
B.1.1 Commandes de haut et bas niveau
Il existe peu de commandes en PVS, mais elles sont paramétrables, ce qui donne une grande
liberté d'action à l'utilisateur. On peut séparer ces commandes en trois types :
Les commandes simples (bas niveau).
Les règles.
Les stratégies.
Les commandes simples permettent à l'utilisateur d'eectuer des preuves avec un très grand
contrôle ou à passer des paramètres complexes.
Les règles sont des suites de commandes de bas niveau qui sont exécutées de manières
atomiques. Ces commandes portent en général sur des numéros de formules (abbrégé par fnums
dans la documentation PVS) qui sont soit un entier positif (un but) ou négatif (une hypothèse),
(+) > (tous les buts), (-) > (toutes les hypothèses), ou (*) > (tous les buts ou toutes les
hypothèses).
Dans les commandes on pourra aussi trouver term et constant qui désignent respectivement
un terme (une expression du séquent courant, entre guillemets) ou une constante libre (une
constante n'apparaissant pas dans le séquent courant).
Il existe un certain nombre de commandes très utiles et très puissantes. Les quatre principales
commandes à connaître sont :
grind : permet d'essayer de prouver le but automatiquement (C'est la procédure de décision/simplication de PVS).
quit : permet de quitter la preuve courante.
undo : permet de revenir en arrière. On peut préciser en argument le nombre de pas qu'on
veut eectuer en arrière.
use "hypo" : ajouter le lemme "hypo" aux hypothèses.
Les commandes suivantes sont les plus utilisées car elle peuvent simplier les buts à chaque
étape :
atten : permet de simplier les disjonctions et conjonctions. Une hypothèse de type A∧B
est remplacée par deux hypothèses :
A, B .
Une conclusion de type A ∨ B est remplacée par deux conclusions
A, B .
Une conclusion A ⇒ B place A dans l'hypothèse et B dans la conclusion.
split permet de remplacer un but en plusieurs buts. Une hypothèse A ∨ B est remplacée
par deux sous buts : A dans les antécédents et B dans les conséquents.
Une conclusion A ∧ B est remplacée par deux sous buts : A d'un côté et B de l'autre.
Une hypothèse A ⇒ B est remplacée par l'hypothèse B dans un but et la conclusion A
dans l'autre but.
skolem ! permet de remplacer des variables de quanticateurs par des constantes internes
générées automatiquement par le prouveur.
La conclusion F ORALL est remplacée par une constante interne. L'hypothèse EXIST S
est aussi remplacée par une constante interne.
ANNEXE B. LE LANGAGE PVS
45
inst ? permet de trouver une correspondance entre les variables des hypothèses et celles des
conclusions pour ainsi aboutir au même terme en instanciant certaines variables. Ces deux
dernières commandes font référence aux commandes skolem et inst qui elles, prennent des
arguments obligatoires en paramètre.
expand est une commande très utile lorsque l'on veut déplier une fonction. Elle admet
des arguments en paramètre.Par exemple pour déplier la dénition du prédicat antisymétrique ? expand antisymetrique ? .
case "X=0" permet d'eectuer des analyses cas par cas de manière exhaustive. Dans
cet exemple un but sera remplacé par l'hypothèse X = O et dans l'autre but (générée
automatiquement) X! = 0.
Il existe enn des commandes de très haut niveau admettant elles aussi des paramètres :
grind présenté plus haut et induct-and-simplify qui sont les commandes les plus puissantes
du prouveur permettant de démontrer un très grand nombre de buts.
induct-and-simplify résoud automatiquement les preuves par inductions, récurrences.
En général on commence toujours par utiliser la commande grind ou induct-and-simplify et
ensuite on essaye de simplier les hypothèses et conclusions avec les diérentes règles atten,
split, skolem !, expand.
On utilise ainsi les stratégies au début, les règles et enn les commandes de bas niveau.
B.1.2 Les stratégies
Bien sûr les commandes et règles présentées ci-dessus ne sont qu'une partie de la puissance
du prouveur PVS.
La grande puissance du prouveur réside dans la dénition de stratégies choisies par l'utilisateur lui-même.
On va décrire d'une façon explicite ce qu'est une stratégie.
Les expressions de stratégies
Toute stratégie peut être écrite comme une preuve, mais la syntaxe des expressions de
stratégie est la suivante :
{
}
{(step) := (primitive-rule)}
| {(defined-rule)}
| {(defined-strategy)}
| (quote{(step)})
| (try{(step) (step) (step)})
| (if{(lisp-expression) (step) (step)})
| (let ({({(symbol) (lisp-expression)})}+) {(step)})
ANNEXE B. LE LANGAGE PVS
46
La dénition d'une stratégie
Les stratégies dénies par l'utilisateur doivent être sauvegardées dans un chier qu'on appelle
pvs-stratégies.PVS va charger les stratégies contenues dans ces chiers à la fois dans le répertoire
de l'utilisateur et dans le répertoire du contexte courant. La dénition de stratégie à la forme
suivante :
(defstep {name}
(required-parameters
\&optional optional-parameters
\&rest {parameter)
strategy-expression
documentation-string
format-string)
Ceci va générer une règle (blackbox) et une stratégie (glassbox). Les diérences entre une
règle dénie et une stratégie sont :
1. La dénition d'une règle comme une règle primitive par exemple, est atomique, alors
qu'une stratégie peut être dépliée comme une application de plusieurs règles atomiques.
2. La forme dépliée d'une stratégie est sauvegardée pour être réexécutée, alors qu'une règle
est réexécutée sous sa forme initiale (non dépliée).
3. Une règle dénie renvoie simplement les nouveaux buts non prouvés tandis que la stratégie
renvoie l'arbre de preuve déplié.
Autrement, les règles dénies et les stratégies se ressemblent beaucoup. Les deux méthodes
peuvent être récursives et peuvent impliquer l'application d'un certain nombre d'étapes de
preuves, de primitives.
les stratégies de base
quote
textitLa stratégie d'identité
syntax : (quote step)
eet : L'expression de stratégie (quote step ) s'évalue à step elle-même. La raison pour
laquelle elle est utilisée est qu'elle est tout à fait typique pour construire une expression
en lisp correspondante à une stratégie, mais celle-ci à besoin d'être unquoted par la suite
pour être employées comme une stratégie.
try : La stratégie de sous-but (subgoaling) et de marche en arrière (backtracking)
syntax : (try step1 step2 step3)
eet : C'est la base du contrôle de stratégie. Elle va appliquer step1 au but courant. Si
step1 génère des sous-buts, alors step2 sera appliquée sur ces sous-buts.Dans le cas où
step1 ne génère aucun sous-buts step3 sera appliquée au but courant.
exemples :
1. (try (atten) (propax) (split) ) :Cette stratégie va appliquer une disjonction sur le but
courant. Si le but est simplié par la disjonction, alors (propax) sera appliquée au but
résultant sinon ce sera la conjonction (split) qui sera appliquée au but courant.
ANNEXE B. LE LANGAGE PVS
47
2. (try (try (atten) (fail) (skolem 1 (a b))) (postpone) (prop)) :Si le but courant est
simplié par disjonction , alors backtrack est appliquée puis prop, sinon on applique
skolem puis simplication propositionnelle (postpone) ou prop dans le cas où skolem
n'a pas réussi. On remarque que (fail) est utilisée pour eectuer une marche en
arrière à partir d'un sous-but.
if
syntax : (if condition step1 step2)
eet : Comme en Lisp si conditon est évaluée à NIL c'est step2 qui est appliquée sinon
c'est step1.
exemples :
(if (equal (get-goalnum *ps*) 1) (groud) (prop)) : Si le but courant (*ps* est l'état de la
preuve courante) est le premier sous-but, alors (ground) est appliquée, sinon (prop) est
appliquée.
let : Utilisation de Lisp dans les stratégies syntax : (let ((var_1 lexpr_1) ... (var_n
lexpr_n)) step) eet : var sont des symboles, et lexpr sont des expressions en Lisp. Let
permet de calculer quelques valeurs et de les appliquer aux stratégies. Elle est similaire à
let* dans le langage lisp.
exemple : (let ((input (qread 'Rule ?'))) (try input (query*) (query*))) : C'est un stratégie
simple appellée query (question). La dénition en Lisp de qread est utilisée pour générer
les règles Rule ? qui lit l'entrée de l'utilisateur.
Annexe C
Exemples PBS
Dans ce chapitre nous présentons quelques exemples de théories générées par l'outil PBS et
les preuves des chiers PVS ainsi obtenues. Toutes les théories ont été prouvées entièrement.
C.1 Dispenser
C.1.1 La Machine PVS : Dispenser
% Dispenser Machine
dispenser [ lifetime:nat ] : MACHINE
BEGIN
TYPES
DSTATE = `{stocked, unstocked}'
CONSTANTS
ok : nat = 0
notok : nat = 1
VARIABLES
dstate : DSTATE
given : nat
INVARIANT
`given <= lifetime'
INITIALIZATION
dstate := unstocked ||
given := 0
48
ANNEXE C. EXEMPLES PBS
OPERATIONS
restock =
dstate := stocked
give_drink =
PRE
`dstate = stocked AND given < lifetime'
THEN
dstate :: DSTATE ||
given := `given + 1'
END
is_stocked : nat =
`IF dstate = stocked THEN
ok
ELSE
notok
ENDIF'
count : nat = given
END dispenser
Fig. C.1 Machine PVS dispenser
49
ANNEXE C. EXEMPLES PBS
C.1.2 La Théorie PVS : Dispenser
%%% dispenser.pvs -- File generated by PBS
%% Theory: Dispenser Machine
dispenser [ lifetime:nat ]: THEORY
BEGIN
%% Type Definitions
DSTATE : TYPE = {stocked, unstocked}
%% Constant Definitions
ok: nat = 0
notok: nat = 1
%% General Type
dispenser_Type : TYPE = [#
dstate:DSTATE,
given:nat
#]
%% Invariant Type
dispenser : TYPE = { self: dispenser_Type |
given(self) <= lifetime }
%% Initialization
init : dispenser =
LET self =
(#
dstate := unstocked,
given := 0
#) IN
self
50
ANNEXE C. EXEMPLES PBS
%% Operations
Restock(self:dispenser) : dispenser =
LET self =
self WITH [
dstate := stocked
] IN
self
give_drink(self:dispenser |
dstate(self) = stocked AND
given(self) < lifetime) : dispenser =
LET self =
self WITH [
dstate := choose! (dstate:DSTATE) : ( TRUE ),
given := given(self) + 1
] IN
self
is_stocked(self:dispenser) : nat =
IF dstate(self) = stocked THEN
ok
ELSE
notok
ENDIF
count(self:dispenser) : nat =
given(self)
END dispenser
Fig. C.2 Théorie PVS dispenser
51
ANNEXE C. EXEMPLES PBS
52
C.1.3 Preuves des TCCs de la théorie Dispenser
Les TCCs engendrées par PVS sont déchargées automatiquement par la commande
Mx tcp
C.2 Ens : spécication d'un tableau
C.2.1 La Machine PVS de Ens1
Ens1[maxe : `posnat'] : MACHINE
BEGIN
PVS
`IMPORTING finite_sets@top'
VARIABLES
ens : `setof[nat]'
INVARIANT
`card(ens)<=maxe'
INITIALIZATION
ens := `emptyset[nat]'
OPERATIONS
ajout(n : nat) =
PRE
`NOT ens(n) AND card(ens)<maxe'
THEN
ens := `add(n,ens)'
END
END Ens1
Fig. C.3 Machine PVS Ens1
ANNEXE C. EXEMPLES PBS
C.2.2 La Théorie PVS de Ens1
%%% Examples/myExamples/Ens1.pvs -- File generated by PBS
%% Theory: Ens1 Machine
Ens1 [ maxe:posnat ]: THEORY
BEGIN
%% PVS Commands
IMPORTING finite_sets@top
%% General Type
Ens1_Type : TYPE = [#
ens:setof[nat]
#]
%% Invariant Type
Ens1 : TYPE = { self: Ens1_Type |
card(ens(self))<=maxe }
%% Initialization
init : Ens1 =
LET self =
(#
ens := emptyset[nat]
#) IN
self
53
ANNEXE C. EXEMPLES PBS
%% Operations
ajout(self:Ens1)(n:nat |
NOT ens(self)(n) AND card(ens(self))<maxe) : Ens1 =
LET self =
self WITH [
ens := add((n::nat),ens(self))
] IN
self
END Ens1
Fig. C.4 Théorie PVS Ens1
C.2.3 Preuves des TCCs de la théorie Ens1
Proof init_TCC1-1 for formula Ens1.init_TCC1
developed with SHOSTAK decision procedures
("" (SUBTYPE-TCC) (GRIND :THEORIES "finite_sets[nat]"))
Proof ajout_TCC1-1 for formula Ens1.ajout_TCC1
developed with SHOSTAK decision procedures
("" (SUBTYPE-TCC) (GRIND :THEORIES "finite_sets[nat]"))
Fig. C.5 Preuves TCCs Ens1
54
ANNEXE C. EXEMPLES PBS
CtxMenu : MACHINE
BEGIN
PVS
`IMPORTING CtxDistributeur, finite_sets@top'
CONSTANTS
nb_boissons
nb_pieces :
nat2boisson
nat2piece :
: nat = `card(BOISSONSET)'
nat = `card(PIECESET)'
: `[subrange(1,nb_boissons) -> BOISSON]'
`[subrange(1,nb_pieces) -> PIECE]'
END CtxMenu
Fig. C.6 Théorie de la machine PBS CtxMenu
C.3 CtxMenu
C.3.1 La Machine PBS de CtxMenu
(voir Fig.B.8)
55
ANNEXE C. EXEMPLES PBS
C.3.2 La théorie PVS de CtxMenu
(voir Fig.B.9)
56
ANNEXE C. EXEMPLES PBS
%%% CtxMenu.pvs -- File generated by PBS
%% Theory: CtxMenu Machine
CtxMenu : THEORY
BEGIN
%% PVS Commands
IMPORTING CtxDistributeur, finite_sets@top
%% Constant Definitions
nb_boissons: nat = card(BOISSONSET)
nb_pieces: nat = card(PIECESET)
nat2boisson: [subrange(1,nb_boissons) -> BOISSON]
nat2piece: [subrange(1,nb_pieces) -> PIECE]
%% General Type
CtxMenu_Type : TYPE = [# dummy: nat
#]
%% Invariant Type
CtxMenu : TYPE = CtxMenu_Type
END CtxMenu
Fig. C.7 Théorie PVS de CtxMenu
57
ANNEXE C. EXEMPLES PBS
Proof n for formula CtxMenu.nat2boisson_TCC1
developed with SHOSTAK decision procedures
(""
(INST * "(lambda (x:subrange(1, nb_boissons)): coca)")
(SKOLEM!)
(EXPAND "BOISSON?")
(PROPAX))
Proof nat2piece_TCC1-1 for formula CtxMenu.nat2piece_TCC1
developed with SHOSTAK decision procedures
("" (EXISTENCE-TCC) (INST * "(lambda (i:subrange(1, nb_pieces)):p1)"))
Fig. C.8 Preuves des TCCs la Théorie CtxMenu
C.3.3 Preuves des TCCs de la théorie CtxMenu
(voir Fig.B.10)
58
ANNEXE C. EXEMPLES PBS
CtxDistributeur : MACHINE
BEGIN
PVS
`IMPORTING finite_sets@top'
TYPES
BOISSON = {coca, pepsi, orangina, perrier}
PIECE = {p1, p2, p5}
CONSTANTS
BOISSONSET : `finite_set[BOISSON]=fullset[BOISSON]'
PIECESET : `finite_set[PIECE]=fullset[PIECE]'
tarif : `[BOISSON -> nat]'
val_piece : `[PIECE -> nat]'
OPERATIONS
afficher_boisson(bb : BOISSON) =
SKIP
afficher_piece(pp : PIECE) =
SKIP
END CtxDistributeur
Fig. C.9 Machine PVS de CtxDistributeur
C.4 CtxDistributeur
C.4.1 La Machine PBS de CtxDistributeur
(voir Fig.B.11)
59
ANNEXE C. EXEMPLES PBS
CtxDistributeur : MACHINE
BEGIN
PVS
`IMPORTING finite_sets@top'
TYPES
BOISSON = {coca, pepsi, orangina, perrier}
PIECE = {p1, p2, p5}
CONSTANTS
BOISSONSET : `finite_set[BOISSON]=fullset[BOISSON]'
PIECESET : `finite_set[PIECE]=fullset[PIECE]'
tarif : `[BOISSON -> nat]'
val_piece : `[PIECE -> nat]'
OPERATIONS
afficher_boisson(bb : BOISSON) =
SKIP
afficher_piece(pp : PIECE) =
SKIP
END CtxDistributeur
Fig. C.10 La théorie PVS de CtxDistributeur
C.4.2 La théorie PVS de CtxDistributeur
(voir Fig.B.12)
60
ANNEXE C. EXEMPLES PBS
Proof BOISSONSET_TCC1-1 for formula CtxDistributeur.BOISSONSET_TCC1
developed with SHOSTAK decision procedures
(""
(EXPAND "fullset")
(EXPAND "is_finite")
(INST 1 "5"
"LAMBDA(x:BOISSON): if x = coca then 0 elsif x = pepsi then 1 elsif x
= orangina then 3 else 4 endif")
(GRIND))
Proof PIECESET_TCC1-1 for formula CtxDistributeur.PIECESET_TCC1
developed with SHOSTAK decision procedures
(""
(EXPAND "fullset")
(EXPAND "is_finite")
(INST 1 "5"
"LAMBDA(x:PIECE): if x = p1 then 0 elsif x = p2 then 1 elsif x
= p5 then 3 else 4 endif")
(GRIND))
Fig. C.11 Preuves des Tccs de la théorie PVS de CtxDistributeur
C.4.3 Preuves de la théorie PVS de CtxDistributeur
(voir Fig.B.13)
61
Table des gures
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
Structure d'une Machine Abstraite . . . . .
Structure d'une Machine d'implantation . .
Fonctionnement de PBS . . . . . . . . . . .
Machine Abstraite B Counter . . . . . . . .
Machine PBS Counter . . . . . . . . . . . .
Théorie PVS Counter . . . . . . . . . . . .
Ranement B de Counter . . . . . . . . . .
Ranement de la Machine PBS de Counter
Théorie PVS du ranement de Counter . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
6
8
9
10
13
15
15
18
C.1 Machine PVS dispenser . . . . . . . . . . . . . . . . .
C.2 Théorie PVS dispenser . . . . . . . . . . . . . . . . . .
C.3 Machine PVS Ens1 . . . . . . . . . . . . . . . . . . . .
C.4 Théorie PVS Ens1 . . . . . . . . . . . . . . . . . . . .
C.5 Preuves TCCs Ens1 . . . . . . . . . . . . . . . . . . .
C.6 Théorie de la machine PBS CtxMenu . . . . . . . . . .
C.7 Théorie PVS de CtxMenu . . . . . . . . . . . . . . . .
C.8 Preuves des TCCs la Théorie CtxMenu . . . . . . . . .
C.9 Machine PVS de CtxDistributeur . . . . . . . . . . . .
C.10 La théorie PVS de CtxDistributeur . . . . . . . . . . .
C.11 Preuves des Tccs de la théorie PVS de CtxDistributeur
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
49
51
52
54
54
55
57
58
59
60
61
62
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Téléchargement