Correção de Software com
Verificação de Modelos
Aline Maria Santos Andrade
Departamento de Ciência da Computação (DCC) Laboratório de Sistemas Distribuídos (LaSiD)
Sumário
• Motivação
• Correção de Software
• Conceito de Métodos Formais
• Técnicas de Verificação Formal
• Verificação de Modelos
– Conceitos
Engenharia? de Software
• Não existe um modelo universalmente aceito para desenvolver software
• As técnicas utilizadas normalmente são derivadas de uma abordagem informal adotada no processo, não incluem teorias e formalismos essenciais a um desenvolvimento científico
• Ambientes (ferramentas) existentes em geral não
possuem uma fundamentação teórica. Difícil garantir a confiabilidade dos software
• Certificação e garantia?
Engenharia de Software
• Incorporou novos paradigmas e metodologias ⇒ sistematização do processo de desenvolvimento ⇒ melhoria da confiabilidade do software produzido.
• Embora os processos sistemáticos de desenvolvimento de software aumentem o grau de confiabilidade, a validação de software é feita de maneira informal ou semi formal e não garantem com precisão que o software atende aos requisitos desejados.
• Em sistemas que envolvem riscos, como sistema de monitoração de pacientes, controle de tráfego aéreo, etc é necessário um processo de validação mais seguro de maneira que possamos garantir a correção do software gerado.
O que são métodos formais
• Utilização de modelos matemáticos para
representar o sistema
• Métodos matemáticos de prova para verificação
Adicionar precisão, auxiliar no entendimento
e raciocinar sobre propriedades de um projeto
Engenharia
Pode ser comparado à forma com que cálculo estrutural é usado no projeto de construções, mecânica computacional de fluídos é usada no projeto de aeronaves, etc
Certificação
/
Garantia!
Validação de Software
• Simulação
• Teste
Aplicação
Requisitos
Máquina Virtual
C on fi ab ili da deEspecificação i
i = 0 i= i+1 Refinamento Formal =>Verificação Formal => Correção
Não Formal => Testes => Confiável Testes Testes / Simulação / Verificação Confiável / Correta
Aline Maria Santos Andrade ([email protected])
Verificação
• Um passo de verificação pode cobrir todo possível
comportamento do sistema
• Verificação antes da implementação diminui o
custo $$ !!
• É especialmente importante quando o
comportamento é complexo.
Especificação formal
• Linguagem formal
• Verificação
• Refinamento
• Geração automática de código
• Propriedades desejadas
– consistência
– correção
– completude
Desenvolvimento formal de
software
• Especificação formal do problema
– B, Z, VDM, CSP, LOTOS, Pi-Calculus, SPIN,
SMV, UPPAAL ...
• Validação
– Simulação
– Verificação
– Refinamento
– Geração automática de código
Sequencial
Concorrente
Distribuído
Móvel
×
Transformacional
×
Reativo
Tipos de Sistemas
Requisitos
• Sistemas
seqüenciais
– funcionalidade• Sistemas
concorrentes
– concorrência – funcionalidade• Sistemas Reativos
– necessitam interagir com o ambiente
frequentemente e frequentemente não terminam. Portanto, não podem ser modelados pelo seu
comportamento de entrada/saída.
Técnicas de verificação
formal
• Provadores de teoremas
– Provam propriedades em uma teoria sobre
o sistema
• Verificadores de modelos (Model
checking)
– Verificam se certas propriedades valem em
um modelo da aplicação
– Sistemas de estados finitos
• As abordagens se complementam
Provador de Teoremas
• Especificar:
– O sistema (em algum nível adequado de abstração) – Propriedades requeridas do sistema
– Suposições (restrições de ambiente, usuário, etc) – Teorias sobre os tipos de dados envolvidos
• Provar:
– Teorias + Suposições + Sistema |-- Requisitos
• Variação:
– Provar que a implementação é um refinamento da especificação
• Funciona melhor em sistemas com intenso tratamento de
dados
Verificador de Modelos
• Especificar
– Modelo do sistema
• Estrutura de Kripke
– Propriedades em uma linguagem lógica
• Lógica temporal
• Provar que as propriedades são válidas no modelo do sistema
modelo do sistema |= propriedades
– Algoritmo faz varredura no modelo do sistema (sistema de transição)
Estrutura de Kripke
• Estado - é uma descrição instantânea do sistema que captura os valores das variáveis em um particular
instante de tempo.
• Transições entre estados representam as ações do sistema.
• Estrutura de Kripke - conjunto de estados, conjunto de transições entre estados e uma função que rotula cada estado com um conjunto de propriedades que são
verdadeiras naquele estado.
Verificação de Modelos
Dado uma estrutura de Kripke M = (S,R,L)
que representa um sistema concorrente e
uma fórmula na lógica temporal f que
expressa alguma especificação desejada,
encontre todos os estados em S que
satisfaz f:
{s ∈ S | M, s |= f}
Verificação de modelos
• Estados
– definidos pelas variáveis do sistema, que
assumem valores dentro de um conjunto
finito de valores
• Um componente do sistema
– modelo de Kripke ----> sistema de
transição
• Vários componentes
– produto síncrono (ou assíncrono) do
sistema de transição de cada componente
Kripke estendida (guardas)
(Máquina de estados finita)
3 2 C 1 C=true/act1 act2 ev1 ev2
3
2c
2
c
c
c
act2 act21
ev2 act1 ev2 ev1 3 2c 2ccc act2 act2 3 1 ev2 act1 3 ev2 3 ev1 3 2c 2ccc act2 act2 3 1 ev2 act1 3 ev2 3 ev1 3 2c 2ccc act2 act2 3 1 ev2 act1 3 ev2 3 ev1
Sistema de transição
(unfolding da estrutura de Kripke)
Produto síncrono / assíncrono
• Combinar os modelos dos componentes
do sistema ---> autômato global
– Produto cartesiano dos autômatos
representando os componentes (estado
global é um vetor construído a partir dos
diferentes estados dos componentes)
– Componentes se sincronizam ---> produto
síncrono ---> subconjunto de transições do
produto cartesiano definido através de um
conjunto de sincronização
Produto assíncrono
3 1 2 1 2 X = 1 1 2 2 1 3 2 3 2 1 1 2 Explosão de estados !!!Otimizações
• Explosão de estados ocorre quando se resolve
representar em memória todos os estados do autômato
• Symbolic Model Checking
– representa estados e transições
simbolicamente ao invés de explicitamente
– BDD - Diagrama de decisões binárias
utilizados para representar simbolicamente
conjunto de estados de um autômato
Um Programa de Exclusão Mútua
P0 :: l0: While True do NC0 : wait(turn = 0) CR0 : turn := 1; end while; l’0 P1 :: l1: While True do NC1 : wait(turn = 1) CR1 : turn := 0; end while; l’1P = m: cobegin P
0|| P
1coend m’
S
0(V,PC) ≡ pc = m ∧ pc
0= ⊥ ∧ pc
1= ⊥
Nenhuma restrição é imposta ao valor de turn
Turn =0 ⊥,⊥ Turn =0 l0,l1 Turn =0 l0,NC1 Turn =0NC0,l1 Turn =0 NC0,NC1 Turn =0 CR0,NC1 Turn =0 CR0,l1 Turn =1 ⊥,⊥ Turn =1 l0,l1 Turn =1 l0,NC1 Turn =1NC0,l1 Turn =1 l0,CR1 Turn =1 NC0,CR1 Turn =1 NC0,NC1
Estados alcançáveis da estrutura de Kripke para o exemplo de exclusão mútua
Garantido exclusão mútua. Não garante ausência de starvation.
Verificação de Modelos
• Usualmente não há necessidade de teorias auxiliares
• Normalmente, as únicas suposições dizem respeito
às propriedades dinâmicas do sistema (safety,
fairness, liveness)
• Funciona melhor com sistemas voltados ao controle
e com um pequeno espaço de estados
Lógica temporal
• Operadores modais de tempo
–
(G) sempre
– (F) em algum tempo futuro
• Relativos a mundos possíveis (estrutura
de kripke)
Mundos Possíveis
(
Kripke
)
- A verdade de uma proposição é verificada em relação a um mundo.
- Os mundos estão relacionados ao tempo (lógica temporal)
- Mundos podem ser vistos como estados locais/globais.
- Estrutura ramificada, ou, linear de tempo. (obs: ¬ P ≡
P
P
P
)
P P,Q Q Q , QQQ P,Q P,Q P,Q Q Q , P P PP P,Q Q Q , QQQ P,Q P,Q P,Q Q Q , P P, Q , PPP P,Q P,Q P PP,Q , P P,Q P,Q P,Q , P P ≡ Sempre P
Fonte: Prof E. H. Haeusler - PUC-Rio
EP P PP,Q Q Q , PPP P,Q P PP,Q P PP,Q Q Q ,EP P PP,Q Q Q , PPP P PP,Q P PP,Q P PP,Q Q Q , PPP EP ≡ Eventualmente P ≡ ◊P
Lógicas temporais
• Lógica temporal ramificada (CTL
-Computational Tree Logic)
– CTL apresenta quantificação sobre caminhos e sobre estados
• AG(p) : p é verdade em todo estado ao longo de cada caminho
• AF(p) : p é verdade em algum estado ao longo de cada caminho
• EG(p) : p é verdade em todo estado ao longo de algum caminho
• EF(p) : p é verdade em algum estado ao longo de algum caminho
• Lógica temporal linear (LTL)
Gp
GFp
FGp
p
p
p
p
p
¬p
p
p
p
¬p
¬p
p
p
p
p
AGp
AGAFp
Não existe
CTL
LTL
p
¬p
¬p
p
p
p
Fp
¬p
AFp
Sistemas concorrentes
• Safety - algo ruim nunca acontece
– ausência de deadlock – exclusão mútua
– sempre a resposta dada é correta
• Liveness - algo bom acontece
– se um processo solicita um recurso eventualmente ele será atendido
– se uma resposta é solicitada então ela será fornecida
enter
code checkcode
unlock door delay count attempts sound alarm valid code/count = 0 invalid code/ code entered timeout count = = 3 /count = 0
Alarme de Cofre
count ++- Verificando
AG(enter_code & valid_code ===> AF(unlock_door)) resulta em verdade
- Verificando
AG(enter_code ===> AF(unlock_door))
resulta no seguinte caminho de computação como contra-exemplo
enter code check code count attempts 3 times sound alarm enter code check code count attempts 3 times
SPIN
• Ferramenta para analisar a consistência lógica
de sistemas concorrentes, especialmente
protocolos de comunicação de dados. (free)
• Linguagem Promela
– Permite criação dinâmica de processos concorrentes – Comunicação via canal pode ser síncrona ou
assíncrona
SPIN
• Dado um modelo do sistema especificado
em Promela, SPIN pode fazer:
– simulações
– verificação online de propriedades de correção
do sistema
– verificação de ausência de deadlocks, código
não executável, etc
– verificação de propriedades de correção
(safety e liveness) expressas em lógica
temporal linear (LTL)
– On the Fly Model Checking
Verificação
On the fly
• A propriedade verificada é traduzida em
um autômato
• Este autômato é utilizado para guiar a
criação do grafo de transição de
estados (modelo do sistema)
• Isto evita a necessidade de se construir
grandes pedaços ou todo o grafo de
Autômatos Finitos Sobre
Palavras Infinitas
• Em muitos sistemas concorrentes a
computação não pára durante uma execução
normal
• Nestes casos, a computação é modelada
como uma sequência infinita de estados
• Estas computações podem ser representadas
através de autômatos finitos sobre palavras
infinitas
Autômatos Büchi
• Um autômato Büchi tem a mesma estrutura
que um autômato sobre palavras finitas
• Estados finais são chamados de estados de
aceitação
• Considere inf(ρ) como o conjunto de estados
que aparecem infinitamente freqüentemente
em uma execução ρ
• Uma execução ρ de um autômato Büchi sobre
uma palavra infinita é aceita se e somente se
inf(ρ) ∩ F ≠ ∅
Exemplo
Se interpretamos o grafo acima como um
autômato Büchi, a linguagem aceita será:
– (b*a)ω
– a palavra (ab)* (sequência infinita de a’s e b’s alternando, começando por a) é aceita
a
b
b
a
Verificação de Modelos
usando Autômatos
• Autômatos finitos podem ser usados
para modelar sistemas concorrentes de
execução infinita
• Uma vantagem de se utilizar autômatos
para verificação de modelos é a
possibilidade de usar a mesma forma
de representação para o sistema
s
0Convertendo estruturas
Kripkes em autômatos
s
0s
1s
2{p,q}
{p}
{q}
s
1s
2i
{p,q}
{p,q}
{p,q}
{q}
{p}
{p}
Turn =0 ⊥,⊥ Turn =0 l0,l1 Turn =0 l0,NC1 Turn =0NC0,l1 Turn =0 NC0,NC1 Turn =0 CR0,NC1 Turn =0 CR0,l1 Turn =1 ⊥,⊥ Turn =1 l0,l1 Turn =1 l0,NC1 Turn =1NC0,l1 Turn =1 l0,CR1 Turn =1 NC0,CR1 Turn =1 NC0,NC1
Estados alcançáveis da estrutura de Kripke para o exemplo de exclusão mútua
1
2
4
6
7
5
3
i
1 2 4 3 6 5 Turn=1, ⊥, ⊥ Turn=0, ⊥, ⊥ Turn=0, CR0, l1 Turn=1, NC0, l1 Turn=1, l0 ,l1 7 Turn=1, l0 , NC1 Turn=1, l0 , l1 Turn=1, NC0, l1Especificações como
autômatos
• Considere L(A) a linguagem do autômato
A que representa a estrutura kripke
• A especificação pode ser dada como um
autômato S sobre o mesmo alfabeto de A
Exemplo de Especificação
como Autômato
(CR
0∧ CR
1)
¬(CR
0∧ CR
1)
true
CR
0¬CR
0true
Exclusão mútua
Liveness: o processo P
0entrará na região crítica
Verificação de Modelos
usando Autômatos
• Considere L(A) a linguagem do
autômato A que representa a estrutura
kripke
• Considere L(S) a linguagem do
autômato que representa a
especificação S
• O sistema A satisfaz S quando:
– L(A) ⊆ L(S)
Algoritmo de Verificação de
Modelos
• O sistema modelado é convertido em um
autômato Büchi A
• O autômato Büchi S’ é gerado a partir da
negação da especificação
ϕ
• Se a interseção A ∩ S’ é vazia a
especificação é satisfeita
Algoritmo de Verificação de
Modelos
On the Fly
• Constrói-se inicialmente o autômato de S’
• Este autômato é usado para
dinamicamente guiar a construção do
autômato do sistema A, ao mesmo tempo
em que a interseção é computada
• Desta forma é possível encontrar um
contra-exemplo ou garantir a
satisfatibilidade sem precisar construir
todo autômato A
Promela
• PROMELA (PROcedural MEta LAnguage) é
uma linguagem de especificação cuja
sintaxe é baseada em:
– C
– CSP (canais para troca de mensagens)
– Comandos Guardados (controle de fluxo)
• Não determinismo
– Utilizada pelo SPIN para especificação do sistema
– Permite abstrações de protocolos (ou sistemas
distribuídos em geral) suprimindo detalhes que
não são relacionados para a interação entre
Promela
• Programas em Promela consistem de:
– Processos - são objetos globais que especificam
comportamento
– Canais e variáveis - podem ser declaradas
globalmente ou localmente dentro de um
processo; canais podem ser síncronos ou
assíncronos. Definem o ambiente em que o
processo executa.
Problema dos filósofos
• 5 filósofos
• Uma mesa circular com 5 cadeiras rotuladas cada uma com o nome do filósofo
• À esquerda de cada filósofo tem um garfo e no meio da mesa uma tigela de macarrão, que é constantemente preenchida
• Para comer o macarrão, o filósofo pega o garfo da esquerda e depois o da direita
• Após o filósofo comer o macarrão, ele deve deitar os dois garfos na mesa
chan garfo[5] = [0] of {mtype}; mtype = {wait, signal};
proctype filosofo(int id){ pensando:
do
::skip -> faminto:
garfo[id]?wait; /*tenta adquirir garfo da esquerda fica bloqueado caso o garfo tenha sido adquirido*/
deadlock: garfo[(id+1)%5]?wait; /*tenta adquirir garfo da direita*/ comendo: skip;
garfo[id]!signal; /*cede garfo da esquerda*/ garfo[(id+1)%5]!signal; /*cede garfo da direita*/
od }
proctype Garfo(int id){ do
:: garfo[id]!wait -> garfo[id]?signal
od }
init{ atomic{ run filosofo(0); run filosofo(1); run filosofo(2); run filosofo(3); run filosofo(4); run Garfo(0); run Garfo(1); run Garfo(2); run Garfo(3); run Garfo(4); } }
#define f1 (filosofo[1]@deadlock) #define f2 (filosofo[2]@deadlock) #define f3 (filosofo[3]@deadlock) #define f4 (filosofo[4]@deadlock) #define f5 (filosofo[5]@deadlock) /*
* Formula As Typed: <> (f1 && f2 && f3 && f4 && f5) */
never { /* (<> (f1 && f2 && f3 && f4 && f5)) */ ... pan: claim violated! (at depth 550)
....
A verificação aponta um erro indicando que a propriedade não é mantida, ou seja, existe a possibilidade do sistema entrar em deadlock. O Spin salva a seqüência na qual o erro foi detectado em arquivo .trail. É possível, então, realizar uma simulação desta seqüência na tentativa de identificar as possíveis causas para a violação da propriedade.
Extensão de Promela
• Extensão de Promela para especificar
sistemas de agentes móveis
– trabalho realizado no LaSiD/UFBA
• Permite a utilização do ambiente SPIN
para a simulação e verificação de
Ferramentas
• UPPAAL
– Verificador de modelos para sistemas de
tempo real
– Especificação: autômato com tempo
– Lógica temporal: dialeto de CTL
• Outras ferramentas
– SMV
– KRONOS
– HYTECH
• Explosão do foguete Ariadne (projeto europeu) poucos segundos após seu lançamento devido a falha de programação.
• Sistema de triagem/controle de bagagem do aeroporto internacional de Denver (EUA) atrasou a inauguração do aeroporto. Custo do
sistema (193 milhões $$ )
– Inauguração estava prevista para Out/1993
– Em Junho/1994 o sistema ainda não estava funcionando, mas custava $$ !!
– No começo de 1995 um controle MANUAL de bagagem foi instalado para que o aeroporto pudesse ser inaugurado (com atraso de mais de um ano).
• O Therac-25, um equipamento de radioterapia controlado por
computador, aplicou doses fatais de radiação em alguns pacientes de câncer.
• Quando decidiram testar o subsistema de desligamento de
emergência da Sizewell-B, uma usina nuclear na Inglaterra, este falhou em mais de 50% das vezes. Não conseguiram encontrar a razão da falha nas 100.000 linhas de código.