1 Noyau fonctionnel : rappels
Le noyau fonctionnel d’un langage est construit sur le mod`ele du λ-calcul. Pour construire le fragment
correspondant, on se donne un ensemble de symboles atomiques contenant des constantes et des variables.
Les expressions du langage sont d´efinies par les trois clauses suivantes :
1. Tout symbole atomique est une expression.
2. Si e, e1,...ensont des expressions, alors l’application (e e1...en)est une expression.
3. Si x1, . . . , xnsont des symboles de variable et si eest une expression, alors l’abstraction
(fun x1...xn=> e)est une expression.
C’est la fonction de param`etre x1. . . xnet de corps e.
On d´efinit sur ce langage une notion d’´evaluation symbolique qui transforme une expression en une autre :
on note e →e2. L’´evaluation symbolique repose sur la notion de substitution pour mod´eliser l’application
d’une fonction (fun x=> e1)`a une expression e2:
((fun x=> e1)e2)s’´evalue en e1[e2/x]
On notera : ((fun x=> e1)e2)→e1[e2/x]
La substitution e1[e2/x] est d´efinie selon la forme de e1:
– si e1est la variable x, alors x[e2/x] = e2;
– si e1est un symbole atomique adiff´erent du symbole de variable x, alors a[e2/x] = a;
– si e1est l’application (e0
1e00
1), alors (e0
1e00
1)[e2/x] = (e0
1[e2/x]e00
1[e2/x]);
– si e1est l’abstraction (fun x=> e0
1), alors (fun x=> e0
1)[e2/x] = (fun x=> e0
1);
– si e1est l’abstraction (fun y=> e0
1)o`u yest un symbole de variable diff´erent de x, alors
(fun y=> e0
1)[e2/x] = fun z=> e0
1[z/y][e2/x].
Dans la derni`ere clause, on remplace le symbole de variable ypar un symbole zdiff´erent de yet choisit
parmi les symboles qui n’apparaissent ni dans e0
1ni dans e2afin d’´eviter le ph´enom`ene dit de capture de
variable. En effet, les fonctions (fun x=> (e x)) et (fun y=> (e y)) sont ´egales : on peut donc changer
le symbole des variables li´ees par l’abstraction fun. Mais on ne peut pas choisir n’importe quel symbole pour
effectuer ce renommage. En effet, les fonctions (fun x=> (f x y)) et (fun y=> (f y y)) ne sont pas
´egales. Ici, le yde la premi`ere expression a ´et´e captur´e par le changement de nom, ce qu’il faut donc bien
interdire.
2 R´ecurrence structurelle avec les listes
Le type des listes param´etr´ees (listes polymorphes) est d´efini comme l’ensemble des valeurs obtenues avec les
constructeurs nil et cons. Le constructeur nil est une constante (pas d’argument). Le constructeur cons
est un op´erateur binaire qui ajoute un ´el´ement `a une liste.
En Coq, ce type est d´efini de la mani`ere suivante
Inductive list {A:Set}: Set :=
nil : (list A)
| cons : A -> (list A) -> (list A).
Soit donc Aun type quelconque, soit a1,a2et a3, trois valeurs de type A, la liste contenant ces trois valeurs,
dans cet ordre, est repr´esent´ee par l’expression (cons a1(cons a2(cons a3nil))) ; la liste contenant
ces trois valeurs, mais dans l’ordre inverse, s’´ecrit (cons a3(cons a2(cons a1nil))). La liste nil est
la liste qui ne contient aucune valeur appel´ee la liste vide.
Par d´efinition, une liste est soit la liste vide (nil), soit une liste non vide. Dans ce cas, elle contient un
premier ´el´ement et se poursuit par la liste de ces autres ´el´ements. Une liste non vide peut donc toujours
2