Termes et relations pour la sémantique
La sémantique ?
fun x -> x * x
» est une expression bien
formée
(en Caml), mais pas « +(
».
1 - 2 - 3 | → |
Savoir que « My taylor is rich » est bien de l’anglais ne suffit pas.
Savoir que « fun x -> x * x
» est bien du Caml ne suffit pas.
On veut en plus savoir ce qui se passe quand on applique ce programme
(cette fonction) à une entrée.
(fun x -> x * x)
, 4
↪ 16
Définir la sémantique c’est définir une relation P, e ↪ v, où P est un programme (ici syntaxe abstraite), e est une entrée (ici une valeur) et v le résultat (ici une valeur).
Si à P et e donnés correspond un unique v, on définit une fonction.
Mais comment définir ↪ ? langue naturelle ou mathématiques ?
Une évidence : pour bien programmer il faut savoir ce que font les programmes.
Or ce n’est pas toujours évident,
Pourtant on essaie quand même de spécifier le comportement des programmes en langue dit naturelle (français, anglais…).
Quel est l’affichage ? « 2 », car en Java les arguments sont évalués de la gauche vers la droite, comme précisé dans la définition du langage.
Si on essaie (ranger dans test.ml et exécuter ocaml test.ml), on obtient 9.
Ici attention, la documentation de OCaml précise que l’ordre d’évaluation des arguments n’est pas spécifié.
Le programme affiche : « 2 ».
On comprend un peu mieux en réécrivant :
Ce sont :
La sémantique est indispensable pour…
Soit la fonction f :
Peut-on « optimiser » tout appel f e1 e2
en e1
?
Non, car par exemple
Mais on peut transformer :
f e1 e2
⇒ let x = e1 and y = e2 in x
The while statement executes an Expression and a Statement repeatedly until the value of the Expression is false.
WhileStatement: while ( Expression ) Statement
A while statement is executed by first evaluating the Expression. If the result is of type Boolean, it is subject to unboxing conversion (§5.1.8). If evaluation of the Expression or the subsequent unboxing conversion (if any) completes abruptly for some reason, the while statement completes abruptly for the same reason. Otherwise, execution continues by making a choice based on the resulting value:
If the (possibly unboxed) value of the Expression is false the first time it is evaluated, then the Statement is not executed.
La suite dans la documentation de Java.
Dans ce cours…
type t = int
.
type t = int * int
.
{ x ∈ ℕ ∣ ∃ z ∈ ℕ, x = 2 × x } { (x,y) ∈ ℕ2 ∣ ∃ z ∈ ℕ, x = y × z } |
Preuve : Considérer limfi(⊥), c’est le plus petit point fixe
de f.
Soit ui = fi(⊥).
Soit p sa limite.
[0,1], ≤ est faiblement complète.
ℝ+ faiblement complète ?
Preuve : la borne inférieure de C = { c ∣ f(c) ≤ c }
est le plus petit point fixe de f.
Soit p borne inférieure des « contractés » C = { c ∈ E ∣ f(c) ≤ c }.
Plus petit point fixe, car tous les points fixes sont dans C.
[0,1], ≤ est fortement complète.
ℝ+ fortement complète ?
P ensemble des entiers pairs peut être défini par les règles suivantes.
|
|
Que l’on note plutôt.
|
|
|
|
|
Autrement dit, P contient 0 et P est clos par la fonction n ↦ n+2.
Il est remarquable que P n’est pas le seul ensemble satisfaisant ces deux propriétés, par ex. ℕ convient.
Alors ? P est le plus petit de ces ensembles.
Soient les fonctions f1 : ℕ0 → ℕ, qui à () associe 0 ; et f2 : ℕ → ℕ, qui à x associe x+2.
Soit ensuite F : 2ℕ → 2ℕ qui à X associe :
{ y ∣ y = f1() } ⋃ { y ∣ ∃ x ∈ X, f2(x) = y } |
Soit si on veut :
F(X) = { 0 } ⋃ { x+2 ∣ x ∈ X } |
F est…
Les deux règles définissent donc un ensemble d’entiers P, qui est le plus petit point fixe de F.
Et au passage P est l’ensemble des entiers pairs (2ℕ), en effet.
Mais ce qui compte c’est que nous avons pu définir un ensemble (d’entiers) inductivement.
Pour tout ensemble E. On peut définir un sous-ensemble A de E par des fonctions fk (eventuellement partielles) de Enk dans E, souvent notées comme les règles :
|
Ce sous-ensemble est le plus petit point fixe de la fonction F de 2E dans 2E.
F(X) = |
| { fk(x1, …, xnk) ∣ x1, …, xnk ∈ Xnk} |
C’est aussi le plus petit ensemble clos par les règles.
Cela permet en particulier de définir des relations, qui sont des ensembles (de paires par ex.)
Soit Σ alphabet (ensemble de caractères notés a, b)
Soit Σ⋆ ensemble des mots (suites finies sur Σ, notés m, n).
Relation de facteur m ≼ n
|
|
|
|
|
Une dérivation ou arbre de preuve est un arbre dont les nœuds sont l’application des règles (les fk).
L’existence d’une dérivation aboutissant en e prouve que e est dans Fi(∅) (et donc dans le plus petit point fixe).
Par ex, ac ≼ abcde.
|
Réciproquement, tout élément du plus petit point fixe est l’aboutissement d’une dérivation (récurrence sur i).
Pour prouver une propriété P des éléments du plus petit point fixe.
Il peut suffire de montrer que P est héreditaire, c’est à dire P(x1), …P(xnk) entraîne P(fk(x1,…,xnk)).
Preuve L’ensemble { e ∈ E ∣ P(e) } est clos par F et second théorème.
Par ex. pour montrer que si m est un facteur de n, alors m est plus court que n :
|
|
|
|
Conséquence directe des propriétés de la longueur ℓ(є) = 0 et ℓ(m1m2) = ℓ(m1) + ℓ(m2).
Nous avons enfoncé une porte ouverte en prouvant que les règles
|
|
définissent bien l’ensemble des entiers pairs.
En effet, si n ∈ P alors n est pair (induction structurelle). Réciproquement, pour tout n = 2k, il existe une dérivation.
On pourrait de même enfoncer une porte (un peu moins) ouverte
en démontrant que m ≼ n, ssi
m est une sous-suite de n au sens usuel.
Soit une relation R, binaire, sur un ensemble E (donc un sous-ensemble du produit cartésien E × E).
On définit R*, la fermeture reflexive et transitive de R inductivement :
|
|
|
Il est assez immédiat que
|
(Induction structurelle.)
Nous avons déjà dit que l’expression (Caml par ex.) « 1-2-3
»
est pour nous le terme :
De même, nous lisons « f x y
», nous comprenons (application
explicitée) :
Mais sommes nous bien sûrs de savoir ce qu’est un terme ?
|
Et les expressions arithmétiques sont définies.
Une définition à peu près équivalente en Caml.
Quand on veut écrire une expression arithmétique sans dessiner un
arbre, il est préférable de donner (presque) toutes les parenthèses.
t = -(-(1,2),3) ou encore t = (1-2)-3 |
Définir une sémantique des expressions arithmétiques, c’est définir une relation e ↪ n entre les expressions et les entiers.
Nous donnons trois techniques.
Au symbole n on associe l’entier n, au symbole + on associe l’addition (fonction ℕ2 dans ℕ, notée +)
|
|
|
Une trivialité, mais
Certes la présentation par règles d’inférences est plus neutre.
On définit donc la relation → sur les expressions, par une infinité d’axiomes :
|
|
|
|
Puis par huit règles d’inférence (qui ici définissent une congruence : ou peut réduire tout sous-terme).
|
|
|
Et on pose ↪ = →*.
Note : Les valeurs sont maintenant nécessairement un sous-ensemble des expressions.
C’est une fonction des expressions dans les entiers, définie explicitement.
|
|
Les différences avec la sémantique naturelle n’apparaissent que sur des exemples plus compliqués.
|
Est la « vraie » fonction sur ℕ, qui à x associe le successeur de x.
Est la factorielle : 0 ↦ 1, 1 ↦ 1 × 1, 2 ↦ 2 × 1 × 1, …n ↦ n × (n−1) × ⋯ × 1 × 1, …
Comment donner une valeur à par exemple « x+x » ?
Simple ! Il suffit de remplacer x par un terme fixé. C’est la substitution [e\x].
Un premier exemple simple : expressions arithmetiques + variables.
|
|
|
|
Et donc [1+1\x](x+x) = (1+1)+(1+1).
Noter : « = » et non « », c;est une meta-opération (i.e. [ex\x]e ne fait pas partie de la syntaxe des termes).
Nous avons déjà écrit par exemple n ↦ n + 2.
En Caml on écrit : « fun n -> n+2
».
Il est remarquable que m ↦ m + 2 et fun m -> m+2
désignent la
même fonction : la variable est muette.
L’expression fun x -> e
, où x est une variable
(ci-dessus n
ou m
) et e est une expression
(ci-dessus n+2
ou m+2
), est à comprendre comme l’arbre :
Vocabulaire :
On dit que la construction fun
lie la variable x dans la
sous-expression e. L’occurence de x dans e est ici libre.
Un autre exemple (Caml) est « let x = ex in e
»,
à lire comme :
où x est liée dans le sous-terme e.
Considérer aussi : « let rec x = ex in e
»,
où x est liée dans ex et e.
Une expression e est :
Dans let x = ex in e, x est liée dans e.
Définies par induction sur la structure des expressions.
|
|
|
|
|
Ce sont les variables non-liées, c’est-à-dire celles dont la valeur doit être fournie.
F(x+1 ) | = | { x } |
F(x+1+y ) | = | { x, y } |
F(let x = 1 in x+1 ) | = | ∅ |
F(let x = 1 in x+1+y ) | = | { y } |
|
|
|
|
|
Et aussi,
|
Une expression peut maintenant contenir des variables (libres).
Une solution simple : l’environnement. La relation sémantique est maintenant de la forme
Γ ⊢ e ↪ v |
Où ici,
|
|
|
|
Un environnement est une liste de paires x × v.
Comment définir → (une étape de calcul) sur
un terme qui contient let ?
L’idée est que on peut effectuer la liason
let x = ex in e
en remplaçant x par ex dans e.
Une substitution est tout simplement une fonction (de domaine fini) des variables dans les… termes. On note [ex\x] la substitution qui à x associe ex.
Les substitutions sont des morphismes, c-à-d respectent la structure de terme.
Les substitutions s’appliquent aux variables libres seulement :
[2\x] (x+1) | = | 2+1 |
[2\x] (fun x -> x+1) | = | fun x -> x+1 |
[2\x] (let x = x+x in x) | = | let x = 2+2 in x |
Remplacer les variables libres par leurs définitions :
|
|
|
|
|
|
|
Et de même :
|
|
Il semble donc que l’on puisse réduire
let x = ex in e
en [ex\x] (e).
Soit la fonction qui ajoute y libre à son argumemt.
Sous-expression par exemple de :
En substituant…
fun x -> x + 4
.
fun x -> x + z
.
fun x -> x + x
?Il ne vaut meux pas ! Considérer :
Dans l’exemple [x\y](fun x -> x+y),
nous sommes victimes de la capture de la variable libre x,
qui devient liée en traversant la liaison fun x ->
…
Or
fun z -> z + y
) =
fun z -> z + x
.
fun x -> x + y
et fun z -> z + y
sont
les mêmes (changement de la variable muette).
L’alpha-équivalence est l’égalité modulo le changement des variables muettes.
En évitant les captures.
|
|
Où z ci-dessus n’appartient ni à F(ex), ni à F(e2).
C’est bien compliqué.
En pratique : z est une variable « fraiche », c’est à dire une variable nouvelle.
Pas le plus efficace, certainement… Mais suffisant pour définir le calcul sur le let.
Pour définir une étape de calcul, il reste à
Ce document a été traduit de LATEX par HEVEA