⋆⋆⋆ |
Question 1. Donner un terme de PCF t1, dont l’exécution termine en appel par nom et ne termine pas en appel par valeur ; puis un terme t2 dont l’exécution ne termine pas en appel par nom.
Question 2. Donner un terme t1 typable selon Damas et Milner mais pas selon Hindley (sections 6.2 et 6.1 du poly). Puis un terme t2 non-typable selon Damas et Milner.
Question 3. On propose les définitions suivantes pour un toplevel PCF.
Donner les schémas de types de ces trois définitions selon le système de Damas et Milner. Puis donner une instance commune à ces trois schémas de types. On choisira cette instance de sorte que toutes les instances communes aux trois termes s’en déduisent par substitution de variables de type.
b_true
est
∀ X,Y[X -> Y -> X],
celui de b_false
est ∀ X,Y[X -> Y -> Y], et celui
de b_loop
est ∀ X[X].L’instance « principale » commune demandée est X -> X -> X.
Question 4. Que peut-on dire de l’exécution d’un terme t tel que ⊢ t:X (le terme t a le type X dans l’environnement de typage vide). La réponse sera justifiée par l’emploi d’un théorème du cours.
Question 5. On considère d’abord l’extension de la syntaxe abstraite. Les termes additionnels sont définis par les symboles additionnels suivants.
Donner une déclaration en Caml du type des termes de PCF étendu, en étendant la définition donnée en annexe.
Question 6. Donner la sémantique à grand pas des nouvelles constructions, sous forme de jugements t↪v (section 2.4 du poly). On notera les points suivants :
|
|
|
|
|
|
|
|
|
|
Question 7. Exprimer !t, t1 && t2 et t1 || t2 uniquement à l’aide du If, des constantes True et False, et de PCF non-étendu. La sémantique donnée à la question précédente doit être respectée, sans que vous ayez à le prouver (cf. question suivante). La réponse à cette question peut servir à simplifier un interpréteur ou un compilateur de PCF étendu.
|
Question 8. Prouver que votre traduction de t1 && t2 est correcte vis à vis de la sémantique donnée à la question 6. C’est-à-dire, en notant T(t1,t2) votre réponse à la question précédente, prouver l’équivalence :
t1 && t2↪v ⇔T(t1,t2)↪v |
Montrons d’abord que t1 && t2↪v ⇒ T(t1,t2)↪v
|
|
|
Réciproquement, on suppose T(t1,t2)↪v. Puisque T(t1,t2) est un terme If, il n’y a que deux règles possibles selon que l’on a t1↪True ou t1↪False.
Remarque : Cela peut paraître un peu piéton. Mais il faut effectivement faire très attention dans ce genre de preuve. Suppons par exemple la définition suivante de T(t1,t2) (que l’on trouve dans beaucoup de copies).
If t1 Then If t2 Then True Else False Else False |
Alors l’équivalence est fausse. Contre-exemple : supposer t1↪True et t2↪10, alors d’une part,
|
Et d’autre part, on ne peut pas prouver :
If t1 Then If t2 Then True Else False Else False↪10 |
Puisque la valeur du terme ci-dessus ne peut être que True ou False. Or si on procède trop rapidement, on risque de ne pas remarquer ce détail.
Au passage, on peut proposer cette traduction, mais alors il faut considérer une autre sémantique, exprimée par exemple ainsi :
|
|
|
Remarque encore : Le correcteur connaît le résultat, ce qu’il veut savoir c’est si vous savez prouver le résultat. Votre but est de l’en convaincre.
De quelles techniques de preuve disposons nous ?
Question 9. Écrire en Caml l’interprétation des nouvelles constructions. On procédera par extension de l’interpréteur (en appel par valeur) donné en annexe. On détaillera les modifications apportées au type value, à la fonction print_value et à la fonction interv.
Extension du type des valeurs
Nouvelle fonction print_value
Nouvel interpréteur
Avec la définition suivante de la fonction mutuellement récursive
inter_bool
(à la fin)
Remarque Notre interpréteur ne respecte pas la sémantique de la question 6 sur un point : si la valeur de t1 est True et que la valeur v de t2 existe mais n’est pas un booléen, alors l’interprétation de t1 && t2 échoue — alors que la semantique donne la valeur v. Ce point est mineur (on peut n’interpréter que des termes bien typés) et surtout traité dans une question ultérieure 12.
Un point plus important est bien traité : si la valeur de t1 est False,
alors la valeur de t1 && t2 est également False, quelque
soit le comportement de t2 (valeur booléene, valeur autre, non-terminaison).
Ce bon comportement découle directement de la sémantique de &&
en Caml.
Ce point est plus important car il comprend le cas significatif
d’un terme t2 de type
Bool (Question 11) dont l’évaluation ne termine pas.
Remarquons encore que nous pouvons écrire un interpréteur complètement conforme.
Ou même…
Question 10. Proposer un schéma de compilation (section 4.4 du poly) pour les nouvelles constructions vers la machine ASEC du cours non-modifiée. On pourra considérer, comme c’est l’usage, que la représentation machine du booléen False est l’entier zéro.
|
|
|
Il reste à exploiter la question 7. Voici par exemple la compilation de t1 && t2.
|
Question 11. Soit Bool, le type des booléens. Donner les règles de typage des nouvelles constructions, dans le style des jugements E ⊢ t:A de la section 6.1 du poly. Les règles de typage seront les règles usuelles, qui correspondent par exemple à celles de Java ou de Caml.
|
|
|
|
|
|
Question 12. Soit le terme (True && 2) + 1
.
Ce terme est-il typable selon les règles de la question précédente ?
Que se passe-t-il lors de l’exécution avec votre interpréteur ?
Avec votre compilateur ?
L’interpréteur échoue lors du calcul de True && 2 car il évalue
2 comme Num_v 2
– plus précisément c’est
l’appel inter_bool (Num 2)
qui va échouer.
Le code ASEC en revanche s’exécute sans erreur et calcule la valeur
entière 3.
Remarque : Ni l’interpréteur, ni la machine ASEC ne « vérifient les types », ils ne disent rien par ex. du terme 1 + True. Tous deux commencent à évaluer le terme, et réagiront lorsqu’une erreur de type empêche l’exécution de se poursuivre. — notons au passage que ces erreurs sont définies sur les valeurs et non sur les termes.
Dans le cas de la machine ASEC, aucune erreur ne se produit, mais le résultat rendu est non-conforme à la sémantique.
Question 13. Le domaine de booléens de Scott B est constitué de trois valeurs ⊥B, true et false, avec ⊥B ≼ true et ⊥B ≼ false. On interprète le type Bool comme étant B. Dans le cadre de PCF explicitement typé, donner la sémantique dénotationnelle du terme suivant :
On remarquera qu’une fonction « à deux arguments » est en fait une fonction qui renvoie une fonction.
Ce document a été traduit de LATEX par HEVEA