universitÀ di pisa - cnr
TRANSCRIPT
UNIVERSITÀ DI PISA
Facoltà di Scienze, Matematiche, Fisiche e Naturali
Corso di Laurea Specialistica in Informatica
Tesi di Laurea
Studio ed implementazione di un algoritmo per generare i
prodotti validi in Product Family Engineering
Relatore Candidato
Prof.ssa Stefania Gnesi Aldi Sulova
Relatore
Dott. Franco Mazzanti
Anno Accademico 2010/2011
Alla mia famiglia...
Sommario
Questo lavoro di tesi si colloca all'interno dell'attività di ricerca svolta presso il gruppo
di metodi formali dell'ISTI al CNR di Pisa. I temi principali sono la Product Family
Engineering (PFE) ed il Model Checking. Più speci�catamente mi sono occupato del-
l'implementazione di un algoritmo che genera i prodotti validi a partire da un modello
astratto di una famiglia di prodotti. Inoltre, è stato realizzato un ambiente che presen-
ta le seguenti funzionalità: 1) descrivere il modello di una famiglia mediante una sintassi
ben de�nita, 2) esprimere vincoli statici e comportamentali sulle funzionalità dei prodotti,
3) generare i prodotti validi, 4) veri�care formalmente proprietà sul modello della famiglia
e sui singoli prodotti. Il contributo principale e più signi�cativo è stato nel punto 3, cosa
che ha dato il titolo anche a questa tesi.
Per realizzare gli obbiettivi il lavoro si è focalizzato sull'attività di ricerca eseguita dal
gruppo di metodi formali nell'ambito del PFE, e sull'utilizzo di FMC, un model checker
con logica branching basata su azioni (ACTL), per reti di automi de�niti come algebra
dei processi in un formalismo CCS-like. Come risultato �nale è ottenuta una applicazione
a linea di comando accessibile anche mediante una più elaborata interfaccia web.
ii
Indice
1 Introduzione 1
1.1 Contributo della tesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Sintesi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Product Family Engineering 6
2.1 Ingengneria del Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Product Family Engineering . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.3 La variabilità . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 Model Checking 12
3.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.2 Modelli formali . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3 Logica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3.4 Model checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4 Attività di ricerca 25
4.1 Introduzione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2 Esempio della macchina del ca�è . . . . . . . . . . . . . . . . . . . . . . . 26
4.3 Feature Modelling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
iii
4.4 Logica deontica e Feature Models . . . . . . . . . . . . . . . . . . . . . . . 28
4.5 Modal Transition System . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
4.6 MHML, logica temporale in Product Families . . . . . . . . . . . . . . . . 34
4.7 Proprietà statiche e comportamentali in MHML . . . . . . . . . . . . . . . 37
5 Generazione dei prodotti validi di una famiglia 39
5.1 Il modello di una famiglia . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.2 Algoritmo per generare i prodotti validi . . . . . . . . . . . . . . . . . . . . 41
5.3 Implementazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.4 Prodotti validi della macchina per ca�è . . . . . . . . . . . . . . . . . . . . 57
5.5 Validità di una sottofamiglia oppure di un prodotto . . . . . . . . . . . . . 57
5.6 Osservazioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
6 Interfaccia Web 61
6.1 De�nire il modello della famiglia . . . . . . . . . . . . . . . . . . . . . . . . 61
6.2 Veri�ca di proprietà con VMC . . . . . . . . . . . . . . . . . . . . . . . . . 66
7 Conclusioni e lavoro futuro 69
iv
Elenco delle �gure
3.1 Modelli per una macchina da ca�è . . . . . . . . . . . . . . . . . . . . . . . 16
3.2 Signi�cato degli operatori temporali in LTL . . . . . . . . . . . . . . . . . 18
3.3 Esempi di predicati in CTL . . . . . . . . . . . . . . . . . . . . . . . . . . 20
3.4 Operatori temporali in HML . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.1 Feature Diagram per la famiglia di macchine da ca�è . . . . . . . . . . . . 28
4.2 MTS per la macchina da ca�è . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.1 Passo dell'algoritmo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
5.2 Generazione delle combinazioni. . . . . . . . . . . . . . . . . . . . . . . . . 55
5.3 LTS della macchina da ca�è per il mercato europeo . . . . . . . . . . . . . 57
5.4 LTS della macchina da ca�è per il mercato statunitense . . . . . . . . . . . 58
5.5 a alternative b, perché non posso tener i prodotti intermedi in MTS . . . . 60
6.1 VMC, pagina iniziale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.2 VMC, scegliere il modello . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
6.3 VMC, descivere il modello . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.4 VMC, modello caricato . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
6.5 VMC, lista prodotti validi della famiglia . . . . . . . . . . . . . . . . . . . 64
6.6 VMC, LTS di un prodotto . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
v
6.7 VMC, MTS della famiglia . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
6.8 VMC, veri�care proprietà sulla famiglia . . . . . . . . . . . . . . . . . . . . 67
6.9 VMC, veri�care proprietà sui prodotti . . . . . . . . . . . . . . . . . . . . 68
vi
Capitolo 1
Introduzione
I sistemi software sono sempre più complessi, questo fa si che le aziende si orientino verso
le cosiddette Product Family. Una Software Product Family [14] è una gamma di prodotti
che condivide una base comune di funzionalità. Diversi modelli si ottengono estendendo
il prodotto base con caratteristiche aggiuntive per, ad esempio, soddisfare una particolare
tipologia di clienti oppure soddisfare mercati di paesi di�erenti. Possiamo distinguere due
parti in una famiglia, la parte condivisa e la parte estendibile. La parte estendibile viene
riferita nel campo con il termine variabilità, e rappresenta quelle funzionalità che sono
usate per costruire diversi prodotti della famiglia.
Un formalismo ampiamente utilizzato e al quale si fa riferimento in questa tesi per descri-
vere una famiglia di prodotti è il Feature Modelling [9]. Nella modellazione della variabilità
in Feature Modelling, l'interesse sta nel de�nire quali funzionalità o componenti di un si-
stema siano opzionali oppure necessari e quali siano le relazioni tra loro.
Le relazioni vincolanti ed ulteriori proprietà dei prodotti si possono formalizzare mediante
una logica proposizionale [15] e veri�cate utilizzando algoritmi e�cienti per trovare un
assegnamento che rende vere le formule (SAT Solvers). In questo modo posso stabilire le
1
funzionalità che un prodotto �nale deve, non deve, o può avere. Mediante questo procedi-
mento però, non si ha la possibilità di esprimere il comportamento nel tempo dei prodotti
e quali caratteristiche nell'evoluzione sono obbligatorie o permesse.
Il Modal Transition System (MTS) [8] è riconosciuto come il modello formale per de-
scrivere il comportamento nel tempo delle famiglie di prodotti. Un MTS è simile ad un
Labelled Transition System (LTS), ma diversamente dall'LTS le transizioni si presentano
in due tipi, must e may. Una transizione must indica che l'azione in essa contenuta è
obbligatoria, ovvero che ogni prodotto �nale deve avere la possibilità di eseguire l'azio-
ne, mentre la transizione may indica che un prodotto �nale può anche non avere tale
possibilità. Questo formalismo esprime in modo naturale le transizioni che devono essere
disponibili in un prodotto e quelle che sono transizioni opzionali per estendere il prodotto.
Data una famiglia di prodotti, un singolo MTS permette di de�nire:
• il comportamento della famiglia mediante stati ed azioni comuni a tutti gli prodotti,
transizioni must,
• la variabilità, ovvero i punti dove il comportamento rende i prodotti estendibili
mediante le transizioni may.
La logica deontica [3] fornisce un modo naturale per formalizzare concetti come la violazio-
ne, obbligo, permesso e divieto. Una logica deontica contiene gli operatori proposizionali
logici classici, negazione (¬), congiunzione (∨), disgiunzione (∧), implicazione (⇒) a cui
sono aggiunti gli operatori deontici. I due principali operatori deontici sono; è obbligatorio
che (O) ed è permesso che (P).
Una caratterizzazione deontica di un Feature Model è un insieme di formule deontiche
la congiunzione delle quali descrive in modo preciso la famiglia dei prodotti. In [1] si
descrive anche una caratterizzazione di un MTS con formule deontiche mediante la logica
2
proposizionale deontica completa de�nita in [3]. Quello che è importante dire è che a
partire da questi studi si hanno le basi per de�nire MHML.
MHML [2][16] è una logica deontica temporale branching basata su azioni ed interpretata
su un MTS, con la quale è possibile esprimere concetti di variabilità su una famiglia di pro-
dotti. In confronto con il Feature Modelling, MHML aggiunge la possibilità di speci�care
ed analizzare nello stesso ambiente proprietà statiche e comportamentali delle famiglie.
I concetti di variabilità trattati in questa tesi e che hanno origine nel Feature Modelling
riguardano le funzionalità opzionali espresse mediante le transizioni may nell'MTS che
descrive la famiglia. In particolare, siamo interessati alla espressione dei seguenti vincoli
fra tali funzionalità:
• a alternative b, solo una delle due funzionalità è presente;
• a requires b, se a è presente nel prodotto �nale anche b lo è;
• a exclude b, a e b non possono co-esistere nello stesso prodotto;
ed alla loro espressione mediante predicati nella logica MHML. Per esempio la formula
logica:
(EF 〈 a〉 true) ⇒ (EF 〈 b〉 true)
rappresenta il vincolo 〈 a requires b〉. In ogni prodotto della famiglia questa proprietà
deve essere valida. In MHML i vincoli che riguardano le funzionalità alternative, exclude e
requires si rappresentano con opportune formule, come vedremo più avanti, simili a quella
introdotta precedentemente.
Una importante operazione in PFE è derivare tutti i prodotti validi di una famiglia. Il
contributo principale di questa tesi è lo studio e l'implementazione di un algoritmo che
3
realizza questa operazione. L'algoritmo parte dall'MTS che modella la famiglia e dall'in-
sieme di formule esprimenti vincoli di variabilità de�nite in MHML. Il risultato della sua
esecuzione è una lista di prodotti validi: un prodotto valido è un LTS con tutte le azioni
presenti in transizioni must della famiglia, la selezione di qualche azione presente in una
transizione may, e che rispetta i vincoli espressi in MHML.
1.1 Contributo della tesi
L'obbiettivo principale della tesi è l'implementazione di un algoritmo che genera i prodotti
validi a partire da un modello astratto di una famiglia di prodotti. Inoltre, è stato
realizzato un ambiente di analisi e veri�ca che permette di:
• descrivere il modello di una famiglia di prodotti mediante una sintassi ben de�nita,
• esprimere vincoli statici e comportamentali sulle funzionalità dei prodotti,
• generare i prodotti validi,
• veri�care formalmente proprietà sul modello della famiglia e sui singoli prodotti.
Il contributo principale e più signi�cativo è stato nel punto 3. Per realizzare gli obbiettivi
il mio lavoro si è focalizzato sull'attività di ricerca eseguita dal gruppo di metodi formali
nell'ambito del PFE [1][2][16][17] , e sull'utilizzo di FMC [12], un model checker con logica
branching basata su azioni (ACTL), per reti di automi de�niti come algebra dei processi
in un formalismo CCS-like. Come risultato �nale è ottenuta una applicazione command
line accessibile anche mediante una più elaborata interfaccia web.
4
1.2 Sintesi
Questa tesi è organizzata come segue. Il Capitolo 2 e 3 o�rono una presentazione sintetica
dei concetti principali della tesi, la Product Family Engineering ed il Model Checking. Nel
capitolo 4 viene presentato il lavoro di ricerca sul quale si basa questa tesi. Nel capitolo
5 sono descritte le scelte, le problematiche ed i risultati ottenuti. Il capitolo 6 presenta
l'interfaccia web ed un semplice esempio su come si può utilizzare. Nel capitolo 7 le
conclusioni e qualche possibile lavoro futuro.
5
Capitolo 2
Product Family Engineering
In questo capitolo si presenta la Product Family Engineering [14]. Inizialmente viene
introdotto l'ingengneria del software come una disciplina ormai consolidata per assistere
un team di sviluppatori nel processo di realizzazione di un sistema software. Il capitolo
procede con una breve descrizione della PFE e del contesto nel quale questo approccio
ingegneristico del software presenta dei vantaggi. In�ne, viene introdotto il concetto
principale di questo paradigma che è la variabilità. Gran parte della ricerca sulla PFE
si concentra su questo concetto, inoltre, ha un ruolo importante nella mia tesi in quanto
l'algoritmo realizzato per generare i prodotti validi della famiglia deve analizzare modelli
che esprimono variabilità.
2.1 Ingengneria del Software
Il primo calcolatore data negli anni 40 del secolo scorso. Si trattava di un semplice ese-
cutore automatico di istruzioni in grado di elaborare funzioni pre stabilite. Il programma
era cablato dentro la macchina e non c'era possibiltà di cambiarlo. Per eseguire altre
6
funzionalità si doveva ricostruire la macchina. In pratica non esisteva la distinzione tra
software e hardware. Negli anni 50 vengono in luce i primi linguaggi di programmazione,
il linguaggio assembler e successivamente Fortran per calcoli scienti�ci e Cobol per appli-
cazioni gestionali. La tecnologia continuava ad evolversi ma non l'approccio allo sviluppo
del software, che si de�niva come un processo artigianale dove il programmatore gestiva
tutte le fasi: costruzione, manutenzione e utilizzo della applicazione.
Negli anni 60 il costo del sviluppo di nuove applicazioni software lievitò drasticamente a
seguito di due principali cause:
• le richieste dal mercato per funzionalità sempre piu complesse, rese disponibili anche
dalle nuove potenzialità di calcolo introdotte da nuovi potenti calcolatori,
• la seria di�coltà del programmatore nel gestire individualmente una quantita di
lavoro che aumentava di dimensioni.
Il risultato era software poco a�dabile, troppo costoso e che generalmente non rispettava
i termini di scadenza. Queste conseguenze implicavano la impossibilità di continuare a
vedere il software come un prodotto artigianale creato da una sola persona, ma come una
attività che doveva essere svolta in gruppo. Il software doveva diventare il prodotto di un
processo ingegneristico, con compiti di�erenziati del personale coinvolto e con metodolo-
gie di sviluppo ben de�nite. Il problema della costruzione di un software doveva essere
a�rontato nello stesso modo adottato dagli ingegneri tradizionali per costruire sistemi
grandi e complessi come ponti, navi, aeroplani, ecc. L'obbiettivo era quello di stabilire
metodologie, strumenti, teorie e tecniche simili a quelle utilizzate in un approccio inge-
gneristico classico.
Possiamo de�nire l'ingegneria del software come l'applicazione dell'ingegneria al software.
Più precisamente, l'IEEE Standard 610.12-1990 Glossario standard della terminologia
7
dell'ingegneria del software(ANSI) de�nisce l'ingegneria del software come l'applicazione
di un approccio sistematico, disciplinato e quanti�cabile nello sviluppo, funzionamento e
manutenzione del software.
2.2 Product Family Engineering
La diversità del software richiesto dal mercato ha dato origine allo sviluppo di nuove
tecniche ingegneristiche. Naturalmente, particolare interesse si è mostrato per i sistemi
software complessi e di grandi dimensioni. Le caratteristiche di questo insieme di pro-
dotti hanno portato gli ingegneri del software a considerare la possibilità del riuso degli
artefatti software. Varie tecnologie sono state proposte tra le quali "l'object-oriented sy-
stem development", "software design patterns" oppure il "component-oriented software
development". Il riuso si è quindi trasformato in un concetto chiave nel campo. Questo
perchè la sua applicazione porta a miglioramenti in termini di produttività, volta alla:
• riduzione dei costi, non si deve rifare tutto dall'inizio;
• risposta al mercato, si può avere un prodotto �nale in tempi più brevi;
• qualità, utilizzo di componenti già utilizzati e veri�cati.
Nel contesto del riuso nasce anche la Product Family Engineering. La PFE è un approccio
ingegneristico nel processo di sviluppo software nel quale, i prodotti generati condividono
una base comune di funzionalità. L'obbiettivo è quello di de�nire delle metodologie for-
mali per assistere il team di sviluppo nel riutilizzo delle architetture, codice sorgente, test
cases, ecc. ai �ni di ridurre i costi ed i tempi di messa ad opera di un prodotto.
La PFE ha una visione del riuso diversa dalle tecnologie menzionate precedentemente. Si
8
passa da una visione opportunistica, dove il team di sviluppatori cerca di utilizzare com-
ponenti standard oppure componenti de�niti in altri progetti, ad una visione piani�cata
dove il sistema che rappresenta il dominio applicativo viene progettato speci�catamente
per praticare un e�cace riuso di componenti e architetture.
Una famiglia di prodotti è una gamma di prodotti che condivide una base comune di
funzionalità. Diversi modelli si ottengono con�gurando il prodotto base con caratteri-
stiche aggiuntive per, ad esempio, soddisfare una particolare tipologia di clienti oppure
soddisfare mercati di paesi di�erenti. Si può fare l'esempio di una famiglia di software per
macchine da ca�è. Per soddisfare il mercato europeo la macchina deve accettare come
moneta l'euro e avere la possibilità di scegliere il cappuccino. La macchina per il mercato
statunitense invece, prende come moneta il dollaro e la possibilità di o�rire il cappuccino
non è obbligatoria. I produttore, quindi, deve riprodurre e/o adattare un suo prodotto un
numero di volte pari al numero di tutte le varianti individuate. Questo signi�ca di dover
gestire n prodotti diversi anche se questi sono estremamente simili tra loro (il ca�è, il tè,
ecc. sono o�erte in tutte le macchine). L'economicità della metodologia sta proprio nella
gestione del nucleo comune di tutti i prodotti e nel costo ridotto della gestione delle parti
di�erenti. I vantaggi di questo approccio sono:
• analizzare i requisiti per l'intera famiglia e speci�care solo le di�erenze tra i singoli
prodotti invece di descrivere i requisiti per ognuno di questi;
• riutilizzo degli artefatti software, si intende parte dell'architettura, documentazione
oppure codice sorgente, ovvero un qualsiasi prodotto del processo di sviluppo;
• limitare alcuni tipi di analisi costosi relativi alla qualità del software solo sul nucleo.
La PFE si compone di due sotto processi relativamente indipendenti tra loro: la domain
engineering e la application engineering. La domain engineering si focalizza nell'iden-
9
ti�cazione degli artefatti software comuni alla famiglia e nell'evidenziazione delle parti
variabili che caratterizzano i prodotti. La application engineering si occupa della crea-
zione dei prodotti a partire dalla piattaforma creata nella de�nizione del dominio. Nella
speci�ca di un nuovo prodotto vengono scelte le caratteristiche che il nuovo prodotto deve
avere oltre alle caratteristiche di base.
2.3 La variabilità
A�nché il paradigma del PFE abbia successo si devono attentamente valutare le parti
comuni e le parti estendibili dei prodotti della famiglia. La parte con�gurabile è ricono-
sciuta nel campo con il termine variabilità, e rappresenta quegli aspetti che sono usati
per costruire diversi prodotti. Un formalismo ampiamente utilizzato e al quale si fa riferi-
mento in questa tesi per descrivere una famiglia di prodotti è il Feature Model. Nella fase
della domain engineering il dominio del sistema software viene rappresentato mediante
un insieme di funzionalità e ogni prodotto si caratterizza da una opportuna selezione delle
medesime. Le features sono classi�cate nel modo seguente:
• optional features, funzionalità opzionali;
• mandatory features, funzionalità obbligatorie;
Si possono de�nire anche vincoli tra le funzionalità:
• alternative features, un insieme di funzionalità tra le quali solo una è presente.
• a require b, se a è presente nel prodotto �nale anche b lo è;
• a exclude b, a e b non possono co-esistere nello stesso prodotto.
10
Nella de�nizione della variabilità l'interesse sta nel descrivere quali funzionalità o com-
ponenti di un sistema siano opzionali oppure necessari e quali siano le relazioni tra loro.
Successivamente, tecniche e strumenti sono stati sviluppati per stabilire se un prodotto
fa parte della famiglia, oppure per derivare un prodotto da una famiglia selezionando le
funzionalità o gli componenti che si vuole.
11
Capitolo 3
Model Checking
In questo capitolo si presenta la tecnica del Model Checking [4]. Una breve introduzione
iniziale da una panoramica generale del metodo. Il capitolo procede con la de�nizione dei
modelli formali utilizzati per descrivere un modello di un sistema software, solitamente
espresso mediante un sistema di transizioni, cioè grafo orientato formato da nodi e archi.
Successivamente si introduce la logica temporale, che consente di formalizzare proprietà
relative all'evoluzione nel tempo del sistema. In�ne, si presentano i due approcci comu-
nemente utilizzati per scrivere algoritmi di veri�ca che sono il global ed il local model
checking.
La conoscenza del model checking è necessaria per studiare l'attività di ricerca descritta
in dettaglio nel capitolo successivo, dove quest'ultima ha come obiettivo la de�nizione di
un framework logico sul quale si possono esprimere e veri�care proprietà su una famiglia
di prodotti. Inoltre, per de�nire in modo corretto la procedura di generazione dei prodotti
validi si poteva far riferimento ad algoritmi di model checking, ovvero l'esplorazione dei
nodi e degli archi di un sistema di transizioni.
12
3.1 Introduzione
La tecnica del model checking, introdotta da Clarke, Emerson [4] e contemporaneamente
da Quielle e Sifakis agli inizi degli anni '80, è basata su idee estremamente semplici ed è
probabilmente uno dei più signi�cativi avanzamenti della ricerca in informatica di base di
questi ultimi decenni.
Nella veri�ca tramite model checking il sistema sotto analisi viene descritto con un lin-
guaggio formale e successivamente modellato mediante un sistema di transizione (Kripke
Structure oppure Labelled Transition System). Le proprietà da veri�care su di esso sono
rappresentate tramite un linguaggio preciso e non ambiguo, tipicamente in logica tem-
porale, e la loro soddisfacibilità sul sistema di transizione che modella il sistema viene
veri�cata in modo e�ciente ed automatico. Se le proprietà non sono soddisfatte una
traccia di esecuzione (controesempio) è mostrata al �ne di evidenziare perche si ha il fal-
limento nella veri�ca.
In sintesi la veri�ca tramite model checking consiste, dato un sistema di transizione M
modello di un sistema e una formula di logica temporale φ, che rappresenta una proprietà
che si desidera che M abbia, nel veri�care se M soddisfa φ.
3.2 Modelli formali
In generale, il comportamento del sistema software viene rappresentato mediante una
struttura a grafo, dove i nodi rappresentano gli stati del sistema e gli archi le transizio-
ni tra gli stati. I gra� di per se non sono molto espressivi quindi a loro viene aggiunto
dell'informazione. Da qui nascono anche i due approcci comunemente utilizzati per for-
malizzare una descrizione del sistema nelle prime fasi del processo di sviluppo, che sono;
13
a) Kripke Structure dove i nodi sono annotati con le proposizioni atomiche (AP, atomic
propositions) e, b) Labelled Transition System (LTS), sistemi di transizioni etichettati
dove gli archi vengono annotati con le azioni.
Le due descrizioni sono ampiamente accettate come delle notazioni formali chiare, sem-
plici e su�cientemente astratte.
Kripke Structure. Un Kripke Structure K è una tupla K = (S, S0, R, L, AP) dove:
1. S è un insieme �nito di stati;
2. S0 ⊆ S è l'insieme degli stati iniziali;
3. R ⊆ S × S è una funzione di transizione totale, ovvero che per ogni stato s ∈ R
esiste uno stato s' ∈ R tale che R(s,s');
4. L: S → 2AP è una funzione che associa ogni stato con l'insieme delle proposizioni
vere in quel stato.
Un cammino nella struttura di Kripke K che parte da uno stato s è una sequenza in�nita
di stati π = s0s1s2... tale che s = s0 e per ogni i ≥ 0, R(si,si+1).
Labelled Transition System. Un LTS è una tupla L = (S, S0, Act, →) dove:
1. S è un insieme �nito di stati;
2. S0 ⊆ S è un l'insieme degli stati iniziali;
3. Act è l'insieme delle azioni;
4. → ⊆ S × Act × S è la funzione di transizione, (s,a,s') oppure sa−→ s' descrive che
il sistema si muove dallo stato s allo stato s' eseguendo l'azione a.
14
Un cammino in un LTS L che parte da uno stato s è una sequenza in�nita di stati
e transizioni alternati π = s0a1s1a2s2... tale che s = s0, ai ∈ Act e per ogni i ≥ 0,
(si ,ai+1, si+1) ∈ →.
3.3 Logica
Delle proprietà tipiche che si possono veri�care su un sistema modellato mediante un
Kripke Structure sono:
• a partire dallo stato s0 esiste uno stato s' in qualche cammino dove la proposizione
logica p è vera, ovvero: ∃ π = s0s1 ... ed una i ≥ 0 tale che si ∈ π e si(p) = true,
• a partire dallo stato s0 si ha un cammino tale che la proposizione logica p è vera su
tutti gli stati del cammino.
In un LTS una proprietà da veri�care può essere:
• a partire dallo stato s0 esiste in qualche cammino uno stato s' dove s'b−→ s�, ovvero:
∃ π = s0a1s1a2s2... ed una i ≥ 0 e ai ∈ Act tale che sib−→ si+1 e b ∈ Act.
Si può notare come le domande proposte hanno implicitamente il senso del tempo. In
un cammino arriverò nel futuro in uno stato con una particolare proprietà (eventually)
oppure, tutti gli stati del cammino hanno una qualche proprietà (always). Per logica
temporale si intende una logica classica in cui le formule possono essere arricchite da dei
quanti�catori temporali (always, eventually), anche se questi non hanno alcuna misura
esplicita del tempo. La logica predica su variabili di stato della struttura di Kripke oppure
sulle azioni di un LTS considerato. Sono interpretate su alberi di computazioni, i cammini
possibili di una esecuzione a partire dallo stato iniziale.
15
I due tipi di logiche temporali più comunemente utilizzate sono: linear-time logic e la
branching-time logic. La nozione qualitativa del tempo è de�nita sul cammino. Nella
logica linear-time in ogni istante esiste un unico possibile successore e quindi un solo
possibile stato futuro. In questo senso il tempo è lineare. Questo modello considera il
comportamento del sistema come l'insieme di tutti i possibili cammini da uno stato par-
ticolare. Un predicato φ è valido se lo è per ogni computazione dell'insieme.
Nella logica branching la nozione del tempo non è lineare bensì ha una struttura ad albero,
ad ogni istante esiste un insieme di possibili stati successori. Le computazioni sono rag-
gruppate in alberi computazionali le cui rami�cazioni rappresentano le diverse possibilità
di continuare in una computazione. Una proprietà φ è valida se l'albero di computazione
generato da uno stato particolare soddisfa φ. Per rendere più chiari i concetti introdotti
prendiamo come esempio due modelli diversi di una macchina da ca�è. La macchina
Figura 3.1: Modelli per una macchina da ca�è
dopo l'inserimento di una moneta può servire il ca�è oppure il tè. Nel primo modello è
il cliente che sceglie la bevanda, nel secondo invece, è la macchina che fa una scelta in-
terna. Tutti a due i modelli hanno lo stesso insieme di computazioni possibili: {(moneta,
ca�è), (moneta, tè)}. Una logica linear-time non sarebbe in grando di distinguere tra i
due modelli. In una logica branching-time invece posso esprimere la proprietà: è possibile
scegliere un ca�è dopo aver inserito una moneta. Tale proprietà distingue i due modelli
16
di una macchina per ca�è.
In seguito vengono introdotte la LTL (Linear Temporal Logic) e la CTL (Computation
Tree Logic), logiche linear-time e branching-time rispettivamente e che vengono inter-
pretate su un Kripke Structure. Inoltre, sono introdote anche la ACTL (Action-Based
Computation Logic) e la Hennessy Milner Logic, logiche interpretate su un LTS.
Linear Temporal Logic. La logica LTL consente di predicare formule senza alcuna consi-
derazione della struttura ad albero dei cammini e�ettuati dal sistema nella sua evoluzione
dallo stato scelto. Nel veri�care la validità di una proprietà devo considerare tutte le
possibili computazioni uno ad uno.
La formule nella logica LTL sono de�nite come segue:
φ ::= p | ¬φ | φ1 ∨ φ2 | X(φ) | U(φ1, φ2) | F (φ) | G(φ)
Le formule sono interpretate sui cammini di un Kripke Structure
K = (S, S0, R, I, AP). Un cammino �nito è una sequenza �nita, non vuota π = 〈s0...sn−1〉
di stati s0, ..., sn−1 ∈ S tale che (si, si+1) ∈ R per ogni 0 ≤ i < n − 1. n viene chiamata
la lunghezza del cammino, e si denota con |π|. Un path in�nito è una in�nita sequenza
π = 〈s0, s1, s2...〉 di stati in S tale che (si, si+1) ∈ R per ogni i ≥ 0. La lunghezza di un
cammino in�nito è ∞. Per 0 ≤ i < |π|, πi denota l'i-esimo stato nel cammino π, mentre
πi = 〈si, si+1, ...〉 è la coda del cammino che inizia in si. In particolare, s0 = π.
Sia K = (S, R, L) un Kripke Structure e sia π un cammino in K, la relazione |= è de�nita
induttivamente come:
• π |= p sse p ∈ L(π0)
• π |= ¬φ sse π 6|= φ
17
• π |= φ1 ∨ φ2 sse π |= s1 oppure π |= φ2
• π |= X(φ) sse |π| > 1 e π1 |= φ
• π |= G(φ) sse per ogni k con 0 ≤ k < |π|, sk |= ϕ
• π |= F (φ) sse esiste k, 0 ≤ k < |π|, con sk |= ϕ
• π |= U(φ, ϕ) sse esiste k, 0 ≤ k < |π|, con sk |= ϕ e per ogni i, 0 ≤ i < k, si |= φ
L'operatore temporale X(φ) stabilisce se φ è valido oppure no nel prossimo stato del cam-
mino; G(φ) se φ è valido in tutti gli stati del cammino; F(φ) se prima o poi (in qualche
stato nel futuro) φ vale; U(φ, ψ) se ψ diventera vero in uno stato e φ è vero in tutti gli
stati visitati precedentemente. Il signi�cato degli operatori temporali è mostrato nella
�gura 3.2. Una struttura di Kripke K in uno stato s ∈ S soddisfa la formula φ (K, s |= φ)
Figura 3.2: Signi�cato degli operatori temporali in LTL
se tutti i cammini di K che partono da s soddisfano φ.
Computation Tree Logic. Le formule in CTL consentono di predicare sulla struttura
ad albero delle possibili computazioni che partono da un determinato stato iniziale. Ar-
rivato in un particolare stato che veri�ca la proprietà p la sua struttura ad albero veri�ca
la proprietà q. Cioè si possono esprimere proprietà della forma; per ogni cammino da
18
uno stato iniziale s si puo trovare nel futuro uno stato s' tale che la proprietà q vale
nel sottoalbero delle computazioni che iniziano in s'. Si può notare come le proprietà
riguardano non solo il cammino ma anche un particolare stato nel cammino. Le formule
in CTL sono divise in formule di stato (state formula) e in formule di cammino (path
formula). Le formule di stato sono a�ermazioni sul valore di una proposizione atomica
in uno stato scelto oppure sulla struttura ad albero delle computazioni che partono da
questo stato. Le path formula sono formule sui cammini che partono da uno stato. Per
speci�care queste proprietà vengono introdotti gli operatori di quanti�cazione universale
ed esistenziale.
Formalmente:
Formule di Stato: φ ::= true | p | φ1 ∨ φ2 | ¬φ | ∃ϕ | ∀ϕ
per p proprietà atomica e ϕ una formula di cammino.
Formule di cammino: ϕ ::= X(φ) | U(φ1, φ2) | F (φ) | G(φ)
dove φ, φ1, φ2 sono state formula.
La �gura 3.3 illustra il signi�cato degli operatori temporali.
Sia K = (R, S, L) un Kripke Structure e sia s ∈ S uno stato qualunque. La relazione |=
è de�nita nel modo seguente:
• K, s |= p sse p ∈ L(s)
• K, s |= ¬φ sse K, s 6|= φ
• K, s |= φ1 ∨ φ2 sse K, s |= φ1 oppure K, s |= φ2
• K, s |= Aϕ sse K, s |= ϕ per ogni cammino π di K che inizia in s
• K, s |= Eϕ sse K, s |= ϕ per qualche cammino π di K che inizia in s
19
Figura 3.3: Esempi di predicati in CTL
Gli operatori temporali X,G, F, U sono de�niti in maniera uguale come per la logica li-
neare.
Hennessy-Milner Logic. E una logica temporale branching il cui dominio di interpretazione
è il Labelled Transition System. Le formule sono de�nite come segue:
φ ::= true | false | φ1 ∧ φ2 | φ1 ∨ φ2 | [a]φ | 〈a〉φ
dove a ∈ Act.
La logica viene interpretata su un LTS. Sia L = (S, Act, −→), la relazione |= viene de�nita
induttivamente,
• L, s |= true sse L, s 6|= false
• L, s |= φ1 ∧ φ2 sse L, s |= φ1 e L, s |= φ2
• L, s |= φ1 ∨ φ2 sse L, s |= φ1 oppure L, s |= φ2
• L, s |= [a]φ sse per ogni a tale che sa−→ s′, s′ |= φ
20
• L, s |= 〈a〉φ sse esiste a tale che sa−→ s′ e s′ |= φ
Il potere espressivo di questa logica è limitato. Si possono esprimere proprietà di una
lunghezza �nita nell'albero delle computazioni, proprietà che garantiscono il funziona-
mento per n volte ma non per sempre. La �gura 3.4 illustra il signi�cato degli operatori
temporali.
Figura 3.4: Operatori temporali in HML
Action-based Computation Tree Logic. Come HML anche nella logica ACTL il dominio di
interpretazione è il LTS. Gli operatori temporali sono gli stessi con quelli de�niti in CTL,
solo che in ACTL le proprietà da veri�care riguardano le azioni che de�niscono il sistema.
La sintassi delle formule è de�nita nel modo seguente:
Formule di azioni: χ ::= true | false | a ∈ Act | ¬χ | χ ∨ χ | χ ∧ χ
Formule di stato: φ ::= true | false | φ1 ∨ φ2 | φ1 ∧ φ2 | Aϕ | Eϕ
Formule di cammino: ϕ ::= Xχ(φ) | φ1χUφ2 | φ1χUχ′φ2
La logica mantiene la struttura della logica de�nita in [5]. Comunque non è di�cile
de�nire gli operatori temporali G ed F da quelli presenti. Valgono le equivalenze:
• Fχφ = true{true}Uχφ
• Gχφ = ¬Fχ¬φ
21
La relazione |= per le formule di azione è de�nita come segue:
• a |= b se e solo se a = b;
• a |= χ se e solo se a 6|= χ;
• a |= χ ∧ χ′ se e solo se a |= χ e a |= χ′.
La semantica degli operatori ACTL si de�nisce come: sia L = (S, Act, →)
• L, s |= true sempre valido
• L, s |= φ1 ∧ φ2 sse L, s |= φ1 e L, s |= φ2
• L, π |= Xχφ sse |π| > 1 e (s0, a, s1) ∈→ e a |= χ e s1 |= φ
• L, π |= φχ U φ′ sse esiste i ≥ 1 tale che L, si |= φ′, e per ogni 1 ≤ j ≤ i−1, L, sj |= φ
e (sj, a, sj+1) ∈→ e a |= χ
• L, π |= φχ U χ′φ′ sse esiste i ≥ 2 tale che L, si |= φ′ e (si−1, a, si) ∈→ e a |= χ′, e
per ogni 1 ≤ j ≤ i− 1, L, sj |= φ e (sj−1, b, sj) ∈→ e b |= χ
3.4 Model checking
La veri�ca tramite model checking consiste, dato un sistema di transizione M modello
di un sistema e una formula di logica temporale φ, che rappresenta una proprietà che si
desidera che M abbia, nel veri�care se M soddisfa φ.
In letteratura, due sono gli approcci di model-checking maggiormente applicati per veri-
�care la validità di una formula logica; global and local model checking. Un algoritmo
globale prima costruisce l'intero spazio degli stati del sistema, successivamente algorit-
mi di ricerca e di etichettatura vengono applicati per trovare particolari stati in cui la
22
proprietà desiderata vale. Un inconveniente dell'approccio globale è la generazione anche
degli stati che non sono rilevanti per dimostrare la formula, specialmente quando lo spazio
degli stati da analizzare diventa troppo grande.
Nel modello locale (on-the-�y model checking) vengono visitati solo gli stati che sono
necessari per dimostrare il valore di verità della formula, espressa rispetto ad un determi-
nato stato iniziale. Un model checker locale può controllare solo una piccola parte della
struttura per decidere il problema, la parte che non serve non viene nemmeno costruita.
L'algoritmo seguente mostra come viene e�ettuata l'etichettatura degli stati quando si
deve veri�care una proprietà della forma E[f1 U f2] in un model checker globale.
Algoritmo: Procedura per etichettare gli stati con formule della forma EU
Input: f1, f2T := {s | f2 ∈ lable(s)};for all s ∈ T do
label(s) := label(s) ∪ { E[f1 U f2]};end for
while T 6= ∅ dochoose s ∈ T ;T := T \ {s};for all t tale che R(t, s) do
if E[f1 U f2] 6∈ label(t) e f1 ∈ label(t) thenlabel(t) := label(t) ∪ {E[f1 U f2]};T := T ∪ {t};
end if
end for
end while
In seguito viene illustrato lo pseudo codice di un algoritmo standard di model checking
locale. L'algoritmo si basa su una visita breadth-�rst oppure depth-�rst del sistema di
transizione.
23
Algoritmo: Procedura per veri�care le formule in un model checker locale
Input: F:Formula ,E:ENV, S:Stateif caso base: true, false, F = p e p ∈ AP then
return il risultatoelse
salva l'informazione che sto valutando la formula F nello stato Sfacendo riferimento all'ambiente E (per esempio, inserisci (F,E,S) in una pila)for all sub-formula F' di F, con S' lo stato successivo ad S, l'ambiente E' aggiornato in S'
do
chiama ricorsivamente (F', E', S');if il risultato di (F', E', S') è su�ciente per stabilire il risultato di (F, E, S) then
esci dal ciclo for;end if
end for
A questo punto abbiamo un risultato.Rimuovi (F, E, S) dalla pila.return il risultato
end if
L'algoritmo realizzato per generare i prodotti validi e che viene descritto in dettaglio nel
capitolo 5, è simile ad un algoritmo di model checking locale. Viene esplorato lo spazio
degli stati mantenendo informazione su quello che si è visto �no allo stato corrente. La
parte alla quale si fa più riferimento è la gestione dell'ambiente da passare al prossimo
passo nell'algoritmo.
24
Capitolo 4
Attività di ricerca
In questo capitolo si presenta il lavoro teorico realizzato dal gruppo dei metodi formali
del CNR di Pisa [1][2][16][17]. Viene descrito il framework logico creato e su come questo
è utilizzato per esprimere: a) un modello di una famiglia di prodotti e, b) variabilità sta-
tica e comportamentale. Inizialmente si introduce il Feature Modelling [9], un formalismo
ampiamente utilizato per descrivere una famiglia di prodotti. Successivamente si descrive
la logica deontica [3] e si mostrano le sue capacità di caratterizzare un Feature Model,
creando le basi per un struttura logica sulla quale esprimere proprietà delle famiglie. Con
l'introduzione anche del Modal Transition System [8], formalismo capace di descrivere
in modo naturale il comportamento di una famiglia, si ha il supporto teorico necessario
per de�nire MHML [2][16]. MHML è una logica deontica temporale branching basata su
azioni, interpretata su un MTS, per esprimere in una famiglia di prodotti concetti di varia-
bilità. In confronto con il Feature Modelling, MHML aggiunge la possibilità di speci�care
nello stesso framework anche proprietà comportamentali delle famiglie di prodotti.
25
4.1 Introduzione
Una famiglia è un insieme di prodotti che condividono una base comune di funzionalità.
Diversi modelli si ottengono estendendo il prodotto base con caratteristiche aggiuntive
per soddisfare una particolare tipologia di clienti oppure per soddisfare mercati di paesi
di�gerenti. Quindi possiamo distinguere due parti in una famiglia, la parte condivisa e la
parte estendibile. La parte estendibile viene riferita nel campo con il termine variabili-
tà, e rappresenta quei aspetti che sono usati per costruire diversi prodotti della famiglia.
La modellazione della variabilità è stata ampiamente studiata in letteratura, soprattutto
quella relativa al Feature Modelling (sezione 4.3). In questo formalismo l'interesse nella
modellazione della variabilità sta nel de�nire quali funzionalità o componenti di un siste-
ma siano opzionali oppure necessari e quali siano le relazioni tra loro. Successivamente,
tecniche e strumenti sono stati sviluppati per stabilire se un prodotto fa parte della fa-
miglia, oppure per derivare un prodotto da una famiglia selezionando le funzionalità o i
componenti che si vuole.
4.2 Esempio della macchina del ca�è
Per rendere più chiaro il contenuto di questo capitolo prendiamo un semplice esempio di
una famiglia di macchine per ca�è. Le seguenti regole caratterizzano i prodotti di questa
famiglia:
1. La macchina viene attivata da una moneta. Le monete accettate sono quella da
un euro (1e) per i prodotti del mercato europeo, e quella da un dollaro (1$) per i
prodotti del mercato statunitense.
26
2. Dopo aver inserito una moneta, l'utente deve scegliere se vuole lo zucchero o meno,
per poi continuare con la selezione della bevanda.
3. La scelta delle bevanda (ca�è, tè, cappuccino) dipende dal prodotto. Ogni macchina
deve dare la possibilità di scegliere il ca�è, inoltre la scelta del cappuccino deve essere
disponibile solo nelle macchine per il mercato europeo.
4. Dopo aver preparato il ca�è la macchina può emettere un suono. Il suono ci deve
essere dopo la preparazione del cappuccino.
5. La macchina ritorna sul suo stato iniziale non attivo dopo che l'utente ha preso la
bevanda.
I requisiti 1, 3 e parzialmente anche il 4, sono considerati come aspetti statici della fami-
glia. Non riguardano il comportamento nel tempo dei prodotti ma semplicemente quelle
funzionalità che un prodotto �nale può o non può avere. I requisiti 2 e 5 e parzialmente il
4 invece, sono vincoli su quello che deve essere il comportamento dei prodotti validi della
famiglia.
4.3 Feature Modelling
Un formalismo ampiamente utilizzato per descrivere una famiglia di prodotti è il Feature
Modelling. Nella fase del domain engineering (vedi sezione 2.2) il dominio del sistema
software viene rappresentato mediante un insieme di funzionalità (feature) e ogni prodotto
si caratterizza da una opportuna selezione di quest'ultime. Le feature sono classi�cate nel
modo seguente:
• optional feature, funzionalità opzionale, è presente solo se il padre lo è;
27
• mandatory feature, funzionalità obbligatoria, è presente se e solo se il padre lo è;
Si possono de�nire anche vincoli tra le feature:
• alternative features, un insieme di funzionalità tra le quali solo una è presente.
• a require b, se a è presente nel prodotto �nale anche b lo è;
• a exclude b, a e b non possono co-esistere nello stesso prodotto.
Una rappresentazione gra�ca di un Feature Model è il Feature Diagram; le features sono
i nodi di un albero nel quale la famiglia è la radice. Il Feature Diagram della macchina
per ca�è introdotta nel paragrafo 4.2 viene mostrato nella �gura 4.1.
Figura 4.1: Feature Diagram per la famiglia di macchine da ca�è
4.4 Logica deontica e Feature Models
La logica deontica fornisce un modo naturale per formalizzare concetti come violazione,
obbligo, permesso e divieto. Una logica deontica contiene gli operatori proposizionali logici
classici, negazione(¬), congiunzione(∧), disgiunzione(∨), implicazione(⇒) ed aggiungendo
gli operatori deontici. In questa ricerca sono considerati solo i due principali operatori
28
deontici; è obbligatorio che (O) ed è permesso che (P ). Nelle classiche versioni della logica
vale la proprietà duale:
P (α) = ¬O(¬α),
qualcosa è permessa se e solo se la sua negazione non è obbligatoria.
Una caratterizzazione deontica di un Feature Model è un insieme di formule deontiche, la
congiunzione delle quali, descrive in modo preciso la famiglia dei prodotti. La costruzione
viene de�nita nel modo seguente:
• Se A è una feature e, A1 e A2 sono due sub-feature (alternative, opzionali oppure
obbligatorie), allora aggiungi la formula:
A =⇒ Φ(A1, A2),
dove la formula Φ(A1, A2) vale:
Φ(A1, A2) = (O(A1) ∨ O(A2)) ∧ ¬(P(A1) ∧ P(A2))
se A1 e A2 sono marcati come due feature alternativi, altrimenti la formula Φ(A1,
A2) vale:
Φ(A1, A2) = φ(A1) ∧ φ(A2),
dove Ai, per i ∈ {1,2}, è de�nita come:
φ(Ai) =
P (Ai), se Ai è opzionale;
O(Ai), se Ai è obbligatorio.
• se A requires B, allora aggiungi la formula:
29
A =⇒ O(B)
• se A excludes B, allora aggiungi la formula:
(A =⇒ ¬ P(B)) ∧ (B =⇒ ¬P(A))
Applichiamo la costruzione appena de�nita all'esempio della macchina del ca�è introdotta
nel paragrafo 4.2. Le formule deontiche risultanti sono:
O(Moneta) ∧ O(Bevanda) ∧ P(Suono)
Moneta =⇒ (O(1$) ∨ O(1e)) ∧ ¬(P(1$) ∧ P(1e))
Bevanda =⇒ O(Ca�è) ∧ P(Tè) ∧ P(Cappuccino)
Cappuccino =⇒ O(Suono)
(1$ =⇒ ¬P(Cappuccino)) ∧ (Cappuccino =⇒ ¬P(1$))
Mediante la caratterizzazione con formule deontiche di un Feature Model posso stabilire
se un prodotto appartiene alla famiglia.
Prendiamo per esempio le formule de�nite qui sopra e supponiamo di avere due modelli
della macchina da ca�è:
CM1 = {Moneta, 1e, Bevanda, Ca�è}
CM2 = {Moneta, 1e, Bevanda, Ca�è, Cappuccino}
La macchina CM1 soddisfa la caratterizzazione deontica della macchina da ca�è ed è
quindi un prodotto corretto della famiglia. La CM2 non soddisfa le formule deontiche in
quanto rende falso il vincolo che dopo aver preparato il cappuccino si deve emettere un
suono. L'appartenenza (oppure la non appartenenza) si può veri�care formalmente rap-
presentando queste formule come una lista di assiomi messi in congiunzione. La formula
30
risultante sarà vera se il prodotto appartiene alla famiglia e falsa altrimenti.
Il problema di trovare un prodotto che soddisfa la caratterizzazione deontica di un Feature
Model si può rappresentare come il problema di trovare un assegnamento che rende vera
la congiunzione delle formule (SAT). Algoritmi e�cienti per SAT si possono utilizzare per
risolvere questi tipi di problemi.
Abbiamo dimostrato che la logica deontica è un formalismo che in modo naturale riesce
ad esprimere nozioni di permesso ed obbligo, fondamentali nel gestire la variabilità nello
sviluppo di Product Families. Si può notare che gli Feature Models esprimono solo gli
aspetti statici di una famiglia di prodotti. Per descrivere anche come i prodotti evolvono
nel tempo e quali caratteristiche nell'evoluzione sono obbligatorie o permesse, si deve ri-
correre ad un formalismo che riesce a descrivere queste particolarità. Uno dei formalismi
più utilizzati in questo contesto è il Labelled Transition System (vedi sez. 3.2). Con gli
LTSs però, non si ha la possibilità di distinguere tra le azioni possibili e quelle necessarie,
per questo che vengono introdotti gli Modal Transition Systems.
4.5 Modal Transition System
Il Modal Transition System (MTS) è riconosciuto come il modello formale per esprime-
re il comportamento nel tempo delle famiglie dei prodotti. Un MTS è un LTS dove le
transizioni sono di due tipi, must e may. Una transizione must indica che l'azione in
essa contenuta è obbligatoria, ovvero che ogni prodotto �nale deve avere la possibilità di
eseguire l'azione, mentre la transizione may indica che un prodotto �nale può anche non
avere tale possibilità. Questo formalismo esprime in modo naturale le transizioni che de-
vono essere disponibili in un prodotto e quelle che sono transizioni opzionali da aggiungere
al prodotto. Data una famiglia di prodotti un singolo MTS permette di de�nire:
31
• il comportamento della famiglia mediante stati ed azioni comuni a tutti gli prodotti,
transizioni must,
• la variabilità, ovvero i punti dove il comportamento rende i prodotti con�gurabili,
mediante gli transizioni may.
Modal Transition System. Un MTS è una quintupla (Q,A, q0, δ�, δ♦), e ha due relazioni di
transizione distinte: δ� ⊆ Q×A×Q è la relazione may che esprime le transizioni possibili,
δ♦ ⊆ Q×A×Q è la relazione must che stabilisce chi sono le transizioni obbligatorie. Per
de�nizione una transizione obbligatoria è anche permessa, δ� ⊆ δ♦.
L'MTS per la macchina da ca�è dell'esempio introdotto nel paragrafo 1 è visualizzato
nella �gura 4.2. Le transizioni may sono rappresentate da frecce tratteggiate mentre
quelle must da frecce solide.
Figura 4.2: MTS per la macchina da ca�è
Cammino must. Sia M un MTS, σ è una must path (da q0) in M se qiai+1−−→� qi+1, per ogni
32
i ≥ 0. L'insieme di tutti i cammini must da q0 si denota con �-path(q0). Un cammino
must si denota con σ�.
Famiglie di un MTS. SiaM = (Q, A, q0, δ♦, δ�) un MTS. L'insieme delle famiglie possibili
di M si possono rappresentare mediante gli MTSs {Mi = (Qi, A, q0, δ♦i , δ
�i ) | i ≥ 0},
dove preso Ri insieme delle transizioni trasformate da may a must, si ha δ♦i ⊆ δ♦ \ Ri e
δ�i ⊆ δ� ∪ Ri. Gli stati Qi sono un sottoinsieme di Q (Qi ⊆ Q) tale che q0 ∈ Qi, e per
ogni q ∈ Qi esiste un cammino da q0 in q con transizioni in δ♦i ∪ δ�i .
Formalmente: Mi è una sottofamiglia di M con Ri insieme di transizioni may trasformati
in must, Mi ` M , se e solo se vale qi0 ` q0, dove qi ` q, per qualche qi ∈ Qi e q ∈ Q vale
se e solo se:
• se qa−→� q′, per qualche q′ ∈ Q, allora ∃q′i ∈ Qi tale che qi
a−→�i q′i e
q′i ` q′ e,
• se qa−→♦ q′ de�nita in Ri, per qualche q′ ∈ Q, allora ∃q′i ∈ Qi tale che
qia−→�i q
′i e q
′i ` q′ e,
• se qia−→♦i q
′i de�nita in δ♦ \ Ri, per qualche q′i ∈ Qi, allora ∃q′ ∈ Q tale che
qa−→♦ q
′ e q′i ` q′.
Si può notare che quando δ♦i = ∅ le transizioni dell'MTS risultante sono tutti must. In
questo caso l'MTS è equivalente ad un LTS dove le transizioni sono tutte obbligatorie e
non si distingue tra must e may.
Nella sezione 4.4 abbiamo mostrato le capacità della logica deontica a modellare una
famiglia di prodotti, descrivendo una trasformazione da un Feature Model in una con-
giunzione di formule logiche. In questa sezione abbiamo introdotto il Modal Transition
System come formalismo che riesce ad esprimere in maniera naturale il comportamento di
33
una famiglia di prodotti. In [1] viene descritto come caratterizzare un MTS con formule
deontiche mediante la logica proposizionale deontica completa de�nita in [3]. Si rimanda
alla lettura degli articoli per approfondire il procedimento. Quello che è importante dire
è che a partire da questi studi si hanno le basi per de�nire un framework logico per espri-
mere proprietà statiche e comportamentali sulle famiglie di prodotti. Il risultato è una
nuova logica temporale con operatori modali deontici che vengono interpretati in maniera
naturale in un MTS.
4.6 MHML, logica temporale in Product Families
MHML è una logica temporale branching basata su azioni simile alla logica Henessy-Milner
con Until[5], aggiungendo anche il quanti�catore esistenziale ed universale da CTL. Il suo
dominio di interpretazione è un MTS. MHML è composta da formule di stato φ, formule
dei cammini π e formule di azioni ϕ (vedi sezione 3.3, action-based logic) de�niti su un
insieme di azioni atomiche Act ={a, b, ...}.
La sintassi della logica MHML è de�nita come segue:
State Formula: φ ::= true | ¬φ | φ ∧ φ′ | 〈a〉φ | [a]φ | Eπ | Aπ
Path Formula: π ::= φ{ϕ}U{ϕ′}φ′ | φ{ϕ}U�{ϕ′}φ′
Action Formula: ϕ := true | false | a ∈ Act | ¬ϕ | ϕ′ ∨ ϕ′′ | ϕ′ ∧ ϕ′′
Il fatto che MHML viene interpretata su un MTS fa si che le classiche modalita box e
diamond, abbiano una interpretazione deontica. Il signi�cato non formale degli operatori
di MHML è come segue:
• 〈a〉φ: esiste uno stato, raggiungibile da una transizione must(a) con a ∈ Act dove
φ è valida,
34
• [a]φ: in tutti gli stati, raggiungibili da una transizione must(a) oppure may(a) con
a ∈ Act, φ è valida,
• Eπ: esiste un camino nel quale π è valida,
• Aπ: in tutti i camini, π e valida,
• φ{ϕ} U {ϕ′}φ′: esiste uno stato nel cammino raggiungibile da una azione che sod-
disfa ϕ′ dove φ′ è valida e φ vale in tutti gli stati precedenti a questo stato nel
cammino, le azioni nel cammino soddisfano ϕ;
• φ{ϕ} U� {ϕ′}φ′: come sopra, ma in questo caso il cammino che porta allo stato in
futuro dove φ′ vale è un cammino must.
La semantica formale di MHML viene interpretata in un MTS. Sia (Q,A, q0,→�,→♦)
una MTS, sia q ∈ Q e sia σ un cammino. La relazione di soddisfacibilità di MHML è
de�nita da:
• q |= true, sempre valida
• q |= ¬φ, se e solo se 6 q |= φ
• q |= φ ∧ φ′ se e solo se q |= φ e q |= φ′
• q |= 〈a〉φ se e solo se ∃q′ ∈ Q : qa−→� q
′ e q′ |= φ
• q |= [a]φ se e solo se ∀q′ ∈ Q: q a−→♦ q′, vale q′ |= φ
• q |= Eπ se e solo se ∃σ′ ∈ path(q) : σ′ |= π
• q |= Aπ se e solo se ∀σ′ ∈ path(q) : σ′ |= π
35
• q |= φ {ϕ} U {ϕ′} φ′ se e solo se ∃j ≥ 1 : σ(j) |= φ′, σ{j} |= φ′ e σ(j + 1) |= φ′, e
∀i, 1 ≤ i ≤ j : σ(i) |= φ e σ{i} |= φ
• q |= φ {ϕ} U� {ϕ′} φ se e solo se σ è un cammino must σ� e σ� |= φ {ϕ} U {ϕ′}φ′
La regola della dualità in Henessy-Milner, la quale stabilisce che 〈a〉φ è equivalente a
¬[a]¬φ, non vale in MHML. La ¬[a]¬φ corrisponde ad una versione piu debole dell'ope-
ratore classico diamond e che viene denotata con P (a)φ: esiste uno stato, raggiungibile
da una transizione may(a) con a ∈ Act e φ valida. Formalmente, sia (Q,A, q0,→�,→♦)
un MTS, sia q ∈ Q, allora:
• q |= 〈a〉φ se e solo se ∃q′ ∈ Q : qa−→♦ q
′ e q′ |= φ.
Una esempio di una formula ben de�nita in MHML è:
[a](P(b) true ∧ (φ =⇒ 〈c〉 true)),
dopo l'esecuzione di una azione a, il sistema si trova in uno stato nel quale: 1) è permesso
eseguire l'azione b (una transizione may(b)) e, 2) quando la formula φ è valida allora
l'esecuzione di c è obligatoria(una transizione must(c)).
Altri operatori logici si possono derivare da quelli sopra de�niti: false è equivalente a
(¬ true), φ ∨ φ′ a ¬ (¬φ ∧ ¬φ′) e φ ⇒ φ′ a ¬φ ∨ φ′. Fφ è equivalente a
(true {true} U {true} φ), esiste uno stato nel futuro dove φ vale. F{ϕ} true è equi-
valente a (true {true} U {ϕ} true), esiste uno stato nel futuro raggiungibile da una
transizione che soddisfa ϕ. F� è equivalente a (true {true} U� {true} φ), esiste uno
stato nel futuro raggiungibile da un cammino must dove φ vale. AG φ è equivalente a
¬EF ¬φ, in tutti gli stati di tutti i cammini φ vale. AG� φ è equivalente a ¬ EF� ¬φ,
in tutti gli stati di tutti i cammini must, φ vale.
36
4.7 Proprietà statiche e comportamentali in MHML
MHML arricchisce la descrizione comportamentale di un MTS con ulteriori concetti di
variabilità. Questo viene realizzato aggiungendo vincoli sulle azioni che compongono
i prodotti di una famiglia. Mediante MHML si possono de�nire proprietà statiche e
comportamentali che un MTS non riesce ad esprimere.
Tornando all'esempio della macchina del ca�è i requisiti si possono formalizzare con le
seguenti formule. Per la parte statica:
• Le azioni 1e e 1$ sono alternativi (1e alternative 1$), requisito 1.
((EF� 〈1e〉 true) ∨ (EF� 〈1$〉 true)) ∧
¬ ((EF P(1e) true) ∧ (EF P(1$) true))
• Il cappuccino non deve essere disponibile in prodotti per il mercato statunitense
(cappuccino excludes 1$), seconda parte del requisito 3.
((EF P(cappuccino) true) =⇒ (AG ¬ P(1$) true)) ∧
((EF P(1$) true) =⇒ (AG ¬ P(cappuccino) true))
• Le macchine che o�rono il cappuccino devono emettere un suono (cappuccino requi-
res suono), requisito 4.
(EF P(cappuccino) true) =⇒ (EF� 〈 suono〉 true)
Il requisito 2 rappresenta un vincolo sul comportamento dei prodotti della famiglia. Un
ca�è non si può consegnare se non si è inserito la moneta prima. In MHML si può de�nire
con la formula seguente:
37
A [ true {¬ca�è} U� {1e ∨ 1$} true]
L'applicazione delle formule divide la famiglia originale in sottofamiglie. Le sottofamiglie
sono degli MTSs con le transizioni must, qualche may cambiato in must e le rimanenti
transizioni may dell'MTS iniziale (vedi de�nizione dell'MTS nella sezione 4.5). Ad esem-
pio la formula che esprime il vincolo 〈1e alternative 1$〉 crea due sottofamiglie. Nella
prima rimuovo la transizione s0dollar−−−→ s1 e modi�co l'altra transizione uscente dallo stato
s0, s0euro−−→ s1, da may a must. Si procede in modo simile anche per la seconda sottofami-
glia e si può notare che la formula esprimente il vincolo alternative addesso è valida per
entrambi i casi.
38
Capitolo 5
Generazione dei prodotti validi di una
famiglia
In questo capitolo si presenta il lavoro eseguito. Inizialmente si descrive un modello
testuale per de�nire una famiglia di prodotti. Successivamente viene introdoto l'algoritmo
per generare i prodotti validi e vengono descritte le principali procedure implementate. Il
risultato �nale è uno modulo nel linguaggio di programmazione Ada [10] [11] aggiunto al
model checker FMC [12] per includere su questo la procedura di generazione.
5.1 Il modello di una famiglia
Come abbiamo de�nito nel capitolo precedente una famiglia di prodotti è un MTS più
una serie di vincoli espressi nella logica temporale MHML. Per rappresentare un MTS è
su�ciente l'utilizzo dell'operatore di ricorsione e dell'operatore della scelta non determi-
nistica oltre ad una chiara distinzione tra i due tipi d'archi. Nella macchina del ca�è per
esempio lo stato iniziale viene modellato come:
39
T0 = may(1e).T1 + may(1$).T1
L'interpretazione è abbastanza intuitiva, nello stato T0 ho due scelte possibili che sono
permesse ma non obbligatorie. Per de�nire i vincoli invece, sono utilizzate le parole chiave
ALT, EXC e REQ che rappresentano le formule dei vincoli alternative, exclude e requires
rispettivamente. L'esempio della macchina del ca�è mediante questo formalismo si può
de�nire nel modo seguente:
Modello della macchina da ca�è
T0 = may(dollar).T1 + may(euro).T1T1 = must(sugar).T2 + must(no_sugar).T3T2 = must(co�ee).T4 + may(tea).T5 + may(cappuccino).T6T3 = may(cappuccino).T7 + may(tea).T8 + must(co�ee).T9T4 = must(pour_sugar).T9T5 = must(pour_sugar).T7T6 = must(pour_sugar).T7T7 = must(pour_co�ee).T10T8 = must(pour_tea).T11T9 = must(pour_co�ee).T11T10= must(pour_milk).T11T11= may(no_ring).T12 + may(ring_a_tone).T12T12= must(cup_taken).T0
net SYS = T0
Constraints {dollar ALT eurodollar EXC cappuccinocappuccino REQ ringatone
}
Un semplice confronto con FMC penso che sia necessario. L'MTS che descrive il compor-
tamento della famiglia si può de�nire mediante un'algebra di processi sequenziali in un
formalismo CCS-like, quest'ultima è anche la sintassi utilizzata per descrivere i modelli
in FMC. Il processo a.P esegue l'azione a per poi comportarsi come il processo P. Nello
40
stesso modo un prodotto dell'MTS può eseguire l'azione euro nello stato T0 per spostarsi
successivamente nello stato T1 e comportarsi come se T1 fosse lo stato iniziale. Si può
notare anche la sintassi utilizzata per distinguere le azioni must da azioni may, costrutti
che in FMC si de�niscono come "typed actions".
5.2 Algoritmo per generare i prodotti validi
Inizio questo paragrafo con una osservazione. Per implementare l'algoritmo si possono
seguire due approcci di base, quello globale oppure quello locale. Nell'approccio globale
inizialmente vengono generate tutte le famiglie dell'MTS e successivamente veri�cata la
validità delle formule che rappresentano i vincoli. Da notare che questo modello introduce
ridondanza, nel senso che sottofamiglie oppure prodotti vengono valutati molte volte
perchè presenti in una sottofamiglia già valutata. Nell'approccio locale invece, ogni volta
che aggiungo un arco veri�co le formule. Risulta più e�ciente in una situazione dove la
famiglia si presenta con un numero abbastanza grande di archi may e vincoli tra loro.
Questo perchè posso tagliare interi sottoalberi a causa della non soddisfazione di qualche
vincolo. Nell'approccio locale però, tenere gli archimay in prodotti intermedi è complicato
come sarà descritto nella sezione 5.6. In quanto siamo interessati alla generazione dei
prodotti �nali penso che la scelta ottimale sia quella di generare i prodotti �nali di un
MTS seguendo l'approccio locale.
In questa sezione viene descritto un algoritmo per generare i prodotti validi di una famiglia.
Un prodotto valido �nale è un LTS dove gli archi sono tutti obbligatori e non esiste la
distinzione fatta per MTS nel quale gli archi sono di due tipi, archi possibili e archi
obbligatori. L'algoritmo parte dall'MTS che modella la famiglia e dall'insieme di formule
espresse in MHML. Il risultato è un sottoinsieme dei prodotti possibili di un MTS (vedi
41
de�nizione delle famiglie di un MTS, sezione 4.5); un elemento di questo sottoinsieme è
un LTS con tutte le azioni presenti in una transizione must, qualche azione presente nelle
transizioni may e che rispetta i vincoli espressi in MHML.
L'idea dell'algoritmo è di costruire LTSs intermedi che sono i prodotti dell'MTS seguendo
la logica sopra descritta e che sono composti dalle azioni e dagli stati �no ad uno particolare
stato della famiglia. Prendiamo l'esempio dell'MTS della macchina per ca�è mostrato in
�gura 5.1, dallo stato iniziale ho 4 possibili LTSs intermedi:
Figura 5.1: Passo dell'algoritmo
Un passo generale dell'algoritmo viene de�nito come: aggiungi ad un LTS intermedio un
arco dell'MTS iniziale e veri�ca le formule che esprimono i vincoli alternative ed exclude,
continuando solo con gli LTSs che soddisfano le formule. Quando non è più possibile
eseguire altri passi perchè abbiamo analizzato tutti gli stati e tutti gli archi dell'MTS,
esegui la veri�ca �nale delle formule dei vincoli alternative (vedi in seguito) e requires.
La veri�ca �nale della formula del vincolo alternative è necessaria in quanto l'algoritmo
in un passo intermedio veri�ca semplicemente che nell'LTS non siano presenti entrambi
gli operandi della formula ma non che almeno uno di questi sia presente. In questo senso
è necessario eseguire la veri�ca �nale in modo da selezionare quei prodotti �nali dove
almeno uno dei operandi ci sia. Consideriamo la proprietà: 1e e 1$ sono alternativi.
L'algoritmo prende uno ad uno le situazioni illustrate nella �gura 5.1. Per ognuna di
queste veri�ca la validità della formula che esprime il vincolo alternative:
(EF 〈1$〉 true ∨ EF 〈1e〉 true) ∧ ¬(EF P(1$) true ∧ EF P(1e) true)
42
Qui si deve fare una precisazione. Le formule sono interpretate su un MTS e quindi il
procedimento sopra introdotto è sensato se diciamo che un prodotto valido, ovvero l'LTS,
in realtà è un MTS dove le transizioni sono tutte must. Se si considera l'LTS come dominio
dell'interpretazione delle formule allora si deve utilizzare una logica simile a MHML ma
senza l'interpretazione deontica degli operatori box e diamond. La formula si trasforma
in:
(EF 〈1$〉 true ∨ EF 〈1e〉 true) ∧ ¬(EF 〈1$〉 true ∧ EF 〈1e〉 true)
All'inizio di questo lavoro si pensava ad un algoritmo che poteva generare anche le sotto-
famiglie valide, ma questo è complicato come sarà descritto in dettaglio nella sezione 5.6.
Quindi per esprimere i vincoli è su�ciente una logica simile ad MHML ma senza l'inter-
pretazione deontica degli operatori box e diamond, osservazione presa in considerazione
anche in [6].
Ritornando all'esempio, per ognuno degli LTSs intermedi si può dire che l'algoritmo con-
tinuerà a procedere in avanti solo nei casi (ii) ed (iii). In questo modo si garantisce che
negli LTSs �nali almeno una delle due azioni in relazione è presente.
Riassumendo, il problema si può speci�care come: data una MTS M ed un insieme Φ di
vincoli sulle azioni, espressi mediante formule φi in MHML per i ≥ 0, derivare un insieme
P di LTSs Lj, per qualche j ≥ 0, tale che per ogni t ≥ 0 e t ≤ j, Pt ` M e Pt |= φi per
ogni i ≥ 0.
Passo di generazione. Un passo di generazione generate(M,p,L,q) si applica ad uno stato
p dell'MTS M e ad uno stato q di un LTS L intermedio. In particolare, q è una foglia
non visitata prima (non ci sono archi in uscita). I possibili e�etti dell'applicazione di un
passo generate(M,p,L,q) sono:
43
• si aggiunge uno stato q' ed un arco qa−→ q' all'LTS L in corrispondenza ad uno stato
p' e ad un arco pa−→ p' dell'MTS M,
• come sopra ma si aggiunge solo l'arco in quanto lo stato q' dell'LTS L risulta visitato
in un passo precedente,
• si crea una copia L' di L se q contiene archi may in uscita, esegue i passi 1) e/o 2)
ed aggiunge L' nell'insieme degli LTSs intermedi,
• si marca q come visitato a causa della applicazione di una delle prime due regole
qui sopra,
• si aggiorna l'insieme D dei passi di generazione di L che l'algoritmo deve eseguire
successivamente, da notare che ogni LTS intermedio ha il suo insieme D di passi di
generazione.
Prima di introdurre l'algoritmo faccio due considerazioni. La prima riguarda gli archi mu-
st e may. Per semplicità, quando si parla di un arco may non sono inclusi gli archi must,
diversamente da come abbiamo de�nito l'MTS nella sezione 4.5. La seconda riguarda le
formule. L'inisieme Φ contiene le formule dei vincoli exlude ed alternative mentre ΦREQ
contiene solo la formula del vincolo requires.
Algoritmo di generazione. L'algoritmo inizia con la MTS M, l'insieme delle formule Φ
ed un ambiente di lavoro P = {L}. L'insieme dei passi di generazione D di L inizialmente
contiene solo generate(M, q0, L, q0) e L solo lo stato iniziale q0 di M. L'algoritmo esegue
un passo di generazione da un qualche D, �no a quando tutti gli D non sono vuoti.
Un passo di generazione generate(M, p, L, q) è de�nito nel modo seguente:
1. Per ogni arco must(a), pa−→� p
′, in M :
44
(a) se p = p', aggiungi l'arco qa−→ q a L,
(b) se lo stato p′ è stato visitato in qualche passo di generazione generate(M,p',L,q')
oppure è stato aggiunto nel passo corrente da un arco pb−→ p′, allora aggiungi
l'arco qa−→ q′ a L;
(c) altrimenti aggiungi uno stato q' e una nuovo arco qa−→ q′ a L, e aggiungi il
passo di generazione generate(M,p',L,q') a D ;
(d) in�ne, marca q come visitato e per ogni formula φ ∈ Φ \ ΦREQ dove l'azione a
occorre, veri�ca se L |= φ. Se L 6|= φ, rimuovi L dall'ambiente di lavoro P ;
2. Per tutti gli archi may(a1) ... may(an), pa1−→♦ p1 ... p
an−→♦ pn, in M, il passo 1) deve
essere ripetuto per ogni combinazione degli archi, ovvero per ogni Act ⊆ a1...an:
(a) aggiungi una copia LAct di L nell'ambiente di lavoro P,
(b) per ogni arco may pa−→♦ pj in M dove 1 ≤ j ≤ n e tale che aj ∈ Act:
• se pj = p, aggiungi un arco qaj−→ q in LAct:
• se pj risulta visitato in un passo di generazione generate(M,pj,L,q') prece-
dente oppure nel gestire un arco della forma pb−→♦ pj oppure p
b−→� pj nel
passo di generazione corrente, allora aggiungi un arco qa−→ q′ a LAct:
• altrimenti, aggiungi uno nuovo stato q′ ed un arco qaj−→ q′ a LAct ed
aggiungi il passo generate(M, pj, LAct, q′) all'insieme D di LAct
(c) marca q come visitato e per ogni formula φ ∈ Φ\ΦREQ dove occorre un azione
che sta in Act, veri�ca se L |= φ. Se L 6|= φ, rimuovi L dall'ambiente di lavoro
P ;
Quando non sarà più possibile eseguire un passo di generazione perché nessuna delle liste
D di qualche L che sta in P ne contiene, l'algoritmo veri�ca se per ogni prodotto LTS
45
in P valgono le formule esprimenti i vincoli requires e alternative. Ovvero, ∀ L in P e
φ ∈ ΦREQ ∪ ALT veri�ca se L |= φ. Se per qualche L ∈ P la formula φ non vale, L 6|= φ,
allora L viene rimosso dall'ambiente di lavoro P. Quando l'algoritmo termina P contiene
un insieme di LTSs che rappresentano i prodotti validi della famiglia.
5.3 Implementazione
Il modulo per generare i prodotti validi viene aggiunto al model checker FMC ed è imple-
mentato nel linguaggio di programmazione Ada.
Ada è un linguaggio di programmazione general-purpose e unisce in un'unica soluzione
principi e tecniche provenienti da diversi paradigmi di programmazione, in particolare
programmazione modulare, programmazione orientata agli oggetti, programmazione con-
corrente e programmazione distribuita. Un programma in Ada è composto da unità di
programmazione. Un'unità può essere:
• un sottoprogramma, nella forma di una funzione oppure di una procedura;
• un package, i sottoprogrammi e tipi di dato che hanno una relazione logica tra loro
possono essere raggruppati in un package;
• un task, attività che può essere realizzata in concorrenza con altre, simile ad un
package, a di�erenza dei package viene speci�cato il comportamento in relazione
con gli altri task ;
• un'unità generica, forma parametrica di package o di programma.
Un programma Ada completo è concepito come una procedura con un nome appropriato,
costituente essa stessa un'unità di programma e che richiama funzionalità rese disponibili
46
da altre unità di programma. Le unità utilizzate possono essere dei sottoprogrammi ma
è piu probabile che siano pacchetti applicativi (packages). Un pacchetto applicativo è co-
stituito da un gruppo di argomenti correlati che possono rappresentare sia altri pacchetti
sia dei sottoprogrammi. Ogni pacchetto applicativo si compone di due parti, l'interfaccia
e l'implementazione. L'interfaccia de�nisce la parte di speci�ca, contiene l'informazione
su quali sono le funzionalità e i tipi di dato visibili ad altre unità, ha l'estensione .ads.
L'implementazione (il body) è la parte che realizza l'interfaccia e di solito non è visibile
ad altre unità; ha l'estensione .adb.
In questo paragrafo sono descritte le unità create e il loro ruolo nella realizzazione dell'al-
goritmo introdotto nel paragrafo precedente. Il codice è organizzato nelle seguenti unità
di programmazione Ada:
• ProductFamily_Types.ads, la speci�ca dei tipi, strutture dati, funzioni e procedure;
de�nisce l'interfaccia dei sottoprogrammi utilizzati nell'algoritmo di generazione.
• ProductFamily_Types.adb, implementazione della speci�ca, realizzazione delle pro-
cedure e delle funzioni. Riorganizza i sottoprogrammi correlati ragruppandoli in tre
nuovi paccheti, ProductFamily_FormulaVerify, ProdutFamily_Con�gurations, Pro-
dutFamily_Derivations e ProdutFamily_Combinations. Dichiara la struttura dei
nuovi pacchetti e, mediante la parola chiave separate, indica che l'implementazione
della unità si trova nel �le con il rispettivo nome e l'estensione .adb;
• ProdutFamily_FormulaVerify.adb l'implementazione del pacchetto ProdutFamily_-
FormulaVerify de�nito nel modulo ProductFamily_Types.adb, realizza le procedure
per veri�care negli LTSs intermedi la validità delle formule esprimenti i vincoli.
Osservazione. Per eseguire le veri�che si poteva procedere in due modi. Nel primo
si interfacciava il codice dell'algoritmo di generazione con quello del model checker
47
FMC. FMC è organizzato in due pacchetti principali, nel primo sono de�nite le
strutture dati che contengono il modello (l'MTS nel nostro caso) e nel secondo le
procedure per veri�care la validità delle formule. Quindi, in riferimento ai punti
1.d), 2.c) e veri�ca �nale dell'algoritmo, si poteva caricare il modello e veri�care le
formule chiamando procedure del codice di FMC. Questa scelta è molto dipendente
dal codice di FMC e in più, analizzando la struttura delle formule che rappresentano
i vincoli si può capire che la veri�ca si può realizzare in modo alternativo, semplice-
mente tenendo un array delle azioni presenti nelle transizioni che compongono l'LTS
intermedio. Quando all'LTS si aggiunge una transizione in riferimento ai punti 1.a),
1.b), 1.c) e 2.b), basta controllare se l'azione in essa contenuta compare in qualche
vincolo, e se questo è vero, controllare che l'altra azione nella relazione vincolante sia
(o non sia) presente nell'array. Abbiamo scelto la seconda modalità. Il pseudocodice
introdotto più avanti in questa sezione da una descrizione dettagliata dell'approccio
seguito.
• ProdutFamily_Con�gurations.adb, realizza le procedure necessarie per esplorare gli
stati e le transizioni del modello della famiglia di prodotti descritta mediante un
MTS;
• ProductFamily_Derivations.adb, realizza le procedure per gestire i passi di genera-
zione;
• ProductFamily_Combinations.adb, realizza le procedure per creare le combinazioni
delle azioni che compaiono in transizioni may come descritto nel passo 2 dell'algo-
ritmo di generazione;
48
• ProductFamily.adb, il main dell'algoritmo di generazione. Questo modulo mette
assieme tutte le procedure de�nite nei moduli descritti qui sopra.
Continuo questo capitolo cercando di descrivere in linea di massima le strutture dati e le
procedure principali, facendo riferimento all'algoritmo del paragrafo precedente per ren-
dere più chiaro il signi�cato del codice.
ProductFamily_Types.ads. È il pacchetto dove sono de�niti i tipi di dato, le funzioni
e le procedure necessarie per implementare l'algoritmo. I tipi di dato piu signi�cativi
sono quelli che rappresentano il passo di generazione e l'LTS intermedio.
Tipo di dato: Il tipo generatetype generate is record
state: PositivetempLTS : Positive
end record
Il record generate a di�erenza del passo "generate" de�nito nell'algoritmo del paragrafo
precedente, contiene solo lo stato q e l'LTS intermedio. L'MTS M e lo stato p dell'MTS
non servono. Questo perchè M è la stessa per tutta l'esecuzione dell'algoritmo e gli stati
p e q rappresentano lo stesso stato sia nel modello M che nell'LTS intermedio. Nella
descrizione del paragrafo precedente sono introdotte per rendere più chiaro l'approccio
seguito.
Il seguente codice presenta il tipo che modella un LTS:
49
Tipo di dato: Il tipo LTStype LTS is record
valid_product:is_valid_product := VALIDseen_Table: Bool_Array_Refgenerate_list: Generate_Container.Vectorlts_actions : array_of_actions_reflts_labels: String_Container.Vector
end record
Il campo valid_product stabilisce se l'LTS intermedio è un prodotto valido oppure no. La
rimozione di un LTS non valido dall'ambiente P, in riferimento ai passi 1.d), 1.c) e veri�-
ca �nale, viene eseguita cambiando il valore di questo campo in "NON_VALID". Dopo
la terminazione dell'esecuzione dell'algoritmo si possono consultare anche i prodotti non
validi e quali transizioni hanno causato la loro non validità. Il campo seen_table tiene
informazione su quali stati sono visitati. Si riferiscono ai passi 1.d) e 2.c) dell'algoritmo
di generazione. Il campo generate_list contiene i passi di generazione che devono ancora
essere eseguiti dall'algoritmo; lts_actions contiene le azioni dell'LTS intermedio nella for-
ma target, source, label ; in questo modo si può costruire il modello che rappresenta l'LTS.
In�ne, lts_labels contiene le etichette delle azioni presenti in questo LTS. Quest'ultime
servono per veri�care la validità delle formule.
Un altro compito importante di questo pacchetto è realizzare la connessione con il codice
di FMC. Per utilizzare le funzionalità delle unità di programma di FMC si inserisce la
riga:
package MyCon�gurations is new Con�gurations
il signi�cato del quale è che le funzionalità sotto il pacchetto Con�gurations di FMC so-
no disponibili nell'unita di programma che realizza l'algoritmo di generazione. Si tratta
principalmente di tipi, strutture dati e funzioni per recuperare e contenere il modello della
famiglia di prodotti espressa in MTS.
50
ProductFamily_Con�gurations.adb. Realizza una procedura, la BreadthFirstExplore, per
esplorare gli stati e le transizioni del modello MTS. Come descritto sopra posso utilizzare
le funzionalità rese disponibili dal pacchetto Con�gurations di FMC. In particolare, una
struttura dati che contiene il modello MTS della famiglia di prodotti. Analizzando questa
struttura dati posso recuperare gli stati e le transizioni e inserirli in un array più semplice
Transitions che contiene le transizioni, dove ogni transizione è un record con tre campi;
source, target e label. Il codice della procedura dipende da strutture dati e funzionalità
disponibili nel pacchetto Con�gurations, per questo motivo non viene mostrato.
ProductFamily_Derivations.adb. Ogni LTS intermedio contiene una lista di passi di ge-
nerazione. Gli LTSs intermedi sono inseriti nell'array lts_list de�nito nell'unità Product-
Family.adb. A causa della veri�ca del passo 2.a) la lista aumenta di un LTS intermedio.
L'algoritmo in questo caso continua con il recupero dei passi "generate" dell'LTS corren-
te. Mediante questo ragionamento la procedura Get_Next_Derive() restituisce il passo
successivo da elaborare.
51
Algoritmo: Recupero delle generateInput: lts_listOutput: has_next_generate, generate1: exit := false2: while not exit do3: if lts_list(lts_index).derives is Empty then
4: lts_index := lts_index + 15: else
6: generate := lts_list(lts_index).generates.FirstElement7: remove lts_list(lts_index).generates.FirstElement from generates8: exit := true9: has_next_generate := true
10: end if
11: if lts_list.length < lts_index then
12: exit := true13: has_next_generate := false14: end if
15: end while
ProductFamily_FormulaVerify.adb. Il tipo di dato LTS contiene il campo lts_label. Que-
sto campo è un array di etichette che speci�cano quali sono le azioni che compongono
l'LTS intermedio. In questo modo si ha tutta l'informazione necessaria per veri�care la
validità delle formule. Le procedure de�nite in questo pacchetto fanno riferimento ai pun-
ti 1.d), 2.c) e alla veri�ca �nale delle formule esprimenti i vincoli requires e alternative
nell'algoritmo di generazione. Le tre procedure per la veri�ca delle formule sono descritte
in seguito.
1) Il signi�cato intodotto dalle formule dei vincoli alternative ed exclude è lo stesso con
l'unica di�erenza che uno dei due operandi in alternative deve essere presente nel prodot-
to �nale. La procedura descritta in seguito realizza la veri�ca della formula del vincolo
exclude e della prima parte della formula del vincolo alternative (nel senso che sarà riva-
lutato nella parte �nale dell'algoritmo). La procedura prende in input l'azione che è stata
aggiunta a causa di uno dei passi 1.b) e 1.c) e le etichette dell'LTS in esame. Per i casi 2.b)
52
e 2.d) l'algoritmo è un po piu complicato perché in questi casi le azioni da aggiungere sono
più di uno. Siccome la base è la stessa per tutti e due le situazioni descrivo la struttura
solo per i casi 1.b) e 1.c) che è la seguente:
Algoritmo: Veri�ca del vincolo exclude e (parziale) di alternativeInput: current_action, current_lts_labelsOutput: true, false1: for i in Constraints do2: if Constraints(i) is ALT or EXC then
3: if una delle azioni in Constraints(i) è uguale alla current_action then
4: veri�ca che current_lts_label non contenga l'altra azione nella relazionevincolante
5: return false se esiste6: end if
7: end if
8: end for
9: return true
2) Veri�ca �nale della formula del vincolo alternative. Una delle due azioni che la formula
mette in relazione deve essere presente nel prodotto �nale.
Algoritmo: Veri�ca della del vincolo alternative per i prodotti �naliInput: current_lts_labelsOutput: true, false1: for i in Constraints do2: if Constraints(i) is ALT then
3: for j in lts_labels do4: if una delle azioni in Constraints(i) è uguale alla lts_labels(j) then5: return true
6: end if
7: end for
8: end if
9: end for
10: return false
3) Veri�ca della formula del vincolo requires. L'algoritmo veri�ca che il primo operando
della formula è presente nella lts_labels e solo quando questo è vero, veri�ca la presenza
nella lts_labels del secondo operando.
53
Algoritmo: Veri�ca del vincolo requires per i prodotti �naliInput: current_lts_labelsOutput: true, false1: for i in Constraints do2: if Constraints(i) is REQ then
3: for j in lts_labels do4: if la prima azione nella relazione vincolante Constraints(i) è uguale alla
lts_labels(j) then5: for k in lts_labels do6: if la seconda azione nella relazione vincolante Constraints(i) è uguale all
lts_labels(k) then7: return true;8: end if
9: end for
10: end if
11: end for
12: end if
13: end for
14: return false
ProductFamily_Combinations.adb. In questo pacchetto sono de�nite le procedure ne-
cessarie per generare l'insieme delle parti di un insieme di etichette. Questo modulo si
riferisce al punto 2 dell'algoritmo di generazione. Nel punto 2 si richiede di generare le
combinazioni delle azioni che compaiono in transizioni may uscenti dallo stato in esame
(si ricordi generate(L,q)) e di veri�care che i nuovi LTSs intermedi, ai quali si aggiungono
queste azioni sono nelle condizioni di diventare prodotti validi. Questo modulo ha due
procedure; la InitializeCombinations(may_actions) e la Get_Next_Comb().
La prima crea l'insieme delle parti a partire da una lista di azioni. È un procedimento
iterativo sulla lista delle azioni dove per ogni azione viene creata una lista di insiemi a
partire da insiemi creati nei passi precedenti ed aggiungendo l'azione corrente. La �gu-
ra 5.2 illustra il risultato dell'applicazione della procedura ad un insieme di 3 elementi.
Get_Next_Comb(), restituisce il prossimo insieme considerando la struttura degli array
mostrata nella �gura 5.2.
54
Figura 5.2: Generazione delle combinazioni.
ProductFamily.adb. Questo è il modulo principale dell'algoritmo di generazione. Contiene
la logica dell'algoritmo presentato nel paragrafo precedente. Il pseudocodice dell'algoritmo
è il seguente:
Algoritmo: Algoritmo per generare i prodotti validi di una famigliaInput: Modello testuale della famiglia di prodotti.Output: Insieme di LTSs che rappresentano prodotti validi.1: LoadModel; . carica il modello2: BreadthFirstExplore; . esplora la MTS e crea l'array delle azioni3: while has_next_generate do4: get_next_generate(has_next_generate, current_generate)5: get_out_actions(current_generate.state); . le transizioni in uscita dallo stato nella
generate corrente6: for i in out_actions do7: if out_actions(i) è una must action then
8: isVeri�ed := Verify_Formula(out_actions(i), cur-rent_generate.tempLTS).actions)
9: if not isVeri�ed then
10: Delete_LTS(lts_list , current_generate.tempLTS)11: else
12: lts_list(current_generate.tempLTS).lts_labels.Append(out_actions(i).label);13: lts_list(current_generate.tempLTS).lts_actions.Append(out_actions(i));14: end if
15: else . out_actions(i) è una transizione may16: may_actions.Append(out_actions(i))17: end if
18: end for
55
Algoritmo: Algoritmo per generare i prodotti validi di una famiglia (continua)
19:
20: Initialize_Combinations(may_actions)21: while has_next_comb do
22: get_next_comb(current_combination_actions,has_next_comb)23: isVeri�ed := Verify_Formula(current_combinations_actions,24: lts_list(current_generate.tempLTS).lts_actions);25: if not isVeri�ed then
26: Delete_LTS(lts_list , current_generate.tempLTS)27: else . crea una coppia della LTS e aggiuingi le nuove azioni28: create new_lts;29: crea una coppia lts_list(current_generate.tempLTS) in new_lts;30: lts_list(current_generate.tempLTS).lts_actions.Append(may_actions(i));31: lts_list(current_generate.tempLTS).lts_labels.Append(may_actions(i).label);32: agggiungi new_lts in lts_list;33: end if
34: end while
35: end while
36: . Veri�ca �nale delle formule REQ e ALT(parziale)37: for i in lts_list do38: if not Verify_ALT_Formula(lts_list(I).lts_labels) then39: Delete_LTS(lts_list(I));40: end if ;41: if not Verify_REQ_Formula(lts_list(I).lts_labels) then42: Delete_LTS(lts_list(I));43: end if ;44: end for
Il codice descritto ha prodotto un �le eseguibile che introduco solo a scopo illustrativo
in quanto la procedura di generazione è più signi�cativa se si mette in relazione con le
capacità di FMC di veri�care proprietà espressse in formule logiche (vedi capitolo 6).
Prendiamo il modello testuale della macchina da ca�è del paragrafo 5.2 ed eseguiamo
l'algoritmo.
> ProductFamily m_ca�e.txt
56
Nella directory corrente vengono create due cartelle. La prima ha il nome "ValidProducts"
e contiene i prodotti validi della famiglia, mentre la cartella "NonValidProducts" contiene
i prodotti non validi e le azioni che hanno causato la non validità.
5.4 Prodotti validi della macchina per ca�è
Le �gure 5.3 e 5.4 mostrano due modelli di macchina per ca�è, risultanti dall'esecuzione
dell'algoritmo di generazione sull'esempio introdotto nel paragrafo 2 di questo capitolo.
Figura 5.3: LTS della macchina da ca�è per il mercato europeo
5.5 Validità di una sottofamiglia oppure di un prodotto
Stabilire se un prodotto oppure una sottofamiglia fa parte della famiglia originale può
essere una operazione molto utile in Product Family Engineering. Una sottofamiglia
oppure un prodotto è un MTS dove ho cambiato alcune transizioni dell'MTS della famiglia
57
Figura 5.4: LTS della macchina da ca�è per il mercato statunitense
iniziale da may a must e ho selezionate qualche may (vedi la de�nizione delle famiglie
di un MTS, sezione 4.5). Successivamente viene applicato l'algoritmo di generazione e
analizzata la lista dei prodotti validi risultanti. Se la lista è vuota signi�ca che il prodotto
oppure la sottofamiglia non è corretta rispetto ai vincoli espressi nella logica MHML.
5.6 Osservazioni
L'algoritmo viene realizzato in un modello on-the-�y, nel senso che non sono costruiti
esplicitamente tutti gli LTSs possibili dell'MTS per poi veri�care le formule, ma ogni
volta che una azione viene aggiunta all'LTS intermedio si procede con la veri�ca delle
formule. Se una delle formule non vale allora l'LTS viene rimosso dall'ambiente di lavoro
P e non può diventare un prodotto valido della famiglia.
La complessità nel tempo dipende dai passi di generazione. In totale, in un modello senza
vincoli sulle azioni, il numero totale dei passi generate è
58
archi(must) × 2archi(may)
Se dobbiamo aggiungere anche i vincoli allora la complessità nel tempo dell'algoritmo è
O(archi(must) × 2archi(may) × k)
dove k rappresenta il tempo necessario per veri�care la validità delle formule (sezione 5.3,
ProductFamily_FormulaVerify). Comunque, in un modello con un numero abbastanza
grande di vincoli tale limite è decisamente più contenuto.
Si poteva fare meglio? Diversi tentativi sono stati e�ettuati per cercare di ottimizare la
complessità in tempo dell'algoritmo. Abbiamo cercato di realizzare un algoritmo dove i
prodotti intermedi non erano LTS ma MTS, mantenendo archimay nei prodotti intermedi.
In questo modo non si doveva generare tutto lo spazio degli LTS di un ramo dell'MTS
originale, quando nessuna delle transizioni del sottoalbero era inclusa in qualche relazione
vincolante. Così si poteva ridurre la complessità mantenendo sottofamiglie invece di
singoli prodotti. In un secondo passo a partire dalle sottofamiglie si potevano derivare i
prodotti �nali.
Comunque, questa operazione non era possibile a causa delle formule che esprimono i
vincoli alternative e requires. La formula del vincolo alternative mi dice che una delle due
azioni in relazione deve essere per forza nel prodotto �nale. Se un'azione in alternative
compare nel sottoalbero di una qualche transizione may allora devo cambiare tutto il
percorso �no alla radice in un cammino must per essere sicuro che l'azione sarà presente
in tutti gli prodotti �nali. La �gura 5.5 mostra la impossibilità di mantenere archi may
in prodotti intermedi. Si può notare come non tutti i prodotti dell'MTS in 5.5(ii) sono
validi rispetto al vincolo 〈a alternative b〉.
59
Figura 5.5: a alternative b, perché non posso tener i prodotti intermedi in MTS
La stessa situazione si presenta anche per azioni presenti in una formula del vincolo
requires.
60
Capitolo 6
Interfaccia Web
In questo capitolo si presenta una semplice interfaccia web per utilizzare le funzionalità
dell'ambiente realizzato. Le operazioni disponibili sono: 1) descrivere il modello di una
famiglia di prodotti mediante la sintassi de�nita nella sezione 5.1, 2) la possibilità di
generare i prodotti validi come descritto nelle sezioni 5.2 e 5.3, 3) veri�care formalmente
proprietà sul modello della famiglia e sui singoli prodotti.
Abbiamo chiamato questo ambiente VMC, Variabilty Model Checker [6].
6.1 De�nire il modello della famiglia
La pagina web si trova sull'indirizzo:
http://fmtlab.isti.cnr.it/vmc/V5.0/vmc.html.
La prima pagina che viene visualizzata è la pagina della �gura 6.1. Nella parte a sinistra ci
sono i comandi che si possono eseguire. Inizialmente è disponibile solo il comando Model
De�nition...; selezionandolo il contenuto della pagina cambia, addesso è possibile sceglie-
re un esempio prede�nito oppure di creare un modello nuovo come illustrato nella �gura
61
Figura 6.1: VMC, pagina iniziale
6.2. Prendiamo l'esempio della macchina da ca�è che sta sotto il nome deontic.ccs. La
Figura 6.2: VMC, scegliere il modello
desrizione testuale del modello viene visualizzata sull'editor di testo nella parte centrale
della �nestra, �gura 6.3. Cliccando sul comando Load Current Model viene caricato il mo-
dello testuale della macchina da ca�è, �gura 6.4. Nella parte a sinistra sono visualizzati i
62
Figura 6.3: VMC, descivere il modello
nuovi comandi che si possono eseguire sul modello, mentre la parte centrale visualizza le
possibili evoluzioni del sistema a partire dallo stato iniziale.
Figura 6.4: VMC, modello caricato
In seguito viene descritto il signi�cato dei comandi disponibili dopo che il modello è stato
caricato. Il comando New Model... riporta la pagina nella situazione iniziale, descritta
63
dalla �gura 6.2, il comando Edit Current Model alla situazione della �gura 6.3 ed il coman-
do Explore the MTS riporta la pagina nella situazione attuale, visualizzando le possibili
evoluzioni dallo stato iniziale. Con il comando Generate All Products si possono genera-
re i prodotti validi della famiglia. Cliccando su questo comando il contenuto dell'editor
di testo nella parte centrale della pagina cambia. Vengono listati i prodotti validi della
famiglia, vedi �gura 6.5. Si può notare che il nome del prodotto è un link ad un'altra
Figura 6.5: VMC, lista prodotti validi della famiglia
pagina. I prodotti a questo punto sono degli LTSs sui quali si possono eseguire veri�che
utilizzando la versione base di FMC. Cliccando su uno dei link una nuova pagina si apre
come mostrato nella �gura 6.6. La struttura della pagina è simile a quella descritta per
VMC.
Un altra operazione utile è la visualizzazione della MTS mediante archi e nodi. Questo
è possibile mediante il comando View Family MTS. Cliccando su questo comando nella
parte centrale della pagina viene visualizzata la famiglia gra�camente, gli archi must sono
frecce non tratteggiate e gli archi may sono frecce tratteggiate.
64
Figura 6.6: VMC, LTS di un prodotto
Figura 6.7: VMC, MTS della famiglia
65
6.2 Veri�ca di proprietà con VMC
VMC è un ambiente dove si può descrivere testualmente una famiglia di prodotti e succes-
sivamente si possono veri�care proprietà espresse in una logica temporale. Fa parte di una
serie di model checker sviluppati preso ISTI-CNR e che comprendono anche FMC, UMC
e CMC [13]. Le proprietà da veri�care vengono espresse in formule scritte nella logica
SocL [7], una logica temporale branching basata su stati e azioni. VMC è una derivazione
di FMC. Prima di continuare con la descrizione dell'interfaccia web vorrei introdurre le
modalità con le quali si può passare da SocL a MHML, quest'ultima logica di VMC.
da MHML a SocL
1: in MHML in SocL2: 〈a〉 φ [must(a)] φ3: [a] φ [must(a) ∨ may(a)] φ4: P(a) φ 〈must(a) ∨ may(a)〉 φ5: E [φ{a} U� {b} φ′] E [ φ {must(a)} U {must(b)} φ′]6: E [φ{a} U {b} φ′] E [ φ {must(a) ∨ may(a)} U {must(b) ∨ may(b)} φ′]
Da notare che le formule sono veri�cate nella famiglia e non sui singoli prodotti. Le
formule logiche che esprimono proprietà sui singoli prodotti non distinguono tra archi
may e archi must, e quindi non contengono informazioni su quest'ultime. Continuiamo
questo paragrafo con la descrizione dell'interfaccia. Dopo aver caricato il modello, nella
parte in basso della pagina viene visualizzato un editor di testo dove si possono inserire le
formule logiche da veri�care sulla famiglia. Le formule si possono applicare alla famiglia
(da considerare che le transizioni sono must e may) oppure ai singoli prodotti. La �gura
6.4 mostra il primo caso e si può notare come il nome dell'editor di testo è SoCL/MTS,
e che quindi le formule sono scritte considerando il fatto che le transizioni sono di tipo
must oppure may. Un esempio di formula in SoCL/MTS è: nella famiglia di macchine da
ca�è dopo aver inserito una moneta è sempre possibile scegliere la bevanda ca�è,
66
AG [may(dollar) or may(euro)] E [true {must(*)} U {must(co�ee)} true]
Il risultato della veri�ca viene mostrato nella parte centrale della pagina, vedi �gura
6.8. La validità della formula mi garantisce che ogni prodotto della famiglia ha questa
Figura 6.8: VMC, veri�care proprietà sulla famiglia
proprietà, includendo anche i prodotti non validi rispetto i vincoli espressi mediante le
formule in MHML. Se la formula non è valida invece, allora esiste qualche prodotto nel
quale la proprietà non vale, ciò non signi�ca però che tale proprietà sia valida per tutti
i prodotti validi rispetto ai vincoli. Infatti, la veri�ca non tiene conto dei vincoli che
vengono utilizzati per generare i prodotti validi.
Le formule si posso applicare anche ai singoli prodotti. In quanto i singoli prodotti sono
LTSs le formule non includono informazione su transizioni must e may. Ad esempio sulla
lista dei prodotti validi si può veri�care la seguente formula:
EX {euro} true
i prodotti con il risultato true sono le macchine per il mercato europeo, le altre per il
mercato statunitense.
67
Figura 6.9: VMC, veri�care proprietà sui prodotti
68
Capitolo 7
Conclusioni e lavoro futuro
Questa tesi conclude la prima parte dell'attività di ricerca presentata nel capitolo 4, dove
quest'ultima si pone l'obiettivo di formalizzare un ambiente di veri�ca e analisi in Pro-
duct Family Engineering (PFE). Una famiglia di prodotti è un Modal Transition System
(MTS) ed un insieme di vincoli de�niti sulle funzionalità dei prodotti ed espressi nella
logica temporale deontica branching MHML. Il mio lavoro, in particolare, è stato quello
di implementare una procedura che permette di generare i prodotti validi considerando
i vincoli e di integrarlo in FMC, un model checker basato su stati ed azioni. Durante lo
studio e l'implementazione dell'algoritmo sono state fatte alcune osservazioni. Una prima
osservazione si è dovuta fare sulla struttura dell'algoritmo da implementare. Si è pensato
ad un algoritmo globale in alternativa ad un algoritmo locale. Nell'approccio globale pri-
ma si generano tutte le famiglie dell'MTS in esame per poi veri�care su queste la validità
delle formule che rappresentano i vincoli. Nell'approccio locale invece, eseguo una suc-
cessione di passi dove in ogni passo aggiungo un arco dell'MTS originale ad un prodotto
intermedio e su questo veri�co la validità delle formule. Nell'approccio locale però avere
MTS come prodotti intermedi era complicato. Inoltre, un algoritmo locale risulta più
69
e�ciente se applicato ad una famiglia che si presenta con un numero abbastanza grande
di vincoli. Questo perché posso tagliare interi sottoalberi a causa della non soddisfazione
di qualche vincolo. In quanto eravamo interessati alla generazione dei prodotti �nali ho
pensato che la scelta ottimale era quella di generare i prodotti (con soli archi must) di
un MTS seguendo l'approccio locale. La seconda osservazione riguardava la veri�ca delle
formule logiche che rappresentavano i vincoli. La prima soluzione consisteva nell'utilizzo
continuo del model checker FMC. Quando si doveva veri�care la validità di una formu-
la, la descrizione del prodotto intermedio veniva caricato nel model checker e in seguito
valutate le formule. Analizzando la struttura dei vincoli si è capito che tale veri�ca si
poteva realizzare in modo alternativo, semplicemente tenendo una struttura dati che con-
tiene le azioni presenti nelle transizioni che compongono il prodotto intermedio. In ogni
passo una scansione della struttura e su�ciente per stabilire la validità delle formule che
rappresentano i vincoli.
L'integrazione con FMC era relativamente facile in quanto per descrivere una famiglia si
utilizza un sottoinsieme degli operatori sinattici di FMC. Abbiamo mostrato anche come
formule logiche in MHML si traducono in SocL che è la logica di FMC.
Variability Model Checker (VMC) è un ambiente completo di analisi e veri�ca in PFE e
mette in condizioni di considerare altri sviluppi futuri. Un possibile sviluppo futuro può
essere quello di identi�care e successivamente aggiungere all'algoritmo altri vincoli signi-
�cativi espressi in MHML (oltre a alternative, exclude e requires), da veri�care durante
la generazione dei prodotti validi.
Si può realizzare uno strumento con il quale sia possibile descrivere gra�camente una
famiglia in MTS+MHML oppure mediante un Feature Diagram. Inoltre, si può realiz-
zare anche un trasformatore da modelli descritti in Feature Model a modelli descritti in
MTS+MHML e viceversa, in modo da mettere in relazione i due formalismi.
70
Un algoritmo per derivare sottofamiglie valide rispetto ai vincoli si può realizzare e può
essere utile in termini di Product Family Engineering.
Un'altra importante questione è di studiare come questo approccio scala in una situazione
reale dove le famiglie si presentano con molte funzionalità e molti vincoli tra loro.
71
Bibliogra�a
[1] P. Asirelli, M.H. ter Beek, A. Fantechi, and S. Gnesi, Deontic Logics for Mo-
delling Behavioural Variability. In: D. Benavides, A. Metzger, and U.Eisenecker
(Eds.): Proceedings of the Third International Workshhop on Variability Modelling
of Software-intensive Systems (VaMos'09), ICB Research report 29, Universität
Duisburg-Essen, 2009, 71-76.
[2] P. Asirelli, M.H. ter Beek, A. Fantechi, and S. Gnesi, A deontical logical framework
for modelling product families. In: D. Benavides, D. Batory, P. Grünbacher (Eds.):
Proceedings Variability Modelling of Software.intensive Systems (VaMoS'10), ICB
Research report 37, Universität Duisburg-Essen, 2010, 37-44.
[3] P.F. Castro and T.S.E. Maibaum, A Complete and Compact Propositional Deontic
Logic. In: C.B. Jones, ZH. Liu and J. Woodcock (Eds.): International Colloquium
Theoretical Aspects of Computing (ICTAC'07),LNCS 4711, Springer, 2007, 109-123.
[4] E.M. Clarke, O. Grumberg and D.A. Peled, Model Checking, MIT Press� 1999.
[5] R. De Nicola and F.W. Vaandrager, Three Logics for Branching Bisimulation.
Journal of the ACM 42, 2 (1995), 458-487.
72
[6] Maurice H. ter Beek, Franco Mazzanti, and Aldi Sulova, VMC: A Tool for the
Analysis of Product Variability. To appear in Sixth International Workshop on Va-
riability Modelling of Software-intensive Systems (VaMoS 2012), Leipzig, Germany,
January 25-27, 2012.
[7] Stefania Gnesi and Franco Mazzanti, An Abstract, on the Fly Framework for the
Veri�cation of Service-Oriented Systems SENSORIA BOOK - Lecture Notes in
Computer Science - to appear
[8] K.G. Larsen and B. Thomsen, A Modal Process Logic. Proceedings Logic in
Computer Science (LICS'88), IEEE, 1988, 203-210.
[9] K. Kang, S. Choen, J. Hess, W. Novak and S. Peterson, Feature Oriented Do-
main Analysis (FODA) Feasibility Study. Technical Report SEI-90-TR-21, Carnegie
Mellon University, Nov. 1990.
[10] Ada 2005 Reference Manual, ISO/IEC 8652:2007(E) Ed. 3
[11] Rationale for Ada 2005, John Barnes.
[12] S. Gnesi and F. Mazzanti. On the Fly Veri�cation of Networks of Automata. In
PDPTA'99 Conference Proceedings, pages 1040-1046. CSREA Press, Athens, GA,
1999.
[13] M.H. ter Beek, F. Mazzanti and A. Fantechi. CMC-UMC: A Framework for the Veri-
�cation of Abstract Service-oriented Properties. In SAC'09 Conference Proceedings,
pages 2111-2117. ACM Press, New York, NY, 2009.
[14] K. Pohl, G. Böckle and F. van der Linden, Software Product Line Engineering:
Foundations, Principles, and Techniques, Springer, 2005
73
[15] D.S. Batory, Feature Models, Grammars, and Propositional Formulas. In J.H. Ob-
bink and K. Pohl (Eds.): Proceedings Software Product Line Conference (SPLC'05),
LNCS 3714, Springer, 2005, 7-20.
[16] P. Asirelli, M.H. ter Beek, A. Fantechi, and S. Gnesi, Formal Description of Variabi-
lity in Product Families. In Proceedings of the 15th International Software Product
Line Conference (SPLC 2011), Munich, Germany. IEEE Computer Society, Los
Alamitos, CA, 2011, 130-139
[17] P. Asirelli, M.H. ter Beek, A. Fantechi, and S. Gnesi, A Logical Framework to Deal
with Variability. In Proceedings of the 8th International Conference on Integrated
Formal Methods (IFM'10), Nancy, France (D. Méry and S. Merz, eds.), Lecture
Notes in Computer Science 6396, Springer-Verlag, Berlin, 2010, 43-58.
74