• Aucun résultat trouvé

Génération des contraintes et des obligations de preuve

Dans le document Réécriture et compilation de confiance (Page 73-77)

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

2

est é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

2

est elle

aussi unique, la réduction de i=i

1

;i

2

est 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 :

π

m

est une compilation correcte de m

⇐⇒

∀∈ Env,∀t∈ T(F),∀p∈ P

m

:

0

∈ Env,h, π

m

(ptq)i 7→

bs

h

0

,accept

p

i

⇔Φ(

0

)(p) =t∧(∀p

0

∈ P

m

tel 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→

bs

h

0

,accept

p

i. Cette réduction existe, et donc on ah, π

m

(ptq)i 7→

bs

h

0

,refusei.

Le second cas peut être prouvé de manière similaire.

Afin de prouver que la compilationπ

m

d’une construction multi-motif mest correcte,

on doit considérer chaque instruction accept

p

dans le programme séparément. Pour

chaque motif p dans la construction «match », on construit toutes les dérivations dans

7→

bs

qui 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)3

etπ

g(x.b)4

les sous parties de π

g(x,b)

.

π

g(x,b)

(s),

if(is_fsym(s,pgq),

π

g(x.b)1

let(x

1

,subterm

g

(s,1),

let(x

2

,subterm

g

(s,2),

π

g(x.b)3

let(x, x

1

,

π

g(x.b)4

if(is_fsym(x

2

,pbq),accept,refuse)))),

π

g(x.b)2

refuse

)

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

1

q,pt

2

q) ≡ pt

1

=t

2

q

is_fsym(ptq,pfq) ≡ pSymb(t) =fq

subterm

f

(ptq,piq) ≡ pt

|i

q 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)