Exercice 2 : Vérification automatique et correction partielle/totale
🌐 Énoncé du problème / Cadre d’étude
Section titled “🌐 Énoncé du problème / Cadre d’étude”La vérification formelle de programmes est une technique rigoureuse permettant de prouver mathématiquement qu’un programme informatique satisfait ses spécifications. Dans ce problème, nous formalisons un sous-ensemble d’un langage impératif simple et nous étudions les mécanismes de la logique de Hoare pour établir la correction partielle et la correction totale de programmes.
Un triplet de Hoare est noté sous la forme : où :
- est la précondition (assertion vraie avant l’exécution de la commande ),
- est une commande (instruction, affectation, boucle, conditionnelle),
- est la postcondition (assertion vraie après l’exécution réussie de ).
On distingue deux notions fondamentales :
- La correction partielle : Si la précondition est satisfaite et que l’exécution de se termine, alors la postcondition est satisfaite.
- La correction totale : La correction partielle est assurée et l’exécution de se termine obligatoirement (pas de boucle infinie).
Nous formaliserons ici les règles de calcul des plus faibles préconditions ( pour Weakest Precondition) pour automatiser la génération de conditions de vérification.
❓ Questions progressives (incluant une analyse critique du modèle)
Section titled “❓ Questions progressives (incluant une analyse critique du modèle)”-
Règles de base de la logique de Hoare
- Rappeler ou établir la règle d’affectation (axiomatique de l’affectation) : .
- Étudier la règle de composition séquentielle : si et , que peut-on déduire pour ?
-
Application à un algorithme itératif simple
- On considère le programme calculant le produit de deux entiers et par additions successives :
x := 0;y := 0;while y < b dox := x + a;y := y + 1;done
- Proposer un invariant de boucle adéquat pour prouver que ce programme calcule bien à la fin, avec la précondition .
- On considère le programme calculant le produit de deux entiers et par additions successives :
-
Correction totale et variants
- Pour la boucle , définir formellement la notion de variant de boucle (ou fonction de termination) permettant d’établir la correction totale.
- Appliquer cette notion au programme pour prouver sa terminaison.
-
Analyse critique du modèle et limites de la vérification formelle
- Le système de Hoare présenté ici suppose un modèle d’arithmétique idéal où les entiers ont une capacité infinie. Discuter brièvement des failles que cela engendre lors du passage à un langage réel (comme le C ou l’Ocaml avec des entiers machine à taille fixe, type
int64).
- Le système de Hoare présenté ici suppose un modèle d’arithmétique idéal où les entiers ont une capacité infinie. Discuter brièvement des failles que cela engendre lors du passage à un langage réel (comme le C ou l’Ocaml avec des entiers machine à taille fixe, type
💡 Pistes & Indications méthodologiques
Section titled “💡 Pistes & Indications méthodologiques”- Question 1 : Pour l’affectation, pensez à substituer toute occurrence de la variable modifiée par l’expression qui lui est affectée dans la postcondition.
- Question 2 : L’invariant doit être vrai avant l’entrée dans la boucle, conservé par une itération, et permettre d’établir la postcondition lorsque la condition de la boucle devient fausse. Testez l’invariant .
- Question 3 : Un variant doit être à valeurs dans un ensemble bien fondé (souvent ) et strictement décroître à chaque itération.
- Question 4 : Pensez aux dépassements de capacité (overflows) qui violent l’hypothèse mathématique de la logique de Hoare classique.
📋 Corrigé détaillé pas à pas
Section titled “📋 Corrigé détaillé pas à pas”1. Règles de base de la logique de Hoare
Section titled “1. Règles de base de la logique de Hoare”-
Règle d’affectation : Démonstration/Justification intuitive : Pour que soit vraie pour la variable après l’affectation , il faut que soit déjà vraie en remplaçant par l’expression avant l’affectation.
-
Règle de composition séquentielle : Si l’on a et , alors par la règle d’affaiblissement/composition : Cette règle permet de chaîner les instructions de manière inductive.
2. Application à et invariant de boucle
Section titled “2. Application à CmultC_{\text{mult}}Cmult et invariant de boucle”Soit le programme :
x := 0;y := 0;while y < b do x := x + a; y := y + 1;donePostcondition souhaitée : . Précondition initiale : .
-
Choix de l’invariant : On pose .
-
Vérification des conditions de Hoare pour la boucle :
- Initialisation : Juste avant la boucle, après , on a et . Comme et (car ), l’invariant est bien vérifié.
- Conservation : Supposons vrai et la condition de boucle vraie. Après le corps de boucle , la postcondition doit être l’invariant au tour suivant. En appliquant la règle d’affectation en sens inverse : . Or, l’hypothèse implique directement . De plus, et impliquent . L’invariant est donc conservé.
- Terminaison et Postcondition : Lorsque la boucle s’arrête, on a , c’est-à-dire . Cela implique , et par conséquent , ce qui correspond exactement à la postcondition .
3. Correction totale et variants
Section titled “3. Correction totale et variants”Pour établir la correction totale d’une boucle , on associe à la boucle un variant (fonction des variables du programme à valeurs dans ) tel que :
- est strictement décroissant à chaque exécution du corps (si est vrai).
- Lorsque atteint (ou une borne minimale), si la boucle continue, cela mène à une contradiction, ou l’atteinte de cette borne force la sortie.
- Application au programme :
On choisit le variant .
- Justification :
- Tant que la boucle tourne, , donc .
- À chaque itération, est incrémenté de (), donc le variant diminue strictement de . Puisque le variant est à valeurs dans et décroît strictement à chaque étape, la boucle ne peut pas tourner infiniment. La correction totale est ainsi établie.
- Justification :
4. Analyse critique du modèle
Section titled “4. Analyse critique du modèle”- Limites de l’arithmétique idéale :
Le système de Hoare classique modélise les entiers ou de l’arithmétique usuelle. En informatique, les types entiers natifs (par exemple les
intsur 32 ou 64 bits en C/C++ ou Java) possèdent des bornes strictes (ex. pour unint64). - Conséquences : Si et sont grands, le calcul ou peut provoquer un dépassement de capacité (overflow). L’invariant mathématique peut alors devenir faux au niveau machine en raison d’un isomorphisme modulo , invalidant de fait la preuve formelle réalisée sur le papier.
- Remède : Utiliser des outils de vérification par SMT-solvers (comme Why3 ou Frama-C) qui intègrent explicitement la sémantique exacte des types machines (bits de poids fort, dépassements, arrondis pour les flotteurs).