Vous êtes sur la page 1sur 27

Introduction à l’outil Spin et au langage Promela

Module SDSC
Institut Galilée
Master 2 PLS

Page web : http://lipn.fr/~rodriguez/teach/sdsc/2015-16/


Enseignant : César Rodríguez
Transparents : préparés par Sami Evangelista, modifiés par César Rodríguez
Présentation de l’outil Spin 2/27

Ï logiciel open source développé initialement par Bell Labs


Ï permet d’analyser formellement des programmes concurrents
Ï langage de description : promela (process meta language)
Ï propriétés analysables : accessibilité, temporelles
Ï page web : http://spinroot.com/spin/whatispin.html
Ï cours en ligne avec plus d’informations :
http://lipn.univ-paris13.fr/~petrucci/poly_spin.ps.gz
Plan 3/27

Le langage Promela

Utilisation de Spin
Structure d’un programme Promela 4/27

Un programme Promela est constitué d’un ensemble de processus.


Ï Chaque processus est donné par une déclaration proctype.
Ï Spin transforme chaque proctype vers un automate.

Deux mécanismes de synchronisation entre processus :


Ï Les variables globales (déclarées hors processus).
Ï Les canaux de communication permettant l’échange de messages entre
processus.
Structure d’un programme Promela — Exemple 5/27
Éléments de base du langage 6/27

Ï beaucoup de points communs avec le C :


Ï le “ ;” pour terminer les instructions
Ï la déclaration des variables
Ï les types de base : int, short, byte, bool
Ï les tableaux
Ï les affectations
Ï le printf
Ï Mais on ne retrouve pas les instructions de contrôle (if, for, . . . ) du C.
Exemple :
int i = 10;
short s [ 1 0 ] ;
i ++;
s [2] = 4;
p r i n t f ( " i ␣=␣%d␣ e t ␣ s [ 2 ] ␣=␣%d\n" , i , s [ 2 ] ) ;
Déclaration des processus 7/27

proctype p r o c ( t y p e A r g 1 a r g 1 ; . . . ; typeArgN argN ) {


/∗ code du p r o c e s s u s ∗/
}

Remarques :
Ï Un processus peut recevoir des arguments à sa création.
Ï Attention, on utilise ; au lieu de , pour la déclaration d’arguments
Ï Un processus peut être créé :
Ï statiquement : à l’initialisation du programme (mot-clé active)
Ï dynamiquement : avec une instruction run exécutée par un autre processus
Le processus init 8/27

init {
/∗ code du p r o c e s s u s i n i t ∗/
}

Remarques :
Ï Le processus init (facultatif) est créé à l’initialisation du programme.
Ï On l’utilise généralement pour
Ï initialiser des variables globales
Ï et lancer d’autres processus.
Processus créés statiquement 9/27

Ï On les déclare avec le mot-clé active.


Ï On peut déclarer N processus.
Ï Les arguments prennent alors une valeur par défaut.
Ï Exemple : 0 pour les arguments de type int.

a c t i v e [ N ] proctype p r o c ( t y p e A r g 1 a r g 1 ; . . . ,
typeArgN argN ) {
/∗ code du p r o c e s s u s ∗/
}
Processus créés dynamiquement 10/27

Ï On les lance avec l’instruction run.


Ï On doit lui passer tous les arguments déclarés pour le processus.

proctype p r o c ( t y p e A r g 1 a r g 1 ; . . . ;
typeArgN argN ) {
/∗ code du p r o c e s s u s ∗/
}
...
run p r o c ( x1 , . . . , xN )
...
Les processus — Exemple 11/27

a c t i v e [ 2 ] proctype s t a t ( ) {
p r i n t f ( " s t a t i q u e \n" ) ;
}
proctype dyn ( i n t x ; i n t y ) {
p r i n t f ( " dynamique ␣ : ␣(%d,%d ) \ n" , x , y ) ;
}
init {
run dyn ( 1 , 2 ) ;
run dyn ( 3 , 4 ) ;
}

Simulation du programme :
$ spin prog . pml
dynamique : (1 ,2)
statique
statique
dynamique : (3 ,4)
Les canaux de communication 12/27

Ï Les canaux sont utilisés par les processus pour s’échanger des messages.
Ï Il faut se les représenter comme des files FIFO de messages.
Ï Les messages stockés dans les canaux sont typés.
Ï Déclaration d’un canal c de N messages contenant des N-uplets.

chan c = [ N ] o f { t y p e 1 , . . . , typeN }

Ï Bonne pratique : mettre un nom symbolique (un mtype) dans le type


des messages pour pouvoir distinguer les messages.
Exemple :

mtype = { r e q u e t e , r e p o n s e , e r r e u r }
chan c = [ 1 ] o f { mtype , i n t }
Réception/émission sur un canal 13/27

canal ! donnees /∗ é m i s s i o n ∗/
canal ? donnees /∗ r é c e p t i o n ∗/

Remarques :
Ï Le récepteur est bloqué si le canal est vide (il attend un message).
Ï L’émetteur est bloqué si le canal est plein (il attend qu’il se vide).
Ï Pour un rendez-vous (canal de taille 0) émetteur et récepteur doivent
être simultanèment sur les instructions d’émission.
Ï Côté récepteur :
Ï On affecte aux variables apparaissant après le ’ ?’ les valeurs contenues
dans le message.
Ï Si des constantes apparaissent dans les données le message reçu devra
contenir ces valeurs (sinon le processus sera bloqué).
Exemple :

c? i ; /∗ j ’ attends un e n t i e r que j e stocke dans i ∗/


c ?5; /∗ j ’ attends l ’ e n t i e r 5 ∗/
Réception/émission sur un canal — Exemple 14/27

chan c = [ 0 ] o f { i n t , i n t } ;
a c t i v e proctype p ( ) {
int x , y ;
c ! 1 0 , 1 2 ; c?x , y ; /∗ p envoie p u i s r e c o i t ∗/
p r i n t f ( "p␣ : ␣ j ’ a i ␣ r e c u ␣(%d , ␣%d ) \ n" , x , y ) ;
}
a c t i v e proctype q ( ) {
int x , y ;
c?x , y ; c ! 1 7 , 4 4 ; /∗ q r e c o i t p u i s envoie ∗/
p r i n t f ( "q␣ : ␣ j ’ a i ␣ r e c u ␣(%d , ␣%d ) \ n" , x , y ) ;
}

Simulation du programme :
$ spin test . pml
q : j ’ ai recu (10 , 12)
p : j ’ ai recu (17 , 44)
2 processes created
Expressions = instructions (bloquantes) 15/27

A différence du C, chaque expression Promela est aussi une instruction :

i = 3 ; /∗ a f f e c t a t i o n , ne bloque jamais ∗/
i == 3 ; /∗ ex é c u t i o n bloqu ée jusqu ’ à que i s o i t 3 ∗/
i < 4 | | t a b [ 7 ] == 4 /∗ s i t u a t i o n analogue ∗/
p r i n t f ( " . . . " ) ; /∗ ne bloque pas ( en p r i n c i p e ) ∗/

Ï Le processus est bloqué tant qu’une condition n’est pas réalisée.


Ï Dès que la condition se réalise (grâce à l’action d’un autre processus) il
peut continuer à exécuter des instructions.

Les opérations sur les canaux peuvent aussi bloquer l’exécution :


Ï can ! var bloque le processus si can est plein
Ï can ? var bloque le processus si can est vide
Ï can ? 5 bloque le processus si can ne contient pas l’entier 5
Instructions bloquantes — Exemple 16/27
Séparateurs d’instructions 17/27

Ï On sépare les instructions par des ; ou des −>


Ï Tous les deux ont exactement la même sémantique, mais :
Ï −> souvent après une expression pouvant bloquer le processus
Ï ; souvent après une instruction ne pouvant pas bloquer le processus
Ï Ceci améliore la lisibilité du code.

Exemple :
( p o r t e F e r m e e == 1 ) −> a s c e n c e u r D e m a r r e = 1 ; e t a g e ++

Ï Dès que la condition se réalise (grâce à l’action d’un autre processus) il


peut continuer à exécuter des instructions.
L’instruction if 18/27

if
:: alternative1
...
: : alternativeN
: : e l s e −> a l t e r n a t i v e E l s e
fi

1. Évalue les alternatives 1 à N dont la garde est exécutable.


Ï (La garde est la première instruction de chaque alternative.)
2. Sélectionne de manière indéterministe une alternative parmi celles-ci et
exécute cette alternative.
3. Exécute alternativeElse si aucune des gardes n’est exécutable.
4. Si aucune des gardes n’est exécutable et qu’il n’y a pas de else, le
processus est bloqué.
Ï Il pourra s’exécuter si une des gardes devient exécutable (ex : en cas de
réception d’un message).
B L’ordre des alternatives n’a pas d’importance :
Ï Les gardes seront toutes évaluées.

Ï On n’exécute pas forcément la première alternative dont la garde est vraie.


L’instruction if — Exemple 19/27

if

/∗ branche ex é c u t a b l e s u r r é c e p t i o n d ’ un message de
type msg contenant une v a l e u r i s u r l e c a n a l c ∗/
: : c ?msg , i −> . . .

/∗ branche ex é c u t a b l e s u r r é c e p t i o n d ’ un message de
type ack contenant une v a l e u r i s u r l e c a n a l c ∗/
: : c ? ack , i −> . . .

/∗ branche ex é c u t a b l e s i l a v a r i a b l e k vaut 1 ∗/
: : k == 1 −> . . .

/∗ branche ex é c u t a b l e s i aucune a u t r e ne l ’ e s t ∗/
: : e l s e −> . . .

fi
L’instruction do 20/27

do
:: alternative1
...
: : alternativeN
: : e l s e −> a l t e r n a t i v e E l s e
od

Ï Même sémantique que le if mais le bloc do est réexécuté après


l’exécution d’une des branches.
Ï Par défaut, on ne sort jamais du do : il faut pour cela placer une
instruction break dans une des branches.
L’instruction do — Exemple 21/27

/∗ on f a i t l a somme de d i x e n t i e r s r é ceptionn é s
s u r l e c a n a l c et on termine ∗/
i = 0;
y = 0;
do
: : i < 10 −>
c?x ;
y = y + x;
i = i + 1
: : i == 10 −>
break
od
Les assertions 22/27

assert ( condition ) ;

Ï Si la condition n’est pas vérifiée le programme s’arrête.


Exemple :
byte s t a t e = 1 ;
a c t i v e proctype A ( ) {
( s t a t e == 1)−> s t a t e = s t a t e + 1 ;
a s s e r t ( s t a t e == 2 )
}
a c t i v e proctype B ( ) {
( s t a t e == 1 ) −> s t a t e = s t a t e − 1 ;
a s s e r t ( s t a t e == 0 )
}
Plan 23/27

Le langage Promela

Utilisation de Spin
Spin en mode simulation 24/27

On appelle spin en lui donnant le programme à simuler.


$ spin programme . pml

Ï En mode simulation, spin simule une exécution possible du système.


Ï Les instructions printf sont évaluées.
Ï La simulation s’arrête en cas d’assertion non vérifiée.
Spin en mode vérification 25/27

1. On appelle spin avec l’option −a.


⇒ Spin génère un fichier pan.c (pan = protocol analyser) qui est
l’algorithme d’exploration de l’espace des états accessibles.
2. On compile puis exécute pan.c.
3. Si une erreur est trouvée, un fichier avec l’extension trail est créé.
Ï Ce fichier décrit une exécution qui mène à l’erreur trouvée.
4. On utilise alors spin avec l’option -t pour afficher cette exécution.

$ spin -a programme . pml


$ gcc pan . c -o pan
$ ./ pan
$ spin -t programme . pml

Ï En mode vérification, spin explore l’espace des états accessibles du


programme (= simule toutes les exécutions possibles du programme).
Ï Les instructions printf sont ignorées.
Ï L’exploration s’arrête en cas d’assertion non vérifiée.
Options de ligne commande 26/27

Spin en mode simulation :


Ï -c : afficher "graphiquement" les émissions et réceptions sur les canaux
Ï -p : afficher les opérations exécutées
Ï -l : afficher la valeur des variables locales
Ï -g : afficher la valeur des variables globales
Ï -i : simulation interactive, l’utilisateur choisit la transition suivante

En mode vérification :
Ï -search : spin génère, compile et exécute pan.c
Ï -replay : similaire à spin -t
Interface graphique ispin.tcl 27/27

Vous aimerez peut-être aussi