Algorithmique-Programmation : IAP1 - 3 novembre 2008
Sans documents - dur´ee : 1h30 -
Sans calculette
Les exercices sont ind´ependants. Ne vous bloquez donc pas sur une question.
Pour r´epondre `a certaines questions, il se peut que vous ayez besoin de d´efinir des fonctions auxiliaires. Dans
ce cas indiquez clairement ce que font ces fonctions auxiliaires en donnant par exemple leur interface.
Pour les fonctions explicitement demand´ees dans l’´enonc´e, n’´ecrivez leur interface que si celle-ci est explicite-
ment demand´ee dans l’´enonc´e.
Exercice 1 (Typage, ´evaluation)
let rec foo l f = match l with
[] -> []
| e::r -> (e f)::(foo r f);;
Question 1
Quel est le type (le plus g´en´eral) de la fonction foo ? Vous expliquerez en quelques phrases le plus
clairement possible comment vous avez obtenu le type pr´ec´edent.
Question 2
Quel est le type de l’expression foo [succ;function x -> x*x] 2 ? La fonction succ est la fonction
successeur des entiers.
Quelle est la valeur de l’expression foo [succ;function x -> x*x] 2 ?
Question 3
Quel est le type de l’expression foo [function s -> "ab" ; function s -> s^s ] ?
Quelle est la valeur de l’expression foo [function s -> "ab" ; function s -> s^s] ?
Exercice 2 (Petite session `a compl´eter)
Question 4
Compl´eter en donnant les r´eponses de Caml si on lit les phrases dans l’ordre 1, 2, 3 et 4.
1. #let rec until a f p = if p a then [a] else a::(until (f a) f p);;
2. #let qui n m = if n<=m then until n (function y -> y+1) (function y -> y >= m) else [];;
3. #qui 2 8;;
4. #qui 2 0;;
Exercice 3 (Expressions arithm´etiques)
Soit expr le type des expressions arithm´etiques d´efini ci-dessous :
type expr = Const of int | Var of string | Plus of expr * expr;;
Question 5
´
Ecrire une fonction egal qui teste l’´egalit´e de deux expressions de type expr. Le constructeur Plus sera
consid´er´e commutatif, ainsi l’expression (x+y)+2est ´egale `a l’expression 2+(y+x). Mais l’expression
(x+y)+2n’est pas ´egale `a l’expression x+(y+2). On ne consid`erera pas en effet la propri´et´e
d’associativit´e.
On d´esire ajouter aux expressions pr´ec´edentes les expressions de la forme let x = e1 in e2 o`u e1 et
e2 sont deux expressions.
Question 6
1
Modifier le type expr pour prendre en compte ce nouveau genre d’expression.
Question 7
Quelle est la valeur de type expr qui code l’expression let x=y+1 in x+2 ? On l’appellera ex1 dans la
suite.
On dit qu’une variable est libre si elle n’est pas introduite par un let. Par exemple, dans l’expression
let x=y+1 in x+2, la variable yest dite libre. Dans l’expression, let x=x+1 in x+2, la variable xdans
l’expression x+1 est libre. Mais la variable xdans la sous-expression x+2 n’est pas libre, elle est introduite
par le let.
Question 8
´
Ecrire une fonction libres qui prend en param`etre une expression et retourne la liste des noms des
variables qui ont au moins une occurrence libre dans l’expression. Par exemple libres ex1 retourne la liste
["y"] alors que le r´esultat pour l’expression letx=x+yinx+1sera la liste ["x"; "y"].
Question 9
´
Ecrire une fonction evalue qui prend en param`etre une expression et un environnement (une liste de
couples de la forme (nom de variable, valeur enti`ere)) et retourne la valeur de l’expression. Si une variable libre
n’a pas de valeur alors la fonction ´echouera. Par exemple la valeur de l’expression ex1 dans l’environnement
[("y", 5)] est l’entier 8. On rappelle que le calcul de la valeur d’une expression let x = e1 in e2 se fait
en ´evaluant d’abord l’expression e1 (soit vsa valeur) puis en ´evaluant l’expression e2 en consid´erant que x
d´esigne la valeur v.
Exercice 4 (Graphes)
On d´esire repr´esenter et manipuler un graphe orient´e en Caml. Pour simplifier on suppose dans la suite
que les sommets sont repr´esenes par des entiers mais ils pourraient ˆetre de n’importe quel type.
Partie 1
Dans cette partie un graphe oriene est repr´esene par la liste de ses arcs. Un arc de xvers yest repr´esene par
le couple (x, y). On dit dans ce cas que yest un successeur de x. Un graphe est donc de type (int int)list.
On d´esignera ce type par graphe dans la suite.
Soit gtest le graphe [(1,2); (1,4); (2,1); (2,3)].
Question 10
´
Ecrire une fonction estsucc dont l’interface est donn´ee ci dessous :
(*interface estsucc
type : graphe * int * int -> bool
arguments : g x y
pre : true
post : retourne true si x est un successeur de y dans le graphe g, false sinon.
tests : estsucc (gtest,4,1) (* true*), estsucc (gtest,4,2) (* false*), estsucc (gtest,5,1) (* false*)
*)
Question 11
´
Ecrire une fonction successeurs qui prend deux param`etres : un graphe get un sommet s, et retourne
la liste des successeurs de sdans g. Elle retourne la liste vide si le sommet ne figure pas dans le graphe.
Question 12
R´e´ecrire la fonction pr´ec´edente en utilisant la fonctionnelle f old lef t ou fold right.
Question 13
´
Ecrire une fonction qui retourne la liste des sommets d’un graphe (on suppose que le graphe ne contient
pas de sommets isol´es, i.e non reli´es `a un autre). On veut obtenir le r´esultat sous la forme d’un liste
2
sans doublons et ordonn´ee dans l’ordre croissant des sommets. Une solution qui consisterait `a chercher les
sommets puis `a supprimer les doublons et trier (ou l’inverse) sera refus´ee. On pourra si besoin est d´efinir une
ou plusieurs fonctions interm´ediaires. Toute fonction interm´ediaire doit ˆetre accompagn´ee de son interface.
Si cette derni`ere ne figure pas, la solution sera ignor´ee.
Partie 2
On adopte maintenant une autre repr´esentation pour un graphe. Pour chaque sommet on dispose de la liste
non vide de ses successeurs. Ainsi le graphe gtest sera repr´esent´e par la valeur [(1,[2; 4]); (2,[1; 3])]. Un
sommet qui n’a pas de successeur ne figure pas en tant que premier composant d’un couple dans la liste.
Question 14
R´e´ecrire la fonction pr´ec´edente estsucc en supposant que le graphe est maintenant de type (int (int list)) list.
Pour ´ecrire cette fonction vous utiliserez (entre autres) la fonction assoc dont l’interface est rappel´ee en fin
de sujet.
Question 15
R´e´ecrire la fonction pr´ec´edente successeurs en supposant que le graphe est maintenant de type (int (int list)) list.
Partie 3
Un chemin de x1`a xnest une liste de sommets [x1;x2;...xn] telle que (x1, x2) soit un arc du graphe, (x2, x3)
un autre arc, ..., (xn1, xn) soit aussi un arc du graphe.
Question 16
´
Ecrire une fonction estchemin qui prend en param`etre un graphe get un chemin ch et retourne true
si ch est un chemin du graphe get f alse sinon. Par exemple, estchemin gtest [1; 2; 1] retourne true,
estchemin gtest [1; 2; 3] retourne true,estchemin gtest [1; 2; 4] retourne f alse et estchemin gtest [1; 2; 5]
retourne false. Vous utiliserez les fonctions estsucc ou successeurs pr´ec´edentes pour ´ecrire votre fonction,
vous ne devez en aucun cas supposer que l’on a choisi l’une ou l’autre des 2 repr´esentations propos´ees pour
le graphe.
Il s’agit maintenant de trouver un chemin de x`a ydans un graphe g. Il peut y avoir plusieurs chemins
reliant un sommet `a un autre. On veut ´ecrire une fonction chemin qui prend en param`etre g,xet yet
retourne un chemin (sous la forme d’une liste de sommets comme pr´ec´edemment) reliant x`a ydans le
graphe gs’il en existe un et ´echoue sinon. Dans ce dernier cas, la fonction l`evera l’exception Impossible.
Par exemple, on obtiendra :
# chemin gtest 1 1;;
- : int list = [1; 2; 1]
# chemin gtest 1 3;;
- : int list = [1; 2; 3]
# chemin gtest 2 4;;
- : int list = [2; 1; 4]
Question 17
D´eclarer l’exception Impossible.
Question 18
´
Ecrire la fonction chemin en vous appuyant sur les remarques suivantes :
Si yest un successeur de x, alors le chemin reliant x`a yest tout trouv´e. Sinon, si zest un successeur possible
pour x, un chemin de x`a yest alors un chemin de x`a z(un arc) suivi d’un chemin de z`a y. Ici aussi vous
ne ferez aucune supposition sur le type de repr´esentation choisie pour le graphe. Si besoin est, utilisez les
fonctions estsucc et successeurs.
Rappel : fonctionnelles classiques sur les listes :
3
let rec map f li = match li with
[] -> []
| x::l -> (f x)::(map f l);;
let rec filter p li = match li with
[] -> []
| x::l -> if (p x) then x::(filter p l) else (filter p l);;
let rec fold_right f l e = match l with
[] -> e
| a::r -> f a (fold_right f r e);;
let rec fold_left f e l = match l with
[] -> e
| a::r -> fold_left f (f e a) r;;
Interface de la fonction assoc :
(*
interface assoc
type : ’a -> ’a * ’b list -> ’b
arguments x l
precondition : il existe un couple de la forme (x,y) dans l
postcondition : retourne y
raises : Not_Found si il n’y aucun couple de la forme (x,..) dans l
*)
4
1 / 4 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 !