Tutorial de Uppaal

Joel Silva Carvalho e Simão Melo de Sousa

      Universidade da Beira Interior

          16 de Março...
Conteúdo

1   Introdução                                                                                                  ...
3   Casos de Estudo                                                                                                       ...
Capítulo 1

Introdução

Este tutorial descreve o Uppaal como ferramenta de Model Checking para sistemas de
tempo real. O U...
Inclusivamente no desenvolvimento de sistemas críticos é recomendável utilizar-se
mais do que uma ferramenta de verificação...
Capítulo 2

Uppaal

2.1     Introdução
O Uppaal consiste numa aplicação cliente/servidor. O cliente (java) consiste numa
i...
2.2.3    Variáveis inteiras limitadas
Quando uma variável inteira é declarada o seu intervalo deve ser definido, no entanto...
feita apenas entre duas transições. Neste tipo de canal a existência de uma transição
emissora implica a existência de uma...
Associado a estes formatos de ficheiros existe ainda o formato .q com a especi-
ficação das propriedades que se pretendem ve...
Figura 2.2: Interface de modelação do Uppaal com o exemplo train-gate.




2.3.3      Edges
A cada transição entre dois es...
Figura 2.3: Janela de propriedades de um Edge.




Sync
Outra forma de fazer evoluir os autómatos de forma "programada"é r...
Figura 2.4: Janela de propriedades de uma Location.




Name
Cada estado possui idealmente (mas não obrigatoriamente) um n...
2.4     Simulação
A simulação não é um processo fundamental para a verificação de modelos no entanto
torna-se útil e intuit...
2.5     Verificação
A verificação de modelos é um processo automatizado por algoritmos que permitem
confirmar que dadas propr...
que nunca estão abertas simultaneamente duas portas.

    Em Uppaal as propriedades de segurança são expressas de forma po...
Figura 2.6: Interface de verificação do Uppaal.




                     15
Capítulo 3

Casos de Estudo

Como casos de estudo são apresentados os modelos de dois algoritmos de exclusão
mútua, mais p...
Figura 3.1: Process(const int pid) do modelo do algoritmo de Dekker.




  Figura 3.2: P(const int pid) do modelo do algor...
P1 = P r o c e s s ( 1 ) ;

/ / Edit system d e f i n i t i o n .
s y s t e m P0 , P1 ;

Listing 3.2: Declaração dos proce...
acesso à zona crítica.

    No caso do outro processo não requerer acesso à zona crítica a execução do pro-
cesso corrente...
tema. A simulação destes dois modelos permite verificar se a sua execução retrata o
comportamento desejado dos algoritmos. ...
Figura 3.4: Simulação do modelo do algoritmo de Peterson.




    Na segunda verifica-se que em todas as execuções possívei...
Figura 3.5: Terminologia do Biphase Mark Protocol.




3.2.2   Modelo
A Figura 3.6 representa a arquitectura do modelo Upp...
• [W ire()] (Figura 3.11) - Modelação do processo de transformação da onda quadrada
     (dita perfeita) num sinal digital...
Figura 3.7: Clock().                 Figura 3.8: Clock2().




Figura 3.9: Coder().

                                     ...
Coder()
O Coder() começa por permanecer no estado inicial enquanto a sincronização get?
não for invocada, sendo o estado i...
Tester()
Este autómato selecciona não deterministicamente bits e coloca-os na variável in, pos-
teriormente confirma se os ...
Capítulo 4

Exercícios

Neste capítulo apresentam-se alguns exercícios a resolver com a ferramenta de veri-
ficação de mode...
Figura 4.1: Esquema das componentes do protocolo.




nem o emissor do atraso. O sistema modela-se com uma rede de autómat...
4.3   Resoluções




                   29
4.3.1    Exercício 1
Para este exercício apresentam-se duas resoluções ligeiramente distintas. Numa as
sincronizações são ...
Figura 4.3: Modelo com sincronizações urgentes.




                      31
gentes não provoca alterações nos modelos.No caso contrário o mesmo poderia já não
se verificar, excepto se os estados inte...
De seguida só é possível executar a transição que volta a por o autómato Emis-
sor no estado P ronto. Existe uma guarda ne...
Figura 4.4: Meio do modelo com sincronizações não urgentes.




  Figura 4.5: Meio do modelo com sincronizações urgentes.
...
condição se verificar primeiro que a sincronização que segue o outro ramo.

    Em termos de verificação as duas soluções se...
Referências

[1] http://www.ita.cs.ru.nl/publications/papers/fvaan/
    MCinEdu/mutex.html.
[2] http://www.it.uu.se/edu/co...
Apêndice A

TA e XTA BNF

Informação retirada da página pessoal do Professor Gerd Behrmann. Esta sintaxe
assemelha-se à da...
OldTransBody : : = ’ { ’ [ < OldGuard > ] [ < Sync > ] [ < A s s i g n > ] ’ } ’

OldGuard : : = ’ g u a r d ’ < E x p r e...
I n i t i a l i s e r : : = <Expression >
    |     ’{ ’ < F i e l d I n i t > ( ’ , ’ < F i e l d I n i t > )∗ ’} ’
F i e...
|    <Expression >     <Rel > < E x p r e s s i o n >
   |    <Expression >     <BinIntOp > < Expression >
   |    <Expres...
Upcoming SlideShare
Loading in …5
×

Tutorial de Uppaal

1,684 views

Published on

Published in: Education
  • Be the first to comment

Tutorial de Uppaal

  1. 1. Tutorial de Uppaal Joel Silva Carvalho e Simão Melo de Sousa Universidade da Beira Interior 16 de Março de 2009
  2. 2. Conteúdo 1 Introdução 3 1.1 Objectivo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Motivação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.3 Limitações . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.4 Organização do documento . . . . . . . . . . . . . . . . . . . . . . . 4 2 Uppaal 5 2.1 Introdução . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2 Autómatos Temporizados e Extensões . . . . . . . . . . . . . . . . . 5 2.2.1 Modelos . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.2 Constantes . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 2.2.3 Variáveis inteiras limitadas . . . . . . . . . . . . . . . . . . . 6 2.2.4 Matrizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2.5 Funções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2.6 Posições urgentes . . . . . . . . . . . . . . . . . . . . . . . . 6 2.2.7 Posições committed . . . . . . . . . . . . . . . . . . . . . . 6 2.2.8 Sincronizações por mensagem . . . . . . . . . . . . . . . . . 6 2.3 Modelação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2.3.1 Especificação Textual . . . . . . . . . . . . . . . . . . . . . . 7 2.3.2 Especificação Gráfica . . . . . . . . . . . . . . . . . . . . . . 8 2.3.3 Edges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.3.4 Locations . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2.4 Simulação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.5 Verificação . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.5.1 Correspondências TCTL em Uppaal . . . . . . . . . . . . . . 13 2.5.2 Reachability . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.5.3 Safety . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.5.4 Liveness . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 2.5.5 Deadlock Freeness . . . . . . . . . . . . . . . . . . . . . . . 14 2.5.6 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1
  3. 3. 3 Casos de Estudo 16 3.1 Algoritmos de Dekker e Peterson . . . . . . . . . . . . . . . . . . . . 16 3.1.1 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.1.2 Modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.1.3 Simulação . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 3.1.4 Verificação . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 3.2 Biphase Mark Protocol . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.2.1 Descrição . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 3.2.2 Modelo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.2.3 Verificação . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 4 Exercícios 27 4.1 Exercício 1 - Protocolo v1 . . . . . . . . . . . . . . . . . . . . . . . 27 4.2 Exercício 2 - Protocolo v2 . . . . . . . . . . . . . . . . . . . . . . . 28 4.3 Resoluções . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 4.3.1 Exercício 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 4.3.2 Exercício 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 A TA e XTA BNF 37 2
  4. 4. Capítulo 1 Introdução Este tutorial descreve o Uppaal como ferramenta de Model Checking para sistemas de tempo real. O Uppaal surgiu em 1995 pela universidade de [Upp]sala e pela univer- sidade de [Aal]borg. Esta ferramenta permite manipular três fases da elaboração do modelo do sistema. Na primeira fase o Uppaal permite a modelação do modelo, na se- gunda fase permite a realização de simulações sobre a execução do modelo e na terceira fase permite a verificação do modelo. A combinação destas três fases permite que as equipas de desenvolvimento adquiram algumas garantias sobre o modelo construído. Isto fornece maior segurança para a realização das fases seguintes do desenvolvimento. A evolução do Uppaal tem sido considerável existindo hoje uma panóplia de ferra- mentas auxiliares. Estas ferramentas merecem o seu destaque no entanto não no âmbito deste tutorial. Para mais informações sobre este assunto recomenda-se a consulta da página oficial do Uppaal em http://www.uppaal.com. 1.1 Objectivo Este tutorial serve como documento de iniciação à utilização do UPPAAL, quer no con- texto académico como empresarial, sintetizando alguma informação necessária para a sua correcta e eficiente utilização. 1.2 Motivação Grande parte dos sistemas de tempo real são considerados críticos e como tal exigem cuidados acrescidos no desenvolvimento. Por exemplo, reforçando a importância da fase de testes é possível reduzir o número de erros. No entanto os testes não são sufi- cientes porque não fornecem certezas, apenas reduzem o espaço de incerteza. Torna- se evidente que as ferramentas de verificação representam uma mais-valia podendo fornecer certezas. 3
  5. 5. Inclusivamente no desenvolvimento de sistemas críticos é recomendável utilizar-se mais do que uma ferramenta de verificação. No caso específico dos sistemas de tempo real críticos é possível ver a combinação de ferramentas de verificação estática como o SPARK com ferramentas de verificação de modelos como o Uppaal[6]. Diferentes tipos de ferramentas complementam-se e permitem a verificação de um maior número de propriedades. 1.3 Limitações A modelação e verificação de sistemas com a ajuda de ferramentas como o Uppaal possuem todavia algumas limitações. Nomeadamente porque aquilo que se verifica é o modelo e não o sistema em si. O modelo necessita espelhar correctamente o que o sistema representa para além de ser fundamental identificar e definir adequadamente as propriedades por verificar. De facto nada se pode afirmar sobre propriedades omissas. 1.4 Organização do documento Cap. 2 - Uppaal Introdução e descrição de aspectos funcionais do Uppaal, quer no que respeita à modelação, como à simulação e à verificação. Juntamente são apresen- tados alguns conceitos teóricos pertinentes. Cap. 3 - Casos de Estudo Descrição de dois casos de estudo relacionados com algoritmos de exclusão mútua e descrição de um caso mais concreto de um protocolo utilizado na indústria. Cap. 4 - Exercícios Enunciado e resolução de exercícios práticos a realizar em Up- paal para testar a compreensão da ferramenta. 4
  6. 6. Capítulo 2 Uppaal 2.1 Introdução O Uppaal consiste numa aplicação cliente/servidor. O cliente (java) consiste numa interface gráfica com um editor, um simulador e um verificador. Este cliente java co- munica com um servidor (C++) que é nada mais do que o verificador de modelos (verifyta). Assim existem duas formas de verificar um modelo, uma é recorrendo à aplicação gráfica Uppaal outra é recorrendo directamente à aplicação verifyta. As referências principais para este capítulo são [5][8][3]. 2.2 Autómatos Temporizados e Extensões O Uppaal utiliza e estende as redes de autómatos temporizados para especificar o mod- elo do sistema. De seguida apresentam-se alguns conceitos sobre autómatos tempo- rizados em Uppaal e sobre as extensões introduzidas. 2.2.1 Modelos No Uppaal os modelos (templates) são a representação individual de cada autómato, opcionalmente com parâmetros. Os parâmetros são um conjunto de declarações de qualquer tipo de variáveis existente no Uppaal e servem essencialmente para gener- alizar a especificação dos autómatos. 2.2.2 Constantes As constantes são declaradas com a palavra reservada const seguida do tipo e uma inicialização, por exemplo: const int i = 2. Uma constante não pode ser modificada ao longo da execução. 5
  7. 7. 2.2.3 Variáveis inteiras limitadas Quando uma variável inteira é declarada o seu intervalo deve ser definido, no entanto se isso não for feito é assumido um valor por defeito (-32768 e 32767). 2.2.4 Matrizes No Uppaal também é possível definir matrizes de tipos de dados simples. A declaração deste novo tipo é feita recorrendo aos típicos parênteses rectos, por exemplo: int i[12]. 2.2.5 Funções O Uppaal permite definir e utilizar funções sintacticamente parecidas com a linguagem C. Estas funções são importantes nas transições onde é necessário realizar operações mais complexas, um exemplo muito simples de uma declaração de função é bool teste(int a)return (a>2);. 2.2.6 Posições urgentes Uma posição identificada como urgente permite que os relógios locais a esse autómato não evoluam enquanto essa posição for mantida. 2.2.7 Posições committed Uma posição committed para além de funcionar analogamente à anterior ela ainda obriga que a próxima transição tenha origem nesta posição. A utilização deste tipo de posição entrou em desuso com a introdução das sincronizações múltiplas (ver 2.2.8), uma vez que esta era uma forma de simular as sincronizações múltiplas utilizando apenas sincronizações binárias. 2.2.8 Sincronizações por mensagem Existem dois tipos de sincronizações possíveis, o primeiro utiliza variáveis globais e o segundo utiliza canais de sincronização (sincronização por mensagem). Esta secção aborda este último tipo de sincronização que é utilizado ao nível das transições. Uma transição com sincronização precisa de pelo menos uma transição emissora, talvez uma ou mais transições receptoras e pelo menos um canal de sincronização. O autómato que pretende comunicar envia o pedido de sincronização recorrendo à etiqueta !, antecedida do nome do canal de sincronização, e o autómato receptor aguarda essa sincronização com a etiqueta ?, antecedida do mesmo nome. Canais binários Os canais de sincronização em Uppaal são declarados recorrendo à palavra reservada chan. Estes canais são considerados binários uma vez que a acção de sincronização é 6
  8. 8. feita apenas entre duas transições. Neste tipo de canal a existência de uma transição emissora implica a existência de uma transição receptora. Canais múltiplos Apesar das sincronizações tradicionais serem binárias é possível definir sincroniza- ções de uma transição para um número arbitrário de transições recorrendo aos canais de sincronização broadcast chan. Neste tipo de canal a existência de uma transição emissora não implica a existência de uma transição receptora, mas obviamente que sem a existência de pelo menos uma transição emissora a sincronização nunca ocorre na realidade. Canais urgentes Qualquer um dos tipos de canais anteriormente referidos ainda pode ser considerdo ur- gente recorrendo à palavra reservada urgent, por exemplo urgentbroadcastchana;. Isto obriga que as transições que usem este tipo de sincronizações não utilizem re- strições de tempo, ou seja não contemplem guardas sobre relógios. 2.3 Modelação A modelação de um sistema em Uppaal pode ser feita de duas formas distintas, tex- tualmente ou graficamente. Ambas as formas possuem vantagens e desvantagens. Por exemplo, a especificação gráfica torna-se bastante intuitiva mas muito mais complexa de automatizar. Ao contrário, a especificação textual permite ser automatizada, mas requer um profundo conhecimento da linguagem. 2.3.1 Especificação Textual O Uppaal permite a leitura de três tipos de ficheiros, no entanto a versão actual já só permite gravar no formato mais recente. O formato mais antigo consiste num ficheiro de texto plano de extensão .ta com a especificação da rede de autómatos temporizados. Neste formato cada autómato é definido por process seguido do nome, mas estes não são equivalentes aos templates anteriormente falados. A partir da versão 3.0 foi introduzido o formato .xta, muito semelhante ao .ta e neste cada process corresponde realmente a um template com parâmetros. O formato .xta permite ainda ser associado a um outro ficheiro .ugi que contém as coordenadas x e y dos objectos. Na versão 3.2 foi introduzido o formato .xml. A expressividade deste tipo de ficheiro é semelhante ao .xta mas aqui os elementos são descritos recorrendo a tags. Este formato é hoje utilizado nativamente pela interface gráfica e possui como grande vantagem a possibilidade de conseguir gravar modelos sintacticamente mal definidos para posterior correcção. No apêndice A é apresentado a sintaxe no formato BNF para os ficheiros .xta e .ta. 7
  9. 9. Associado a estes formatos de ficheiros existe ainda o formato .q com a especi- ficação das propriedades que se pretendem verificar. Este formato é uma mera lista textual das propriedades, para mais informações consultar a secção 2.5. 2.3.2 Especificação Gráfica A especificação gráfica consiste na produção do modelo por intermédio do separador editor disponível na interface gráfica do Uppaal. Esta interface de modelação (ver Figura 2.1) é constituída por três zonas distintas. A zona superior da interface inclui o menu da aplicação, alguns ícones de atalho e os separadores de navegação entre os diferentes modos de visualização (edição/simulação/verificação). Figura 2.1: Interface de modelação do Uppaal. Na zona inferior esquerda consta uma estrutura de opções que permite mudar entre as diferentes partes descritivas do modelo. A opção Declarations contém a especifi- cação das variáveis globais do modelo (variáveis inteiras, canais de sincronização, reló- gios e constantes). A opção T emplate representa um autómato temporizado do mod- elo que por sua vez pode ter declarações locais. Por fim a opção System declarations contém a declaração dos processos com a devida atribuição de parâmetros. Na zona inferior direita consta uma área de trabalho que pode ser constituída por texto, no caso de uma das opções de declaração estar seleccionada, ou por uma repre- sentação gráfica de um autómato, no caso de algum template estar seleccionado. 8
  10. 10. Figura 2.2: Interface de modelação do Uppaal com o exemplo train-gate. 2.3.3 Edges A cada transição entre dois estados de um autómato temporizado corresponde um edge no Uppaal. Na figura 2.3 é apresentada a janela de edição de uma transição com algu- mas opções preenchidas. Select O parâmetro select permite atribuir um valor a uma variável temporária (apenas válida para essa transição), dado um intervalo, de forma não determinista. Um exemplo de declaração possível para um select é i : int[0, 3]. Esta declaração permite que o i receba um valor entre 0 e 3 (inclusive) e que seja utilizado nas declarações das restantes opções da transição. Guard O parâmetro guard serve para activar a transição sobre uma dada condição. Um exem- plo de declaração de uma guarda é x >= 4. Considerando x como sendo um relógio, esta condição permite que a transição seja activada quando tiverem passado pelo menos quatro unidades de tempo no relógio x. 9
  11. 11. Figura 2.3: Janela de propriedades de um Edge. Sync Outra forma de fazer evoluir os autómatos de forma "programada"é recorrendo aos canais de sincronização. Com este parâmetro é possível invocar ou activar uma ou mais transições utilizando um canal de sincronização previamente definido (ver 2.2.8). Sem- pre que numa transição o parâmetro sync tiver uma declaração semelhante à seguinte c1! significa que, pelo menos um outro autómato vai necessitar de uma transição semel- hante a c1?. A utilização da etiqueta ! pode ser vista como um envio e a etiqueta ? como uma recepção. Update O parâmetro update serve para actualizar variáveis globais ou locais, um exemplo de declaração é x = 0. Considerando este x como sendo um relógio, esta declaração per- mite reinicializar o relógio o que é prática bastante comum na modelação de sistemas temporizados com Uppaal. O update também pode incluir a utilização de funções ou até mesmo servir para invocar uma função que não devolve nenhum valor mas que altera variáveis locais ou globais. Caso a função invocada não tenha um impacto no estado do sistema a mesma torna-se inútil e é gerado um warning aquando da verifi- cação sintáctica do modelo. 2.3.4 Locations A cada estado de um autómato temporizado corresponde uma location no Uppaal. Na figura 2.4 é apresentada a janela de edição de um estado com algumas opções preenchidas. 10
  12. 12. Figura 2.4: Janela de propriedades de uma Location. Name Cada estado possui idealmente (mas não obrigatoriamente) um nome que serve de iden- tificador para a linguagem de especificação do modelo e para a linguagem de especifi- cação de propriedades. Caso o nome seja definido o mesmo deve estar em conformi- dade com ambas as linguagens. Por exemplo um nome não pode começar por um valor numérico. Invariant Os invariantes surgem da teoria dos autómatos temporizados e são propriedades asso- ciadas aos estados. Quando um invariante I é associado ao estado P , então P tem de verificar necessariamente I quando o mesmo tem o controlo. Quando I deixa de ser verificado P tem de deixar o controlo, isto é, uma transição deve ser executada. No Uppaal, os estados que violem o seu invariante são indefinidos, por definição estes es- tados não existem. Nesta ferramenta os invariantes são expressões limitadas a conjunções de condições simples sobre relógios, diferenças entre relógios e expressões booleanas que não en- volvem relógios. Quando um invariante envolve a comparação do valor de um relógio com um inteiro não é permitido verificar se o tempo é maior do que o inteiro ou es- tritamente igual, por exemplo a > 4 ou a == 4. Assim apenas é possível utilizar expressões como a < 4 ou a <= 4. Initial/Urgent/Committed Estas opções são activadas com meras selecções na interface. Cada autómato tem obrigatoriamente de possuir um único estado inicial. Mais informações sobre as outras duass opções na secção 2.2.6 e 2.2.7. 11
  13. 13. 2.4 Simulação A simulação não é um processo fundamental para a verificação de modelos no entanto torna-se útil e intuitiva para uma avaliação eficiente aquando da construção do modelo. Dada a especificidade dos modelos é possível recorrer à simulação para realizar ajustes e correcções. Inclusivamente com o problema da explosão de estados pode acontecer que um modelo complexo não seja facilmente verificável. Neste tipo de situações a simulação torna-se ainda mais importante. Interface O simulador do Uppaal permite três modos de funcionamento distintos. No primeiro o utilizador executa a simulação passo a passo sendo livre de escolher a transição que pretende fazer. No segundo o utilizador executa a simulação de forma automática e aleatória podendo controlar a velocidade de simulação. No terceiro o utilizador pode percorrer execuções anteriormente realizadas. Cada um destes modos de funciona- mento pode ser intercalado a qualquer momento dando ao simulador toda a sua flexi- bilidade. Como é possível constatar na figura 2.5 a interface do simulador é composta por diversas janelas. Na janela mais à esquerda é possível controlar os modos de execução do simulador. Na janela logo à direita são listadas todas as variáveis do sistema. Na janela inferior direita são apresentadas as sincronizações entre os diferentes autómatos bem como os estados activos. Na janela logo acima desta são apresentados todos os autómatos e a vermelho as transições e estados activos. Figura 2.5: Interface de simulação do Uppaal. 12
  14. 14. 2.5 Verificação A verificação de modelos é um processo automatizado por algoritmos que permitem confirmar que dadas propriedades estão presentes na representação feita do sistema. Estando a verificação de modelos baseados em autómatos temporizados associada a lógicas temporais, torna-se necessário classificar os diferentes tipos de propriedades. O Uppaal recorre a uma fracção da lógica TCTL não permitindo por exemplo a combinação de múltiplos quantificadores de caminho. 2.5.1 Correspondências TCTL em Uppaal Correspondências entre a Lógica TCTL e a especificação em Uppaal. • A - Todos os caminhos(A em Uppaal). • E - Existe um caminho (E em Uppaal). • G - Todos os estados num caminho ([] em Uppaal). • F - Algum estado num caminho (<> em Uppaal). 2.5.2 Reachability As propriedades de acessibilidade são aquelas que permitem especificar que uma situ- ação pode ser atingida. Sendo ϕ uma fórmula de estado, a especificação desta pro- priedade faz-se recorrendo ao quantificador E e ao combinador F : EF ϕ. Por outras palavras, diz-se que seguindo uma das execuções, ϕ pode ser verificado. Por exemplo num sistema de controlo de acessos, esta propriedade permite validar que existem sempre condições para que a porta se abra. Em Uppaal as propriedades de acessibilidade são expressas da seguinte forma: E <> ϕ. 2.5.3 Safety As propriedades de segurança são aquelas que permitem especificar que algo negativo nunca vai acontecer. Este tipo de propriedades pode limitar-se a uma execução ou abranger o conjunto de todas as execuções possíveis. Sendo ϕ uma fórmula de estado, a especificação desta propriedade faz-se recorrendo quer ao quantificador E como ao quantificador A e ao combinador G: AG¬ϕ ou EG¬ϕ. Este tipo de propriedades é fundamental para garantir situações críticas num mod- elo. Recorrendo ao exemplo de um sistema de controlo de acessos com fecho au- tomático de portas, esta propriedade permite validar que uma porta nunca fica aberta mais de x unidades de tempo. Ou no caso de existirem várias portas, como nos bancos, 13
  15. 15. que nunca estão abertas simultaneamente duas portas. Em Uppaal as propriedades de segurança são expressas de forma positiva: A[]ϕ ou E[]ϕ. Sendo que na primeira especificação (com o quantificador universal A) ϕ é obri- gatoriamente verdade em todos os estados. Enquanto na segunda (com o quantificador existencial E) ϕ é verdade em todos os estados de uma execução possível. De notar que as restantes propriedades podem ser traduzidas em propriedades destes dois últimos tipos via técnicas conhecidas. 2.5.4 Liveness As propriedades de evolução permitem especificar que dentro de determinadas condições algo inevitavelmente vai acontecer. Recorrendo ao exemplo de um sistema de controlo de acessos, esta propriedade permite validar que quando alguém é identificado inevitavelmente uma porta vai abrir. Em Uppal estas propriedades são expressas da seguinte forma: A <> ϕ ou ϕ−− > ψ. Sendo que a primeira especificação significa que ϕ é inevitavelmente verdade nal- gum estado de todas as execuções. E a segunda significa que sempre que ϕ for verdade então ψ também vai ser verdade nalgum estado de todas as execuções seguintes. 2.5.5 Deadlock Freeness Por fim a propriedade de ausência de deadlock permite especificar que o sistema não entra numa situação da qual não consiga sair. Em Uppal esta propriedade é expressa da seguinte forma: A[] not deadlock. 2.5.6 Interface A interface de verificação possui uma lista de propriedades que pode ser seleccionada e aumentada ou reduzida. Cada propriedade possui uma declaração (query), um texto associado que é facultativo (comment) e um objecto que representa a propriedade na lista. Quando uma prioridade é avaliada a mesma fica com o indicador a verde ou vermelho. O verde significa que a propriedade foi correctamente verificada pelo algo- ritmo de verificação de modelos enquanto o vermelho significa o contrário. Sempre que uma propriedade não é verificada o Uppaal permite construir um contra-exemplo que fica exposto no ambiente de simulação. No entanto esse contra-exemplo não é construído por defeito. Para que isso seja feito é necessário ir ao menu Options > DiagnosticT race e escolher uma das três opções Some, Shortest ou F astest. 14
  16. 16. Figura 2.6: Interface de verificação do Uppaal. 15
  17. 17. Capítulo 3 Casos de Estudo Como casos de estudo são apresentados os modelos de dois algoritmos de exclusão mútua, mais precisamente o algoritmo de Dekker e de Peterson. Estes algoritmos não possuem qualquer restrição temporal, no entanto pela sua simplicidade tornam-se bons exemplos para iniciar uma apresentação concreta sobre Uppaal. Como terceiro caso de estudo é apresentado o modelo do Biphase Mark Protocol. Trata-se de um caso mais completo com diversas restrições temporais e mais de trinta propriedades especificadas e verificadas. As referências principais para este capítulo são [7][1][9]. 3.1 Algoritmos de Dekker e Peterson 3.1.1 Descrição Estes algoritmos permitem que dois processos partilhem um recurso conjunto recor- rendo apenas à memória partilhada. O primeiro algoritmo foi definido em 1964 por T. J. Dekker e o segundo em 1981 por G. Peterson. 3.1.2 Modelo Na Figura 3.1 é apresentado o único template do modelo do algoritmo de Dekker tal como na Figura 3.2 para o modelo do algoritmo de Peterson. Ambos os modelos possuem a particularidade de serem constituídos por dois autómatos (representando os processos consumidores) que são nada mais do que uma declaração duplicada do template de cada um com alteração dos respectivos parâmetros de entrada (ver Listing 3.1 e Listing 3.2). Listing 3.1: Declaração dos processos de sistema do modelo do algoritmo de Dekker. / / Insert process assignments . P0 = P r o c e s s ( 0 ) ; 16
  18. 18. Figura 3.1: Process(const int pid) do modelo do algoritmo de Dekker. Figura 3.2: P(const int pid) do modelo do algoritmo de Peterson. 17
  19. 19. P1 = P r o c e s s ( 1 ) ; / / Edit system d e f i n i t i o n . s y s t e m P0 , P1 ; Listing 3.2: Declaração dos processos de sistema do modelo do algoritmo de Peterson. P0 = P ( 0 ) ; P1 = P ( 1 ) ; s y s t e m P0 , P1 ; Os dois modelos utilizam também algumas variáveis globais (ver Listing 3.3 e List- ing 3.4) para permitir que a exclusão mútua seja devidamente realizada. A ausência de canais de sincronização entre os autómatos justifica-se pela vontade de representar fiel- mente os algoritmos. Listing 3.3: Declaração das variáveis globais do modelo do algoritmo de Dekker. bool f l a g [2] = { false , f a l s e }; int turn = 1; No caso do algoritmo de Dekker é declarada uma matriz booleana f lag de dois el- ementos, inicializados a f alse, e uma variável inteira turn, inicializada a 1. A variável f lag indica a intenção dos processos entrarem na zona crítica e a variável turn indica qual dos processos possui prioridade para aceder à zona crítica. Listing 3.4: Declaração das variáveis globais do modelo do algoritmo de Peterson. const int N = 2; i n t [ 0 , 1 ] f l a g [N ] ; int [0 ,1] turn ; À semelhança do caso do algoritmo de Peterson é declarada uma constante inteira N , inicializada com o valor 2, uma matriz de inteiros f lag de N elementos limitados aos valores 0 e 1 e uma variável inteira turn. As variáveis inteiras que não são ini- cializadas assumem por defeito o valor 0 ou o valor do limite inferior caso elas tenham um limite definido na sua declaração. A constante N define o tamanho da matriz f lag enquanto as duas restantes variáveis assumem a função descrita no caso do algoritmo de Dekker. De notar ainda que no autómato a matriz de inteiros é actualizada com valores booleanos em vez de valores inteiros. À semelhança do que acontece em C, o Uppaal assume valores inteiros para cada uma das expressões booleanas true (1) e f alse (0). Observando detalhadamente o modelo do algoritmo de Dekker (Figura 3.1) verifica- se que o mesmo inicia a sua execução actualizando a f lag do processo corrente para true (Update f lag[pid] = true) indicando a intenção de aceder à zona crítica. No estado seguinte existem duas execuções possíveis (Guard f lag[1 − pid] == true e Guard f lag[1 − pid] == f alse) consoante o outro processo esteja ou não a pedir 18
  20. 20. acesso à zona crítica. No caso do outro processo não requerer acesso à zona crítica a execução do pro- cesso corrente entra directamente na zona crítica (estado critical_section) e efectua duas actualizações seguidas (Update turn = 1 − pid e Update f lag[pid] = f alse) voltando ao estado inicial remainder. A actualização turn = 1 − pid indica que o outro processo ganha prioridade e a actualização f lag[pid] = f alse remove a indi- cação de acesso à zona crítica por parte do processo corrente. No caso do outro processo estar a pedir acesso à zona crítica são avaliadas mais duas guardas turn == pid, turn == 1 − pid. Estas permitem verificar qual dos pro- cessos possui prioridade no acesso à zona crítica. Caso a prioridade esteja do lado do processo corrente então o modelo volta a avaliar a f lag do outro processo. Caso con- trário a f lag do processo corrente é alterada para f alse (Update f lag[pid] = f alse) e a execução seguinte fica avaliar as guardas turn == 1 − pid, turn == pid. Estas guardas estão numa posição do ramo diferente no entanto são uma repetição das anteriores com uma ligeira nuance, desta vez não existe transição de estado en- quanto o outro processo tiver prioridade de acesso à zona crítica. Assim que o processo corrente ganhe prioridade no acesso à zona crítica então é feita uma nova actualização f lag[pid] = true para indicar a intenção de acesso à zona crítica e o modelo volta a avaliar se existem condições para que o acesso seja feito. Observando detalhadamente o modelo do algoritmo de Peterson (Figura 3.2) verifica- se algo semelhante. Partindo do estado inicial a execução do modelo começa por fazer duas actualizações de variáveis. A primeira f lag[pid] = true indica a intenção do processo corrente ter acesso à zona crítica e a segunda turn = 1 − pid dá prioridade de acesso ao outro processo. No estado seguinte existem duas guardas que verificam se f lag[1 − pid] é f alse ou true. Se o outro processo não indicou intenção de aceder à zona crítica (Guard f lag[1 − pid] == f alse) então o modelo entra na zona crítica (estado cs). Posteriormente a execução volta ao estado inicial actualizando a intenção do processo corrente em não pretender aceder à zona crítica (Update f lag[pid] = f alse). Se em contrapartida o outro processo indicou intenção de aceder à zona crítica (Guard f lag[1 − pid] == true) então o modelo realiza uma segunda verificação mas desta vez sobre a variável turn. Se a prioridade de acesso à zona crítica for do outro processo turn == 1 − pid então o modelo volta ao estado anterior para nova avaliação caso contrário turn == pid o modelo continua a sua execução para a zona crítica (estado cs) e posteriormente volta ao estado inicial tal como anteriormente descrito. 3.1.3 Simulação No modo de simulação do Uppaal é possível verificar que ambos os modelos possuem dois processos designados por P0 e P1, tal como foi descrito nas declarações de sis- 19
  21. 21. tema. A simulação destes dois modelos permite verificar se a sua execução retrata o comportamento desejado dos algoritmos. Apesar de aqui não existir uma relação for- mal entre os modelos e o respectivo algoritmo de exclusão mútua é possível, mesmo assim, tirar algumas conclusões sobre o seu funcionamento. Algo especialmente interessante para este tipo de problemas é o de poder verificar visualmente e das formas já descritas se o modelo realmente está a fazer aquilo que se pretende. Esta metodologia pode inclusivamente ser utilizada para introduzir estes con- ceitos de uma forma bastante prática. Programando estes algoritmos numa linguagem "não formal", não existe a possibilidade de visualizar directamente ou verificar formal- mente possíveis problemas. Neste tipo de simulação o mesmo já não acontece. É muito intuitivo perceber que o modelo avalia as variáveis descritas e consoante os seus valores o acesso à zona crítica é dada a um ou outro processo. Inclusivamente é possível verificar a validade de algumas propriedades do modelo tal como vai ser visto na secção seguinte. Figura 3.3: Simulação do modelo do algoritmo de Dekker. 3.1.4 Verificação A verificação destes dois modelos consiste na verificação de duas propriedades. Na primeira verifica-se, como é de costume, se existe ou não deadlock freeness recorrendo à seguinte especificação A[]notdeadlock. Executando a verificação desta propriedade no Uppaal verifica-se que realmente ambos os modelos a cumprem. 20
  22. 22. Figura 3.4: Simulação do modelo do algoritmo de Peterson. Na segunda verifica-se que em todas as execuções possíveis o modelo nunca está simultaneamente na zona crítica dos dois processos. Essa especificação de propriedade de segurança faz-se em Uppaal com a seguinte fórmula A[] (not (P 0.cs and P 1.cs)). 3.2 Biphase Mark Protocol 3.2.1 Descrição Como terceiro caso de estudo apresenta-se o modelo do Biphase Mark Protocol. Este protocolo é largamente utilizado especialmente para comunicação ao nível físico da arquitectura OSI. O mesmo encontra-se implementado em micro controladores como o Intel 82530 Serial Communications Controler. Resumidamente neste protocolo cada bit de uma mensagem é codificado numa célula que consiste num número de ciclos do relógio divido logicamente numa mark subcell e numa code subcell. Tal como se pode ver na Figura 3.5 sempre que estas duas subcells formarem um par de sinais iguais (1 e 1 ou 0 e 0) o bit da mensagem corre- spondente é 0, sempre que o par de sinais for diferente (1 e 0 ou 0 e 1) então o bit da mensagem corresponde é 1. A grande vantagem deste protocolo é que a sincronização dos relógios do codificador e do descodificador é feita no início de cada célula. 21
  23. 23. Figura 3.5: Terminologia do Biphase Mark Protocol. 3.2.2 Modelo A Figura 3.6 representa a arquitectura do modelo Uppaal deste protocolo. Este modelo é constituído por 7 autómatos temporizados (representados na figura por rectângulos) que comunicam quer por variáveis globais (representadas por círculos) como por sin- cronizações (representadas por setas). Figura 3.6: Arquitectura do modelo do BMP. De forma sucinta descreve-se de seguida a funcionalidade de cada um dos autó- matos: • [Clock()] (Figura 3.7) - Modelação lógica do relógio físico do sistema do lado do codificador. Este autómato produz tick’s, não confundir com as variáveis de relógio do Uppaal. • [Coder()] (Figura 3.9) - Modelação do processo de codificação. Através de uma sequência de bits (variável in) e dos tick’s do relógio (do autómato Clock()) gera-se uma onda quadrada. 22
  24. 24. • [W ire()] (Figura 3.11) - Modelação do processo de transformação da onda quadrada (dita perfeita) num sinal digital. • [Clock2()] (Figura 3.8) - Semelhante ao Clock() mas desta vez para o descodi- ficador. • [Sampler()] (Figura 3.12) - Modelação do processo de cópia periódica do valor de w para new. • [Decoder()] (Figura 3.10) - Modelação do processo de descodificação. Aquando de um novo tick se este autómato observar uma alteração da variável new ele começa a contagem de um número específico de tick’s e compara o valor inicial da variável new com o seu valor final. De seguida actualiza a variável out e informa o T ester() da actualização através da sincronização put. • [T ester()] (Figura 3.13) - Modelação do ambiente. Este autómato representa a última componente do modelo no entanto não faz parte integrante do protocolo. Neste modelo não existem declarações de variáveis locais nem existem parâmetros nos templates criados. Assim a declaração do sistema (ver Listing 3.6) resume-se à invocação de cada template e todos os canais de sincronização e variáveis utilizadas são globais (ver Listing 3.5). Listing 3.5: Declaração das variáveis globais do modelo do BMP. / / Global Declar ations c h a n t i c k , t o c k , edge , g e t , p u t ; b r o a d c a s t c h a n f u z z , s e t t l e , Sample ; i n t m, n ; b o o l i n , o u t , v , w, s , new , o l d , b u f ; clock x , y , z ; c o n s t i n t c e l l =14 , mark =7 , s a m p l e = 1 0 ; c o n s t i n t min =93 , max =100 , e d g e l e n g t h = 1 0 0 ; Listing 3.6: Declaração de sistema do modelo do BMP. s y s t e m Coder , Clock , Wire , Sampler , Clock2 , Decoder , T e s t e r ; Clock() e Clock2() Tanto o Clock() como o Clock2() são compostos por um único estado e uma transição. Ambos utilizam variáveis de relógio distintas (x e y respectivamente) reinicializadas a cada tick. Cada um destes autómatos possui um invariante que controla o tempo durante o qual podem permanecer no estado inicial sem produzir um tick. Ambos possuem uma guarda que activa a respectiva transição apenas quando a mesma for verdade. Deste modo o Clock() só produz um tick entre as 93 e as 100 unidades de tempo tal como o Clock2(), mas este último ainda precisa que a variável s tenha o valor true (1). Esta variável serve para que o Sampler() apenas seja executado uma vez por cada tick do Clock2(). 23
  25. 25. Figura 3.7: Clock(). Figura 3.8: Clock2(). Figura 3.9: Coder(). Figura 3.10: Decoder(). Figura 3.11: Wire(). Figura 3.12: Sam- pler(). Figura 3.13: Tester(). 24
  26. 26. Coder() O Coder() começa por permanecer no estado inicial enquanto a sincronização get? não for invocada, sendo o estado inicial urgente o tempo não evolui. Assim que o Tester() efectuar a sincronização get! o Coder() transita para o estado C1 (também ele urgente) e consoante o valor do bit transmitido seja 1 ou 0 a respectiva transição é efectuada gerando imediatamente uma nova aresta da onda quadrada. Se o bit for 1 o autómato fica no estado C2 durante 6 tick’s do Clock(), a transição para o estado C4 corresponde a mais um tick e então é gerada uma nova aresta da onda quadrada. O processo volta-se a repetir de forma análoga até ser gerada outra aresta ao 14o tick (contando do ínicio). Se em contrapartida o bit for 0 o autómato passa directamente para o estado C3 gerando uma aresta na transiçao e ao 14o tick do Clock() gera outra ao voltando ao estado inicial. Wire() Este autómato introduz o pressuposto que indica que um sinal eléctrico só estabiliza após algum tempo da ocorrência de uma aresta da onda quadrada. Assim considera-se que no estado W 0 o sinal é estável enquanto no estado W 1 não. Para os parâmetros que permitem que o protocolo esteja correcto é fundamental que o Coder() nunca gere uma nova aresta enquanto o sinal é instável, isto é, enquanto o Wire() se encontre no estado W 1. No caso de ser gerada uma nova aresta sobre estas condições então o Wire() passa ao estado W 2. No entanto a verificação do modelo vai provar que esta situação nunca ocorre. Sampler() Este autómato apenas possui um estado e uma transição responsável por copiar o valor do sinal w para a variável new utilizada como variável de entrada pelo Decoder(). Para garantir que apenas é copiado um valor por cada tick do Clock2()é utilizada uma variável booleana s. Decoder() O Decoder() modela o processo de descodificação do sinal recolhido pelo Sampler(). De forma análoga ao Coder() este autómato rege a sua execução por tick’s, mas desta feita do Clock2(). No estado inicial cada tick é responsável pela comparação do valor recolhido do Sampler() com o valor anterior. Enquanto os valores forem iguais o pro- cesso de comparação repete-se. Assim que for detectada uma variação no sinal o autó- mato passa para o estado D1 armazenando o último valor recolhido. A execução vai manter-se no estado D1 enquanto não passarem um número de tick’s iguais ao valor da variável sample. Quando for efectuada a transição para o estado D2 é novamente avaliado se o valor do sinal recolhido naquele momento pelo Sampler() é o mesmo do que o inicial para permitir gerar o bit correspondente. Isto é, se os valores forem diferentes o bit gerado vai ser 1 caso contrário 0. Quando a execução voltar ao estado inicial é efectuada a sincronização put! para informar o Tester() de que um novo bit foi gerado. 25
  27. 27. Tester() Este autómato selecciona não deterministicamente bits e coloca-os na variável in, pos- teriormente confirma se os bits recebidos através da variável out correspondem aos anteriores. Sempre que for observada uma diferença nos valores o autómato entra num estado de erro. Se o modelo estiver correcto esse estado nunca é atingido. 3.2.3 Verificação Das 39 propriedades especificadas para este modelo descrevem-se apenas as seguintes: • A[] Coder.C0 imply Tester.T0 - Sempre que o Coder está no estado inicial isso implica que o Tester também se encontre no seu estado inicial. • A[] not (Tester.T2 or Tester.T3 or Tester.Error) - Para qualquer execução o Tester nunca atinge o estado T2, T3 ou Error. Esta verificação acaba por ser redundante com a de deadlock freeness porque em ambas as situações se esses estados são atingidos o modelo entra em deadlock. • A[] Coder.C0 or Coder.C1 imply n == 0 - Sempre que o estado C0 ou C1 do Coder é o estado corrente então a variável n tem de ser igual a 0. Isto é, o contador de tick’s tem de estar reinicializado. • A[] Decoder.D0 imply m == 0 - Sempre que o Decoder está no estado D0 então a variável m tem de ser igual a 0. Análogo ao anterior. • A[] y >= 0 and y <= Max - O relógio y está sempre compreendido entre 0 e Max. Isto é, em nenhuma situação o tick do Clock2 ultrapassa o valor de Max. • A[] Coder.C1 or Coder.C2 or Coder.C4 imply Tester.T1 - Sempre que o Coder está num outro estado que não o C0 ou o C3 então o Tester está obrigatoriamente no estado T1. • A[] not Wire.W2 - O estado W2 do coder nunca é atingido. Isto garante que o modelo nunca produz uma nova aresta da onda quadrada enquanto o Wire está na posição W1 (de sinal instável). 26
  28. 28. Capítulo 4 Exercícios Neste capítulo apresentam-se alguns exercícios a resolver com a ferramenta de veri- ficação de modelos Uppaal. Estes exercícios contemplam quer a modelação, como a simulação e a verificação dos modelos. No fim do capítulo encontram-se resoluções para os exercícios propostos. No entanto é vivamente recomendado que essas res- oluções só sejam consultadas no fim dos exercícios estarem resolvidos. As referências principais para este capítulo são [2][4]. 4.1 Exercício 1 - Protocolo v1 Num contexto de comunicação, o mais simplista possível, é sugerida a implementação de um protocolo com três componentes interligadas: emissor, meio e receptor (ver Figura 4.1). • O emissor transmite uma mensagem de tamanho fixo. Esse tamanho corre- sponde ao tempo entre o início do envio e o fim do envio da mensagem. • O meio corresponde à componente central responsável pela passagem da men- sagem do emissor para o receptor. Este meio introduz um atraso fixo na comu- nicação que corresponde ao tempo entre o início do envio por parte do emissor e o início da recepção por parte do receptor ou o fim do envio por parte do emissor e o fim da recepção por parte do receptor. • O receptor recepciona a mensagem vinda do meio de comunicação. Nesta primeira versão parte-se do princípio que o tamanho é menor que o atraso (tamanho < atraso), i.e. o meio só transmite a mensagem para o receptor depois do envio (por parte do emissor) ter sido finalizado. É recomendada a utilização de constantes inteiras para o tamanho e para o atraso. O meio não deve, nesta primeira versão, ter conhecimento do tamanho da mensagem, 27
  29. 29. Figura 4.1: Esquema das componentes do protocolo. nem o emissor do atraso. O sistema modela-se com uma rede de autómatos sin- cronizados, utilizando o início e fim de comunicação do emissor e do receptor como sincronizações com o meio. Pretende-se ainda que o modelo seja verificado garantido a não existência de dead- lock’s e identificando qual o tempo decorrido do início do envio até ao fim da recepção da mensagem. 4.2 Exercício 2 - Protocolo v2 Este exercício consiste na alteração do protocolo modelado anteriormente de modo a que o mesmo agora consiga lidar com mensagens de tamanho maior que o atraso do meio. Nesta versão não é exigido que o modelo seja rigoroso, admite-se a possi- bilidade das execuções nem sempre escolherem a forma mais rápida de comunicar a mensagem. Isto partindo do princípio que o meio continua a não conhecer o tamanho da mensagem. Pretende-se que o modelo seja verificado pelo menos com as propriedades anteri- ormente definidas. 28
  30. 30. 4.3 Resoluções 29
  31. 31. 4.3.1 Exercício 1 Para este exercício apresentam-se duas resoluções ligeiramente distintas. Numa as sincronizações são urgentes (ver Figura 4.3) enquanto na outra não (ver Figura 4.2). Para esta situação ambos os modelos cumprem o objectivo anteriormente definido, no entanto existem diferenças significativas entre as sincronizações urgentes e as não urgentes. Como foi referido numa sincronização urgente a passagem de tempo não ocorre e consequentemente torna-se impossível utilizar guardas sobre relógios simul- taneamente. Figura 4.2: Modelo com sincronizações não urgentes. Nestas duas soluções as execuções não são realmente paralelas, porque seguem uma sequência linear que se repete, logo o facto de utilizar, ou não, sincronizações ur- 30
  32. 32. Figura 4.3: Modelo com sincronizações urgentes. 31
  33. 33. gentes não provoca alterações nos modelos.No caso contrário o mesmo poderia já não se verificar, excepto se os estados intermédios fossem sempre committed. A declaração de variáveis globais e declaração de variáveis locais de ambos os modelos são iguais (ver Listing 4.1 e 4.2). Listing 4.1: Declaração de variáveis globais. / / Place global d e c l a r a t i o n s here . clock tglobal ; bool m_enviada ; Listing 4.2: Declaração de variáveis locais do Meio. clock atraso_i , atraso_f ; Já a declaração de sistema muda ligeiramente devido à existência dos canais de sincronização urgentes e não urgentes. Na Listing 4.3 é possível ver uma declaração completa e na Listing 4.4 apresenta-se a diferença do modelo com os canais de sin- cronização urgentes. Listing 4.3: Declaração de sistema do modelo da Figura 4.2. / / Place template i n s t a n t i a t i o n s here . c h a n i n i c i o _ e , fim_e , i n i c i o _ r , f i m _ r ; c o n s t i n t tamanho =3 , a t r a s o = 1 0 ; e = E m i s s o r ( i n i c i o _ e , fim_e , tamanho ) ; r = Receptor ( i n i c i o _ r , fim_r ) ; m = Meio ( i n i c i o _ e , fim_e , i n i c i o _ r , f i m _ r , a t r a s o ) ; / / L i s t one o r more p r o c e s s e s t o be composed i n t o a s y s t e m . s y s t e m e , r , m; Listing 4.4: Parte da declaração de sistema do modelo da Figura 4.3. u r g e n t c h a n i n i c i o _ e , fim_e , i n i c i o _ r , f i m _ r ; / / R e p e t i ç ã o d a s d e c l a r a ç õ e s de s i s t e m a do o u t r o modelo / / sem a o u t r a d e c l a r a ç ã o de c a n a i s de s i n c r o n i z a ç ã o . Olhando mais detalhadamente para a solução apresentada na Figura 4.2 e após terem sido apresentadas todas as declarações sabe-se que cada template vai dar origem a um único autómato do modelo. Existindo três estados iniciais a execução poderia começar por qualquer um deles, mas dois dos estados iniciais esperam por sincroniza- ções. Assim só existe uma primeira execução possível que consiste na transição para o estado Envio do Emissor. A primeira transição para além de umas actualizações de variáveis faz ainda uma sincronização com o Meio dando início à execução do mesmo. Esta sincronização representa o início do envio da mensagem por parte do Emissor e coloca o Meio no estado Recepcao. 32
  34. 34. De seguida só é possível executar a transição que volta a por o autómato Emis- sor no estado P ronto. Existe uma guarda nessa transição indicando que tglobal >= tamanho, logo a transição só vai ser activada quando for atingida esta condição. Por outras palavras, a execução só evolui, finalizando o envio da mensagem, quando o tempo correspondente ao tamanho da mensagem passar. Esta transição faz ainda uma sincronização com o Meio para permitir que de seguida seja iniciado o processo de recepção da mensagem por parte do Receptor. Não esquecer que a mensagem é total- mente enviada antes de ser iniciado este processo porque partiu-se do pressuposto que o tamanho é sempre menor que o atraso. A próxima execução consiste na transição para o estado Envio do Meio. Nesta transição é possível verificar a existência da guarda atraso_i >= atraso que permite que a evolução do autómato só seja realizada quando o tempo de atraso tenha sido atingido. A transição inicia o processo de recepção da mensagem por parte do receptor através da sincronização colocando o Receptor no estado Recepcao. A execução seguinte remete o Meio para o estado P ronto. A transição responsável por essa execução possui a guarda atraso_f >= atraso indicando que a evolução só é feita quando o atraso de finalização do processo de comunicação seja cumprido. Esta transição faz ainda uma sincronização com o Receptor, por sua vez a transição do Re- ceptor realiza a actualização m_enviada = true. Esta actualização permite saber quando o Receptor está no estado P ronto se o tglobal contém o tempo total de comu- nicação ou se o mesmo já foi reinicializado. Simulando e estudando este protocolo chega-se à conclusão que o tempo total de comunicação corresponde à soma do tamanho com o atraso. Assim o modelo deve veri- ficar correctamente as propriedades A[] not deadlock e A[] (r.P ronto and m_enviada == true imply tglobal >= (tamanho + atraso)). Outra propriedade que pode ser in- teressante verificar é E <> (r.P ronto and m_enviada == true and tglobal < (tamanho + atraso)). Isto é, será que existe algum caminho com tempo total de co- municação menor que a soma do tamanho com o atraso? A resposta óbvia é não. No entanto esta propriedade pode ser interessante para descortinar erros no modelo numa fase intermédia. 4.3.2 Exercício 2 A resolução deste exercício consiste meramente na alteração do Meio para conseguir lidar com a situação citada no enunciado. Na Figura 4.4 e na Figura 4.5 é possível ver o Meio de cada uma das soluções. Uma vez que as alterações entre ambas as soluções são menores, lidando com a questão da sincronização de maneira diferente, de seguida descreve-se apenas as alterações para a Figura 4.4. Além da alteração gráfica, que é irrelevante funcionalmente, verifica-se que o Meio possui um novo estado com transições que sincronizam primeiro com o autómato Re- ceptor e posteriormente com o autómato Emissor. A primeira transição possui a guarda atraso_i >= atraso limitando a evolução do modelo a este ramo apenas quando esta 33
  35. 35. Figura 4.4: Meio do modelo com sincronizações não urgentes. Figura 4.5: Meio do modelo com sincronizações urgentes. 34
  36. 36. condição se verificar primeiro que a sincronização que segue o outro ramo. Em termos de verificação as duas soluções seguem o comportamento do exercício anterior, o que seria de esperar uma vez que as propriedades definidas mantêm-se. No entanto se for pretendido um modelo rigoroso, nota-se com a simulação, que em ambas as soluções o Meio necessita conhecer o tamanho da mensagem para tomar a decisão correcta sobre qual dos ramos a executar. 35
  37. 37. Referências [1] http://www.ita.cs.ru.nl/publications/papers/fvaan/ MCinEdu/mutex.html. [2] http://www.it.uu.se/edu/course/homepage/realtid/ p1ht08/uppaal. [3] Systems and software verification: model-checking techniques and tools. Springer- Verlag New York, Inc., New York, NY, USA, 1999. [4] Hugh Anderson. Verification of real time systems - cs5270 (lecture 11). http://www.comp.nus.edu.sg/~cs5270/2006-semesterII/ foils11.print.pdf, March 2007. [5] Gerd Behrmann, Alexandre David, and Kim G. Larsen. A tutorial on UPPAAL. In Marco Bernardo and Flavio Corradini, editors, Formal Methods for the Design of Real-Time Systems: 4th International School on Formal Methods for the Design of Computer, Communication, and Software Systems, SFM-RT 2004, number 3185 in LNCS, pages 200–236. Springer–Verlag, September 2004. [6] A. Burns and T. M. Lin. An engineering process for the verification of real-time systems. Form. Asp. Comput., 19(1):111–136, 2007. [7] R. "Hamberg and F.W."Vaandrager. "Using Model Checkers in an Introductory Course on Operating Systems". Technical Report "ICIS–R07031", "Radboud Uni- versity Nijmegen", "December2007". [8] Kim G. Larsen, Paul Pettersson, and Wang Yi. U PPAAL in a Nutshell. Int. Journal on Software Tools for Technology Transfer, 1(1–2):134–152, Oct 1997. [9] F.W. Vaandrager and A.L. de Groot. Analysis of a biphase mark protocol with Up- paal and PVS. Formal Aspects of Computing Journal, 18(4):433–458, December 2006. 36
  38. 38. Apêndice A TA e XTA BNF Informação retirada da página pessoal do Professor Gerd Behrmann. Esta sintaxe assemelha-se à da linguagem C, tanto que é possível declarar funções C dentro da especificação do modelo. Listing A.1: BNF do formato TA/XTA v3.x OldXTA : : = < O l d D e c l a r a t i o n > ∗ < I n s t a n t i a t i o n >∗ <System > O l d D e c l a r a t i o n : : = < VariableDecl > | <OldConstDecl > | <OldProcDecl > OldConstDecl : : = ’ const ’ <OldConstDeclId > ( ’ , ’ <OldConstDeclId >)∗ ’ ; ’ O l d C o n s t D e c l I d : : = ID < A r r a y D e c l >∗ [ < I n i t i a l i s e r > ] O l d P r o c D e c l : : = ’ p r o c e s s ’ ID [ < O l d P r o c P a r a m s > ] ’ { ’ <OldProcBody > ’ } ’ O l d P r o c P a r a m s : : = ’ ( ’ [ < OldProcParam > ( ’ ; ’ < OldProcParam > ) ∗ ] ’ ) ’ O l d P r o c P a r a m : : = <Type > ID < A r r a y D e c l >∗ ( ’ , ’ ID < A r r a y D e c l > ∗ ) ∗ | ’ c o n s t ’ ID < A r r a y D e c l >∗ ( ’ , ’ ID < A r r a y D e c l > ∗ ) ∗ OldProcBody : : = ( < VarDecl > | < O l d C o n s t D e c l > ) ∗ < O l d S t a t e s > [ < Commit > ] [ < U r g e n t > ] < I n i t > [ < O l d T r a n s i t i o n s > ] O l d S t a t e s : : = ’ s t a t e ’ < OldStateDecl > ( ’ , ’ < OldStateDecl >)∗ ’ ; ’ O l d S t a t e D e c l : : = ID [ ’ { ’ < O l d I n v a r i a n t > ’ } ’ ] O l d I n v a r i a n t : : = < Expression > ( ’ , ’ < Expression >)∗ OldTransitions ::= ’ trans ’ <OldTransition > ( ’ , ’ < O l d T r a n s i t i o n O p t >)∗ ’ ; ’ O l d T r a n s i t i o n : : = ID ’−>’ ID < OldTransBody > O l d T r a n s i t i o n O p t : : = O l d T r a n s i t i o n | ’−>’ ID < OldTransBody > 37
  39. 39. OldTransBody : : = ’ { ’ [ < OldGuard > ] [ < Sync > ] [ < A s s i g n > ] ’ } ’ OldGuard : : = ’ g u a r d ’ < E x p r e s s i o n > ( ’ , ’ < E x p r e s s i o n > ) ∗ ’ ; ’ Listing A.2: BNF do formato XTA v4.x XTA : : = < D e c l a r a t i o n >∗ < I n s t a n t i a t i o n >∗ <System > D e c l a r a t i o n : : = < F u n c t i o n D e c l > | < V a r i a b l e D e c l > | <TypeDecl > | <ProcDecl > I n s t a n t i a t i o n : : = ID ASSIGNMENT ID ’ ( ’ < A r g L i s t > ’ ) ’ ’ ; ’ System : : = ’ s y s t e m ’ ID ( ’ , ’ ID ) ∗ ’ ; ’ ParameterList : : = ’( ’ [ <Parameter > ( ’ , ’ <Parameter > )∗ ] ’) ’ P a r a m e t e r : : = <Type > [ ’& ’ ] ID < A r r a y D e c l >∗ F u n c t i o n D e c l : : = <Type > ID < P a r a m e t e r L i s t > < Block > P r o c D e c l : : = ’ p r o c e s s ’ ID < P a r a m e t e r L i s t > ’ { ’ <ProcBody > ’ } ’ ProcBody : : = ( < F u n c t i o n D e c l > | < V a r i a b l e D e c l > | <TypeDecl > ) ∗ < S t a t e s > [ < Commit > ] [ < U r g e n t > ] < I n i t > [ < T r a n s i t i o n s > ] S t a t e s : : = ’ s t a t e ’ < S t a t e D e c l > ( ’ , ’ < S t a t e D e c l >)∗ ’ ; ’ S t a t e D e c l : : = ID [ ’ { ’ < E x p r e s s i o n > ’ } ’ ] Commit : : = ’ commit ’ S t a t e L i s t ’; ’ Urgent : : = ’ urgent ’ S t a t e L i s t ’; ’ S t a t e L i s t : : = ID ( ’ , ’ ID ) ∗ I n i t : : = ’ i n i t ’ ID ’ ; ’ T r a n s i t i o n s : : = ’ t r a n s ’ < T r a n s i t i o n > ( ’ , ’ < T r a n s i t i o n O p t >)∗ ’ ; ’ T r a n s i t i o n : : = ID ’−>’ ID < T r a n s i t i o n B o d y > T r a n s i t i o n O p t : : = T r a n s i t i o n | ’−>’ ID < T r a n s i t i o n B o d y > T r a n s i t i o n B o d y : : = ’ { ’ [ < Guard > ] [ < Sync > ] [ < A s s i g n > ] ’ } ’ Guard : : = ’ g u a r d ’ < E x p r e s s i o n > ’ ; ’ Sync : : = ’ sync ’ < E x p r e s s i o n > ( ’ ! ’ | ’? ’) ’; ’ Assign : : = ’ assign ’ <ExprList > ’; ’ TypeDecl : : = ’ t y p e d e f ’ <Type > < T y p e I d L i s t > ( ’ , ’ < TypeIdList >)∗ ’ ; ’ T y p e I d L i s t : : = ID < A r r a y D e c l >∗ Listing A.3: BNF da declaração de variáveis V a r i a b l e D e c l : : = <Type > < D e c l I d > ( ’ , ’ < D e c l I d > ) ∗ ’ ; ’ D e c l I d : : = ID < A r r a y D e c l >∗ [ ASSIGNMENT < I n i t i a l i s e r > ] 38
  40. 40. I n i t i a l i s e r : : = <Expression > | ’{ ’ < F i e l d I n i t > ( ’ , ’ < F i e l d I n i t > )∗ ’} ’ F i e l d I n i t : : = [ ID ’ : ’ ] < I n i t i a l i s e r > ArrayDecl : : = ’[ ’ <Expression > ’] ’ Type : : = < P r e f i x > ID [ <Range > ] | < P r e f i x > ’ s t r u c t ’ ’ { ’ < F i e l d D e c l >+ ’ } ’ F i e l d D e c l : : = <Type > < F i e l d D e c l I d > ( ’ , ’ < F i e l d D e c l I d > ) ∗ ’ ; ’ F i e l d D e c l I d : : = ID < A r r a y D e c l >∗ Pref ix : : = ( [ ’ urgent ’ ] [ ’ broadcast ’ ] | [ ’ const ’ ] ) Range : : = ’ [ ’ < E x p r e s s i o n > ’ , ’ < E x p r e s s i o n > ’ ] ’ Listing A.4: BNF das instruções B l o c k : : = ’ { ’ ( < V a r i a b l e D e c l > | <TypeDecl > ) ∗ < S t a t e m e n t >∗ ’ } ’ S t a t e m e n t : : = <Block > | ’; ’ | <Expression > ’; ’ | ’ for ’ ’( ’ < ExprList > ’ ; ’ < ExprList > ’ ; ’ <ExprList > ’) ’ <Statement > | ’ while ’ ’( ’ < ExprList > ’) ’ < Statement > | ’ do ’ < S t a t e m e n t > ’ w h i l e ’ ’ ( ’ < E x p r L i s t > ’ ) ’ ’ ; ’ | ’ if ’ ’( ’ <ExprList > ’) ’ <Statement > [ ’ else ’ <Statement > ] | ’ break ’ ’; ’ | ’ continue ’ ’; ’ | ’ s w i t c h ’ ’ ( ’ < E x p r L i s t > ’ ) ’ ’ { ’ <Case >+ ’ } ’ | ’ return ’ ’; ’ | ’ return ’ <Expression > ’; ’ Case : : = ’ c a s e ’ < E x p r e s s i o n > ’ : ’ < S t a t e m e n t >∗ | ’ d e f a u l t ’ ’ : ’ < S t a t e m e n t >∗ Listing A.5: BNF das expressões ExprList : : = <Expression > ( ’ , ’ <Expression > )∗ E x p r e s s i o n : : = ID | NAT | ’ true ’ | ’ f a l s e ’ | ID ’ ( ’ < A r g L i s t > ’ ) ’ | <Expression > ’[ ’ <Expression > ’] ’ | ’( ’ <Expression > ’) ’ | < E x p r e s s i o n > ’++ ’ | ’++ ’ < E x p r e s s i o n > | < E x p r e s s i o n > ’−−’ | ’−−’ < E x p r e s s i o n > | < E x p r e s s i o n > <AssignOp > < E x p r e s s i o n > | <UnaryOp > < E x p r e s s i o n > 39
  41. 41. | <Expression > <Rel > < E x p r e s s i o n > | <Expression > <BinIntOp > < Expression > | <Expression > <BinBoolOp > < E x p r e s s i o n > | <Expression > ’? ’ <Expression > ’: ’ <Expression > | <Expression > ’ . ’ ID> AssignOp : : = ASSIGNMENT | ’+= ’ | ’−=’ | ’∗= ’ | ’ / = ’ | ’%=’ | ’ | = ’ | ’&= ’ | ’ ^ = ’ | ’ < <= ’ | ’ > >= ’ UnaryOp : : = ’ − ’ | ’ ! ’ R e l : : = ’ < ’ | ’ <= ’ | ’== ’ | ’ ! = ’ | ’ >= ’ | ’ > ’ B i n I n t O p : : = ’+ ’ | ’ − ’ | ’ ∗ ’ | ’ / ’ | ’% ’ | ’& ’ | ’ | ’ | ’ ^ ’ | ’<<’ | ’>>’ BinBoolOp : : = ’&&’ | ’ | | ’ ArgList : : = [ <Expression > ( ’ , ’ <Expression > )∗ ] 40

×