Sei sulla pagina 1di 47

Spin & Alloy a confronto

Gasparri Danny
Comparazione di due strumenti di model checking per la verifica dei sistemi informativi

degli studi di Milano-Bicocca A.A.2011/2012 Sicurezza dei sistemi informatici Professor Claudio Ferretti

Universit

Sommario
Introduzione............................................................................................... 4

Introduzione al caso di studio ................................................................ 5


Promela & Spin ........................................................................................... 7

Promela .............................................................................................. 7 Spin ................................................................................................... 8


Alloy ......................................................................................................... 9

Il linguaggio ........................................................................................ 9 Il tool ................................................................................................. 9


Caso di studio ........................................................................................... 10

Implementare il modello e le propriet ...................................................12 Descrizione dellimplementazione per Spin ...........................................12 Descrizione dellimplementazione Alloy ................................................14
Implementazione Promela per Spin.............................................................. 16

Macro delle pre-post condizioni delle entit .............................................16 Membro...........................................................................................16 Libro ...............................................................................................16 Macro delle pre-post condizioni delle azioni delle associazioni ...................17 Prestito ...........................................................................................17 Prenotazione ....................................................................................18 Variabili globali ...................................................................................19 Definizione dei processi ........................................................................19 Membro...........................................................................................19 Libro ...............................................................................................19 Prestito ...........................................................................................20 Prenotazione ....................................................................................20 Propriet in LTL ...................................................................................21 Definizione dei predicati .......................................................................22 Definizione dei predicati can_xxx ........................................................22
Specifiche Alloy........................................................................................ 23

Dichiarazione iniziale ed importazione ....................................................23 Classi .................................................................................................23 Predicati di invarianza (no change) ........................................................24 Inizializzazione ....................................................................................24 Azioni ................................................................................................25 Acquisisci ........................................................................................25 1

Iscrivi .............................................................................................25 Prende in prestito .............................................................................26 Prenota ...........................................................................................27 Cancella prenotazione .......................................................................28 Restituisci ........................................................................................28 Ritira ..............................................................................................29 Cancella Iscrizione ............................................................................30 Scarta .............................................................................................30 Rinnova Prestito ...............................................................................31 Lista delle 15 propriet da verificare ......................................................32 Propriet 1 e 2 .................................................................................32 Propriet 3 ......................................................................................32 Propriet 4 ......................................................................................33 Propriet 5 ......................................................................................33 Propriet 6 ......................................................................................33 Propriet 7 ......................................................................................33 Propriet 8 ......................................................................................34 Propriet 9 ......................................................................................34 Propriet 10 .....................................................................................34 Propriet 11 .....................................................................................34 Propriet 12 .....................................................................................35 Propriet 13 .....................................................................................35 Propriet 15 .....................................................................................35 Propriet 14 .....................................................................................36
Analisi dei risultati ..................................................................................... 42

Linguaggio di specifica del modello (Promela vs Alloy) .............................42 Astrazione sulle istanze delle entit .....................................................42 Rappresentazione di strutture di entit e associazioni ............................42 Rappresentazione degli scenari dei SI .................................................42 Linguaggio di specifica delle propriet (LTL vs Alloy) ................................42 Astrazione sulle istanze delle entit .....................................................42 Specifica delle propriet dei SI ...........................................................42 Accesso a stati ed eventi ...................................................................43 Tempo di esecuzione e numero di istanze delle entit ...............................43
Conclusioni .............................................................................................. 44 Bibliografia ............................................................................................... 45

Introduzione
Le tecniche di verifica a stati finiti vengono usate per controllare che i programmi possiedano certe propriet difficili, se non impossibili, da trovare con il test randomico. Creando un modello del programma da testare, si pu controllare se il primo possiede certe propriet e, se stato creato correttamente (cio se il comportamento modellato rispecchia quello dellapplicazione), ci si pu aspettare che anche per il programma valgano le stesse propriet. Le propriet che vengono verificate si dividono in due categorie: safety properties (nothing bad happens) come lassenza di deadlock o il controllo che X sia sempre diversa da 10 e liveness properties (something good eventually happens) come il controllo sulla terminazione del sistema o la Response (se accade X allora, prima o poi, accadr anche Y). Esempio: i difetti nella sincronizzazione nei programmi multi-thread possono sollecitare i difetti molto raramente, o sotto condizioni quasi impossibili da ricreare nel testing, ma la verifica a stati finiti pu individuarli considerando in modo esaustivo tutti i possibili interleaving dei processi concorrenti. I sistemi che si occupano della verifica a stati finiti si chiamano model checkers, in questo approfondimento ne verranno confrontati due in particolare: Spin e Alloy; il primo tool verifica modelli in linguaggio Promela il secondo invece usa un linguaggio omonimo allo strumento.

Nello schema seguente viene rappresentato in breve il funzionamento di uno strumento di model checking.

Nel dettaglio i Model checkers si dividono in quattro categorie. Explicit state model checkers, come Spin, cadp e FDR2 usano una rappresentazione esplicita della sistema di transizioni associate alla specifica del modello. Questo sistema di transizioni pu essere controllato a priori per la verifica di propriet (CADP e FDR2), oppure on-the-fly mentre si controlla una propriet (Spin). I model checker simbolici, come NuSMV, rappresentano i sistemi di transizione come una formula booleana. I bounded model checkers, come Alloy e NuSMV, considerano le tracce del sistema di transizione e le rappresentano usando una formula booleana. I Constraint satisfaction model checker, come ProB, usano la programmazione logica per verificare le specifiche delle propriet. Alloy e FDR2 usano lo stesso linguaggio sia per la specifica del modello che per le propriet (logica del primo ordine per il primo e CSP per il secondo).

Introduzione al caso di studio

I sistemi informativi (SI) hanno un ruolo fondamentale nella societ attuale: supportano i processi di business e condividono dati organizzativi. Ancora oggi, anche se essi sono uno dei primi domini applicativi dellinformatica, il loro sviluppo dipende principalmente da processi informali e manuali. Il problema studiato in questa relazione la validazione formale delle specifiche dei SI 5

usando il model checking. Il model checking una tecnica interessante per la validazione delle specifiche dei sistemi informativi, per una serie di motivi: produce una copertura maggiore della simulazione e del testing, inoltre richiede meno interazione umana rispetto alla prova formale di teoremi ed ha la capacit di gestire le propriet di safety e liveness. La validazione delle specifiche dei SI di particolare interesse nel model-driven engeneering (MDE ingegnerizzazione basata guidata dai modelli / progettazione basata sui modelli) e programmazione generativa, che mira a creare limplementazione di un sistema dai modelli. Se esistessero degli algoritmi di generazione corretti, una persona dovrebbe avere solo bisogno di validare i modelli per produrre sistemi corretti, cosa che porterebbe ad avere un notevole risparmio di risorse. I linguaggi di specifica per SI MDE di norma non hanno model checker dedicati; dato che lo sviluppo di un model checker un processo lungo e visto che ci sono degli strumenti gi esistenti pi semplice scegliere uno strumento disponibile, gi mantenuto da un team specializzato nel model checking, piuttosto che crearne uno dal nulla anche se non ha un linguaggio creato per il nostro scopo. In questa relazione vengono confrontati Spin e Alloy. Il confronto basato su un singolo caso di studio che rappresentativo della struttura e delle propriet dei sistemi informativi. La comparazione cerca di rispondere alle seguenti domande: Il linguaggio di modellazione del model checker adatto a modellare sistemi informativi? questo importante soprattutto nella MDE, visto che il modello deve essere tradotto automaticamente in codice sorgente. Il linguaggio di specifica delle propriet adatto a descrivere le propriet dei SI? Il model checker in grado di controllare un numero sufficiente di istanze di entit di un SI ? Il caso di studio si concentra sulla parte di controllo di un sistema informativo, che determina la sequenza delle azioni che il SI deve accettare. La validazione del comportamento di input-output e le interazioni con linterfaccia grafica sono state omesse.

Promela & Spin


Promela

Promela (Protocol/Process Meta Language) un linguaggio di modellazione orientato alla verifica a stati finiti. Questo linguaggio stato ideato per controllare la logica dei sistemi paralleli. Ad ogni modello creato corrisponde una macchina a stati finiti che verr usata da Spin per verificare se il primo ha le propriet che ci interessano. Questo linguaggio ispirato al C, per questo motivo un linguaggio imperativo, che ha per dei costrutti per gestire i processi concorrenti. Le variabili di stato possono essere globali ed accedute da ogni processo. Promela offre tipi base di variabili come char, bit, int ed array di questi tipi. I processi possono comunicare tramite scrittura e lettura di un canale(channel), in modo sincrono (usando un canale di lunghezza 0), o in modo asincrono(usando un canale di lunghezza maggiore di zero). L'operatore atomic permette di considerare uno statement composto come una singola transizione atomica, eccetto quando questa composizione contiene uno statement bloccante, come una scrittura bloccante o la lettura da un canale, in questi casi l'esecuzione del costrutto atomic pu essere interrotta ed il controllo trasferito ad un altro processo. Gli statements possono essere etichettati e queste etichette possono essere usate nelle formule LTL. La Linear Temporal Logic (LTL) una logica con riferimenti a stati temporali. In LTL si possono scrivere formule riguardanti li futuro dei percorsi dei modelli di Kripke. Spin gestisce una LTL proposizionale, con i tradizionali operatori always, eventually e until. Gli elementi fondamentali del linguaggio sono: Variabili: locali o globali, tipizzate; Canali: sincroni / asincroni, buffer FIFO di dimensione specificata; Asserzioni: verifica di propriet(LTL); Atomic: composizione di statement da eseguire come se fossero un unico statement; Send & Receive: operazioni per luso dei canali.

Spin
Spin fu uno dei primi model checker sviluppati, gi nel 1980 ci fu la prima versione per mano di Gerard Holzmann dei laboratori Bell. Egli introdusse l'approccio, ora classico, per l'on-the-fly LTL model checking. Prendendo in ingresso un sistema di transizioni scritte in linguaggio Promela, questo strumento verifica la veridicit delle propriet LTL inserite nelle asserzioni. Spin genera il codice sorgente C di un verificatore on-the-fly, una volta compilato, questo verificatore controlla se la propriet soddisfatta dal modello. Lavorare on-the-fly significa che Spin evita la costruzione di un grafo globale di transizione tra gli stati, ci implica che le transizioni vengano rieseguite per ogni propriet da verificare; perci, se ci sono n propriet da verificare, la stessa transizione potenzialmente eseguita n volte, questo numero pu diminuire a seconda delle ottimizzazioni.

Alloy
Il linguaggio
Alloy un linguaggio di modellazione basato sulla FOL (First Order Logic) che sfrutta ben tre livelli di astrazione diversi: Paradigma orientato agli oggetti; Teoria degli insiemi; Atomi e relazioni Il Paradigma object oriented il livello di astrazione pi alto del linguaggio, molto utile per definire in modo semplice modelli facilmente comprensibili (per persone che hanno usato in precedenza linguaggi O.O.). La teoria degli insiemi il livello di astrazione intermedio per Alloy, sfrutta i concetti di insiemi, elementi e relazioni tra elementi ed insiemi. Viene usato di norma in combinazione con oggetti del livello superiore. Il livello di astrazione pi basso quello basato su atomi e relazioni, la vera semantica del linguaggio, ma di norma non viene usato perch, non avendo costrutti, aiuta poco il programmatore. Viene usato comunemente per la comprensione del funzionamento del solver. Gli elementi fondamentali del linguaggio sono: Signatures: costrutto simile alle classi dei linguaggi di programmazione object-oriented che supportano l'ereditariet(Insiemi e relazioni sono definiti da signatures); Fact: sono i limiti che vengono imposti manualmente, i vincoli che vengono dati al sistema; Operazini su insiemi: unione, intersezione, differenza; Quantificatori: esistenziale ed universale; Asserzioni: propriet da verificare (FOL).

Il tool
Alloy un model checker simbolico che fu sviluppato dal Software Design Group del MIT nel 1997; venne creato appositamente per supportare il checking tramite metodi formali leggeri. Lintento dei suoi creatori stato quello di fornire uno strumento di analisi automatica, in contrasto con le tecniche di prova di teoremi usate da altri linguaggi. Lo sviluppo del tool era ispirato allanalisi dei model checker, termine che si usa in modo improprio per Alloy. In realt sarebbe pi corretto chiamarlo analyzer, perch la parte di checking effettivo viene fatta da un SAT-solver booleano(selezionabile dallutente). I SAT-solver vengono invocati da Alloy per verificare la soddisfacibilit degli assiomi definiti nel modello, trovando controesempi per propriet (teoremi) che dovrebbero essere limitate dagli assiomi. Alloy oltre a fare da ambiente di sviluppo aiuta a comprendere i controesempi tramite rappresentazioni grafiche.

Caso di studio

Questa sezione presenta i requisiti utente per il sistema informativo di una biblioteca, questi verranno usati per la verifica formale delle propriet. Di seguito la definizione di alcuni concetti chiave. Verranno modellati due tipi di entit: Member: Essere un membro della biblioteca, significa essere iscritti ad essa (e non aver ancora cancellato liscrizione). o Join: una persona pu iscriversi alla biblioteca e diventare membro. o Leave: un membro pu cancellare la sua iscrizione alla biblioteca. Book: libro o Acquire: un libro che manca alla biblioteca pu essere acquisito da essa. o Discard: un libro che non in prestito n stato prenotato pu essere scartato.

Oltre alle entit compariranno nel modello due tipi di relazione Loan: Prestito, un libro pu essere preso in prestito da un utente, se il libro non in gi in prestito e non stato prenotato. o Lend: Prendere in prestito. o Renew: Rinnovare un Prestito, il prestito di un libro pu essere rinnovato dal membro che lha preso in prestito, se il libro non stato prenotato. o Return: un membro che ha preso in prestito un libro lo pu Restituire. Reservation: Prenotazione o Reserve: un membro pu prenotare un libro, se gi stato preso in prestito da qualcun altro. o Take: un libro pu essere ritirato da un membro se il libro stato restituito e il membro il primo nella lista di prenotazione. o Cancel: un utente che ha prenotato un libro pu cancellare la sua prenotazione.

10

Il diagramma delle classi, in figura, corrisponde al modello dei requisiti. Gli attributi delle entit sono elencati nella parte superiore di ogni classe, mentre i metodi (o azioni) sono nella parte inferiore. Il sistema della biblioteca contiene solo due tipi di entit: libri e membri. I membri possono iscriversi o cancellare iscrizione. I libri possono essere acquisiti o scartati. I membri possono prendere in prestito libri, restituirli o rinnovare prestiti. Sotto certe condizioni un membro pu prenotare un libro (Es. in caso in cui non possa essere preso in prestito in quel momento), successivamente il membro deve ritirare il libro oppure cancellare la prenotazione. Il sistema informativo della biblioteca contiene 10 azioni. La lista seguente descrive le propriet che sono state verificate usando i model checkers. 1. Un libro pu sempre essere acquisito dalla biblioteca se non attualmente acquisito. 2. Un libro non pu essere acquisito dalla biblioteca se gi acquisito. (semanticamente simile al punto uno ma sintatticamente diverso) 3. Un libro acquisito pu essere scartato solo se non stato prenotato n preso in prestito. 4. Una persona deve essere membro della biblioteca per prendere libri in prestito. 5. Un libro pu essere prenotato solo se gi stato preso in prestito o prenotato da un altro membro. 6. Un libro non pu essere prenotato dal membro che lo ha preso in prestito. 7. Un libro non pu essere prenotato da un membro che lha gi prenotato. 8. Un libro non pu essere dato in prestito a un membro se stato prenotato. 9. Un membro non pu rinnovare un prestito se il libro prenotato. 10. Un membro ha il permesso di ritirare un libro prenotato solo se ha la prenotazione pi vecchia. 11. Un libro pu essere ritirato solo se non in prestito. 12. Un membro che ha prenotato un libro pu cancellare la 11

prenotazione in qualunque momento prima di ritirarlo. 13. Un membro pu cancellare la sua iscrizione alla biblioteca solo se tutti i suoi prestiti sono stati restituiti e tutte le sue prenotazioni sono state usate o cancellate. 14. C sempre una procedura che permette ad un membro di cancellare la sua iscrizione alla biblioteca. 15. Un membro non pu prendere in prestito pi libri del limite di prestiti definito a livello di sistema per tutti gli utenti. Nel contesto dei sistemi informativi si distinguono normalmente due tipi di propriet: liveness e safety. La prima rappresenta il fatto che il sistema sia ancora vivo (es. non essere in deadlock o livelock [il sistema cicla tra un sottoinsieme di stati senza evolvere]). Il livelock viene usato raramente nei sistemi informativi, dove le azioni sono scelte da utenti umani. Le propriet 1, 12 e 14 sono di tipo liveness. Nei SI queste propriet descrivono, solitamente, condizioni sufficienti per abilitare unazione; per esempio, la propriet 1 dice che la biblioteca ha il diritto di acquisire un certo libro (sotto alcune condizioni). In altri termini, forza il sistema informativo a permettere lazione, ma lutente non forzato ad invocare lazione. Le propriet di safety sono normalmente usate per descrivere condizioni necessarie per abilitare unazione o per delineare cosa un utente non pu fare con il sistema in un certo momento. Esiste un terzo tipo di propriet, dette fairness ma visto che un sistema informativo raramente viene forzato nel fare qualche azione, capitano difficilmente in questo dominio, perci non sono considerate per questo confronto.

Implementare il modello e le propriet

Questa sezione descrive come il modello IS e le propriet sono state implementate con i model checker sotto esame. Descrizione dellimplementazione per Spin Per le specifiche di Spin sono stati considerati due stili di checking. Il primo stile ha solo un processo che cicla su una scelta tra tutte le azioni possibili. E stato abbandonato presto perch in breve crea unesplosione combinatoria in termini di numero di stati. Cambiando stile di controllo, stato scelto di usare un processo per le istanze di ogni entit e associazione. Quindi la specifica Promela del caso di studio contiene le definizioni di quattro processi, una per ogni entit (Libro e Membro) e ogni associazione (Prestito e Prenotazione). Ogni definizione di processo istanziata ni volte per modellare ni istanze dellentit i, e ni * nj volte per modellare unassociazione tra le entit i e j. stato usato il pattern produttore-modificatore-consumatore come base per il ciclo di vita di unentit e unassociazione, esso pu essere rappresentato seguendo lespressione regolare P.M*.C dove P il produttore (es. Acquisisci), M il modificatore(Es Prendere in prestito e Restituzione) e C il consumatore (es. Scarta). Loperatore di concatenazione . delle espressioni regolari pu 12

essere rappresentato da un punto e virgola;, loperatore di composizione sequenziale di Promela, oppure da una freccia ->, che denota lo stesso operatore. Alcuni eventi hanno una precondizione che non rappresentata nellespressione regolare; ad esempio: un libro non pu essere scartato se in prestito, di conseguenza lesecuzione di un evento garantita da una precondizione. Quando un membro ritira un libro che ha prenotato, sono coinvolte due associazioni: prestito e prenotazione; ci porta ad assicurare che entrambi i processi eseguano levento Ritira in un passo atomico; cosa non ovvia per levento Ritira che composto da due azioni: una nellassociazione Prenotazione (come consumatore) e laltra nellassociazione Prestito (come produttore). Per assicurare lhandshake si usa una strategia classica di Promela, si sfrutta un canale senza buffer (o meglio con buffer di dimensione 0). Tuttavia lhandshake non pu essere fatto con unistruzione atomica, questo rompe latomicit del sender, per lhandshake pu essere fatto tra due istruzioni di tipo atomic. In questo modo nessun altro processo potr interferire nellhandshake. Il risultato un pattern descritto nellarticolo [6], nel quale un evento simultaneamente consumatore di unassociazione e il produttore in unaltra. Le propriet di raggiungibilit sono difficili da esprimere in LTL, fortunatamente le precondizioni di un evento possono essere scritte esplicitamente tramite etichette nelle specifiche (esprimendo propriet come un libro pu essere acquisito). Di conseguenza quando una propriet asserisce la possibilit di esecuzione di un evento, rappresentato da una formula proposizionale in LTL, formula che usa unetichetta di un processo e, qualche volta, la precondizione di questo evento. Per esempio, il libro b0 pu essere acquisito espresso come il processo Libro b0 alletichetta Scartato. La propriet 14 non esprimibile in LTL, dato che una propriet reset, questa propriet nota per essere esprimibile solo in CTL (Computation Tree Logic). LTL e CTL sono linguaggi complementari; la semantica delle formule LTL definita sulle tracce del sistema di transizione, mentre la semantica delle formule CTL definita sul sistema di transizione stesso, ci permette di riferirsi alla struttura ad albero dellesecuzione. Alcune propriet possono essere espresse solo in LTL o in CTL. Ad esempio: una propriet reset dice che sempre possibile tornare ad un certo stato desiderato, questo non pu essere espresso in LTL, dato che questa transizione non si verifica in ogni esecuzione possibile del sistema modellato. Visto che una formula LTL tiene se e solo se tiene per ogni possibile esecuzione del sistema, una propriet LTL forzerebbe il reset in ogni esecuzione. Inoltre una propriet nella formula eventualmente p tiene sempre, non pu essere espressa in CTL [9], data la natura della logica. Due pattern semplici possono esprimere quasi il 70% dei requisiti, in LTL e con il paradigma orientato agli stati, questi pattern sono espressi in forma: se lazione A pu essere eseguita allora lo stato verifica P oppure se P tiene allora lazione A pu essere eseguita dove P vera solo se compresa tra B e C. Perci due pattern principali sono (can_A)=> P or (P=> can_A). Le 13

propriet inesprimibili non possono essere considerate irrilevanti solo per via dei limiti della linear temporal logic, purtroppo questa una lacuna di Spin che non pu essere colmata. Descrizione dellimplementazione Alloy Ogni entit del sistema informativo rappresentata da una signature E, che modella linsieme delle possibili istanze dellentit. Gli stati del sistema sono rappresentati da una signature sig S {e1 : E1, e2 : E2, , en : En, a1 : Ei -> Ej, }, dove ei modella listanza attiva di Ei in uno stato, e ai modella listanza di unassociazione Ai. Ogni azione rappresentata da un predicato P[s : S, s : S,p : T] relativo ad un pre-stato s verso un post-stato s con i parametri p come input. stato seguito sistematicamente un pattern per questi predicati, che una congiunzione di una pre-condizione, una post-condizione e una serie di predicati di invarianza predicato(nochanges) di invarianza che determina quali attributi sono rimasti invariati dallazione. Una propriet nella forma quando la condizione C tiene, deve essere eseguita lazione A (come la propriet 1), si scrive come segue: s : S,p : T C => preA[s,p]; dove preA[s,p] la precondizione dellazione a(p). Analogamente, se C il risultato dellesecuzione di unazione b(p) che dovrebbe abilitare unazione a(p) (come la propriet 12), si pu scrivere s,s,p : T : S b[s,s,p] => preA[s,p]. Una propriet nella forma lazione A eseguibile solo quando la condizione C tiene (come nelle propriet 2,3,4,5,6,7,8,9,10,11,13) si scrive: s : S preA[s,p] => C; Questi tre pattern sono approssimazioni delle propriet, perch unazione pu essere eseguita quando la sua precondizione tiene e quando s : S postA[s,s,p] tiene. In altre parole la precondizione deve tenere e la postcondizione deve essere fattibile. Comunque controllare una formula esistenziale come questa, sugli stati di un sistema informativo, solitamente non fattibile in Alloy, a causa dei limiti della memoria. Fortunatamente la fattibilit delle postcondizioni una problematica rara, perci possiamo presumere con sicurezza leseguibilit di unazione solo dalle sue precondizioni. Le propriet invarianti I per alcune azioni a (come nel caso della propriet 15) sono esprimibili in modo semplice con una formula nella forma: s,s : S,p : T I[s] ^ a[s,s,p] => I[s]. Propriet che esprimono la raggiungubilit di uno stato da una condizione C (come la 14) sono pi difficili da formulare. Prima si cercato di trovare una traccia nel sistema di transizione, ma ci si rivelato impossibile a causa dei limiti della memoria, successivamente si provato a mostrare lesistenza di una traccia descrivendo come pu essere computata. Per la propriet 14, il predicato che descrive questa traccia, che una serie di azioni return, cancel e leave, che infine porta ad uno stato in cui il membro non esiste. I motivi per cui lesecuzione della traccia pu fallire sono: il limite dato alla lunghezza della traccia troppo corto (ad esempio quando lultimo stato della traccia soddisfa le precondizioni di un return, un cancel o un leave) oppure perch la propriet falsa nel modello. Guardando il controesempio trovato stato possibile determinare quale caso tiene e cresce in concomitanza con i limiti sulle tracce e il numero degli stati del sistema della biblioteca. Una difficolt aggiuntiva determinare gli stati validi della biblioteca per i quali la condizione C tiene: 14

questi possono essere caratterizzati da fatti(Soluzione 1), che sono proni agli errori di specifica, ma sono pi efficenti nel controllo, oppure eseguendo entit ed associazioni produttore dallo stato iniziale del sistema per costruire automaticamente gli stati validi della biblioteca che soddisfano C(Soluzione 2), questo metodo semplice da scrivere, ma decisamente meno efficiente nel controllo. Nellimplementazione seguente sono mostrate entrambe le versioni.

15

Implementazione Promela per Spin


Macro delle pre-post condizioni delle entit
Membro
inline pre_join(mId) { true } inline post_join(mId) { // mId membro is_member[mId]=true } inline pre_leave(mId) { // lutente non deve avere libri n prenotazioni ( !nb_loans[mId] && !is_reserving_n_books[mId] ) } inline post_leave(mId) { //il membro mId non pi membro is_member[mId]=false ; goto out }

Libro
inline pre_acquire (bId) { true } inline post_acquire (bId) { // il libro lId diventa acquisito is_acquired[bId]=true } inline pre_discard (bId) { //il libro lId non deve essere in prestito //non ci devono essere membri nella lista di prenotazione del libro ( !is_borrowed[bId] && empty(is_reserved_by[bId]) ) } inline post_discard (bId) { //il libro lId non pi acquisito is_acquired[bId]=false ; goto not_acquired }

16

Macro delle pre-post condizioni delle azioni delle associazioni


Prestito
inline pre_lend (mId, bId) { //per poter prendere un libro necessario: //essere membri //il libro deve essere stato acquisito dalla biblioteca //il libro non deve gi essere in prestito //il numero di libri presi in prestito dalla biblioteca non deve superare MAXPRESTITI //non ci devono essere persone nella lista di quelli che hanno prenotato il libro ( is_member[mId] && is_acquired[bId] && !is_borrowed[bId] && (nb_loans[mId] < NBMAXLOANS) && empty(is_reserved_by[bId]) ) } inline post_lend (mId, bId) { // viene incrementato il contatore dei libri presi da mId // lId viene impostato in prestito // viene impostato lutente che ha preso in prestito lId nb_loans[mId]++ ; is_borrowed[bId] = true ; is_borrowed_by[bId] = mId } inline pre_renew (mId, bId) { //viene controllato che il libro non sia stato prenotato ( empty(is_reserved_by[bId]) ) } inline post_renew (mId, bId) { goto borrowed } inline pre_return (mId, bId) { true } inline post_return (mId, bId) { //lId viene impostato come non in prestito //viene decrementato il numero di libri che ha preso in prestito mId is_borrowed[bId] = false ; nb_loans[mId]-- ; goto not_borrowed }

17

Prenotazione
inline pre_reserve (mId, bId) { //mId deve essere membro e lId deve essere acquisito, inoltre: //lId deve essere stato preso in prestito o deve essere stato gi prenotato //lId non deve essere in prestito o non deve essere stato preso in prestito da mId //lId non deve essere gi stato prenotato o non deve essere gi stato prenotato da mId ( is_member[mId] && is_acquired[bId] && ( is_borrowed[bId] || nempty(is_reserved_by[bId]) ) && ( !is_borrowed[bId] || (is_borrowed_by[bId] != mId) ) && ( empty(is_reserved_by[bId]) || !is_reserved_by[bId]??[eval(mId)] )) } inline post_reserve (mId, bId) { //il primo nella lista delle prenotazioni di lId non deve essere mId //il contatore di prenotazioni di mId viene incrementato is_reserved_by[bId]!mId ; is_reserving_n_books[mId]++ } inline pre_cancel (mId, bId) { true } inline post_cancel (mId, bId) { //mId viene tolto dalla coda di quelli che hanno prenotato lId //il contatore dei libri prenotati viene decrementato is_reserved_by[bId]??eval(mId) ; is_reserving_n_books[mId]-- ; goto not_reserved } inline pre_take (mId,bId) { //devono essere verificate le precondizioni di prestito del libro e quelle di ritiro pre_take_in_loan(mId,bId) && pre_take_in_reservation(mId,bId) } inline pre_take_in_loan (mId,bId) { true } inline post_take_in_loan (mId, bId) { //viene incrementato il contatore dei libri presi in prestito da mId //il libro viene dichiarato in prestito //viene impostato che mId ha preso in prestito lId nb_loans[mId]++ ; is_borrowed[bId] = true ; is_borrowed_by[bId] = mId } inline pre_take_in_reservation (mId, bId) { //mId deve essere membro //lId deve essere stato acquisito //mId non deve aver raggiunto il limite di prestiti //mId deve aver prenotato il libro per primo ( is_member[mId] && is_acquired[bId] && !is_borrowed[bId] && (nb_loans[mId] < NBMAXLOANS) && is_reserved_by[bId]?[eval(mId)] ) } inline post_take_in_reservation (mId, bId) { //il primo ad aver prenotato lId stato mId che viene rimosso dalla lista //il numero di prenotazioni di mId viene decrementato is_reserved_by[bId]?eval(mId) ; is_reserving_n_books[mId]-- ; goto not_reserved }

18

Variabili globali
int nb_loans [NB_MEMBER] ; bool is_acquired [NB_BOOK] ; bool is_member [NB_MEMBER] ; bool is_borrowed [NB_BOOK] ; MEMBERID is_borrowed_by [NB_BOOK] ; chan is_reserved_by [NB_BOOK] = [NB_MEMBER] of { MEMBERID } ; int is_reserving_n_books[NB_MEMBER] ; mtype = { from_reservation, from_loan } ; chan ready_to_take[NB_BOOK] = [0] of { mtype, MEMBERID } ;

Definizione dei processi

Vengono chiamati i metodi che verificano le pre e post condizioni delle azioni di entit e associazioni. Membro
proctype member(MEMBERID mId) { out: left: progress_member: end_member: atomic{ /*pre_join(mId) -> commentato per ottimizzare*/ printf("join(%d)\n",mId) ; post_join(mId) } ; in: joined: atomic{ pre_leave(mId) -> printf("leave(%d)\n",mId) ; post_leave(mId) } }

Libro
proctype book(BOOKID bId) { not_acquired: discarded: progress_book: end_book: atomic{ /*pre_acquire(bId) -> commentato per ottimizzare */ printf("acquire(%d)\n", bId) ; post_acquire(bId) } ; acquired: atomic{ pre_discard(bId) -> printf("discard(%d)\n", bId) ; post_discard(bId) } }

19

Prestito
proctype loan(MEMBERID mId; BOOKID bId) { not_borrowed: end_loan: progress_loan: if :: atomic{ pre_lend(mId, bId) -> printf("lend(%d,%d)\n", mId, bId) ; post_lend(mId, bId) } :: atomic{ ready_to_take[bId]?from_reservation,eval(mId) -> /* pre_take_in_loan(mId, bId) -> commentato per ottimizzare */ printf("take awaiting(%d,%d)\n", mId, bId) ; post_take_in_loan(mId, bId) ; ready_to_take[bId]!from_loan,mId } fi ; borrowed: if :: atomic{ pre_renew(mId, bId) -> printf("renew(%d,%d)\n", mId, bId) ; post_renew(mId, bId) } :: atomic{ /*pre_return(mId, bId) ->*/ printf("return(%d,%d)\n", mId, bId) ; post_return(mId, bId) } fi }

Prenotazione
proctype reservation(MEMBERID mId; BOOKID bId) { not_reserved: end_reservation: progress_reservation: if :: atomic{ pre_reserve(mId, bId) -> printf("reserve(%d,%d)\n", mId, bId) ; post_reserve(mId, bId) ; } fi ; reserved: if :: atomic{ pre_take_in_reservation(mId, bId) -> ready_to_take[bId]!from_reservation,mId } ; is_taking: atomic{ ready_to_take[bId]?from_loan,eval(mId) ; printf("take(%d,%d)\n", mId, bId) ; post_take_in_reservation(mId, bId) } :: atomic{ /*pre_cancel(mId, bId) -> commentato per ottimizzare */ printf("cancel(%d,%d)\n", mId, bId) ; post_cancel(mId, bId) } fi }

20

Propriet in LTL
1. Un libro pu essere sempre Acquisito dalla biblioteca a meno che sia gi Acquisito.
<>b0_can_be_acquired && [](b0_is_discarded -> b0_can_be_acquired)

2. Un libro non pu essere Acquisito dalla biblioteca a meno che sia gi Acquisito.
[] (!(b0_is_acquired && b0_is_discarded))

3. Un libro Acquisito pu essere Scartato solo se non in prestito n prenotato.


[] (b0_is_discarded -> b0_is_neither_borrowed_nor_reserved)

4. Una persona deve essere un membro della biblioteca per poter prendere in prestito un libro.
[] (b0_can_be_borrowed_by_m0 -> m0_has_joined)

5. Un libro un libro pu essere prenotato solo se in prestito o gi stato prenotato da un altro membro.
[] (b0_can_be_reserved_by_m0 -> (b0_is_borrowed || (!b0_is_not_reserved && !b0_is_reserved_by_m0))

6. Un libro non pu essere prenotato dal membro che lha preso in prestito.
[] (b0_can_be_reserved_by_m0 -> !b0_is_borrowed_by_m0)

7. Un libro non pu essere prenotato da un membro che lo ha gi prenotato.


[] (b0_can_be_reserved_by_m0 -> !b0_is_reserved_by_m0)

8. Un libro non pu essere dato in prestito ad un membro se prenotato.


[] (b0_is_reserved -> !b0_can_be_lent_to_m0)

9. Un membro non pu rinnovare un prestito se il libro stato prenotato.


[] (b0_is_reserved -> !m0_can_renew_loan_b0)

10. E concesso ad un membro di ritirare un libro prenotato solo se ha la prenotazione pi vecchia.


[] (b0_can_be_taken_by_m0 -> b0_is_reserved_by_m0_first)

11. Un libro pu essere ritirato solo se non gi in prestito.


[] (b0_can_be_taken_by_m0 -> !b0_is_borrowed)

12. Chiunque abbia prenotato un libro pu cancellare la sua prenotazione in qualunque momento, prima di ritirarlo.
[](b0_is_reserved_by_m0 -> ((m0_can_cancel_b0_reservation U m0_is_taking_b0_reservation)|| []!m0_is_taking_b0_reservation)

13. Un membro pu cancellare la sua iscrizione alla biblioteca solo se tutti i suoi prestiti sono stati restituiti e tutte le sue prenotazioni sono state usate o cancellate.
[](m0_can_leave -> (m0_has_no_reservation && m0_has_no_loan)

C sempre una procedura che permette ad un membro di lasciare la libreria. 14. C sempre una procedura che permette ad un membro di lasciare la libreria. Non descrivibile in LTL. 15. Un membro non pu prendere in prestito pi libri del limite di prestiti definito a livello di sistema per tutti gli utenti.
[] (nb_of_loan_of_m0_is_less_than_max)

21

Definizione dei predicati


#define b0_is_acquired (book[b_pid[0]]@acquired) #define b0_is_discarded (book[b_pid[0]]@discarded) #define b0_is_borrowed (is_borrowed[0]) #define b0_is_not_reserved (empty(is_reserved_by[0])) #define b0_is_reserved (nempty(is_reserved_by[0])) #define b0_is_neither_borrowed_nor_reserved ( !b0_is_borrowed && b0_is_not_reserved ) #define b0_is_either_borrowed_or_reserved ( b0_is_borrowed || b0_is_reserved ) #define m0_has_joined (member[m_pid[0]]@joined) #define nb_of_loan_of_m0_is_less_than_max (nb_loans[0] <= NBMAXLOANS) #define nb_of_loan_of_m0_is_strictly_less_than_max (nb_loans[0] < NBMAXLOANS) #define m0_has_no_reservation (!is_reserving_n_books[0]) #define m0_has_no_loan (!nb_loans[0]) #define b0_is_borrowed_by_m0 (loan[l_pid[0]]@borrowed) #define b0_is_not_borrowed_by_m0 (loan[l_pid[0]]@not_borrowed) #define b0_is_reserved_by_m0 (reservation[r_pid[0]]@reserved) #define m0_is_taking_b0_reservation (reservation[r_pid[0]]@is_taking) #define b0_is_reserved_by_m0_first (is_reserved_by[0]?[0])

Definizione dei predicati can_xxx


#define b0_can_be_acquired ( b0_is_discarded ) #define b0_can_be_lent_to_m0 ( b0_is_not_borrowed_by_m0 && m0_has_joined && b0_is_acquired && !b0_is_borrowed && nb_of_loan_of_m0_is_strictly_less_than_max && b0_is_not_reserved ) #define b0_can_be_taken_by_m0 ( b0_is_not_borrowed_by_m0 && m0_has_joined && b0_is_acquired && !b0_is_borrowed && nb_of_loan_of_m0_is_strictly_less_than_max && b0_is_reserved_by_m0_first ) #define b0_can_be_borrowed_by_m0 ( b0_is_not_borrowed_by_m0 && (b0_can_be_lent_to_m0 || b0_can_be_taken_by_m0) ) #define b0_can_be_reserved_by_m0 ( b0_is_not_reserved_by_m0 && m0_has_joined && b0_is_acquired && ( b0_is_borrowed || b0_is_reserved ) && ( !b0_is_borrowed || !b0_is_borrowed_by_m0 ) && ( b0_is_not_reserved || !b0_is_reserved_by_m0 ) ) #define m0_can_renew_loan_b0 ( b0_is_borrowed_by_m0 && b0_is_not_reserved ) #define m0_can_cancel_b0_reservation ( b0_is_reserved_by_m0 ) #define m0_can_leave ( m0_has_joined && m0_has_no_loan && m0_has_no_reservation )

22

Specifiche Alloy

In questo capitolo verranno mostrate le specifiche Alloy commentate.

Dichiarazione iniziale ed importazione


//dichiarazione del modello module model //sequenza di azioni open util/sequniv as ResSq

Classi
//Classe con variabili globali. one sig Constants { maxNbLoans : Int } { maxNbLoans = 7 } //Elemento Libro sig Book{} //Elemento membro sig Member{} //Elemento Biblioteca sig Lib { //members un insieme di membri //books un insieme di libri //loans (prestiti) una relazione monodirezionale che ha come dominio i libri e come //codominio i membri //membersReservingOneBooks (prenotazione di un libro) una relazione monodirezionale che //ha come dominio una lista di membri e come codominio linsieme dei libri //Renew (rinnova prestito) una relazione monodirezionale che ha come dominio i libri e //come codominio i membri members:set Member, books: set Book , loan: (books -> members), membersReservingOneBook: (seq members)->books, Renew: (books -> members) }

23

Predicati di invarianza (no change)

Questi predicati vengono usati nelle azioni per dichiarare quali variabili di stato rimangono invariate.
//tutti i nochange prendono in ingresso due oggetti che rappresentano lo stato corrente // lo stato seguente della biblioteca pred NoChangebooks[L,L:Lib] { L.books =L.books } pred NoChangemembers[L,L:Lib] { L.members =L.members } pred NoChangeloan[L,L:Lib] { L.loan=L.loan } pred NoChangeSeqBook[L,L:Lib] { L.membersReservingOneBook= L.membersReservingOneBook } pred NochangeRenew[L,L:Lib] { L.Renew = L.Renew }

Inizializzazione
//gli insiemi vengono dichiarati vuoti; viene dichiarato che non ci sono elementi in //relazione loan, membersReservingOneBook n Renew //prende in ingresso un oggetto biblioteca L pred Init [L:Lib] { no L.books no L.members no L.loan no L.membersReservingOneBook no L.Renew }

24

Azioni
Acquisisci
//definizione della precondizione //CanBeAcquire verifica che il libro b non sia gi tra i libri posseduti dalla biblioteca //cio, che lintersezione tra b e linsieme dei libri della biblioteca dia insieme vuoto //Prende in ingresso: //L: un oggetto biblioteca //b: un oggetto libro pred CanBeAcquire[L:Lib,b:Book] { no(b & L.books) } //Prende in ingresso: //L: un oggetto biblioteca //b: un oggetto libro pred Acquire[b:Book,L,L:Lib] { //Verifica della precondizione CanBeAcquire[L,b] //Postcondizione, aggiunge b allinsieme di libri di L L.books = L.books + b // lista di ci che non deve cambiare NoChangemembers[L,L] NoChangeloan[L,L] NoChangeSeqBook[L,L] NochangeRenew[L,L] }

Iscrivi
//definizione della precondizione //verifica che il membro m non sia gi tra i membri della biblioteca, o meglio che //lintersezione tra m e linsieme dei membri della biblioteca dia insieme vuoto //Prende in ingresso: //L: un oggetto biblioteca //b: un oggetto libro //m: un oggetto membro pred CanJoin[m:Member,L:Lib] { no (m & L.members) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //m: un oggetto membro pred Join[m:Member,L,L:Lib]{ //verifica della precondizione CanJoin[m,L] //Postcondizione: aggiunge m allinsieme dei membri L.members=L.members +m // lista di ci che non deve cambiare NoChangebooks[L,L] NoChangeloan[L,L] NoChangeSeqBook[L,L] NochangeRenew[L,L] }

25

Prende in prestito
//definizione della precondizione //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //b: un oggetto libro //m: un oggetto membro pred CanLend[m:Member,b:Book,L:Lib] { //b nellinsieme dei libri della biblioteca e m nellinsieme dei membri //il numero dei prestiti di m minore del numero massimo di prestiti //b non deve essere in prestito //b non deve essere stato prenotato (b in L.books) and (m in L.members) (#((L.loan).m)<Constants.maxNbLoans) all m:Member|no((L.loan).m & b) (no (L.membersReservingOneBook.b)) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro //m: un oggetto membro pred Lend[m:Member,b:Book,L,L:Lib] { //Verifica delle precondizioni CanLend[m,b,L] //Postcondizioni: la relazione prestito ora coinvolge anche b e m L.loan=L.loan + (b->m) // lista di ci che non deve cambiare NoChangebooks[L,L] NoChangemembers[L,L] NoChangeSeqBook[L,L] NochangeRenew[L,L] }

26

Prenota
//definizione della precondizione //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //b: un oggetto libro //m: un oggetto membro pred CanReserve[m:Member,b:Book,L:Lib] { //b nellinsieme dei libri della biblioteca e m nellinsieme dei membri //b in prestito //non pu essere prenotato pi di una volta dallo stesso membro (b in L.books and m in L.members ) one (b & ((L.loan).Member)) or (some (L.membersReservingOneBook.b)) no (m & b.(L.loan)) // m is not lent no (Int.(L.membersReservingOneBook.b) & m) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro //m: un oggetto membro pred Reserve[m:Member,b:Book,L,L:Lib] { //verifica delle precondizioni CanReserve[m,b,L] //postcondizione: la relazione membersReservingOneBook ora coinvolge anche b e m L.membersReservingOneBook.b = ResSq/add[L.membersReservingOneBook.b,m] // lista di ci che non deve cambiare //visto che NoChangeSeqBook non pu essere chiamato, //dato che una relazione memberReservingOneBook stata aggiunta: //viene dichiarato manualmente che le altre relazioni memberReservingOneBook cambiano all b:Book - b|L.membersReservingOneBook.b = L.membersReservingOneBook.b NoChangebooks[L,L] NoChangemembers[L,L] NoChangeloan[L,L] NochangeRenew[L,L] }

non

27

Cancella prenotazione
//precondizione //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //b: un oggetto libro //m: un oggetto membro pred CanCancel[m:Member,b:Book,L:Lib] { //b nellinsieme dei libri della biblioteca e m nellinsieme dei membri //b stato prenotato da m (b in L.books and m in L.members ) one (Int->m & (L.membersReservingOneBook.b)) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro //m: un oggetto membro pred Cancel[m:Member,b:Book,L,L:Lib] { //verifica precondizione CanCancel[m,b,L] //postcondizione: viene rimosso m dalla lista dei membri che hanno prenotato b L.membersReservingOneBook.b=ResSq/delete[L.membersReservingOneBook.b,ResSq/ indsOf [L.membersReservingOneBook.b,m]] // lista di ci che non deve cambiare, viene imposto il non cambiamento anche //alle relazioni di prenotazione di tutti i libri tranne a quelle che coinvolgono b all b:Book - b|L.membersReservingOneBook.b = L.membersReservingOneBook.b NoChangebooks[L,L] NoChangemembers[L,L] NoChangeloan[L,L] NochangeRenew[L,L] }

Restituisci
//precondizione //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //b: un oggetto libro //m: un oggetto membro pred CanReturn[m:Member,b:Book,L:Lib] { //b nellinsieme dei libri della biblioteca e m nellinsieme dei membri //tra linsieme dei prestiti di m c b (b in L.books and m in L.members ) one ((L.loan).m & b) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro //m: un oggetto membro pred Return[m:Member,b:Book,L,L:Lib] { //verifica della precondizione CanReturn[m,b,L] //postcondizione: viene rimossa la relazione prestito tra b e m // viene rimossa la relazione rinnova prestito tra b e m L.loan=L.loan - (b ->m) L.Renew = L.Renew - (b -> m) // lista di ci che non deve cambiare NoChangebooks[L,L] NoChangemembers[L,L] NoChangeSeqBook[L,L] }

28

Ritira
//precondizione //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //b: un oggetto libro //m: un oggetto membro pred CanTake[m:Member,b:Book,L:Lib] { //b nellinsieme dei libri della biblioteca e m nellinsieme dei membri //il numero dei prestiti di m minore del numero massimo di prestiti //m il primo nella lista delle prenotazioni di b //b non in prestito (b in Lib.books) and (m in L.members) (#((L.loan).m)<Constants.maxNbLoans) (L.membersReservingOneBook.b) = (0 -> m) no (b.(L.loan)) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro //m: un oggetto membro pred Take[m:Member,b:Book,L,L:Lib] { //verifica della precondizione CanTake[m,b,L] //postcondizione: b viene messo in relazione prestito con m //m viene rimosso dalla lista di chi ha prenotato b L.loan=L.loan + (b->m) L.membersReservingOneBook.b=ResSq/delete[L.membersReservingOneBook.b,0] // lista di ci che non deve cambiare, viene imposto il non cambiamento anche //alle relazioni di prenotazione di tutti i libri tranne a quelle che coinvolgono b all b:Book - b|L.membersReservingOneBook.b = L.membersReservingOneBook.b NoChangebooks[L,L] NoChangemembers[L,L] NochangeRenew[L,L] }

29

Cancella Iscrizione
//Precondizione //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //m: un oggetto membro pred CanLeave[m:Member,L:Lib] { //m nellinsieme dei membri //m non ha libri in prestito (non nellinsieme dei membri che hanno libri in prestito) //m non ha prenotazioni (non in nessuna lista di prenotazione) m in L.members no (L.loan.m) no( Int.(L.membersReservingOneBook.Book) & m) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro //m: un oggetto membro pred Leave[m:Member,L,L:Lib] { //verifica delle precondizioni CanLeave[m,L] //postcondizione: m viene rimosso dallinsieme dei membri L.members = L.members - m // lista di ci che non deve cambiare NoChangeloan[L,L] NochangeRenew[L,L] NoChangeSeqBook[L,L] NoChangebooks[L,L] }

Scarta
//precondizioni //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //b: un oggetto libro pred CanDiscard[b:Book,L:Lib] { //b nellinsieme dei libri //b non in prestito //b non prenotato b in L.books no (b.(L.loan)) no ((L.membersReservingOneBook.b) ) } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro pred Discard[b:Book,L,L:Lib] { //verifica delle precondizioni CanDiscard[b,L] //postcondizione: b viene rimosso dallinsieme dei libri L.books = L.books - b // lista di ci che non deve cambiare NoChangeloan[L,L] NoChangeSeqBook[L,L] NoChangemembers[L,L] NochangeRenew[L,L] }

30

Rinnova Prestito
//precondizioni //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //b: un oggetto libro //m: un oggetto membro pred CanRenew[m:Member,b:Book,L:Lib] { //m ha gi b in prestito ( lintersezione tra m e linsieme dei membri che hanno b in // prestito d un risultato ) //il libro non ha prenotazioni (la lista di prenotazioni vuota) -one (b.(L.loan) & m) ResSq/isEmpty [L.membersReservingOneBook.b] } //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente //b: un oggetto libro //m: un oggetto membro pred Renew[m:Member,b:Book,L,L:Lib] { //precondizioni CanRenew[m,b,L] //postcondizione: riscrive la prenotazione L.Renew=L.Renew ++ (b->m) // lista di ci che non deve cambiare NoChangebooks[L,L] NoChangemembers[L,L] NoChangeloan[L,L] NoChangeSeqBook[L,L] }

31

Lista delle 15 propriet da verificare


//dichiarazione di utilizzo delle specifiche della biblioteca mostrate sopra open LibSpecification

Propriet 1 e 2

//Un libro pu sempre essere acquisito dalla biblioteca se non attualmente acquisito. //Un libro non pu essere acquisito dalla biblioteca se gi acquisito. assert Prop1And2 { all b:Book,L:Lib { //valgono le precondizioni se e solo se b non nellinsieme dei libri CanBeAcquire[L,b] <=> not (b in L.books) } } check Prop1And2 for 2 Lib,8 Member,8 Book //non stato possibile esprimere la propriet 1 nella forma esatta /* //Non pu essere espressa perch sarebbe necessario il grafo delle transizioni assert Prop1And2 { all b:Book,L:Li { //lacquisizione di b implica che b non sia nellinsieme dei libri della biblioteca some L:Lib| Acquire[b,L,L] => not (b in L.books) //lassenza di b dallinsieme dei libri della biblioteca implica il suo acquisto not (b in L.books) =>some L:Lib| Acquire[b,L,L] } } check Prop1And2 for 2 Lib,8 Member,8 Book */

Propriet 3
//Un libro acquisito pu essere scartato solo se non stato prenotato //n preso in prestito. assert Prop3 { all b:Book,L:Lib { //scartare b implica che b non sia in prestito //e che non sia stato prenotato some L:Lib |Discard[b,L,L] => no (b.(L.loan)) and no ((L.membersReservingOneBook.b) ) } } check Prop3 for 2 Lib,8 Member,8 Book

32

Propriet 4
//Una persona deve essere membro della biblioteca per poter prendere libri in prestito. assert Prop4 { all b:Book,m:Member,L:Lib { //prestare b a m implica che b sia nellinsieme dei libri e m in quello dei membri //lo stesso vale per quando un membro ritira un libro che ha prenotato some L:Lib|Lend[m,b,L,L] => (b in L.books) and (m in L.members) some L:Lib|Take[m,b,L,L] => (b in L.books) and (m in L.members) } } check Prop4 for 2 Lib,8 Member,8 Book

Propriet 5
//Un libro pu essere prenotato solo se gi stato preso in prestito o prenotato //da un altro membro. assert Prop5 { all b:Book,m:Member,L:Lib { //la prenotazione di b da parte di m implica che //b sia nellinsieme dei libri presi in prestito //oppure che sia nellinsieme dei libri prenotati some L:Lib|Reserve[m,b,L,L] => (b in ((L.loan).Member)) or (some (L.membersReservingOneBook.b)) } } check Prop5 for 2 Lib,8 Member,8 Book

Propriet 6
//Un libro non pu essere prenotato dal membro che lo ha preso in prestito. assert Prop6 { all b:Book,m:Member,L:Lib { //la prenotazione di b da m, implica che b sia in prestito ad un membro diverso da m some L:Lib|Reserve[m,b,L,L] => ((m !in b.(L.loan))) } } check Prop6 for 2 Lib,8 Member,8 Book

Propriet 7
// Un libro non pu essere prenotato da un membro che lha gi prenotato. assert Prop7 { all b:Book,m:Member,L:Lib { //la prenotazione di b da m implica che m non sia nella lista di quelli che hanno //prenotato b some L:Lib|Reserve[m,b,L,L] => ( (m !in Int.(L.membersReservingOneBook.b))) } } check Prop7 for 2 Lib,8 Member,8 Book

33

Propriet 8
// Un libro non pu essere dato in prestito a un membro se stato prenotato. assert Prop8 { all b:Book,m:Member,L:Lib { //il prestito di b ad m implica che la lista di quelli che hanno prenotato b sia //vuota some L:Lib|Lend[m,b,L,L] => (no (L.membersReservingOneBook.b)) } } check Prop8 for 2 Lib,8 Member,8 Book

Propriet 9
// Un membro non pu rinnovare un prestito se il libro prenotato. assert Prop9 { all b:Book,m:Member,L:Lib { //il rinnovo del prestito di b da parte di m implica che la lista di quelli che hanno //prenotato b sia vuota some L:Lib|Renew[m,b,L,L] => (no (L.membersReservingOneBook.b)) } } check Prop9 for 2 Lib,8 Member,8 Book

Propriet 10
// Un membro ha il permesso di ritirare un libro prenotato solo se ha la prenotazione pi //vecchia. assert Prop10 { all b:Book,m:Member,L:Lib { //il ritiro di b da parte di m implica che m sia il primo nella lista di //prenotazione some L:Lib|Take[m,b,L,L] => (L.membersReservingOneBook.b) = (0 -> m) } } check Prop10 for 2 Lib,8 Member,8 Book

Propriet 11
// Un libro pu essere ritirato solo se non in prestito. assert Prop11 { all b:Book,m:Member,L:Lib { //il ritiro di b da parte di m implica che b non sia in prestito some L:Lib|Take[m,b,L,L] => not ( b in (L.loan).Member) } } check Prop11 for 2 Lib,8 Member,8 Book

34

Propriet 12
//Un membro che ha prenotato un libro pu cancellare la prenotazione in qualunque momento //prima di ritirarlo. assert Prop12 { all b:Book,L:Lib,m:Member { //se possibile ritirare b allora devono valere le precondizioni di cancella //prenotazione some L:Lib| Take[m,b,L,L] => CanCancel[m,b,L] } } check Prop12 for 2 Lib,8 Member,8 Book

Propriet 13
//Un membro pu cancellare la sua iscrizione alla biblioteca solo se tutti i suoi prestiti //sono stati restituiti e tutte le sue prenotazioni sono state usate o cancellate. assert Prop13 { all m:Member,L:Lib { //la cancellazione delliscrizione di m alla biblioteca implica che linsieme dei //suoi prestiti sia vuoto e che non ci siano libri che lo hanno nella loro lista //di prenotazioni some L:Lib|Leave[m,L,L] => (no (L.loan.m) and (m !in Int.(L.membersReservingOneBook.Book))) } } check Prop13 for 2 Lib,8 Member,8 Book

Propriet 15
//Un membro non pu prendere in prestito pi libri del limite di prestiti definito a //livello di sistema per tutti gli utenti. for all users assert Prop15 { all L,L:Lib,m:Member,b:Book { //se m pu ritirare o prendere in prestito un libro, allora il numero di prestiti di //m minore di 7 Take[m,b,L,L] => #(L.loan.m)<=7 Lend[m,b,L,L] => #(L.loan.m)<=7 } } check Prop15 for 2 Lib, 8 Member, 8 Book

35

Propriet 14 C sempre una procedura che permette ad un membro di cancellare la sua iscrizione alla biblioteca.Questa propriet richiede una gestione molto diversa rispetto alle altre, viene quindi trattata separatamente. Di seguito due possibili soluzioni. Perch LCR? Ci sono due vincoli che devono essere rispettati da un utente per poter cancellare liscrizione: non deve avere libri prenotati e non deve avere libri in prestito; perci, dato un membro iscritto alla biblioteca, almeno una tra le azioni: cancella iscrizione, cancella prenotazione o restituisci libro, devono essere eseguibili. Soluzione 1
//import delle specifiche del modello open LibSpecification //Sequenza di Join Acquire Lend Reserve Take open util/IJALSequence[Lib] as LibSeq1 //Sequenza di Leave Cancel Return open util/LCRSequence[Lib] as LibSeq2 e Renew

//determinazione degli stati validi tramite fatti fact { //inizializzazione della prima sequenza della biblioteca Init[LibSeq1/first[Seq]] //per ogni indice nella in lista tranne lultimo all idx : LibSeq1/inds[Seq] - LibSeq1/lastIdx[Seq]| //esistono un membro ed un libro tali che siano coinvolti in unazione some m:Member,b:Book| Join[m,at[Seq,idx],at[Seq,idx.LibSeq1/ord/next]] or Acquire[b,at[Seq,idx],at[Seq,idx.LibSeq1/ord/next]] or Lend[m,b,at[Seq,idx],at[Seq,idx.LibSeq1/ord/next]] or Reserve[m,b,at[Seq,idx],at[Seq,idx.LibSeq1/ord/next]] or Take[m,b,at[Seq,idx],at[Seq,idx.LibSeq1/ord/next]] or Renew[m,b,at[Seq,idx],at[Seq,idx.LibSeq1/ord/next]] }

//LCR sta per: //L = Leave = Cancella Iscrizione //C = Cancel = Cancella prenotazione //R = Return = Restituisci (libro) //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente//b: un oggetto libro //m: un oggetto membro pred LCR[m:Member,L,L : Lib] { //esiste un libro b per cui siano valide Cancella Prenotazione, Restituisci o Cancella //iscrizione some b:Book | Cancel[m,b,L,L] or Return[m,b,L,L] or Leave[m,L,L] }

36

//precondizioni di LCR //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //m: un oggetto membro pred CanLCR[L:Lib,m:Member] { // devono essere valide le precondizioni di leave // oppure esiste un libro per cui siano valide le precondizioni di Cancella prenotazione // oppure esiste un libro per cui siano valide le precondizioni di Restituisci CanLeave[m,L] or some b:Book|CanCancel[m,b,L] or some b :Book|CanReturn[m,b,L] }

//chiamata della funzione LCR fatta su tutti i possibili stati tranne lultimo (che non ha membri) //Prende in ingresso: //m: un oggetto membro //P: una sequenza LCR pred TransLCR[m:Member,P:SeqLCR] { //per ogni stato della sequenza tranne lultimo //viene invocato LCR sullo stato corrente, il successivo ed m all idx : LibSeq2/inds[P]-LibSeq2/lastIdx[P] | LCR[m,LibSeq2/at[P,idx],LibSeq2/at[P,idx.LibSeq2/ord/next]] } pred NegProp14 [] { //esistono una e solo una sequenza LCR ed //esiste almeno una sequenza LCR P tale che //esista almeno un membro m appartenente allultimo stato della sequenza tale che //lultimo stato nella sequenza IJAL sia il primo nella sequenza di LCR e //viene eseguito LCR passando m e P, cio il membro e la sequenza e //m deve essere tra i membri nellultimo stato della sequenza LCR e // nellultimo stato della sequenza LCR non deve essere pi possibile fare LCR // Oppure // lultimo stato deve essere lo stato finale one SeqLCR some P : SeqLCR| some m : LibSeq1/last[Seq].members | //LibSeq1/last[Seq] = LibSeq2/first[P] //and TransLCR[m,P] and m in LibSeq2/last[P].members and (not CanLCR[LibSeq2/last[P],m] or LibSeq2/lastIdx[P] = LibSeq2/finalIdx ) } run{ NegProp14[]}for 3 Member,3 Book,36 Lib, 13 SeqIdx,13 SeqIdx1,13 SeqLCR //lultimo stato della sequenza IAJLR il primo della sequenza LCR fact{ LibSeq1/last[Seq] = LibSeq2/first[SeqLCR] }

37

assert Prop14 { //per ogni sequenza LCR //Ogni membro appartenente allinsieme dei membri presenti nellultimo stato //della sequenza IJAL //se vale TransLCR passandogli il membro e lo stato allora: //m non nei membri dellultimo stato della sequenza LCR //oppure //la sequenza LCR non completa, cio: // valgono le precondizioni di LCR ( ancora possibile eseguire LCR) // e // la sequenza LCR non arrivata alla sua massima lunghezza all P : SeqLCR| all m: LibSeq1/last[Seq].members| TransLCR[m,P] => ( (not m in LibSeq2/last[P].members) or ( (CanLCR[LibSeq2/last[P],m] and (not LibSeq2/lastIdx[P] = LibSeq2/finalIdx)) ) ) } check Prop14 for 4 Member,4 Book, 50 Lib, 25 SeqIdx,25 SeqIdx1,25 SeqLCR

Soluzione 2 Implementazione della propriet 14 usando le tracce. Un fatto usato per definire gli stati nei quali la propriet deve essere soddisfatta. (Es. se le tracce non iniziano dallo stato iniziale della biblioteca non siamo su una traccia valida).
//import delle specifiche del modello open LibSpecification //sequenza di stati biblioteca open util/sequence[Lib] as LibSeq //LCR sta per: //L = Leave = Cancella Iscrizione //C = Cancel = Cancella prenotazione //R = Return = Restituisci (libro) //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //L: un oggetto biblioteca che rappresenta lo stato seguente//b: un oggetto libro //m: un oggetto membro pred LCR[m:Member,L,L : Lib] { //esiste almeno un libro b per cui siano valide: //Cancella Prenotazione, Restituisci o Cancella iscrizione some b:Book | Cancel[m,b,L,L] or Return[m,b,L,L] or Leave[m,L,L] }

38

//chiamata della funzione LCR fatta su tutti i possibili stati tranne //lultimo (che non ha membri) //Prende in ingresso: //m: un oggetto membro //P: una sequenza LCR pred TransLCR[m:Member,P:Seq] { //per ogni stato della sequenza tranne lultimo //viene invocato LCR sullo stato corrente, il successivo ed m all idx : LibSeq/inds[P]-LibSeq/lastIdx[P] | LCR[m,LibSeq/at[P,idx],LibSeq/at[P,idx.LibSeq/ord/next]] } //precondizioni di LCR //Prende in ingresso: //L: un oggetto biblioteca, che rappresenta lo stato corrente //m: un oggetto membro pred CanLCR[L:Lib,m:Member] { // devono essere valide le precondizioni di leave // oppure esiste un libro per cui siano valide le precondizioni di Cancella prenotazione // oppure esiste un libro per cui siano valide le precondizioni di Restituisci CanLeave[m,L] or some b:Book|CanCancel[m,b,L] or some b :Book|CanReturn[m,b,L] }

pred NegProp14 { //per ogni stato della biblioteca //esiste almeno una traccia P tale che //esiste almeno un membro m tale che //possa essere eseguita TransLCR su m e P //m sia nellinsieme dei membri dellultimo stato //e // non siano valide le precondizioni di LCR sullultimo stato // oppure // sia stata raggiunta la lunghezza massima della sequenza all P : Seq | Prop14StartLib[LibSeq/first[P]] some P : Seq | some m : LibSeq/first[P].members | TransLCR[m,P] and m in LibSeq/last[P].members and ( not CanLCR[LibSeq/last[P],m] or LibSeq/lastIdx[P] = LibSeq/finalIdx ) } //Verificare la propriet 14 usando run: //questa propriet verificata eseguendo un fatto che la nega. //m membri, b libri implica che al massimo possono esserci //l prestiti e b-l prenotazioni //quindi sono necessari l restituzioni, (b-l) cancellazioni //cancellazione di iscrizione //questo implica b+1 azioni //che implica che la lunghezza delle tracce sia b+2 run NegProp14 for 10 but 8 Book, 8 Member run NegProp14 for 8 but 6 Book, 6 Member run {} for 3 but 2 Lib

di

prenotazioni

una

39

//Definizione degli stati validi tramite predicato pred Prop14StartLib[L:Lib] { //il numero di prestiti di ogni membro deve essere minore o uguale al limite maxNbLoans all m: Member| (#((L.loan).m)<=Constants.maxNbLoans) //la prenotazione del libro b implca che b sia in prestito ad un membro o che sia stato //prenotato all b : Book| some (L.membersReservingOneBook.b) => ((b in L.loan.Member) or ((#L.membersReservingOneBook.b) > 0)) //un membro m che ha preso in prestito un libro b non pu prenotarlo all m : Member,b : Book| (m in b.(L.loan) => not (m in Int.(L.membersReservingOneBook.b))) //un membro che ha prenotato un libro b non pu prenderlo in prestito (deve ritirarlo) all m : Member,b : Book| (m in Int.(L.membersReservingOneBook.b)) => not (m in b.(L.loan)) //il rinnovo del prestito di un libro da parte di un membro implica che il membro abbia //preso in prestito il libro all b : Book,m : Member| (b in L.Renew.m) =>b in (L.loan.m) //se un libro nellinsieme dei libri della biblioteca ed in prestito ad un membro, //allora il libro stato dato in prestito ad un unico membro all b : Book| ((b in L.books) and (b in L.loan.Member)) => one (b ->Member & (L.loan)) //se un libro nellinsieme dei libri della biblioteca ed stato rinnovato il suo //prestito, allora deve essere in prestito ad un unico membro all b : Book| ((b in L.books) and (b in L.Renew.Member)) => one (b ->Member & (L.Renew)) //un membro pu essere presente solo una volta nella coda di prenotazione di un libro all m:Member,b:Book | (m in Int.(Lib.membersReservingOneBook.b)) => one (Int->m & (Lib.membersReservingOneBook.b)) }

40

assert Prop14 { //per ogni stato della biblioteca //Per ogni membro appartenente allinsieme dei membri presenti nellultimo stato //della traccia //se // il primo stato della sequenza deve essere uno stato valido // e // valido TransLCR //allora // m non nellinsieme dei membri dellultimo stato della sequenza // o // la sequenza non completa, cio: // sono valide le precondizioni di LCR // e // P non lo stato finale all P : Seq | all m : LibSeq/first[P].members | ( Prop14StartLib[LibSeq/first[P]] and TransLCR[m,P] ) => ( (not m in LibSeq/last[P].members) or ( // case when the sequence is incomplete CanLCR[LibSeq/last[P],m] and not LibSeq/lastIdx[P] = LibSeq/finalIdx) ) } //Verificare la propriet 14 usando una check check Prop14 for 10 but 8 Book, 8 Member

41

Analisi dei risultati


In questo capitolo vengono analizzati i risultati del caso di studio riguardo vari aspetti delle specifiche dei sistemi informativi. Dividendo in questo modo si riescono a confrontare pi facilmente i due model checker.

Linguaggio di specifica del modello (Promela vs Alloy)


Astrazione sulle istanze delle entit Questa caratteristica consente la parametrizzazione dei numeri di istanze per ogni entit ed associazione (come il numero dei libri). Se non possibile fare questa parametrizzazione, la dimensione del testo di specifica cresce esponenzialmente. Sia Promela che Alloy hanno questa funzionalit, questa per non va data per scontata, esistono, infatti, alcuni model checker che non la forniscono (come NuSMV e Lotos-NT). Rappresentazione di strutture di entit e associazioni Questa caratteristica propria di entrambi i model checker anche se modellare azioni che coinvolgono pi associazioni (come Ritira) non banale con Promela. Rappresentazione degli scenari dei SI Questa funzione ben supportata dai model checker sotto esame. I requisiti dei sistemi informativi sono spesso descritti come scenari su eventi, dai quali sono deducibili i vincoli sullordine degli eventi. Questi vincoli sono rappresentati pi esplicitamente in linguaggi basati sugli eventi come Promela. In Alloy, che basato sugli stati anzich sugli eventi i vincoli sono specificati come precondizioni, queste sono meno facili da comprendere da un programmatore Alloy.

Linguaggio di specifica delle propriet (LTL vs Alloy)


Astrazione sulle istanze delle entit Questa caratteristica permette di scrivere propriet astraendo dalle istanze delle entit usando quantificatori sulle variabili. In caso di carenze su questo aspetto il numero di propriet da scrivere ed il numero di entit da controllare cresce esponenzialmente, perch le propriet andrebbero scritte per una particolare istanza di ogni entit. Questa funzionalit non supportata dalla LTL (e neanche dalla CTL). Alloy invece gestisce questa funzione. Specifica delle propriet dei SI Sono state identificate

le

seguenti

classi

di

propriet

dei

SI:

1. SCE: Sufficient state condition to enable an event (Es. le propriet 1 e 12). Queste sono propriet relativamente semplici da scrivere in linguaggi basati sugli stati come LTL. Tutte queste propriet devono 42

essere approssimate in Alloy, altrimenti richiederebbero un numero troppo grande di atomi per essere controllate in modo esaustivo. La validit dellapprossimazione si basa sullipotesi che la postcondizione di unazione sia soddisfacibile quando le precondizioni tengono. 2. NCE: Necessary state condition to enable an event(Es. le propriet da 2 a 11 e la 13). Come per le SCE le propriet che ricadono in questa classe sono relativamente semplici da implementare sia con i linguaggi state-based come lLTL di Spin che con le approssimazioni per Alloy. 3. SCEF: Sufficient state condition to enable an event on some execution path (Es propriet 14). Possono essere implementate in Alloy fornendo la sequenza di eventi che porta a quello desiderato, per possibile farlo solo quando la sequenza non supera il numero di atomi disponibile per questo tipo di sequenze. Non possibile implementare questo genere di propriet in LTL. 4. INV: Invariant state property (Es. propriet 15). Tutti i model checker possono gestire questo genere di propriet senza problemi. Accesso a stati ed eventi Dato che la maggior parte delle propriet usa sia stati che eventi i model checker che hanno linguaggi che supportano entrambi, come Alloy, sono pi semplici da usare, dato che possono rappresentare delle propriet in modo pi esplicito o diretto rispetto agli altri. La LTL di Spin offre un ottimo supporto per gli eventi, ma non consente di riferirsi agli stati. La gestione degli stati fondamentale per i SI.

Tempo di esecuzione e numero di istanze delle entit


La tabella sottostante mostra lesecuzione per i numeri di istanze delle entit (numero di libri e numero di membri). mostrato anche il tempo medio per lesecuzione delle propriet. Spin pu gestire fino a 5 istanze di entit. Alloy pi efficiente per i sistemi informativi su grandi quantit di istanze, pu gestire fino a 98 istanze per ogni propriet, eccetto la 14, in meno di un minuto; la propriet 14 viene verificata su 8 membri e 8 libri in pochi minuti. Con il caso di studio della biblioteca, 3 il numero minimo di istanze che consentono di controllare la coda di prenotazioni con lunghezza maggiore di 1.

43

Spin |Libri|/|Membri| 3/3 Tempo di 772,52 verifica(sec) Numero di 14 propriet controllate Tempo medio di 55,18 verifica per propriet(sec)

5/5 8645,6 14 617,54

Alloy 3/3 221,08 15 14,74

8/8 288,59 15 19,24

Conclusioni
stata descritto il confronto tra due model checker per la verifica dei sistemi informativi, il paragone basato su un tipico SI. Lo studio rivela che un buon model checker per sistemi informativi deve avere un linguaggio di specifica molto duttile per permettere di implementare in modo adeguato modelli e propriet, questo dovrebbe supportare sia gli stati che gli eventi. Laccessibilit agli operatori algebrici necessaria se si vuole esprimere in modo semplice i vari scenari dei SI, mentre le variabili di stato sono utili per snellire le specifiche delle propriet. La LTL utile ma insufficiente visto che non permette di descrivere alcune propriet, come quelle di classe SCEF. Alloy che usa logica del primo ordine pura sufficiente, anche se poco intuitivo nel caso delle propriet SCEF. Dato che queste conclusioni derivano da un singolo esempio, dovrebbero essere validate da esperimenti con altri esempi. Comunque il caso di studio della biblioteca sufficientemente complesso da mostrare un buon numero di caratteristiche che si possono trovare nella maggior parte dei SI. Questo esempio contiene solo due entit e due associazioni, sistemi informativi di grandi dimensioni, solitamente, hanno centinaia di entit ed associazioni, ma ragionevole supporre che la verifica di una propriet possa essere limitata alle entit ed alle relazioni coinvolte; quindi le propriet da verificare in questo caso di studio possono rappresentare quelle di un vero sistema informativo. Casi di studio addizionali troveranno sicuramente altri limiti di questi model checker, ad esempio questo caso di studio orientato alla validazine di una sequenza di azioni che devono essere accettate da un sistema informativo, ma non copre loutput delivery (Es. query) o le interazioni sulle interfacce utente. Si ribadisce che questo un confronto su un dominio specifico, non stabilisce la netta superiorit di Alloy su Spin nel caso generale, ma si limita ad ipotizzarla per il dominio dei SI. 44

Bibliografia
[1] Pezz, M., Young, M.: Software testing and analisys: Process, Principles and tecniques. Wiley (2008) [2] Marc Frappier, Benot Fraikin, Romain Chossart, Raphal Chane-Yack-Fa, Mohammed Ouenzar: Comparison of Model Checking Tools for Information Systems. GRIL, Universit de Sherbrooke, Qubec, Canada (2010) [3] Aydal, E.G., Utting, M., Woodcock, J.: A comparison of state-based modelling tools for model validation. TOOLS-Europe08, Switzerland (2008) [4] Biere, A., Clarke, E.M., Cimatti, A., Zhu, Y.: Symbolic model checking without BDDs. In: Proceeding of Tools and Algorithms for the Analysis and Construction of Systems (TACAS99). LNCS, vol. 1579, pp. 193207 (1999) [5] Bolognesi, T., Brinksma, E.: Introduction to the ISO specification language LOTOS. In: van Eijk, P.H.J., Vissers, C.A., Diaz, M. (eds.) The Formal Description Technique LOTOS, pp. 2373. Elsevier Science Publishers B.V. (1989) [6] Chane-Yack-Fa, R., Fraikin, B., Frappier, M., Chossard, R., Ouenzar, M.: Comparison of model checking tools for information systems. Tech. Rep. 29, Universit de Sherbrooke (Jun 2010), disponible from http://pages.usherbrooke.ca/gril/TR/TR-GRIL-1006-29.pdf [7] Clarke, E.M., Emerson, E.A.: Synthesis of synchronization skeletons for branching time temporal logic. In: Kozen, D. (ed.) Logic of Programs Workshop. LNCS, vol. 131. Springer-Verlag (1981) [8] Deutsch, A., Sui, L., Vianu, V.: Specification and verification of data-driven web applications. Journal of Computer and System Sciences 73(3), 442474 (2007) [9] Emerson, E.A., Halpern, J.Y.: Sometimes and Not Never revisited: On branching versus linear time temporal logic. J. ACM 33(1), 151178 (1986) [10] Garavel, H.: Compilation et vrification de programmes LOTOS. Ph.D. thesis, Universit Joseph Fourier, Grenoble (November 1989) [11] Holzmann, G.J.: The Spin Model Checker: Primer and Reference Manual. Addison-Wesley (2004) [12] Jackson, D.: Software Abstractions. MIT Press (2006) [13] Leuschel, M., Butler, M.: ProB: A model checker for B. In: Araki, K., Gnesi, S., Mandrioli, D. (eds.) FME 2003: Formal Methods. LNCS, vol. 2805, pp. 855 874. Springer-Verlag (2003) 45

[14] Mateescu, R., Garavel, H.: XTL: A meta-language and tool for temporal logic model-checking. In: Proceedings of the InternationalWorkshop on Software Tools for Technology Transfer STTT98. p. 10. Aalborg, Denmark (Jul 1998) [15] McMillan, K.L.: Symbolic Model Checking. Ph.D. thesis, Carnegie Mellon University (1993) [16] Morimoto, S.: A survey of formal verification for business process modeling. Lecture Notes in Computer Science 5102, 514524 (2008) [17] Pnueli, A.: The temporal logic of programs. In: Foundations of Computer Science, 18th Annual Symposium on. pp. 4657 (1977) [18] Abrial, J.R.: The B-Book: Assigning Programs to Meanings. Cambridge University Press, Cambridge,UK (1996) [19] Augusto, J.C., Ferreira, C., Gravell, A.M., Leuschel, M., Ng, K.M.Y.: The benefits of rapid modellingfor e-business system development. ER Workshops pp. 1728 (2003)

46