Les12: Validation ITA (parte 1) - Facolta di Ingegneria

Software Engineering
a.y. 2016-2017
Convalida e verifica del software (parte 1)
Prof. Luca Mainetti
Università del Salento
Obiettivi della lezione
■  Fare alcune riflessioni sul processo di sviluppo del software
che ci portano ad introdurre l’argomento della convalida e
verifica
■  Passare in rassegna alcune tecniche di convalida e verifica
del software che permettono di provare il livello di qualità
raggiunto dal prodotto
–  Un prodotto software deve essere collaudato, anche se il processo
di sviluppo contiene tecniche sistematiche di codifica
–  Obiettivo del collaudo è la prova della rispondenza del prodotto ai
requisiti
–  Già durante l’attività di specifica dei requisiti è bene anticipare i casi
di test che compongono il collaudo
–  Le prove di convalida e verifica devono essere consegnate al
committente assieme al prodotto
–  Dovete sottoporre il risultato dei vostri progetti ad una o più tecniche
di convalida e verifica che qui analizziamo
Convalida e verifica del software (parte 1)
2
Luca Mainetti
Processo di sviluppo del software
■  Uno degli obiettivi primari dell’ingegneria del software è di
provare che il processo di produzione del software può
essere schematizzato come un’attività di derivazione
formale dell'implementazione a partire dalle specifiche
–  la codifica è un mapping dal design al codice
–  il design è un mapping dai requisiti al progetto
■  Ancora non siamo giunti ad un approccio generale in questi
termini, ma il alcune aree applicative, dove l’affidabilità del
sistema software finale sia critica, l’approccio fa ben
sperare
–  sistemi di controllo
–  sistemi che possono essere caratterizzati da un punto di vista
operazionale
Convalida e verifica del software (parte 1)
3
Luca Mainetti
Processo di sviluppo del software (cont.)
■  Linguaggi formali di specifica
–  definizione di un’applicazione per livelli di astrazione successivi
–  dimostrazione formale della consistenza del passaggio tra un livello
e quello successivo
–  il livello finale coincide con il linguaggio di programmazione scelto
–  perché si possa procedere, i requisiti iniziali devono essere tradotti
in termini matematici: modello formale
•  il fatto che il modello formale esprima esattamente i requisiti iniziali è
l’unica prova informale dell’approccio
–  in uno o più passi successivi si prova con tecniche logico/matematiche che dal modello formale si possa derivare una specifica
formale di più basso livello, fino a giungere al codice finale
•  la prova può essere automatica oppure può richiedere l’intervento di un
umano
Convalida e verifica del software (parte 1)
4
Luca Mainetti
Processo di sviluppo del software (cont.)
■  Il meccanismo di prova consiste di due parti
–  prova che il sistema specificato in modo operazionale soddisfa
particolari condizioni invarianti che rappresentano i vincoli ed i
requisiti critici del sistema
–  prova di consistenza tra un livello di specifica e quello successivo
■  Specifiche algebriche
–  è un insieme di notazioni e di metodi che permettono una
descrizione ed implementazione formale e rigorosa dei tipi di dati
astratti, che sono alla base del principio di information hiding
–  con una notazione algebrica è possibile definire le principali strutture
dati
–  l’implementazione può essere descritta sempre in termini algebrici e
dimostrata a partire dalla specifica del tipo di dato implementato
Convalida e verifica del software (parte 1)
5
Luca Mainetti
Processo di sviluppo del software (cont.)
■  Nel presente corso di Software Engineering non
approfondiremo i metodi formali né le specifiche algebriche
■  Non perché non siano importanti, ma perché sono
certamente più diffusi i metodi di specifica semi-formali e le
tecniche di codifica che non fanno uso di derivazione
matematica tra livelli di astrazione successivi
■  La sperimentazione durante lo svolgimento del progetto vi
permetterà di provare ad utilizzare comunque un
procedimento sistematico
■  Il ricorso a pattern di design e di codifica vi aiuterà ad
utilizzare (e riusare) tecniche consolidate
Convalida e verifica del software (parte 1)
6
Luca Mainetti
Processo di sviluppo del software (cont.)
■  Implementazione fortemente basata sul design (“up-front
design”)
–  benché all’interno di un ciclo iterativo, la fase di design cerca di
anticipare e vincolare tutte le caratteristiche del prodotto software
–  si pone monta enfasi (ed effort) sulla definizione di interfacce di
moduli e sull’uso preventivo di pattern per il riuso
■  Implementazione basata su tecniche di XP - Extreme
Programming (“continuous design”)
–  il design è molto semplice e leggero
–  si procede ad un’implementazione molto anticipata ed il design
riflette le caratteristiche dell’implementazione
–  i pattern vengono utilizzati come strumenti di supporto
all’implementazione, meno come strumenti per il riuso ed evoluzione
Convalida e verifica del software (parte 1)
7
Luca Mainetti
Processo di sviluppo del software (cont.)
■  La crescente disponibilità di strumenti di “continuous
integration”, refactoring, testing pone una reale problema di
capire quale sia l’approccio più conveniente tra up-front
design e continuous design
–  strumenti come ANT (Another Neat Tool, http://ant.apache.org)
permettono di creare build di sistema in modo continuo
–  strumenti come JUnit, DBUnit, HttpUnit, ServletUnit permettono di
automatizzare test di verifica del software
–  la valutazione di una versione concreta di un’applicazione software
diviene sempre più un’attività supportata, automatizzabile, semplice,
rapida
■  Probabilmente la via di mezzo tra up-front design e
continuous design è quella più adatta alla maggior parte dei
casi applicativi
Convalida e verifica del software (parte 1)
8
Luca Mainetti
Convalida e verifica
■  Le attività di convalida e verifica devono essere effettuate
durante il ciclo di sviluppo del software (devono essere
iterate), non solamente prima della fase di rilascio
■  Le attività di convalida e verifica si avvalgono di varie
tecniche, ognuna delle quali ha delle precise specificità e
meglio si adatta alla prova di fattori di qualità
■  Il punto di partenza è sempre e comunque una chiara
definizione e specifica delle proprietà (qualità) che il
prodotto software deve avere
–  la correttezza funzionale è una di queste proprietà, non la sola, né, a
volte, la più importante
–  non sono molte le tecniche di verifica totalmente generali (come, ad
esempio, la valutazione delle prestazioni)
Convalida e verifica del software (parte 1)
9
Luca Mainetti
Convalida e verifica (cont.)
■  I risultati della verifica possono non essere binari (OK, KO)
–  alcuni difetti possono essere tollerati
–  il concetto di correttezza è relativo, è meglio esprimere una certo livello o
“misura” di correttezza
•  ad esempio, l’efficienza può essere misurata in modo relativo con una formula del
tipo: “il tempo richiesto per eseguire una computazione è dato dalla funzione f(n)
della lunghezza n dei dati di ingresso”
■  La verifica può essere oggettiva o soggettiva
–  oggettiva, alcuni esempi: verifica dei risultati a partire da dati di ingresso,
misura delle prestazioni
–  soggettiva, alcuni esempi: verifica della manutenibilità, test di usabilità
■  Anche le qualità implicite (robustezza, manutenibilità, efficienza) devono
essere verificate sebbene spesso non siano espresse nei requisiti
Convalida e verifica del software (parte 1)
10
Luca Mainetti
Convalida e verifica (cont.)
■  Approcci alla verifica
–  effettuare esperimenti con il prodotto funzionante (tecniche
dinamiche)
–  analizzare il prodotto in modo da dedurre (dal suo codice, dalla sua
documentazione) delle proprietà (tecniche statiche)
■  Procedimento di testing
–  si verifica il comportamento definendo in insieme di “casi di test”
–  è impossibile dedurre la correttezza del software da un insieme finito
di casi di test
–  per quanti casi di test si possano prevedere ed eseguire, il software
può comunque rimanere non corretto per qualche caso d’uso
Convalida e verifica del software (parte 1)
11
Luca Mainetti
Convalida e verifica (cont.)
■  Se si confronta il comportamento del software con i requisiti
informali estratti dal committente, le tecniche di convalida e
verifica utilizzabili sono necessariamente vaghe
■  Invece, se si confronta il comportamento del software con
una specifica semi-formale (o formale) dei requisiti, le
tecniche possono essere sistematiche e supportate da
strumenti automatici
■  Esistono due momenti distinti
–  convalida: confronto del comportamento del software con i requisiti
estratti dal committente
–  verifica: confronto del comportamento del software con la specifica
dei requisiti stessi prodotta da un analista
Convalida e verifica del software (parte 1)
12
Luca Mainetti
Convalida e verifica (cont.)
■  Convalida e verifica sono quindi attività complementari
–  la verifica potrebbe provare che il software è corretto rispetto alla
specifica dei requisiti, ma la specifica dei requisiti potrebbe non
rappresentare correttamente i “desiderata” del committente
–  al contrario, la sola convalida potrebbe non renderci
sufficientemente confidenti in un livello di correttezza accettabile del
software
■  Definizioni
–  malfunzionamento (guasto, failure): comportamento errato di un
programma (non è legato alla struttura logica del programma)
–  anomalia (difetto, fault, bug): è la causa di un malfunzionamento
(riguarda la struttura statica del programma, il codice)
•  un programma potrebbe contenere anomalie senza manifestare
malfunzionamenti
•  un malfunzionamento può essere dovuto a più anomalie
Convalida e verifica del software (parte 1)
13
Luca Mainetti
Convalida e verifica (cont.)
■  Esempio
–  se un programma che vuole calcolare il doppio di un numero
contiene la linea di codice y=x * x, contiene evidentemente
un’anomalia, che però non si manifesta come malfunzionamento se
il programma viene provato con x = 2
■  Definizioni
–  errore: è la causa di un’anomalia, dovuta frequentemente ad un
errore umano piuttosto che ad un errore di uno strumento di
produzione
■  Varie tecniche di prova della correttezza del software
–  prova formale: prova dell’assenza di anomalie
–  test: rilevamento di eventuali malfunzionamenti
–  debugging: localizzazione delle anomalie in base ai malfunzionam.
–  analisi statica: prove basate sull’esame del codice sorgente
–  analisi dinamica: prove basate sull’esecuzione del programma
Convalida e verifica del software (parte 1)
14
Luca Mainetti
Convalida e verifica (cont.)
■  Alcune tecniche di convalida e verifica fanno uso del “grafo
di controllo di un programma sequenziale”: si tratta di una
rappresentazione grafica delle strutture di controllo del
codice
■  Il grafo di controllo può essere visualizzato a vari livelli di
dettaglio “espandendo” o “contraendo” blocchi di codice
n1
n1
S1
S1
S2
S
S2
n2
if cond S1 else S2
Convalida e verifica del software (parte 1)
n2
while cond do S
15
S1; S2
Luca Mainetti
Convalida e verifica (cont.)
begin
read(x, y);
a = x;
b = y;
while a != b do
begin
if a > b
a = a - b;
else
b = b - a;
end;
…...
end
read(x, y);
a = x;
b = y;
a != b
a>b
a=a-b;
……
b=b-a;
end;
Esempio di grafo di controllo
Convalida e verifica del software (parte 1)
16
Luca Mainetti
Analisi statica
■  Viene analizzato il codice sorgente dell’applicativo software
■  Non è quindi richiesta l’esecuzione del programma
■  L’analisi statica si basa sull’esame su un insieme finito di
elementi, che sono le istruzioni del codice sorgente
■  L’analisi dinamica si basa invece sull’esame dell’insieme
delle esecuzioni, che benché finito, non è limitabile a priori
■  Per l’analisi statica non vi è quindi il problema di limitare il
numero di casi da prendere in esame
■  Però proprio la finitezza dei casi implica un numero inferiori
di anomalie che possono essere rilevate
–  ad esempio, non possono essere rilevate anomalie alla base di
malfunzionamenti che dipendono dal valore assunto da variabili
Convalida e verifica del software (parte 1)
17
Luca Mainetti
Analisi statica in compilazione
■  L’analisi statica permette quindi di rilevare un numero
minore di anomalie rispetto a quella dinamica, ma è meno
costosa ed è più direttamente automatizzabile
■  I compilatori effettuano un’analisi statica del codice
sorgente
–  analisi lessicale: errori nella formazioni delle parole chiave e dei
nomi definiti dall’utente
–  analisi sintattica: errori nelle relazioni tra gli elementi ottenuti
dall’analisi lessicale
–  controllo dei tipi: violazione delle regole del “type system” del
linguaggio di programmazione
■  Molti compilatori effettuano anche l’analisi di flusso dati
Convalida e verifica del software (parte 1)
18
Luca Mainetti
Analisi di flusso dati
■  E’ un’analisi dell’evoluzione del valore delle variabili durante
l’esecuzione di un programma
■  Tale valutazione è intrinsecamente dinamica, ma possibili
anomalie possono essere rilevate anche con tecniche
statiche
■  Sappiamo che durante l’uso di variabili possiamo
distinguere tre momenti principali
–  definizione (d)
•  x = y + 1;
//il valore della variabile x viene definito
–  uso (u)
•  x = y + 1;
//il valore della variabile y viene usato
–  annullamento (a)
•  return( k );
//dopo l’istruzione, il valore della variabile k è annullato
Convalida e verifica del software (parte 1)
19
Luca Mainetti
Analisi di flusso dati (cont.)
■  Ad ogni comando è quindi associabile in maniera statica il
tipo di operazione effettuata sulle variabili
■  In altre parole, sequenze di comandi, che corrispondono a
possibili esecuzioni, possono essere mappate su sequenze
di definizioni (d), usi (u) e annullamenti (a)
■  Sequenza di operazioni su x
void swap(int x1, int x2)
{
int x;
–  auu
■  Sequenza di operazioni su x1
–  dud
x2 = x;
x2 = x1;
x1 = x;
■  Sequenza di operazioni su x2
–  ddd
}
Convalida e verifica del software (parte 1)
20
Luca Mainetti
Analisi di flusso dati (cont.)
■  Analizzando poi le sequenze di operazioni ottenute per ogni
variabile, possono essere evidenziate delle anomalie o delle
possibili anomalie
–  la sequenza auu permette di dedurre che il valore utilizzato non è
stato precedentemente definito
•  si può quindi risalire all’anomalia, la cui causa è dovuto al fatto che le
due variabili x2 e x nel primo assegnamento sono state erroneamente
invertite
–  anche la sequenza ddd (sequenze di definizioni senza usi intermedi)
permette di risalire all’anomalia precedentemente evidenziata
■  Regole per il rilevamento di possibili anomalie
–  R1: l’uso di una variabile x deve sempre essere preceduto in ogni
sequenza da una definizione di x, senza annullamenti intermedi
–  R2: una definizione di una variabile x deve sempre essere seguita
da un uso di x, prima di un’altra definizione o di un annullamento di x
Convalida e verifica del software (parte 1)
21
Luca Mainetti
Analisi di flusso dati (cont.)
■  La tecnica dell’analisi del flusso dati, che i compilatori fanno
per noi, e che spesso i programmatori eseguono con un
procedimento “mentale” o avvalendosi di tool di debugging,
può essere estesa ad altri ambiti
■  Ad esempio, si possono ricondurre ad analisi statica le
operazioni svolte sui file
■  Questo è il significato principale del ripercorre tecniche che
sono implementate dai compilatori: avere un modello in
mente che possa essere riusato in altre situazioni
■  Provate, ad esempio, ad ipotizzare un procedimento simile
al precedente, per applicato all’analisi di operazioni con
Web service
Convalida e verifica del software (parte 1)
22
Luca Mainetti
Analisi di flusso dati (cont.)
■  Se il codice sorgente contiene condizioni e/o cicli, il numero
di cammini non è limitabile a priori. In questo caso, la
formulazione di sequenze di operazioni può essere
effettuata con uso di espressioni regolari
1
2
3
4
5
6
7
8
9
10
11
read(x, y);
a = x;
a = y;
while a != b do
begin
if a > b
a = a - b;
else
b = b - a;
end;
…...
Convalida e verifica del software (parte 1)
Si costruisce il grafo di
controllo utilizzando due
operazioni per gli
assegnamenti
6
23
1
read(x, y);
2
a = x;
3
a = y;
4
a != b
a>b
11 ……
7
r1=a-b;
9
r2=b-a;
7’
a=r1;
9’
b=r2;
Luca Mainetti
Analisi di flusso dati (cont.)
■  A ciascun nodo del grafo di controllo si assegnano gli
insiemi delle variabili definite, usate, annullate
6
0
begin
1
read(x, y);
2
a = x;
3
a = y;
4
a != b
a>b
11 write(a);
7
r1=a-b;
9
r2=b-a;
7’
a=r1;
9’
b=r2;
Convalida e verifica del software (parte 1)
24
Luca Mainetti
Analisi di flusso dati (cont.)
■  Percorrendo un cammino nel grafo, consultando la tabella
ed annotando i tipi di operazioni, è possibile, per ogni
variabile definirne la sequenza
■  Ad esempio, percorrendo il cammino
–  [0, 1, 2, 3, 4, 6, 7, 7’, 4, 11]
per la variabile “a” si ottiene la sequenza di operazioni
–  adduuuuduu
■  Se vogliamo invece scrivere la sequenza di operazioni che
corrisponde a più cammini, è necessario un linguaggio che
permetta di esprimere alternative e cicli: possiamo utilizzare
le espressioni regolari (“+” esprime l’alternativa, “*” esprime
il ciclo)
Convalida e verifica del software (parte 1)
25
Luca Mainetti
Analisi di flusso dati (cont.)
■  Ad esempio, l’espressione regolare che descrive il cammino
uscente dal nodo 4 per la variabile “a” è
–  (u(ud+u)u)*u
■  In modo analogo, l’espressione regolare che descrive il
cammino uscente dal nodo 0 per la variabile “a” è
–  addu(u(ud+u)u)*u
–  è facile verificare che tutti gli usi sono preceduti da una definizione,
ma esiste una definizione mai seguita da un uso (la prima)
■  L’esame delle espressioni regolari permette quindi di
verificare se le regole R1 e R2 sono violate
■  Poiché il grafo di controllo può essere complesso ed il
numero di variabili elevato, il procedimento qui presentato
non viene attuato, ma si preferiscono algoritmi ottimizzati
Convalida e verifica del software (parte 1)
26
Luca Mainetti
Analisi dinamica
■  Le tecniche di analisi dinamica richiedono l’esecuzione del
programma da convalidare e verificare
■  Poiché il numero di possibili esecuzioni è molto grande, si
ha la necessità di selezionare un insieme limitato di input
significativi
■  La scelta casuale di tali input è generalmente poco
significativa e poco praticabile, ma conviene sfruttare la
conoscenza del dominio associata alla conoscenza degli
algoritmi utilizzati (ad esempio, analizziamo un ciclo “for” in
prossimità degli estremi del ciclo steso)
–  massimizzare la probabilità di rilevare malfunzionamenti
–  minimizzare i costi di test, cioè il numero di dati di test
–  utilizzare criteri sistematici
Convalida e verifica del software (parte 1)
27
Luca Mainetti
Analisi dinamica (cont.)
■  Selezionati i casi di test ed eseguiti sui dati di input, si pone
il problema di capire se i risultati ottenuti siano corretti
■  Se confrontiamo i risultati ottenuti con le specifiche, stiamo
effettuando una verifica
■  Se confrontiamo i dati di test con i requisiti iniziali o,
tipicamente, al giudizio dell’utente, stiamo effettuando una
convalida
■  E’ possibile confrontare i risultati ottenuti, con risultati
ottenuti da versioni precedenti del programma stesso
eseguito sui medesimi input: test di regressione
–  l’ipotesi è che non siano stati introdotti nuovi malfunzionamenti
–  il test è facilmente automatizzabile anche per programmi che non
producono semplici risultati atomici (analizzare la base dati)
■  Tipicamente si decide essere conclusa la fase di analisi
dinamica sulla base di un semplice criterio temporale
Convalida e verifica del software (parte 1)
28
Luca Mainetti
Analisi dinamica (cont.)
■  Nel seguito presentiamo alcuni fondamenti della teoria del
test che possono mostrare come criteri per la terminazione
della fase di analisi possono essere derivati da criteri di
selezione dei dati di test
■  Un programma P è considerato una funzione dal dominio
dei D dei dati al codominio R dei risultati
■  Il risultato P(d) dell’esecuzione di P sul dato d∈D è corretto
se soddisfa le specifiche: si indica ok(P,d)
■  Un programma P è corretto, ok(P), se ∀d ∈D, ok(P,d)
■  Un test T per un programma P con dominio D è un
sottoinsieme di D: t ∈T è detto dato di test
Convalida e verifica del software (parte 1)
29
Luca Mainetti
Analisi dinamica (cont.)
■  L’esecuzione di un test T è l’esecuzione di un programma P
per tutti i dati di test t appartenenti a T
■  Un programma P è corretto per un test T, ok(P,T), se il
programma P è corretto per tutti gli elementi di T, cioè se
∀t ∈T, ok(P,t)
■  Scopo dell’attività di test è rilevare malfunzionamenti, quindi
si dice che un test T ha successo, successo(P,T), se rileva
uno o più malfunzionamenti di P
■  Se un test non rileva malfunzionamenti non può essere
dedotta la correttezza di P
–  è l’atteggiamento inverso rispetto a quanto si vive nei team di
sviluppo: la positività sta nel rilevare malfunzionamenti
–  in genere si è “soddisfatti” dal non rilevare malfunzionamenti in casi
di test perché da qui si deduce (erroneamente) la correttezza di P
Convalida e verifica del software (parte 1)
30
Luca Mainetti
Analisi dinamica (cont.)
■  La generalizzazione vale solo nel caso ideale: un test T è
detto ideale per P se e solo se ok(P,T) ⇒ ok(P)
■  Ovviamente uno degli scopi della teoria del test è la
definizione dei metodi che consentono la selezione di test
che approssimano quelli ideali
■  Un criterio C di selezione di test T per P è un insieme di
predicati sul dominio D
■  Un test T è selezionato dal criterio C, selezionato(C,T), se
∀t ∈T ∃c ∈C tale che c(t) è vero e ∀c ∈C ∃t ∈T tale che c(t)
è vero
■  Un criterio di selezione di test consente di selezionare più
test per lo stesso programma
Convalida e verifica del software (parte 1)
31
Luca Mainetti
Analisi dinamica (cont.)
■  Consideriamo infatti il criterio di test
–  C = {(∃t ∈C tale che t<0), (0 ∈ C), (∃t ∈C tale che t>0)}
cioè un test contiene almeno un numero negativo, 0 e
almeno un numero positivo. Allora sono test selezionati
–  {-4, 0, 11}
–  {-4, -8, -42, 0, -1, 3}
■  Un criterio di test C è affidabile per un programma P,
affidabile(C,P), se per ogni coppia di test T1 e T2 selezionati
da C, se il test T1 ha successo allora anche T2 ha successo
e viceversa, successo(P,T1)⇔successo(P,T2)
–  il successo di un test selezionato da un criterio affidabile permette di
di dedurre il successo di qualsiasi test selezionato dallo stesso
criterio
Convalida e verifica del software (parte 1)
32
Luca Mainetti
Analisi dinamica (cont.)
■  Il fatto che un criterio di test sia affidabile non implica che
tutti i test selezionati permettano di evidenziare gli stessi
malfunzionamenti
■  Un criterio C di selezione di test è valido per un programma
P, valido(C,P), se qualora P non sia corretto, esiste almeno
un test T selezionato da C che ha successo per P, cioè è in
grado di rilevare i malfunzionamenti di P
–  se esiste un malfunzionamento in P, tale malfunzionamento è
rilevato da uno dei test selezionati da C
–  per il programma raddoppia con corpo y=x * x
•  {0, 2} è affidabile (il programma risulta corretto per tutti i test selezionati)
•  {0, 1, 2, 3, 4} è valido, ma non affidabile
•  {3, 4, 5, 6, ...} è valido e affidabile
Convalida e verifica del software (parte 1)
33
Luca Mainetti
Analisi dinamica (cont.)
■  Teorema di Goodenough e Gerhart
–  il fallimento di un test T per un programma P selezionato da un
criterio C affidabile e valido per P, permette di dedurre la correttezza
di P
–  affidabile(C,P) ∧ valido(C,P) ∧ selezionato(C,T) ∧ ¬successo(T,P)
⇒ ok(P)
■  L’affidabilità e la validità sono quindi le proprietà che ci
interessano nei criteri di test, ma l’importante è non dedurre
tali proprietà dalla conoscenza a priori della correttezza di P
■  Al di là di casi banali (ad esempio il test esaustivo, cioè
quello che contiene tutto il dominio D), non è possibile
costruire un criterio di selezione generale valido e affidabile
Convalida e verifica del software (parte 1)
34
Luca Mainetti
Analisi dinamica (cont.)
■  Teorema di Howden
–  non esiste un algoritmo che, dato un programma arbitrario P, generi
un test ideale finito, e cioè un test definito da un criterio affidabile e
valido
■  Tesi di Dijkstra
–  il test di un programma può rilevare la presenza di malfunzionamenti, ma mai dimostrarne l’assenza
•  è una diretta corrispondenza al teorema di Howden
■  Esistono vari problemi di decidibilità legati alla teoria del test
–  un problema è detto “non decidibile” se può essere dimostrato che
non esiste alcun algoritmo finito che lo possa risolvere
–  un problema P non è decidibile se non esiste una macchina di
Turing in grado di risolverlo
Convalida e verifica del software (parte 1)
35
Luca Mainetti
Analisi dinamica (cont.)
■  Segue l’espressione di tre problemi non decidibili
■  (1) Teorema di equivalenza dei programmi
–  non è possibile stabilire se due generici programmi calcolino la
stessa funzione o meno
•  in particolare non si può dimostrare la correttezza di P a partire
dall’equivalenza di P con un P1 noto corretto a priori
■  (2) Teorema di equivalenza di cammini
–  non esiste un algoritmo in gradi di stabilire se due generici cammini
del grafo di flusso di un programma calcolino la stessa funzione o
meno
•  ciò è utile nell’ambito dell’esecuzione simbolica
Convalida e verifica del software (parte 1)
36
Luca Mainetti
Analisi dinamica (cont.)
■  (3) Teorema di Weyuker
–  Dato un generico programma P i seguenti problemi risultano
indecidibili
•  esiste almeno un dato ingresso che causa l’esecuzione di un particolare
comando?
•  esiste un particolare dato di ingresso che causa l’esecuzione di una
particolare condizione (branch)?
•  esiste un particolare dato di ingresso che causa l’esecuzione di un
particolare cammino?
•  è possibile trovare almeno un dato di ingresso che causi l’esecuzione di
ogni condizione (branch) di P?
•  è possibile trovare almeno un dato di ingresso che causi l’esecuzione di
ogni cammino di P?
■  Il teorema di Weyuker è importante per i metodi di test
strutturale
Convalida e verifica del software (parte 1)
37
Luca Mainetti