TP5 Prog 2 : Continuations et générateurs à la Python Exercice 1

L3 ENS Cachan Programmation 2 13 mars 2017
TP5 Prog 2 : Continuations et générateurs à la
Python
Dans ce TP nous allons utiliser les continuations pour imiter un code python
à base de générateurs.
Votre but est de programmer en OCaml un équivalent du générateur de
permutations suivant :
def gen er at e (n) :
if n > 1:
for iin rang e (n -1) :
for sin g e ne ra te ( n - 1) :
yield s
if ( n % 2 == 0) :
yield (i , n - 1)
else :
yi el d (0 , n - 1)
for sin g ene rat e (n -1) :
yield s
def print_pe rm s (n ):
a = r ang e (n)
for (i , j ) in ge ne ra te ( n) :
print a
a[ i ] , a [j] = a[j ] , a [ i]
print_perms(n) va afficher toutes les permutations de {0, . . . , n 1}. Intui-
tivement, generate génère une suite de transpositions qui engendre toutes les
permutations. Plus précisément, cette suite de transpositions décrit un che-
min hamiltonien dans le graphe dont les sommets sont les permutations de
{0, . . . , n 1}et les arètes les paires de permutations égales à une transposition
près.
L’algorithme utilisé ci-dessus est dû à Heap (cf wikipedia). Pour ce TP, peu
importe de comprendre comment fonctionne cet algorithme.
Exercice 1 : premiers générateurs
On se fixe les types suivants
type cont = unit -> unit
type a succe ss = ’a -> cont -> unit
type fai lur e = cont
type a gen = ’a succ ess -> f ailur e - > unit
Intuitivement, un ’a gen est un générateur de valeurs de type ’a. Le premier
argument qu’il prend est une continuation de succès sk qui fait quelque chose
avec un agénéré et continue avec la continuation qu’on lui a spécifié. Le deuxième
argument d’un générateur est une continuation d’échec fk qui est appellée quand
il n’y a plus rien à générer. Les générateurs qui génèrent respectivement un et
aucun élément peuvent être définis ainsi :
1
L3 ENS Cachan Programmation 2 13 mars 2017
let yield (a: a ) : a gen = fun sk fk -> sk a fk
let stop : ’a gen = fun sk fk -> fk ()
Question 1
Écrivez une fonction qui itère une fonction donnée sur les éléments générés
par un générateur.
val iter : ( a -> unit ) -> ’a gen -> unit
Testez votre fonction.
let () = ite r pr in t_in t ( yie ld 1) (* affic he 1 *)
let () = iter pr in t_int s top (* n ’ a ff ic he ri en *)
Question 2
Écrivez une fonction yield2 qui crée un générateur à deux éléments.
val yield2 : ’a -> ’a -> ’a gen
Testez votre fonction.
let pri nt _g en p rin ter g =
g ( fun x k -> p ri nt er x ; k () ) ( fun ()->print_string ".")
let () = p rint _gen pri nt_i nt ( y ie ld 2 1 2)
(* affic he : 12. *)
Question 3
Écrivez une fonction qui crée un générateur range m n qui génère en ordre
croissant les entiers entre met n-1.
val range : int -> int -> int gen
Testez votre code.
let () = p ri nt_gen prin t_ in t ( rang e 2 7)
Exercice 2 : combinaisons de générateurs
Question 4
Écrivez les fonctions qui font la composition séquentielle et le produit de
deux générateurs.
2
L3 ENS Cachan Programmation 2 13 mars 2017
val seq : ’a gen -> ’a gen -> ’a gen
val prod : ’a gen -> ’b gen -> ’(a * b ) gen
Testez votre code.
let () = p ri nt _ge n p rin t_ in t ( seq ( r an ge 0 5) ( r ange 5 10) )
(* a ffich e 01 23 45 67 89 . *)
let print _pa ir (x , y) = Forma t . pr in tf " (% d ,% d )" x y
let () = p ri nt_gen print_pair ( prod ( range 0 2) ( range 0 2) )
(* affic he (0 ,0) (0 ,1) (1 ,0) (1 ,1) . *)
Question 5
On veut maintenant créér un générateur de ’b à partir d’un autre générateur
de ’a et d’une fonction qui pour un ’a crée un générateur de ’b.
Écrivez la fonction foreach correspondante.
val for eac h : ’a gen -> ( a -> ’b gen ) -> ’b gen
Testez votre code.
let prod2 g1 g2 =
foreach g1 (fun x - >
foreach g2 (fun y - >
yi el d ( x ,y )
)
)
let () = prin t_ ge n pr in t_ pa ir ( prod2 ( range 0 2) ( ran ge 0 2) )
(* affic he (0 ,0) (0 ,1) (1 ,0) (1 ,1) . *)
Exercice 3 : mise en oeuvre
Question 6
En vous inspirant du code Python de départ, programmez un générateur de
permutations basé sur l’algorithme de Heap.
3
1 / 3 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !