wptrans: um assistente para veri cação de programas em … · tes oferecem comunicação com...

161

Upload: others

Post on 04-Nov-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Universidade Federal do Rio Grande do Norte

Centro de Ciências Exatas e da Terra

Departamento de Informática e Matemática Aplicada

Programa de Pós-graduação em Sistemas e Computação

Mestrado Acadêmico em Sistemas e Computação

WPTrans: Um Assistente para Veri�cação deProgramas em Frama-C

Vítor Alcântara de Almeida

Natal-RN

Abril de 2016

Page 2: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Vítor Alcântara de Almeida

WPTrans: Um Assistente para Veri�cação de

Programas em Frama-C

Dissertação de Mestrado apresentada ao Pro-grama de Pós-graduação em Sistemas e Com-putação do Departamento de Informática eMatemática Aplicada da Universidade Fede-ral do Rio Grande do Norte como requisitoparcial para a obtenção do grau de Mestreem Sistemas e Computação.

Linha de pesquisa:Métodos Formais

Orientador

Prof. Dr. David Boris Paul Déharbe

PPgSC � Programa de Pós-graduação em Sistemas e Computação

DIMAp � Departamento de Informática e Matemática Aplicada

CCET � Centro de Ciências Exatas e da Terra

UFRN � Universidade Federal do Rio Grande do Norte

Natal-RN

Abril de 2016

Page 3: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Almeida, Vítor Alcântara de. WPTrans: um assistente para verificação de programas emFrama-C / Vítor Alcântara de Almeida. - Natal, 2016. 159f: il.

Orientador: Prof. Dr. David Boris Paul Déharbe.

Dissertação (Mestrado) - Universidade Federal do Rio Grandedo Norte. Centro de Ciências Exatas e da Terra. Programa de Pós-Graduação em Sistemas e Computação.

1. Métodos formais. 2. Frama-C. 3. WP. 4. WPTrans. 5.Obrigação de prova. 6. Coq. 7. SMT. I. Déharbe, David BorisPaul. II. Universidade Federal do Rio Grande do Norte. III.Título.

RN/UF/CCET CDU 004.05

Catalogação da Publicação na FonteUniversidade Federal do Rio Grande do Norte - UFRN

Sistema de Bibliotecas - SISBI

Page 4: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Dissertação de Mestrado sob o título WPTrans: Um Assistente para Veri�cação de Pro-

gramas em Frama-C apresentada por Vítor Alcântara de Almeida e aceita pelo Programa

de Pós-graduação em Sistemas e Computação do Departamento de Informática e Mate-

mática Aplicada da Universidade Federal do Rio Grande do Norte, sendo aprovada por

todos os membros da banca examinadora abaixo especi�cada:

Prof. Dr. David Boris Paul DéharbePresidente

DIMAp � Departamento de Informática e Matemática Aplicada

UFRN � Universidade Federal do Rio Grande do Norte

Prof. Dr. Umberto Souza da CostaExaminador

DIMAp � Departamento de Informática e Matemática Aplicada

UFRN � Universidade Federal do Rio Grande do Norte

Prof. Dr. Richard Walter Alain BonichonExaminador

UPMC � Université Pierre et Marie Curie

Prof. Dr. Plácido Antônio de Souza NetoExaminador

IFRN � Instituto Federal de Educação, Ciência e Tecnologia doRio Grande do Norte

Natal-RN, 29 de abril de 2016.

Page 5: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

A Meine Siomara Alcântara, minha mãe, pela vida que tenho e por todas as

oportunidades que me proporcionou, sempre me estimulando a crescer mais e mais, por

ser meu espelho em sua vida de lutas e felicidades.

Page 6: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Agradecimentos

Agradeço a Ocimar de Souza Alcântara, avó querida e presente, pela paciência e por

compreender a minha ausência devido à dedicação ao mestrado. Espero poder dedicar

mais tempo para estar presente com a senhora nos anos vindouros, e desejo que sua casa

esteja sempre cheia de alegria.

Agradeço à minha irmã Maira Alcântara César Soares dos Santos, por me permi-

tir compartilhar brincadeiras e momentos sérios, compreendendo a complexidade deste

trabalho, já que também passa por um momento de estudo e dedicação. Estendo esse

agradecimento ao seu namorado Rafael, que partilhou desses momentos conosco.

Agradeço a Josenildo César Soares dos Santos, meu pai de coração, pelas lições de

vida, apesar dos momentos em que possamos ter desavenças, sei que tudo é pensando

para o meu futuro e sucesso, mas também respeitando minhas vontades e ambições.

Agradeço a Pedro de Alcântara Gregório, meu falecido avô, por passar a mensagem

do que é ser batalhador e defensor de seus direitos, sem atropelar a honra e dignidade de

ninguém. As saudades sempre permanecerão em meu coração e não esquecerei jamais de

seus ensinamentos.

Agradeço à vovó Geni por sempre ter esperanças de que eu concluiria o mestrado com

triunfo, me acolhendo calorosamente em todas as viagens a João Pessoa.

Aos meus queridos tios e padrinhos Regina Cassia e Algacy de Almeida, por ter me

acompanhado nessa trajetória, sempre com muito afeto, carinho e atenção. A eles meu

profundo respeito.

Agradeço a Edinalva Soares dos Santos (in memoriam), querida avó, apesar de nosso

contato pouco frequente, sempre foi bondosa e caridosa, olhando sempre para o lado

positivo da vida.

Agradeço a Juvenal José dos Santos, meu avô de coração, por ser homem forte, tra-

balhador, mas, puxando um pouco para o lado da vovó �dona� Edinalva, também é super

caridoso e sorridente, apesar das intempéries que insistem em bagunçar nossas rotinas.

Page 7: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Agradeço a David Bóris Paul Déharbe, meu orientador, pela orientação cuidadosa e

de qualidade desde a iniciação cientí�ca, me dando oportunidade de me quali�car acade-

micamente, acreditando no meu potencial e por me aceitar novamente como orientando

nesta etapa.

Agradeço a Richard Walter Alain Bonichon, meu coorientador, por acreditar em mim

mesmo em minhas falhas na graduação, proporcionar uma nova oportunidade de aprender

e contribuir no mundo acadêmico, e pelos ensinamentos na área de pesquisa que domina

e que já me sinto introduzido.

A Michelle Sinara, prima especial, que me acolheu tão bem nas terras baianas quando

da ida à Franca. A sua simpatia e vivacidade permitiu que tudo fosse mais leve e familiar

na minha partida. A ela meu imensurável agradecimento.

Agradeço aos meus tios: Miguel Neto, Margarete e Fátima, por acreditarem que eu

possa ser o sobrinho bom na área da computação, sempre muito receptivos e lutadores.

Também por manter a harmonia da nossa família, inclusive com seus �lhos.

Agradeço aos meus primos Carol, Daniela, Diego, Gilmara, Guilherme, Laisa, Luciane

e Silmara pela alegria e espontaneidade nos encontros atuais e nas lembranças do passado,

sendo um elo entre a geração dos nossos pais e a geração que nós acolheremos.

Agradeço a Tia Neide e Tio Janiro pelos exemplos que são na família e dedicação a

estudos que sempre �zeram parte de suas vidas, sendo inspiradores em minha busca pelo

conhecimento.

Agradeço a Umberto Souza da Costa, por aceitar participar na minha banca, apon-

tando críticas e recomendações, elevando assim a rigorosidade de meu trabalho, além de

ter sido um ótimo professor na graduação.

Agradeço a Edgard de Faria Corrêa, pelas oportunidades que me proporcionou na

graduação e por ter acreditado que eu poderia ser o pontapé inicial a outros estudantes

que procurassem experimentar culturas e aprendizados além-mar.

Agradeço a Plácido Antônio de Souza Neto por aceitar o convite para participar da

minha banca e pelas ótimas contribuições ao trabalho.

Agradeço a Jussara Paiva Nunes, segunda mãe, por se preocupar tanto com meu

futuro e me dar uns cocorotes por eu, às vezes, desviar dos meus objetivos.

Agradeço a Jailma Lima, amiga exemplar, por me achar o menino mais �lindo�, e por

me incentivar tanto a �nalizar meu mestrado, e, quem sabe, um doutorado em seguida.

Page 8: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Agradeço a Micussi e Acácia por sempre tão animados e receptivos, convidando para

todas as celebrações entre amigos e sempre se lembrando de mim.

Agradeço a Márcio, Edilene, Zé Martins, Agslene, Núbia e grandes amigos dos meus

pais, por acharem sempre que sou �o cara� e serem exemplos de amizade e maturidade,

me sentindo bem recebido em seus lares.

Agradeço a Loreta Melo, meu amor, por ter me dado forças e mostrado que todas

as di�culdades enfrentadas em um mestrado não são absurdas e sim possíveis de serem

superadas, além do carinho amoroso para me tranquilizar em momentos tensos. Agradeço

ainda pela preciosa revisão no texto.

Agradeço a Tânia de Melo, pelo carinho e sempre ter uma mesa gastronomicamente

criativa, me recebendo de braços abertos.

Agradeço a Kiko, meu �el cachorro, por, apesar de algumas mordidas marcadas em

mim, sempre atencioso, peludo, branquinho, grande e brincalhão. Que ele possa continuar

proporcionando alegrias, enchendo nossos corações.

Agradeço aos meus amigos pela diversão que me proporcionaram em momentos de

estresse e tensos, lembrando-me que, apesar de nossos esforços, o que nos faz felizes é

aproveitar a vida, e com risadas companheiras é ainda mais proveitoso.

Agradeço ao Departamento de Informática e Matemática Aplicada por ter me passado

os ensinamentos essenciais da computação e por ter me instruído a tanto ser um bacharel

quanto rumar um caminho como mestre em Sistemas e Computação.

Agradeço à Universidade Federal do Rio Grande do Norte por ter me recebido e me en-

sinado os valores do ensino superior, permitindo que eu retorne à sociedade o investimento

que ela fez em mim.

Agradeço à Coordenação de Aperfeiçoamento de Pessoal de Nível Superior por ter me

provido auxílio para que eu pudesse realizar o mestrado com sucesso.

Page 9: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

WPTrans: Um Assistente para Veri�cação deProgramas em Frama-C

Autor: Vítor Alcântara de Almeida

Orientador(a): Prof. Dr. David Boris Paul Déharbe

Resumo

A plataforma Frama-C é uma ferramenta utilizada em diversos tipos de análise de có-

digo de softwares escritos em C, sendo essas análises disponibilizadas através de plugins

acoplados à plataforma. Um desses plugins é o WP, utilizado na veri�cação dedutiva de

código C com a linguagem de especi�cação ACSL. A presente dissertação descreve uma

extensão para esse plugin, sendo ela denominada WPTrans. Essa extensão permite a ma-

nipulação, através de regras de inferência, das obrigações de prova geradas pelo WP, com a

possibilidade de serem enviadas, em qualquer etapa da modi�cação, a provadores automá-

ticos (notadamente solucionadores SMT) e interativos de teoremas. Algumas obrigações

de prova podem ser validadas automaticamente, enquanto outras são muito complexas

para os provadores automáticos de teoremas, exigindo uma prova manual pelo desen-

volvedor, através dos assistentes de prova. Contudo, a segunda abordagem geralmente

requer do usuário uma experiência signi�cativa em estratégias de prova. Alguns assisten-

tes oferecem comunicação com provadores automáticos, entretanto, essa ligação pode ser

complexa ou incompleta, restando ao usuário apenas a prova manual. O objetivo desse

plugin é prover um meio de modi�car manualmente, pelo usuário, as obrigações de prova

geradas pelo WP, com uma linguagem simples para a manipulação. Assim, o usuário pode

simpli�car su�cientemente as obrigações de prova para que possam ser validadas por um

provador automático de teoremas. Não obstante, a extensão é interligada diretamente ao

WP, facilitando a instalação do plugin no Frama-C. Essa extensão também é uma porta

de entrada para outras possíveis funcionalidades, que serão discutidas neste documento.

Palavras-chave: Frama-C, WP, WPTrans, Obrigação de prova, Coq, SMT.

Page 10: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

WPTrans: A proof assistant for program veri�cation inFrama-C

Author: Vítor Alcântara de Almeida

Supervisor: Prof. Dr. David Boris Paul Déharbe

Abstract

The platform Frama-C is a tool dedicated to analysis of source code of software written in

C, with the possible types of analysis provided by plugins attached to the platform. One of

its plugins is WP, used for deductive veri�cation of C code with ACSL, a formal speci�ca-

tion language. This dissertation describes the extension of this plugin, named WPTrans.

This extension allows generated proof obligations from WP to be manipulated through

inference rules and sent, at any stage of the proof, to automatic (mainly SMT solvers) and

interactive theorem provers. Some proof obligations may be proved automatically, while

others can be too complex to be solved by automatic theorem provers, requiring the users

of Frama-C and WP to handle them manually. This approach usually requires a signi�cant

experience in proof strategies. Some interactive theorem provers provide communication

with automatic provers. However, this connection can be complex and incomplete, lea-

ving the user with the manual proof option only. The strength of WPTrans is to combine

the features of automatic and interactive theorem provers in a precise and complete way,

with a simple manipulation language. Thus, the user can simplify the proof obligations

enough in order for its proof to be concluded with an SMT solver, letting the proof be

partially manual and partially automatic. Nevertheless, the plugin is directly linked do

WP, facilitating the installation of the extension in Frama-C. This tool is also a gateway

to other possible features, which we discuss herein.

Keywords : Frama-C, WP, WPTrans, Proof obligation, Coq, SMT.

Page 11: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Lista de �guras

1 Exemplo de função C anotada com especi�cação em ACSL . . . . . . . p. 28

2 Exemplo de lemas em ACSL . . . . . . . . . . . . . . . . . . . . . . . . p. 29

3 Exemplo de de�nições axiomáticas em ACSL . . . . . . . . . . . . . . . p. 29

4 Exemplo de função em ACSL . . . . . . . . . . . . . . . . . . . . . . . p. 30

5 Exemplo de behavior em ACSL . . . . . . . . . . . . . . . . . . . . . . p. 30

6 Exemplo de normalização da função C anotada com especi�cação em ACSL p. 32

7 Exemplo de função C com anotações geradas pelo Annotation Genera-

tion. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 33

8 Arquitetura do Frama-C. Fonte: Cuoq et al. (2012). p. 3 . . . . . . . . p. 34

9 Interface grá�ca do Frama-C . . . . . . . . . . . . . . . . . . . . . . . . p. 36

10 Esquema do WP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 38

11 Exemplo da notação utilizada . . . . . . . . . . . . . . . . . . . . . . . p. 39

12 Exemplo de uso da notação . . . . . . . . . . . . . . . . . . . . . . . . p. 39

13 Regra da atribuição . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 40

14 Exemplo da regra da atribuição . . . . . . . . . . . . . . . . . . . . . . p. 41

15 Regra da sequência . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 41

16 Formas da regra da implicação . . . . . . . . . . . . . . . . . . . . . . . p. 42

17 Regra da escolha . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 42

18 Regra do laço . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 44

19 Exemplo de reescrita de comando para aplicação da regra da escolha.

Fonte: adaptado de Burghardt e Gerlach (2015, p. 21) . . . . . . . . . . p. 44

Page 12: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

20 Exemplo de interpretação de um programa que calcula a soma dos valores

de um vetor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 45

21 Tipos de nós do �uxograma . . . . . . . . . . . . . . . . . . . . . . . . p. 46

22 Operadores e constantes presentes na lógica de termos do WP . . . . . p. 49

23 Estruturas de uma hipótese . . . . . . . . . . . . . . . . . . . . . . . . p. 50

24 Função C anotada com contrato em ACSL para exempli�car modelos de

números inteiros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 54

25 OP no modelo inteiro de máquina . . . . . . . . . . . . . . . . . . . . . p. 54

26 OP no modelo de inteiros naturais . . . . . . . . . . . . . . . . . . . . . p. 55

27 OP no modelo de inteiros naturais sem faixa de valores . . . . . . . . . p. 55

28 Função C anotada com contrato em ACSL para exempli�car modelos de

ponto �utuante. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 56

29 OP no modelo de ponto �utuante IEEE . . . . . . . . . . . . . . . . . . p. 56

30 OP no modelo de números reais . . . . . . . . . . . . . . . . . . . . . . p. 56

31 Um exemplo de função C anotada com um contrato em ACSL . . . . . p. 57

32 Exemplo de OP do tipo Annot . . . . . . . . . . . . . . . . . . . . . . p. 57

33 Um exemplo de lema ACSL . . . . . . . . . . . . . . . . . . . . . . . . p. 58

34 OP do tipo Lemma gerada a partir do lema plusEqual . . . . . . . . . p. 58

35 Exemplo de entrada do Why3 . . . . . . . . . . . . . . . . . . . . . . . p. 60

36 Exemplo de entrada de driver para Z3 . . . . . . . . . . . . . . . . . . p. 62

37 Exemplo de tarefa de prova WhyML . . . . . . . . . . . . . . . . . . . p. 62

38 Why3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 64

39 Exemplo de OP em SMT-LIB . . . . . . . . . . . . . . . . . . . . . . . p. 66

40 Exemplo de OP na linguagem nativa do Alt-Ergo . . . . . . . . . . . . p. 68

41 Exemplo do Coq . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 70

42 Esquema do WP com o WPTrans . . . . . . . . . . . . . . . . . . . . . p. 73

43 Exemplo de OP do tipo Lemma com o novo formato . . . . . . . . . . p. 75

Page 13: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

44 De�nição de assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 79

45 Exemplo da regra assert . . . . . . . . . . . . . . . . . . . . . . . . . . p. 80

46 De�nição de int_ind . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 81

47 Exemplo da regra int_ind . . . . . . . . . . . . . . . . . . . . . . . . . p. 81

48 De�nição de intro - instanciação universal . . . . . . . . . . . . . . . . p. 82

49 De�nição de intro . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 82

50 Primeiro exemplo da regra intro . . . . . . . . . . . . . . . . . . . . . . p. 82

51 Segundo exemplo da regra intro . . . . . . . . . . . . . . . . . . . . . . p. 82

52 De�nição de unfold . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 83

53 De�nição de unfold_all . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 83

54 Exemplo da regra unfold . . . . . . . . . . . . . . . . . . . . . . . . . . p. 84

55 De�nição de existo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 84

56 Exemplo da regra existo . . . . . . . . . . . . . . . . . . . . . . . . . . p. 85

57 De�nição de case . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 85

58 Exemplo da regra case . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 86

59 Exemplo da regra intros . . . . . . . . . . . . . . . . . . . . . . . . . . p. 86

60 Janela principal do WPTrans . . . . . . . . . . . . . . . . . . . . . . . p. 90

61 Janelas Proof Skeleton e Event-B Explorer do Rodin . . . . . . . . . . p. 91

62 Gramática para inserção de termos no WPTrans com sintaxe ACSL . . p. 92

63 Janela principal do WPTrans . . . . . . . . . . . . . . . . . . . . . . . p. 94

64 Árvore de OPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 97

65 OP Lemma CountBounds . . . . . . . . . . . . . . . . . . . . . . . . . p. 106

66 Lemma CountBounds em ACSL . . . . . . . . . . . . . . . . . . . . . . p. 107

67 Prova de Lemma CountBounds com Coq . . . . . . . . . . . . . . . . . p. 107

68 Prova de Lemma CountBounds com WPTrans . . . . . . . . . . . . . . p. 107

69 Prova de Lemma CountBounds com WPTrans . . . . . . . . . . . . . . p. 108

Page 14: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

70 OP Lemma RemoveCountMonotonic . . . . . . . . . . . . . . . . . . . p. 108

71 Prova de Lemma RemoveCountMonotonic com Coq . . . . . . . . . . . p. 108

72 Prova de Lemma RemoveCountMonotonic com WPTrans . . . . . . . . p. 109

73 Exemplo de função com ponteiro para funções . . . . . . . . . . . . . . p. 111

74 Axiomas e lemas de sum array . . . . . . . . . . . . . . . . . . . . . . . p. 112

75 OP Lemma sum3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 112

76 OP Lemma sum_footprint . . . . . . . . . . . . . . . . . . . . . . . . . p. 112

77 Prova da OP Lemma sum3 com WPTrans . . . . . . . . . . . . . . . . p. 113

78 Prova da OP Lemma sum_footprint com WPTrans . . . . . . . . . . . p. 113

79 Axiomas e lemas de unique_copy . . . . . . . . . . . . . . . . . . . . . p. 114

80 OP Lemma unique_lemma_4 . . . . . . . . . . . . . . . . . . . . . . . p. 114

81 OP Lemma unique_5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 114

82 Prova da OP Lemma unique_lemma_4 com WPTrans . . . . . . . . . p. 114

83 Prova da OP Lemma unique_5 com WPTrans . . . . . . . . . . . . . . p. 115

84 OP do algoritmo unique_copy . . . . . . . . . . . . . . . . . . . . . . . p. 117

85 De�nição de weakening . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 128

86 Exemplo da regra weakening . . . . . . . . . . . . . . . . . . . . . . . . p. 129

87 De�nição de to_goal . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 129

88 Exemplo de to_goal . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 129

89 De�nição de split . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 130

90 Exemplo da regra split . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 130

91 De�nição de splith . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 131

92 Exemplo da regra splith . . . . . . . . . . . . . . . . . . . . . . . . . . p. 131

93 De�nição de splitdh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 131

94 Exemplo da regra splitdh . . . . . . . . . . . . . . . . . . . . . . . . . . p. 132

95 De�nição de splitdo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 132

Page 15: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

96 Exemplo da regra splitdo . . . . . . . . . . . . . . . . . . . . . . . . . . p. 132

97 De�nição de contradict . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 133

98 Exemplo da regra contradict . . . . . . . . . . . . . . . . . . . . . . . . p. 133

99 De�nição de contrapose . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 133

100 Exemplo da regra contrapose . . . . . . . . . . . . . . . . . . . . . . . . p. 134

101 De�nição de restructure para If . . . . . . . . . . . . . . . . . . . . . . p. 134

102 restructure para Either . . . . . . . . . . . . . . . . . . . . . . . . . . p. 134

103 Primeiro exemplo da regra restructure . . . . . . . . . . . . . . . . . . p. 135

104 Segundo exemplo da regra restructure . . . . . . . . . . . . . . . . . . . p. 135

105 De�nição de allh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 135

106 Exemplo da regra allh . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 136

107 De�nição de existh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 136

108 Exemplo da regra existh . . . . . . . . . . . . . . . . . . . . . . . . . . p. 137

109 De�nição de apply . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 137

110 Exemplo da regra apply . . . . . . . . . . . . . . . . . . . . . . . . . . p. 137

111 De�nição de mp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 138

112 Exemplo da regra mp . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 138

113 De�nição de replace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 139

114 De�nição de replace para o segundo caso . . . . . . . . . . . . . . . . . p. 139

115 Exemplo da regra replace . . . . . . . . . . . . . . . . . . . . . . . . . . p. 139

116 De�nição de replaceh . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 140

117 Exemplo da regra replaceh . . . . . . . . . . . . . . . . . . . . . . . . . p. 140

118 De�nição de replace_all . . . . . . . . . . . . . . . . . . . . . . . . . . p. 140

119 Exemplo da regra replace_all . . . . . . . . . . . . . . . . . . . . . . . p. 140

120 De�nição de rewriteh . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 142

121 De�nição de rewritel . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 142

Page 16: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

122 Exemplo da regra rewriteh . . . . . . . . . . . . . . . . . . . . . . . . . p. 143

123 Exemplo da regra rewritel . . . . . . . . . . . . . . . . . . . . . . . . . p. 143

124 Algoritmo is_sorted especi�cado . . . . . . . . . . . . . . . . . . . . . p. 151

125 Algoritmo is_sorted_until especi�cado . . . . . . . . . . . . . . . . . . p. 152

126 Algoritmo min_max_element especi�cado . . . . . . . . . . . . . . . . p. 153

127 Algoritmo remove especi�cado . . . . . . . . . . . . . . . . . . . . . . . p. 154

128 Algoritmo unique especi�cado . . . . . . . . . . . . . . . . . . . . . . . p. 155

129 Algoritmo unique especi�cado . . . . . . . . . . . . . . . . . . . . . . . p. 156

130 Algoritmo sum of values in array especi�cado . . . . . . . . . . . . . . p. 157

Page 17: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Lista de tabelas

1 Comparação do número de comandos com Coq e WPTrans para prova

de OPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 110

2 Condições para uni�cação de termos nas regras rewriteh e rewritel . . . p. 141

Page 18: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Lista de abreviaturas e siglas

ACSL - ANSI/ISO C Speci�cation Language

CIL - C Intermediate Language

OP - Obrigação de prova

TPTP - Thousands of Problems for Theorem Provers

SAT - Problema de Satisfatibilidade Booleana

SMT - Satisfatibilidade Módulo Teoria

API - Application Programming Interface

Page 19: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Lista de algoritmos

1 De�nição de newhyp na aplicação de regra de inferência em OP do tipo

Annot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 76

2 De�nição de newhyp na aplicação de regra de inferência em OP do tipo

Lemma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 77

3 De�nição de pstep na aplicação de regra de inferência em OP do tipo

Annot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 77

4 De�nição de pstep na aplicação de regra de inferência em OP do tipo

Lemma . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 77

5 De�nição de repl na aplicação de regra de inferência em OP do tipo Lemma p. 78

6 De�nição de repl na aplicação de regra de inferência em OP do tipo Annot p. 78

7 De�nição abstrata de vars . . . . . . . . . . . . . . . . . . . . . . . . . p. 78

8 Prova de Lemma CountBounds . . . . . . . . . . . . . . . . . . . . . . p. 144

9 Prova de Lemma CountUnion . . . . . . . . . . . . . . . . . . . . . . . p. 144

10 Prova de Lemma CountMonotonic . . . . . . . . . . . . . . . . . . . . . p. 144

11 Prova de Lemma RemoveCountMonotonic . . . . . . . . . . . . . . . . p. 145

Page 20: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Sumário

1 Introdução p. 22

1.1 Objetivo Proposto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 25

1.2 Organização do trabalho . . . . . . . . . . . . . . . . . . . . . . . . . . p. 25

2 A linguagem de especi�cação ACSL e a plataforma Frama-C p. 27

2.1 A linguagem de especi�cação ACSL . . . . . . . . . . . . . . . . . . . . p. 27

2.2 Frama-C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 31

3 O plugin WP p. 37

3.1 Regras de inferência de Hoare . . . . . . . . . . . . . . . . . . . . . . . p. 39

3.1.1 Regra da atribuição, na ausência de efeitos colaterais . . . . . . p. 40

3.1.2 Regra da sequência . . . . . . . . . . . . . . . . . . . . . . . . . p. 41

3.1.3 Regra da consequência . . . . . . . . . . . . . . . . . . . . . . . p. 41

3.1.4 Regra da escolha . . . . . . . . . . . . . . . . . . . . . . . . . . p. 42

3.1.5 Regra do laço . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 43

3.1.6 Regras derivadas . . . . . . . . . . . . . . . . . . . . . . . . . . p. 44

3.2 Técnica de Floyd . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 44

3.3 Precondição mais fraca . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 47

3.4 Obrigação de prova . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 48

3.4.1 Modelos de memória e aritméticos . . . . . . . . . . . . . . . . . p. 52

3.4.2 Qed e simpli�cações na OP . . . . . . . . . . . . . . . . . . . . p. 58

3.5 A plataforma para veri�cação dedutiva Why3 . . . . . . . . . . . . . . p. 59

Page 21: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

3.6 Provadores automáticos de teoremas e os provadores SMT . . . . . . . p. 65

3.7 Assistentes de Prova . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 68

3.8 Veri�cação das OPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 71

4 A extensão WPTrans p. 73

4.1 Asserção - assert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 79

4.2 Indução sobre inteiros - int_ind . . . . . . . . . . . . . . . . . . . . . . p. 80

4.3 Introdução de objetivo na hipótese - intro . . . . . . . . . . . . . . . . p. 81

4.4 Desdobrar função - unfold e unfold_all . . . . . . . . . . . . . . . . . . p. 83

4.5 Instanciar quanti�cador existencial no objetivo - existo . . . . . . . . . p. 84

4.6 Prova por casos - case . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 85

4.7 Introdução de hipótese - intros . . . . . . . . . . . . . . . . . . . . . . p. 86

4.8 Conclusões do capítulo . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 86

5 WPTrans - Outras funcionalidades e aspectos técnicos p. 88

5.1 Interface Grá�ca . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 89

5.2 Leitura de termos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 91

5.3 Comandos implementados . . . . . . . . . . . . . . . . . . . . . . . . . p. 93

5.4 Organização do código . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 94

5.5 Ferramentas e versões . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 98

5.6 Di�culdades e experiências . . . . . . . . . . . . . . . . . . . . . . . . . p. 98

5.7 Ideias e modi�cações descartadas e não realizadas . . . . . . . . . . . . p. 101

6 Análise experimental p. 103

6.1 Veri�cação de OPs não validadas por solucionadores SMT . . . . . . . p. 104

6.2 Comparação do WPTrans com Coq . . . . . . . . . . . . . . . . . . . . p. 106

6.3 Especi�cação e veri�cação de algoritmos do STL C++ e do Toccata com

o WPTrans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 110

Page 22: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

6.4 Considerações sobre as Análises Experimentais . . . . . . . . . . . . . . p. 115

7 Considerações �nais p. 118

Referências p. 122

Apêndice A -- Outras regras de inferência implementadas no WPTrans p. 128

A.1 Remover hipóteses - weakening . . . . . . . . . . . . . . . . . . . . . . p. 128

A.2 Introdução da implicação - to_goal . . . . . . . . . . . . . . . . . . . . p. 129

A.3 Dividir conjunções no objetivo - split . . . . . . . . . . . . . . . . . . . p. 130

A.4 Eliminar conjunção em hipótese - splith . . . . . . . . . . . . . . . . . . p. 130

A.5 Eliminar disjunção em hipótese - splitdh . . . . . . . . . . . . . . . . . p. 131

A.6 Eliminar disjunção no objetivo - splitdo . . . . . . . . . . . . . . . . . . p. 132

A.7 Contradição - contradict . . . . . . . . . . . . . . . . . . . . . . . . . . p. 133

A.8 Contraposição - contrapose . . . . . . . . . . . . . . . . . . . . . . . . . p. 133

A.9 Reescrever hipótese - restructure . . . . . . . . . . . . . . . . . . . . . . p. 134

A.10 Instanciar quanti�cador universal em hipótese - allh . . . . . . . . . . . p. 135

A.11 Instanciar quanti�cador existencial em hipótese - existh . . . . . . . . . p. 136

A.12 Substituir objetivo por hipótese - apply . . . . . . . . . . . . . . . . . . p. 137

A.13 Modus ponens - mp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . p. 138

A.14 Substituir - replace, replaceh e replace_all . . . . . . . . . . . . . . . . p. 138

A.15 Reescrever - rewriteh e rewritel . . . . . . . . . . . . . . . . . . . . . . p. 141

Apêndice B -- Provas realizadas com o WPTrans p. 144

Apêndice C -- Exemplo de teoria SMT-LIB para inteiros p. 146

Apêndice D -- Obrigação de prova SMT-LIB gerada pelo Why3 para o

solucionador Z3 p. 147

Page 23: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

Apêndice E -- Algoritmos da STL C++ e do Toccata especi�cados para

análises experimentais p. 151

Apêndice F -- Modi�cações realizadas no WP p. 158

Page 24: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

22

1 Introdução

A linguagem de programação C é uma das mais utilizadas no mundo atual, estando em

segundo lugar no ranking disponibilizado em TIOBE (2015). Ela é utilizada em diversas

áreas, incluindo sistemas críticos de segurança (safety-critical systems) (BARR; MASSA,

2006) e sistemas embutidos (BARR, 1999). É necessário assegurar que a execução des-

ses programas ocorra como o previsto pelos desenvolvedores e usuários, principalmente

quando há a possibilidade de ameaças à integridade humana, danos materiais ou prejuízos

ambientais com a falha desses sistemas.

Os Métodos Formais constituem uma subárea da Engenharia de Software, cuja ca-

racterística principal é o uso de formalismo matemático na especi�cação e veri�cação de

sistemas (SOMMERVILLE, 2010). Os requisitos e funcionalidades dos sistemas devem ser

especi�cados detalhadamente com esses métodos, eliminando descrições confusas e ambi-

guidades com a rigorosidade matemática, sendo uma opção que deve ser considerada no

desenvolvimento de sistemas críticos de segurança (ALMEIDA, 2011). O uso dos Méto-

dos Formais é aceito cada vez mais pela indústria, principalmente devido à melhora das

ferramentas de especi�cação e veri�cação formal de sistemas. Contudo, sua adoção ainda

encontra entraves por um expressivo número de engenheiros de software (ALMEIDA,

2011).

Os métodos formais são compostos por diferentes técnicas de modelagem e veri�cação

de sistemas. Por exemplo, o sistema pode ser representado formalmente através de um

modelo com uma linguagem própria, começando em um estado mais abstrato e re�nado

sucessivamente até chegar ao mais próximo possível (ou satisfatório) da representação

�nal do sistema. Em seguida, esse modelo pode ser traduzido - de forma automática ou

manual, dependendo das ferramentas e linguagens envolvidas, bem como da complexidade

do projeto - para uma linguagem de programação, gerando o código do sistema �nal.

Alguns exemplos que se enquadram nessa técnica são os métodos formais B (ABRIAL,

2005), Event-B (ABRIAL, 2010), Z (SPIVEY, 1989) e VDM (FITZGERALD; LARSEN;

VERHOEF, 2008).

Page 25: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

23

Uma outra abordagem adotada pelos métodos formais é a inserção de anotações di-

retamente no código do programa veri�cado. Normalmente, essas anotações descrevem

condições que devem ser respeitadas antes e após funções e trechos de códigos do pro-

grama, além de de�nir propriedades e invariantes que o programa deve respeitar. Geral-

mente, as anotações utilizam uma linguagem própria e seguem um formalismo tal como

a lógica de Hoare (1969). Isso posto, um sistema é responsável por analisar e veri�car se

a execução do código irá satisfazer as condições impostas pelas anotações. Um exemplo

dessa técnica formal diz respeito à linguagem Java: ela possui uma linguagem de anota-

ção denominada JML (Java Modelling Language) (LEAVENS et al., 2013) e pelo menos 3

(três) ferramentas que veri�cam se o código em Java respeita sua especi�cação JML, sendo

elas Krakatoa (FILLIÂTRE; MARCHÉ, 2007), KeY (BECKERT; HÄHNLE; SCHMITT,

2007) e Esc/Java2 (COK; KINIRY, 2004).

A plataforma Frama-C é outra ferramenta que utiliza a técnica de anotações, sendo

C a linguagem utilizada. Seu objetivo é realizar diversos tipos de análise em códigos na

linguagem-alvo, através do uso de plugins. O Frama-C é utilizado em uma gama de �nali-

dades, sendo algumas delas: veri�cação de ataques físicos em smart cards (BERTHOMÉ

et al., 2010); especi�cação formal e veri�cação automática de software ferroviário (PRE-

VOSTO et al., 2013); análise estática do núcleo de um servidor de virtualização e ge-

renciador de máquinas virtuais (PUCCETTI, 2010); entre outras. É importante observar

que as análises disponibilizadas pelos plugins abrangem desde interpretação abstrata, ob-

tendo, por exemplo, um conjunto de possíveis valores como resultado de uma função, à

veri�cação dedutiva de código, em que são geradas obrigações de prova para avaliar se

o código C satisfaz sua especi�cação em ACSL (ANSI/ISO-C Speci�cation Language),

linguagem formal utilizada pelo Frama-C para anotações no código.

Na plataforma Frama-C, a veri�cação dedutiva é realizada a partir de um plugin

denominado WP. As condições de veri�cação, também denominadas neste documento

como obrigações de prova, são um conjunto de fórmulas, formadas por hipóteses e objetivo,

que devem ser validadas através de um simpli�cador de obrigações de prova do WP

(realizando simpli�cações e obtendo provas triviais) ou através de provadores de teoremas,

executados externamente pelo WP. Esses provadores tanto podem ser automáticos, a

exemplo de solucionadores SMT (Satisfatibilidade Módulo Teoria), quanto interativos,

provendo assistência na prova manual pelo usuário.

A abordagem mais intuitiva para veri�car as obrigações de prova é através das provas

automáticas do WP, seguido dos provadores automáticos. Porém, ambos podem falhar,

Page 26: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

24

deixando ao usuário a opção da prova manual com os assistentes de provas. O WP pode se

comunicar diretamente com o assistente de provas Coq (BERTOT; CASTÉRAN, 2004),

mas também pode enviar as obrigações de prova a outros assistentes através da plata-

forma Why3 (FILLIÂTRE; PASKEVICH, 2013). O problema relacionado aos assistentes

de prova é que, geralmente, faz-se necessário experiência e habilidade do usuário para

a realização de provas manuais. Caso o usuário não tenha conhecimento e/ou estraté-

gia su�ciente, ele poderá despender mais tempo para veri�car a obrigação de prova e,

consequentemente, para validar o sistema. E o tempo é um fator crucial na indústria de

software.

Destarte, propomos uma solução que possa combinar a prova automática com a ma-

nual: permitir ao usuário realizar alterações manuais nas obrigações de prova, chegando

a um estado em que possam ser provadas automaticamente. Essa solução foi produzida

na forma de uma extensão para o WP, sendo implementado diretamente no código-fonte

do plugin. Batizada com o nome WPTrans, a extensão acessa as obrigações de prova

diretamente do WP e disponibiliza-os ao usuário para que este possa aplicar um con-

junto de regras de inferência implementadas na extensão. Por �m, as obrigações de prova

manipuladas podem ser enviadas a provadores conectados ao WP para veri�cação.

Descrevemos nesta pesquisa a justi�cativa para a construção do WPTrans, as regras de

inferência implementadas, sua interface e formas de interação com o usuário, outras fun-

cionalidades presentes na extensão, estratégias tomadas na implementação do WPTrans

incluindo modi�cações realizadas no WP e, �nalmente, testes realizados com a extensão.

Nesta pesquisa foi crucial a compreensão e a experiência em assistentes de prova, pois

várias funcionalidades e regras de inferência implementadas no WPTrans foram inspira-

das em alguns provadores interativos de teoremas já disponíveis à comunidade. Um dos

principais assistentes selecionados é o Coq (BERTOT; CASTÉRAN, 2004), pois o WP

se comunica diretamente com ele para a realização de provas manuais. Além de obter

regras de inferência com o Coq, também realizamos comparações entre esse programa e o

WPTrans para analisar a e�ciência e usabilidade da extensão para o WP.

O autor desta dissertação esteve envolvido anteriormente com outra pesquisa relaci-

onada aos métodos formais. Realizado no período entre janeiro de 2010 e julho de 2012,

o projeto consistiu em desenvolver um plugin para a plataforma de especi�cação formal

Rodin que permitisse o uso de solucionadores SMT, veri�cadores que realizam decisões

com relação a problemas de Satisfatibilidade Módulo Teorias, na resolução de obriga-

ções de prova geradas pela plataforma. Esta pesquisa fez parte do projeto de pesquisa

Page 27: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

25

SMT-SAVeS, sendo alguns de seus focos �projetar, desenvolver, implementar e disseminar

técnicas de prova automática de teoremas abertas, con�áveis, e�cientes e versáteis�, apli-

cando os resultados para melhorar o apoio à veri�cação formal no desenvolvimento de sis-

temas de softwares e para aumentar a produtividade de assistentes de prova (DÉHARBE,

2016). A plataforma Rodin, os problemas SMT e seus respectivos solucionadores são abor-

dados também nesta pesquisa, sendo suas de�nições aprofundadas nos capítulos subse-

quentes.

1.1 Objetivo Proposto

O objetivo proposto deste trabalho é apresentar uma extensão para o WP que possa

aproveitar as características de funcionamento de provadores automáticos e interativos

de teoremas. Essa solução possui um conjunto de regras de inferência disponíveis ao

usuário para modi�car manualmente uma obrigação de prova, mas, também, permite que o

usuário execute provadores automáticos nessa obrigação de prova modi�cada, facilitando e

agilizando veri�cações que não tiveram sucesso de forma totalmente automática. Listamos

a seguir uma sequência de objetivos especí�cos para compreender o problema e propor

uma solução para saná-lo.

1. Apresentar a estrutura e utilidade da plataforma Frama-C na análise de códigos na

linguagem C;

2. Explicar o funcionamento do WP, um plugin do Frama-C utilizado na veri�cação

dedutiva de sistemas em C;

3. Descrever di�culdades e problemas relacionados ao uso do WP; e

4. Propor uma solução para os problemas abordados no item anterior, exibindo resul-

tados de testes e discussões acerca do futuro da pesquisa.

1.2 Organização do trabalho

O trabalho está estruturado em 7 (sete) capítulos, sendo um capítulo de introdução,

2 (dois) capítulos de fundamentação teórica, 3 (três) capítulos destinados ao seu desen-

volvimento, e o último de considerações �nais. A seguir, caracterizamos o teor de cada

um.

Page 28: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

26

O Capítulo 2 apresenta a linguagem ACSL e a plataforma Frama-C. Essa plataforma

realiza um pré-processamento das anotações em ACSL, junto com o código C, disponibi-

lizando ambos para os plugins acoplados ao sistema. Esse capítulo ainda descreve como o

pré-processamento é realizado e disponibilizado para os plugins acoplados ao programa,

assim como são comentadas as funcionalidades de alguns desses plugins.

O Capítulo 3 apresenta o plugin WP: sua função, como é ligado ao Frama-C, sua

representação interna e fundamentos teóricos por trás de sua construção. Além disso, esse

capítulo detalha como uma obrigação de prova é produzida, qual seu papel na veri�cação

formal, bem como as formas disponíveis de veri�cação de sua validade. Por último, ele

apresenta os problemas relacionados ao WP e algumas propostas para contorná-los.

No Capítulo 4 é apresentada uma proposta para solucionar os problemas citados

no capítulo anterior: o WPTrans, uma extensão para o WP. Ele detalha as principais

funcionalidades do WPTrans, sendo elas a aplicação de regras de inferência, envio da

prova a provadores automáticos de teoremas e como o WPTrans pode reduzir o impacto

dos problemas relacionados ao WP.

O Capítulo 5 aborda outras funcionalidades do WPTrans que não foram mencionadas

no capítulo anterior: a descrição de interface visual de uso, formas de interação entre o

usuário e a extensão, estratégias aplicadas na implementação do WPTrans, organização

do código-fonte, experiências e di�culdades no andamento da pesquisa e, por último,

funcionalidades descartadas ao longo do desenvolvimento do plugin.

Já no Capítulo 6 são mostradas as primeiras análises experimentais realizadas com a

extensão. Foram realizadas comparações entre o uso do WPTrans (com os solucionadores

SMT Alt-Ergo (CONCHON; IGUERNELALA, 2014), Z3 (MOURA; BJØRNER, 2008)

e CVC4 (BARRETT et al., 2011)) e o Coq para a veri�cação de obrigações de provas,

identi�cando a facilidade e quantidade de comandos necessários para a realização das

provas. Também tentamos veri�car obrigações de prova usando somente o WPTrans,

examinando a e�ciência e usabilidade da extensão.

Por último, apresentamos as considerações �nais no Capítulo 7. Nesse capítulo há

uma discussão acerca dos resultados, argumentando como o WPTrans pode in�uir no

Frama-C e no WP, apresentação de trabalhos futuros e um levantamento da questão

sobre a corretude do WPTrans. Concluímos o capítulo com propostas para assegurar que

a implementação e a execução da extensão sejam corretas, isto é, que não comprometam

a veri�cação do WP.

Page 29: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

27

2 A linguagem de especi�cação

ACSL e a plataforma Frama-C

2.1 A linguagem de especi�cação ACSL

A ANSI/ISO C Speci�cation Language(ACSL) é uma linguagem usada na especi�-

cação formal de código C (BAUDIN et al., 2015d). As anotações ACSL são compostas

de palavras-chave e fórmulas na lógica de primeira ordem com tipos, sendo inseridas no

código na forma de comentários. Para isso, é necessário que se insira o símbolo @ após /*

e //.

Essa linguagem pode de�nir o contrato de funções, isto é, pré e pós-condições, asser-

ções na execução de uma função, lemas e axiomas para auxiliar na especi�cação, condições

para execução de um laço, entre outros. A Figura 1 apresenta uma função em C especi�-

cada em ACSL, com um subconjunto das possíveis anotações. Essa função, denominada

equal, é o predicado de igualdade, célula por célula, sobre dois arranjos de tamanho n. Os

tipos inseridos em ACSL podem ser tanto os tipos em C (int, float, char etc.) assim

como tipos matemáticos e lógicos (integer para números inteiros, real para números

reais etc.).

/*@

predicate

EqualRanges{A,B}(int * a, integer n, int * b) =

\forall integer i; 0 <= i < n ==> \at(a[i], A) == \at(b[i], B);

/*@

requires \valid_read(a + (0..n-1));

requires \valid_read(b + (0..n-1));

assigns \nothing;

ensures \result <==> EqualRanges{Here ,Here}(a, n, b);

*/

int equal(const int * a, unsigned int n, const int * b)

{

/*@

loop invariant 0 <= i <= n;

loop invariant EqualRanges{Here ,Here}(a, i, b);

Page 30: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

28

loop assigns i;

loop variant n-i;

*/

for (unsigned int i = 0; i < n; ++i)

{

if (a[i] != b[i])

{

return 0; //false

}

}

return 1; //true

}

Figura 1: Exemplo de função C anotada com especi�cação em ACSL

As pré e pós-condições da função são de�nidas, respectivamente, pelas palavras-chave

requires e ensures, enquanto a palavra-chave \result representa o valor do seu resul-

tado. No exemplo da Figura 1, \result pode ter o valor 0 ou 1 e as precondições são de

que os vetores a e b sejam válidos, isto é, suas posições de memórias estejam alocadas para

leitura da posição 0 até n− 1, sendo n o tamanho dos vetores. A função \valid_read faz

parte de um conjunto de funções predeterminadas pela ACSL, sendo seu objetivo veri�car

se as regiões de memória determinadas pelo argumento são válidas. Além dessa função

podemos citar outras como \valid, que averigua se uma certa região de memória pode ser

tanto lida quanto escrita, \separated, que analisa se dois ponteiros ou vetores apontam

para regiões distintas de memória, e \freeable, que veri�ca se um ponteiro ou um vetor

podem ter suas regiões de memória liberadas de forma segura quando é usada a função

free do C. Essa função do C desaloca a memória de ponteiros, liberando-os para uma

realocação posterior.

As palavras-chave loop invariant, loop variant e loop assigns determinam con-

dições para a execução do laço. O valor do predicado de cada loop invariant deve ser

verdadeiro imediatamente antes, durante, e após sair do laço, antes da execução do co-

mando seguinte. Na especi�cação da Figura 1, i terá um valor entre 0 e n desde imedia-

tamente antes de começar o laço até imediatamente antes da execução de return 1.

A palavra-chave loop assigns identi�ca quais variáveis poderão ter seus valores mo-

di�cados após a execução do laço, sendo, no caso do exemplo, i a única variável cujo valor

pode ser alterado no laço. Essa palavra-chave pode ser usada apenas em variáveis criadas

antes do laço, isto é, se uma nova variável é declarada dentro de um for ou while ou

do-while, ela não deve ser especi�cada com loop assigns nesse mesmo laço. Já loop

variant é uma condição que indica a quantidade máxima de iterações que terá o laço,

diminuindo seu valor a cada iteração. O valor da expressão ao �m de cada iteração nunca

Page 31: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

29

deve ser maior que no seu início, além de que esse valor deve ser sempre positivo no início

da execução do laço.

A palavra-chave predicate de�ne predicados que auxiliam na escrita da especi�cação.

Podem ser inseridos rótulos na declaração das funções e predicados através de palavras

entre chaves (`{' e `}'), cuja função é indicar em qual estado da veri�cação devem ser

considerados os valores dos parâmetros. Na declaração EqualRanges, \at(a[i], A) e

\at(b[i], B) representam os valores de a[i] e b[i] nos estados determinados, respec-

tivamente, pelos rótulos A e B. O rótulo Here se refere ao estado das variáveis na exata

localização em que se encontra a anotação. No invariante de laço do exemplo, Here se

refere a a e b imediatamente antes de começar o laço. Já na pós-condição da função, Here

se refere ao estado de a e b logo após o término da mesma função. Outros exemplos de

rótulos são Old e Post, que indicam, respectivamente, o estado dos parâmetros antes e

após a execução de uma função.

O ACSL permite, também, criar funções, lemas e de�nições axiomáticas para auxiliar

na especi�cação. A Figura 2 mostra a de�nição de um lema, a�rmando que, para quaisquer

dois inteiros x e y tais que y é maior ou igual a x, x + y/2 é maior ou igual a x e menor

ou igual a y.

/*@ lemma mean_property:

\forall integer x,y; x <= y ==> x <= (x+y)/2 <= y;

*/

Figura 2: Exemplo de lemas em ACSL

A Figura 3 mostra um conjunto de de�nições axiomáticas, no qual se de�ne um

tipo int_list, um conjunto de funções associadas assim como axiomas, sentenças que

são assumidas como sempre verdadeiras. As funções podem ser apenas declaradas, sendo

suas de�nições determinadas pelos axiomas subsequentes. Os axiomas append_cons e

append_nil de�nem o comportamento das funções nil, cons e append.

/*@ axiomatic IntList {

type int_list;

logic int_list nil;

logic int_list cons(integer n,int_list l);

logic int_list append(int_list l1,int_list l2);

axiom append_nil: \forall int_list l; append(nil ,l) == l;

axiom append_cons: \forall integer n, int_list l1,l2;

append(cons(n,l1),l2) == cons(n,append(l1,l2));

}

*/

Figura 3: Exemplo de de�nições axiomáticas em ACSL

Page 32: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

30

A Figura 4 mostra uma função lógica que tem como argumento um número real x,

retornando 1 se x for positivo e 0 caso contrário.

//@ logic integer get_sign(real x) = x > 0.0 ? 1 : ( x < 0.0 ? -1 : 0);

Figura 4: Exemplo de função em ACSL

Uma outra palavra-chave presente no ACSL é o behavior, determinando �comporta-

mentos� que podem ser assumidos na especi�cação da função. No exemplo da Figura 5,

há dois comportamentos possíveis: caso x seja positivo, então o resultado deve ser o valor

100. Caso contrário, isto é, se x não for positivo, o resultado deve então ser 50. A cláusula

assumes determina em que situação o comportamento deve entrar em vigor, devendo a

sentença dessa cláusula ser verdadeira para isso. Já a cláusula ensures continua de�nindo

a pós-condição da função, porém devendo ser válida apenas se as condições assumes do

comportamento a que ela pertence estejam ativadas, isto é, as sentenças em assumes se-

jam verdadeiras. Um behavior deve ter sempre um nome e pode ter 0 (zero) ou mais

cláusulas assumes e ensures.

/*@

behavior is_pos:

assumes is_positive(x);

ensures \result == 100;

behavior is_neg:

assumes !is_positive(x);

ensures \result == 50;

disjoint behaviors;

complete behaviors;

*/

int tfun(int x) {

if (x > 0) return 100;

else {

return 50;

}

}

Figura 5: Exemplo de behavior em ACSL

Para um certo conjunto de valores é possível que tanto nenhum como mais de um com-

portamento sejam assumidos ao mesmo tempo. Para evitar a primeira situação utiliza-se

a cláusula complete behaviors: ela especi�ca que ao menos um comportamento deva

ser válido em cada execução da função. Já para evitar o segundo caso pode ser utilizada

a cláusula disjoint behaviors: ela determina que nenhum ou somente um comporta-

mento seja válido em cada execução da função. Essas duas cláusulas foram adicionadas no

Page 33: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

31

exemplo da Figura 5, pois a precondição da segunda cláusula é a negação da precondição

da primeira cláusula.

2.2 Frama-C

O Frama-C é uma plataforma aberta e extensível de análise de programas na lin-

guagem C, auxiliando na veri�cação formal de sistemas baseados nessa linguagem de

programação (CORRENSON et al., 2015). Possui um conjunto de plugins, provendo, no-

tadamente, análise estática e veri�cação formal de código em C. Uma nova versão do

Frama-C é lançada em média uma a duas vezes por ano, sendo a versão denominada de

acordo com o nome de um elemento químico. As versões estudadas nesta pesquisa foram

a Neon, lançada em março de 2014, Sodium, lançada em fevereiro de 2015, e Magnesium,

lançada em outubro do mesmo ano.

Essa plataforma lê e interpreta um código em C junto com sua especi�cação em

ACSL e realiza transformações nessa entrada, disponibilizando-o aos plugins acoplados.

Para isso, o Frama-C se baseia no CIL (C Intermediate Language), um front-end consti-

tuído por uma representação em alto nível da linguagem C assim como um conjunto de

ferramentas que permite tanto análises como transformações de código para programas

nessa linguagem (NECULA et al., 2002).

As análises do Frama-C são feitas sobre uma linguagem intermediária desenvolvida

como uma extensão de CIL, tratando, além de código C, anotações em ACSL (CUOQ et

al., 2012, p. 2). Porém, antes de o Frama-C traduzir o código para a variante do CIL, ela

faz uma normalização do código, sendo mostrada na Figura 6 a normalização do código

inserido na Figura 1. É possível notar que alguns símbolos matemáticos foram trocados

por outros com apenas um caractere, o comando for foi substituído pelo while e a ação

de retorno da função foi movida do laço para o �m da função.

/*@

predicate EqualRanges{A, B}(int *a, Z n, int *b) =

∀ Z i; 0 ≤ i < n � \at(*(a+i),A) ≡ \at(*(b+i),B);

*/

/*@ requires \valid_read(a+(0 .. n-1));

requires \valid_read(b+(0 .. n-1));

ensures \result 6≡ 0 ↔EqualRanges{Here , Here }(\old(a) ,\old(n) ,\old(b));

assigns \nothing;

*/

int equal(int const *a, unsigned int n, int const *b)

{

Page 34: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

32

int __retres;

{

unsigned int i;

i = (unsigned int)0;

/*@ loop invariant 0 ≤ i ≤ n;

loop invariant EqualRanges{Here , Here}(a, i, b);

loop assigns i;

loop variant n-i;

*/

while (i < n) {

if (*(a + i) != *(b + i)) {

__retres = 0;

goto return_label;

}

i ++;

}

}

__retres = 1;

return_label: return __retres;

}

Figura 6: Exemplo de normalização da função C anotada com especi�cação em ACSL

Após normalizar o código, o Frama-C o traduz para a variante do CIL, criando uma

árvore sintática abstrata com o resultado da tradução. Essa árvore associa cada anotação

ACSL ao trecho do código que ela especi�ca. Em seguida, ela é disponibilizada para os

plugins, permitindo que eles possam realizar análises estáticas no código processado. A

plataforma também tem a opção de criar uma árvore sintática abstrata sem a etapa de

tradução do CIL, gerando uma árvore com o código normalizado. O propósito dessa árvore

são para alguns casos especí�cos como transformações no código C (SIGNOLES et al.,

2015).

A cada distribuição do Frama-C se encontram já instalados um conjunto de plugins,

sendo também possível instalar outros na plataforma. A seguir são apresentados alguns

desses plugins :

• Value Analysis - Usando técnicas de interpretação abstrata, esse plugin calcula o

domínio de valores para cada variável do programa, isto é, os possíveis valores que

essas variáveis podem ter (CUOQ; YAKOBOWSKI; PREVOSTO, 2015).

• Impact Analysis - Esse plugin calcula, para uma dada instrução em C selecionada

pelo usuário, as demais instruções no programa que são in�uenciadas por ele. Se a

instrução selecionada for modi�cada, o conjunto de instruções mostradas pelo plugin

podem ter seus resultados modi�cados também. O Impact Analysis é executado no

resultado do Value Analysis, sendo dependente desse plugin (FRAMA-C, 2015).

Page 35: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

33

• PathCrawler - A função desse plugin é gerar automaticamente casos de testes para

um dado programa. Esses testes são criados de modo a cobrir todos os caminhos pos-

síveis de execução do código, podendo o usuário modi�car os critérios de cobertura.

Um exemplo desses critérios é a cobertura k-path, na qual os caminhos se limitam

a executar cada laço do código no máximo k vezes. O PathCrawler também pode

ser usado para detectar código impossível de ser executado, over�ow de inteiros,

variáveis não inicializadas e outros erros de execução (BOTELLA et al., 2009).

• Annotation Generation - Também denominado Runtime error annotation gene-

ration (RTE), essa extensão gera, automaticamente, novas anotações para o código,

veri�cando possíveis erros de execução, como, por exemplo: divisão por zero, over-

�ow de inteiros, acesso de memória inválido etc. (HERRMANN; SIGNOLES, 2015).

Para exempli�car seu uso, na Figura 7 se encontra a função equal da Figura 1 após

as inserções inseridas pelo RTE, sendo as anotações escritas com o texto assert

rte geradas pelo plugin. As duas primeiras asserções inseridas veri�cam se as posi-

ções de memória a+ i e b+ i são válidas para leitura, enquanto na terceira e última

asserção é analisado se não há risco de over�ow ao incrementar a variável i.

int equal(int const *a, unsigned int n, int const *b)

{

int __retres;

{

unsigned int i;

i = (unsigned int)0;

/*@ loop invariant 0 ≤ i ≤ n;

loop invariant EqualRanges{Here , Here}(a, i, b);

loop assigns i;

loop variant n-i;

*/

while (i < n) {

/*@ assert rte: mem_access: \valid_read(a+i); */

/*@ assert rte: mem_access: \valid_read(b+i); */

if (*(a + i) != *(b + i)) {

__retres = 0;

goto return_label;

}

/*@ assert rte: unsigned_overflow: i+1 ≤ 4294967295; */

i ++;

}

}

__retres = 1;

return_label: return __retres;

}

Figura 7: Exemplo de função C com anotações geradas pelo AnnotationGeneration.

Page 36: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

34

• Jessie e WP - Esses plugins permitem veri�car se o código do programa satisfaz a

uma especi�cação escrita em ACSL. Para isso, geram obrigações de prova, estruturas

compostas de fórmulas lógicas que devem ser provadas a partir de um provador

interno ou externo. O Jessie era disponibilizado junto com o Frama-C nas primeiras

versões da plataforma, sendo subsequentemente substituído pelo WP.

Os plugins podem ser utilizados em conjunto para obter uma veri�cação mais com-

pleta. Uma das formas existentes é executá-los sequencialmente, sendo o resultado da

análise de um plugin a entrada do plugin seguinte. O outro modo possível é através da

combinação de análises parciais realizadas por diferentes plugins, constituindo uma ve-

ri�cação mais completa. Um exemplo de combinação de plugins é o uso do RTE para

gerar condições ACSL com o propósito de veri�car erros de execução do programa e,

em seguida, o uso do WP (ou do Jessie) para realizar a veri�cação dedutiva do código e

do ACSL de modo a cobrir esses erros. Esse exemplo é discutido com mais detalhes no

próximo capítulo.

Figura 8: Arquitetura do Frama-C.Fonte: Cuoq et al. (2012). p. 3

O Frama-C realiza o controle das entradas e saída das extensões a �m de evitar

con�itos no acesso aos dados assim como na exibição dos resultados. A plataforma também

fornece diversos serviços para os plugins, como, por exemplo, journaling (registro das ações

tomadas pelas extensões e pelo próprio Frama-C), mecanismos de transmissão e impressão

de mensagens, persistência de dados, funções e estruturas de dados padronizadas, entre

outros. É permitido ao usuário trabalhar com diferentes programas paralelamente, através

da noção de projetos. Um projeto é uma representação do programa junto com as análises

aplicadas nele e os parâmetros con�gurados para a realização dessas análises. O Frama-

C pode armazenar e carregar na memória múltiplos projetos, sem que os dados de um

Page 37: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

35

projeto inter�ram nos demais (CUOQ et al., 2012, p. 4). A Figura 8 ilustra a arquitetura

do Frama-C com relação aos plugins e serviços disponíveis.

O Frama-C pode ser executado tanto por linha de comando como através de uma

interface grá�ca, sendo a segunda versão ilustrada na Figura 9. Na janela de código mais

à direita, é exibido o código original C mais a especi�cação ACSL e, na janela central, a

versão normalizada do código mais a anotação. O usuário só pode interagir com o código

normalizado, executando, por exemplo, a análise de um plugin instalado.

Na coluna mais à esquerda se encontram, na região superior, a árvore do projeto, na

qual são exibidos os arquivos-fontes em C e, para cada arquivo, tanto suas funções em

C como as de�nições criadas nas anotações. Já na região inferior da mesma coluna se

encontram as opções de con�guração de alguns dos plugins presentes na plataforma.

Na região central inferior, se encontra um conjunto de informações disponíveis ao

usuário, divididas em abas. Elas exibem mensagens enviadas pelos plugins, assim como

pelo próprio Frama-C, registro das ações ocorridas na plataforma, dependências entre

partes do código e listagem das obrigações de prova.

Os círculos coloridos em verde e as circunferências azuis demarcam sentenças ACSL

que precisam ser provadas, havendo 0 (zero), 1 (um) ou mais obrigações de prova para

cada demarcação, geradas pelo WP. No próximo capítulo é descrito de modo mais de-

talhado o funcionamento desse plugin, incluindo o processo de produção das obrigações

de prova assim como a sua estrutura. A descrição do WP também é imprescindível para

compreender e se aprofundar no foco desta pesquisa.

Page 38: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

36

Figura 9: Interface grá�ca do Frama-C

Page 39: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

37

3 O plugin WP

A nomenclatura WP é uma sigla para Weakest Precondition, pois utiliza-se da técnica

de cálculo de precondição mais fraca para a prova de propriedades funcionais, baseada nos

trabalhos de Hoare (HOARE, 1969), Floyd (FLOYD, 1967) e Dijkstra (DIJKSTRA, 1968)

sobre corretude de programas (CUOQ et al., 2012). O WP é um dos plugins do Frama-C,

sendo distribuído junto com a plataforma. A função do plugin é veri�car formalmente

se programas na linguagem C satisfazem seus contratos escritos em ACSL. O WP pode

veri�car tanto as propriedades funcionais (os resultados das funções condizem com a sua

especi�cação) como sua segurança (safety) através da análise de propriedades genéricas:

acessos de memória (se são válidos), ausência de estouro aritmético (arithmetic over�ow),

ausência de divisão por zero, etc.

O WP surgiu como uma alternativa ao plugin Jessie, que também utiliza a técnica do

cálculo da precondição mais fraca. Porém, ambos possuem formas diferentes de representar

a memória. O modelo de memória do Jessie é e�ciente para uma variedade de programas

em C, porém ela não permite a veri�cação de programas quando há uma manipulação de

memória em um nível mais baixo, como conversões de tipos de ponteiros. Além disso, o

Jessie compila o programa em C para o Why3, uma solução que impossibilita o usuário

de combinar os resultados desse plugin com outros como o Value Analysis por exemplo.

Para se compreender o funcionamento do WP é necessário que se conheça o princípio

do cálculo da precondição mais fraca. Esse princípio é baseado na semântica axiomática

expressa com as triplas de Hoare cuja forma é:

{P}C{Q}

na qual P e Q são asserções (fórmulas lógicas), e C é uma sentença (um comando) do

código. Essa tripla determina que, caso a precondição P seja verdadeira antes da execução

de C, então a pós-condição Q será verdadeira após sua execução. O objetivo dessas triplas

é assegurar que os valores das variáveis do programa atendam a determinadas restrições

após a execução de cada comando. Um exemplo se encontra na tripla a seguir:

Page 40: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

38

{x+ 1 > 0}x = x+ 1; {x > 0}

Se a expressão x+ 1 > 0 for verdadeira antes da execução de x = x+ 1, então x > 0

será verdadeira após a execução. Hoare (1969) formaliza um conjunto de axiomas e de

regras de inferência para realizar a veri�cação completa de um programa, sendo cada regra

relacionada com um tipo de comando, exempli�cando a aplicação dessas regras com uma

linguagem simples orientada a procedimentos. Não há a presença de efeitos colaterais

na avaliação de condições e expressões nessa linguagem pois, em caso contrário, �seria

necessário primeiramente provar a ausência desses efeitos colaterais em cada caso antes

de aplicar a técnica de prova adequada� 1 (HOARE, 1969, p. 3). Esses axiomas e regras

são descritos por Burghardt e Gerlach (2015) para a linguagem C.

Para validar um projeto no WP, isto é, assegurar que a implementação corresponda

à especi�cação, é necessário provar todas as OPs produzidas. Elas podem ser veri�cadas

através do simpli�cador interno ao plugin, denominado Qed, através de solucionadores

SMT ou utilizando assistentes de prova (CORRENSON, 2014). Para que a problemática

relacionada ao WP possa ser claramente explicada, descrevemos nas próximas seções

algumas de�nições em que o plugin se baseia para a realização da veri�cação dedutiva e

os elementos que compõem o WP, sendo apresentado na Figura 10 um esquema geral da

execução do WP.

Figura 10: Esquema do WP

Introduziremos nas seguintes seções as regras de Hoare (3.1) e a técnica de Floyd

(3.2), a de�nição de precondição mais fraca, assim como sua relação com as triplas de

Hoare e o WP (3.3), a estrutura e a linguagem das obrigações de prova do WP (3.4), a

plataforma Why3 (3.5), a teoria básica sobre provadores SMT (3.6) e assistentes de prova

1No original: �it would be necessary to prove their absence in each case before applying the appropriateproof technique�.

Page 41: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

39

(3.7) e, por último, a relação entre essas ferramentas com o WP, esclarecendo o problema

motivador da pesquisa (3.8).

3.1 Regras de inferência de Hoare

Antes de dar prosseguimento à explicação da lógica de Hoare, expomos a notação

utilizada para descrever as regras de inferência presentes desta seção em diante no do-

cumento. Todas as regras foram formalizadas usando notação usual para a de�nição de

regras de inferência, na qual um sequente (H ` O) é composto de 0, 1 ou mais hipóteses

(H) e um objetivo (O). Observando a Figura 11, acima da linha horizontal se encontram

os antecedentes da regra, nas quais podem haver um ou mais hipóteses. Já abaixo da

mesma linha se encontra o consequente da regra, possuindo apenas uma obrigação de

prova.

H1 ` O1 · · · Hn ` On

H ` O

Figura 11: Exemplo da notação utilizada

Essa notação de�ne que para provar o consequente basta veri�car todos os antece-

dentes, isto é, se todos os antecedentes forem verdadeiros, então o consequente também

será. Na Figura 12 se encontra um exemplo dessa notação. Ela mostra que se provarmos

os objetivos x = 5 e z = 10, podemos inferir que a conjunção de ambas (x = 5 ∧ z = 10)

também está correta.

x = 5⇒ z = 10, x = 5 ` x = 5 x = 5⇒ z = 10, x = 5 ` z = 10

x = 5⇒ z = 10, x = 5 ` x = 5 ∧ z = 10

Figura 12: Exemplo de uso da notação

Há situações em que queremos provar uma sentença mas temos apenas o consequente.

Como ele (o consequente) só é verdadeiro se os antecedentes também o forem, podemos

veri�car esses antecedentes para validar a obrigação de prova veri�cada. No exemplo

Page 42: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

40

anterior, se tivermos apenas x = 5 ⇒ z = 10, x = 5 ` x = 5 ∧ z = 10 podemos obter

os dois antecedentes eliminando a conjunção e criando duas novas obrigações de prova,

sendo o objetivo de cada uma um dos termos da conjunção. A obtenção dos antecedentes

do exemplo segue a regra de inferência eliminação de conjunção no objetivo. Essa é uma

formalização utilizada neste e nos próximos capítulos desta dissertação.

3.1.1 Regra da atribuição, na ausência de efeitos colaterais

Essa regra é fundamental na lógica de Hoare, determinando a veri�cação de um co-

mando no caso em que ele é uma atribuição. Considere a seguinte tripla de Hoare:

{y == 1} x = y; {x == 1}

se y possui o valor 1 antes, x terá esse mesmo valor após a atribuição. Essa tripla indica

justamente isto: se na precondição y = 1, então x = 1 na pós-condição. Abaixo um outro

exemplo com atribuição:

{y + z == 1} x = y + z; {x == 1}

Da mesma forma que na tripla anterior, se y + z == 1 antes da atribuição, então

x == 1 após esta. Com isso pode-se observar que o valor no lado direito da atribuição

na precondição (1 no exemplo) é transferido à variável no lado esquerdo da atribuição na

pós-condição (x no exemplo). A formalização dessa regra para todos os casos de atribuição

sem efeitos colaterais é apresentada na Figura 13, em que x é uma variável livre, a é uma

expressão e P é uma propriedade (um predicado).

{P [x 7→ a]} x = a; {P}

Figura 13: Regra da atribuição

Essa regra determina que, para a propriedade P ser verdadeira após a atribuição (x =

a), P deve ser verdadeira também antes, mas com todas as ocorrências de x substituídas

pela expressão a. Uma condição para essa regra ser aplicada é que a expressão de atribuição

não pode ter efeitos colaterais. Caso contrário, devem ser realizadas novas veri�cações para

assegurar que a expressão esteja livre de efeitos colaterais e/ou reescrever a expressão

de modo eliminar essa característica. Hoare (1969) utiliza a sintaxe de uma linguagem

Page 43: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

41

procedural simples para a apresentação das regras, já aqui utilizamos a sintaxe de C para

os comandos devido a ser essa a linguagem analisada pelo Frama-C.

Na Figura 14 se encontra um exemplo com predicados maiores, sendo a propriedade

P = x > 0 && a[2*x] = 0. Para que P seja verdadeiro, é necessário que P [x 7→ y]

também o seja, isto é, y+1 > 0 && a[2*(y+1)] = 0. Essa fórmula é obtida substituindo-

se todas as aparições de x por y+1 no predicado.

{y+1 > 0 && a[2*(y+1)] == 0;}x = y+1;

{x > 0 && a[2*x] == 0;}

Figura 14: Exemplo da regra da atribuição

3.1.2 Regra da sequência

A regra da sequência formaliza a tripla no caso de uma sequência de comandos, a partir

das pré e pós-condições individuais de cada sentença. A Figura 15 exibe essa formalização.

A pós-condição do primeiro comando deve ser igual à precondição do comando seguinte.

C1 e C2 são comandos e P , Q e R são predicados.

{P} C1 {Q}{Q} C2 {R}{P} C1C2 {R}

Figura 15: Regra da sequência

3.1.3 Regra da consequência

Essa regra é utilizada para deduzir novas a�rmativas a partir das asserções já provadas.

Em algumas situações as pré e pós-condições existentes podem não se adequar a uma regra

que desejamos aplicar. Por exemplo, uma precondição pode estar logicamente mais fraca

do que queremos, assim como uma pós-condição pode estar logicamente mais forte do que

precisamos. Por exemplo, a seguinte tripla de Hoare

{\true;} x = 3; {x == 3;}

Page 44: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

42

é válida, porém a regra de atribuição não pode ser aplicada diretamente nessa tripla. Caso

a precondição \true fosse transformada em (x == 3), logicamente equivalentes, a regra

de atribuição poderia ser �nalmente aplicada. Esse tipo de transformação é possível com

a regra da consequência, sendo mostrado na Figura 16 os dois casos possíveis de aplicá-la.

O caso à esquerda na �gura é utilizado para fortalecer a precondição, já o caso à direita

de�ne como enfraquecer a pós-condição. P , P ′, Q e Q são predicados e C um comando.

{P ′} C {Q}P ⇒ P ′

{P} C {Q}

{P} C {Q′}Q′ ⇒ Q

{P} C {Q}

Figura 16: Formas da regra da implicação

Um exemplo de uso dessa regra é apresentada após a explicação da regra da escolha,

logo a seguir.

3.1.4 Regra da escolha

A regra de escolha é aplicável nos comandos do tipo if(...){...} else{...}, pre-

sentes na linguagem C, sendo sua formalização exibida na Figura 17. P , Q e b são predi-

cados; e C1 e C2 são sequências de comandos.

{P ∧ b} C1 {Q}{P ∧ (¬b)} C2 {Q}

{P} if (b) C1 else C2 {Q}

Figura 17: Regra da escolha

Essa regra também pode ser usada no caso em que não haja a cláusula else{...},

sendo ela considerada como uma sentença vazia. A seguir se encontra um exemplo de uso

dessa regra junto com a regra da consequência. Suponha que queiramos provar:

{0 <= i < n} if (i < n-1) {i = i + 1;} else {i = 0;} {0 <= i < n}

para isso devemos provar as duas premissas da regra da escolha:

Page 45: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

43

{0 <= i < n && i < n-1} i = i+1; {0 <= i < n}{0 <= i < n && !(i < n-1)} i = 0; {0 <= i < n}

{0 <= i < n} if (i < n-1) {i = i+1;} else {i = 0;} {0 <= i < n}

ou, com as premissas simpli�cadas:

{0 <= i < n - 1} i = i+1; {0 <= i < n}{i == n - 1} i = 0; {0 <= i < n}

{0 <= i < n} if (i < n-1) {i = i+1;} else {i = 0;} {0 <= i < n}

Para provar a primeira premissa aplicamos a regra da atribuição:

{0 <= i+1 < n} i = i+1; {0 <= i < n}

reescrevemos a precondição:

{-1 <= i < n-1} i = i+1; {0 <= i < n}

e aplicamos a regra da consequência, fortalecendo a precondição:

{0 <= i < n-1} i = i+1; {0 <= i < n}

Para a segunda premissa podemos usar a mesma estratégia. Aplicamos a regra da

atribuição:

{0 <= 0 < n} i = 0; {0 <= i < n}

como a precondição é sempre verdadeira, podemos fortalecê-la substituindo-a pela pre-

condição original:

{i == n - 1} i = 0; {0 <= i < n}

provando assim que a tripla de Hoare veri�cada está correta.

3.1.5 Regra do laço

Essa regra diz respeito à veri�cação de laços while do C, formalizada na Figura 18. A

fórmula P , também chamada de invariante de laço (loop invariant), deve ser uma fórmula

verdadeira durante toda a execução do laço, assumindo que a guarda é satisfeita. P e B

são predicados e C uma sequência de comandos.

Page 46: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

44

{P ∧B} C {P}{P} while (B) C {¬(B) ∧ P}

Figura 18: Regra do laço

3.1.6 Regras derivadas

Os demais tipos de comandos em C podem ser reescritos de acordo com as regras

anteriores, de modo a cobrir por completo a sintaxe da linguagem C. A Figura 19 exibe um

exemplo de reescrita de comandos do tipo switch para comandos if-else, possibilitando

a aplicação da regra da escolha (outro exemplo que podemos citar é a transformação de

comandos do tipo for em while, possibilitando o uso da regra do laço).

switch(E){

case E1: Q1; break; ...

case En: Qn; break;

default: Q0; break;

}

if (E == E1){

Q1;

} else ... if (E == En){

Qn;

} else {

Q0;

}

Figura 19: Exemplo de reescrita de comando para aplicação da regra da escolha.Fonte: adaptado de Burghardt e Gerlach (2015, p. 21)

Burghardt e Gerlach (2015) também abordam funções recursivas e o comando goto.

Para o primeiro caso, é necessário um invariante que se mantenha válido durante toda a

cadeia de chamadas da função, enquanto, no segundo, é apontada uma solução discutida

em Floyd (1967), uma vez que esse comando não pode ser veri�cado com o cálculo de

Hoare. Essa técnica é apresentada na próxima seção.

3.2 Técnica de Floyd

Na técnica de veri�cação de programas apresentada por Floyd (1967), o programa

é representado através de um �uxograma. Basicamente cada nó do �uxograma é um

comando, havendo nós a mais para indicar entradas e saídas do programa. Entre cada dois

nós é inserida uma asserção, de modo que haja sempre uma asserção antes e uma depois

de cada comando. Uma interpretação de um programa é um �uxograma com asserções

representando seu comportamento. Por exemplo, a Figura 20 é uma interpretação de um

programa que calcula a soma de todos os valores de um array, utilizando uma linguagem

Page 47: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

45

com construções simples. É possível notar que esse programa pode ser implementado em

C utilizando o comando goto.

start

i ← 1

S ← 0

i > n?

No

Yes

HALT

S ← S + ai

i ← i + 1

n ∈ J+

n ∈ J+ ∧ i ∈ J+ ∧ i ≤ n ∧ S =i∑

j=1

aj

n ∈ J+ ∧ i = 1

n ∈ J+ ∧ i ∈ J+ ∧ i ≤ n ∧ S =i−1∑j=1

aj

n ∈ J+ ∧ i = n+ 1 ∧ S =i−1∑j=1

aj; i. e., S =n∑

j=1

aj

n ∈ J+ ∧ i = 1 ∧ S = 0

n ∈ J+ ∧ i ∈ J+ ∧ i ≤ n+ 1 ∧ S =i−1∑j=1

aj

n ∈ J+ ∧ i ∈ J+ ∧ 2 ≤ i ≤ n+ 1 ∧ S =i−1∑j=1

aj

Figura 20: Exemplo de interpretação de um programa que calcula a soma dos valores deum vetor.

Fonte: Adaptado de Floyd (1967, p. 2)

O propósito da técnica é provar que se a asserção na entrada do �uxograma for

verdadeira, então a asserção na saída também será. Para isso, é realizada uma veri�cação

em cada comando, devendo provar que se uma asserção P antes de um comando C for

verdadeira, a asserção seguinte Q também será após a execução desse comando. Em

Page 48: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

46

outras palavras, é preciso provar a tripla {P}C{Q}. Devem ser criados sequentes para

cada veri�cação da interpretação, sendo suas formas de�nidas a partir do tipo do nó. Floyd

(1967) demonstra o uso dessa técnica com a mesma linguagem da Figura 20, de�nindo

cinco tipos de nós possíveis para um �uxograma e como a veri�cação é realizada para

cada tipo, sendo eles mostrados na Figura 21.

x ← E

A

B

φ

yes no

A

B1 B2

A1

A2

B

START

B

HALT

A

Figura 21: Tipos de nós do �uxogramaFonte: Adaptado de Floyd (1967, p. 5)

O primeiro caso é o mais complexo de todos, sendo o sequente a ser provado ∃x0 ·(x =

E(x0/x))∧A(x0/x) ` B. A expressão E(x0/x) signi�ca E com todas as ocorrências de x

substituídas por x0, sendo o mesmo válido para A. No segundo caso, seleção de caminho,

deve-se provar (A∧φ ` B1) e (A∧¬φ ` B2). No terceiro caso, união de caminhos, deve-se

provar A1 ∨ A2 ` B. No quarto e quinto casos, não é necessário realizar nenhuma prova,pois para ambos os tipos de nós o sequente produzido é ` >.

Floyd (1967) também discute como determinar as asserções para veri�car a corretude

de um programa. Para isso, ele de�ne o conceito �consequente veri�cável mais forte�2.

O consequente veri�cável mais forte de um comando c precedido por uma asserção P é

uma asserção Q∗ tal que Q∗ ⇒ Q para toda asserção Q que satisfaça {P}c{Q}. Com esse

conceito é possível veri�car a corretude de um programa com uma asserção inicial I e

uma �nal F encontrando o consequente veri�cável mais forte F ∗ ao �m do �uxograma e

veri�cando se F ∗ ⇒ F . Floyd (1967) especi�ca como o consequente veri�cável mais forte

pode ser encontrado em cada tipo de nó, exempli�cando-o com uma versão mais simples

da linguagem ALGOL.

2No original: �strongest veri�able consequent�.

Page 49: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

47

Na próxima seção é discutida a técnica da precondição mais fraca, relacionando-a

com o cálculo de Hoare e a técnica apresentada por Floyd (1967). Nós iremos nos referir

à técnica introduzida nesta seção como Técnica de Floyd.

3.3 Precondição mais fraca

OWP se baseia nas regras supracitadas para a veri�cação do código em C, utilizando-

se da técnica de precondição mais fraca. Essa técnica consiste na situação em que dada

uma pós-condição Q e uma sentença s, calcular a propriedade menos restritiva para que

Q seja verdadeiro após a execução de s, respeitando as regras de Hoare. Baudin et al.

(2015a) descrevem uma função wp que calcula essa precondição mais fraca, através da

seguinte formalização:

{wp(s,Q)}s{Q}

A apresentação dessa função é imprescindível na explicação de contratos de funções,

elemento de veri�cação também presente no WP. O contrato consiste na situação em que

dadas as precondições e o conjunto de comandos da função, veri�ca-se se a pós-condição

será válida ao �m de sua execução (da função). Seja a veri�cação de uma função dada

pela seguinte tripla:

{P}f{Q}

Podemos ter, pela de�nição de wp, a tripla descrita a seguir:

{wp(f,Q)}f{Q}

O método tomado pelo WP é, a partir da veri�cação da pós-condição Q e dos co-

mandos de f , chegar à precondição mais fraca (wp(f,Q)), veri�cando se a precondição

original P implica na precondição mais fraca, isto é, se as condições para a execução da

função calculadas pelo WP estão de acordo com a especi�cação prévia da função. Isso é

formalizado na regra de inferência subsequente:

(P ⇒ wp(f,Q)) {wp(f,Q)}f{Q}{P}f{Q}

Page 50: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

48

Outro tópico abordado por Baudin et al. (2015a) é o término da execução do programa.

Uma execução pode ser �nalizada por algum tipo de erro, sendo ele, por exemplo, um

acesso a uma região de memória inválida ou uma divisão por zero. Para que o WP possa

veri�car esses tipos de erros é necessário que estejam explicitados na anotação ACSL,

como no exemplo da Figura 7(p. 33). O plugin RTE, descrito na página 33, é capaz de

produzir anotações lógicas para que sejam veri�cados os tipos de erros supracitados. Outro

plugin que também pode realizar algumas dessas veri�cações é o Value Analysis, descrito

na página 32.

Na seção seguinte é apresentada a estrutura das obrigações de prova, assim como

outras de�nições associadas a elas.

3.4 Obrigação de prova

As obrigações de prova são produzidas a partir das técnicas descritas nas seções an-

teriores deste capítulo, mas há outras questões que também in�uenciam na quantidade

e complexidade das obrigações de provas geradas. Essas questões são apresentadas nesta

seção, começando pela descrição das estruturas das obrigações de prova. Para simpli�car

o uso dessa denominação, obrigação de prova é referida como OP desse ponto em diante

no documento.

A lógica presente nas OPs é, assim como na ACSL, de primeira ordem dotada de

tipos. É de�nida nessa lógica os seguintes tipos básicos: int, addr, real, bool, prop e array

de um outro tipo, mas o WP pode criar novos tipos para, por exemplo, representar structs

C. Esses tipos não estão determinados no manual do WP mas foram encontrados em seu

código. O tipo int é o tipo de uma expressão inteira, real é o tipo de uma expressão

real, bool é o tipo de uma expressão booleana e addr é o tipo de variáveis e termos que

representem ponteiros. A representação da memória é discutida com detalhes a partir da

página 52. Finalmente, o tipo prop é utilizado para fórmulas, porém como uma fórmula

pode ser representada tanto como um termo do tipo prop como bool no WP, decidimos não

distinguir termos e fórmulas desse ponto em diante no documento quando nos referimos

a termos da lógica presente nas OPs do plugin. Não encontramos uma gramática para a

construção de termos, mas identi�camos as constantes e operações de�nidas, sendo elas

listadas na Figura 22. O símbolo τ é usado para representar um termo.

Page 51: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

49

trueconstantes booleanas

false

τ + · · ·+ τ adição

τ ∗ · · · ∗ τ multiplicação

τ [τ ] acesso a posição de array

τ [τ → τ ] modi�cador de array

τ.τ acesso a campo de struct

τ{τ = τ} modi�cador de campo de struct

¬τ negação

τ % τ operação módulo

τ = τ igualdade

τ 6= τ diferença

τ < τ menor que

τ ≤ τ menor ou igual

if τ then τ else τ condição ternária

τ ∧ · · · ∧ τ conjunção

τ ∨ · · · ∨ τ disjunção

τ ⇒ · · · ⇒ τ implicação

f(τ · · · τ) aplicação de função

∀x · t, τ quanti�cação universal

∃x · t, τ quanti�cação existencial

τ.x acesso a campo de estrutura

Figura 22: Operadores e constantes presentes na lógica de termos do WP

É possível notar na Figura 22 que alguns operadores clássicos estão ausentes, a exem-

plo de − (subtração) e > (maior que). Isso ocorre porque todo termo criado pelo WP é

normalizado, isto é, é reescrito de modo que a OP seja escrita em uma linguagem simples,

sendo as expressões substancialmente simpli�cadas. Por exemplo, se for inserido no WP

o termo 4 + 5, este será reescrito para 9, já se for inserido o termo true ∨ false, ele seráreescrito true.

O WP possui mais de um tipo de OP, listados a seguir:

Lemma: Esse tipo de OP é gerado a partir de lemas inseridos pelo usuário nas anotações

do código, criados através de predicados em ACSL com a palavra-chave lemma. As

OPs desse tipo não possuem hipóteses, apenas um termo do tipo bool ou prop que

Page 52: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

50

deve ser provado.

Annot: Esse tipo de OP é gerado para veri�car as demais propriedades funcionais das

anotações e do código. Sua estrutura é:

H1, · · · , Hn ` O

em que H1, · · · , Hn são hipóteses e O o objetivo da OP, sendo o segundo constituído

de um termo do tipo bool ou prop. Essas hipóteses não são termos, mas estruturas

que contêm um ou mais termos do tipo bool ou prop, sendo a gramática das possíveis

estruturas exibidas na Figura 23. Devido ao tipo dessas hipóteses serem denominadas

condition no código-fonte do WP3, utilizamos o termo �condição� para nos referirmos

a uma hipótese desse tipo. Por exemplo,When (x ≤ 0) é uma condição. O tipos de

condições com as palavras-chave Core e Init foram inseridas apenas na versão do

WP que acompanha o Frama-C versão Magnesium. Não encontramos na literatura

o signi�cado de cada tipo de condição, porém observamos no código-fonte do WP

que, quando uma OP do tipo Annot é traduzida para a linguagem de um provador

externo ao WP, apenas os termos das condições são utilizadas, sendo elas extraídas

das condições. A etapa de tradução e prova das OP é comentada com mais detalhes

nas próximas seções.

H := Type (τ)

| Core (τ)

| Init (τ)

| Have (τ)

| When (τ)

| If τ Then (H, · · ·, H) Else (H, · · ·, H)

| Either (H, · · ·, H)

Figura 23: Estruturas de uma hipótese

Além desses dois, existe mais um tipo de OP de�nido no WP, denominado Check.

Esse tipo de OP não foi considerado na pesquisa, pois não identi�camos na literatura nem

no código-fonte do WP em que situação OPs desse tipo são produzidas, assim como não

encontramos nenhuma descrição sobre Check no manual do WP. Esse tipo de OP apenas

foi considerado no texto pois ele se encontrava de�nido no código do WP junto com

3Quando falamos código-fonte do WP nos referimos à versão 0.9 do plugin, disponível em:<http://frama-c.com/download/frama-c-Magnesium-20151002.tar.gz>. Acesso em: 6 abr. 2016.

Page 53: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

51

os outros dois tipos, sendo composto de três fórmulas distintas com propósitos que não

compreendemos. Planejamos, em um momento futura, contatar os autores do WP para o

esclarecimento dessa questão e outras que surgiram enquanto estudávamos o plugin.

As OPs podem ser geradas em diversos casos a partir das técnicas apresentadas no

início do capítulo. Não encontramos na literatura como as diferentes técnicas e simpli-

�cações são combinadas para criar as OPs, mas, analisando o comportamento do WP,

observamos alguns casos em que elas são produzidas, sendo listadas a seguir:

• Veri�cação de lemas - é gerada uma OP para cada lema inserido nas anotações;

• Veri�cação de asserções - é gerada uma OP para cada sentença com a palavra-chave

assert;

• Veri�cação de condições em laços - são geradas OPs para cada sentença inserida

antes de um laço, por exemplo, invariantes de laço (loop invariant), atribuições

de laço (loop assigns) e variantes de laço (loop variant). Para cada invariante de

laço é necessário uma OP para validar o estado antes da inicialização do laço e uma

para provar que o invariante é verdadeiro a cada iteração. Também é produzida uma

OP para cada variável da atribuição de laço e duas para cada variante, veri�cando

tanto o estado inicial quanto o seu decréscimo;

• Veri�cação de pós-condição de função - é gerada uma OP para cada pós-condição

(ensures) da função;

• Veri�cação de atribuições na função - é gerada uma OP para cada sentença assigns

que determina quais variáveis poderão ter seus valores modi�cados pela função (efei-

tos colaterais);

A quantidade de OPs produzidas pela análise pode ser menor ou maior do que o

previsto pelas condições supracitadas, pois o WP realiza simpli�cações e aplica regras

de inferência nas OPs resultantes da análise do código e suas anotações (BAUDIN et

al., 2015b). Por exemplo, o WP pode eliminar conjunções nos objetivos de OPs, criando

uma nova OP para cada termo da conjunção original e, consequentemente, aumentando a

quantidade de OPs produzidas. Estas simpli�cações e regras de inferência são explicadas

mais adiante neste capítulo.

O conteúdo e a complexidade das OPs são determinados, além do código e das ano-

tações, a partir do modelo de memória e do modelo aritmético. Os modelos de memória

Page 54: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

52

determinam como representar variáveis e ponteiros com relação à memória do programa, e

os modelos aritméticos determinam como representar números inteiros e ponto �utuante.

Os modelos são apresentados na próxima subseção.

3.4.1 Modelos de memória e aritméticos

O WP possui três modelos de memória, estando um ainda em desenvolvimento, e

cinco modelos aritméticos, sendo três para representar inteiros e dois para representar

ponto �utuante. Os modelos de memória são listados a seguir:

• Modelo Hoare: as variáveis em C são mapeadas diretamente para variáveis lógicas.

Esse modelo produz OPs mais simples que os demais modelos, mas ele possui algu-

mas desvantagens com relação ao uso de ponteiro. A princípio, o modelo Hoare não

trata esse tipo de dados, impedindo que códigos e anotações com ponteiros sejam

analisados. Entretanto, o WP possui algumas otimizações que permitem o uso desse

modelo com ponteiros em casos especiais. Um exemplo de otimização possível é mes-

clar os modelos Hoare e Typed (o segundo modelo é explicado no próximo item).

O modelo Typed permite tratar ponteiros, assim, o valor de um ponteiro pode ser

representado no modelo Hoare enquanto o ponteiro em si pode ser representado no

modelo Typed.

• Modelo Typed : as variáveis são traduzidas para vetores de tipos atômicos. Esse

modelo permite tratar ponteiros, mas produz OPs mais complexas que o modelo

Hoare e não trata conversões explícitas de tipos diferentes.

• Modelo Bytes : as variáveis são representadas diretamente em vetores de bytes. Esse

modelo pode representar todos os detalhes do programa, mas gera OPs mais com-

plexas que as anteriores. Esse modelo ainda não se encontra implementado até a

versão 0.9 do WP (BAUDIN et al., 2015a).

O modelo aritmético diz respeito a como representar inteiros e ponto �utuante em C.

Baudin et al. (2015a) descrevem três modelos diferentes para representar os inteiros:

• Modelo Natural : Os números inteiros são representados matematicamente (modelo

dito Natural), mas conversões entre inteiros de diferentes tipos são realizados com

o operador módulo. As OPs geradas com esse modelo são suportadas por vários

provadores no estado da arte.

Page 55: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

53

• Modelo Natural sem faixa de valores : esse modelo é similar ao anterior, porém os

limites dos inteiros nunca são levados em consideração. No modelo natural, todo tipo

inteiro deve estar limitado por uma faixa de valores especi�cada pela plataforma-

alvo do código. Entretanto, nesse modelo apenas o sinal (positivo ou negativo) é

conhecido. Ele é uma novidade da versão 0.9 do WP.

• Modelo Inteiro de Máquina: Os inteiros são representados com a faixa de valores

limites de inteiros C, sendo essa delimitação realizada através do operador módulo.

Por exemplo, uma variável do tipo inteiro de máquina pode ter um valor entre

−2147482648 e 2147482647 em uma máquina especí�ca. Contudo, as OPs geradas

nesse modelo são mais complexas para serem provadas.

Baudin et al. (2015a) também descrevem dois modelos para representar ponto �utu-

ante:

• Modelo de números reais: nesse modelo os pontos �utuantes são tratados como

números reais, isto é, sem arredondamentos em seus valores (BAUDIN et al., 2015a).

Esse modelo remove a necessidade de gerar condições para veri�car over�ows, porém

as OPs podem ser bastante complexas para serem provadas. Ele também não satisfaz

as semânticas de C e do padrão para ponto �utuantes do Institute of Electrical and

Electronics Engineers - IEEE 4. Baudin et al. (2015a) a�rmam que o modelo não é

seguro (unsound), sem explicar detalhadamente o motivo.

• Modelo de ponto �utuante IEEE: nesse modelo há arredondamentos nas operações

de ponto �utuante, respeitando as semânticas de C e do IEEE. Entretanto, a mai-

oria dos provadores automáticos de teoremas não consegue provar OPs com ponto

�utuante nesse modelo.

Para toda análise realizada pelo WP deve ser escolhido um modelo de memória, um

para números inteiros e um para ponto �utuante. Por padrão, são selecionados os modelos

Typed, Natural e Real, mas podem ser modi�cados manualmente pelo usuário. No modelo

natural, como os inteiros podem ter valores além dos limites dos inteiros da linguagem

C, há o risco de estouro aritmético (over�ow ou under�ow). Os problemas desse tipo

não são veri�cados isoladamente pelo WP, sendo necessária a adição de asserções que os

veri�quem. Isso é possível utilizando o plugin RTE, extensão descrita na seção 2.2 do

capítulo anterior.4O Institute of Electrical and Electronics Engineers é uma instituição fundada nos EUA na qual uma

de suas atribuições é de�nir padrões em diversas áreas tecnológicas, incluindo a tecnologia da informação.

Page 56: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

54

Para esclarecer como são as OPs geradas pelo WP, exemplos delas serão mostrados

a seguir, nos diferentes modelos aritméticos e de memória. Na Figura 24, é descrita uma

função com uma especi�cação intencionalmente incompleta, sendo apresentadas nas Fi-

guras 25, 26 e 27 três versões de uma mesma OP. Elas veri�cam a primeira pós-condição

ensures, diferenciando-se pelo modelo de números inteiros aplicado.

#include <limits.h>

/*@

ensures x >= INT_MAX ==> \result == x + 1000 && \result > x;

ensures x < INT_MAX ==> \result == x - 1000 && \result < x;

*/

int fun1 (int x){ return x >= INT_MAX ? x+1000 : x -1000; }

Figura 24: Função C anotada com contrato em ACSL para exempli�car modelos denúmeros inteiros

Na Figura 25, é utilizado o modelo inteiro de máquina enquanto o modelo presente na

Figura 26 é o de inteiros naturais. A primeira diferença que pode ser notada entre ambas

as OPs é que na primeira �gura o resultado das operações matemáticas são corrigidas

para a faixa de valores de um inteiro em C. Isso é feito através da função to_sint32,

aplicando o operador modulo. Essa função confere se o argumento está dentro do limite

dos valores válidos para inteiros de 32 bits. Como esperado, a OP com o modelo de inteiros

de máquina não pode ser validado, pois o resultado da função pode ser menor que seu

parâmetro x devido à possibilidade de over�ow, invalidando a condição x0 < fun0. Como

na OP com o modelo de inteiros naturais não há a atualização dos inteiros para a faixa de

valores possíveis para inteiros em C, o resultado de 1000+x0 na OP sempre será positivo,

sendo então a OP válida. Devido ao over�ow não ser veri�cado nesse modelo, esse é um

exemplo de que a adição de mais especi�cações ou o uso de um plugin para veri�car erros

de execução é necessário, como o plugin RTE.

Type (is_sint32(fun10)) ∧ (is_sint32(x0))

When (2147483647 <= x0)

If 2147483647 <= x0

Then (Have (x0 <= 2147482647 ∧ fun10 = (to_sint32(1000 + x0))))

Else (Have (−2147482648 <= x0 ∧ fun10 = (to_sint32(x0 − 1000))))

`(x0 < fun10) ∧ (fun10 = (1000 + x0))

Page 57: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

55

Figura 25: OP no modelo inteiro de máquina

Type (is_sint32(fun10)) ∧ (is_sint32(x0))

When 2147483647 <= x0

If 2147483647 <= x0

Then (Have (x0 <= 2147482647 ∧ fun10 = (1000 + x0)))

Else (Have (−2147482648 <= x0 ∧ x0 = (1000 + fun10)))

`(x0 < fun10) ∧ (fun10 = (1000 + x0))

Figura 26: OP no modelo de inteiros naturais

A Figura 27 apresenta a mesma OP no modelo de inteiros naturais sem faixa de valo-

res. Essa OP se iguala à da Figura 26, porém as variáveis inteiras não possuem delimitação

de valores possíveis, sendo notável pela ausência da primeira hipótese da OP na Figura

26 na OP da Figura 27.

When 2147483647 <= x0

If 2147483647 <= x0

Then (Have (x0 <= 2147482647 ∧ fun10 = (1000 + x0)))

Else (Have (−2147482648 <= x0 ∧ x0 = (1000 + fun10)))

`(x0 < fun10) ∧ (fun10 = (1000 + x0))

Figura 27: OP no modelo de inteiros naturais sem faixa de valores

Para os modelos para ponto �utuante seguem-se mais duas OPs como exemplo. Dada

a especi�cação da Figura 28, as �guras 30 e 29 apresentam duas versões da mesma OP

para a veri�cação da primeira condição ensures. As duas OPs se diferenciam pelo modelo

de ponto �utuante utilizado: enquanto a OP da Figura 29 se encontra no modelo de ponto

�utuante IEEE, a OP da Figura 30 se encontra no modelo de números reais.

Page 58: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

56

#include <float.h>

/*@

requires FLT_MIN +10 < x < FLT_MAX -10;

ensures x >= 0 ==> \result > 0;

ensures x < 0 ==> \result < 0;

*/

float fun2 (float x){ return x >= 0 ? x+5 : x-5; }

Figura 28: Função C anotada com contrato em ACSL para exempli�car modelos deponto �utuante.

Type (is_�oat32(fun20)) ∧ (is_�oat32(x0))

When 0 ≤ x0

If 0x0.0000000000000p− 1022 ≤ x0

Then (Have (fun20 = (add_�oat32(x0, 0x1.4000000000000p2))

Else (Have (fun20 = (add_�oat32(x0,−0x1.4000000000000p2))))

`0 < fun20

Figura 29: OP no modelo de ponto �utuante IEEE

Type (is_�oat32(x0)) ∧ (is_�oat32(5.+ x0))

When (0 ≤ x0)

Have (((10 + 1.17549435082e− 38) < x0) ∧ ((10 + x0) < 3.40282346639e+ 38))

`0 < 5.+ x0

Figura 30: OP no modelo de números reais

Os exemplos anteriores que demonstram os modelos aritméticos foram criados no

modelo de memória Hoare, mas seriam exatamente iguais caso fossem criados no modelo

Typed uma vez que, como não há envolvimento de ponteiros, as OPs seriam de�nidas de

modo semelhante ao modelo Hoare. Nesses exemplos também foram criadas apenas OP

do tipo Annot, pois não há lemas de�nidos nas especi�cações das �guras 24 (p. 54) e 28

(p. 56).

Page 59: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

57

Nas próximas �guras, será mostrado um exemplo de OP no modelo Typed. A Figura

31 ilustra um código C com anotação ACSL, sendo apresentada na Figura 32 uma das

OPs do tipo Annot geradas após a análise do exemplo, com o modelo de memória Typed e

representação natural de inteiros e reais (modelos Natural e Real). A �nalidade dessa OP

é veri�car se a cláusula ensures (*a == \old(*b) && *b == \old(*a)) é respeitada.

/*@ requires \valid(a) && \valid(b);

ensures (*a == \old(*b) && *b == \old(*a));

*/

void swap(int *a, int *b){

int tmp = *a;

*a = *b;

*b = tmp;

}

Figura 31: Um exemplo de função C anotada com um contrato em ACSL

a0 : addr

Mint0 : array[int]

b0 : addr

Malloc0 : array[int]

Type(let x0 = Mint0[a0] in

let x1 = Mint0[b0] in

is_sint32(x0) ∧ is_sint32(x1) ∧ is_sint32(Mint0[a0 7→ x1][b0 7→ x0][a0]))

Have(linked(Malloc0) ∧ region(base(a0)) ≤ 0 ∧ region(base(b0)) ≤ 0)

Type(valid_rw(Malloc0, a0, 1) ∧ valid_rw(Malloc0, b0, 1))

`let x0 = Mint0[b0] in x0 = Mint0[a0 7→ x0][b0 7→Mint0[a0]][a0]

Figura 32: Exemplo de OP do tipo Annot

Para ilustrar melhor o exemplo, inserimos na Figura 32 as variáveis e seus tipos apre-

sentados. O termo linked(Malloc_0) é utilizado para de�nir que o estado da memória

é representada por Malloc_0, sendo um dos propósitos dessa variável identi�car regiões

válidas para escrita e leitura de dados. A variável Mint_0 armazena todas valores inteiros

da memória e a_0 e b_0 representam os ponteiros da função swap. Não identi�camos

o signi�cado das funções region(base(a_0)) e region(base(b_0)), mas notamos que

Page 60: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

58

esses termos são inseridos para todos os argumentos da função que sejam ponteiros no

modelo Typed. O código com a especi�cação da Figura 31 não poderia ser veri�cado no

modelo Hoare, uma vez que há o uso de ponteiros no algoritmo (*a e *b).

O último exemplo de OP é mostrado na Figura 34. Ela é do tipo Lemma e é gerada a

partir do lema da Figura 33, usando as mesmas con�gurações do exemplo de OP anterior.

É visível a ausência de hipóteses na OP gerada, sendo essa OP produzida tanto no modelo

Hoare quanto Typed.

/*@

lemma plusEqual:

\forall integer n, m, o;

n == m ==> m == o ==> n + m == m + o;

*/

Figura 33: Um exemplo de lema ACSL

` m0 = n0 ⇒ m0 = o0 ⇒ n0 = o0

Figura 34: OP do tipo Lemma gerada a partir do lema plusEqual

O conteúdo e complexidade �nal das OPs também são in�uenciadas por reescritas e

simpli�cações, realizadas durante a criação das OPs. Algumas dessas simpli�cações são

discutidas na próxima seção.

3.4.2 Qed e simpli�cações na OP

O WP realiza diferentes níveis de simpli�cação, sendo o primeiro aplicado ao nível

dos termos, como a normalização exempli�cada na gramática de termos (p. 49), e o se-

gundo ao nível das OPs. No primeiro caso, a simpli�cação é automática, realizada toda

vez que um termo é criado ou modi�cado. Algumas dessas simpli�cações são propagação

de negação (Leis de Morgan), absorção de elementos neutros e eliminação de fatos redun-

dantes (BAUDIN et al., 2015a). Já o segundo nível é aplicado ao nível das OPs, através

do Qed (CORRENSON, 2014). O Qed é um arcabouço (framework) cuja função é realizar

diversos tipos de manipulação em termos e OPs. Esse arcabouço inicialmente foi desen-

volvido dentro do Frama-C, sendo posteriormente implementado como uma biblioteca

independente.

Page 61: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

59

As simpli�cações realizadas pelo Qed são optativas ao usuário. Exemplos de regras

de inferência disponíveis são: eliminação de conjunção, de implicação e de condicional,

sendo os três casos aplicáveis ao objetivo da OP. A aplicação dos dois simpli�cadores

pode resultar em objetivos triviais validados automaticamente: 1 + 0 = 1 é simpli�cado

para true, por exemplo. Dessa forma, uma OP pode ser validada apenas utilizando o Qed.

Caso a OP não seja validada pelo arcabouço supracitado, o usuário tem a opção

de utilizar um provador externo, sendo ele um provador automático de teoremas ou um

assistente de provas, acessados diretamente ou através do Why3. Abordamos essas opções

nas próximas seções, �nalizando com a problemática relacionada ao WP.

3.5 A plataforma para veri�cação dedutiva Why3

OWhy3 é uma plataforma usada na veri�cação dedutiva de programas. Sua linguagem

de especi�cação é o WhyML, cuja lógica é de primeira ordem e aceita tipos polimór�cos,

casamento de padrões e tipos indutivos. O Why3 se comunica com diversos provadores

automáticos e interativos para provar as OPs geradas com sua linguagem, possuindo uma

biblioteca padrão para teorias lógicas (inteiro e aritmético reais, operações com boole-

anos etc.) e estruturas de dados para programação (arrays,queues etc.) (FILLIÂTRE;

PASKEVICH, 2013).

Para executar os provadores conectados a si, o Why3 traduz as OPs do WhyML para

linguagens suportadas pelos provadores. A título de exemplo, as OPs podem ser traduzidas

para o formato SMT padronizado pela SMT-LIB, uma iniciativa internacional para o de-

senvolvimento e pesquisa de problemas SMT (BARRETT; FONTAINE; TINELLI, 2015),

TPTP (Thousands of Problems for Theorem Provers5), uma linguagem formalizada para

a criação e especi�cação de problemas para provadores de teoremas (SUTCLIFFE, 2009)

e Gallina, a linguagem do assistente de provas Coq (BERTOT; CASTÉRAN, 2004), entre

outros formatos. A linguagem Gallina é introduzida na seção 3.7 e tanto a SMT-LIB como

o formato SMT são explanados mais detalhadamente na seção subsequente.

Os valores de entrada do Why3 são constituídos por uma lista de teorias em WhyML,

sendo cada teoria composta por uma lista de declarações. Cada declaração contém de�-

nições de tipos, funções e predicados, axiomas, lemas e objetivos. A Figura 35 apresenta

um exemplo de entrada do Why3 contendo quatro teorias.

5TPTP - Milhares de Problemas para Provadores de Teoremas

Page 62: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

60

theory Order

type t

predicate (<=) t t

axiom le_refl : forall x : t. x <= x

axiom le_asym : forall x y : t. x <= y -> y <= x -> x = y

axiom le_trans: forall x y z : t. x <= y -> y <= z -> x <= z

end

theory List

type list 'a = Nil | Cons 'a (list 'a)

predicate mem (x: 'a) (l: list 'a) = match l with

| Nil -> false

| Cons y r -> x = y \/ mem x r

end

end

theory SortedList

use import List

clone import Order as O

inductive sorted (l : list t) =

| sorted_nil : sorted Nil

| sorted_one : forall x:t. sorted (Cons x Nil)

| sorted_two : forall x y : t, l : list t.

x <= y -> sorted (Cons y l) -> sorted (Cons x (Cons y l))

lemma sorted_mem:

forall x: t, l: list t. sorted (Cons x l) ->

forall y: t. mem y l -> x <= y

end

theory SortedIntList

use import int.Int

use import List

clone import SortedList with type O.t = int , predicate O.(<=) = (<=)

goal sorted123: sorted (Cons 1 (Cons 2 (Cons 3 Nil)))

end

Figura 35: Exemplo de entrada do Why3.Fonte: Adaptado de Bobot et al. (2011, p. 4)

A primeira teoria de�ne um tipo novo abstrato t, um predicado binário abstrato <= e

três axiomas de�nindo esse predicado. A segunda teoria, List, declara um novo tipo com

listas polimór�cas e um predicado recursivo que veri�ca se um elemento pertence ou não à

lista. Já a terceira teoria, SortedList, mostra a possibilidade de aproveitar as de�nições

de outras teorias anteriormente de�nidas. O comando import é utilizado para aproveitar

as de�nições e tipos existentes da teoria importada e clone é empregado para instanciar

a teoria selecionada, permitindo que os tipos abstratos sejam instanciados na teoria que

realizou a importação. A quarta e última teoria, SortedIntList, copia a teoria anterior

de�nindo quais os tipos concretos serão utilizados na instanciação dos tipos abstratos. Na

última teoria também é inserido um objetivo que deve ser veri�cado.

Page 63: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

61

A principal atividade do Why3 é a criação e veri�cação de tarefas de prova (proof

tasks), sendo cada tarefa um sequente: uma lista de declarações com um objetivo que

deve ser provado. Essas tarefas de prova são extraídas a partir das teorias inseridas na

entrada da plataforma.

Cada tarefa de prova é enviada a um dos provadores supracitados, sendo necessá-

rio traduzi-la para a linguagem do provador alvo. A tradução é realizada gradualmente,

através da aplicação de um conjunto de transformações. Essas transformações são con-

troladas por um arquivo de con�guração denominado driver, sendo mostrado na Figura

36 um exemplo de driver para o solucionador Z3. Os drivers identi�cam como inserir

os dados nos provadores e interpretar suas respostas, as transformações que devem ser

feitas na tarefa de prova antes de enviá-la ao provador etc. Por exemplo, inline_trivial

expande de�nições como em predicate (>=) (x y : t) = y <= x, isto é, expressões

que são, entre outros aspectos, não recursivas e lineares, e eliminate_algebraic_cost

codi�ca alguns tipos de dados e expressões com casamento de padrões para símbolos de

funções e tipos não interpretados SMT-LIB.

printer "smtv2"

filename "%f-%t-%g.smt"

valid "^unsat"

invalid "^sat"

unknown "^\\( unknown \\| Fail \\)" "Unknown"

time "why3cpulimit time : %s s"

transformation "inline_trivial"

transformation "eliminate_builtin"

transformation "eliminate_definition"

transformation "eliminate_inductive"

transformation "eliminate_algebraic_smt"

transformation "simplify_formula"

transformation "discriminate"

transformation "encoding_smt"

prelude "(set -logic AUFNIRA)"

theory BuiltIn

syntax type int "Int"

syntax type real "Real"

syntax predicate (=) "(= %1 %2)"

end

theory int.Int

prelude ";;; this is a prelude for Z3 integer arithmetic"

syntax function zero "0"

syntax function one "1"

syntax function (+) "(+ %1 %2)"

syntax function (-) "(- %1 %2)"

syntax function (*) "(* %1 %2)"

syntax function (-_) "(- %1)"

Page 64: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

62

syntax predicate (<=) "(<= %1 %2)"

syntax predicate (<) "(< %1 %2)"

syntax predicate (>=) "(>= %1 %2)"

syntax predicate (>) "(> %1 %2)"

remove prop CommutativeGroup.Comm.Comm

remove prop CommutativeGroup.Assoc.Assoc

remove prop CommutativeGroup.Unit_def

remove prop CommutativeGroup.Inv_def

Figura 36: Exemplo de entrada de driver para Z3.Fonte: Adaptado de Bobot et al. (2011, p. 7)

O Why3 é utilizado pelo WP para provar as OPs geradas com outros provadores

que não sejam o Alt-Ergo ou o Coq (BAUDIN et al., 2015a, p. 15-16). Esses provadores

podem ser executados de duas formas: através da interface grá�ca doWhy3 ou diretamente

pelo WP, pois este pode executar o Why3 em segundo plano para ativar os provadores.

Em ambos os casos o plugin traduz as OPs para a linguagem WhyML, enviando-os ao

Why3. Essa plataforma �ca então responsável por traduzir as OPs em WhyML para

a linguagem nativa do provador externo a ser executado, enviando-a a esse provador e

obtendo resultado da prova.

A Figura 37 exibe a tradução da OP da Figura 34 para o WhyML. O comando �use

import� é usado para importar bibliotecas externas usadas pelo Why3, sendo Q_plusEqual

o lema da Figura 33 a ser provado. A biblioteca Qed foi de�nida no WP, enquanto as de-

mais se encontram nas bibliotecas padrões do Why3.

theory Axiomatic

use import bool.Bool

use import int.Int

use import int.ComputerDivision

use import real.RealInfix

use import Qed.Qed

use import int.Abs as IAbs

use import map.Map

lemma Q_plusEqual: forall m n o : int. (m = n) -> (m = o) -> (n = o)

end

Figura 37: Exemplo de tarefa de prova WhyML

A Figura 38 ilustra uma instância da interface grá�ca do Why3, executada pelo WP

quando o usuário escolhe a opção de interface grá�ca. São listadas, na coluna central,

todas as OPs do projeto, sendo elas as versões em WhyML das OPs do WP. Na coluna à

Page 65: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

63

esquerda são listados os principais comandos que podem ser aplicados no programa, sendo

alguns desses comandos a seleção do provador que será aplicado para a veri�cação das

OPs e a aplicação de transformações sintáticas (regras de inferência), como, por exemplo,

divisão de conjunções no objetivo da OP. Na coluna superior à direita são exibidos os

axiomas e de�nições (funções e predicados) que serão utilizados pelas OPs. E, por último,

no canto inferior direito, são listadas as OPs que serão veri�cadas.

Page 66: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

64

Figura 38: Why3

Page 67: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

65

3.6 Provadores automáticos de teoremas e os provado-

res SMT

Os provadores automáticos �consistem de um conjunto de procedimentos de deci-

são bem escolhidos permitindo que fórmulas com um formato restrito especí�co sejam

provadas automaticamente�6(GEUVERS, 2009, p. 3). A linguagem desse tipo de ferra-

menta in�ui na sua habilidade de prova: quanto menos expressiva ela for, maior o nível

de automação da ferramenta (ALMEIDA et al., 2011). Por outro lado, o aumento da ex-

pressividade da linguagem permite representar deduções e estruturas matemáticas mais

complexas. Um tipo de provador é o solucionador SAT: seu objetivo é encontrar uma

intepretação de valores que satisfaça um problema SAT (Problema de Satisfatibilidade

Booleana) 7(MOSKEWICZ et al., 2001). Esses problemas são compostos por expressões

booleanas, sendo verdadeiro e falso os valores possíveis para cada variável. Por exemplo,

há para a fórmula a ∧ ¬b, no qual a e b são váriáveis booleanas, uma valoração que a

satisfaça atribuindo-se os valores a = true e b = false (a é verdadeiro e b é falso).

Os solucionadores SMT formam outro subconjunto existente de provadores automá-

ticos de teoremas. Um problema SMT (Satisfatibilidade Módulo Teorias)8 consiste em

veri�car se uma fórmula α é satisfatível, isto é, se existe pelo menos uma atribuição possí-

vel de valores às variáveis tal que α seja verdadeira (BARRETT; FONTAINE; TINELLI,

2015). Cada fórmula é contextualizada por uma assinatura Σ, que declara os tipos, variá-

veis e funções utilizadas, e por uma teoria Γ, que descreve a interpretação dos símbolos

utilizados em Σ. Além das teorias utilizadas, um problema SMT também está restrito a

uma lógica subjacente (lógica de primeira ordem, modal, temporal). A satisfatibilidade

de α é veri�cada, então, com relação às teorias selecionadas e à lógica subjacente.

Os problemas SMT são padronizados por uma entidade internacional denominada

SMT-LIB, cujo objetivo é realizar pesquisa e desenvolvimento relacionado a SMT. Essa

entidade provê padrões de linguagem para a representação dos problemas SMT, comandos

de entrada e saída para os solucionadores SMT, descreve detalhadamente as teorias SMT

e disponibiliza publicamente bibliotecas com esses problemas para estudos (BARRETT;

FONTAINE; TINELLI, 2015). Nesse padrão, a lógica subjacente aplicada nas fórmulas

é uma versão da lógica de primeira ordem tipada com igualdade. Além disso, não há

distinção entre termo e fórmula, sendo o segundo tipo determinado como termo do tipo

6No original: �consisting of a set of well chosen decision procedures that allow formulas of a speci�crestricted format to be proved automatically�.

7No original: �Boolean Satis�ability Problem�.8No original: �Satis�ability Modulo Theories�.

Page 68: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

66

Bool.

A linguagem padronizada SMT é a lógica de primeira ordem com tipos, sendo dividida

em três partes principais: declaração das teorias, declaração das lógicas e os scripts, tendo

uma sintaxe parecida com a linguagem de programação LISP (BARRETT; FONTAINE;

TINELLI, 2015, p. 20).

Na declaração das teorias, o usuário pode de�nir as assinaturas utilizadas, sendo

elas compostas por símbolos de tipos e funções, a de�nição formal ou informal (numa

linguagem natural) desses símbolos, os valores possíveis para os tipos de�nidos, entre

outros atributos. Uma teoria pode de�nir, por exemplo, o tipo inteiro e funções que

possam manipular termos e variáveis desse tipo, como os símbolos de operação aritmética

(soma, subtração, negação e multiplicação) e relacional entre inteiros (menor que, menor

ou igual, igualdade, maior ou igual e maior que). A declaração formal para essa teoria é

demonstrada no Apêndice C.

Um problema padrão SMT pode estar restrito a uma sublógica da lógica subjacente do

SMT-LIB, tendo a linguagem da declaração das lógicas justamente o propósito de de�nir

as sublógicas utilizadas. As sublógicas podem restringir tanto a semântica quanto a sintaxe

da lógica subjacente, além de de�nir o conjunto de teorias aceitas pela sublógica. A lógica

proposicional é um exemplo possível de sublógica: quanti�cadores não são permitidos e

as funções são constantes do tipo Bool.

Os scripts são uma sequência de comandos usados para a comunicação com um solu-

cionador SMT. Com os comandos é possível, por exemplo, con�gurar o provador, obter

dados, adicionar de�nições de funções e fórmulas lógicas, executar veri�cações etc. A

Figura 39 ilustra dois desses comandos, set-logic e assert. A função do primeiro co-

mando é de�nir a sublógica do problema SMT, enquanto a do segundo é veri�car se o

termo inserido como argumento é satisfatível de acordo com de�nições e teorias previa-

mente inseridas pelo usuário do solucionador SMT.

(set -logic AUFNIRA)

(assert

(not (forall ((m Int) (n Int) (o Int)) (=> (= m n) (=> (= m o) (= n o)

)))))

(check -sat)

Figura 39: Exemplo de OP em SMT-LIB

A fórmula da �gura é um trecho da tradução realizada pelo Why3 a partir do lema

da Figura 37 para o provador Z3. Além da tradução do lema, o Why3 insere um conjunto

de de�nições no problema SMT, sendo a OP completa exibida no Apêndice D.

Page 69: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

67

A sublógica AUFNIRA permite o uso de quanti�cadores, arranjos, funções não inter-

pretadas e de aritmética não linear sobre inteiros e números reais (SMT-LIB, 2016). Essa

é a lógica con�gurada no driver padrão do Why3 para alguns solucionadores SMT como

o Z3 e o CVC4. Entretanto, o WP permite que o usuário insira seus próprios drivers, per-

sonalizando as transformações que o Why3 fará para produzir a OP em SMT-LIB. Uma

das personalizações possíveis é a escolha de uma sublógica com um escopo mais restrito

ao problema, auxiliando os solucionadores na escolha de uma estratégia mais adequada

de prova.

O SMT-LIB também padroniza outros comandos que possam ser utilizados em um

problema SMT. O comando declare-sort é utilizado para declarar um novo tipo, infor-

mando um nome e uma aridade. Por exemplo, (declare-sort uni 0) declara um novo

tipo uni, de aridade 0. Já declare-fun é utilizado para declarar uma nova função, no

qual devem ser inseridos, nessa ordem, um nome, os tipos dos argumentos, e o tipo da

função. (declare-fun eq (Int Int) Bool) é um exemplo de função booleana com dois

argumentos do tipo inteiro. Uma função pode também não ter argumentos, sendo, nesse

caso, uma constante.

Um dos principais objetivos dos provadores (ou solucionadores) SMT é veri�car se um

problema desse tipo é insatisfatível. Cada provador possui uma limitação das sublógicas

possíveis, assim como um conjunto de teorias já implementadas. Exemplos de solucio-

nadores SMT são o CVC4 (BARRETT et al., 2011), Z3 (MOURA; BJØRNER, 2008),

Alt-Ergo (CONCHON; IGUERNELALA, 2014) e veriT (BOUTON et al., 2009).

Alguns provadores podem disponibilizar informações adicionais:

• Se a instância é insatisfatível, o solucionador pode fornecer uma prova; e,

• Se a instância é satisfatível, o solucionador pode fornecer um modelo, ou seja, uma

valoração das constantes, funções e predicados com ocorrências livres na fórmula,

tal que a fórmula seja avaliada em �verdadeiro�.

Os solucionadores SMT podem ser utilizados na análise da corretude de sistemas.

Uma forma de usá-los com esse intuito é decidir se uma certa fórmula φ é válida para uma

dada teoria Γ, isto é, se a fórmula avaliada é verdadeira para todas as combinações de

valores possíveis em suas variáveis, sendo interpretadas por Γ. O solucionador pode tentar

obter essa solução através da veri�cação da insatisfatibilidade de ¬φ, pois φ é válido com

relação a Γ apenas se não há valoração possível para satisfazer ¬φ.

Page 70: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

68

Apesar de haver uma linguagem padrão para os problemas SMT, alguns soluciona-

dores permitem o uso de outras linguagens prede�nidas para a inserção e manipulação

de fórmulas, sendo o Alt-Ergo um exemplo. Esse solucionador possui uma linguagem na

lógica de primeira ordem com tipos de dados polimór�cos e algumas teorias construídas

internamente (CONCHON, 2012).

A linguagem do Alt-Ergo possui quanti�cadores, conectivos proposicionais, símbolos

funcionais e relacionais, teorias aritmética, de igualdade, arrays polimór�cos funcionais,

entre outros. O WP pode se comunicar diretamente com o Alt-Ergo, traduzindo as OPs

para a sua linguagem prede�nida. A Figura 40 ilustra a tradução do trecho da OP presente

na Figura 34 para a linguagem do Alt-Ergo. Junto com essa OP são também inseridos

axiomas de�nidos pelo WP como, por exemplo, de�nições para números (inteiros e reais)

e para o tipo Bool.

goal lemma_plusEqual:

forall i_2 ,i_1 ,i : int. (i = i_1) -> (i_1 = i_2) -> (i = i_2)

Figura 40: Exemplo de OP na linguagem nativa do Alt-Ergo

3.7 Assistentes de Prova

Os assistentes de prova (ou provadores interativos) são, como o nome sugere, ferramen-

tas que dão assistência na elaboração de teorias matemáticas. Tais teorias são compostas

por de�nições de tipos, estruturas de dados e funções, estabelecimento de sentenças lógi-

cas (teoremas, lemas) e provas da corretude dessas a�rmações, podendo de�nições prévias

serem usadas na prova de novos fatos (GEUVERS, 2009).

A construção das provas se dá através da aplicação de regras matemáticas e lógicas

de modo a obter uma prova completa. Um exemplo de assistente de provas é o Coq:

Essa ferramenta possui dezenas de regras de inferência prede�nidas disponíveis. Bertot e

Castéran (2004) empregam o termo tática para de�nir uma transformação sintática que o

Coq pode aplicar numa OP, gerando novas sub-OPs. Portanto, decidimos utilizar o termo

supracitado quando mencionamos uma regra de inferência do Coq.

O Coq permite aplicar tanto as táticas prede�nidas como suas combinações, criando

novas táticas ou estratégias de prova. Sua arquitetura é composta por dois níveis: o pri-

meiro é um núcleo com um veri�cador de tipos, algumas regras de computação e um

interpretador com algumas de�nições (funções, tipos etc.). Já o segundo nível, construído

em cima do núcleo, é um ambiente com um conjunto de funcionalidades para a criação de

Page 71: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

69

de�nições, como notações e bibliotecas. Com esse ambiente, é possível criar novas táticas

para realizar automação de provas (PAULIN-MOHRING, 2012).

O Coq pode ser acessado a partir de linha de comando ou de uma IDE. O Frama-C

executa o provador através da CoqIde, uma de suas interfaces grá�cas, ilustrada na Figura

41.

A janela à esquerda na interface é o console do Coq. Nele o usuário pode inserir

de�nições, fórmulas que devem ser provadas, táticas para a conclusão dessas provas e

importar bibliotecas com táticas e de�nições. Os comandos no console podem ser tanto

carregados quanto salvos em arquivos de texto, permitindo retomar provas e de�nições.

Na janela na região superior direita, é exibida a descrição de uma de�nição criada

pelo usuário ou o estado atual da veri�cação de uma OP. E, por último, na janela abaixo,

são exibidas as mensagens provenientes da execução de táticas e comandos, retornando

informações adicionais ao usuário como, por exemplo, uma justi�cativa para uma tática

não poder ser aplicada.

Quando uma prova é enviada do Frama-C ao Coq, o WP traduz a OP da sua própria

linguagem para a Gallina, uma linguagem de especi�cação aceita no Coq, salvando-a em

um arquivo e executando o CoqIde logo em seguida. Os primeiros comandos inseridos são

as bibliotecas importadas (Require Import), seguido da tradução da OP após a palavra-

chave Goal, e, por último, as palavras-chave Proof e Qed. As táticas para a resolução da

prova devem ser inseridas entre as duas últimas palavras-chave e, caso a prova seja válida,

o estado da OP é atualizado no Frama-C.

A OP na Figura 41 é a tradução para o Coq do lema da Figura 34, na qual foi utilizada

a tática auto with zarith para a veri�cação da prova. O ZArith9 é uma biblioteca do

Coq, com um conjunto de operadores aritméticos e lógicos para trabalhar com inteiros.

A tática auto consiste na aplicação automática de sucessivas táticas mais atômicas para

tentar resolver a prova. No exemplo em questão, auto utilizou de forma sistemática os

operadores presentes no ZArith, chegando à validação da prova.

9Disponível em:<https://coq.inria.fr/library/Coq.ZArith.ZArith.html>. Acesso em: 5 abr. 2016

Page 72: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

70

Figura 41: Exemplo do Coq

Page 73: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

71

3.8 Veri�cação das OPs

A forma mais rápida para validar uma OP é através do Qed. Caso não haja sucesso

na prova, o usuário pode utilizar um provador automático de teorema, notadamente um

solucionador SMT. A prova pode ser realizada diretamente pelo Alt-Ergo, sendo a OP

traduzida para sua linguagem padrão ou para outros provadores SMT, através do Why3.

Os solucionadores SMT podem não ter sucesso na prova, sendo duas as razões possíveis

para tal: anotações não condizentes com a implementação; ou a OP é bastante complexa

para ser resolvida nas restrições de tempo e espaço de�nidas pelo usuário. No primeiro

caso, é preciso veri�car e corrigir manualmente as anotações e/ou o código. Já na segunda

situação, o usuário deve provar a OP interativamente. Assim como com o Alt-Ergo, o WP

possui comunicação direta com o Coq, mas outros assistentes de provas também podem

ser utilizados através do Why3, sendo estes: Isabelle (NIPKOW; PAULSON; WENZEL,

2002) e PVS (OWRE et al., 2001).

Podem existir alguns inconvenientes na prova através dos assistentes: as OPs podem

ser bastante complexas, exigindo experiência signi�cativa do usuário em estratégias de

prova. Além disso, a linguagem e os artefatos do assistente devem ser conhecidos, deman-

dando tempo para estudá-los.

Um suporte que pode ser dado ao usuário é o uso misto de assistentes e provadores

automáticos: a prova é simpli�cada ao ponto de poder ser validada por um provador auto-

mático. Entretanto, é necessária uma integração concisa entre os dois tipos de provadores,

sendo desenvolvidas algumas abordagens nesse sentido. Denman e Muñoz (2014) integram

PVS com MetiTarski (AKBARPOUR; PAULSON, 2010), sendo este último um provador

automático de teoremas para expressões na lógica de primeira ordem envolvendo funções

especiais como sin, cos, exp, sqrt etc. Blanchette, Bulwahn e Nipkow (2011) listam algu-

mas formas de automatização de provas para Isabelle. Duas das extensões mencionadas

são o Sledgehammer (PAULSON, 2010), utilizado para �nalizar uma prova com provado-

res automáticos de teoremas e Nitpick (BLANCHETTE; NIPKOW, 2010), cuja função é

encontrar contramodelos de prova através do uso de solucionadores SAT. Armand et al.

(2011) propõem e desenvolvem uma forma de integrar solucionadores SMT e SAT com o

Coq.

Contudo, essas ferramentas podem não estar completas para uso em escala industrial

com o WP: não há como capturar o resultado dessas extensões, estão em fase experimental

ou não aceitam todos os tipos de construções da linguagem na ferramenta original, entre

Page 74: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

72

outros possíveis problemas. Somado a isso, o usuário deve aprender sobre a ferramenta

estudada e instalá-la também.

A partir dessa análise, foi decidido criar uma extensão para o WP que permitisse ao

usuário simpli�car as OPs e, a qualquer etapa da prova, enviá-las a provadores automá-

ticos. Essas simpli�cações seriam possíveis através da aplicação de algumas das regras de

inferência mais comuns encontradas em ambientes de prova, sendo a comunicação entre as

OPs e os solucionadores direta, concisa e completa, sem uso de ferramentas intermediárias.

A linguagem para a manipulação das OPs seria simples de aprender e manusear, assim

como a extensão seria totalmente integralizada ao WP e Frama-C, permitindo que novas

características pudessem ser adicionadas. Ainda, essa extensão poderia auxiliar o usuário

a se familiarizar com o uso de ambientes de prova. Por �m, essa extensão foi implementada

com o nome WPTrans e sua descrição é documentada nos próximos capítulos.

Page 75: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

73

4 A extensão WPTrans

O WPTrans é uma alternativa para a realização de provas que usa, conjuntamente,

provadores automáticos e interativos de teoremas. Ela fornece uma interface grá�ca para

veri�car interativamente as OPs, submetendo-as a um provador externo em qualquer

etapa da prova. A interação consiste na aplicação de um conjunto preestabelecido de

regras de inferência, dando ao usuário a possibilidade de simpli�car as OPs até que elas

se encontrem tratáveis pelos provadores automáticos.

Figura 42: Esquema do WP com o WPTrans

Observando a Figura 42 percebe-se que o WPTrans foi implementado dentro do WP,

lendo e modi�cando as OPs diretamente. Todas as OPs manipuladas pelo WPTrans são

imediatamente disponibilizadas ao WP, de modo que toda alteração realizada pela ex-

tensão é re�etida diretamente no plugin. Além disso, o WPTrans pode acessar todas as

opções de con�guração do WP, sendo, dessa forma, possível que o usuário execute um pro-

vador de teoremas e modi�que opções de prova diretamente a partir da extensão (como

o tempo máximo de execução do provador por exemplo). Sendo a aplicação de regras de

inferência nas OPs o principal elemento dessa extensão, explicamos neste capítulo apenas

as regras implementadas, descrevendo suas de�nições, formas de uso e justi�cativas para a

implementação. Se encontram descritos no próximo capítulo os demais itens do WPTrans:

como aplicar as regras de inferência, a descrição de interface visual de uso, formas de inte-

Page 76: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

74

ração entre o usuário e a extensão, estratégias aplicadas na implementação do WPTrans,

organização do código-fonte, experiências e di�culdades na construção dessa extensão e

funcionalidades descartadas ao longo do desenvolvimento desta pesquisa.

A escolha das regras implementadas foi realizada a partir do estudo das táticas e

regras de inferência das seguintes fontes:

• O assistente de provas Coq, usado para veri�car interativamente OPs geradas pelo

WP a partir dos exemplos fornecidos por Burghardt e Gerlach (2015) - a de�nição

das táticas do Coq estão disponíveis em The Coq development team (2015);

• O provador interativo do Atelier-B, uma plataforma de projeto formal de compo-

nentes de software com o método B (MENTRÉ et al., 2012);

• O provador interativo do Rodin, uma plataforma desenvolvida para especi�cação

formal de sistemas em Event-B (ABRIAL et al., 2010);

• Regras de inferência de�nidas em Abrial (2010).

O B e o Event-B são métodos formais utilizados na especi�cação de sistemas a partir da

criação de modelos formais, produzindo OPs para assegurar a validade da especi�cação.

Tanto o Rodin quanto o Atelier-B possuem provadores interativos que podem aplicar

regras de inferência nas OPs geradas. As linguagens de ambos os métodos formais, assim

como as OPs, são da lógica de primeira ordem com teoria dos conjuntos (ABRIAL, 2005;

ABRIAL, 2010).

As primeiras regras de inferência implementadas foram as selecionadas a partir das

duas ferramentas mencionadas no parágrafo anterior. Como a lógica presente no WP não

engloba teoria dos conjuntos, foram descartadas as regras de inferência que não tratavam

dessa teoria. Das regras restantes, algumas delas foram selecionadas arbitrariamente para

serem implementadas no WPTrans, objetivando aprender a manipular as OPs geradas

pelo WP. Essas regras foram selecionadas pois partimos do pressuposto de que, como elas

já existiam nas ferramentas supracitadas, elas poderiam ter bastante relevância para o

WPTrans.

Posteriormente, introduzimos regras de inferências a partir das táticas do Coq utili-

zadas nas provas de algumas OPs. Burghardt e Gerlach (2015) apresentam um conjunto

de exemplos de código C com anotações ACSL, no qual geraram várias OPs a partir da

Page 77: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

75

análise pelo Frama-C com o WP. Algumas delas foram provadas apenas com o Coq, sendo

disponibilizadas as táticas usadas para as provas em um repositório 1.

Dadas essas informações, apresentamos as regras de inferência em dois lugares desta

dissertação. Introduzimos neste capítulo as regras de inferência implementadas tanto para

provar as OPs veri�cadas com o Coq como para realizar testes com o WPTrans. Essas

justi�cativas são detalhadas em cada regra de inferência apresentada. Já no Apêndice

A são apresentadas regras de inferência não utilizadas para veri�car nenhuma OP, mas

que, por estarem presentes no assistentes de prova supracitados (Atelier-B, Rodin e Coq),

optamos por implementá-los e torná-los disponíveis ao usuário também.

Algumas regras de inferência fazem acesso às hipóteses das OPs, alterando-as quando

necessário. Porém, como as OPs do tipo Lemma não possuem hipóteses na de�nição

original do WP, a estrutura desse tipo de OP foi modi�cada, sendo adicionado um novo

campo que representa uma lista de hipóteses. Seu novo formato é:

H1, · · · , Hn ` O

no qual H1, · · · , Hn são hipóteses e O o objetivo a ser provado. Tanto o objetivo como

as hipóteses são termos do tipo prop ou bool. A Figura 43 é um exemplo de OP do tipo

Lemma com a nova estrutura, sendo possível observar que as hipóteses são termos, não

condições.

let x0 = Mint0[a0] in

let x1 = Mint0[b0] in

is_sint32(x0) ∧ is_sint32(x1) ∧ is_sint32(Mint0[a0 7→ x1][b0 7→ x0][a0]).

linked(Malloc0) ∧ region(base(a0)) ≤ 0 ∧ region(base(b0)) ≤ 0

valid_rw(Malloc0, a0, 1) ∧ valid_rw(Malloc0, b0, 1)

`let x0 = Mint0[b0] in x0 = Mint0[a0 7→ x0][b0 7→Mint0[a0]][a0]

Figura 43: Exemplo de OP do tipo Lemma com o novo formato

Todas as regras de inferência possuem dois comportamentos dependendo do tipo de

OP. No caso das OPs do tipo Lemma, tanto as hipóteses como o objetivo são acessados

1Disponível em:<https://gitlab.fokus.fraunhofer.de>. Acesso em: 5 abr. 2016.

Page 78: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

76

e modi�cados diretamente. Já para o caso das hipóteses do tipo Annot, os termos den-

tro das condições são extraídos e manipulados, substituindo as condições existentes por

novas com os termpos manipulados. Para o segundo caso poderíamos ter representado

as hipótese das OPs do tipo Annot simplesmente como termos ao invés de condições,

vide o exemplo de OP para o tipo Lemma exibido anteriormente. Entretanto, decidimos

apresentar as regras de inferência com o formato original das OPs do tipo Annot, pois

intencionamos descrever de forma mais exata a implementação do WPTrans: se as regras

de inferência forem apresentadas de forma simpli�cada, considerando que uma OP seja

formada apenas de termos, um leitor que enseje compreender o código-fonte e modi�cá-lo

poderia encontrar di�culdades em compreender como as condições foram manipuladas.

Além disso, são documentadas de forma mais con�ável as modi�cações feitas na extensão.

Também poderíamos ter criado um novo tipo de OP removendo essas estruturas, utili-

zando simplesmente termos como hipóteses, também a exemplo das OPs do tipo Lemma.

Entretanto, de modo a agilizar o desenvolvimento do WPTrans assim como aproveitar

o máximo possível os módulos e funções do WP, tentamos modi�car apenas as funções

diretamente necessárias para o funcionamento pleno do WPTrans. Se criássemos um novo

tipo de OP, teríamos que modi�car todas as funções do WP que acessassem e modi�cas-

sem OPs do tipos Annot para que executassem as mesmas operações no novo tipo de OP.

Essas operações poderiam tanto alterar o WP signi�cativamente, o que não desejamos,

como tomar um tempo relevante na implementação do WPTrans.

De modo a detalhar o acesso e modi�cação das hipóteses, de�nimos algumas funções

que são descritas a seguir, possuindo dois comportamentos distintos: uma para OPs do

tipo Annot e a outra para OPs do tipo Lemma. Essas funções são utilizadas somente

no momento em que é aplicada uma regra de inferência, sendo seus comportamentos

determinados de acordo o tipo da OP alvo da regra. Inicialmente apresentaremos suas

de�nições, mostrando exemplos de uso em uma OP.

A primeira função, newhyp, é especi�cada nos algoritmos 1 e 2. Caso a OP sendo

modi�cada por uma regra de inferência seja do tipo Annot, essa função cria uma nova

condição, isto é, uma nova hipótese para OPs do tipo Annot. Caso contrário, newhyp se

comporta como uma função identidade.

Algoritmo 1 De�nição de newhyp na aplicação de regra de inferência em OP do tipoAnnot1: function newhyp(T : termo) : condição2: return Have T

Page 79: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

77

Algoritmo 2 De�nição de newhyp na aplicação de regra de inferência em OP do tipoLemma1: function newhyp(T : termo) : termo2: return T

A segunda função, pstep, é especi�cada nos algoritmos 3 e 4. Caso a OP sendo modi�-

cada por uma regra de inferência seja do tipo Lemma, o seu argumento é um termo e seu

valor retornado é exatamente esse mesmo termo, se comportando como uma função iden-

tidade. Caso contrário, isto é, caso a OP sendo modi�cada seja uma condição, essa função

retorna o termo dentro da condição. Para as condições If e Either, é retornado um único

termo com valor semântico equivalente. Essa função foi baseada em pred_cond, uma fun-

ção presente no módulo Conditions do WP e responsável por extrair o(s) predicado(s)

dentro de uma condição.

Algoritmo 3 De�nição de pstep na aplicação de regra de inferência em OP do tipo Annot1: function pstep(S : condição) : termo2: match S with

3: | Core T → return T4: | Init T → return T5: | Type T → return T6: | Have T → return T7: | When T → return T8: | If X Then (A1, · · ·, An) Else (B1, · · ·, Bm) →9: return ((X)∧(pstep(A1))∧· · ·∧(pstep(An)))∨(¬(X)∧(pstep(B1))∧· · ·∧(pstep(Bm)))10: | Either(T1, · · · , Tn) → return (pstep(T1)) ∨ · · · ∨ (pstep(Tn))

Algoritmo 4 De�nição de pstep na aplicação de regra de inferência em OP do tipoLemma1: function pstep(S : termo) : termo2: return S

A terceira função, repl, é especi�cada nos algoritmos 5 e 6. Caso a OP sendo modi�cada

por uma regra de inferência seja do tipo Lemma, essa função recebe dois termos como

argumentos, S e K, e o valor de retorno da função é simplesmente o termo K, sendo

ignorado o termo S. Já no contexto de uma OP do tipo Annot, o argumento S é uma

condição. Sua função nesse caso é substituir o predicado dentro de S pelo novo predicado

K. Nos casos de If e Either a condição é substituída por Have com o novo predicado

K.

Page 80: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

78

Algoritmo 5 De�nição de repl na aplicação de regra de inferência em OP do tipo Lemma1: function repl(S : termo, K : termo) : termo2: return K

Algoritmo 6 De�nição de repl na aplicação de regra de inferência em OP do tipo Annot1: function repl(S : Condição, K : Termo) : Termo2: match S with

3: | Core T → return Core K4: | Init T → return Init K5: | Type T → return Type K6: | Have T → return Have K7: | When T → return When K8: | If τ Then (A1, · · ·, An) Else (B1, · · ·, Bm) → return Have K9: | Either (T1, · · · , Xn) → return Have K

Algoritmo 7 De�nição abstrata de vars1: function vars(T : Termo) : Lista de variáveis2: return todas as variáveis livres e ligadas de T

São utilizadas ainda mais duas funções para explicar as regras de inferência, sendo

elas denominadas tipo e vars. A primeira retorna o tipo do termo ou da variável no

qual ela é aplicada e a segunda retorna o conjunto de todas as variáveis presentes no seu

argumento, sendo ele um termo. A descrição de vars se encontra no Algoritmo 7, sendo um

dos principais usos dessa função auxiliar na criação de uma variável distinta das demais

presentes na OP.

Para exempli�car o uso dessas funções, supomos dois cenários diferentes, sendo o

primeiro a aplicação de uma regra de inferência em uma OP do tipo Annot e a segunda

a aplicação da mesma regra em uma OP do tipo Lemma. Então, no primeiro cenário,

newhyp(a + 5) retorna Have a + 5, pstep(When c ⇒ d) retorna c ⇒ d e repl(Have x ∗y, a − 5) retorna Have a − 5. Já no segundo cenário, newhyp(a + 5) retorna a + 5,

pstep(c⇒ d) retorna c⇒ d e repl(x ∗ y, a− 5) retorna a− 5.

As de�nições formais apresentadas nas próximas seções para cada regra de inferência

são válidas tanto para Lemma quanto para Annot. De modo a simpli�car a apresentação

dessas notações, alguns símbolos estão sublinhados. Isso signi�ca que, se a OP sendo

modi�cada por uma regra de inferência for do tipo Annot, então o símbolo representa

uma condição. Caso contrário, isto é, a OP modi�cada é do tipo Lemma, então o símbolo

representa um predicado. Por exemplo, a notação A,B ` O representa uma OP com

duas hipóteses e um objetivo, sendo as hipóteses termos caso a OP seja do tipo Lemma

e condições caso a OP seja do tipo Annot.

Page 81: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

79

A notação T (X1, · · · , Xn) representa um termo (T ) e um subconjunto de seus termos

(X1, · · · , Xn). Se um dos termos é modi�cado por outro, digamos, o termoX1 por Y1, então

toda ocorrência de X1 em T é substituída por Y1. Da mesma forma que com termos, essa

notação também pode ser aplicada em condições. Seja pstep(E) = T , E(X1, · · · , Xn) =

T (X1, · · · , Xn).

A última notação a ser introduzida é a representação de um conjunto de hipóteses.

Utilizamos as letras H para representar H1, · · · , Hn, isto é, um conjunto qualquer de

hipóteses.

Nas seções seguintes serão apresentadas as regras de inferência, sendo o capítulo �-

nalizado com a introdução de um comando que aplica sistematicamente uma das re-

gras implementadas. Algumas delas exigem que sejam inseridos índices de hipótese para

selecioná-los. Cada índice é um número inteiro, sendo 1 (um) o índice da primeira hipótese,

2 (dois) o índice da segunda hipótese, assim por diante. Se o índice inserido for negativo

ou maior que o número de hipóteses, é retornado uma mensagem de índice inválido ao

usuário. Ademais, argumentos adicionados além dos exigidos pela regra de inferência são

ignorados. Para facilitar a compreensão das regras, serão mostrados, em cada caso, exem-

plos de aplicação, utilizando OPs do tipo Lemma. Quando a aplicação de uma regra não

é bem-sucedida, como no caso em que os argumentos inseridos são inválidos, o WPTrans

não realiza nenhuma ação na OP.

4.1 Asserção - assert

A função dessa regra é inserir uma nova hipótese na OP, sendo ela constituída por

um termo escrito pelo usuário. A regra recebe como argumento o termo T que será a nova

hipótese e cria duas OPs. A primeira é igual à OP original, porém com uma hipótese a

mais: T caso a OP seja um Lemma e Have T em caso contrário. A segunda OP possui

as mesmas hipóteses da OP original mas seu objetivo é T . Essa regra é baseada na tática

assert do Coq (The Coq development team, 2015, p. 188), sendo sua formalização exibida

na Figura 44.

H,D ` O H ` TH ` O

D = newhyp(T ) ∧ (tipo(T ) = bool ∨ tipo(T ) = prop)

Figura 44: De�nição de assert

.

Page 82: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

80

A asserção foi implementada para provar a OP Lemma RemoveCountMonotonic,

sendo essa OP e sua prova explicadas detalhadamente na seção 6.2, p. 108.

O comando para utilizar a regra é:

assert <termo>

em que <termo> é o termo inserido pelo usuário. Caso o argumento não seja um termo

do tipo bool ou prop como, por exemplo, uma expressão inteira, a regra de inferência não

é aplicada, retornando uma mensagem de erro informando que o argumento do comando

é inválido. A Figura 45 exempli�ca o uso de assert gerando duas OPs: o antecedente

esquerdo veri�ca se a asserção é válida e o direito adiciona a nova hipótese na OP original.

` n+m = m+ n

n+m = m+ n

`n+m+ (p+ q) = m+ n+ (p+ q)

` n+m+ (p+ q) = m+ n+ (p+ q)assert n + m = m + n

Figura 45: Exemplo da regra assert

A expressão assert n + m = m + n à direita da Figura 45 representa o comando que

deve ser inserido noWPTrans para que haja a respectiva modi�cação sintática do exemplo.

Exemplos da aplicação de comando também estão presentes nos próximos exemplos deste

capítulo.

4.2 Indução sobre inteiros - int_ind

Dados como argumentos uma variável livre k do tipo inteiro e um termo T também

do mesmo tipo, essa regra de inferência aplica uma indução matemática sobre k, sendo

o caso base k = T e o passo indutivo veri�car se a OP é válida par k + 1 considerando

que ela é válida para k. Tanto a variável k como as variáveis e funções em T devem estar

presentes no contexto da OP analisada.

Explicando de forma mais detalhada, essa regra cria três OPs: a primeira veri�ca que

k >= T , a segunda substitui todas as ocorrências de k por T em toda a OP (objetivo

e hipóteses) e a terceira substitui todas as ocorrências de k por k + 1 no objetivo. No

último caso o objetivo original se torna uma nova hipótese. Essa regra é baseada na tática

induction do Coq (The Coq development team, 2015, p. 194), sendo sua formalização

presente na Figura 46.

Page 83: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

81

P1(k), · · · , Pn(k) ` T ≤ k P1(T ), · · · , Pn(T ) ` O(T ) P1(k), · · · , Pn(k),W (k) ` O(k + 1)

H ` O(k)

pstep(W (k)) = O(k) ∧(tipo(k) = prop ∨ tipo(k) = bool) ∧ (tipo(T ) = prop ∨ tipo(T ) = bool)

Figura 46: De�nição de int_ind

Da mesma forma que assert, a indução sobre inteiros foi implementada para provar

uma OP, sendo ela o Lemma RemoveCountMonotonic, também explicada detalhadamente

na seção 6.2, p. 108.

O comando para utilizar essa regra é:

int_ind <variável> <termo>

no qual <variável> e <termo> são, respectivamente, a variável e o termo inseridos pelo

usuário. Essa regra não é aplicada nos seguintes casos: a variável não está presente na OP,

há variáveis e de�nições no termo inserido que também não se encontram no contexto da

OP ou o tipo da variável ou do termo não é int.

Na Figura 47 se encontra um exemplo de aplicação nessa regra, sendo a indução

aplicada à variável j, tendo como base o termo i+ 1. Abaixo se encontram três lemas no

contexto da OP para justi�car o uso da indução.

• ∀t : array[int] · P (t, 0) = 0

• ∀t : array[int], i : int · t[i] = t[i+ 1]⇒ P (t, i) = P (t, i+ 1)

• ∀t : array[int], i : int · t[i] 6= t[i+ 1]⇒ P (t, i+ 1) = P (t, i) + 1

i < j

P (a, i) ≤ P (a, j)

`P (a, i) ≤ P (a, j + 1)

i < j

`i+ 1 ≤ j

i < i+ 1

`P (a, i) ≤ P (a, i+ 1)

i < j ` P (a, i) ≤ P (a, j)int_ind j i+1

Figura 47: Exemplo da regra int_ind

4.3 Introdução de objetivo na hipótese - intro

Essa regra não possui argumentos e apresenta dois comportamentos possíveis: pri-

meiro, se o objetivo da OP for uma implicação, o termo à sua esquerda (da implicação)

Page 84: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

82

é removido do objetivo e inserido no conjunto de hipóteses, deixando no objetivo apenas

o lado direito da implicação. Entretanto, um segundo comportamento emerge quando o

objetivo for uma quanti�cação universal, pois, nesse caso, será realizada uma instancia-

ção, sendo a variável criada pela regra inserida no contexto da OP. O intro realiza um

subconjunto de ações possíveis da tática com mesmo nome de�nida no Coq (The Coq

development team, 2015, p. 180). Sua representação formal para os dois comportamentos

descritos se encontram nas �guras 48 e 49. Assim como com int_ind, essa regra de infe-

rência foi implementada para provar a OP Lemma CountBounds, sendo sua de�nição e

prova detalhadas na seção 6.2, p. 106.

H ` O(t)

H ` ∀x ·O(x)t /∈ (

⋃ni=0 vars(pstep(Hi)) ∪ vars(O))

Figura 48: De�nição de intro - instanciação universal

H,T ` BH ` A⇒ B

T = newhyp(A)

Figura 49: De�nição de intro

A estrutura dessa regra é apenas

intro

sem nenhum argumento. Caso o objetivo não seja mais uma implicação, simplesmente

nenhuma ação é tomada. As �guras 50 e 51 contêm exemplos de aplicação de intro. Na

primeira �gura, o termo à esquerda da implicação é enviado ao conjunto de hipóteses,

enquanto na segunda, é realizada uma instanciação universal, sendo adicionada a variável

t no conjunto de variáveis do contexto da OP.

0 < a ` 0 ≤ a

` 0 < a⇒ 0 ≤ aintro

Figura 50: Primeiro exemplo da regra intro

` t+ 0 = t

` ∀t : int · t+ 0 = tintro

Figura 51: Segundo exemplo da regra intro

Page 85: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

83

4.4 Desdobrar função - unfold e unfold_all

A ação dessa regra é substituir uma aplicação de função por sua de�nição, sendo seu

argumento o nome da função que será substituída por sua de�nição. Ela pode ser aplicada

tanto apenas no objetivo como em todos os termos da OP. No último caso, a regra possui

o nome unfold_all.

Quando essa regra é aplicada, todos os argumentos da função são substituídos pelos

termos da OP aplicados na chamada da função. Para explicar melhor, segue-se um exem-

plo: seja uma função f(x) = 1 < x ∧ x < 5, e um objetivo a = 4 ∧ f(a + 1), essa regra

irá gerar o seguinte objetivo: a = 4 ∧ 1 < (a + 1) ∧ x < 5, no qual o argumento x foi

substituído pelo termo a+ 1, presente na chamada da função f . A de�nição formal dessa

regra se encontra nas �guras 52 e 53.

H ` O(D(X1, · · · , Xn))

H ` O(f(X1, · · · , Xn))D(X1, · · · , Xn) = def(f,X1, · · · , Xn)

Figura 52: De�nição de unfold

P1(D(X1, · · · , Xn)), · · · , Pn(D(X1, · · · , Xn)) ` O(f(X1, · · · , Xn))

P1(f(X1, · · · , Xn)), · · · , Pn(f(X1, · · · , Xn)) ` O(f(X1, · · · , Xn))

D(X1, · · · , Xn) = def(f,X1, · · · , Xn)

Figura 53: De�nição de unfold_all

A função def possui como argumentos uma função (digamos f) e um conjunto de

termos, retornando a de�nição de f com seus argumentos substituídos pelos termos pre-

sentes nos argumentos de def (essa de�nição é presentada pelo termo D com os argumen-

tos X1, · · · , Xn). Essa regra foi baseada na tática homônima presente no Coq (The Coq

development team, 2015, p. 215). Assim como a regra assert, unfold foi implementada

para provar a OP Lemma RemoveCountMonotonic, sendo a OP e sua prova explicadas

detalhadamente na seção 6.2, p. 108.

Os comandos para aplicar essa regra são:

unfold <função>

unfold_all <função>

em que <função> é o nome da função que deverá ser desdobrada. Nenhuma ação é

Page 86: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

84

realizada caso a função inserida não esteja presente no contexto da OP. A Figura 54

ilustra um exemplo da aplicação de unfold, sendo desdobrada a função f(x) = x+ 1.

` t < t+ 1

` t < f(t)unfold f

Figura 54: Exemplo da regra unfold

Algumas funções são de�nidas apenas em arquivos externos ao WP, nas diferentes

linguagens para o qual o WP pode traduzir as OPs: WhyML, Gallina e a linguagem

nativa do Alt-Ergo. Quando o WP traduz uma OP para uma dessas linguagens, ela anexa

as de�nições externas no arquivo gerado com a tradução, mantendo em memória apenas a

declaração dessas funções. Devido às suas de�nições estarem armazenadas externamente,

o unfold não pode ser aplicado para essa funções. Algumas funções que se encontram nesse

caso são shift, offset e is_sint32, sendo as duas primeiras usada para localização e

acesso à posição em um vetor no modelo Typed.

4.5 Instanciar quanti�cador existencial no objetivo -

existo

Se o objetivo for uma quanti�cação existencial, essa regra elimina o quanti�cador,

substituindo sua variável ligada por um termo inserido pelo usuário. Caso contrário, não

é realizada nenhuma ação na OP. A instanciação do quanti�cador existencial é baseada

na regra XST_R, presente em Abrial (2010, p. 317). A prova por casos também foi

implementada para provar a OP Lemma RemoveCountMonotonic, sendo ela e sua prova

explicadas detalhadamente na seção 6.2, p. 108. A formalização do existo é descrita na

Figura 55.

H ` O(E)

H ` ∃x ·O(x)

vars(E) ⊆ (⋃n

i=0 vars(pstep(Hi)) ∪ vars(O)) ∧ tipo(E) = tipo(x)

Figura 55: De�nição de existo

Da mesma forma que na regra allh, todas as variáveis livres do termo inserido pelo

usuário devem estar presentes no contexto da OP, sendo o novo termo aceito apenas se

possuir estritamente o mesmo tipo da variável que será instanciada.

Page 87: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

85

A estrutura do comando dessa regra é:

existo <termo>

sendo <termo> o termo que irá substituir a variável ligada existencialmente no objetivo.

Caso esse termo possua de�nições e variáveis livres que não estejam no contexto da OP,

uma mensagem de erro é retornado ao usuário. A Figura 56 exibe um exemplo de existo:

a variável quanti�cada y no objetivo é instanciada com uma variável existente t da OP.

a = 5, b = 6 ` b > a

a = 5, b = 6 ` ∃t · t > aexisto t

Figura 56: Exemplo da regra existo

4.6 Prova por casos - case

Dado um termo E, inserido pelo usuário, e uma OP com objetivo O, essa regra cria

duas OPs com os objetivos ¬(E) ⇒ O e E ⇒ O, sendo baseada no comando Do cases

do Atelier-B (CLEARSY, 2008, p. 45). Essa regra de inferência foi implementada para

provar a OP do lema sum3, sendo a OP e sua prova explicadas detalhadamente na seção

6.3, p. 112. Sua descrição formal se encontra na Figura 57.

H ` A⇒ O H ` ¬A⇒ O

H ` Otipo(A) = prop ∨ tipo(A) = bool

Figura 57: De�nição de case

A estrutura do comando da prova por casos é

case <termo>

sendo <termo> o termo aplicado pela regra. Caso o termo inserido não seja do tipo

prop ou bool, uma mensagem de erro é retornado ao usuário. A aplicação de case no

exemplo da Figura 58 cria duas novas OPs, sendo o objetivo da primeira o novo termo

m ≥ 0 implicando no objetivo da OP original, e o objetivo da segunda a negação do novo

termo (¬m ≥ 0), implicando também no objetivo da OP original. No exemplo também é

possível notar a reescrita realizada pelo WP ao receber o novo termo, substituindo ≥ por

≤ e removendo a negação.

Page 88: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

86

m− s = r

`0 ≤ m⇒ m = r + s

m− s = r

`m < 0⇒ m = r + s

m− s = r ` m = r + scase m >= 0

Figura 58: Exemplo da regra case

4.7 Introdução de hipótese - intros

O comando intros consiste em executar a regra intro repetidamente enquanto for

possível, parando sua execução quando é detectado que não há mais nenhuma alteração

na OP após a aplicação da regra. Esse comando não requer argumento, sendo baseado

na tática homônima do Coq (The Coq development team, 2015, p. 180). Para usar essa

regra basta apenas inserir o comando:

intros

sem nenhuma variável.

A Figura 59 demonstra o uso do comando. Após a aplicação da regra tanto a quanti-

�cação universal quanto as implicações no objetivo foram removidas.

a > b, c = d ` z = a− 10

` ∀ · a > b⇒ c = d⇒ z = a− 10intros

Figura 59: Exemplo da regra intros

Esse comando foi utilizado em todas as OPs veri�cadas, eliminando a necessidade de

inserir intro repetidas vezes.

4.8 Conclusões do capítulo

As regras de inferência constituem o fator principal do WPTrans, tendo sido imple-

mentadas 21 (vinte e uma) regras de inferência que podem ser aplicadas nas OPs com

a intenção de modi�cá-las. Essas regras foram implementadas gradualmente, a partir da

seleção de um conjunto pré-selecionado de OPs. Enquanto testávamos a implementação

da extensão, também realizávamos uma análise de sua e�ciência, registrando as provas

Page 89: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

87

que eram concluídas com o auxílio do WPTrans. Dessa forma, descrevemos a metodologia

de testes nas análises experimentais, presente no capítulo 6.

Outrossim, tivemos preocupações com diversos outros aspectos no desenvolvimento

do WPTrans. Apresentamos no próximo capítulo o modo como as regras de inferência

devem ser aplicadas, a descrição de interface visual de uso, meios de interação entre o

usuário e a extensão, estratégias aplicadas na implementação do WPTrans, organização

do código-fonte, experiências e di�culdades na construção dessa extensão e funcionalidades

descartadas ao longo do desenvolvimento desta pesquisa.

Page 90: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

88

5 WPTrans - Outras funcionalidades

e aspectos técnicos

No desenvolvimento do WPTrans, tivemos que de�nir algumas estratégias para im-

plementar as regras descritas no capítulo anterior, mas respeitando e reaproveitando o

máximo possível as funções e estruturas do Frama-C. Um dos pontos discorridos foi a

interface grá�ca, sendo ele como o usuário poderá interagir com o WPTrans de forma

clara e e�caz. As decisões tomadas estão comentadas na seção 5.1.

Algumas regras de inferência requerem termos como argumentos, sendo estes argu-

mentos inseridos pelo usuário. Destarte, é necessário que o WPTrans dispusesse de meca-

nismos para lê-los e interpretá-los. É descrito na seção 5.2 o analisador léxico e sintático

inserido na extensão, a gramática aceita para termos e a estratégia de implementação. Na

seção 5.3, são descritos outros comandos que interagem com as OPs e com a interface do

WPTrans, sendo alguns deles chamar provador externo, reverter a aplicação de uma regra

etc.

Já na seção 5.4 é exposta a organização do código, mostrando os módulos implementa-

dos, suas funcionalidades e como eles estão interligados com os módulos do WP. Na seção

5.5, são apresentadas as tecnologias utilizadas na implementação, descrevendo desde a

linguagem de programação até as ferramentas usadas para a inserção de código.

Na seção 5.6, são comentadas as di�culdades no desenvolvimento da extensão, re-

latando as soluções tomadas para superá-las e a experiência obtida. En�m, a seção 5.7

aborda ideias e modi�cações descartadas no desenvolvimento do plugin, apresentando, por

exemplo, regras de inferência removidas.

Page 91: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

89

5.1 Interface Grá�ca

A Figura 60 ilustra a janela principal da extensão, mostrando, na coluna central, as

hipóteses e o objetivo da OP a ser provada. Na coluna esquerda estão listadas, na região

superior, as OPs do projeto, e, na região inferior, as variáveis da OP selecionada.

Na coluna direita se encontram, na região superior, o histórico de regras de inferência

aplicadas e as de�nições de funções e lemas acessíveis à OP selecionada. Essas de�nições

são provenientes de duas fontes diferentes. As anotações ACSL constituem a primeira

fonte de funções e lemas, sendo determinadas pelo WP quais de�nições estão disponíveis

para a OP. Já a segunda fonte são funções predeterminadas pelo modelo de memória

utilizado. Por exemplo, o modelo Typed contém funções para acessar regiões de memória

e para veri�car se uma variável é válida para leitura e escrita de dados. O espaço textual

central é o console por onde o usuário pode interagir com as OPs. Por último, as duas

abas na região inferior são, respectivamente, os resultados da execução dos comandos no

console e dos diferentes provadores aplicados na tentativa de prova da OP.

As regras de modi�cação e os demais comandos possíveis (desfazer a aplicação de uma

regra de inferência, executar um provador SMT etc.) são executados no console. Ao inserir

o comando e pressionar o botão enter ele é imediatamente executado, apagando o texto

no console em seguida. Por exemplo, inserindo

case i <= 0

no terminal e pressionando enter, o WPTrans tenta aplicar a regra de inferência case com

o argumento i <= 0 na OP exibida ao usuário, removendo o comando do console logo em

seguida. Nas próximas versões da extensão, pretendemos permitir que vários comandos

sejam executados em sequência, utilizando um separador como ponto e vírgula (�;�). Além

do console, é possível executar as regras de modi�cação através do clique com o botão

direito do mouse nas hipóteses e no objetivo, sendo listadas todas as regras de inferência

que possam ser aplicadas nos elementos selecionados.

Todas as subjanelas da interface grá�ca (console, região onde se encontram as hipó-

teses, a seção com a lista de OPs etc.) possuem tamanhos ajustáveis, isto é, elas podem

ser manualmente expandidas (e reduzidas) tanto vertical quanto horizontalmente pelo

usuário, con�gurando-a de modo que lhe seja mais adequado.

O leiaute do WPTrans foi inspirado predominantemente pelo CoqIde. Essa interface

é composta de três janelas, sendo uma para a exibição da OP em veri�cação, uma para

Page 92: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

90

Figura 60: Janela principal do WPTrans

Page 93: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

91

inserção de comandos pelo usuário e uma para a exibição de mensagens de retorno do Coq

para a aplicação de cada comando. A descrição e uma captura de tela desse programa são

descritas na seção 3.7 sendo todas as três janelas adaptadas ao WPTrans.

O WPTrans também foi moldado a partir de duas janelas do Rodin: Proof Skeleton

e Event-B Explorer. A primeira janela lista todas as regras aplicadas em uma OP, assim

como o estado atual da veri�cação, exibindo as regras como uma árvore de prova. Já a

segunda mostra todas as OPs dos projetos abertos, junto, também, com o estado atual

da veri�cação. Ambas as janelas in�uenciaram na criação da coluna com a lista de OPs à

esquerda do WPTrans, sendo apresentadas na Figura 61.

Figura 61: Janelas Proof Skeleton e Event-B Explorer do Rodin 1

A interface grá�ca do WPTrans possui os mesmos requisitos da versão grá�ca do

Frama-C (frama-c-gui) e do WP. Portanto, se as duas primeiras ferramentas forem

possíveis de serem instaladas e usadas em um computador, o WPTrans também será.

5.2 Leitura de termos

Algumas regras de inferência exigem que o usuário insira novos termos, sendo a regra

case um exemplo. Contudo, a di�culdade encontrada foi em como analisar e transformar

léxica e sintaticamente as strings inseridas pelo usuário em termos do WP.

Decidiu-se, inicialmente, ler e imprimir termos na sintaxe concreta padrão que o WP

usa para exibir as OPs. Porém, são disponibilizadas apenas funções de impressão para essa

sintaxe. Com isso, teríamos que implementar um analisador léxico e sintático completo

para termos, mas, receosos de não haver tempo hábil na duração desta pesquisa, optamos

por uma realização alternativa. O Frama-C dispõe de um interpretador para expressões

em ACSL assim como todos os operadores e construções de termos em WP possuem

1Disponível em <http://wiki.event-b.org/images/ProofSkelUncertain.png>. Acesso em: 5 abr. 2016.

Page 94: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

92

um equivalente em ACSL. Desse modo, reaproveitamos esse interpretador no WPTrans,

dando essa opção de sintaxe ao usuário. Entretanto, as funções de impressão de termos e

predicados em ACSL não estavam de�nidas, o que nos levou a implementá-las, respeitando

a sintaxe da ACSL presente em Baudin et al. (2015d).

A gramática utilizada para inserir termos e predicados está detalhada na Figura 62.

Construções ACSL que não estejam de�nidas nessa gramática são consideradas erros de

sintaxe no WPTrans. integer e real representam, respectivamente, números inteiros e reais,

já id representa identi�cadores usuais da linguagem C composta por uma letra seguida

por letras e dígitos.

vars := tipo id | vars, tipo id

tipo := tipo1 | tipo*

tipo1 := int | boolean | real | struct id

literal := \true | \false constantes booleanas

| integer números inteiros

| real números reais

bin-op := + | - | * | / | % | == | != | <= | >= | > | < | && operadores binários

| ==> | <==>

unary-op := + | - | ! operadores unários

term := literal

| id identi�cador

| unary-op term

| term [ term ] acesso à posição de array

| { term \with [ term ] = term } atualização de array

| term.id acesso a campo de struct

| { term \with . id = term } atualização de struct

| ( term ) parênteses

| term ? term : term operador ternário

| \forall vars ; term quanti�cação universal

| \exists vars ; term quanti�cação existencial

Figura 62: Gramática para inserção de termos no WPTrans com sintaxe ACSL

A palavra-chave int representa o tipo int, real representa o tipo real e boolean

representa o tipo bool. Para inserir um tipo diferente é necessário usar a regra struct

id, substituindo id pelo nome do tipo. Adotamos essa solução paliativa pois o analisador

Page 95: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

93

léxico e sintático do ACSL não permite que seja inserido diretamente um tipo que não

esteja prede�nido na gramática da linguagem, sendo \exists addr x, addr y; x == y

uma sintaxe inválida por exemplo.

Posteriormente, retomamos a ideia do uso da sintaxe original do WP, e tentamos im-

plementar um interpretador para este, utilizando um gerador de analisador léxico (ocaml-

lex ) e um sintático (ocamlyacc) 2. Ela foi parcialmente concluída, todavia decidimos pri-

orizar outras funcionalidades da extensão, deixando essa tarefa para trabalhos futuros.

5.3 Comandos implementados

Além das regras de inferência, também foram criados outros comandos para interagir

com as OPs e com os provadores de teoremas. Esses comandos foram baseados nos mesmos

assistentes de prova utilizados para criar as regras de inferência, sendo listados a seguir:

• call <provador> - esse comando executa o Qed ou um provador externo, sendo ele

o Alt-Ergo, o Coq ou um provador conectado ao Why3. Por exemplo, para chamar

o Alt-Ergo é necessário inserir call alt-ergo. O WPTrans possui a função de

autocomplemento, mostrando os provadores instalados e disponíveis. Esse comando

não permite que a OP seja manipulada externamente por um assistente de provas,

devendo ser utilizado o comando edit para tal �m.

• edit <provador> - esse comando executa um provador externo, sendo ela em modo

edição. Por exemplo, se o provador for o Coq, é executado o CoqIde, já se a seleção for

o Alt-Ergo é executado o Altgr-Ergo, a interface grá�ca desse solucionador SMT.

Caso o provador não tenha um modo de edição de OP o comando retorna uma

mensagem de erro ao usuário.

• reset_all - remove todos os antecedentes de uma OP criada pelo WP, retornando

ao seu estado original.

• undo - desfaz a última regra aplicada, retornando a OP ao estado anterior.

• set_timeout <tempo> - de�ne o tempo limite em segundos para a execução de um

provador externo.

2Disponível em: <http://caml.inria.fr/pub/docs/manual-ocaml/lexyacc.html>. Acesso em: 5 jun.2015.

Page 96: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

94

• set_processes <processos> - de�ne a quantidade limite de processos utilizados

para a veri�cação de uma prova.

5.4 Organização do código

Foram implementados no total oito (8) módulos agregando todas as funcionalidades

da extensão, totalizando aproximadamente seis mil (6000) linhas de código. Na Figura

63 se encontra o esquema de organização desses módulos, sendo os nós com fundo cinza

módulos do WPTrans e nós com fundo branco módulos do WP. A seguir temos uma breve

descrição de cada módulo:

Figura 63: Janela principal do WPTrans

• WpoRewriter_infRules_names - esse módulo consiste basicamente de constantes e

de�nições de tipos, sendo utilizadas pelos demais módulos para identi�car as regras

de inferência implementadas;

Page 97: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

95

• infRules - esse módulo contém a implementação de todas as regras de inferência do

WPTrans. Uma regra de inferência é executada a partir de parâmetros com tipos

de�nidos pelo módulo WpoRewriter_infRules_names;

• GuiWpoRewriter - esse módulo de�ne a janela principal da interface do WPTrans.

Além disso, ele também de�ne a apresentação das OPs e executa os demais módulos

relacionados à interface grá�ca;

• GuiWpoTreeView - esse módulo de�ne a interface da janela na qual é mostrada a

árvore de OPs do projeto e seus estados. Ele é inicializado pelo GuiWpoRewriter;

• GuiConsole - esse módulo é utilizado para inicializar e de�nir o comportamento da

interface grá�ca do console no qual o usuário insere os comandos. Os comandos

são lidos e enviados ao módulo WpoRewriter_console para serem interpretados.

Também é inicializado pelo GuiWpoRewriter;

• WpoRewriter_console - esse módulo lê e interpreta os comandos inseridos pelo usuá-

rio;

• Formula_Parser - esse módulo possui a implementação do analisador léxico e sin-

tático apresentado na seção 5.2;

• Rewriter_utils - esse módulo possui funções auxiliares utilizadas pelo WPTrans,

como, por exemplo, obter todas as variáveis livres utilizadas por um termo. É tam-

bém implementado nesse módulo o comportamento dos comandos undo e reset_all.

Nós também precisamos utilizar diretamente os seguintes módulos doWP, modi�cando-

os quando necessário:

• VCS - esse módulo armazena nomes e tipos de provadores e linguagens, assim os

tipos de dados para representar o estado de cada prova (se foi provado ou não, qual

provador utilizado, tempo de prova etc.);

• Wpo - esse módulo de�ne o tipo OP, incluindo modelo utilizado, e estado da prova

(utilizando os tipos de�nidos em VCS). Ele também armazena as OPs produzidas

para cada análise. O tipo de dado para representar uma OP não se encontra to-

talmente de�nida nesse módulo, sendo necessário acessar o módulo Conditions pra

obter a de�nição de condição;

Page 98: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

96

• Conditions - esse módulo de�ne as condições, isto é, as hipóteses presentes em OPs

do tipo Annot;

• De�nitions - esse módulo possui a de�nição de funções e lemas, além de armazenar

as funções e lemas acessíveis a cada OP;

• Lang - esse módulo possui funções para obter tipos de termos e variáveis, criar novos

termos e variáveis, obter versões em strings desses tipos, entre outras funções.

• Model - esse módulo registra e disponibiliza os modelos de memória utilizados em

uma análise;

• Wp_parameters - esse módulo registra todas as opções de con�guração do WP, in-

cluindo escolha dos modelos de memória e aritmético, provador utilizado na análise,

estratégia de simpli�cação aplicadas etc.

• GuiGoal - esse módulo implementa a apresentação da versão impressa da OP na

janela do WP, sendo utilizado pelo GuiWpoREwriter para exibir a OP no WPTrans;

• Prover e ProverTask - esses módulos executam um provador de teorema externo. O

primeiro módulo organiza os dados para lançar o provador, já o segundo inicializa

e controla o processo de execução de cada provador.

• ProverWhy3 - as principais funções desse módulo são traduzir uma OP para a

linguagem WhyML e executar um provador conectado ao Why3;

• WpPropId - uma das funcionalidades desse módulo é lidar com OPs geradas a partir

de uma mesma fonte de informação, atribuindo um índice a cada uma delas. Por

exemplo, duas OPs podem ser criadas para um mesmo invariante de laço, sendo a

primeira para provar que ela é válida antes do laço ser executado e a segunda para

provar que ela continua válida após cada iteração.

Nos próximos parágrafos são comentadas algumas das modi�cações realizadas tanto

no WP quanto no WPTrans.

O WP armazena suas OPs em um conjunto dentro do módulo Wpo, exibindo e veri�-

cando apenas as OPs dentro dele. Para que o plugin acesse e analise as OPs geradas pelo

WPTrans, seu código do Wpo foi modi�cado de modo que os antecedentes produzidos por

uma regra de inferência sejam adicionadas a esse conjunto, removendo o respectivo conse-

quente. Desse modo, as OPs produzidas pelo WPTrans �cam �visíveis� ao WP, podendo

acessá-las e manipulá-las da mesma forma que as demais.

Page 99: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

97

Além da modi�cação mencionada no parágrafo anterior, mantemos, para cada OP,

uma referência ao seu consequente e aos seus antecedentes, formando uma árvore de OPs.

A Figura 64 demonstra um exemplo em que foi aplicada uma regra de inferência na OP

2, gerando duas novas OPs. Tanto a OP 2 mantém referência para OP 2a e OP 2b como

o contrário, isto é, ambas mantêm uma referência para OP 2.

Figura 64: Árvore de OPs

Uma outra alteração também realizada foi a adição de um campo na estrutura de dado

que representa a OP. Esse campo registra a regra de inferência aplicada para produzir a

OP, sendo útil para mostrar ao usuário o histórico de regras aplicadas. Outrossim, essas

informações podem ser úteis tanto para salvar o estado das modi�cações, podendo ser

retomadas em outra instância do WPTrans, como para veri�car, através de um analisador

externo, a corretude da prova. Ambos os pontos são detalhados, respectivamente, na seção

5.5 e nas Considerações Finais.

Com relação ao WPTrans, seu principal módulo é o InfRules. Ela dispõe de duas

funções públicas, sendo elas:

val string_of_inf_rule: tactic_s -> string

val execute_inf_rule : po_gid:string -> tactic_s -> Wpo.t

A primeira função retorna uma representação textual de uma regra de inferência

enquanto a segunda aplica uma regra de inferência na OP a partir de seu identi�ca-

dor. Toda OP possui um campo denominado po_gid, do tipo string, devendo ele ser

único por OP. Todos os valores possíveis para o tipo tactic_s se encontram no módulo

WpoRewriter_infRules_names.

A decisão de encapsular as regras de inferência em objetos do tipo tactic_s foi

tomada para que as regras de inferência aplicadas a uma OP pudessem ser salvas no WP ou

externamente, revertidas com alguns comandos como o undo e adicionadas no histórico de

Page 100: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

98

regras de inferência utilizadas. A arquitetura de InfRules foi levemente baseada no padrão

de projeto Comando (Command) da Engenharia de Software. Esse padrão se caracteriza

por encapsular requisições em objetos para que possam ser executadas posteriormente

e/ou registrar seu uso no programa (GAMMA et al., 1995).

5.5 Ferramentas e versões

A extensão do WP foi implementada na linguagem OCaml versões 4.02.1 e 4.02.3. Nos

primeiros seis meses da pesquisa, utilizamos a versão Frama-C Neon, sendo substituído

pela versão Sodium em abril de 2015. A última substituição foi realizada em novembro

do mesmo ano pela versão Magnesium.

Foram utilizadas apenas funções das bibliotecas do Frama-C e padrões do OCaml.

O código, por sua vez, foi armazenado em um repositório Git no Bitbucket3. En�m, a

escrita do código foi realizada usando a ferramenta Emacs4 versão 24 utilizando os modos

Tuareg5 e Merlin6.

5.6 Di�culdades e experiências

Nesta seção descrevemos di�culdades e experiências antes e durante o desenvolvimento

do WPTrans.

A primeira tentativa de implementação foi através da criação de um novo plugin que

acessasse as funções e as estruturas do WP. Porém, o WP disponibiliza poucas funções

públicas, sendo sua estrutura interna privada, notadamente as de�nições das OPs. Isso

posto, foi imediatamente adotada a ideia de modi�car o próprio WP, buscando alterar

minimamente o código dos arquivos já existentes. Adotamos essa ideia como um pali-

ativo, procurando imediatamente desenvolver a extensão e analisar o quão bené�co ela

pode ser com relação ao WP. No caso de sucesso nos testes, poderíamos contatar os de-

senvolvedores do WP para propor uma integração do WPTrans no código-fonte do WP

ou tornar públicos funções e módulos do WP que foram necessários para o funcionamento

do WPTrans.3Disponível em:<https://bitbucket.org/>. Acesso em: 6 abr. 2016.4Disponível em: <https://www.gnu.org/software/emacs/>. Acesso em: 6 de abr. 2016.5Disponível em: <https://www.emacswiki.org/emacs/TuaregMode>. Acesso em: 6 abr. 2016.6Disponível em: <https://github.com/the-lambda-church/merlin/wiki/emacs-from-scratch>. Acesso

em: 6 abr. 2016.

Page 101: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

99

Algumas modi�cações do WP consistiram em tornar públicos tipos, funções e variá-

veis presentes no WP, principalmente os tipos que de�nem as OPs e as que de�nem as

hipóteses do tipo Annot. Os módulos relacionados à interface grá�ca do WP também

foram modi�cadas para que eles pudessem executar o WPTrans. Detalhes da modi�cação

do código do WP são descritos no Apêndice F.

Contudo, tivemos di�culdade em compreender o código do WP. Apesar de estar dis-

ponível publicamente uma documentação da Application Programming Interface(API) do

Frama-C e do WP, isto é, as descrições dos módulos, funções, classes, de�nições e va-

riáveis da plataforma, elas não estão su�cientemente detalhadas para o plugin. A API

do WP contém apenas os nomes e estruturas das de�nições públicas de cada módulo,

sem descrever seus propósitos ou comportamentos. Assim, nós aprendemos a utilidade de

alguns módulos e funções ou analisando o código-fonte ou observando os resultados de

suas execuções, através de tentativa e erro. No início do projeto não éramos experientes

com o OCaml, o que agravava ainda mais o entendimento do código. Esse fator in�u-

enciou signi�cativamente no desenvolvimento do WPTrans, estendendo o cronograma da

pesquisa.

Além da API do WP, tivemos di�culdades no uso da biblioteca LablGtk7. Essa bibli-

oteca é um adaptador que permite ao OCaml utilizar a biblioteca GTK8 para a criação

de uma interface grá�ca. Apesar de haver exemplos de uso e uma documentação para o

LablGtk, tivemos de reexecutar o WPTrans uma quantidade signi�cativa de vezes apenas

para realizar ajustes em sua interface grá�ca.

Para escolher quais regras de inferência implementar era necessário que entendêssemos

como uma prova era realizada no Coq, analisando quais táticas seriam mais adequadas

e/ou essenciais, além de observar quais de�nições são acessíveis ao usuário. Havíamos

implementado algumas regras de inferência a partir do Rodin e do Atelier-B, porém in-

tencionávamos que novas regras de inferência fossem adicionadas estritamente se neces-

sário, tentando manter um conjunto e�ciente de regras implementadas. Para tal �m, era

imprescindível saber manejar o Coq e ter uma habilidade mínima de provas. No início da

pesquisa não havíamos utilizado esse assistente de provas antes, assim como observamos

que algumas OPs produzidas pelo WP tinham muitas hipóteses, tornando-as consideravel-

mente complexas. Com o objetivo de amenizar os dois problemas abordados, estudamos o

conteúdo de Pierce et al. (2015), realizando provas com o Coq e aprimorando habilidades

de prova.

7Disponível em: <http://lablgtk.forge.ocamlcore.org/>. Acesso em: 6 abr. 2016.8Disponível em: <http://www.gtk.org/>. Acesso em: 6 abr. 2016.

Page 102: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

100

Com relação a testes, desejávamos avaliar e testar as implementações que realizáva-

mos. Nossa primeira ideia foi criar testes unitários e de cobertura de código. Percebemos

que o WP utiliza a ferramenta ptests, disponibilizada pelo Frama-C. Ela permite que se-

jam realizados testes unitários e de não regressão, sendo este último para assegurar que

modi�cações no plugin tenham o efeito esperado.

O ptests consiste em executar a análise de plugin num arquivo selecionado pelo usuário,

sendo ele geralmente um código C com ACSL, salvando o resultado dessa análise em um

�oráculo� (SIGNOLES et al., 2015). Os resultados do oráculo devem ser veri�cados pelo

usuário, assegurando que estão corretos. As execuções subsequentes a esse teste comparam

os resultados com o resultado do �oráculo�, retornando as diferenças entre ambas. Caso

estas mudanças sejam desejáveis, fruto da adição de uma funcionalidade no plugin por

exemplo, o resultado pode se tornar o novo �oráculo�, sendo comparado com o resultado

de novos testes.

Pensamos em utilizar o ptests no projeto, porém consideramos a con�guração dos

testes relativamente complexas no início do projeto, assim como teríamos que automatizar

a aplicação do WPTrans nas OPs do WP. Decidimos então postergar o uso de ptests para

outras oportunidades de pesquisa.

A forma que utilizamos, de fato, para analisar o comportamento do WPTrans foi

através da observação manual da execução da interface grá�ca e através de mensagens

de log e erros do sistema, acompanhando resultados inesperados. O Frama-C e o WP

permitem que sejam inseridas mensagens de depuração (debug) no código, como em:

let dkey = Wp_parameters.register_category "wptrans" (* debugging key *)

let debug fmt = Wp_parameters.debug ~dkey fmt

let contains s1 s2 =

debug "s1=%s,s2=%s" s1 s2;

let re = Str.regexp_string s2 in

try ignore (Str.search_forward re s1 0); true

with Not_found -> false

As duas primeiras linhas registram uma categoria de depuração, denominado wptrans,

e, na função mais abaixo, são impressos seus dois argumentos. A função debug só é

executada quando é adicionado o argumento

-wp-msg-key wptrans

ao executar o Frama-C com o WP.

Page 103: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

101

5.7 Ideias e modi�cações descartadas e não realizadas

Durante a implementação, houve duas regras de inferência que foram implementadas

e posteriormente descartadas do projeto. A primeira foi a reescrita do símbolo <= (menor

ou igual). Toda ocorrência de um subtermo com o formato a <= b era substituída por

(a < b) ∨ (a = b). Essa regra foi uma primeira tentativa de se realizar prova por casos,

separando limites da comparação. Porém, durante as tentativas de prova de OPs seu uso

mostrou-se dispensável, sobretudo após a implementação da regra de prova por casos.

A segunda regra descartada foi a reescrita do símbolo ⇒ (implicação). Ela consistia

em substituir toda ocorrência de um subtermo com o formato a ⇒ b em (¬a) ∨ b. Noentanto, assim como a regra anterior, esta não causou impacto em nenhuma tentativa de

prova, sendo considerada não proveitosa para o WPTrans.

Uma funcionalidade idealizada, mas não implementada, foi a capacidade de salvar e

recuperar, de forma persistente, as regras de inferência aplicadas. Houve duas abordagens

na tentativa de implementação: salvar e carregar as modi�cações em arquivos externos ao

programa ou utilizar o mecanismo de persistência de dados do Frama-C.

O primeiro caso consistiu em salvar as regras aplicadas em um arquivo de texto, com

formato próprio, numa pasta e com nome de�nidos pelo usuário. Essa opção chegou a ser

implementada, porém acabamos julgando-a desconexa com o Frama-C, uma vez que este

possui uma biblioteca para salvar e ler dados. Ademais, essa biblioteca também separa os

dados de acordo com os projetos a que eles pertencem, o que poderia ser consideravelmente

proveitoso para o WPTrans. Consequentemente, a opção de salvar as regras aplicadas num

arquivo externo foram descartadas.

A segunda alternativa foi justamente utilizar a biblioteca mencionada no parágrafo

anterior. Entretanto, o WP não salva as OPs no Frama-C. Isto é, se o usuário realizar os

seguintes passos:

1. Abrir o Frama-C

2. Analisar código C com o WP, gerando OPs

3. Salvar um novo projeto no Frama-C

4. Fechar e reiniciar o Frama-C

5. Reabrir o projeto

Page 104: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

102

As OPs não estarão mais presentes no programa, tornando impossível retomar o estado

anterior e continuar a veri�cação. Devido às limitações de tempo da pesquisa, decidimos

então adiar a adição dessa funcionalidade na extensão, discutindo qual das duas ou mesmos

se ambas as soluções devem ser implementadas.

No próximo capítulo serão apresentados os resultados experimentais da aplicação do

WPTrans em algumas OPs, seguido das Considerações Finais.

Page 105: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

103

6 Análise experimental

Na análise experimental avaliamos a e�cácia da extensão através de três abordagens:

1. Usando o WPTrans, provar OPs que não foram validadas pelo Qed, tampouco por

solucionadores SMT;

2. Provar as OPs geradas pelos exemplos de Burghardt e Gerlach (2015) validadas

somente com o Coq, comparando a quantidade de regras de inferência usadas com

o Coq e com o WPTrans.

3. Especi�car os algoritmos da STL do C++, veri�cando com o WPTrans as OPs que

não foram validadas nem pelo Qed nem por solucionadores SMT.

Antes de dar prosseguimento à explicação das três abordagens supracitadas, introdu-

zimos quais solucionadores e versões do Frama-C e do WP foram utilizados, assim como

quais comandos foram aplicados. Para a realização de todos os testes tentamos utilizar os

seguintes solucionadores SMT:

• Alt-Ergo public release versão 0.99.1;

• CVC4 versão 1.4;

• Z3 versão 4.3.2;

As veri�cações foram realizadas na versão 0.9 do WP. Foram utilizadas duas versões do

Frama-C, sendo a Sodium utilizada nas duas primeiras abordagens e a versão Magnesium

na última. Em todas as três abordagens de testes foi utilizado o comando frama-c-gui

-wp -wp-rte -pp-annot -wp-model Typed+ref -wp-split <arquivo.c>. Esse comando

é o mesmo utilizado por Burghardt e Gerlach (2015, p. 121) para veri�car seus códigos C

especi�cados em ACSL. O signi�cado de cada parâmetro é listado a seguir:

• -wp: usar o plugin wp.

Page 106: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

104

• -wp-rte: usar o plugin RTE.

• -wp-model Typed+ref: usar o modelo Typed junto com Ref, sendo o segundo uma

otimização para os modelos de memória.

• <arquivo.c>: analisar o código presente em arquivo.c

A opção Ref ativa uma otimização no qual ponteiros são representados no modelo

Hoare em casos especí�cos. Por exemplo, dadas as seguintes funções:

void swap(int *a,int *b)

{

int tmp = *a ;

*a = *b ;

*b = tmp ;

}

void f(void)

{

int x=1,y=2 ;

swap(&x,&y);

}

como swap acessa e modi�ca *&x e *&y, isto é, ele lê e os valores de x e y sem ler nem

modi�car seus endereços diretamente, ambas as variáveis *a *b podem ser tratadas como

variáveis do tipo int.

Em cada uma das próximas seções são detalhadas as abordagens descritas no início

do capítulo, na ordem em que foram listadas.

6.1 Veri�cação de OPs não validadas por solucionado-

res SMT

Para o primeiro caso foram analisados códigos em C e selecionadas OPs que não foram

provadas diretamente pelos solucionadores SMT. Esses códigos foram obtidos a partir de

diferentes fontes, sendo elas:

• O sítio do Toccata - O Toccata é um grupo de pesquisa francês focado em estudo

e desenvolvimento em métodos formais1. Ele possui um conjunto composto por 20

exemplos de códigos C com anotações em ACSL veri�cados com o Jessie;

• Exemplos do WP - O WP possui um conjunto de códigos em C com anotações

ACSL no seu código-fonte, usado para testes automatizados do plugin;

1Disponível em:<http://toccata.lri.fr/gallery/jessieplugin.en.html>. Acesso em: 6 abr. 2016.

Page 107: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

105

• Exercícios de sala de aula - extraímos alguns códigos C com ACSL a partir de listas

de exercícios da disciplina de Especi�cação e Veri�cação de Programas na UFRN,

no segundo semestre de 2014.

Após a etapa da seleção dos arquivos para os testes, eles foram veri�cados com o WP

para remover os códigos que eram provados completamente de forma automática, isto

é, cujas OPs eram 100% validadas utilizando somente o Qed e solucionadores SMT. A

maioria dos arquivos se enquadrava nessa condição, sobrando poucos para análise.

Uma outra situação que ocorreu é com relação aos algoritmos do sítio do Toccata.

Como os algoritmos dessa fonte foram especi�cados para serem analisados com o Jessie,

algumas modi�cações tiveram de ser realizadas para que pudessem ser veri�cadas com

o WP. Um exemplo dessas especi�cações foi a adição da condição loop assigns para

determinar quais variáveis podem ter seus valores modi�cados dentro de um laço, pois

não há a exigência desse tipo de condição ACSL no Jessie. O loop assigns é descrito na

seção 2.1(p. 28).

Além do fato mencionado no parágrafo anterior, vários algoritmos do Toccata não

puderam ser analisados com WP. Esses algoritmos utilizam funções prede�nidas na espe-

ci�cação da linguagem ACSL que não foram implementadas no WP. Algumas delas são

as funções matemáticas como \pow, que calcula potenciação e \abs que calcula o valor

absoluto de um número. Outros elementos ACSL que também não são reconhecidos pelo

WP são construções que envolvem computações com números reais como, por exemplo, a

construção \exact, sendo seu propósito retornar o valor exato de uma variável C se esta

fosse computada como um número real (sem arredondamento) (BAUDIN et al., 2015c,

p. 24-25). Poderíamos tentar inserir anotações ACSL para especi�car essas construções,

porém, por julgar que essa tarefa tomaria possivelmente um tempo signi�cativo na análise

do WPTrans, decidimos não utilizar os algoritmos do Toccata que se enquadrassem nesse

problema.

A etapa seguinte constituiu-se de separar e veri�car as OPs geradas pela análise dos

códigos restantes. Nós tentamos utilizar o WPTrans para simpli�car essas OPs, porém,

encontramos duas situações que di�cultaram essa tarefa. A primeira é que vários dos

códigos se encontravam com uma especi�cação incompleta, gerando OPs incorretas ou

com hipóteses insu�cientes. Já a segunda é que a análise dos códigos restantes produziam

OPs muito complexas para as regras de inferência implementadas. Nessa etapa tinham

sido implementadas apenas as regras de inferência que foram obtidas do Rodin e do

Atelier-B.

Page 108: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

106

Durante a realização dessa etapa da análise experimental não tivemos sucesso nas

provas com as regras de inferência implementadas, sendo notado que a escolha arbitrária

das regras não eram su�cientes, assim como era necessário estudar e compreender mais a

complexidade das OPs analisadas. Nós consideramos essa etapa mais como uma metodo-

logia para o desenvolvimento da ferramenta do que uma análise experimental, aprendendo

a modi�car o código do WP e criando as primeiras interfaces para interação com o usuá-

rio. Mas registramos esses passos nesse capítulo pois, à medida que implementávamos a

extensão, realizávamos testes para medir sua e�ciência e utilidade. Antes de dar o pros-

seguimento na implementação de novas regras de inferência, mudamos a estratégia de

escolha de novas regras, iniciando uma segunda etapa de análises experimentais. A nova

etapa é descrita na próxima seção.

6.2 Comparação do WPTrans com Coq

Nesse mesmo período em que tentávamos a primeira abordagem, Burghardt e Gerlach

(2015) disponibilizaram publicamente as soluções para as OPs veri�cadas apenas com o

Coq2. Com isso, foi iniciada uma segunda abordagem, que consistiu em tentar veri�car

essas mesmas OPs com o WPTrans. Essa abordagem serviu para decidir quais regras de

inferência deviam ser adicionadas à extensão, assim como entender seus comportamentos

na OP. Além disso, foi considerada uma nova forma de análise do WPTrans: compará-lo

com o Coq na quantidade de comandos que precisavam ser aplicados para realizar a prova,

observando o impacto que os solucionadores SMT teriam para a sua validação.

No total, eram dez (10) OPs provadas apenas com Coq, e, até o momento presente,

quatro (4) dessas OPs foram provadas também com o WPTrans. Percebemos que foi

necessária uma quantidade consideravelmente menor de comandos para provar essas OPs

em relação ao Coq. Isso é ilustrado no exemplo a seguir.

`let x0 = L_Count(Mint0, a0, n0, v0) in

0 ≤ n0 → is_sint32(v0)→ (0 ≤ x0 ∧ x0 ≤ n0)

Figura 65: OP Lemma CountBounds

2Disponível em: <https://gitlab.fokus.fraunhofer.de>. Acesso em: 6 abr. 2016.

Page 109: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

107

lemma CountBounds: \forall value_type *a, v, integer n;

0 <= n ==> 0 <= Count(a, n, v) <= n;

Figura 66: Lemma CountBounds em ACSL

A Figura 65 exibe uma das OPs provadas tanto com Coq quanto com o WPTrans. O

nome da OP é Lemma CountBounds, seus modelos de memória e aritmético são, respecti-

vamente, Typed e inteiros naturais, sendo a OP produzida a partir do lema da �gura 66,

presente no algoritmo remove_copy, versão estável. A função Count determina que um

vetor a contém n posições com o valor presente em v. Desse modo, o lema expressa que a

contagem de posições que há o valor de v em a é entre 0 e n.

Burghardt e Gerlach (2015) não obtiveram sucesso com os solucionadores SMT Alt-

Ergo e CVC4, tendo que elaborar uma prova com o Coq. Foi utilizada uma sequência de

mais de quinze (15) comandos na prova, exibidos na Figura 67. Repetimos a tentativa de

prova com os solucionadores SMT, porém, também não obtivemos sucesso. Contudo, ao

utilizar o WPTrans, essa OP foi validada utilizando os comandos ordenados da Figura 68.

Proof.

intros v n M a. intros. subst x.

apply natlike_rec2 with (z := n); auto with zarith.

{ (* base step *) rewrite <- Q_CountEmpty; auto with zarith. }

{ (* induction step *) intros.

replace (Z.succ z) with (1 + z) by omega.

assert (M.[ shift a z] = v \/ M.[ shift a z] <> v) by tauto.

elim H3; intros.

{ rewrite Q_CountOneHit; auto with zarith. }

{ rewrite <- Q_CountOneMiss; auto with zarith. } }

Qed.

Figura 67: Prova de Lemma CountBounds com Coq

1. intros (introdução de objetivo)

2. int_ind n_0 (Indução sobre n_0)

3. call alt-ergo (Alt-Ergo é chamado para a conclusão da prova)

Figura 68: Prova de Lemma CountBounds com WPTrans

Com nossa extensão implementada, apenas dois comandos são necessários para chegar

a um estado no qual o provador SMT possa concluir a prova. A metodologia utilizada

com o WPTrans foi tentar executar as regras de inferência exatamente como no Coq, e,

a cada comando inserido, chamar um solucionador SMT para tentar concluir a prova. A

estratégia aplicada na prova OP da �gura 65 é a indução sobre a variável n0, veri�cando,

Page 110: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

108

primeiramente, se a OP é válida para o caso n0 = 0 e, em seguida, assumindo que a OP

seja válida para o caso n0 = x, sendo x um inteiro positivo qualquer, ela também seja

válida pra n0 = x+ 1. Dessa forma, para se chegar aos comandos aplicados na Figura 68,

executamos as tentativas de prova exibidas na Figura 69. Tanto as regras de inferência

intro e int_ind assim como o comando intros foram implementados justamente para

poder provar essa OP.

1. intros 1. intros 1. intros

2. call <solucionador SMT> 2. int_ind n_0

3. call <solucionador SMT>

Figura 69: Prova de Lemma CountBounds com WPTrans

`(0 ≤ m0)⇒ (m0 ≤ n0)⇒ (is_sint32(v2))

⇒ ((L_Count(Mint0, a0,m0, v0))⇒ (L_Count(Mint0, a0, n0, v0)))

Figura 70: OP Lemma RemoveCountMonotonic

Um segundo exemplo utilizado para a comparação é a prova da OP Lemma Remo-

veCountMonotonic, também gerado a partir do algoritmo remove_copy, cuja de�nição se

encontra na Figura 70. As provas de Lemma RemoveCountMonotonic OP com o Coq e

com o WPTrans se encontram, respectivamente, nas �guras 71 e 72.

Proof.

unfold L_RemoveCount in *. intros v m n M a. intros.

cut(m + (L_Count M a n v) <= n + (L_Count M a m v)).

{ omega .}

{ replace (n) with ((n-m) + m) by omega.

rewrite Q_CountUnion with (i := n-m); auto with zarith.

unfold shift_sint32.

cut (L_Count M (shift a m) (n - m) v <= n - m).

{ auto with zarith. }

apply Q_CountBounds; auto with zarith. }

Qed.

Figura 71: Prova de Lemma RemoveCountMonotonic com Coq

Page 111: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

109

1. intros

2. unfold_all L_RemoveCount

3. assert m_0 + L_Count(Mint_0,a_0,n_0,v_0) <= n_0 + L_Count(Mint_0,a_0,m_0,v_0)

4. assert \exists integer t; t + m_0 == n_0

5. existo n_0 - m_0

6. call alt-ergo

7. call alt-ergo

8. call alt-ergo

Figura 72: Prova de Lemma RemoveCountMonotonic com WPTrans

Ao tentar repetir a aplicação das regras de inferência do Coq no WPTrans, tivemos

uma di�culdade adicional devido à propriedade de reescrita automática dos termos no

WP. O comando replace (n) with ((n-m) + m) by omega não pôde ser igualmente

repetido no WPTrans, pois toda vez que n é substituído por (n - m) + m, o simpli�cador

do WP o substitui novamente para n. Nesse caso, a estratégia no WPTrans foi utilizar o

comando assert com uma quanti�cação existencial, a�rmando que ∃t·t+m = n. Inserida

essa hipótese, foi necessário apenas instanciar essa quanti�cação e, em seguida, concluir

automaticamente com o Alt-Ergo as OPs geradas. As regras de inferência assert e existo

foram implementadas para poder provar essa OP.

Na Tabela 1 é exibida uma comparação do número de comandos utilizados com o

Coq e com o WPTrans em 4 (quatro) OPs provadas com ambos. A con�guração para

gerar as OPs foi a mesma do exemplo anterior, sendo a contagem baseada na quanti-

dade de comandos aplicados na solução do documento supracitado. Foi considerado que

cada comando é uma transformação atômica da OP, sendo a aplicação repetida de in-

tros avaliada como um só comando. Os comandos aplicados após ponto e vírgula no Coq

são aplicados automaticamente em cada sub-OP gerada. Por exemplo, na sequência de

comandos apply natlike_rec2 with (z := n); auto with zarith, o comando auto

with zarith é aplicado automaticamente nas duas sub-OPs geradas pelo apply. Mesmo

que sejam aplicadas várias vezes, os comandos após a vírgula foram contados como se

fossem utilizados uma só vez. As regras de contagem foram arbitrárias, no intuito de se

padronizar a comparação entre o Coq e o WPTrans.

Não é possível tirar conclusões com os resultados mostrados na tabela e nos exemplos,

mas são indicativos de que é possível exigir um menor esforço do usuário para realizar as

provas não concluídas automaticamente através do WPTrans. O Apêndice B contém os

comandos utilizados para provar todas as OPs da Tabela 1.

Page 112: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

110

OP # ComandosCoq WPTrans

Lemma CountBounds 11 3Lemma CountUnion 19 3Lemma CountMonotonic 8 3Lemma RemoveCountMonotonic 12 8

Tabela 1: Comparação do número de comandos com Coq e WPTrans para prova de OPs

Antes de dar prosseguimento na comparação das OPs restantes decidimos tentar ve-

ri�car novas OPs que não foram solucionadas por Burghardt e Gerlach (2015). Para isso,

tentamos utilizar a combinação WPTrans e solucionador SMT em OPs que não foram

veri�cadas automaticamente, consolidando a efetividade da extensão junto ao Frama-C e

o WP. Essas veri�cações se encontram descritas na próxima seção.

6.3 Especi�cação e veri�cação de algoritmos do STL

C++ e do Toccata com o WPTrans

A terceira abordagem de veri�cação consistiu em veri�car OPs geradas a partir da

especi�cação de algoritmos em The C++ Resources Network (2000) assim como os algo-

ritmos do Toccata possíveis de serem analisadas pelo WP e cuja análise geravam OPs que

não podiam ser validadas automaticamente. Nós selecionamos os algoritmos que não se

enquadravam nas seguintes situações:

1. funções muito simples, que não percorriam vetores, como as funções max e min da

biblioteca STL;

2. funções já especi�cadas e completamente validadas em Burghardt e Gerlach (2015);

3. funções que tomam outras funções como argumento, como em �nd_if da STL.

A justi�cativa para não selecionar os algoritmos que se enquadravam no terceiro item

é que, de acordo com Baudin et al. (2015c), a única veri�cação que pode ser realizada com

parâmetros que sejam funções é comparar o parâmetro com alguma função já existente

no código, vide o exemplo da Figura 73.

int f(int x);

int g(int x);

//@ requires p == &f || p == &g;

void h(int(*p)(int)) {

...

}

Page 113: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

111

Figura 73: Exemplo de função com ponteiro para funções.Fonte: Adaptado de Baudin et al. (2015c, p. 26)

As funções presentes em The C++ Resources Network (2000) se encontram na lin-

guagem C++ utilizando iteradores e estruturas de�nidas apenas nessa linguagem (como

vector por exemplo). Para analisar essas funções, reescrevemo-as para a linguagem C

seguindo os mesmos padrões de Burghardt e Gerlach (2015). Essas modi�cações estão

descritas na apresentação de cada algoritmo modi�cado.

As funções que especi�camos e tentamos veri�car foram:

1. is_sorted (STL)

2. is_sorted_until (STL)

3. min_max_element (STL)

4. remove (STL)

5. unique (STL)

6. unique_copy (STL)

7. �nd_end (STL)

8. sum of values in array (Toccata)

9. operações com heap (STL)

(a) is_heap

(b) push_heap

(c) pop_heap

(d) make_heap

(e) sort_heap

(f) heap_sort

Dos algoritmos listados, is_sorted, is_sorted_until, min_max_element e remove fo-

ram totalmente validados pelos solucionadores SMT, não restando OPs que poderiam ser

veri�cadas com o WPTrans. Com relação aos algoritmos heap e unique_copy obtemos

suas especi�cações a partir de, respectivamente, Burghardt et al. (2012) e Burghardt et

al. (2013). Para os algoritmos restantes, especi�camos unique a partir de unique_copy

uma vez que ambos os algoritmos são muito parecidos, adaptamos a especi�cação de

sum of values in array do Toccata para ser utilizada com o WP e especi�camos manual-

mente o algoritmo �nd_end. Nós listamos no Apêndice E a especi�cação dos algoritmos

supracitados, exceto aqueles que já se encontravam delimitados na literatura.

Com relação às OPs geradas, nossa estratégia foi tentar primeiramente os lemas e,

em seguida, as OPs do tipo Annot. Essa decisão foi tomada pois as OPs geradas a partir

dos lemas não possuem hipóteses, sendo mais fácil elaborar uma estratégia de prova.

Nesse sentido, conseguimos provar quatro (4) OPs do tipo Lemma que não tinham sido

veri�cadas automaticamente.

Page 114: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

112

/*@

axiomatic Sum {

//sum(t,i,j) denotes t[i]+...+t[j-1]

logic integer sum{L}(int *t, integer i, integer j)

reads i,j,t, t[i..j-1] ;

axiom sum1{L}:\ forall int *t, integer i, j; i >= j ==> sum(t,i,j) == 0;

axiom sum2{L}:\ forall int *t, integer i, j;

i <= j ==> sum(t,i,j+1) == sum(t,i,j) + t[j]; } */

/*@ lemma sum3{L}:

\forall int *t, integer i, j, k;

i <= j <= k ==> sum(t,i,k) == sum(t,i,j) + sum(t,j,k); */

/*@ lemma sum_footprint{L}:

\forall int *t1 ,*t2, integer i, j;

(\ forall integer k; i<=k<j ==> t1[k] == t2[k]) ==>

sum(t1 ,i,j) == sum(t2,i,j); */

Figura 74: Axiomas e lemas de sum array

Duas das quatro OPs provadas com o uso do WPTrans foram originadas a partir dos

lemas do algoritmo sum of values in array, exibidos na Figura 74. As OPs se encontram

nas �guras 75 e 76. A função L_sum representa a função lógica sum descrita na anotação

ACSL,Mint0 é um vetor representando os números inteiros da memória e as variáveis das

OPs representam as respectivas variáveis da anotação ACSL (i0 representa i, t0 representa

t, etc.).

`(i0 ≤ j0)⇒ (j0 ≤ k0)⇒(L_sum(Mint0, t0, i0, k0) =

((L_sum(Mint0, t0, i0, j0) + (L_sum(Mint0, t0, j0, k0)))

Figura 75: OP Lemma sum3

`(∀i1 : int · (i1 < j0)⇒ (i0 ≤ i1)⇒(Mint0[shift_sint32(t10, i1)] = Mint0[shift_sint32(t20, i1)]))⇒(L_sum(Mint0, t10, i0, j0) = L_sum(Mint0, t20, i0, j0))

Figura 76: OP Lemma sum_footprint

Page 115: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

113

Para provar as OPs dos lemas sum3 e sum_footprint foram utilizados os comandos das

�guras 77 e 78. A regra de inferência case foi implementada com a intenção de resolver

essas duas OPs, servindo também para as demais OPs provadas e apresentadas nessa

seção. O comando call sem argumentos executa o Alt-Ergo para a conclusão da prova,

sendo um sinônimo para call Alt-Ergo.

1. intros

2. case j_0 > i_0

3. int_ind k_0 i_0 Caso j0 > i0

4. call Prova da primeira sub-OP da indução

5. call Prova da segunda sub-OP da indução

6. call Prova da terceira sub-OP da indução

7. call Prova do caso j0 ≤ i0

Figura 77: Prova da OP Lemma sum3 com WPTrans

1. case j_0 > i_0

2. intro Caso j0 > i0

3. int_ind j_0 i_0 indução sobre i0 em que i0 ≥ j0

4. call Prova da primeira sub-OP da indução

5. call Prova da segunda sub-OP da indução

6. call Prova da terceira sub-OP da indução

7. call Prova do caso j0 ≤ i0

Figura 78: Prova da OP Lemma sum_footprint com WPTrans

As duas outras OPs provadas foram originadas de lemas de�nidos na especi�cação

do algoritmo unique_copy, sendo elas exibidas na Figura 79. Os lemas veri�cados foram

unique_lemma_4 e unique_5, sendo suas OPs exibidas respectivamente nas �guras 80 e

81.

/*@

axiomatic WhitherUnique_Function{

logic integer WhitherUnique{L}( value_type * a, integer i)

reads a[0],a[i];

axiom unique_1: \forall value_type *a; WhitherUnique(a, 0) == 0;

axiom unique_2: \forall value_type *a, integer i;

a[i] == a[i+1] ==> WhitherUnique(a, i+1) == WhitherUnique(a, i);

axiom unique_3: \forall value_type *a, integer i;

a[i] != a[i+1] ==> WhitherUnique(a, i+1) == WhitherUnique(a, i) + 1;

lemma unique_lemma_4: \forall value_type *a, integer i, j;

Page 116: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

114

i < j && a[i] != a[i+1] ==> WhitherUnique(a, i) < WhitherUnique(a, j);

lemma unique_5: \forall value_type *a, integer i, j;

i < j ==> WhitherUnique(a, i) <= WhitherUnique(a, j);

}*/

Figura 79: Axiomas e lemas de unique_copy

`(i0 < j0)⇒(Mint0[shift_sint32(a0, i0)] 6= Mint0[shift_sint32(a0, (1 + i0))])⇒(L_WhiterUnique(Mint0, a0, i0) < L_WhitherUnique(Mint0, a0, j0))

Figura 80: OP Lemma unique_lemma_4

` (i0 < j0)⇒ (L_WhiterUnique(Mint0, a0, i0) ≤ L_WhitherUnique(Mint0, a0, j0))

Figura 81: OP Lemma unique_5

Para provar as OPs Lemma unique_lemma_4 e Lemma unique_5 foram utilizados

os comandos das �guras 82 e 83.

1. intros

2. case j_0 >= i_0

3. intros Prova do caso j0 ≥ i0

4. int_ind j_0 i_0

5. call Prova da primeira sub-OP da indução

6. call Prova da segunda sub-OP da indução

7. case Mint_0[(shift_sint32 a_0 i_0)]=caso a[i] = a[j]

Mint_0[(shift_sint32 a_0 = j_0)]

8. call Prova do caso a[i] = a[j]

9. call Prova do caso a[i] 6= a[j]

10. call Prova do caso j0 < i0

Figura 82: Prova da OP Lemma unique_lemma_4 com WPTrans

Page 117: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

115

1. intros

2. case j_0 > i_0

3. call Prova do caso j0 > i0

4. int_ind j_0 i_0 Prova do caso j0 ≤ i0

5. call Prova da primeira sub-OP da indução

6. call Prova da segunda sub-OP da indução

7. case Mint_0[(shift_sint32 a_0 i_0)]=caso a[i] = a[j]

Mint_0[(shift_sint32 a_0 = j_0)]

8. call Prova do caso a[i] = a[j]

9. call Prova do caso a[i] 6= a[j]

Figura 83: Prova da OP Lemma unique_5 com WPTrans

Após essas provas concluímos que os solucionadores SMT de fato auxiliaram na veri-

�cação das OPs do tipo Lemma após um direcionamento na estratégia de prova. Obser-

vamos que as regras de inferência case e int_ind auxiliam bastante para que os solucio-

nadores SMT possam encontrar, em tempo hábil, a solução da prova.

Uma vez provadas essas quatro (4) OPs, tentamos veri�car as OPs do tipo Annot.

Contudo, não conseguimos prová-las tanto devido às suas complexidades como também

não havia mais tempo hábil na pesquisa para mais testes, devendo serem documentados

os resultados alcançados até então. Na Figura 84 (117) se encontra um exemplo de OP do

tipo Annot gerado a partir da análise do algoritmo unique_copy, sendo uma das duas OPs

que veri�cam a condição loop invariant UniqueCopy(a, i, b, j); do algoritmo. As

demais OPs do tipo Annot encontradas tinham uma quantidade de hipóteses aproximada

a do exemplo da �gura supracitada.

Os resultados atingidos indicam que, apesar da veri�cação não ter sido bem-sucedida

para OPs do tipo Annot, há uma justi�cativa su�ciente para que o objeto desta pesquisa

continue em desenvolvimento, podendo ser adicionado futuramente ao WP para auxiliar

os usuários desse plugin e do Frama-C na veri�cação formal de sistemas em C.

6.4 Considerações sobre as Análises Experimentais

A primeira análise experimental serviu primariamente como uma metodologia para

o desenvolvimento inicial do WPTrans, determinando quais regras de inferência imple-

mentar. Esta etapa foi considerada uma análise experimental pois eram realizados testes

Page 118: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

116

à medida que o WPTrans era implementado. Esperávamos não ter um signi�cativo su-

cesso nesta etapa pois, somado à incompletude da versão inicial da extensão, estávamos

ainda aprendendo a complexidade das OPs geradas assim como determinando e estudando

estratégias possíveis para prová-las.

A segunda análise experimental foi uma forma mais e�ciente de se de�nir quais regras

de inferência implementar, pois nessa fase tínhamos exemplos concretos de quais regras

de inferência foram utilizadas com um assistente de prova (o Coq) para provar algumas

das OPs geradas. Copiando e adaptando estas regras, conseguimos ter sucesso na prova de

algumas das OPs com o WPTrans, inclusive permitindo uma comparação da quantidade

de comandos entre a extensão e o assistente de provas.

Já a terceira e última análise experimental foi imprescindível pois a �nalidade do

WPTrans é tentar provar novas OPs que ainda não tinham sido veri�cadas anteriormente,

seja por meio manual ou automático. Com esse �m, tentamos provar novas OPs que

não eram validadas automaticamente utilizando somente o WPTrans (com provadores

automáticos de teoremas), registrando os sucessos e di�culdades do uso da extensão.

No próximo capítulo, apresentaremos as considerações �nais e possibilidades de planos

futuros para o projeto discutido nesta pesquisa.

Page 119: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

117

When (is_uint32(i2) ∧ is_uint32(j1) ∧∧is_uint32(n0) ∧ is_uint32(1 + i2) ∧is_uint32(1 + j1) ∧ is_sint32(Mint4[shift_sint32(a1, i2)]) ∧is_sint32(Mint4[shift_sint32(a1, (i2 − 1))])))

Have (linked(Malloc0) ∧ (region(base, a1) ≤ 0 ∧ region(base, b1) ≤ 0))

Have (0 ≤ n0 ∧ n0 ≤ 2147483646)

Have (valid_rd(Malloc0, shift_sint32(a1, 0), (1 + n0)))

Have (valid_rw(Malloc0, shift_sint32(b1, 0), (1 + n0)))

Have (separated(shift_sint32(a1, 0), n0, shift_sint32(b1, 0), n0))

Have (0 < n0)

Have (valid_rw(Malloc0, shift_sint32(b1, 0), 1))

Have (valid_rd(Malloc0, shift_sint32(a1, 0), 1))

Have (havoc(Mint8[shift_sint32(b1, 0)⇒Mint8[shift_sint32(a1, 0)]],

Mint4, shift_sint32(b1, 1), n0 − 1))

Have (P_UniqueCopy(Mint4, a1, i2, b1, j1))

Have (0 < j1 ∧ i2 ≤ n0 ∧ j1 ≤ i2)

Have (i2 < n0)

Have (valid_rd(Malloc0, shift_sint32(a1, i2), 1))

Have (0 < i2)

Have (valid_rd(Malloc0(shift_sint32, a1, to_uint32(i2 − 1)), 1))

Have (Mint4[shift_sint32(a1, i2)] = Mint4[shift_sint32(a1, (i2 − 1))])

Have (j1 ≤ 4294967294)

Have (valid_rw(Malloc0(shiftsint32, b1, j1), 1))

Have (i2 ≤ 4294967294)

`P_UniqueCopy(

Mint4[shift_sint32(b1, j1)⇒Mint4[shift_sint32(a1, i2)]], a1, 1 + i2, b1, 1 + j1

)

Figura 84: OP do algoritmo unique_copy

Page 120: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

118

7 Considerações �nais

Apresentamos nesta dissertação a plataforma para a veri�cação estática de código

C, o Frama-C, expondo sua arquitetura e utilidade na análise de códigos na linguagem

C. Em seguida, descrevemos um dos plugins para veri�cação dedutiva da plataforma, o

WP, especi�cando seu funcionamento e estrutura. Logo depois abordamos as di�culdades

relacionadas ao uso desse plugin, o que leva à necessidade de integrar caraterísticas de

provadores automáticos e interativos de teoremas. Por último, propusemos uma solução

para as di�culdades mencionadas anteriormente, que se trata de uma extensão para o WP

denominada WPTrans. Em relação a esta extensão, apresentamos sua arquitetura, regras

de inferência implementadas, aspectos da implementação e teste realizados.

Sendo um intermediário entre o WP e provadores automáticos, o WPTrans possui

vinte e uma (21) regras de inferência que podem ser aplicadas nas OPs a �m de manipulá-

las. Além disso, o WPTrans também permite enviar as OPs, a qualquer momento da prova,

para solucionadores SMT (ou mesmo outros provadores de teoremas). Isso posto, o usuário

é desobrigado a manipular a OP até encontrar o resultado, exigindo menos experiência e

reduzindo o tempo necessário para concluir a prova.

Apresentamos o WPTrans em dois eventos ocorridos no ano de 2015. O primeiro

evento foi o Workshop Dimap 30 Anos, ocorrido no período entre 24 e 28 de Agosto de

2015 em Natal, Rio Grande do Norte, sendo o objetivo do Workshop realizar palestras

e apresentações de trabalhos cientí�cos de professores e estudantes do Departamento de

Informática e Matemática Aplicada (DIMAp), pertencente à UFRN (DIMAp, 2015). Nesse

Workshop apresentamos um artigo introduzindo a teoria por trás do WP e do WPTrans

assim como os objetivos de ambos os plugins (ALMEIDA, 2015).

O segundo evento foi a sessão de Workshops do Congresso Brasileiro de Software: Te-

oria e Prática, edição 2015, ocorrido no período entre 21 e 25 de setembro de 2015 em Belo

Horizonte, Minas Gerais. Nesse evento foram apresentados, com mais detalhes em relação

ao Workshop anterior, os problemas relacionados ao WP e o WPTrans (DÉHARBE; BO-

Page 121: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

119

NICHON; ALMEIDA, 2015). Também foram feitas demonstrações do uso da extensão,

no qual os participantes puderam interagir diretamente com o WPTrans.

Além das apresentações realizadas, pretendemos submeter o WPTrans a uma avalia-

ção para o jornal SoftwareX (ELSEVIER, 2016). Um dos principais objetivos desse jornal

é identi�car softwares cienti�camente relevantes analisando-os para determinar suas fun-

cionalidades, corretude, e escopo. Ademais, o software torna-se citável e seus desenvolve-

dores são reconhecidos pela implementação realizada. Nós temos a intenção de divulgar

o WPTrans no SoftwareX para torná-lo mais con�ável e útil no ambiente acadêmico e

industrial, assim como ter mais visibilidade por outros pro�ssionais e cientistas.

Apontamos ainda algumas possibilidades para trabalhos futuros:

• Introduzir novas regras de inferência - isso poderia ser realizado a partir da análise

de OPs geradas em novos projetos encontrados, identi�cando as que precisam ser

manipuladas antes de serem enviadas a um solucionador SMT;

• Extrair contraexemplo de prova - aplicável quando a prova é refutada por um soluci-

onador. As atuais alternativas de provadores no Frama-C não disponibilizam muitas

informações além do resultado, sendo esta uma forma de permitir uma maior comu-

nicação com os provadores;

Alguns solucionadores SMT possuem comandos para a obtenção de contraexemplos

de uma prova, a exemplo do Z3. Exceto para o Alt-Ergo, essas informações devem

ser capturadas pelo Why3 antes de serem enviadas ao WPTrans. Essa plataforma

não analisa a saída dos solucionadores, obtendo apenas o veredito das provas reali-

zadas (BOBOT et al., 2011). Apesar disso, há uma perspectiva de se implementar

a extração de provas do Why3. Sendo essa característica implementada, pode-se

realizar um estudo futuro para identi�car como extrair essa contraprova do Why3.

Por outro lado, o Alt-Ergo possui uma opção para extrair um modelo da prova no

caso em que esta seja refutada. Entretanto, até a versão pública 0.99.1, essa opção se

encontra em estado experimental. Com o possível amadurecimento dessa habilidade

nas próximas versões do Alt-Ergo, pode ser realizado um estudo sobre como extrair

esses modelos para o WP, através do WPTrans.

• Provar automaticamente as OPs restantes - essa opção consistiria em aplicar os so-

lucionadores nas OPs ainda não provadas em segundo plano, acelerando a realização

das provas;

Page 122: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

120

• Salvar o estado das OPs - essa é uma funcionalidade discutida no Capítulo 5 e que,

apesar de sua implementação não ter sido bem-sucedida, pode ser implementada em

um trabalho futuro;

• Dar suporte a novas sintaxes - prover facilidades para que desenvolvedores acoplem

novas impressoras (printers) das fórmulas. Com isso, as OPs poderiam ser exporta-

das para outros formatos desejados, como LaTeX e HTML;

• Dar suporte à criação de novas regras pelo usuário - prover um conjunto de funções

que permitam a inserção de novas regras de inferência por terceiros. Isso poderia ser

expandido para que o usuário pudesse combinar a aplicação de uma ou mais regras

de inferência, provendo mecanismos de automação e uso de estratégias de prova.

Uma atenção teria que ser dada a como validar a corretude dessas inserções.

• Criação de um manual do usuário e do desenvolvedor.

• Aprimoramento da interface grá�ca - isso poderia ser realizado a partir da distri-

buição gradual do WPTrans a outros desenvolvedores, recebendo opiniões sobre o

uso da extensão. Isso também poderia melhorar signi�cativamente a comunicação

entre o WPTrans e o usuário.

• Comparar o WPTrans com outras ferramentas que interligam provadores de teore-

mas com solucionadores SMT (ou outros provadores automáticos) - os parâmetros

de comparação poderiam ser: a capacidade de integração com o WP; se todas as

OPs geradas pelo WP poderão ser enviadas a essas ferramentas; e facilidade de uso

e aprendizagem.

Além dos planos futuros listados, acreditamos que o WPTrans pode contribuir na

implementação do WP. Por exemplo, detectamos e listamos dados e de�nições do WP

que precisamos e não se encontravam disponíveis publicamente. A API do WP poderia

ser modi�cada para que essas informações se tornassem públicas, permitindo inclusive a

implementação e inclusão de novas extensões ao plugin.

Na utilização do WPTrans, é importante veri�car suas provas, por meio da corretude

dos seguintes pontos:

• A de�nição das regras de inferência

• A implementação dessas regras no WPTrans

Page 123: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

121

• A prova gerada pelos solucionadores SMT

Déharbe, Bonichon e Almeida (2015) citam soluções para esses três pontos. Uma

forma de veri�car a corretude das de�nições é através do Coq. As regras de inferência do

WPTrans podem ser formalizadas traduzindo-as para esse assistente de provas, gerando

de�nições que asseguram a corretude da de�nição das regras.

Pensamos em validar o WPTrans através do gerador automático de código do Coq,

produzindo uma implementação correta a partir das de�nições provadas no parágrafo

anterior. Com relação ao terceiro item, alguns solucionadores SMT possuem geradores de

provas que retornam a sequência de comandos aplicados para encontrar o resultado. Essas

provas poderão ser analisadas com um veri�cador de provas, agregado ao WPTrans para

simplicidade e completude de seu uso.

Deixamos para um estudo futuro a implementação das soluções propostas para a

veri�cação do WPTrans, uma vez que pode ser necessário um tempo signi�cativo para a

sua conclusão. Outro estudo que também propomos é comparar o tempo e a complexidade

para a veri�cação de obrigações de prova entre o WPTrans e outros assistentes de prova

que podem ser executados pelo WP, a exemplo de Coq, Isabelle e PVS.

En�m, constatada a e�cácia do WPTrans, planejamos discutir com os desenvolvedores

do Frama-C e do WP a possibilidade de embutir integralmente essa extensão nas próximas

distribuições do programa e do plug-in com o intuito de agilizar a especi�cação formal,

bem como diminuir custos no desenvolvimento de sistemas em C.

Page 124: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

122

Referências

ABRIAL, J. The B-book - assigning programs to meanings. [S.l.]: Cambridge UniversityPress, 2005. ISBN 978-0-521-02175-3.

ABRIAL, J. et al. Rodin: An Open Toolset for Modelling and Reasoning in Event-B.STTT, v. 12, n. 6, p. 447�466, 2010.

ABRIAL, J.-R. Modeling in Event-B: System and Software Engineering. 1st. ed. NewYork, NY, USA: Cambridge University Press, 2010. ISBN 0521895561, 9780521895569.

AKBARPOUR, B.; PAULSON, L. C. Metitarski: An automatic theorem prover forreal-valued special functions. J. Autom. Reasoning, v. 44, n. 3, p. 175�205, 2010.Disponível em: <http://dx.doi.org/10.1007/s10817-009-9149-2>. Acesso em: 5 jan. 2016.

ALMEIDA, J. et al. An Overview of Formal Methods Tools and Techniques. In:Rigorous Software Development. [S.l.]: Springer London, 2011, (Undergraduate Topics inComputer Science). p. 15�44. ISBN 978-0-85729-017-5.

ALMEIDA, J. B. Rigorous Software Development - An Introduction to ProgramVeri�cation. In: . [S.l.]: Springer, 2011. (Undergraduate Topics in ComputerScience), cap. An Overview of Formal Methods Tools and Techniques. ISBN978-0-85729-017-5.

ALMEIDA, V. A. de. Assistente para Veri�cação de Programas em Frama-C. In:Workshop DIMAp 30 Anos. Natal, Brasil: [s.n.], 2015.

ARMAND, M. et al. A modular integration of SAT/SMT solvers to coq through proofwitnesses. In: JOUANNAUD, J.; SHAO, Z. (Ed.). Certi�ed Programs and Proofs - FirstInternational Conference, CPP 2011, Kenting, Taiwan, December 7-9, 2011. Proceedings.Springer, 2011. (Lecture Notes in Computer Science, v. 7086), p. 135�150. ISBN978-3-642-25378-2. Disponível em: <http://dx.doi.org/10.1007/978-3-642-25379-9_12>.Acesso em: 5 jan. 2016.

BARR, M. Programming embedded systems in C and C++ - thinking inside the box.[S.l.]: O'Reilly, 1999. ISBN 978-1-56592-354-6.

BARR, M.; MASSA, A. Programming Embedded Systems: With C and GNU DevelopmentTools. [S.l.]: O'Reilly Media, Inc., 2006. ISBN 0596009836.

BARRETT, C. et al. CVC4. In: Proceedings of the 23rd International Conference onComputer Aided Veri�cation. Berlin, Heidelberg: Springer-Verlag, 2011. (CAV'11), p.171�177. ISBN 978-3-642-22109-5. Disponível em: <http://dl.acm.org/citation.cfm?id=2032305.2032319>. Acesso em: 5 abr. 2015.

BARRETT, C.; FONTAINE, P.; TINELLI, C. The SMT-LIB Standard: Version 2.5.[S.l.], 2015. Disponível em: <http://www.SMT-LIB.org>. Acesso em: 6 mar. 2015.

Page 125: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

123

BAUDIN, P. et al. WP Plug-in Manual. [S.l.], 2015. Disponível em: <http://frama-c.com/download/wp-manual-Sodium-20150201.pdf>. Acesso em: 3 abr. 2015.

BAUDIN, P. et al. WP Plug-in Manual. [S.l.], 2015. Disponível em: <http://frama-c.com/download/wp-manual-Magnesium-20151002.pdf>. Acesso em: 2 mar.2016.

BAUDIN, P. et al. ACSL: ANSI C Speci�cation Language - Version 1.10 -Magnesium-20151002. [S.l.], 2015. Disponível em: <http://frama-c.com/download/acsl-implementation-Magnesium-20151002.pdf>. Acesso em: 15 nov. 2015.

BAUDIN, P. et al. ACSL: ANSI C Speci�cation Language - Version 1.9 -Sodium-20150201. [S.l.], 2015. Disponível em: <http://frama-c.com/download/acsl-implementation-Sodium-20150201.pdf>. Acesso em: 12 ago. 2015.

BECKERT, B.; HÄHNLE, R.; SCHMITT, P. H. Veri�cation of Object-oriented Software:The KeY Approach. Berlin, Heidelberg: Springer-Verlag, 2007. ISBN 3-540-68977-X,978-3-540-68977-5.

BERTHOMÉ, P. et al. Attack model for veri�cation of interval security properties forsmart card C codes. In: BANERJEE, A.; GARG, D. (Ed.). Proceedings of the 2010Workshop on Programming Languages and Analysis for Security, PLAS 2010, Toronto,ON, Canada, 10 June, 2010. ACM, 2010. p. 2. ISBN 978-1-60558-827-8. Disponível em:<http://doi.acm.org/10.1145/1814217.1814219>. Acesso em: 5 jul. 2015.

BERTOT, Y.; CASTÉRAN, P. Interactive Theorem Proving and Program Development -Coq'Art: The Calculus of Inductive Constructions. Springer, 2004. (Texts in TheoreticalComputer Science. An EATCS Series). ISBN 978-3-642-05880-6. Disponível em:<http://dx.doi.org/10.1007/978-3-662-07964-5>. Acesso em: 5 jun. 2015.

BLANCHETTE, J. C.; BULWAHN, L.; NIPKOW, T. Automatic proof and disproofin isabelle/hol. In: TINELLI, C.; SOFRONIE-STOKKERMANS, V. (Ed.). Frontiersof Combining Systems, 8th International Symposium, FroCoS 2011, Saarbrücken,Germany, October 5-7, 2011. Proceedings. Springer, 2011. (Lecture Notes inComputer Science, v. 6989), p. 12�27. ISBN 978-3-642-24363-9. Disponível em:<http://dx.doi.org/10.1007/978-3-642-24364-6_2>. Acesso em: 5 jan. 2016.

BLANCHETTE, J. C.; NIPKOW, T. Nitpick: A counterexample generator forhigher-order logic based on a relational model �nder. In: KAUFMANN, M.; PAULSON,L. C. (Ed.). Interactive Theorem Proving, First International Conference, ITP 2010,Edinburgh, UK, July 11-14, 2010. Proceedings. Springer, 2010. (Lecture Notes inComputer Science, v. 6172), p. 131�146. ISBN 978-3-642-14051-8. Disponível em:<http://dx.doi.org/10.1007/978-3-642-14052-5_11>.

BOBOT, F. et al. Why3: Shepherd your herd of provers. In: In Workshop on IntermediateVeri cation Languages. [S.l.: s.n.], 2011.

BOTELLA, B. et al. Automating structural testing of C programs: Experience withpathcrawler. In: DRANIDIS, D.; MASTICOLA, S. P.; STROOPER, P. A. (Ed.).Proceedings of the 4th International Workshop on Automation of Software Test,AST 2009, Vancouver, BC, Canada, May 18-19, 2009. IEEE, 2009. p. 70�78. ISBN

Page 126: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

124

978-1-4244-3711-5. Disponível em: <http://dx.doi.org/10.1109/IWAST.2009.5069043>.Acesso em: 15 jan. 2015.

BOUTON, T. et al. veriT: an open, trustable and e�cient SMT-solver. 2009.

BURGHARDT, J. et al. ACSL By Example: Towards a Veri�ed C Standard Library.Version 7.1.1 for Frama-C Nitrogen. [S.l.]: Fraunhofer FOKUS, 2012.

BURGHARDT, J. et al. ACSL By Example: Towards a Veri�ed C Standard Library.Version 9.3.0 for Frama-C Fluorine. [S.l.]: Fraunhofer FOKUS, 2013.

BURGHARDT, J.; GERLACH, J. ACSL By Example: Towards a Veri�ed C StandardLibrary. Version 11.1.0 for Frama-C (Sodium). [S.l.]: Fraunhofer FOKUS, 2015.

CLEARSY. Atelier B Interactive Prover Reference Manual. Aix-en-Provence, França,2008. Disponível em: <http://tools.clearsy.com/wp-content/uploads/sites/8/resources/MREFPRI.pdf>. Acesso em: 5 jun. 2015.

COK, D. R.; KINIRY, J. ESC/Java2: Uniting ESC/Java and JML. In: BARTHE, G. etal. (Ed.). Construction and Analysis of Safe, Secure, and Interoperable Smart Devices,International Workshop, CASSIS 2004, Marseille, France, March 10-14, 2004, RevisedSelected Papers. [S.l.]: Springer, 2004. (Lecture Notes in Computer Science, v. 3362), p.108�128. ISBN 3-540-24287-2.

CONCHON, S. SMT Techniques and their Applications: from Alt-Ergo to Cubicle.Tese (Thèse d'habilitation) � Université Paris-Sud, dez. 2012. In English,<http://www.lri.fr/~conchon/publis/conchonHDR.pdf>. Disponível em: <http://www.lri.fr/~conchon/bib/conchon.html>. Acesso em: 9 jan. 2016.

CONCHON, S.; IGUERNELALA, M. Tuning the Alt-Ergo SMT Solver for B ProofObligations. In: AMEUR, Y. A.; SCHEWE, K. (Ed.). Abstract State Machines, Alloy,B, TLA, VDM, and Z - 4th International Conference, ABZ 2014, Toulouse, France,June 2-6, 2014. Proceedings. [S.l.]: Springer, 2014. (Lecture Notes in Computer Science,v. 8477), p. 294�297. ISBN 978-3-662-43651-6.

CORRENSON, L. Qed. computing what remains to be proved. In: BADGER, J. M.;ROZIER, K. Y. (Ed.). NASA Formal Methods - 6th International Symposium, NFM2014, Houston, TX, USA, April 29 - May 1, 2014. Proceedings. Springer, 2014. (LectureNotes in Computer Science, v. 8430), p. 215�229. ISBN 978-3-319-06199-3. Disponívelem: <http://dx.doi.org/10.1007/978-3-319-06200-6_17>. Acesso em: 6 dec. 2015.

CORRENSON, L. et al. Frama-C User Manual. Release Magnesium-20151002. [S.l.], 2015.Disponível em: <http://frama-c.com/download/user-manual-Magnesium-20151002.pdf>. Acesso em: 2 mar. 2016.

CUOQ, P. et al. Frama-C: A Software Analysis Perspective. In: Proceedings of the10th International Conference on Software Engineering and Formal Methods. Berlin,Heidelberg: Springer-Verlag, 2012. (SEFM'12), p. 233�247. ISBN 978-3-642-33825-0.

CUOQ, P.; YAKOBOWSKI, B.; PREVOSTO, V. Frama-C's value analysis plug-in. [S.l.],2015. Disponível em: <http://frama-c.com/download/frama-c-value-analysis.pdf>.Acesso em: 12 ago. 2015.

Page 127: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

125

DÉHARBE, D. SMT-SAVeS: Veri�cação automática de software por resolução móduloteorias. 2016. Disponível em: <https://sigaa.ufrn.br/sigaa/public/programa/pesquisa.jsf?lc=pt\_BR&id=73>. Acesso em: 18 jan. 2016.

DÉHARBE, D.; BONICHON, R.; ALMEIDA, V. A. de. WPTrans: Um assistente paraVeri�cação de Programas no Frama-C. In: Congresso Brasileiro de Software: Teoriae Prática - Sessão de Ferramentas. Belo Horizonte, Brasil: [s.n.], 2015. p. 105�112.Disponível em: <http://cbsoft.org/articles/0000/0529/Ferramentas.pdf>.

DENMAN, W.; MUÑOZ, C. A. Automated real proving in PVS via metitarski. In:JONES, C. B.; PIHLAJASAARI, P.; SUN, J. (Ed.). FM 2014: Formal Methods - 19thInternational Symposium, Singapore, May 12-16, 2014. Proceedings. Springer, 2014.(Lecture Notes in Computer Science, v. 8442), p. 194�199. ISBN 978-3-319-06409-3.Disponível em: <http://dx.doi.org/10.1007/978-3-319-06410-9_14>.

DIJKSTRA, E. A constructive approach to the problem of program correctness. BITNumerical Mathematics, Kluwer Academic Publishers, v. 8, n. 3, p. 174�186, 1968. ISSN0006-3835.

DIMAp. Workshop DIMAp 30 Anos. 2015. Disponível em: <http://www.dimap.ufrn.br/dimap30anos/>. Acesso em: 18 jan. 2016.

ELSEVIER. SoftwareX. 2016. Disponível em: <http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html>. Acesso em: 12 mar. 2016.

Event-B and Rodin Documentation Wiki. Inference Rules. 2015. Disponível em:<http://wiki.event-b.org/index.php/Inference_Rules>. Acesso em: 6 abr. 2016.

FILLIÂTRE, J.; MARCHÉ, C. The Why/Krakatoa/Caduceus Platform for DeductiveProgram Veri�cation. In: DAMM, W.; HERMANNS, H. (Ed.). Computer AidedVeri�cation, 19th International Conference, CAV 2007, Berlin, Germany, July 3-7,2007, Proceedings. [S.l.]: Springer, 2007. (Lecture Notes in Computer Science, v. 4590),p. 173�177. ISBN 978-3-540-73367-6. Acesso em: 13 ago. 2015.

FILLIÂTRE, J.; PASKEVICH, A. Why3 - Where Programs Meet Provers. In:FELLEISEN, M.; GARDNER, P. (Ed.). Programming Languages and Systems - 22ndEuropean Symposium on Programming, ESOP 2013, Held as Part of the European JointConferences on Theory and Practice of Software, ETAPS 2013, Rome, Italy, March16-24, 2013. Proceedings. [S.l.]: Springer, 2013. (Lecture Notes in Computer Science,v. 7792), p. 125�128. ISBN 978-3-642-37035-9.

FITZGERALD, J. S.; LARSEN, P. G.; VERHOEF, M. Vienna Development Method. In:WAH, B. W. (Ed.).Wiley Encyclopedia of Computer Science and Engineering. John Wiley& Sons, Inc., 2008. Disponível em: <http://dx.doi.org/10.1002/9780470050118.ecse447>.Acesso em: 30 ago. 2015.

FLOYD, R. W. Assigning Meanings to Programs. Proceedings of Symposium on AppliedMathematics, v. 19, p. 19�32, 1967. Disponível em: <http://laser.cs.umass.edu/courses/cs521-621.Spr06/papers/Floyd.pdf>. Acesso em: 14 abr. 2015.

FRAMA-C. Impact analysis plug-in. 2015. Disponível em: <http://frama-c.com/impact.html>. Acesso em: 3 mar. 2016.

Page 128: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

126

GAMMA, E. et al. Design Patterns: Elements of Reusable Object-oriented Software.Boston, MA, USA: Addison-Wesley Longman Publishing Co., Inc., 1995. ISBN0-201-63361-2.

GEUVERS, H. Proof assistants: History, ideas and future. Sadhana, Springer-Verlag,v. 34, n. 1, p. 3�25, 2009. ISSN 0256-2499.

HERRMANN, P.; SIGNOLES, J. Frama-C's annotation generator plug-in. [S.l.], 2015.Disponível em: <http://frama-c.com/download/frama-c-rte-manual.pdf>. Acesso em:11 ago. 2015.

HOARE, C. A. R. An Axiomatic Basis for Computer Programming. Commun. ACM,ACM, New York, NY, USA, v. 12, n. 10, p. 576�580, out. 1969. ISSN 0001-0782.Disponível em: <http://doi.acm.org/10.1145/363235.363259>. Acesso em: 14 abr. 2015.

HODER, K.; VORONKOV, A. Comparing Uni�cation Algorithms in First-orderTheorem Proving. In: Proceedings of the 32Nd Annual German Conference onAdvances in Arti�cial Intelligence. Berlin, Heidelberg: Springer-Verlag, 2009.(KI'09), p. 435�443. ISBN 3-642-04616-9, 978-3-642-04616-2. Disponível em:<http://dl.acm.org/citation.cfm?id=1814110.1814175>. Acesso em: 13 set. 2015.

LEAVENS, G. T. et al. JML Reference Manual . 2013. Disponível em: <http://www.eecs.ucf.edu/~leavens/JML//refman/jmlrefman.pdf>. Acesso em: 21 set. 2015.

MENTRÉ, D. et al. Discharging Proof Obligations from Atelier-B Using MultipleAutomated Provers. In: Abstract State Machines, Alloy, B, VDM, and Z - ThirdInternational Conference, ABZ 2012, Pisa, Italy, June 18-21, 2012. Proceedings. [S.l.:s.n.], 2012. p. 238�251.

MOSKEWICZ, M. W. et al. Cha�: Engineering an E�cient SAT Solver. In: Proceedingsof the 38th Design Automation Conference, DAC 2001, Las Vegas, NV, USA,June 18-22, 2001. ACM, 2001. p. 530�535. ISBN 1-58113-297-2. Disponível em:<http://doi.acm.org/10.1145/378239.379017>. Acesso em: 21 ago. 2015.

MOURA, L. M. de; BJØRNER, N. Z3: An E�cient SMT Solver. In: RAMAKRISHNAN,C. R.; REHOF, J. (Ed.). Tools and Algorithms for the Construction and Analysisof Systems, 14th International Conference, TACAS 2008, Held as Part of the JointEuropean Conferences on Theory and Practice of Software, ETAPS 2008, Budapest,Hungary, March 29-April 6, 2008. Proceedings. [S.l.]: Springer, 2008. (Lecture Notes inComputer Science, v. 4963), p. 337�340. ISBN 978-3-540-78799-0.

NECULA, G. C. et al. CIL: Intermediate Language and Tools for Analysis andTransformation of C Programs. In: Proceedings of the 11th International Conferenceon Compiler Construction. London, UK, UK: Springer-Verlag, 2002. (CC '02), p.213�228. ISBN 3-540-43369-4. Disponível em: <http://dl.acm.org/citation.cfm?id=647478.727796>. Acesso em: 12 ago. 2015.

NIPKOW, T.; PAULSON, L. C.; WENZEL, M. Isabelle/HOL - A Proof Assistant forHigher-Order Logic. [S.l.]: Springer, 2002. v. 2283. (Lecture Notes in Computer Science,v. 2283). ISBN 3-540-43376-7.

OWRE, S. et al. PVS System Guide. Menlo Park, CA, 2001.

Page 129: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

127

PAULIN-MOHRING, C. Introduction to the Coq Proof-Assistant for Practical SoftwareVeri�cation. In: MEYER, B.; NORDIO, M. (Ed.). Tools for Practical SoftwareVeri�cation. [S.l.]: Springer Berlin Heidelberg, 2012, (Lecture Notes in Computer Science,v. 7682). p. 45�95. ISBN 978-3-642-35745-9.

PAULSON, L. C. Three Years of Experience with Sledgehammer, a PracticalLink between Automatic and Interactive Theorem Provers. In: SCHMIDT,R. A.; SCHULZ, S.; KONEV, B. (Ed.). Proceedings of the 2nd Workshop onPractical Aspects of Automated Reasoning, PAAR-2010, Edinburgh, Scotland, UK,July 14, 2010. EasyChair, 2010. (EPiC Series, v. 9), p. 1�10. Disponível em:<http://www.easychair.org/publications/?page=560965337>. Acesso em: 3 abr. 2015.

PIERCE, B. C. et al. Software Foundations. Electronic textbook, 2015. Disponível em:<http://www.cis.upenn.edu/~bcpierce/sf>. Acesso em: 10 jan. 2016.

PREVOSTO, V. et al. Formal speci�cation and automated veri�cation of railway softwarewith Frama-C. In: 11th IEEE International Conference on Industrial Informatics,INDIN 2013, Bochum, Germany, July 29-31, 2013. IEEE, 2013. p. 710�715. ISBN978-1-4799-0752-6. Disponível em: <http://dx.doi.org/10.1109/INDIN.2013.6622971>.Acesso em: 19 mai. 2015.

PUCCETTI, A. Static Analysis of the XEN Kernel using Frama-C. J. UCS, v. 16, n. 4,p. 543�553, 2010. Disponível em: <http://dx.doi.org/10.3217/jucs-016-04-0543>. Acessoem: 16 mai. 2015.

ROBINSON, J. A. A machine-oriented logic based on the resolution principle. J. ACM,v. 12, n. 1, p. 23�41, 1965. Disponível em: <http://doi.acm.org/10.1145/321250.321253>.

SIGNOLES, J. et al. Plug-in Development Guide. Release Magnesium-20151002. [S.l.], 2015. Disponível em: <http://frama-c.com/download/plugin-development-guide-Magnesium-20151002.pdf>. Acesso em: 2 mar. 2016.

SMT-LIB. SMT-LIB Logics. 2016. Disponível em: <http://smtlib.cs.uiowa.edu/logics.shtml>. Acesso em: 13 fev. 2016.

SOMMERVILLE, I. Software Engineering. 9. ed. Harlow, England: Addison-Wesley,2010. ISBN 978-0-13-703515-1.

SPIVEY, J. M. The Z notation - a reference manual. [S.l.]: Prentice Hall, 1989. (PrenticeHall International Series in Computer Science). ISBN 978-0-13-983768-5.

SUTCLIFFE, G. The TPTP Problem Library and Associated Infrastructure: The FOFand CNF Parts, v3.5.0. Journal of Automated Reasoning, v. 43, n. 4, p. 337�362, 2009.

The C++ Resources Network. Library algorithm. 2000. Disponível em: <http://www.cplusplus.com/reference/algorithm/>. Acesso em: 28 jan. 2016.

The Coq development team. The Coq proof assistant reference manual. [S.l.], 2015.Version 8.4p16. Disponível em: <http://coq.inria.fr>. Acesso em: 15 abr. 2015.

TIOBE. TIOBE Index for December 2015. 2015. Disponível em: <http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html>. Acesso em: 15 nov. 2015.

Page 130: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

128

APÊNDICE A -- Outras regras de inferência

implementadas no WPTrans

Neste apêndice se encontram descritas as demais regras de inferência implementadas

no WPTrans que não foram listadas no Capítulo 4. Essas regras de inferência não foram

aplicadas em nenhuma prova que tenha sido validada pelo WPTrans, porém foram im-

plementadas para enriquecer a possibilidade de modi�cações nas OPs. Para cada regra

de inferência é apresentada a sua de�nição formal, um exemplo de uso, o comando para

aplicar a regra no WPTrans e a fonte em que nos baseamos para implementá-la.

A.1 Remover hipóteses - weakening

O propósito dessa regra é remover hipóteses de uma OP. Ela é baseada na tática clear

presente no Coq (The Coq development team, 2015, p. 184). No entanto, há uma diferença

importante entre as duas regras: clear pode ser usada para remover tanto hipóteses quanto

de�nições inseridas no escopo da OP, enquanto weakening remove apenas hipóteses, sendo

a regra formalizada na Figura 85.

H ` OH,R1 · · ·Rn ` O

Figura 85: De�nição de weakening

A estrutura dessa regra é

weakening <H1> <H2> · · · <Hn>

em que <H1>, · · · , <Hn> são os índices das hipóteses. A Figura 86 introduz um exemplo

de weakening. Após aplicação da regra, é gerada uma nova OP sem as duas hipóteses no

consequente.

Page 131: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

129

` let x0 = Mint0[b0] in x0 = Mint0[a0 7→ x0][b0 7→Mint0[a0]][a0] weakening1 2let x0 = Mint0[a0] in

let x1 = Mint0[b0] in

is_sint32(x0) ∧ is_sint32(x1) ∧ is_sint32(Mint0[a0 7→ x1][b0 7→ x0][a0]).

linked(Malloc0) ∧ region(base(a0)) ≤ 0 ∧ region(base(b0)) ≤ 0

`let x0 = Mint0[b0] in x0 = Mint0[a0 7→ x0][b0 7→Mint0[a0]][a0]

Figura 86: Exemplo da regra weakening

A.2 Introdução da implicação - to_goal

Sendo seu argumento o índice de uma hipótese, essa regra remove a hipótese selecio-

nada da OP, sendo seu termo inserido no objetivo através de uma implicação. A condição

lateral na Figura 87 determina que, quando a regra é aplicada a uma condição, seus ter-

mos são extraídos e inseridos no objetivo da OP. Caso contrário, isto é, se a OP for do

tipo Lemma, então R = G, de acordo com a de�nição de pstep.

H ` G⇒ O

H,R ` OG = pstep(R)

Figura 87: De�nição de to_goal

Essa regra é baseada na tática revert do Coq (The Coq development team, 2015, p.

185), porém, com uma diferença: revert pode generalizar uma instanciação, não sendo o

mesmo possível com to_goal. O comando para utilizar a regra é:

to_goal <H>

em que <H> é o índice da hipótese que deverá ser enviada ao objetivo da OP. A Figura

88 mostra um exemplo dessa regra, sendo a primeira hipótese movida para o objetivo

após sua aplicação.

` 0 < x⇒ 0 ≤ xto_goal 1

0 < x ` 0 ≤ x

Figura 88: Exemplo de to_goal

Page 132: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

130

A.3 Dividir conjunções no objetivo - split

Se o objetivo da OP selecionada for uma conjunção de termos, essa tática gera novas

OPs, sendo o objetivo de cada um dos termos distintos da conjunção original. Essa regra

é baseada na tática split do Coq (The Coq development team, 2015, p. 179), sendo sua

representação formal mostrada na Figura 89.

H ` O1 · · ·H ` On

H `∧

i∈{1..n}Oi

Figura 89: De�nição de split

.

O comando para utilizar esse regra é mostrado a seguir, sem argumentos:

split

Caso o objetvo não seja uma conjunção, nenhuma ação é realizada. Um exemplo da

aplicação de split se encontra na Figura 90, na qual foram geradas três OPs, uma para

cada termo da conjunção.

0 < a

0 < b

0 < c

`0 ≤ a

0 < a

0 < b

0 < c

`0 ≤ b

0 < a

0 < b

0 < c

`0 ≤ c

0 < a

0 < b

0 < c

`≤ a ∧ 0 ≤ b ∧ 0 ≤ c

split

Figura 90: Exemplo da regra split

A.4 Eliminar conjunção em hipótese - splith

Se a OP possui uma hipótese constituída por uma conjunção de termos, estas podem

ser divididas em n hipóteses, sendo, cada uma, um dos operandos da conjunção original.

Page 133: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

131

A remoção de conjunção em hipótese foi baseada na regra AND_L descrita em Abrial

(2010, p. 67), sendo sua descrição formal exposta na Figura 91.

H,newhyp(P1), · · · , newhyp(Pn) ` OH, T ` O

pstep(T ) =∧

i∈{1..n} Pn

Figura 91: De�nição de splith

O comando para utilizar a regra é:

split <H>

no qual <H> é o índice da hipótese que terá as conjunções removidas. Caso a hipótese

selecionada não seja uma conjunção, nenhuma ação é realizada.

A Figura 92 demonstra uma aplicação de splith no qual a conjunção da primeira

hipótese foi removida, sendo substituída por duas novas hipóteses com seus termos.

b < a, c < b ` c < a

Hb < a ∧ c < b ` c < asplit 1

Figura 92: Exemplo da regra splith

A.5 Eliminar disjunção em hipótese - splitdh

Se a OP possui uma hipótese R composta por uma disjunção de n termos, essa regra

cria n OPs, sendo a fórmula em R substituída por um dos n termos, conforme Figura

93. A remoção de disjunção em hipótese foi baseada na regra OR_L descrita em Abrial

(2010, p. 46).

H,newhyp(P1) ` O · · ·H,newhyp(Pn) ` OH, T ` O

pstep(T ) =∨

i∈{1..n} Pn

Figura 93: De�nição de splitdh

O comando para utilizar a regra é:

splitdh <H>

Page 134: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

132

no qual <H> é o índice da hipótese que terá a disjunção eliminada. Caso a hipótese

selecionada não seja uma disjunção, nenhuma ação é realizada. Um exemplo dessa regra

é exibido na Figura 94, no qual são criadas duas novas OPs, cada uma contendo um dos

termos da disjunção na terceira hipótese.

0 < c, 0 < b, a = b ` 0 < a 0 < c, 0 < b, a = c,` 0 < a

0 < c, 0 < b, a = b ∨ a = c ` 0 < asplitdh 3

Figura 94: Exemplo da regra splitdh

A.6 Eliminar disjunção no objetivo - splitdo

Se a OP possui um objetivo R composto por uma disjunção de n termos, um desses

operandos pode ser removido pelo usuário, gerando uma nova OP sem o termo selecionado,

conforme a de�nição na Figura 95. A regra possui um (1) argumento, sendo este um

número inteiro indicando qual dos termos deve ser removido. Realizando a seleção da

esquerda para a direita, o índice 1 (um) seleciona o primeiro termo, 2 (dois) o segundo

termo e assim sucessivamente. A remoção da disjunção no objetivo foi baseada nas regras

OR_R1 e OR_R2, de�nidas em Abrial (2010, p. 46).

H ` Pi

H `∨n

i=1 Pi ∈ {1 · · ·n}

Figura 95: De�nição de splitdo

O comando para utilizar essa regra é:

splitdo <inteiro>

no qual <inteiro> é um número inteiro indicando o termo escolhido para a eliminação,

sendo a seleção do termo descrita no primeiro parágrafo dessa seção. Caso o objetivo não

seja uma disjunção, nenhuma ação é realizada. Essa regra é demonstrada na Figura 96: o

segundo termo da disjunção na OP original é removida após a aplicação de splitdo.

` 0 < a ∨ a = 0

` 0 < a ∨ a < 0 ∨ a = 0splitdo 2

Figura 96: Exemplo da regra splitdo

Page 135: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

133

A.7 Contradição - contradict

Essa regra aplica contradição lógica na OP, realizando duas modi�cações; A primeira

é a adição de uma nova hipótese, sendo esta a negação do objetivo da OP original.

Já a segunda é a substituição do objetivo original por false, conforme a Figura 97.

A contradição é baseada na regra CONTRADICT_R do Rodin (Event-B and Rodin

Documentation Wiki, 2015).

H,newhyp(¬O) ` ⊥H ` O

Figura 97: De�nição de contradict

O comando para utilizar a contradição é:

contradict

sem nenhum argumento. A Figura 98 exibe um exemplo da contradição aplicada: a negação

de 0 < a é enviada ao conjunto de hipóteses, sendo false o novo objetivo.

0 < b, b < a, a ≤ 0 ` false0 < b, b < a ` 0 < a

contradict

Figura 98: Exemplo da regra contradict

A.8 Contraposição - contrapose

Essa regra aplica a lei de contraposição em uma hipótese selecionada pelo usuário,

sendo realizadas duas ações. A primeira se constitui em adicionar uma nova hipótese

cujo conteúdo é a negação do objetivo. Já a segunda é a remoção da hipótese selecionada,

substituindo o objetivo pela negação dos termos dessa hipótese. A contraposição é baseada

na regra CONTRADICT_L do Rodin (Event-B and Rodin Documentation Wiki, 2015).

H,newhyp(¬O) ` (¬pstep(R))

H,R ` O

Figura 99: De�nição de contrapose

O comando para utilizar a contraposição é:

Page 136: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

134

contrapose <H>

no qual <H> é o índice da hipótese escolhida para a contraposição. É exibido na Figura

100 um exemplo dessa regra: a negação da segunda hipótese é enviada ao objetivo, sendo

a negação do objetivo original enviada simultaneamente ao conjunto de hipóteses da nova

OP.

0 < b, a ≤ 0 ` a ≤ b

0 < b, b < a ` 0 < acontrapose 2

Figura 100: Exemplo da regra contrapose

A.9 Reescrever hipótese - restructure

Essa regra é aplicada apenas em OPs do tipo Annot, recebendo como argumento o

índice de uma hipótese. Se a hipótese selecionada tiver uma das estruturas a seguir:

• If T Then(A1, · · · , An) Else(B1, · · · , Bn)

• Either (H1, · · · , Hn)

então a hipótese é reescrita para o formato Have B, com mesma equivalência semântica.

O objetivo de restructure é simpli�car a hipótese para ser utilizável por outras regras,

como, por exemplo, divisão de conjunção. Caso a hipótese não possua um dos formatos

anteriores, a OP não é modi�cada. Essa regra não foi baseada em nenhuma ferramenta

externa, porém foi inserida para que permitisse a aplicação de outras regras de inferência

nas hipóteses. Suas de�nições formais se encontram nas �guras 101 e 102.

H,newhyp(pstep(If T Then(A1, · · · , An) Else(B1, · · · , Bn))) ` GH, If T Then(A1, · · · , An) Else(B1, · · · , Bn) ` G

Figura 101: De�nição de restructure para If

H,newhyp(pstep(Either(H1, · · · , Hn))) ` GH,Either(H1, · · · , Hn) ` G

Figura 102: restructure para Either

O comando para utilizar essa regra é:

Page 137: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

135

restructure <H>

sendo <H> o índice da hipótese na qual será aplicada a regra de inferência. É retornada

uma mensagem de erro ao usuário caso essa regra seja aplicada a uma OP do tipo Lemma.

Para demonstrar o uso da regra foram criados dois exemplos, sendo um para cada caso.

Suas demonstrações se encontram nas �guras 103 e 104.

Have((0 ≤ a ∧ a = b) ∨ (a < 0 ∧ a = c)) ` a = 0

If 0 ≤ a Then(Have( a = b)) Else(Have( a = c)) ` a = 0restructure H0

Figura 103: Primeiro exemplo da regra restructure

Have((a = 0) ∨ (a = 1) ∨ (a = 2)) ` a = 0

Either(Have( a = 0),Have( a = 1),Have( a = 2)) ` a = 0restructure H0

Figura 104: Segundo exemplo da regra restructure

A.10 Instanciar quanti�cador universal em hipótese -

allh

Essa regra possui somente um parâmetro, sendo aplicável apenas em hipóteses cuja

fórmula seja uma quanti�cação universal. Se a restrição for respeitada, uma nova OP é

gerada com o mesmo objetivo e as mesmas hipóteses da OP original, mas com uma nova

hipótese. Seu termo é a instanciação da hipótese selecionada (quanti�cador universal

removido), sendo a variável quanti�cada substituída por um termo inserido pelo usuário,

conforme Figura 105. A instanciação do quanti�cador universal em hipótese é baseada na

regra ALL_L presente em Abrial (2010, p. 317).

H,T , repl(T , P (E)) ` OH, T (x) ` O

pstep(T ) = ∀x · P ∧vars(E) ⊆ (

⋃ni=0 vars(pstep(Hi))

∪ vars(O) ∪ vars(pstep(T ))) ∧tipo(E) = tipo(x)

Figura 105: De�nição de allh

Todas as variáveis livres do termo inserido pelo usuário devem estar presentes no

contexto da OP. Além disso, o termo inserido só é aceito se possuir estritamente o mesmo

tipo da variável que será instanciada.

Page 138: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

136

O comando para realizar a instanciação é:

allh <H> <termo>

em que o termo <termo> é instanciado na hipótese de�nida pelo índice <H>. Caso

<termo> possua de�nições e/ou variáveis livres que não estejam no contexto da OP, uma

mensagem de erro é retornado ao usuário, não sendo realizada nenhuma ação. A Figura

106 demonstra um exemplo da aplicação de allh, no qual foi criada uma nova hipótese,

sendo ela o resultado da instanciação da variável x por um termo composto pela variável

t.

∀x : int · (∃y : int · P (x, y)⇒ Q(x))

∃y : int · P (t, y)⇒ Q(t)

`Q(t)

∀x : int · (∃y : int · P (x, y)⇒ Q(x))

`Q(t)

allh 1 t

Figura 106: Exemplo da regra allh

A.11 Instanciar quanti�cador existencial em hipótese -

existh

Se a hipótese selecionada for uma quanti�cação existencial, essa regra elimina o quan-

ti�cador, substituindo sua variável por uma nova não ligada, com um nome distinto das

demais variáveis presentes no contexto da OP, sendo elas ligadas ou não. Caso contrário,

não é realizada nenhuma ação na OP. A de�nição formal dessa regra se encontra na Figura

107, sendo ela baseada na regra XST_L presente em Abrial (2010, p. 317).

H, repl(T , P (t)) ` OH, T ` O

pstep(T ) = ∃x · P (x) ∧t /∈ (

⋃ni=0 vars(pstep(Hi)) ∪ vars(pstep(T ) ∪ vars(O)) ∧

tipo(t) = tipo(x)

Figura 107: De�nição de existh

O comando para aplicar a quanti�cação existencial em hipótese é:

Page 139: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

137

existh <H>

sendo <H> o índice da hipótese no qual será aplicado a instanciação existencial. A Figura

108 exempli�ca a regra existh: a variável quanti�cada x é instanciada em uma nova variável

t.

t+ (t ∗ t) = 12 ` ∃v · v ∗ v = 9

∃x · x+ (x ∗ x) = 12 ` ∃v · v ∗ v = 9existh 1

Figura 108: Exemplo da regra existh

A.12 Substituir objetivo por hipótese - apply

O argumento dessa regra é o índice de uma hipótese. Se o termo à direita da implicação

for igual ao objetivo, então essa hipótese é removida, sendo o objetivo substituído pelo

termo à esquerda da implicação. Caso contrário, nenhuma ação é realizada. Essa regra se

encontra formalizada na Figura 109, sendo um dos possíveis casos da tática apply do Coq

(The Coq development team, 2015, p. 174).

H ` AH, T ` P

pstep(T) = (A ⇒ P)

Figura 109: De�nição de apply

O comando para aplicar a regra é:

apply <H>

sendo <H> o rótulo da hipótese que será aplicada. Caso a hipótese selecionada não seja

uma implicação ou o lado direito da implicação não é igual ao objetivo, uma mensagem

de erro é retornado ao usuário, não sendo realizada nenhuma ação. A Figura 110 exibe

um exemplo do uso de apply : o objetivo da OP original foi substituído pelo lado esquerdo

da implicação na segunda hipótese.

x = 2, 0 ≤ x⇒ b = 5 ` 0 ≤ x

x = 2, 0 ≤ x⇒ b = 5 ` b = 5apply 2

Figura 110: Exemplo da regra apply

Page 140: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

138

A.13 Modus ponens - mp

Sejam A, B e O termos, se a OP possuir duas hipóteses cujos termos sejam A ⇒ B

e A, sendo O o seu objetivo, ao aplicar essa regra de inferência o novo objetivo se torna

B ⇒ O. Para isso, o usuário deve inserir o índice da hipótese que seja o termo A ⇒ B,

sendo procurado pelo WPTrans a hipótese que seja o termo A. A formalização da regra

se encontra na Figura 111.

H,P , T ` B ⇒ O

H,P , T ` O(pstep(P ) = A⇒ B) ∧ (pstep(T ) = A)

Figura 111: De�nição de mp

Essa regra é baseada no comando Modus ponens in hypothesis, do Atelier-B (CLE-

ARSY, 2008, p. 84). A estrutura do comando para utilizá-la é:

mp <H>

sendo <H> o índice da hipótese no qual a regra será aplicada. Caso a regra não possa

ser aplicada, duas mensagens podem ser retornadas ao usuário. A primeira é exibida

caso a hipótese selecionada não seja uma implicação e a segunda é exposta caso não seja

encontrada uma hipótese cujo termo seja igual ao lado esquerdo da implicação.

A Figura 112 exempli�ca o uso de mp. Como a OP possui as hipóteses (z = 5⇒ t = 1)

e (z = 5), sendo a segunda hipótese igual ao termo à esquerda da implicação, então é

inserido o lado direito da implicação no objetivo.

z = 5⇒ t = 1, z = 5 ` t = 1⇒ ¬(t = 2)

z = 5⇒ t = 1, z = 5 ` ¬(t = 2)mp 1

Figura 112: Exemplo da regra mp

A.14 Substituir - replace, replaceh e replace_all

Essa regra realiza uma substituição de subtermos nos termos selecionados da OP, pos-

suindo três formas de ação. Denominada replace, a primeira forma exige dois argumentos,

os termos T e V , substituindo todas as ocorrências de T por V no objetivo selecionado.

Para isso, são criadas duas OPs: uma tal que todas as ocorrências do subtermo T são

Page 141: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

139

substituídas por V , e outra OP com as mesmas hipóteses da OP original, porém com o

objetivo T = V . Isso é formalizado na Figura 113.

H ` O(V ) H ` T = V

H ` O(T )

Figura 113: De�nição de replace

Caso já exista uma hipótese com T = V , a OP com a igualdade não é gerada pela

regra, isto é, não é criada a OP com o objetivo T = V . Sua formalização se encontra

presente na Figura 114.

H,A ` O(V )

H,A ` O(T )pstep(A) = (T = V )

Figura 114: De�nição de replace para osegundo caso

O replace é baseado na tática com mesmo nome presente no Coq (The Coq develop-

ment team, 2015, p. 209). O comando para aplicar essa regra de inferência é:

replace <termo1> with <termo2>

no qual o termo <termo1> será substituído pelo termo <termo2> no objetivo. A Figura

115 ilustra um exemplo para o primeiro caso de replace, sendo geradas duas OPs após a

aplicação da regra.

` m+ n+ p = m+ n+ p ` m+ n = n+m

` n+m+ p = m+ n+ preplace (n + m) with (m + n)

Figura 115: Exemplo da regra replace

A segunda e a terceira forma são baseadas tanto na tática replace do Coq como no

comando Use equality in hypothesis, presente no Atelier-B (CLEARSY, 2008, p. 55). A

segunda forma, replaceh, realiza a mesma ação que replace, mas a substituição é realizada

em uma outra hipótese da OP no lugar do objetivo. Além disso, a hipótese T = V deve

estar obrigatoriamente presente na OP. Essa obrigatoriedade torna-se necessária pois o

comando Use equality in hypothesis também exige que haja uma hipótese com a igualdade

a ser aplicada na OP.

O comando para aplicar a segunda forma da regra é:

Page 142: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

140

replaceh <índice> <termo1> with <termo2>

no qual o termo <termo1> será substituído pelo termo <termo2> na hipótese indicada

pelo índice <índice>. A formalização dessa regra se encontra na Figura 116.

H,A,X(V ) ` O(V )

H,A,X(T ) ` O(T )

Figura 116: De�nição de replaceh

A Figura 117 exempli�ca o uso de replaceh. Nele, x é substituído por u na terceira

hipótese.

u = x, 10 ≤ u, u+ y = 5, y = −5 ` u+ y = 5

u = x, 10 ≤ x, x+ y = 5, y = −5,` u+ y = 5replaceh 3 x with u

Figura 117: Exemplo da regra replaceh

Denominada replace_all, a terceira forma realiza a substituição em todas as hipóte-

ses assim como no objetivo da OP, exceto na hipótese selecionada com a igualdade. O

comando para aplicar essa versão da regra é:

replace_all <termo1> with <termo2>

no qual o termo <termo1> será substituído pelo termo <termo2> em todas as hipóteses

e no objetivo, exceto na hipótese que possua a igualdade <termo1> = <termo2>. A

formalização de replace_all se encontra na Figura 118.

H(V ), A ` O(V )

H(T ), A ` O(T )

Figura 118: De�nição de replace_all

A Figura 119 mostra um exemplo de uso de replace_all. Nele, x é substituído por u

em todas as hipóteses da OP exceto na primeira.

u = x, 10 ≤ u, u+ y = 5, y = −5 ` u+ y = 5

u = x, 10 ≤ x, x+ y = 5, y = −5 ` u+ y = 5replace_all x with u

Figura 119: Exemplo da regra replace_all

Page 143: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

141

A.15 Reescrever - rewriteh e rewritel

Essa regra é baseada na tática rewrite do Coq (The Coq development team, 2015,

p. 208). Ela modi�ca o objetivo da OP e possui dois argumentos, sendo um deles um

termo. O segundo argumento depende da variação dessa regra: ela pode ser o índice de

uma hipótese da OP (quando utilizado o comando rewriteh) como pode também ser o

nome de um lema existente no contexto da OP (quando utilizado o comando rewritel).

Para que essa regra possa ser aplicada, dois requisitos devem ser respeitados:

• o termo inserido deve ser um subtermo do objetivo;

• o termo da hipótese escolhida ou o termo do lema escolhido deve possuir um dos

seguintes formatos:

1. ∀x1 · · ·xn · P1 ⇒ · · · ⇒ Pn ⇒ T = V

2. P1 ⇒ · · · ⇒ Pn ⇒ T = V

3. ∀x1 · · ·xn · T = V

4. T = V

Em que:

� P1 · · · Pn, T e V são termos

� x1 · · · xn são variáveis

Sendo as duas condições validadas, é realizada uma uni�cação do termo inserido pelo

usuário (que chamaremos de T ′) com o termo da hipótese ou do lema selecionado (que

chamaremos de T ). Dois termos só podem ser uni�cados de acordo com as regras esta-

belecidas na Tabela 2. A substituição resultante é aplicada em V , gerando uma instância

V ′, sendo todas as ocorrências de T ′ substituídas por V ′.

Forma de T ′ Forma de T Condições para uni�caçãovariável livre variável livre T ′ = Tconstante constante T ′ = T

variável ligada universalmente qualquer termo sort(T ′) = sort(T )f(x1 · · ·xn) g(y1 · · · yn) f = g ∧match(x1, xn) · · ·match(y1, yn)

Qualquer outro caso Não há uni�cação

Tabela 2: Condições para uni�cação de termos nas regras rewriteh e rewritel

Page 144: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

142

A função sort retorna o tipo do termo, f e g são identi�cadores de funções e x1 · · ·xn,y1 · · · yn são termos. Para uni�car os termos, foi utilizado o algoritmo de uni�cação de

Robinson (HODER; VORONKOV, 2009; ROBINSON, 1965).

A formalização de rewriteh pode ser visualizada na Figura 120; podendo ser observada,

para reescrita a partir de lema, na Figura 121. A função match(A,B) veri�ca se os termos

A e B podem ser uni�cados, e a função lema(T ) veri�ca se existe um lema com o termo

T no escopo da OP. O próprio WP determina e armazena os lemas disponíveis para cada

OP, cabendo ao WPTrans lê-las e usá-las na aplicação da reescrita.

H,M ` P1 · · ·H,M ` Pn H ` O(V ′)

H,M ` O(T ′)

match(T, T ′) ∧ (

pstep(M) = ∀x1 · · · xn · P1 ⇒ · · ·· · · ⇒ Pn ⇒ T = V

∨pstep(M) = P1 ⇒ · · · ⇒ Pn ⇒ T = V

∨pstep(M) = ∀x1 · · · xn · T = V

∨pstep(M) = T = V

)

Figura 120: De�nição de rewriteh

H ` P1 · · ·H ` Pn H ` O(V ′)

H ` O(T ′)

match(T, T ′) ∧ (

lema(∀x1 · · · xn · P1 ⇒ · · · ⇒ Pn ⇒ T = V)

∨lema(P1 ⇒ · · · ⇒ Pn ⇒ T = V)

∨lema(∀x1 · · · xn · T = V)

∨lema(T = V)

)

Figura 121: De�nição de rewritel

As �guras 122 e 123 demonstram, respectivamente, um exemplo com o uso de rewriteh

e um com o uso de rewritel. No primeiro exemplo, a primeira hipótese contém a igualdade

(∀a : nat · 2 ∗ a = a+ a) usada para a reescrita de subtermo no objetivo (2 ∗ a = 10).

Page 145: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

143

∀a : nat · 2 ∗ a = a+ a, a+ a = 10 ` a+ a = 10

∀a : nat · 2 ∗ a = a+ a, a+ a = 10 ` 2 ∗ a = 10rewriteh 1

Figura 122: Exemplo da regra rewriteh

No segundo exemplo, a igualdade tomada para a reescrita vem de um lema externo,

de�nido a seguir:

Lemma def_zero : ∀a, b · a = 0⇒ a ∗ b = 0

A partir desse lema, a ∗ b é substituída por 0, sendo criada uma OP adicional para a

restrição à esquerda da implicação no lema (a = 0).

a = 0 ` a = 0 a = 0 ` 0 = 0

a = 0 ` a ∗ b = 0rewritel def_zero

Figura 123: Exemplo da regra rewritel

Page 146: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

144

APÊNDICE B -- Provas realizadas com o

WPTrans

Neste apêndice são listadas as OPs provadas de Burghardt e Gerlach (2015) com o

WPTrans, sendo exibidas as regras de inferências e comandos aplicadas para se obter

a conclusão. As OPs foram geradas usando a con�guração descrita na introdução do

Capítulo 6, sendo produzidas a partir da análise do algortitmo remove_copy (versão

estável).

Algoritmo 8 Prova de Lemma CountBounds1: intros

2: nat_ind n_0

3: call alt-ergo

4: call alt-ergo

5: call alt-ergo

Algoritmo 9 Prova de Lemma CountUnion1: intros

2: nat_ind k_0

3: call alt-ergo

4: call alt-ergo

5: call alt-ergo

Algoritmo 10 Prova de Lemma CountMonotonic1: intros

2: replace (L_Count(Mint_0,a_0,n_0,v_0)) with (L_Count(Mint_0,a_0,m_0,v_0)

+ L_Count(Mint_0,shift(a_0,m_0),(n_0-m_0),v_0))

3: call alt-ergo

Page 147: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

145

Algoritmo 11 Prova de Lemma RemoveCountMonotonic1: intros

2: unfold_all L_RemoveCount

3: assert m_0 + L_Count(Mint_0,a_0,n_0,v_0) <= n_0 +

L_Count(Mint_0,a_0,m_0,v_0)

4: assert \exists integer t; t + m_0 == n_0

5: existo n_0 - m_0

6: call alt-ergo

7: call alt-ergo

8: call alt-ergo

Page 148: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

146

APÊNDICE C -- Exemplo de teoria SMT-LIB

para inteiros

(theory Ints

:sorts ( (Int 0) )

:funs ( (NUMERAL Int)

(- Int Int) ; negation

(- Int Int Int :left -assoc) ; subtraction

(+ Int Int Int :left -assoc)

(* Int Int Int :left -assoc)

(<= Int Int Bool :chainable)

(< Int Int Bool :chainable)

(>= Int Int Bool :chainable)

(> Int Int Bool :chainable) )

:definition

"For every expanded signature Sigma , the instance of Ints with

that signature is the theory consisting of all Sigma -models

that interpret

- the sort Int as the set of all integers ,

- the function symbols of Ints as expected. "

:values

"The Int values are all the numerals and all the terms of the

form (- n) where n is a non -zero numeral."

)

Page 149: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

147

APÊNDICE D -- Obrigação de prova SMT-LIB

gerada pelo Why3 para o

solucionador Z3

;;; this is a prelude for Z3

(set -logic AUFNIRA)

;;; this is a prelude for Z3 integer arithmetic

;;; this is a prelude for Z3 real arithmetic

(declare -sort uni 0)

(declare -sort ty 0)

(declare -fun sort (ty uni) Bool)

(declare -fun witness (ty) uni)

;; witness_sort

(assert (forall ((a ty)) (sort a (witness a))))

(declare -fun int () ty)

(declare -fun real () ty)

(declare -fun bool () ty)

(declare -fun match_bool (ty Bool uni uni) uni)

;; match_bool_sort

(assert (forall ((a ty)) (forall ((x Bool) (x1 uni) (x2 uni)) (sort a (

match_bool a x x1 x2)))))

;; match_bool_True

(assert (forall ((a ty)) (forall ((z uni) (z1 uni)) (=> (sort a z) (=

(match_bool a true z z1) z)))))

;; match_bool_False

(assert (forall ((a ty)) (forall ((z uni) (z1 uni)) (=> (sort a z1) (=

(match_bool a false z z1) z1)))))

(declare -fun index_bool (Bool) Int)

;; index_bool_True

(assert (= (index_bool true) 0))

;; index_bool_False

(assert (= (index_bool false) 1))

;; bool_inversion

(assert (forall ((u Bool)) (or (= u true) (= u false))))

;; CompatOrderMult

(assert (forall ((x Int) (y Int) (z Int)) (=> (<= x y) (=> (<= 0 z)

(<= (* x z) (* y z))))))

(declare -fun abs1 (Int) Int)

;; abs_def

(assert (forall ((x Int)) (ite (<= 0 x) (= (abs1 x) x) (= (abs1 x) (-

x)))))

;; Abs_le

(assert (forall ((x Int) (y Int)) (= (<= (abs1 x) y) (and (<= (- y) x)

(<= x y)))))

Page 150: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

148

;; Abs_pos

(assert (forall ((x Int)) (<= 0 (abs1 x))))

(declare -fun div1 (Int Int) Int)

(declare -fun mod1 (Int Int) Int)

;; Div_mod

(assert (forall ((x Int) (y Int)) (=> (not (= y 0)) (= x (+ (* y (div1

x y)) (mod1 x y))))))

;; Div_bound

(assert (forall ((x Int) (y Int)) (=> (and (<= 0 x) (< 0 y)) (and (<=

0 (div1 x y)) (<= (div1 x y) x)))))

;; Mod_bound

(assert (forall ((x Int) (y Int)) (=> (not (= y 0)) (and (< (- (abs1 y

)) (mod1 x y)) (< (mod1 x y) (abs1 y))))))

;; Div_sign_pos

(assert (forall ((x Int) (y Int)) (=> (and (<= 0 x) (< 0 y)) (<= 0 (

div1 x y)))))

;; Div_sign_neg

(assert (forall ((x Int) (y Int)) (=> (and (<= x 0) (< 0 y)) (<= (div1

x y) 0))))

;; Mod_sign_pos

(assert (forall ((x Int) (y Int)) (=> (and (<= 0 x) (not (= y 0))) (<=

0 (mod1 x y)))))

;; Mod_sign_neg

(assert (forall ((x Int) (y Int))

(=> (and (<= x 0) (not (= y 0))) (<= (mod1 x y) 0))))

;; Rounds_toward_zero

(assert (forall ((x Int) (y Int)) (=> (not (= y 0)) (<= (abs1 (* (div1

x y) y)) (abs1 x)))))

;; Div_1

(assert (forall ((x Int)) (= (div1 x 1) x)))

;; Mod_1

(assert (forall ((x Int)) (= (mod1 x 1) 0)))

;; Div_inf

(assert (forall ((x Int) (y Int)) (=> (and (<= 0 x) (< x y)) (= (div1

x y) 0))))

;; Mod_inf

(assert (forall ((x Int) (y Int)) (=> (and (<= 0 x) (< x y)) (= (mod1

x y) x))))

;; Div_mult

(assert (forall ((x Int) (y Int) (z Int)) (! (=> (and (< 0 x) (and (<=

0 y) (<= 0 z)))(= (div1 (+ (* x y) z) x) (+ y (div1 z x)))) :

pattern ((div1 (+ (* x y) z) x)) )))

;; Mod_mult

(assert (forall ((x Int) (y Int) (z Int)) (! (=> (and (< 0 x) (and (<=

0 y) (<= 0 z)))(= (mod1 (+ (* x y) z) x) (mod1 z x))) :pattern ((

mod1 (+ (* x y) z) x)) )))

;; add_div

(assert (forall ((x Real) (y Real) (z Real)) (=> (not (= z 0.0)) (= (/

(+ x y) z) (+ (/ x z) (/ y z))))))

;; sub_div

(assert (forall ((x Real) (y Real) (z Real)) (=> (not (= z 0.0)) (= (/

(- x y) z) (- (/ x z) (/ y z))))))

;; neg_div

(assert (forall ((x Real) (y Real)) (=> (not (= y 0.0)) (= (/ (- x) y)

(- (/ x y))))))

;; assoc_mul_div

(assert (forall ((x Real) (y Real) (z Real)) (=> (not (= z 0.0)) (= (/

(* x y) z) (* x (/ y z))))))

Page 151: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

149

;; assoc_div_mul

(assert (forall ((x Real) (y Real) (z Real)) (=> (and (not (= y 0.0))

(not (= z 0.0))) (= (/ (/ x y) z) (/ x (* y z))))))

;; assoc_div_div

(assert (forall ((x Real) (y Real) (z Real)) (=> (and (not (= y 0.0))

(not (= z 0.0))) (= (/ x (/ y z)) (/ (* x z) y)))))

;; CompatOrderMult

(assert (forall ((x Real) (y Real) (z Real)) (=> (<= x y) (=> (<= 0.0

z) (<= (* x z) (* y z))))))

(declare -fun ite1 (ty Bool uni uni) uni)

;; ite_sort

(assert (forall ((a ty)) (forall ((x Bool) (x1 uni) (x2 uni)) (sort a

(ite1 a x x1 x2)))))

(declare -fun eqb (ty uni uni) Bool)

;; eqb1

(assert (forall ((a ty)) (forall ((x uni) (y uni)) (=> (sort a x) (=>

(sort a y) (= (= (eqb a x y) true) (= x y)))))))

(declare -fun neqb (ty uni uni) Bool)

;; neqb1

(assert (forall ((a ty)) (forall ((x uni) (y uni)) (=> (sort a x) (=>

(sort a y) (= (= (neqb a x y) true) (not (= x y))))))))

(declare -fun zlt (Int Int) Bool)

(declare -fun zleq (Int Int) Bool)

;; zlt1

(assert (forall ((x Int) (y Int)) (= (= (zlt x y) true) (< x y))))

;; zleq1

(assert (forall ((x Int) (y Int)) (= (= (zleq x y) true) (<= x y))))

(declare -fun rlt (Real Real) Bool)

(declare -fun rleq (Real Real) Bool)

;; rlt1

(assert (forall ((x Real) (y Real)) (= (= (rlt x y) true) (< x y))))

;; rleq1

(assert (forall ((x Real) (y Real)) (= (= (rleq x y) true) (<= x y))))

(declare -fun truncate (Real) Int)

;; truncate_of_int

(assert (forall ((x Int)) (= (truncate (to_real x)) x)))

;; c_euclidian

(assert (forall ((n Int) (d Int)) (! (=> (not (= d 0)) (= n (+ (* (

div1 n d) d) (mod1 n d)))) :pattern ((div1 n d) (mod1 n d)) )))

;; cdiv_cases

(assert (forall ((n Int) (d Int)) (! (and (=> (<= n 0) (=> (< 0 d) (=

(div1 n d) (- (div1 (- n) d))))) (and (=> (<= 0 n) (=> (< d 0) (= (

div1 n d) (- (div1 n (- d))))))(=> (<= n 0) (=> (< d 0) (= (div1 n

d) (div1 (- n) (- d))))))) :pattern ((div1 n d)) )))

;; cmod_cases

(assert (forall ((n Int) (d Int)) (! (and (=> (<= n 0) (=> (< 0 d) (=

(mod1 n d) (-

(mod1 (- n) d))))) (and (=> (<= 0 n) (=> (< d 0) (= (mod1 n d) (mod1 n

(- d)))))

(=> (<= n 0) (=> (< d 0) (= (mod1 n d) (- (mod1 (- n) (- d))))))))

:pattern (

(mod1 n d)) )))

;; cmod_remainder

(assert (forall ((n Int) (d Int)) (! (and (=> (<= 0 n) (=> (< 0 d) (

and (<= 0 (mod1 n d)) (< (mod1 n d) d)))) (and (=> (<= n 0) (=> (<

0 d) (and (< (- d) (mod1 n d)) (<= (mod1 n d) 0)))) (and (=> (<= 0

n) (=> (< d 0) (and (<= 0 (mod1 n d)) (< (mod1 n d) (- d))))) (=>

(<= n 0) (=> (< d 0) (and (< d (mod1 n d)) (<= (mod1 n d) 0)))))))

Page 152: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

150

:pattern ((mod1 n d)))))

;; cdiv_neutral

(assert (forall ((a Int)) (! (= (div1 a 1) a) :pattern ((div1 a 1)))))

;; cdiv_inv

(assert (forall ((a Int)) (! (=> (not (= a 0)) (= (div1 a a) 1)) :

pattern ((div1 a a)))))

(declare -fun map (ty ty) ty)

(declare -fun get (ty ty uni uni) uni)

;; get_sort

(assert (forall ((a ty) (b ty)) (forall ((x uni) (x1 uni)) (sort b (

get b a x x1)))))

(declare -fun set (ty ty uni uni uni) uni)

;; set_sort

(assert (forall ((a ty) (b ty)) (forall ((x uni) (x1 uni) (x2 uni)) (

sort (map a b) (set b a x x1 x2)))))

;; Select_eq

(assert (forall ((a ty) (b ty)) (forall ((m uni)) (forall ((a1 uni) (

a2 uni)) (forall ((b1 uni)) (! (=> (sort b b1) (=> (= a1 a2) (= (

get b a (set b a m a1 b1) a2) b1))) :pattern ((get b a (set b a m

a1 b1) a2)) ))))))

;; Select_neq

(assert (forall ((a ty) (b ty)) (forall ((m uni)) (forall ((a1 uni) (

a2 uni)) (=> (sort a a1) (=> (sort a a2) (forall ((b1 uni)) (! (=>

(not (= a1 a2)) (= (get b a (set b a m a1 b1) a2) (get b a m a2)))

:pattern ((get b a (set b a m a1 b1) a2)) ))))))))

(declare -fun const1 (ty ty uni) uni)

;; const_sort

(assert (forall ((a ty) (b ty)) (forall ((x uni)) (sort (map a b) (

const1 b a x)))))

;; Const

(assert (forall ((a ty) (b ty)) (forall ((b1 uni) (a1 uni)) (=> (sort

b b1) (= (get b a (const1 b a b1) a1) b1)))))

(assert

;; Q_plusEqual File "Axiomatic.why", line 14, characters 6-17

(not (forall ((m Int) (n Int) (o Int)) (=> (= m n) (=> (= m o) (= n o)

)))))

(check - sat)

Page 153: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

151

APÊNDICE E -- Algoritmos da STL C++ e do

Toccata especi�cados para

análises experimentais

Os algoritmos listados nesta seção foram implementados e especi�cados para as aná-

lises experimentais da seção 6.3.

1. Algoritmo is_sorted :

typedef int value_type;

typedef unsigned int size_type;

typedef int bool;

#include <limits.h>

/*@

requires 0 < n < INT_MAX && \valid_read(a + (0..n-1));

ensures \result ==> \forall value_type x,y; 0 <= x <= y < n ==> a

[x] <= a[y];

ensures !\ result ==> \exists value_type x,y; 0 <= x <= y < n ==>

a[x] > a[y];

*/

bool is_sorted(const value_type* a, size_type n){

if (n <= 1) return true;

int first = 0;

/*@

loop invariant 0 <= first < n;

loop invariant \forall value_type x,y; 0 <= x <= y <= first

==> a[x] <= a[y];

loop assigns first;

loop variant n-first;

*/

while(first +1 < n){

if(a[first +1] < a[first]) return false;

++ first;

}

return true;

}

Figura 124: Algoritmo is_sorted especi�cado

Page 154: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

152

2. Algoritmo is_sorted_until :

typedef int value_type;

typedef unsigned int size_type;

#include <limits.h>

/*@

requires 0 < n < INT_MAX && \valid_read(a + (0..n-1));

ensures \result == n ==> \forall value_type x,y; 0 <= x <= y < n

==> a[x] <= a[y];

ensures \result != n ==> a[\ result] < a[\result -1];

*/

int is_sorted_until(const value_type* a, size_type n){

if (n <= 1) return n;

int first = 0;

/*@

loop invariant 0 <= first < n;

loop invariant \forall value_type x,y; 0 <= x <= y <= first

==> a[x] <= a[y];

loop assigns first;

loop variant n-first;

*/

while(first +1 < n){

if(a[first +1] < a[first]) return first +1;

++ first;

}

return n;

}

Figura 125: Algoritmo is_sorted_until especi�cado

3. Algoritmo min_max_element :

typedef int value_type;

typedef unsigned int size_type;

#include "MinElement.h"

struct pdata { size_type min; size_type max; };

typedef struct pdata pair;

/*@

requires \valid_read(a + (..n-1));

assigns \nothing;

behavior empty:

assumes n == 0;

ensures \result.min == 0 && \result.max == 0;

behavior not_empty:

assumes 0 < n;

ensures 0 <= \result.min < n && 0 <= \result.max < n;

ensures \forall integer i;

0 <= i < n ==> a[i] <= a[\ result.max];

ensures \forall integer i;

0 <= i < \result.max ==> a[i] < a[\ result.max];

ensures minimum: MinElement(a, n, \result.min);

ensures first:

Page 155: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

153

StrictLowerBound(a, 0, \result.min , a[\ result.min]);

complete behaviors;

disjoint behaviors;

*/

pair minmax_element(const value_type* a, size_type n){

if (n == 0){

pair minmax; minmax.min = 0; minmax.max = 0;

return minmax;

}

size_type min = 0; size_type max = 0;

/*@

loop invariant 0 <= i <= n && 0 <= max < n;

loop invariant

\forall integer k; 0 <= k < i ==> a[k] <= a[max];

loop invariant

\forall integer k; 0 <= k < max ==> a[k] < a[max];

loop invariant min: 0 <= min < n;

loop invariant lower: LowerBound(a, 0, i, a[min]);

loop invariant first: StrictLowerBound(a, 0, min , a[min]);

loop assigns max , min , i;

loop variant n-i;

*/

for (size_type i = 0; i < n; i++){

if (a[max] < a[i]) {max = i;}

if (a[i] < a[min]) {min = i;}

}

pair minmax; minmax.max = max; minmax.min = min; return minmax;

}

Figura 126: Algoritmo min_max_element especi�cado

4. Algoritmo remove (STL):

typedef int value_type;

typedef unsigned int size_type;

#include "../ LogicSpecifications/HasValue.h"

#include "../ LogicSpecifications/Unchanged.h"

#include "../ LogicSpecifications/PreserveCount.h"

/*@

requires \valid(a + (0..n-1));

assigns a[0..(n-1)];

ensures 0 <= \result <= n && !HasValue(a, \result , v);

*/

size_type remove(value_type* a, size_type n, value_type v){

size_type i = 0; size_type k = 0;

/*@

loop invariant 0 <= i <= k <= n;

loop invariant \forall integer x; 0 <= x < i ==> a[x] != v;

loop assigns i,k, a[0..n-1];

loop variant n-k;

*/

while (k < n){

Page 156: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

154

if(a[k] == v){++k;}

else{a[i++] = a[k++];}

}

return i;

}

Figura 127: Algoritmo remove especi�cado

5. Algoritmo unique (STL):

typedef int value_type;

typedef unsigned int size_type;

/*@ axiomatic WhitherUnique_Function

{ logic integer WhitherUnique{L}( value_type * a, integer i) reads

a[0],a[i];

axiom unique_1: \forall value_type *a; WhitherUnique(a, 0)

== 0;

axiom unique_2: \forall value_type *a, integer i;

a[i] == a[i+1] ==> WhitherUnique(a, i+1) ==

WhitherUnique(a, i);

axiom unique_3: \forall value_type *a, integer i;

a[i] != a[i+1] ==> WhitherUnique(a, i+1) ==

WhitherUnique(a, i) + 1;

lemma unique_lemma_4: \forall value_type *a, integer i, j;

i < j && a[i] != a[i+1] ==> WhitherUnique(a, i) <

WhitherUnique(a, j);

lemma unique_5: \forall value_type *a, integer i, j;

i < j ==> WhitherUnique(a, i) <= WhitherUnique(a, j

); }

*/

/* predicate UniqueCopy{A,B}( value_type * a, integer n, integer m)

=

(n == 0 ==> m == 0) &&

(n >= 1 ==> m-1 == WhitherUnique (\at(a,B), n-1)) &&

\forall integer i; 0 <= i < n ==>

\at(a[i],A) == \at(a[WhitherUnique (\at(a,A), i)],B)

;

*/

/*@ predicate UniqueCopy{L}( value_type * a, integer n, value_type *

b, integer m) =

(n == 0 ==> m == 0) &&

(n >= 1 ==> m-1 == WhitherUnique(a, n-1)) &&

\forall integer i; 0 <= i < n ==> a[i] == b[WhitherUnique(a

, i)];

*/

/*@ requires 0 <= n < INT_MAX;

requires \valid(a+ (0..n));

assigns a[0..(n-1)];

ensures \forall integer k; \result <= k < n ==> a[k] == \

old(a[k]);

ensures 0 <= \result <= n;

ensures UniqueCopy (\at(a,Pre), n,\at(a,Post),\result);

*/

Page 157: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

155

size_type unique(value_type * a, size_type n)

{

if (n <= 0) return 0; size_type i = 1; size_type j = 1;

/*@ loop invariant 1 <= j <= i <= n;

loop invariant UniqueCopy (\at(a,Pre), i, \at(a,

LoopCurrent), j);

loop assigns a[1..n-1], i, j;

loop variant n - i; */

while (i < n)

{

if (a[i] != a[i - 1])

a[j++] = a[i];

++i;

//@ assert 0 < i <= n;

}

return j;

}

Figura 128: Algoritmo unique especi�cado

6. Algoritmo �nd_end (STL): O arquivo equal.c contém a de�nição do algoritmo

equal, especi�cado em Burghardt et al. (2013).

#include "equal.c"

typedef int value_type;

typedef unsigned int size_type;

/*@

predicate

EqualRanges{A,B}( value_type* a, integer n, value_type* b) =

\forall integer i; 0 <= i < n ==> \at(a[i], A) == \at(b[i], B

);

*/

/*@

requires \valid_read(a + (0..m-1));

requires \valid_read(b + (0..n-1));

assigns \nothing;

ensures (n == 0 || m == 0) ==> \result == 0;

behavior has_match:

assumes HasSubRange(a, m, b, n);

ensures 0 <= \result <= m-n;

ensures EqualRanges{Here ,Here}(a+\result , n, b);

ensures !HasSubRange(a, \result+n-1, b, n);

behavior no_match:

assumes !HasSubRange(a, m, b, n);

ensures \result == m;

complete behaviors;

disjoint behaviors;

*/

size_type find_end(const value_type* a, size_type m,

Page 158: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

156

const value_type* b, size_type n)

{

if ((n == 0) || (m == 0)) return 0;

if (n > m) return m;

/*@

loop invariant 0 <= i <= m-n+1;

loop invariant !HasSubRange(a+i, m-i, b, n);

loop assigns i;

loop variant i;

*/

for (size_type i = m-n; i >= 0; i--)

{

if (equal(a + i, n, b)) return i;

}

return m;

}

Figura 129: Algoritmo unique especi�cado

7. Algoritmo sum of values in array (STL):

#include <limits.h>

/*@ axiomatic Sum {

// sum(t,i,j) denotes t[i]+...+t[j-1]

logic integer sum{L}(int *t, integer i, integer j)

reads i,j,t, t[i..j-1] ;

axiom sum1{L} :

\forall int *t, integer i, j; i >= j ==> sum(t,i,j) == 0;

axiom sum2{L} :

\forall int *t, integer i, j; i <= j ==>

sum(t,i,j+1) == sum(t,i,j) + t[j]; }

lemma sum3{L} :

\forall int *t, integer i, j, k;

i <= j <= k ==>

sum(t,i,k) == sum(t,i,j) + sum(t,j,k);

lemma sum_footprint{L} :

\forall int *t1 ,*t2, integer i, j;

(\ forall integer k; i<=k<j ==> t1[k] == t2[k]) ==>

sum(t1 ,i,j) == sum(t2,i,j);

*/

/*@

requires INT_MIN <= sum(t,0,n) <= INT_MAX;

requires 0 <= n <= INT_MAX;

requires n >= 1 && \valid(t+(0..n-1)) ;

ensures \result == sum(t,0,n);

*/

int test1(int t[],int n) {

int i,s = 0;

/*@ loop invariant 0 <= i <= n && s == sum(t,0,i);

loop assigns s,i;

loop variant n-i;

Page 159: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

157

*/

for(i=0; i < n; i++)

{

s += t[i];

}

return s;

}

/*@

requires INT_MIN <= sum(t,0,n) <= INT_MAX;

requires 0 <= n <= INT_MAX;

requires n >= 1 && \valid(t+(0..n-1));

assigns t[..];

ensures sum(t,0,n) == \old(sum(t,0,n))+n;

*/

void test2(int t[],int n) {

int i;

/*@ loop invariant 0 <= i <= n &&

@ sum(t,0,n) == \at(sum(t,0,n),Pre)+i;

loop assigns i,t[0..n-1];

@ loop variant n-i;

*/

for(i=0; i < n; i++)

{

//@ assert sum(t,0,n) == sum(t,0,i) + t[i] + sum(t,i+1,n);

t[i] += 1;

//@ assert sum(t,0,n) == sum(t,0,i) + t[i] + sum(t,i+1,n);

}

}

Figura 130: Algoritmo sum of values in array especi�cado

Page 160: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

158

APÊNDICE F -- Modi�cações realizadas no

WP

Neste apêndice são listadas as modi�cações realizadas no WP, versão 0.9, para que o

WPTrans pudesse ser implementado. As diferenças são listadas para cada módulo OCaml.

• Wpo (arquivos wpo.mli e wpo.ml) - adicionamos dois campos na de�nição de uma

OP, sendo eles mutable po_leaves : po list ; e

po_partac : (int * po * WpoRewriter_infRules_names.tactic_s) option;.

Ambos os campos são utilizados apenas quando a OP é resultante da aplicação

de uma regra de inferência, possuindo, respectivamente, os valores None e [] (lista

vazia) quando a OP não é gerada pelo WPTrans. O segundo campo possui três

argumentos, sendo eles o índice da sub-OP, seu consequente e a regra de inferência

que foi aplicada. Já o segundo argumento contém os antecedentes diretos da OP.

• VCS (arquivos VCS.ml e VCS.mli) - adicionamos os valores Rewriter e L_rewriter

nos tipos prover e language, consequentemente, tivemos de modi�car algumas fun-

ções como filename_for_prover, pois elas manipulam argumentos dos dois tipos

supracitados. O motivo dessas modi�cações é que caso todos os antecedentes de uma

OP sejam validadas ela também deve o ser, sendo necessário de�nir como a OP foi

provada. Os dois tipos, prover e language, servem justamente para identi�car o

provador que foi utilizado na prova, isto é, com que forma a OP foi validada.

• Conditions (arquivo Conditions.mli) - tornamos públicos os tipos step, sequencee condition, assim como a função step, para pode acessar e modi�car hipóteses

presentes em OP do tipo Annot.

• De�nitions (arquivos De�nitions.ml e De�nitions.mli) - adicionamos o novo campol_assumptions : pred list ; no tipo dlemma para representar as hipóteses em

OPs do tipo Lemma, sendo elas sempre inicializadas com uma lista vazia.

Page 161: WPTrans: Um Assistente para Veri cação de Programas em … · tes oferecem comunicação com proadoresv automáticos, entretanto, essa ligação pode ser complexa ou incompleta,

159

• Logic (arquivo logic.mli) - a função val c_bind : binder -> (Field.t, ADT.t)

datatype -> term -> term foi tornada pública para que novos termos com quan-

ti�cadores universais e existenciais pudessem ser criados.

• Term (arquivos term.ml e term.mli) - criamos uma nova função denominada

iter_on_builtin_funs para obtermos todas as funções acessíveis a uma OP. Isso

serviu tanto para serem usadas com a regra de inferência unfold como para mostrá-

las ao usuário.

• GuiNavigator eGuiCon�g (arquivos GuiNavigator.ml e GuiCon�g) - �zemos pe-quenas adaptações para que o WPTrans pudesse ser inicializado a partir da interface

do WP. A principal função que inicializa a extensão é popup_Rewriter.

• Lang (aruivo Lang.mli) - tornamos a função pp_tau pública para que pudéssemos

obter o nome de uma variável.

• ProverCoq e ProverErgo (arquivos ProverCoq.ml e ProverErgo.ml) - modi�ca-

mos a função prove_lemma. Ela é utilizada para obter o objetivo e dependências

(de�nições e axiomas) de uma OP para traduzi-las à linguagem de um provador alvo.

Modi�camos a sentença let prop = F.p_forall lemma.l_forall lemma.l_lemma

para let prop = F.p_forall lemma.l_forall ((F.p_hyps lemma.l_assumptions)

lemma.l_lemma) de modo que as hipóteses nas OPs do tipo Lemma também pu-

dessem ser incluídos na tradução e, consequentemente, na prova.

• ProverWhy3 (arquivos ProverWhy3.ml e ProverWhy3.mli) - criamos uma função

denominada let detect_why3_task para executar provadores em segundo plano.

Ela é uma versão da função detect_why3 já presente no módulo, na qual o provador

não é inicializado de imediato, e sim com execução agendada.

• WpPropId (arquivos wpPropId.ml e wpPropId.mli) - realizamos uma modi�cação

que fez com que o campo p_part do tipo prop_id se tornasse mutável, permi-

tindo que ele seja atualizado quando OPs fossem geradas a partir do WPTrans.

Ademais, criamos uma função denominada compare_prop_id_kind_and_property

para comparar duas OPs com mesmo consequente, mas com índices diferentes.