• Aucun résultat trouvé

a diff´erents outils de simplification sp´ecifiques ´ecrits en HOL4 et enfin aux solveurs externes. Il s’agit d’une chaˆıne compl`etement automatique : la fonction ML verif y

prend en entr´ee le nom d’un programme `a v´erifier, g´en`ere la repr´esentation interne,

fait l’ex´ecution symbolique du programme en fournissant une trace des chemins ex-plor´es et renvoie le terme RESU LT s si le programme est correct (s est l’´etat final), et renvoie ERROR s s’il y a une erreur. Dans ce dernier cas, s est instanci´e avec une des erreurs (i.e. solution trouv´ee par le solveur externe).

J’effectue une critique de ce premier travail dans la section VI.2 et en pr´esente les questions ouvertes et perspectives. La section suivante est une formalisation de l’ex´ecution symbolique en terme de g´en´eration de plus forte post-condition.

IV.3 V´erification des programmes par g´en´eration d’une

plus forte post-condition

Cette section expose quelques ´el´ements de l’article que Mike Gordon a ´et´e invit´e `

a ´ecrire pour c´el´ebrer le 75i`emeanniversaire de Tony Hoare, et dont je suis co-auteur.

Il est inclus comme article support section IV.5.1 page 186.

J’introduis tout d’abord, de fa¸con succincte et sans aucune perspective his-torique, les preuves par g´en´eration d’une plus faible pr´e-condition, et d´etaille l’ex´ecution symbolique vue comme une g´en´eration de plus forte post-condition. Ce dernier point fournit un cadre th´eorique aux travaux de la section pr´ec´edente. De plus, il pose de nombreuses questions et perpectives qui seront discut´ees au chapitre VI.

IV.3.1 V´erification de triplets de Hoare

Un triplet de Hoare {P }S {Q} (o`u P et Q sont des assertions et S est un

ensem-bles d’instructions) signifie que Q (la “post-condition”) est vraie dans chaque ´etat

at-teint par l’ex´ecution de S `a partir d’un ´etat initial dans lequel P (la “pr´e-condition”)

est vraie. La logique de Hoare [8] est un syst`eme d´eductif dont les axiomes et les r`egles d’inf´erence fournissent une m´ethode pour prouver de tels triplets.

La g´en´eration de plus forte post-condition et plus faible pr´e-condition

permet ´egalement de prouver de tels triplets. Si P ⇒ Q alors P est dit plus fort que

9

Q. Un g´en´erateur10 de plus forte post-condition pour un programme S transforme le pr´edicat de pr´e-condition P en un pr´edicat de post-condition sp S P , qui est le pr´edicat ‘le plus fort’ qui est vrai apr`es avoir ex´ecut´e S dans un ´etat qui satisfait la pr´e-condition P . Il est plus fort dans le sens que si Q est vrai pour chaque ´etat r´esultant de l’ex´ecution de S quand P est vrai, alors sp S P est plus fort que Q – i.e. sp S P ⇒ Q.

Si P ⇒ Q alors Q est plus faible que P . Un g´en´erateur de plus faible pr´e-condition pour un programme S transforme le pr´edicat de post-condition Q en un pr´edicat de pr´e-condition wp S Q, qui est le pr´edicat le ‘plus faible’ qui assure que si un ´etat le satisfait alors apr`es ex´ecution de S le pr´edicat Q est vrai. Il est plus faible dans le sens que si P a la propri´et´e qu’ex´ecuter S quand P est vrai assure que Q est vrai apr`es ex´ecution, alors wp S Q est plus faible que P – i.e. P ⇒ wp S Q.

Le lien entre ces deux g´en´erateurs et la v´erification d’un triplet de Hoare est que le triplet {P }S {Q} est v´erifi´e si et seulement si (sp S P ) ⇒ Q et aussi si et seulement si P ⇒ wp S Q. Les ´equations satisfaites par sp S P et wp S Q sont donn´ees figure

IV.8. Calculer sp (S1;S2) P avec ces ´equations revient `a partir d’une pr´e-condition

P , `a calculer d’abord sp S1P et ensuite appliquer sp S2 au pr´edicat r´esultant. Cela

correspond `a une ex´ecution symbolique en avant. Au contraire, calculer wp (S1;S2) Q

proc`ede en arri`ere `a partir de la post-condition Q en calculant d’abord wp S2Q en

appliquant ensuite wp S1 au pr´edicat r´esultant.

Une diff´erence majeure entre les deux approches r´eside dans la r`egle de trans-formation de l’affectation. Le fait que cette r`egle soit plus complexe dans le cas en avant (`a cause du quantificateur existentiel), semble expliquer pourquoi la plupart des prouveurs utilisent la g´en´eration en arri`ere. En effet, la r`egle de g´en´eration d’une plus faible pr´e-condition pour la s´emantique de l’affectation V := E est :

wp(V := E) Q = Q[E/V ]

tandis que la r`egle de g´en´eration d’une plus forte post-condition est :

sp(V := E) P = ∃v. (V = E[v/V ]) ∧ P [v/V ]

o`u la notation M [E/V ], avec M formule ou expression, repr´esente le r´esultat de

la substitution de V par E dans M . Pour la plus faible pr´e-condition, il suffit de remplacer V par E dans Q. Pour la plus forte post-condition, des quantificateurs existentiels sont introduits afin de repr´esenter les modifications successives de la variable. En effet, ∃v. (V = E[v/V ]) ∧ P [v/V ] signifie qu’il existe une variable v qui ´etait la valeur de V avant ex´ecution de l’affectation et qui v´erifie la pr´e-condition. De plus, la variable V apr`es affectation (i.e. partie gauche de V = E[v/V ]) est calcul´ee en fonction de cette valeur pr´ec´edente. Notons que les renommages SSA utilis´es dans notre pr´ec´edente approche peuvent ˆetre vus comme une skol´emisation

de ces quantificateurs existentiels11. L’exemple IV.5 compare la g´en´eration d’une

plus faible pr´e-condition, d’une plus forte post-condition et de la forme SSA pour v´erifier un triplet de Hoare tr`es simple.

Exemple IV.5 (R´egle d’affectation) Soit le triplet de Hoare suivant :

{x=0}x :=x+1 ;x :=x+2 ;{x=3}, sp´ecifiant le programme nomm´e “TresSimple”.

10

J’ai choisi d’appeler “g´en´erateur de plus forte post-condition” la notion de “strongest postcon-dition predicate transformer”.

11

IV.3. G ´EN ´ERATION D’UNE PLUS FORTE POST-CONDITION 179

Plus faible pr´e-condition

La plus faible pr´e-condition est g´en´er´ee en partant de la post-condition, en proc´edant vers l’arri`ere depuis la derni`ere instruction du programme et en rempla¸cant dans la post-condition courante les variables par les valeurs qui leur sont affect´ees.

wp TresSimple (x = 3) =

wp(x := x + 1; x := x + 2; ) (x = 3) =

wp(x := x + 1; ) (x+2 = 3) =

((x+1)+2 = 3)

Pour montrer le triplet de Hoare {x=0}x :=x+1 ;x :=x+2 ;{x=3} il faut alors

mon-trer que x=0 ⇒ wp TresSimple (x=3) c’est-`a-dire que x=0 ⇒ (x+1)+2=3 ce qui est

trivialement v´erifi´e. Plus forte post-condition

La plus forte post-condition est g´en´er´ee en partant de la pr´e-condition et en proc´edant vers l’avant depuis la premi`ere instruction du programme. Chaque affectation intro-duit un quantificateur existentiel pour repr´esenter la valeur pr´ec´edente de la variable modifi´ee.

sp TresSimple (x = 0) =

sp(x := x + 1; x := x + 2; ) (x = 0) =

sp(x := x + 2; ) (∃v1. x = v1+ 1 ∧ v1= 0) =

(∃v2. x = v2+ 2 ∧ (∃v1. v2= v1+ 1 ∧ v1 = 0))

Pour montrer le triplet de Hoare {x=0}x :=x+1 ;x :=x+2 ;{x=3} il faut alors

mon-trer que sp TresSimple (x = 0) ⇒ x=3 c’est-`a-dire que (∃v2. x = v2+2∧(∃v1. v2 =

v1+ 1 ∧ v1= 0)) ⇒ x=3 ce qui est v´erifi´e.

Forme SSA

La forme SSA du programme est calcul´ee en introduisant un renommage de la

vari-able `a chaque nouvelle d´efinition (voir figure III.3 section III.2.2 page 97).

SSA(x :=x+1 ;x :=x+2 ;)=

x1 = x0+ 1; x2 = x1+ 2

Pour montrer le triplet de Hoare, il faut alors montrer que la conjonction de la

pr´e-condition (o`u les variables ont leur renommage initial, x0 ici) et du programme en

forme SSA implique la post-condition (o`u les variables ont leur renommage final, x2

ici). Il faut donc montrer que (x0 = 0 ∧ (x1 = x0 + 1 ∧ x2 = x1+ 2)) ⇒ x2 = 3

ce qui est aussi trivialement v´erifi´e. Notons que cette formule est exactement celle obtenue pour la plus forte post-condition si l’on skol´emise l’expression en prenant la

constante x0 pour v1, la constante x1 pour v2 et que l’on renomme x en x2. ♯

IV.3.2 Ex´ecution symbolique et preuve en avant

Le calcul na¨ıf de sp S P par les ´equations de la figure IV.8 produit des for-mules compliqu´ees avec des quantifications existentielles imbriqu´ees. Cependant, une strat´egie plus fine est possible et constitue un cadre th´eorique pour l’ex´ecution sym-bolique en v´erification de logiciels [12].

Supposons que toutes les variables d’un programme S soient incluses dans la liste

sp SKIPP = P wp SKIPQ = Q sp(V := E) P = ∃v. (V =E[v/V ]) ∧ P [v/V ] wp(V := E) Q = Q[E/V ] sp(S1;S2) P = sp S2(sp S1P ) wp(S1;S2) Q = wp S1(wp S2Q)

sp(if B then S1 else S2) P = (sp S1(P ∧ B)) ∨ (sp S2(P ∧ ¬B))

wp(if B then S1 else S2) Q = ((wp S1Q) ∧ B) ∨ ((wp S2Q) ∧ ¬B)

sp(WHILE B DO S) P = (sp (WHILE B DO S) (sp S (P ∧ B))) ∨ (P ∧ ¬B)

wp(WHILE B DO S) Q = (wp S (wp (WHILE B DO S) Q) ∧ B) ∨ (Q ∧ ¬B)

Fig.IV.8 – Equations d´efinissant les plus fortes post-conditions (sp) et plus faibles

pr´e-conditions (wp)

d’´etats des variables du programme symboliquement par des formules logiques de la forme :

∃x1· · · xn. X1 = e1 ∧ · · · ∧ Xn= en ∧ φ

o`u x1,. . .,xn sont des variables logiques (i.e. xi repr´esente symboliquement la valeur

initiale de la variable Xi), e1, . . .,en sont des expressions (ei repr´esente la valeur

courante de Xi) et φ est une formule logique qui ´etablit des relations entre les

valeurs des variables (i.e. post-condition en cours de construction pour le calcul de la plus forte post-condition par ex´ecution symbolique). Pour ´eviter les captures de

variables lors des substitutions, e1,. . .,en et φ ne doivent pas contenir les variables

du programme X1,. . .,Xn; par contre, elles peuvent tr`es bien contenir les variables

logiques x1,. . .,xn. Par exemple, la formule

∃i j. I = i ∧ J = j ∧ i < j

repr´esente l’ensemble des ´etats dans lesquels la valeur de la variable du programme

I(repr´esent´ee symboliquement par i) est plus petite que la valeur de la variable du

programme J (repr´esent´ee symboliquement par j). Cette formule est logiquement

´equivalente `a I < J.

En g´en´eral, chaque pr´edicat P peut se r´e´ecrire :

∃x1· · · xn. X1 = x1 ∧ · · · ∧ Xn= xn ∧ P [x1, . . . , xn/X1, . . . , Xn]

o`u P [x1, . . . , xn/X1, . . . , Xn] (qui correspond au φ pr´ec´edent) d´enote le r´esultat du

remplacement des occurrences de la variable du programme Xi par la variable xi

(1 ≤ i ≤ n) qui repr´esente symboliquement sa valeur.

Ainsi, calculer sp (Xi:=E) consiste `a ´evaluer E dans l’´etat courant

(i.e. E[e1, . . . , en/X1, . . . , Xn]) et mettre `a jour l’´equation pour Xi pour sp´ecifier

que c’est la nouvelle valeur apr`es l’ex´ecution symbolique de l’affectation.

Si X1, . . . , Xn, x1, . . . , xn et e1, . . . , en sont libres par rapport au contexte, alors

on peut les abr´eger en X, x et e respectivement. Nous pouvons aussi ´ecrire X = e

pour X1= e1∧ . . . ∧ Xn= en. Avec ces notations, la r`egle d’affectation devient :

sp(Xi:=E) (∃x. X = e ∧ φ)

= ∃x. X1= e1∧ . . . ∧ Xi = E[e/X] ∧ . . . ∧ Xn= en∧ φ

IV.3. G ´EN ´ERATION D’UNE PLUS FORTE POST-CONDITION 181

P a la forme ∃x. X = e ∧ φ, alors pour calculer sp (S1;S2) P il suffit de mettre `a

jour les ´equations dans la conjonction correspondant `a la variable affect´ee par S1

suivi de celle affect´ee par S2.

L’exemple IV.6 reprend le calcul de la plus forte post-condition du programme T resSimple de l’exemple IV.5 en montrant comment sont effectu´ees les affectations pour l’ex´ecution symbolique.

Exemple IV.6 (Plus forte post-condition par ex´ecution symbolique) Soit le

triplet de Hoare {x=0}x :=x+1 ;x :=x+2 ;{x=3} de l’exemple IV.5. Alors la plus forte post-condition est calcul´ee de la fa¸con suivante avec la r`egle d’affectation pour l’ex´ecution symbolique :

sp TresSimple (X = 0) =

sp(X := X + 1; X := X + 2; ) (∃x X = x ∧ x = 0) =

(par introduction de ∃ dans x = 0)

sp(x := X + 2; ) (∃x X = X+1[x/X] ∧ x = 0) =

(par la r`egle daf f ectation )

sp(x := X + 2; ) (∃x X = x + 1 ∧ x = 0) =

(apr`es substitution de X par x)

(∃x X = X+2[(x + 1)/X] ∧ x = 0) =

(par la r`egle daf f ectation )

(∃x X = (x + 1) + 2 ∧ x = 0)

(apr`es substitution de X par x + 1)

Dans cette d´erivation, la fonction φ ci-dessus est le pr´edicat x = 0. Notons que l’int´erˆet majeur de cette nouvelle approche par rapport aux ´equations classiques de

sp est qu’elle ne g´en`ere qu’un seul quantificateur existentiel par variable du

pro-gramme, pour repr´esenter sa valeur initiale. ♯

Pour les conditionnelles, l’´equation pour calculer la plus forte post-condition est :

sp(if B then S1 else S2) P = (sp S1(P ∧ B)) ∨ (sp S2(P ∧ ¬B)).

Si P a la forme ∃x. X = e ∧ φ alors P ∧ B et P ∧ ¬B peuvent ´egalement ˆetre mis sous cette mˆeme forme. Par cons´equent, si une conditionnelle est dans une s´equence

alors comme sp S (P1∨ P2) = sp S P1∨ sp S P2 pour tout programme S, il suit que :

sp((if B then S1 else S2);S3) P =

sp(S1;S3) (P ∧ B) ∨ sp (S2;S3) (P ∧ ¬B)

Cela ´etablit que le calcul de la plus forte post-condition d’une s´equence qui commence par une conditionnelle peut ˆetre effectu´e par des ex´ecutions symboliques s´epar´ees. Donc si l’on peut montrer que P ∧ B ou P ∧ ¬B sont faux alors, puisque pour chaque S, sp S F = F, une des disjonctions peut ˆetre supprim´ee. Sinon, l’ex´ecution symbolique des deux branches doit ˆetre faite (en appliquant diff´erentes heuristiques d’exploration en profondeur ou en largeur d’abord).

L’exemple IV.7 illustre l’ex´ecution symbolique d’instructions conditionnelles. Il montre la g´en´eration de la plus forte post-condition du programme AbsM inus pr´esent´e dans la sous-section IV.2 figure IV.3, quand la pr´e-condition est i < j. C’est la formalisation exacte de l’ex´ecution symbolique d´etaill´ee dans la sous-section IV.2, en particulier en ce qui concerne le calcul de l’´etat. En effet, ∃x. X = e formalise

la gestion de l’´etat par des listes associatives o`u Xi sont les symboles des

associa-tions, xi sont les valeurs initiales associ´ees et ei les valeurs courantes associ´ees. De

plus, dans les formules ci-dessus, φ est la post-condition en cours de construction :

il s’agit de la pr´e-condition `a l’´etat initial et de la conjonction de la pr´e-condition et

des d´ecisions prises sur le chemin courant pour les ´etats de calcul interm´ediaires. Exemple IV.7 (Plus forte post-condition pour le programme AbsM inus) Pour chaque transformation, le terme qui a ´et´e introduit ou modifi´e est soulign´e.

sp AbsMinus (I < J) =

sp(R := 0;

K:= 0;

IF I< J THEN K := K + 1 ELSE SKIP;

IF K= 1 ∧ ¬(I = J) THEN R := J − I ELSE R := I − J)

(∃i j k r. I = i ∧ J = j ∧ K = k ∧ R = r ∧ i < j) = sp(K := 0;

IF I< J THEN K := K + 1 ELSE SKIP;

IF K= 1 ∧ ¬(I = J) THEN R := J − I ELSE R := I − J)

(∃i j k r. I = i ∧ J = i ∧ K = k ∧ R = 0 ∧ i < j) = sp(IF I < J THEN K := K + 1 ELSE SKIP;

IF K= 1 ∧ ¬(I = J) THEN R := J − I ELSE R := I − J)

(∃i j k r. I = i ∧ J = i ∧ K = 0 ∧ R = 0 ∧ i < j) =

(sp(K := K + 1; IF K = 1 ∧ ¬(I = J) THEN R := J − I ELSE R := I − J) (∃i j k r. I = i ∧ J = i ∧ K = 0 ∧ R = 0 ∧ (i < j ∧ (I < J)[i, j/I, J])) ∨

sp(SKIP; IF K = 1 ∧ ¬(I = J) THEN R := J − I ELSE R := I − J)

(∃i j k r. I = i ∧ J = i ∧ K = 0 ∧ R = 0 ∧ (i < j ∧ ¬(I < J)[i, j/I, J])))

Puisque (I < J)[i, j/I, J] = i < j la pr´e-condition de la seconde disjonction contient la conjonction i < j ∧ ¬(i < j) qui est fausse. Donc la seconde disjonction peut ˆetre supprim´ee pour obtenir :

sp(K := K + 1; IF K = 1 ∧ ¬(I = J) THEN R := J − I ELSE R := I − J) (∃i j k r. I = i ∧ J = i ∧ K = 0 ∧ R = 0 ∧ i < j)) =

sp(IF K = 1 ∧ ¬(I = J) THEN R := J − I ELSE R := I − J) (∃i j k r. I = i ∧ J = i ∧ K = (K+1)[0/K] ∧ R = 0 ∧ i < j)) = (sp(R := J − I) (∃i j k r. I = i ∧ J = i ∧ K = 1 ∧ R = 0 ∧ (i < j ∧ (1 = 1 ∧ ¬(i = j)))) ∨ sp(R := I − J) (∃i j k r. I = i ∧ J = i ∧ K = 0 ∧ R = 0 ∧ (i < j ∧ ¬(1 = 1 ∧ ¬(i = j))))) = I= i ∧ J = i ∧ K = 1 ∧ R = 0 ∧ (i < j ∧ ¬(1 = 1 ∧ ¬(i = j))))) =

La seconde disjonction est supprim´ee car i < j ∧ ¬(1 = 1 ∧ ¬(i = j)) se simplifie en F.

sp(R := J − I)

(∃i j k r. I = i ∧ J = i ∧ K = 1 ∧ R = 0 ∧ i < j) =

IV.3. G ´EN ´ERATION D’UNE PLUS FORTE POST-CONDITION 183

La partie droite de cette ´equation se simplifie en R = J−I∧I < J en effectuant la sub-stitution et en utilisant les propri´et´es des quantificateurs existentiels. Finalement :

sp AbsMinus (I < J) = R = J−I ∧ I < J. ♯

IV.3.3 Boucles et invariants

Le BMC d´eplie les boucles jusqu’`a une certaine profondeur. La v´erification est

donc plutˆot une recherche d’erreurs : en cas de succ`es, on peut seulement affirmer

que le programme ne contient pas d’erreurs jusqu’`a cette profondeur. D’autre part,

il n’y a pas de fa¸con g´en´erale pour calculer la plus forte post-condition ou la plus faible pr´e-condition pour les boucles WHILE : la r´e´ecriture avec les ´equations de la figure IV.8 peut ne pas terminer. Une fa¸con d’effectuer une preuve formelle et compl`ete est donc d’utiliser des invariants de boucle qui peuvent ˆetre fournis par un humain ou par un algorithme de g´en´eration d’invariants. La logique de Hoare fournit la r`egle WHILE suivante :

⊢ P ⇒ R ⊢ {R ∧ B}S {R} R ∧ ¬B ⇒ Q

⊢ {P }WHILE B DO{R} S {Q}

o`u {R} est une assertion qui repr´esente l’invariant. Cette r`egle est la base logique

de toutes les m´ethodes qui utilisent un invariant pour v´erifier des programmes con-tenant des boucles. Elle stipule que le triplet {P}WHILE B DO{R} S{Q} est correct si l’invariant est impliqu´e par la pr´e-condition (P ⇒ R), si l’invariant est pr´eserv´e par ex´ecution d’une ´etape de la boucle {R ∧ B}S {R} et que la conjonction de l’invariant et de la condition de sortie de boucle implique Q (R ∧ ¬B ⇒ Q).

La g´en´eration des plus fortes post-conditions de programmes avec boucle en utilisant la r`egle WHILE ci-dessus, est distingu´ee de la g´en´eration classique (i.e. sans utiliser d’invariant) en l’appelant “approximation de la plus forte post-condition” (en ce sens que l’invariant peut donner un r´esultat approxim´e de l’ex´ecution de la boucle). Les r`egles asp S P pour calculer l’approximation de la plus forte post-condition sont les mˆemes que celles pour calculer sp S P sauf que la r`egle

asp WHILEB DO{R} S P a ´et´e ajout´ee : asp (WHILE B DO{R} S) P = R ∧ ¬B

En effet, c’est la partie de la r`egle WHILE qui concerne la v´erification de la post-condition. Dans le cadre de l’ex´ecution symbolique, cette ´equation peut ˆetre r´e-´ecrite en :

asp(WHILE B DO{R} S) (∃x. X1= e1∧ . . . ∧ Xn= en∧ φ)

= ∃x. X = x ∧ (R ∧ ¬B)[x/X]

Ainsi, ex´ecuter symboliquement WHILE B DO{R} S consiste `a supprimer la

pr´e-con-dition et `a recommencer l’ex´ecution dans un nouvel ´etat symbolique qui correspond

`

a l’´etat sp´ecifi´e comme vrai apr`es la boucle par la r`egle WHILE de Hoare.

Pour effectuer correctement la v´erification d’un triplet de Hoare en utilisant la

r`egle WHILE, il faut s’assurer que le contexte de son utilisation est correct c’est-`

a-dire que la pr´e-condition implique l’invariant et que l’invariant en est bien un. Les m´ethodes de preuve bas´ees sur ce principe g´en`erent donc deux types d’informa-tion : d’une part l’approximad’informa-tion de la plus forte post-condid’informa-tion (ou plus faible pr´e-condition), et d’autre part un ensemble de conditions de v´erification not´ees svc S P