2. Le langage Tom 17
3.5. Génération des contraintes et des obligations de preuve
sous-section 3.4.1(seq
a)est applicable. La réduction de i
1;i
2est égale à la réduction de
i
1, et est donc unique.
– Dans le second cas, la règle(seq
b) est applicable. Puisque la réduction dei
2est elle
aussi unique, la réduction de i=i
1;i
2est unique.
Théorème 3. Étant donnés un ancrage formel pq, m une construction multi-motif et
π
m∈PILun programme bien formé, on a :
π
mest une compilation correcte de m
⇐⇒
∀∈ Env,∀t∈ T(F),∀p∈ P
m:
∃
0∈ Env,h, π
m(ptq)i 7→
bsh
0,accept
pi
⇔Φ(
0)(p) =t∧(∀p
0∈ P
mtel que p
0< p,Φ(
0)(p
0)6=t)
Démonstration. On veut montrer, de la même manière que pour la propriété 3, que
(M sound
OK)⇒(M complete
KO) et(M complete
OK)⇒(M sound
KO).
Dans le premier cas, supposons(M sound
OK) et∀p∈ P
m, p6t. Puisque la réduction
de h, π
m(ptq)i est unique, il est impossible d’avoir une réduction de h, π
m(ptq)i 7→
bsh
0,accept
pi. Cette réduction existe, et donc on ah, π
m(ptq)i 7→
bsh
0,refusei.
Le second cas peut être prouvé de manière similaire.
Afin de prouver que la compilationπ
md’une construction multi-motif mest correcte,
on doit considérer chaque instruction accept
pdans le programme séparément. Pour
chaque motif p dans la construction «match », on construit toutes les dérivations dans
7→
bsqui mènent versaccept
p, et déduit de celles si une contrainte, formée d’une
disjonc-tion de conjoncdisjonc-tions de contraintes simplesCπ
m, p. On peut alors pour chaque contrainte
prouver l’obligation de preuve correspondante, comme exprimé dans le théorème 3.
3.5. Génération des contraintes et des obligations de preuve
Il est maintenant nécessaire d’expliciter l’algorithme générant les contraintes associées
à un programme bien formé du langage PIL. On décrit ici cet algorithme, et discute de
sa complexité.
3.5.1. Algorithme de collecte de contraintes
L’extraction commence à partir d’un environnementinstanciant toutes les variables
libres du programme à vérifier, comme montré dans la sous-section 3.3.4.
Définition 25 (Extraction des contraintes). L’algorithme d’extraction de contraintes,
notéC, est définit comme suit :
C(let(x, u, i), but) = C(i, but)∧x=u
C(if(e, i
1, i
2), but) = (C(i
1, but)∧e≡true)
∨C(i
2, but)∧e≡false)
C(i
1;i
2, but) = C(i
1, but)∨(C(i
1,refuse)∧ C(i
2, but))
C(i, but) = > sii=but,
⊥ sinon
Cet algorithme calcule une disjonction de conjonction de contraintes élémentaires. La
disjonction représente les différents chemins que le flot de contrôle peut suivre dans le
programme, tandis que les conjonctions représentent les ensembles de contraintes qui
sont levées sur un chemin.
Il est intéressant de noter que dans le case de motifs simples, lorsque l’on utilise pas
l’instruction « ; » et qu’il n’y a qu’une occurrence deacceptdans le programme, alors
un seul chemin de flot de contrôle est possible pour atteindre l’état accept, et ainsi,
toutes les disjonctions peuvent être simplifiées pas une analyse booléenne simple de la
contrainte générée.
Cependant, cette fonction est encore trop abstraite pour pouvoir être utilisée ou
im-plantée telle qu’elle : on a besoin pour construire les obligations de preuve du problème
de correction de la compilation du filtrage des substitutions construites par le programme
lorsqu’il atteint l’état accept. Pour rendre plus facile l’implantation, on s’autorisera à
passer en argument à la fonction d’extraction la substitution construite par l’évaluation,
et à l’appliquer aux contraintes dès que possible.
Définition 26 (Extraction des contraintes et substitutions). On obtient alors
l’algo-rithme d’extraction des contraintes et des substitutions :
C(,let(x, u, i), but) = C([x←(u)], i, but)
C(,if(e, i
1, i
2), but) = (C(, i
1, but)∧(e)≡true)
∨(C(, i
2, but)∧(e)≡false)
C(, i
1;i
2, but) = C(, i
1, but)∨(C(, i
1,refuse)∧ C(, i
2, but))
C(, i, but) = > sii=but,⊥ sinon
Dans l’ensemble de contraintes résultant de l’exécution de cet algorithme, on propage
les instanciations de variables et applique les équations de l’ancrage formel pour simplifier
les contraintes.
En pratique, cette simplification est faite durant l’extraction proprement dite des
contraintes, pour permettre la détection le plus tôt possible d’ensembles insatisfiables de
contraintes (et dont de chemins impossibles dans le flot de contrôle) afin de les supprimer.
Exemple 16. On considère comme exemple le programme résultant de la compilation
du problème de filtrageg(x, b) avec x∈ X décrit dans la sous-section 3.3.4, qui consiste
3.5. Génération des contraintes et des obligations de preuve
en un programmeπ
g(x,b)dans lequelsest la variable d’entrée. On noteraπ
g(x.b)1,π
g(x.b)2,
π
g(x.b)3etπ
g(x.b)4les sous parties de π
g(x,b).
π
g(x,b)(s),
if(is_fsym(s,pgq),
π
g(x.b)1let(x
1,subterm
g(s,1),
let(x
2,subterm
g(s,2),
π
g(x.b)3let(x, x
1,
π
g(x.b)4if(is_fsym(x
2,pbq),accept,refuse)))),
π
g(x.b)2refuse
)
On initialise l’algorithme d’extraction des contraintes de la définition 26 avec
l’envi-ronnement = [s←t]etacceptcomme but.
Une fois cette contrainte calculée comme le montre la figure 3.7, on peut l’utiliser pour
montrer la validité de la compilation du filtrage. La substitution nous donne les valeurs
des variables, tandis que les contraintes associées nous donnent l’« allure » de ces valeurs.
3.5.2. Simplification des contraintes
L’utilisation de l’algorithme de la définition 26 pour collecter les contraintes et les
substitutions générées par un programmePILproduit de très grosses formules, contenant
beaucoup de constantes>et⊥, et donc il est possible de simplifier cette formule comme
une formule booléenne.
On applique le système de règles suivant, avec une stratégieleftmost-innermost
1:
⊥ ∧x → ⊥
x∧ ⊥ → ⊥
> ∨x → >
x∨ > → >
⊥ ∨x → x
x∨ ⊥ → x
¬> → ⊥
¬⊥ → >
Ce système de réécriture simplifie les contraintes booléennes pour obtenir des contraintes
simplifiées, qui ont maintenant pour notre exemple π
g(x,b)la forme :
is_fsym(s,pgq)≡true
∧ x
1=subterm
g(s,1)
∧ x
2=subterm
g(s,2)
∧ x=x
1∧ is_fsym(subterm
g(s,2),pbq)≡true
1
On verra dans le chapitre 4 comment on aurait pu utiliserGompour faire en sorte que l’application de cette simplification soit implicite et intégrée à la structure de données
C([s←t], π
g(x,b),accept)
= C([s←t], π
g(x,b)1,accept)∧is_fsym(t,pgq)≡true
∨ C([s←t], π
g(x,b)1,accept)∧is_fsym(t,pgq)≡false
= C([s←t][x
1←subterm
g(t,1)], π
g(x,b)2,accept)∧is_fsym(t,pgq)≡true
∨ ⊥ ∧is_fsym(t,pgq)≡false
= C([s←t][x
1←subterm
g(t,1)][x
2←subterm
g(t,2)]π
g(x,b)3,accept)
∧is_fsym(t,pgq)≡true
∨ ⊥ ∧is_fsym(t,pgq)≡false
= C([s←t][x
1←subterm
g(t,1)][x
2←subterm
g(t,2)][x←subterm
g(t,1)],
π
g(x,b)4,accept)
∧is_fsym(t,pgq)≡true
∨ ⊥ ∧is_fsym(t,pgq)≡false
= C([s←t][x
1←subterm
g(t,1)][x
2←subterm
g(t,2)][x←subterm
g(t,1)],
accept,accept)
∧is_fsym(subterm
g(t,2),pbq)≡true
∨ C([s←t][x
1←subterm
g(t,1)][x
2←subterm
g(t,2)][x←subterm
g(t,1)],
refuse,accept)
∧is_fsym(subterm
g(t,2),pbq)≡false
∧is_fsym(t,pgq)≡true
∨ ⊥ ∧is_fsym(t,pgq)≡false
= C([s←t][x
1←subterm
g(t,1)][x
2←subterm
g(t,2)][x←subterm
g(t,1)],
accept,accept)
∧is_fsym(subterm
g(t,2),pbq)≡true
∨ ⊥ ∧is_fsym(subterm
g(t,2),pbq)≡false
∧is_fsym(t,pgq)≡true
∨ ⊥ ∧is_fsym(t,pgq)≡false
Fig. 3.7: Extraction des contraintes pourπ
g(x,b)Ces contraintes sont ensuite simplifiées en utilisant les définitions de l’ancrage formel,
données en définition 15 :
eq(pt
1q,pt
2q) ≡ pt
1=t
2q
is_fsym(ptq,pfq) ≡ pSymb(t) =fq
subterm
f(ptq,piq) ≡ pt
|iq si Symb(t) =f
Les égalités de l’ancrage formel peuvent être orientées pour être utilisées comme un
système de réécriture. Le but ici est de transformer une contrainte donnant des
infor-mations à propos des objets manipulés par le programme en une contrainte donnant des
informations sur les termes algébriques utilisés au niveau du code source (ceux auquel
3.6. Autres extensions : notation crochet, alias
Dans le document
Réécriture et compilation de confiance
(Page 73-77)