Todos os programas, exceto os mais triviais, estão cheios de bugs e, portanto, qualquer coisa que promova removê-los é extremamente atraente. No momento, as provas de correção são um código extremamente esotérico, principalmente por causa da dificuldade de aprender isso e do esforço extra necessário para provar que um programa está correto. Você acha que a prova de código decolará?
programming-practices
Casebash
fonte
fonte
não pode ser totalmente comprovado como correto com um esforço razoável. Para qualquer prova formal de correção, você precisa de pelo menos uma especificação formal, e essa especificação deve estar completa e correta. Isso normalmente não é nada que você possa criar facilmente para a maioria dos programas do mundo real. Por exemplo, tente escrever essa especificação para algo como a interface do usuário deste site de discussão e você entende o que quero dizer.
Aqui encontrei um bom artigo sobre o tema:
http://www.encyclopedia.com/doc/1O11-programcorrectnessproof.html
fonte
printf("1")
está correto ou não (por exemplo, porque o requisito era "imprimir um número aleatório igualmente distribuído de 1 a 6") não pode ser decidido por um analisador estático.O problema das provas formais é que ele apenas retrocede o problema.
Dizer que um programa está correto é equivalente a dizer que um programa faz o que deve fazer. Como você define o que o programa deve fazer? Você o especifica. E como você define o que o programa deve fazer em casos extremos que as especificações não cobrem? Bem, então você precisa tornar as especificações mais detalhadas.
Então, digamos que suas especificações finalmente se tornem detalhadas o suficiente para descrever o comportamento correto de todos os aspectos de todo o programa. Agora você precisa de uma maneira de fazer com que suas ferramentas de prova entendam. Então você tem que traduzir as especificações em algum tipo de linguagem formal que a ferramenta de provas possa entender ... ei, espere um minuto!
fonte
A verificação formal já percorreu um longo caminho, mas geralmente as ferramentas amplamente utilizadas pela indústria / setor ficam atrás das pesquisas mais recentes. Aqui estão alguns esforços recentes nessa direção:
Spec # http://research.microsoft.com/en-us/projects/specsharp/ Esta é uma extensão do C # que suporta contratos de código (condições pré / pós e invariantes) e pode usar esses contratos para fazer vários tipos de análise estática .
Projetos semelhantes a esse existem para outros idiomas, como o JML para java, e o Eiffel tem esse recurso embutido.
Indo além, projetos como slam e blast podem ser usados para verificar determinadas propriedades comportamentais com anotação / intervenção mínima do programador, mas ainda não conseguem lidar com a generalidade total das linguagens modernas (coisas como excesso de número inteiro / aritmética de ponteiro não são modeladas).
Acredito que veremos muito mais dessas técnicas usadas na prática no futuro. A principal barreira é que os invariantes do programa são difíceis de inferir sem anotações manuais, e os programadores geralmente não estão dispostos a fornecer essas anotações porque isso é muito tedioso / demorado.
fonte
A menos que surja um método para provar automaticamente o código sem um extenso trabalho do desenvolvedor.
fonte
Algumas ferramentas formais de métodos (como, por exemplo, o Frama-C para software C crítico incorporado) podem ser vistas como (mais ou menos) fornecer, ou pelo menos verificar, uma prova (de correção) de um determinado software. (O Frama-C verifica se um programa obedece à sua especificação formalizada, em algum sentido, e respeita os invariantes explicitamente anotados no programa).
Em alguns setores, esses métodos formais são possíveis, por exemplo, o DO-178C para software crítico em aeronaves civis. Portanto, em alguns casos, essas abordagens são possíveis e úteis.
Obviamente, desenvolver um software com menos bugs é muito caro. Mas a abordagem do método formal faz sentido para algum tipo de software. Se você é pessimista, pode pensar que o bug foi movido do código para sua especificação formal (que pode ter alguns "bugs", porque formalizar o comportamento pretendido de um software é difícil e propenso a erros).
fonte
Eu me deparei com essa questão e acho que esse link pode ser interessante:
Aplicações Industriais da Astrée
Provar a ausência do RTE em um sistema usado pela Airbus com mais de 130 mil linhas de código em 2003 não parece ruim, e imagino que haverá alguém dizendo que esse não é o mundo real.
fonte
Não. O provérbio comum para isso é: "Em teoria, teoria e prática são iguais. Na prática, não".
Um exemplo muito simples: erros de digitação.
Realmente, executar o código através de testes de unidade encontra essas coisas quase imediatamente, e um conjunto coeso de testes negará a necessidade de quaisquer provas formais. Todos os casos de uso - casos bons, ruins, de erro e de borda - devem ser enumerados nos testes de unidade, que acabam como prova melhor de que o código está correto do que qualquer prova separada do código.
Especialmente se os requisitos forem alterados ou o algoritmo for atualizado para corrigir um erro - a prova formal tem mais probabilidade de ficar desatualizada, da mesma forma que os comentários de código costumam ter.
fonte
Penso que os limites impostos às provas de correção por causa do problema de parada podem ser a maior barreira para que as provas de correção se tornem comuns.
fonte
Já é usado por todos. Toda vez que você usa a verificação de tipo da sua linguagem de programação, está basicamente fazendo uma prova matemática da correção do seu programa. Isso já funciona muito bem - requer apenas a escolha de tipos corretos para cada função e estrutura de dados que você usar. Quanto mais preciso for o tipo, melhor será a verificação. Os tipos existentes disponíveis nas linguagens de programação já possuem ferramentas poderosas o suficiente para descrever praticamente qualquer comportamento possível. Isso funciona em todos os idiomas disponíveis. C ++ e as linguagens estáticas estão apenas fazendo as verificações em tempo de compilação, enquanto linguagens mais dinâmicas, como python, estão fazendo isso quando o programa é executado. A verificação ainda existe em todos esses idiomas. (por exemplo, o c ++ já suporta a verificação de efeitos colaterais da mesma forma que haskell,
fonte
mutable
ouconst_cast
. Eu certamente vejo a conexão que você desenha lá, mas o sabor de duas abordagens parece bastante diferente para mim.