Sémantique dénotationnelle
description
Transcript of Sémantique dénotationnelle
Sémantique dénotationnelleSémantique dénotationnelle
Idée :
Le sens d’un programme est un objet mathématique(souvent, une fonction)
Notation lambda ()But : une notation pour les fonctions
Ex. : la fonction qui met au carré (sqr en Pascal)
x. x * x
est une déclaration de paramètre qui suit les règles de visibilité :
x . x + sqr ((x. x + x) (x + 2))
On peut simplifier grâce aux règles :
: ( x . E) (A) se simplifie en E [A x]E où toutes les occurrences libres de x sontremplacées par A
: ( x . E(x)) se simplifie en E, si E n’a aucune occurrence libre de x
Exemple de simplificationx. x + sqr ((x . x + x) (x + 2))
portée : x. x + ( x. x * x) (( x. x + x) (x + 2))
Il y a deux endroit où s’applique : 1 , 2
1 x. x + ((x. x + x) (x + 2)) * (x. x + x) (x + 2)
3 x. x + ((x + 2) + (x + 2)) * (x. x + x) (x + 2))
4 x. x + (((x+ 2) + (x + 2)) * ((x + 2) + (x + 2)))
= x. 4x2 + 9x + 16 si on emploie les simplifications arithmétiques.
On pourrait aussi appliquer les règles dans un autre ordre : on arrive aumême résultat (Théorème de Church-Rosser)
Ex. : 2 x. x + (x. x * x) (x+2 + x+2)
1 x. x + (x+2 + x+2) * (x+2 + x+2)
1 2def.
3 4
4
1
Domaines sémantiques
Quel objet mathématique représente le sens d’un programme ?
Ceci dépend du langage considéré, et du sens qu’on lui accorde.
Ex. : Pour Pascal, on convient habituellement que :
- il devrait être déterministe (OK si on évite les effets de bord dans les fonctions)
- on ne considère que les états initiaux et finaux des fichiers
le sens est une fonction des états initiaux vers les états finaux.
Ex. : Pour les langages concurrents (Ada, LOTOS, CSP, CCS,...) les opérations intermédiaires visibles comptent aussi :
le sens est un objet plus compliqué (p.ex. des arbres)
CompositionnalitéOn veut donner un sens à chaque partie de façon à ce que le
sens d’un composé se déduise du sens de ses composants.
Avantages :
• Si deux composants ont le même sens, on peut toujours remplacer l’un par l’autre (p.ex. compilateur optimisant)
• La définition de la sémantique suivra la structure de la syntaxe.
Exemple : séquence en Pascal
• Le sens d'une instruction S, noté [[ S ]], est une fonction de
l'état initial vers l'état final
• Alors le sens d'une séquence est la composition
fonctionnelle du sens de ses composants:
• [[ S1 ; S2 ]] = x. [[S2]] ([[ S1]] (x)) = [[ S2 ]] ° [[ S1 ]]
Non-terminaison
Certains programmes bouclent pour certaines données
Ex. : la fonction factorielle pour les nombres négatifs
pour représenter cela, on ajoute une valeur spéciale
« bouclage » ou « bottom »
à l’ensemble des résultats.Comme ce résultat peut être l’argument d’un autre appel, il
faut aussi l’ajouter dans les données.
Strict
Si un paramètre est nécessaire pour évaluer une fonction, dès que l'évaluation du paramètre ne termine pas, l'appel de fonction ne termine pas non plus.
Def. : une fonction F est stricte dans son ième argument si F(x1, , …, xi-1, , xi+1, ...) =
Exemple: Pascal
Presque toutes les fonctions de la sémantique de Pascal sont strictes, parce qu'on évalue tous les paramètres avant un appel.
Exception: le sens de l'instruction if ne nécessite pas d'évaluer une des deux parties.
Etat
• On représente ici l'état d'un programme par une fonction des variables vers leur valeur
Sémantique des instructions Pascal• [[ S1 ; S2 ]] = [[ S2 ]] ° [[ S1 ]]
• [[ skip ]] = x. x
• [[ if E then S1 else S2 ]] = x.
if ([[ E ]] (x) = true) then [[ S1 ]] (x)
else [[ S2 ]] (x)
• [[ V := E ]] = x. i. if i = V then [[ E ]] (x) else x(i)
• [[ while E do S ]] = x. if ([[ E ]] (x) = true)
then [[while E do S]] ° [[ S ]](x)
else x
Récursivité• la définition du while est récursive, mais pas bien
fondée.• Comment calculer son sens ?• Ce doit être une solution de:
W = x. if [[ E ]] (x) then W ° [[ S ]](x) else x.
• Cette équation peut avoir plusieurs solutions, mais une seule est intuitive.
• Les solutions sont appellées points fixes de:
F = W. x. if [[ E ]] (x) then W ° [[ S ]](x) else x.
Ordre d’information
• Pour comparer les solutions et choisir la plus naturelle, on définit un ordre partiel
• X Y se lit
« Y contient au moins l’info de X »
ou
« X approxime Y »
Bouclage
Considérons le programme f(x) = f(x)+1
Cette équation n’a pas de solution dans les nombres
Le programme boucle à l’exécution
On ajoute une valeur spéciale qui représente le fait qu’un programme boucle.
= +1 est alors la seule solution.
Ordre partiel
Un ordre partiel est une relation:• Réflexive: X X • Transitive: X Y et YZ implique X Z• Antisymétrique: XY et YX implique X=Y
Supremum
• Un majorant de Y est un élément b plus grand que tous ceux d'Y:
bMaj(Y) = yY, yb• Un majorant plus petit que les autres est le
supremum de Ys=sup(Y)
ssi s Maj(Y) et m Maj(Y), sm
Chaîne
Une chaîne est une suite croissante
(xi)i N telle que xixi+1
Domaine
Un domaine ou ordre partiel complet (CPO)est un ensemble X muni d'un ordre partiel • X contient un minorant • Toute chaîne de X a un supremumIntuition:• Un programme qui boucle ne fournit aucune info:
X• On peut représenter l’info accumulée par un
programme par le supremum de ses calculs partiels
CPO plat
Pour les valeurs classiques, on ajoute juste en dessous: x y ssi x = ou x =y
Par exemple: les entiers avec , noté ZZ, est obtenu ainsi.-4 -3 -2 -1 0 1 2 3 4
Exercice: est-ce bien un CPO?
CPO Union disjointe
Si on a deux CPOs A, B on forme le type union disjointe de A et B en rajoutant encore un en-dessous:
A+B
BA
Indique une valeur inconnue
Indique une valeur inconnue de B
A B
Ordre ponctuel
Pour les fonctions, on emploie l’ordre ponctuel:
f DC g ssi xD, f(x) Cg(x)
L’élément minimum est la fonction qui renvoie toujours .
Fonction monotone
• Une application entre CPOs est monotone si elle préserve l'ordre :
Si x y alors f(x) f(y)
Théorème de Tarski
Si F est une application monotone d’un CPO dans lui-même, elle a un plus petit point fixe, noté fix(F).
Continuité pour l’ordre
Une fonction f est continue si elle préserve les suprémums:
Pour toute chaîne C: f(sup (C) ) =sup(f (C))
Attention cette continuité n’est pas celle de la topologie usuelle sur les nombres rééls!
Avec cette déf, toute fonction continue est monotone.
Théorème de Scott
Si f est une application continue d’un CPO dans lui-même, son plus petit point fixe peut se calculer en itérant f à partir de
, f(), f(f()), f(f(f())), …
et en prenant le supremum
fix(f) = supi(fi())
où fi(x) note f(f(…f(x)))
Preuve
1. Ce supremum est un point fixe
= f0() f() puisque CPO
fi() fi+1() par monotonie
(fi()) i N est une chaîne, donc a un supremum s = supi(fi())
f(s) =f(supi(fi())) = supi(f(fi())) = s
Preuve (2)
Il est le plus petit: Soit v un autre point fixe v puisque CPO
fi() fi(v) = v par monotonie càd v majorant
s v def. supremum
Exemple
Quel est le sens de la fonction récursive ML:f b = if b then 3 else 2*f(b) f : bool intC’est le plus petit point fixe de H:H f b = if b then 3 else 2*f(b)On le calcule par la chaîne:H = if b then 3 else H(H ) = if b then 3 else Donc, i>0, Hi = if b then 3 else = fix H = [[f]]
Continuité
Pour appliquer le théorème de Scott, il faut que la fonction soit « continue »
En pratique: toute fonction écrite en ML, Pascal, … est continue.
Schéma de preuve: • Les fonctions de base sont continues• La composition préserve la continuité• Un point fixe d’une fonctionnelle continue est
continu.
Exemple de point fixe
Quel est le sens de f n = n+(if n=0 then 0 else f(f(n-1))
R: le plus petit point fixe deH f n = n+(if n=0 then 0 else f(f(n-1))
H0 n = H1 n = n+(if n=0 then 0 else )
= if n=0 then 0 else H2 n = n+(if n=0 then 0 else H1 (if n-1=0 then 0 else ))
= n+(if n=0 then 0 else if n=1 then 0 else )= if n=0 then 0 else if n=1 then 1 else
…
Exemple de point fixe
H3 n = H(H2 ) n = n+(if n=0 then 0 else H2 (H2 (n-1))
= n+(if n=0 then 0 else H2 (if n-1=0 then 0 else if n-1=1 then 1 else ))
= if n=0 then n+0 else if n=1 then n+ H2 0 else if n=2 then n+ H2 1 else
= if n=0 then 0 else if n=1 then 1 else if n=2 then 2+ H2 1 else
= if n=0 then 0 else if n=1 then 1 else if n=2 then 3 else
Exemple de point fixeH4 n = H(H3 ) n = n+(if n=0 then 0 else H3 (H3 (n-1))
= n+(if n=0 then 0 else H3 (if n-1=0 then 0 else if n-1=1 then 1 else if n-1=2 then 3 else ))= if n=0 then 0 else if n=1 then n+ H3 0 else if n=2 then n+ H3 1 else if n=3 then n+ H3 3 else = if n=0 then 0 else if n=1 then 1 else if n=2 then 3 else if n=3 then else = if n=0 then 0 else if n=1 then 1 else if n=2 then 3 else = H3 n : le point fixe est atteint
Interprétation Abstraite
L’interprétation abstraite est une technique pour calculer des propriétés d’un programme.
En principe ces propriétés se déduisent de la sémantique du programme, mais celle-ci est trop coûteuse à calculer.
On ne calcule donc que les propriétés qui nous intéressent;Le plus souvent ceci amène à faire des approximations.La sémantique sert à trouver et prouver ces approximations.
W447
Interprétation Abstraite: cadre1. Une sémantique dénotationnelle compositionnelle
[[ . ]] : programme Domaine standard A
Chaque construction f du langage a sa sémantique fA
2. On veut construire une sémantique abstraite compositionnelle qui retient les propriétés à calculer
Abs : programme Domaine abstrait B
avec une relation «est représenté par » entre les deux domaines :
- compatible : si a b , alors fA(a) fB(b)
- continue : si supi(ai) = a, supi(bi) = b, iNN ai bi, alors a b
W470
Exemple: Signe
On veut que le compilateur calcule, si possible, le signe des expressions entières
Domaine standard = ZZ
Domaine abstrait = {0, p, n, ?}
0 représente 0: 0 p représente les nombres positifs: z p ssiz>0
n représente les nombres négatifs: z n ssi z<0
? représente tout le domaine abstrait: z
n 0 p
?
Exemple: Signe: fonctions abstraites
On construit les meilleures approximations des 4 opérations:
* p 0 n ?
p p 0 n ?
0 0 0 0 0
nn 0 p ?
? ? 0 ? ?
+ p 0 n ?
p p p ? ?
0 p 0 n ?
nn n ?
? ? ? ? ?
p 0 n ?
p ? p p ?
0 n 0 p ?
nn n ? ?
? ? ? ? ?
/ p 0 n ?
p p err n ?
0 0 err 0 0
nn err p ?
? ? err ? ?
est continue (les chaînes sont finies).
Exemple: Signe: point fixe
i := 1;
f := 1;
while i<v do begin
f := i*f;
i := i+1;
end
Le compilateur utilise des états abstraits
Si n est positif à l’entrée de ce programme, il calcule que f et n seront positifs à la sortie.
Avant la boucle:
Après la boucle, par point fixe:
i f v
p p p
i f v
p p p
D’autres applications de l’interprétation abstraite
L’interprétation abstraite permet au compilateur de calculer des réponses approchées à des questions comme:
• Des variables sont-elles synonymes ?• Des structures de pointeurs ont-elles des cellules
partagées ?• Une fonction est-elle stricte ?• Une fonction a-t-elle des effets de bord ?• Une variable a-t-elle un effet sur une autre ?• Combien de temps prend un programme ?• Calculs sur les grammaires (voir plus loin)
Sémantique des grammaires non contextuelles
Le sens d’un non-terminal X dans une grammaire G = (S, VN, VT, P)
est l’ensemble des textes corrects pour X, càd {w VT* | X * w }.
Les règles d'une grammaire sont récursives: la théorie du point fixe convient donc pour
leur donner un sens.
Si on suppose qu'on a donné un sens à chaque non-terminal (càd on a une fonction de VN
P(VT*) ) alors on peut l'utiliser dans les règles de la grammaire pour calculer un
nouveau sens. Le plus petit point fixe donne la sémantique de chaque non-terminal.
La sémantique du symbole initial donne le langage de la grammaire. L'ordre utilisé
est l'ordre sur les vecteurs d'ensembles:
A1 (X) A2 (X) ssi X VN, A1 (X) A2 (X)
Continuité
Toutes les grammaires définissent une fonction "continue" pour l'inclusion. En effet, le supremum pour l'inclusion est simplement l'union (infinie).
Les grammaires BNF sont écrites avec les 4 opérateurs:
union, . suivi de, a symbole terminal, chaîne vide.
On peut montrer qu'ils sont continus, p.ex.: Donc
(i Li ).M = {x.y | i. xLi et yM} = i ( Li .M)
Donc le langage peut se calculer par point fixe.
Exemple
La grammaire P
A ::= a A c | B
B ::= b B | C
C ::= | C
= {A=, B=, C=}[[P]] = {A=, B=, C=}[[P]]2 = {A=, B= , C= }[[P]]3 = {A= , B= {,b}, C= }[[P]]4 = {A= {ac,,b}, B= {,b,bb}, C= }On généralise:[[P]]n = { A = {ai bj ci | i+j n-3},
B = { bj | j n-2}, C= si n 1, C= sinon }
On fait la preuve par inductionPuis le passage à la limite:fix [[P]] = { A = {ai bj ci }, B = { bj }, C= }
Interprétation abstraite de grammaires
Le calcul des k premiers symboles terminaux (voir chap.2) est une interprétation abstraite.
L'opérateur . (suivi de) est donc abstrait en une concaténation bornée à k symboles. Les autres sont inchangés.
Le domaine abstrait des langages bornés à k caractères a des chaînes finies, donc le calcul du point fixe converge finiment.