SPIN è un sistema per il model checking per proprietà di programmi software asincroni.
Il sistema è reperibile nel sito Spinroot.
Linguaggio per la scrittura di programmi asincroni.
PROMELA: linguaggio testuale di tipo imperativo con costrutti per la descrizione di processi paralleli e comunicanti.
Linguaggio per la scrittura delle proprietà da verificare.
LTL: Linear Temporal Logic.
Variabili dei seguenti tipi di dati di base predefiniti
Dichiarazioni variabili
<tipo><variabile>;<tipo><variabile> ;
int state;
byte msg;
Dichiarazioni array
<tipo><variabile>[dimensione];
byte stato[100] (locazioni 0..99)_
Assegnamento
<nome><variabile>=<espressione>;
Es. state = state + 1
Azione nulla
skip
Condizione
(<espressione booleana>)
Es. (a == b)
Per eseguire un processo serve
proctype <nome> ([parametri])
{ <body> }
Il corpo comprende dichiarazioni locali e/o istruzioni.
Esempio: dichiarazione di una variabile globale (statoglobale) e di due processi (A e B).
proctype A (byte parametro)
{ byte statolocale;(parametro==1) ->statolocale=4 }
byte statoglobale
proctype B ()
{ (statoglobale==4)-> statoglobale=statoglobale-1 }
(; e -> sono due separatori di istruzioni tra loro intercambiabili)
Possono essere associati solo parametri di tipo base e non array.
In ogni specifica è necessario dichiarare un processo iniziale
init{ <body>}
(assimilabile ad un main() in un programma C).
Nel processo init è possibile inizializzare variabili globali e instanziare processi
init{ statoglobale=4; run A(1); run B() }
il corpo comprende dichiarazioni locali e/o istruzioni.
Istanziazione di processo
run ([valori parametri])
(Es. dopo aver inizializzato A non si aspetta la terminazione del processo A per inizializzare B).
Init{ statoglobale=4; run A(1); run B() }
byte stato = 1
proctype A() { (stato ==1)-> stato = stato +1 }
proctype B() { (stato ==1)-> stato = stato - 1 }
init{ run A(); run B() }
Possibili esecuzioni:
L’interfogliazione può essere limitata rendendo atomica l’esecuzione di sequenze di istruzioni.
byte stato = 1
proctype A() { atomic {(stato ==1)-> stato = stato +1 }}
proctype B() { atomic {(stato ==1)-> stato = stato -1 }}
init{ run A(); run B() }
Possibili esecuzioni:
PROMELA permette forme di comunicazione sincrona e asincrona mediante canali.
I canali sono tipi di base dichiarati come gli altri tipi di base
chan <nomecanale>= [dim] of { tipo1, .., tipon }
Esempio:
chan coda = [10] of { short, short }
I messaggi sono strutturati in coppie di interi. La capacità del buffer è di dieci unità.
chan <nomecanale> = [dim] of { tipo1, .., tipon }
Comunicazione asincrona (dim > 0)_
Istruzione di Invio
<nomecanale>! <expr1>,..,<exprn>
L’operazione di invio è eseguibile solo se il buffer associato al canale non è pieno.
Il messaggio è memorizzato in coda al buffer;
Se vengono passati solo m < n valori, gli ultimi n-m campi del messaggio hanno valore indefinito.
Istruzione di Ricezione
<nomecanale>? <Var1>,..,<Varn>
L’operazione di ricezione è eseguibile solo se il buffer del canale non è vuoto;
L’operazione estrae il messaggio dalla testa del buffer e memorizza le componenti del messaggio in ordine nelle variabili;
Se sono presenti solo m < n variabili, gli ultimi n-m campi del messaggio sono ignorati.
Per verificare il numero di messaggi in coda ad un canale
len (<nomecanale> )
atomic { (len(canale) > 1) -> canale?X }
Per condizionare la ricezione alla presenza di valori specifici nel messaggio
<nomecanale>? <Const1> ,..,<Varn>
Al posto di una variabile si può avere un valore costante;
L’istruzione viene eseguita solo se la componente corrispondente a una costante ha lo stesso valore espresso dalla costante.
Canale?0
eseguibile solo se il messaggio in testa al buffer è 0
Variante in forma di condizione
Canale?[0]
Condizione verificata se Canale? 0 è eseguibile. Non altera il contenuto del buffer.
I nomi dei canali per le operazioni di comunicazione possono essere parametrici e comunicati dinamicamente ai processi
proctype A(chan c1)_
{ chan c2 ;
c1?c2;
c2!25
}
sul canale parametrico c1 A riceve il nome di un canale (C2) e su quel canale trasmette 25. Nell’esempio il canale effettivamente usato è “canale”.
Init
{
short X;
chan passaggio = [1] of { chan };
chan canale = [1] of { short };
run A( passaggio );
paggaggio!canale;
canale?X
}
chan <nomecanale>[0] of { tipo1, .., tipon }
con dimensione 0 del buffer la comunicazione è sincrona nella forma dell’ HANDSHACKING.
Esempio:
chan canale = [0] of {int}
proctype A (){ canale!125; canale!126 }
proctype B (){ int X; canale?X }
init {run A(); run B()}
Solo il processo B può terminare dopo la prima sincronizzazione.
Il processo A rimane in attesa della seconda sincronizzazione e non può terminare (stato waiting).
Costrutto di scelta
if
:: istruzione1
:: istruzione 2
:: istruzione n
fi
Tra le istruzioni elencate, viene scelta una istruzione eseguibile; Se più di una istruzione è eseguibile la scelta è non-deterministica; L’istruzione If non è eseguibile quando nessuna delle istruzioni è eseguibile.
Costrutto iterativo
do
:: istruzione1
:: istruzione 2
:: istruzione n
od
proctype contatore()
{ int X =1;
do
:: (X != 0); if
:: X=X+1
:: X=X-1
fi
:: (X == 0); break
od }
Costrutto di salto incondizionato
<etichetta>:
.
.
goto <etichetta>
Il salto incondizionato è una istruzione sempre eseguibile;
La scelta dei nomi delle etichette deve essere fatta con cura: le etichette che abbiano i seguenti prefissi “end“, “progress“, “accept” assumono significato specifico chiarito nelle lezioni successive.
Processi ricorsivi descritti mediante run (spawn) e canali.
Esempio della definizione per il fattoriale.
proctype fact(int n; chan p)
{ chan child = [1] of { int };
int result;
if :: (n <= 1) -> p!1
:: (n >= 2) -> run fact(n-1, child); child?result; p!n*result
fi }
init { chan child = [1] of { int };
int result;
run fact(4, child);
child?result }
SPIN, permettendo di definire solo programmi a stati finiti, consente solo la creazione di un numero limitato (dall’implementazione) di processi e dunque non consente di calcolare il fattoriale per numeri arbitrari.
1. Introduzione ai metodi formali di specifica
2. Semantica dei formalismi di specifica
3. Astrazione e Bisimulazione debole
4. FSM: Macchine a Stati Finiti
5. FSM: Non-determinismo e succintezza
7. FSM e Parallelismo – seconda parte
8. FSM e Parallelismo – terza parte
9. Promela
10. Specifica e verifica in SPIN
11. Proprietà di liveness in SPIN
12. Specifica di proprietà in Logica Temporale Lineare
13. Comportamenti infiniti: Automi di Büchi
14. Model checking di LTL basato su automi
15. Specifica di sistemi real time: Automi Temporizzati
16. Proprietà degli Automi Temporizzati
17. Problemi di decisione negli Automi Temporizzati
18. Il sistema di verifica UPPAAL