Tous les programmes sauf les plus triviaux sont remplis de bogues et donc tout ce qui promet de les supprimer est extrêmement séduisant. Pour le moment, les preuves d'exactitude sont du code sont extrêmement ésotériques, principalement en raison de la difficulté à apprendre cela et de l'effort supplémentaire qu'il faut pour prouver qu'un programme est correct. Pensez-vous que la preuve du code prendra son envol?
la source
ne peut être entièrement vérifié pour être correct avec un effort raisonnable. Pour toute preuve formelle d'exactitude, vous avez besoin d'au moins une spécification formelle, et cette spécification doit être complète et correcte. Ce n'est généralement rien que vous puissiez facilement créer pour la plupart des programmes du monde réel. Par exemple, essayez d'écrire une telle spécification pour quelque chose comme l'interface utilisateur de ce site de discussion, et vous savez ce que je veux dire.
Ici, j'ai trouvé un bel article sur le sujet:
http://www.encyclopedia.com/doc/1O11-programcorrectnessproof.html
la source
printf("1")
est correct ou non (par exemple, parce que l'exigence était "d'imprimer un nombre aléatoire également distribué de 1 à 6") ne peut pas être décidé par un tel analyseur statique.Le problème avec les preuves formelles est qu'elles ne font que reculer le problème d'une étape.
Dire qu'un programme est correct équivaut à dire qu'un programme fait ce qu'il doit faire. Comment définissez-vous ce que le programme doit faire? Vous le spécifiez. Et comment définissez-vous ce que le programme doit faire dans les cas marginaux que la spécification ne couvre pas? Eh bien, alors vous devez rendre la spécification plus détaillée.
Supposons donc que vos spécifications deviennent finalement suffisamment détaillées pour décrire le comportement correct de chaque aspect de l'ensemble du programme. Vous avez maintenant besoin d'un moyen de faire comprendre vos outils de preuve. Vous devez donc traduire la spécification dans une sorte de langage formel que l'outil de preuve peut comprendre ... hé, attendez une minute!
la source
La vérification formelle a parcouru un long chemin, mais généralement les outils de l'industrie / largement utilisés sont à la traîne des dernières recherches. Voici quelques efforts récents dans cette direction:
Spec # http://research.microsoft.com/en-us/projects/specsharp/ Il s'agit d'une extension de C # qui prend en charge les contrats de code (conditions pré / post et invariants) et peut utiliser ces contrats pour effectuer différents types d'analyse statique .
Des projets similaires à celui-ci existent pour d'autres langages, tels que JML pour java, et Eiffel a à peu près cela intégré.
Pour aller encore plus loin, des projets comme le slam and blast peuvent être utilisés pour vérifier certaines propriétés comportementales avec une annotation / intervention minimale du programmeur, mais ne peuvent toujours pas traiter la généralité complète des langages modernes (des choses comme l'arithmétique du débordement d'entier / du pointeur ne sont pas modélisées).
Je crois que nous verrons beaucoup plus de ces techniques utilisées dans la pratique à l'avenir. Le principal obstacle est que les invariants de programme sont difficiles à déduire sans annotations manuelles, et les programmeurs ne sont généralement pas disposés à fournir ces annotations car cela est trop fastidieux / prend trop de temps.
la source
Non, sauf si une méthode de vérification automatique du code sans travail de développeur approfondi se pose.
la source
Certains outils de méthodes formelles (comme par exemple Frama-C pour les logiciels C embarqués critiques) peuvent être considérés comme (en quelque sorte) fournissant, ou du moins vérifiant, une preuve (d'exactitude) d'un logiciel donné. (Frama-C vérifie qu'un programme obéit à sa spécification formalisée, dans un certain sens, et respecte les invariants explicitement annotés dans le programme).
Dans certains secteurs, de telles méthodes formelles sont possibles, par exemple comme le DO-178C pour les logiciels critiques des aéronefs civils. Dans certains cas, de telles approches sont donc possibles et utiles.
Bien sûr, développer des logiciels moins bogués est très coûteux. Mais l'approche de méthode formelle a du sens pour une sorte de logiciel. Si vous êtes pessimiste, vous pourriez penser que le bogue est déplacé du code vers sa spécification formelle (qui peut avoir quelques "bogues", car formaliser le comportement prévu d'un logiciel est difficile et sujet aux erreurs).
la source
Je suis tombé sur cette question, et je pense que ce lien pourrait être intéressant:
Applications industrielles d'Astrée
Prouver l'absence de RTE dans un système utilisé par Airbus avec plus de 130 000 lignes de code en 2003 ne semble pas être mauvais, et je me demande s'il y aura quelqu'un pour dire que ce n'est pas le monde réel.
la source
Non. Le proverbe commun est: "En théorie, la théorie et la pratique sont les mêmes. En pratique, non."
Un exemple très simple: Typos.
En fait, l'exécution du code via des tests unitaires trouve ces choses presque immédiatement, et un ensemble cohérent de tests annulera le besoin de preuves formelles. Tous les cas d'utilisation - bons, mauvais, erreurs et cas limites - doivent être énumérés dans les tests unitaires, qui se révèlent être une meilleure preuve que le code est correct que n'importe quelle preuve distincte du code.
Surtout si les exigences changent ou si l'algorithme est mis à jour pour corriger un bogue - la preuve formelle est plus susceptible de devenir obsolète, comme les commentaires de code l'obtiennent souvent.
la source
Je pense que les limites imposées aux preuves de correction en raison du problème d'arrêt pourraient être le plus grand obstacle à la généralisation des preuves de correction.
la source
Il est déjà utilisé par tout le monde. Chaque fois que vous utilisez la vérification de type de votre langage de programmation, vous faites essentiellement une preuve mathématique de l'exactitude de votre programme. Cela fonctionne déjà très bien - il vous suffit de choisir des types corrects pour chaque fonction et structure de données que vous utilisez. Plus le type est précis, meilleure sera la vérification. Les types existants disponibles dans les langages de programmation disposent déjà d'outils suffisamment puissants pour décrire presque tous les comportements possibles. Cela fonctionne dans toutes les langues disponibles. C ++ et les langages statiques font juste les vérifications au moment de la compilation, tandis que les langages plus dynamiques comme python le font lorsque le programme est exécuté. Le chèque existe toujours dans toutes ces langues. (par exemple, c ++ prend déjà en charge la vérification des effets secondaires de la même manière que haskell,
la source
mutable
ouconst_cast
. Je vois certainement le lien que vous y établissez, mais la saveur de deux approches me semble plutôt différente.