TD 5 Sémantique opérationnelle et points fixes Aspects Impératifs

publicité
Université de Provence
M1 Informatique- Logique, Déduction, Programmation
2008 – 2009
TD 5
Solange Coupet-Grimal
Sémantique opérationnelle et points fixes
On se donne, à partir de l’environnement initial Caml E0 , les définitions suivantes:
let a =3;;
let rec liste = fun n -> if n = 0 then [] else a::(liste (n-1));;
let a = 1;;
1. Donner l’état de l’environnement courant après chaque définition.
2. Décrire avec précision chaque étape de l’évaluation de liste (a+a) dans le dernier environnement obtenu à la question précédente.
3. Quelle est la réponse affichée par Caml après:
let resultat() = liste (a+a);;
puis après : resultat;; puis enfin après : resultat();;
4. Définir une fonctionnelle F dont liste est point fixe.
5. Reprogrammer liste comme point fixe de F.
6. Décrire les étapes de l’évaluation de liste (a+a) avec cette nouvelle définition.
Aspects Impératifs
Question 1 Ecrire une fonction qui imprime à l’écran une liste d’entiers, séparés par une virgule
suivie d’un caractère blanc. Plus précisément on devra obtenir:
#print_list [12; 187; 0];;
12, 187, 0
- : unit = ()
Question 2 Ecrire une fonction qui imprime à l’écran une matrice d’entiers, représentée sous
forme de listes de listes. On écrira deux fonctions, produisant les effets suivants:
print_matrice [[1;23;251]; [12;4; 975]; [4321; 11; 0]; [0;0;0]];;
1
23
251
12
4
975
4321 11
0
0
0
0
- : unit = ()
print_matrice’ [[1;23;251]; [12;4; 975]; [4321; 11; 0]; [0;0;0]];;
1
23
251
12
4
975
4321
11
0
0
0
0
- : unit = ()
Termes Formels
On considère dans cet exercice le type tree des arbres quelconques défini par:
type ’a tree = Tr of ’a* ’a tree list;;
On s’intéresse, dans un premier temps, à des expressions définies par un type récursif simple,
dont les constructeurs s’appliquent sur un certain nombre d’arguments du même type. Le type ty
suivant en est un exemple:
type ty = A | B of ty | C of ty*ty;;
Question 1 Ecrire la fonction tree of ty qui calcule l’arbre syntaxique d’une expression de type
ty. Par exemple, on devra obtenir l’évaluation suivante:
#tree_of_ty (C(B(C(A, A)), B(A)));;
- : string tree =
Tr
("C",
[Tr ("B", [Tr ("C", [Tr ("A", []); Tr ("A", [])])]);
Tr ("B", [Tr ("A", [])])])
Réciproquement, on se propose de déterminer si un arbre donné est, ou n’est pas, l’arbre syntaxique
d’une expression d’un certain type récursif simple. Il faut en particulier vérifier si le nombre de fils
d’un noeud correspond bien à l’arité de l’étiquette. Pour cela on se donne une liste de signatures,
qui indique le nombre d’arguments de chaque constructeur. Avec l’exemple du type ty, la liste des
signatures est la suivante:
#let sig1=[("A",0);("B",1);("C",2)];;
sig1 : (string * int) list = ["A", 0; "B", 1; "C", 2]
De façon générale, une signature pour un type récursif simple sera du type ’a*int list.
Question 2 Ecrire une fonction arity qui étant donné un constructeur et une liste de signatures,
permet de rechercher l’arité d’un constructeur. Si le constructeur ne figure pas dans la liste, on
devra lever une exception Sig error que l’on aura définie au préalable.
Question 3 Ecrire une fonction correct qui étant donnée une liste de signatures et un arbre,
renvoie un booléen indiquant s’il s’agit de l’arbre syntaxique d’une expression correcte.
On considère maintenant le cas des types mutuellement récursifs, comme par exemple les types:
#type ty1 = A|B of ty1*ty2 and
ty2 = C|D of ty2*ty1;;
Type ty1 defined.
Type ty2 defined.
Question 4 Ecrire des fonctions tree of ty1 et tree of ty2 analogues à la fonction tree of ty
de la question 1. On devra obtenir par exemple l’exécution suivante:
#tree_of_ty1 (B(A,D(C,A)));;
- : string tree =
Tr ("B", [Tr ("A", []); Tr ("D", [Tr ("C", []); Tr ("A", [])])])
De tels types sont caractérisés par une liste de signatures, associant à chaque constructeur son
type, et la liste des types des arguments. L’arité est inutile, ce n’est autre que la longueur de la
liste des types des arguments. Pour ty1 et ty2 on obtient:
#let sig2 = [("A",([],"ty1"));("B",(["ty1";"ty2"],"ty1"));("C",([],"ty2"));
("D",(["ty2";"ty1"],"ty2"))];;
sig2 : (string * (string list * string)) list = ...
Question 5 Ecrire une fonction get type qui étant donnée une liste de signatures et un constructeur renvoie la signature de ce constructeur en renvoyant éventuellement l’exception Sig error si
ce constructeur ne figure pas dans la liste.
Question 5 Ecrire une fonction typing qui étant donnée une liste de signatures et un arbre
renvoie le type de l’expression représentée par l’arbre s’il est correct et une exception sinon. On
devra par exemple obtenir les évaluations suivantes:
#typing sig2 (Tr ("B", [Tr ("A", []); Tr ("D", [Tr ("C", []); Tr ("A", [])])]));;
- : string = "ty1"
#typing sig2 (Tr ("A", [Tr ("A", []); Tr ("D", [Tr ("C", []); Tr ("A", [])])]));;
Uncaught exception: Sig_error
Ici, le typage de ”A” n’est pas bon.
#typing sig2 (Tr ("E", [Tr ("A", []); Tr ("D", [Tr ("C", []); Tr ("A", [])])]));;
Uncaught exception: Sig_error
Ici, ”E” n’existe pas.
Question 6 Ecrire une fonction qui étant donnée une liste de signatures et une liste l d’arbres,
renvoie true si tous les arbres de la liste sont bien typés et f alse sinon.
Téléchargement