Come creare un software Mission Critical?


15

Sono metodi formali di autoapprendimento. Ho sentito che i metodi formali vengono utilizzati (e di solito utilizzati solo) per creare software mission-critical (come controller di reattori nucleari, controller di volo di aerei, controller di sonda spaziale). Ecco perché sono interessato a impararlo: p

Tuttavia, dopo aver appreso i metodi formali (in particolare LTL, CTL e i loro fratelli), sento che possono essere utilizzati solo per verificare la correttezza delle specifiche (sicurezza, liveness, equità, ecc.).

Ma allora come verificare che il software (non solo le specifiche) sia effettivamente corretto?

Disclaimer: sono un idiota al 90% quando si tratta di informatica teorica. Quindi per favore sii misericordioso mentre rispondi.


2
Cosa intendi esattamente con "... che il software è davvero corretto ..." ? Quale delle seguenti 2 intendete: 1) Il software è conforme alla specifica 2) Blocchi specifici di codice rispettano una determinata proprietà o una relazione input - output.
Giorgio Camerani,

@GiorgioCamerani: il primo
fajrian,

2
La correttezza di un programma di solito significa che (1) è coerente con una specifica e (2) non si blocca mai. Il punto (1) è in realtà un'affermazione sulla coppia (programma, specifica) piuttosto che sul programma in sé. Un'ulteriore complicazione è che "programma" è in genere una scorciatoia per "modello di un programma", poiché i programmi stessi sono piuttosto complicati o non hanno una semantica precisa. Detto questo, penso che tu stia chiedendo del divario tra un programma e il suo modello, ma non sono del tutto sicuro.
Radu GRIGore,

@RaduGRIGore: In realtà non capisco cosa sia il "modello". Ma penso che tu affronti la mia domanda abbastanza da vicino. Fondamentalmente, quello che mi chiedo è il divario tra le specifiche e il codice sorgente del programma. Molte cose stupide possono accadere quando i programmatori (come me) stanno implementando le specifiche.
Fajrian,

1
@fajrian: sospetto che tu dica "specifica" per quello che definirei "modello". Esistono strumenti che funzionano con programmi scritti in linguaggi come C o Java, o anche con codice macchina. (È comunque un modello, dato che devono assumere una semantica, che dovrebbe , ma potrebbe non corrispondere a ciò che fa il compilatore / elaboratore.)
Radu GRIGore

Risposte:


11

La domanda è piuttosto ampia. Per rispondere in uno spazio ragionevole farò molte semplificazioni eccessive.

Concordiamo sulla terminologia. Un programma è corretto quando implica la sua specifica. Questa vaga affermazione è resa precisa in molti modi, bloccando cosa è esattamente un programma e cosa è esattamente una specifica. Ad esempio, nel controllo del modello il programma è una struttura di Kripke e la specifica è spesso una formula LTL . Oppure, il programma potrebbe essere un elenco di istruzioni PowerPC e la specifica potrebbe essere un insieme di asserzioni Hoare-Floyd scritte, diciamo, nella logica del primo ordine. Esistono moltissime varianti possibili. È allettante concludere che in un caso (struttura di Kripke) non verifichiamo un programma reale, mentre nel secondo caso (elenco di istruzioni PowerPC) lo facciamo. Tuttavia, è importante rendersi conto che stiamo davvero esaminando modelli matematici in entrambi i casi, e questo va benissimo. (La situazione è abbastanza simile alla fisica in cui, ad esempio, la meccanica classica è un modello matematico della realtà.)

La maggior parte delle formalizzazione distingue tra sintassi e semantica di un programma; cioè, come viene rappresentato e cosa significa. La semantica di un programma è ciò che conta dal punto di vista della verifica del programma. Ma è ovviamente importante avere un modo chiaro di assegnare significati a (rappresentazioni sintattiche di) programmi. Due modi popolari sono i seguenti:

  • (piccola fase) semantica operativa : è molto simile alla definizione di un linguaggio di programmazione scrivendo un interprete per esso. Per questo è necessario dire qual è lo stato ed è influenzato da ogni affermazione nella lingua. (Potresti chiederti in quale lingua scrivi l'interprete, ma farò finta di non esserlo.)
  • semantica assiomatica : qui ogni tipo di istruzione viene fornito con uno schema assioma. Quindi, all'incirca, ogni volta che viene usata un'affermazione particolare di quel tipo, si traduce nella capacità di usare certi assiomi. Ad esempio, l'assegnazione viene fornita con lo schema ; l'assegnazione particolare viene fornita con l'assioma se istanziamo lo schema con .X: =e{P[X/e]}X: =e{P}X: =X+1{X+1=1}X: =X+1{X=1}P=(X=1)

(Ce ne sono altri. Mi sento particolarmente male per aver omesso la semantica denotazionale, ma questa risposta è già lunga.) Il codice macchina più la semantica operativa è abbastanza vicino a quello che la maggior parte delle persone chiamerebbe un "vero programma". Ecco un documento fondamentale, che sembra usare la semantica operativa per un sottoinsieme del codice macchina DEC Alpha:

Perché mai useresti alcune semantiche di livello superiore, come quelle assiomatiche? Quando non si desidera che la prova della correttezza dipenda dall'hardware su cui si esegue. L'approccio quindi è quello di dimostrare la correttezza di un algoritmo rispetto ad alcune pratiche semantiche di alto livello e quindi dimostrare che la semantica suona rispetto alla semantica di livello inferiore più vicina alle macchine reali.

In sintesi, potrei pensare a tre motivi che hanno portato alla tua domanda:

  1. Hai visto solo la semantica di alto livello che non assomiglia a quello che sei abituato a chiamare un programma e ti chiedi se ce ne sono di basso livello. La risposta è si.
  2. Ti chiedi come dimostri che un modello corrisponde alla realtà. Come in fisica, no. Devi semplicemente trovare modelli migliori e confrontarli con la realtà.
  3. Non hai visto la distinzione tra sintassi e semantica e vari modi per assegnare significati ai programmi. Due domande precedenti elencano alcuni libri.

Questa risposta sta semplicemente cercando di identificare tre diversi modi in cui ho capito la domanda. Andare in profondità in uno di questi punti richiederebbe molto spazio.


8

Un approccio per ridurre il divario tra un programma e le sue specifiche è l'uso di un linguaggio con una semantica formale. Un esempio interessante qui sarebbe Esterel . Dai un'occhiata alla pagina web di Gérard Berry per alcuni interessanti colloqui sul suo lavoro che porta metodi formali nel mondo reale. http://www-sop.inria.fr/members/Gerard.Berry/

ps Sei stato su un Airbus? Hai volato con metodi formali!


1
qualsiasi riferimento a come Airbus utilizza metodi formali sarebbe utile. (capisci che è possibile informazioni riservate.)
vzn

@RossDuncan Ho trovato questa pagina web dopo essere andato alla pagina Web di Berry e alcune ricerche. Sono questi i metodi formali che Airbus stava usando a cui ti riferivi?
scaaahu,

Non ho informazioni privilegiate sull'uso di Esterel da parte di Airbus; il mio commento ripete semplicemente un'osservazione fatta da Berry durante una lezione. Tuttavia, questa pagina tromba l'uso riuscito del prodotto SCADE con Airbus. Se guardi alla storia di Esterel, è stato adottato da Dassault abbastanza presto. Google è tuo amico.
Ross Duncan,

2
Airbus utilizza anche astree.ens.fr
Radu GRIGore,

7

La scienza di costruire software affidabile nel "mondo reale" è ancora in fase di sviluppo ed è in qualche misura al limite di uno studio intrinsecamente culturale o antropologico, perché computer e software non "causano" bug - gli umani! questa risposta si concentrerà su approcci Q / A generali di cui la verifica formale del software può essere vista come un elemento.

un'osservazione notevole è che spesso un software "abbastanza buono" ma "buggy" può spesso essere venduto meglio del software meglio testato ma con funzionalità inferiori sul mercato. in altre parole, il mercato non pone sempre un premio alla qualità del software e le moderne tecniche di ingegneria del software, che non sempre enfatizzano la qualità, riflettono in qualche modo questo. inoltre la qualità può spesso aggiungere una spesa significativa al prodotto finale. con questi avvertimenti, ecco alcune delle basi:

  • sistemi ridondanti / tolleranti ai guasti. questa è una vasta area di studio. la tolleranza agli errori e la ridondanza possono essere progettate nei molti strati di un sistema. ad esempio un router, un server, un'unità disco, eccetera.

  • test . tutti i tipi: test di unità, test di integrazione, test di accettazione dell'utente, test di regressione, ecc.

  • al giorno d'oggi i test automatici tramite suite di test che possono essere eseguiti incustoditi sono più sviluppati / importanti. le suite di test in esecuzione sono spesso associate allo strumento di creazione.

  • un concetto importante nei test è la copertura del codice . cioè quale codice viene esercitato dal test. un test non trova un bug nel codice che non viene "toccato" dal test.

  • un altro concetto chiave nei test è l' imbracatura di prova del codice di esercizio a cui non è possibile accedere direttamente direttamente.

  • i test dovrebbero esercitare tutti i livelli del software. se il software è ben modulare, questo non è difficile. test di livello superiore dovrebbero penetrare profondamente nel codice. i test che esercitano grandi quantità di codice con una configurazione di test ridotta aumentano la "leva del test" .

  • rendere il codice il meno complicato possibile è importante per i test. i test dovrebbero essere presi in considerazione nella progettazione dell'architettura. spesso ci sono diversi modi per implementare la stessa funzionalità, ma alcuni hanno implicazioni molto diverse per la copertura / leva del test. per ogni ramo del codice, spesso è un altro caso di test. i rami all'interno dei rami si intensificano all'aumento esponenziale dei percorsi del codice. quindi evitare logiche condizionate / nidificate migliora la capacità di testare.

  • lo studio di errori software (enormi) famosi di cui esistono molti esempi e casi studio è utile per comprendere la storia e sviluppare una mentalità orientata verso considerazioni di qualità.

  • si può lasciarsi trasportare dai test! c'è sia un problema con test troppo piccoli o troppo . c'è un "punto debole". il software non può essere costruito con successo in nessuno dei due estremi.

  • utilizzare tutti gli strumenti di base nel modo più efficace. debugger, profiler di codice, strumenti di copertura del codice di test, sistema di tracciamento dei difetti, ecc. non impegnarsi necessariamente a risolvere, ma traccia anche i più piccoli difetti nel software di monitoraggio.

  • l'uso attento di SCM, gestione del codice sorgente e tecniche di ramificazione è importante per evitare regressioni, isolare e far progredire le correzioni, ecc.

  • Programmazione versione N : una pratica spesso utilizzata per lo sviluppo di software Mission Critical. La premessa di questa pratica è che è improbabile che N programmi sviluppati indipendentemente abbiano lo stesso bug / errore comune. Questo è stato criticato in alcuni articoli . NVP è, tuttavia, una pratica non un concetto teorico.

Credo che il fisico Feynman abbia una qualche spiegazione del metodo usato dalla NASA per garantire l'affidabilità dei sistemi di navetta spaziale nel suo libro "Cosa ti importa di quello che pensano gli altri?" - ha detto che avevano due squadre, affermano che la squadra A e la squadra B. hanno costruito il software. il team B ha adottato un approccio contraddittorio nei confronti del team A e ha cercato di rompere il software.

aiuta se il Team B ha un buon background di ingegneria del software, cioè se stessi possono scrivere cablaggio di codice / test programmatici eccetera. in quel caso il Team B aveva quasi lo stesso livello di risorse del Team A. D'altra parte, questo approccio è costoso perché può quasi raddoppiare il costo di costruzione del software. più in genere, esiste un team di controllo qualità più piccolo rispetto al team di sviluppo.


8
Qualcuno dovrebbe verificare la correttezza del sistema operativo rispetto alla specifica che premendo il tasto Maiusc e una lettera produce una lettera maiuscola.
Andrej Bauer,

1
addendum: i vincoli di pianificazione possono influire sulla qualità. vedi anche il triangolo del progetto mgt composto da portata, costo, pianificazione con qualità dell '"area" interessata da tutti 3. vedi anche "Perché il settore IT non può realizzare rapidamente progetti di grandi dimensioni e senza errori come in altri settori?" . non ho aggiunto l'elemento N-Version [la sua altra risposta coperta] ma nota che Feynman ha detto che la NASA lo ha usato anche nel design dello space shuttle.
vzn,


1
un altro caso di studio interessante è il Mars Rover che ha grandi quantità di codice, in gran parte autogenerato. in quel caso i precedenti rover hanno testato la maggior parte del software e sono stati riutilizzati.
vzn

6

Un vecchio approccio (ma è ancora usato in alcune applicazioni) è la programmazione della versione N

Da Wikipedia:

La programmazione N-version ( NVP ), nota anche come programmazione multiversione , è un metodo o processo nell'ingegneria del software in cui più programmi funzionalmente equivalenti sono generati indipendentemente dalle stesse specifiche iniziali. Il concetto di programmazione in versione N è stato introdotto nel 1977 da Liming Chen e Algirdas Avizienis con la congettura centrale secondo cui "l'indipendenza degli sforzi di programmazione ridurrà notevolmente la probabilità che si verifichino guasti software identici in due o più versioni del programma". di NVP è quello di migliorare l'affidabilità del funzionamento del software creando tolleranza di errore o ridondanza.
....

Vedi ad esempio: " Sfide nell'errore di costruzione - Sistema di controllo di volo tollerante per un aereo civile "


Vale la pena notare che la programmazione della versione n non funziona . L'ipotesi fondamentale - vale a dire che gli errori nelle ripetute prove del processo di sviluppo del software sono indipendenti - è completamente falsa . Questa idea non ha senso teoricamente (un algoritmo difficile da implementare non sarà magicamente più facile per un secondo team indipendente), ed è stato anche sfatato sperimentalmente: l'esperimento di John Knight e Nancy Leveson mostra che l'assunto di indipendenza non è statisticamente valido è uno dei documenti più famosi nell'ingegneria del software.
Neel Krishnaswami,

@NeelKrishnaswami: sono d'accordo! Tuttavia penso che (ma non sono un esperto) che non funziona dovrebbe essere sostituito con esso non migliora l'affidabilità di quanto dovrebbe se confrontato con altri approcci . Citando K&L: " ... Non abbiamo mai suggerito che il nostro risultato dovrebbe essere usato da solo come base per una decisione sull'efficacia della programmazione in versione N. Abbiamo semplicemente suggerito che la cautela sarebbe appropriata ... ". Penso che il dibattito su quanto l'approccio NVP possa essere utile per la progettazione di sistemi critici sia ancora aperto (vedi il recente lavoro di Khoury et al.)
Marzio De Biasi,

4

Fajrian, questa domanda che hai posto riguarda due dei maggiori problemi nella ricerca dell'ingegnere del software: la conformità tra le specifiche e il modello e tra il modello e il codice. Modella qui una rappresentazione di ciò che farà il sistema o di come sarà fatto, ci sono molti livelli per modellare un sistema.

Quindi, ci sono alcune persone che cercano di trovare la risposta migliore alla tua domanda. Perché è molto difficile verificare la correttezza di un software basato su un modello, ad esempio usando metodi formali. So che JML è un modo per farlo, ma non conosco i limiti del suo utilizzo.

Per concludere, come è difficile fare la verifica della correttezza del codice, le persone cercano di mescolare metodi formali e test, creando test automaticamente dalle specifiche, ad esempio. Un esempio per i sistemi in tempo reale è il TIOSTS basato su eventi temporizzati di input / output.

Il solo test non è un approccio metodico formale, ma migliora l'affidabilità ma non verifica la correttezza.


3

Due o tre anni fa ho iniziato a dare un'occhiata ai metodi formali applicati al software. Questa era una ricerca guidata dalla curiosità e dalla sensazione che dovevo imparare strumenti e metodi di programmazione con intervalli di tempo più lunghi. Anche se ho sognato volentieri un proiettile d'argento , ho davvero pensato che non ci fosse una risposta alla domanda: "Come posso scrivere un programma corretto?".

A questo punto della ricerca dopo aver provato alcuni strumenti (Z, B, VHDL ed Estelle), sto usando TLA + . Questa è una variante della logica temporale con strumenti software per il controllo del modello e prove meccaniche. Penso di aver scelto questo approccio perché L. Lamport era alla base, la sintassi era semplice, c'erano molti esempi, c'era una comunità che se ne occupava e il linguaggio e gli strumenti erano abbastanza ben documentati.

Per quanto riguarda la mia domanda iniziale, penso che non ci sia una risposta completa. Tuttavia, vale la pena imparare che è utile specificare formalmente alcune parti di un sistema. È anche abbastanza utile decodificare alcuni di quelli complessi. Cioè, è efficace creare un progetto per le parti difficili e critiche. Tuttavia, non credo che esista un metodo efficace per tradurre automaticamente le specifiche in un linguaggio di programmazione o in un framework (a meno che non si limiti il ​​progetto a un ambiente molto specifico). Inoltre, non credo che avere una specifica formale dovrebbe impedirti di testare il software.

In poche parole, penso che la seguente metafora (da Lamport) sia davvero potente: "Ti aspetti che una casa venga costruita automaticamente da un progetto? Comprerai una casa che non è ancora stata costruita e non ha un progetto?" .

Durante questa ricerca, ho trovato utili le seguenti risorse:

  • Metodi di specifica del software . Questo libro offre un'ampia panoramica dei metodi e degli strumenti esistenti. Qui puoi trovare spiegazioni di base ed esempi di Z, SDL, TLA +, reti di Petri, Coq, ecc.
  • Se ritieni che TLA + soddisfi le tue esigenze, consiglio vivamente il libro Specification Systems . Puoi ottenere il libro gratuitamente e viene fornito con esempi con cui giocare :).
  • Di recente, ho letto un paio di articoli correlati che danno due diverse prospettive allo stato dell'arte dei metodi formali: il caso dei metodi formali e la matematica formalmente verificata .

In bocca al lupo!


1

Le risposte finora coprivano già la maggior parte di ciò che si dovrebbe dire sulle basi di come collegare le specifiche e il codice tra loro. Voglio solo aggiungere un punto più pratico che affronta la domanda nell'intestazione di questo thread:

Come creare software mission critical?

Esistono strumenti che analizzano automaticamente il tuo codice per errori (violazioni delle specifiche o "bug tipici"). Per quanto ne sappia, questi metodi si basano principalmente sull'analisi statica e non sono immediatamente correlati alle teorie che hai citato (LTL / CTL / ...), ma trovano errori nel codice reale ed è già fattibile, da un punto pratico di visualizzare, per utilizzare tali strumenti in progetti industriali. Personalmente non ne ho usati molti, ma sembra che questi strumenti inizino ad essere accettati dai professionisti. Per ulteriori letture, posso raccomandare il seguente articolo di blog:

http://www.altdevblogaday.com/2011/12/24/static-code-analysis/


implementazione di esempio con java,
apache

0

Gli algoritmi di certificazione possono essere utili per la creazione di software mission-critical.

Un algoritmo di certificazione è un algoritmo che produce, con ogni output, un certificato o testimone (prova di facile verifica) che il risultato specifico non è stato compromesso da un bug.

Maggiori informazioni in questo documento di indagine Algoritmi di certificazione di McConnell, RM e Mehlhorn, K. e Naher, S. e Schweitzer, P.


Nel 1998, Pnueli, Siegel e Singerman descrissero questa idea applicata ai compilatori, sotto il nome di validazione della traduzione. I compilatori sono intrinsecamente di ordine superiore (l'input è un programma, l'output è un programma), quindi tendono ad essere difficili da verificare. Ma ci sono persone pazze come X. Leroy che sviluppano compilatori verificati comunque. (Pazzo nel miglior senso possibile!)
Radu GRIGore,

-2

Ma allora come verificare che il software (non solo le specifiche) sia effettivamente corretto?

Test unitari? Scrivi un test per ogni singolo requisito nella specifica, quindi verifica ogni singolo metodo nella tua implementazione per vedere che il suo output / input è conforme a detta specifica. Questo può essere automatizzato in modo che questi test vengano eseguiti continuamente per garantire che nessuna modifica interrompa mai le funzionalità precedentemente funzionanti.

Teoricamente parlando, se i tuoi test unitari hanno una copertura del codice del 100% (cioè ogni singolo metodo nel tuo codice è testato) il tuo software dovrebbe essere corretto, a condizione che i test stessi siano accurati e realistici.


5
Per qualsiasi programma ragionevolmente complesso, la copertura del codice (mediante test) non può garantire la correttezza. Dovresti coprire tutte le possibili esecuzioni; tutte le righe di codice non sono sufficienti.
Radu GRIGore,

1
La copertura del codice è un concetto troppo vago. Distinguiamo tra, ad esempio copertura del metodo, copertura delle dichiarazioni, copertura delle filiali, copertura del percorso e così via. Come sottolinea Radu, per i programmi non banali, i test si imbattono spesso in esplosioni combinatorie. Detto questo, il software aeronautico ha una notevole esperienza, e la sua correttezza si basa spesso su test approfonditi.
Martin Berger,

Se intendete testare con strumenti come JUnit, questo tipo di test automatico standard non può coprire tutti i casi (a meno che il programma non sia estremamente piccolo). Per un'applicazione tipica, questo tipo di test è in genere sufficiente. Ma per un'applicazione mission-critical, non so se sia abbastanza (o no).
fajrian,

2
@vzn: Nella mia esperienza, c'è un notevole accordo tra ciò che è considerato un bug dagli accademici e, rispettivamente, dai professionisti. Inoltre, scommetto che la maggior parte dei miei (ex) colleghi del settore concorderebbe sul fatto che "ogni singolo metodo nel tuo codice è testato" non sembra molto rassicurante. (E, no, non ho votato a fondo. Non lo faccio quasi mai.)
Radu GRIGore,

1
@vzn: Ho detto che hai detto diversamente? Stavo semplicemente cercando di spiegare perché credo che gli altri non stiano votando questa risposta. Al momento non posso rispondere a questa domanda, perché non la capisco.
Radu GRIGore,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.