• Aucun résultat trouvé

Conséquences de la possible vacuité des sous-ensembles de cellules

2.4 Exemple

3.1.3 Conséquences de la possible vacuité des sous-ensembles de cellules

∀r ∈ R(σ),∃σ∈X, σ=σ◦ro

Les fonctionsαetγseront décrites plus en profondeur dans la section 3.4. D’ici là, nous allons devoir compliquer encore un peu la situation. Néanmoins, le processus d’abstraction restera le même : on permet au domaine abstrait de décrire des propriétés sur des sous-ensembles de cellules, en énumérant tous lesn-uplets de cellules sur lesquels on veut exprimer ces propriétés.

3.1.3 Conséquences de la possible vacuité des sous-ensembles de cellules

Pour saisir les problèmes qu’impliquent la manipulation de sous-ensembles revenons à notre exemple initial de l’initialisation de tableaux. Prenons la valeur abstraite exprimant l’invariant de boucle après l’affectation, en ne considérant que les propriétés sur les cellules du tableau :

a1=a2=0

ce qui signifierait que toutes les cellules d’indice compris entre 1 eti−1 ainsi que la cellule d’indiceiont pour contenu 0. Ce qui pourrait s’écrire :

∀`1, `2,1≤`1 <i∧`2=i⇒ A[`1]=A[`2]=0

Dans la formalisation de la section précédente, cela donnerait pourR: R(σ)=        r:        a17→A[`1] a27→A[`2] 1≤`1 ≤σ(i)∧`2=σ(i)       

Malheureusement lorsquei= 1 l’interprétation de la valeur abstraite ne nous apprend rien : la partie gauche de l’implication est impossible et donc l’implication est toujours vraie. Or, on a besoin de la propriétéA[1]=0 même lorsquei=1.

Le problème de notre formalisation c’est qu’on doit toujours avoir un choix de représentants pour chaque sous-ensemble de cellules symbolisé. Or quand ce sous-ensemble est vide, il est effectivement impossible d’en choisir un élément.

Comme noté précédemment, on pourrait être tenté de décomposer la valeur abstraite en deux : une partie qui décrita1et une partie qui décrita2. Ici, on ne perdrait rien à faire cette décom-position, si ce n’est la relation d’égalité entrea1eta2qui ne nous sert pas pour la preuve. Mais observons un exemple où l’on a besoin de propriétés relationnelles : la segmentation de tableau figure 3.3. On devrait pouvoir obtenir une valeur abstraite décrivant l’état du programme à la fin de l’exécution similaire à celle-ci :

Qu’on voudra certainement interpréter de la manière suivante afin d’en tirer le maximum d’in-formation :

∀`, 2≤` <i ⇒ A[`]<A[1] ∧ ∀`, i≤`≤n ⇒ A[1]≤A[`] Bien sûr de cette formule on peut déduire aussi

∀`1, `2,1≤`1<i≤`2≤n ⇒ A[`1]<A[`2] ce qui s’écrirait dans le domaine abstrait

a2 <a3

Or cette dernière propriété sera en principe déduite automatiquement par le domaine abstrait. Mais cela uniquement si les variables a1, a2 eta3 sont décrites par la même valeur abstraite. Si on décomposait en deux valeurs abstraites, l’une décrivant les relations entre les variablesa1

eta2 l’autre décrivant les relations entre les variablesa1 eta3 il faudrait trouver le moyen de combiner ces valeurs abstraites afin de dériver les relations entrea2eta3qui peuvent être utiles à la preuve du programme.

Pour obtenir le maximum de précision de l’analyse d’un programme, il est nécessaire de regrouper dans une même valeur abstraite toutes les variables ayant une relation pour ce domaine abstrait. Ainsi toute relation valide entre ces variables pourra potentiellement être déduite. Évolution de la formalisation. Comme nous l’avons vu plus haut, nous ne pouvons pas gar-der exactement le même formalisme pour les choix de représentants. Lorsqu’un ensemble de cellules est vide, il est impossible d’en choisir un représentant. Modifions alors la définition d’un choix de représentants en n’obligeant plus à ce que ce soient des fonctions totales. Voyons les choix de représentants comme des fonctions partielles qui ne sont pas définies lorsque l’en-semble de cellules symbolisé par une variable est vide. Ainsi, pour l’initialisation de tableau, lorsqueσ(i)=1 et pourr∈ R(σ) on aura quer(a1) est indéfini.

En conséquence, la construction des intermédiaires est aussi modifiée. La composition

σ=σ◦r

n’est plus définie que sur le domaine de définition der. Ainsi, un état intermédiaire ne sera pas défini sur une variable symbolisant un sous-ensemble de cellules vide.

Conséquences sur le domaine abstrait. Ce choix a des conséquences importantes. Il nous force à abandonner l’une des contraintes que l’on s’était fixé : la préservation des domaines abstraits. On va maintenant demander au domaine abstrait d’être capable d’abstraire des états qui ne sont plus des fonctions totales mais des fonctions partielles. Il va falloir donner du sens à ces états partiels, et ce, pour chaque domaine abstrait. En fait, notre changement de formalisation n’a pas résolu de problème. Notre problème qui était de réussir à exprimer des propriétés entre des sous-ensembles potentiellement vides de cellules n’a été que repoussé jusque dans le domaine abstrait.

Souvent, une valeur peut être vue comme une formule sur des variables logiques, c’est ce que nous avons fait jusqu’ici. Une idée assez générale que nous développerons dans le chapitre 7

i←1 ou 2 aléatoirement Sii=1alors x ← 0 A[i] ← x sinon x ← 1 A[i−1] ← x

Figure3.5 :Exemple de programme sur lequel une analyse maladroite peut dériver des proprié-tés fausses.

pour modifier le domaine abstrait est que chaque formule atomique peut être testée sur un état partiel. Si les variables de cette formule atomique ne sont pas définies dans l’état partiel, c’est que l’un des ensembles de cellules symbolisé est vide et on pourra donc considérer la formule vraie. A partir de là, il est possible de tester des conjonctions, des disjonctions et des négations de formules atomiques.

Le danger. Si on a choisi de ne pas décomposer les valeurs abstraites c’est essentiellement pour des questions de précision de l’analyse. En n’utilisant qu’une seule valeur abstraite pour décrire chacun des sous-ensembles de cellules qu’on souhaite décrire, on sera en mesure de dériver des relations entre eux. Malheureusement, ce n’est pas sans risque.

Supposons qu’on ait obtenu lors d’une analyse la valeur abstraite

x<a1∧a1<y

où xetysont des variables du programme eta1 une variable représentant un ensemble de cel-lules. S’il est correct de dire que toutes les cellules de cet ensemble ont un contenu supérieur à

xet inférieur ày, cela n’implique pas nécessairementx<y. En toute rigueur, on aurax<ysi et seulement si l’ensemble de cellules est non vide. Dans le cas contraire, on ne saura rien dexni dey.

Voici le genre de danger auquel nous serons confrontés. L’exemple figure 3.5 montre comment le problème peut devenir dramatique. Il initialise une variableiavec pour valeur 1 ou 2 et suivant cette valeur affecte une variable x et la cellule A[1] avec la valeur 0 ou 1. On peut décrire précisément l’état du tableau en utilisant, ce qui ne semble pas nécessairement naturel, deux ensembles de cellules : l’ensemble{A[`] |1≤`≤i−1}et{A[`] | i≤`≤1}. Lorsquei=1 le premier est vide, tandis que le second l’est quandi= 2. De fait le premier n’est affecté que par la seconde branche de l’instruction conditionnelle tandis que le second ne sera affecté que par la première. Si on associe ces deux ensembles respectivement aux variablesa1 eta2on sera en mesure d’écrire :

dont l’interprétation serait 1≤i≤2 ∧ ∀`,1≤`≤i−1 ⇒ A[`]=1 ∧ ∀`,1≤`≤i−1 ⇒ A[`]= x ∧ ∀`,i≤`≤1 ⇒ A[`]=1 ∧ ∀`,i≤`≤1 ⇒ A[`]=0

Des deux sous-ensembles de cellules, il y en a toujours un qui est vide pour un état donné. On peut donc très bien écrire

∀`1, `2,1≤`1≤i−1∧i≤`2≤1 ⇒ A[`1]= A[`2]

qui est une tautologie : il est impossible d’avoir à la fois un`1et un`2vérifiant la partie gauche de l’implication. Il n’y a donc pas de mal à ce que la propriété

a1 =a2

soit dérivable de la valeur abstraite. Mais la propriété 1=a1= x=a2=0

est plus gênante car elle conclut à une contradiction. De cette contradiction on peut déduire toute chose fausse du programme.

La transformation des domaines abstraits va donc nécessiter un travail certain, et va en parti-culier demander à ce qu’une partie des preuves de corrections soient reconstruites.