---
# System prepended metadata

title: CorrectionExamen2013

---

# CorrectionExamen2013

## 1 Typage

### Question 1.1
```ocaml=
let f1 x y = (x, not y)

val f1 : 'a -> bool -> 'a * bool
```
```ocaml=
let rec f2 a b =
  match a with
  | [] -> not b
  | x::l -> f2 l x

val f2 : bool list -> bool -> bool
```

```ocaml=
let f3 f g h = f g && g h

val f3 : (('a -> bool) -> bool) -> ('a -> bool) -> 'a -> bool
```

```ocaml=
let f4 x y = if x y then [x] else [y]
```

`f4` n'est pas bien typée. Si c'était bien typé alors on aurait`x` d'un certain type `a -> b` avec `y` de type `a` (appel `x y`). Donc puisque les branches d'un `if` doivent être de même type on doit avoir `a = (a -> b)`, d'où la contradiction.

### Question 1.2

```ocaml=
let f x = if x = 0.0 then G("erreur") else D(1.0 /. x)

val f : float -> float t
```

```ocaml=
let g h x = h (D x)

val g : ('a t -> 'b) -> 'a -> 'b
```

## 2 Évaluation

### Question 2.1

Même question que la [question 6](https://hackmd.io/o6f5yiLdQd-tSC-L7YNObQ#Question-6) dans le TP précédent.

### Question 2.2

La fonction `f` retire `2` à son argument jusqu'à ce qu'il soit négatif puis renvoie une erreur et donc la ligne `b := !b + 4` n'est jamais évaluée. Lorsqu'on évalue l'expression finale, on commence par appliquer `f` sur `a` qui pointe vers `9`. À la fin de l'exécution de `f`, `a` pointe vers `-1` (car c'est la première valeur négative en partant de `9` et en retirant `2` à chaque fois) et l'erreur `Exit` est levée.  On passe donc directement au rattrapage de l'erreur et la valeur `-1` est donc renvoyée. De meme, `!a + 20` n'est jamais evaluee. 

## 3 Évaluation

### Question 3.1

La fonction `mystere` renvoie `r` qui commence à `0`. Le début de la liste est utilisé pour augmenter la valeur de `r` puis est retiré de la liste et on recommence jusqu'à ce que la liste soit vide. Autrement dit `mystere` calcule la somme des entiers dans la liste donnée en argument. Donc `mystere [4; 1; 5; 3]` renvoie `13`.

On réécrit cette fonction : 
```ocaml=
let mystere = List.fold_left (+) 0
```

### Question 3.2

```ocaml=
let affiche = List.iter (List.iter print_int)
```

## 4 Génération d'arbres binaires

### Question 4.1

Les arbres de hauteur strictement plus petite que `2` :
```ocaml=
let a1 = E
let a2 = N (E, E)
```

Les arbres de hauteur `2` :
```ocaml=
let a3 = N (N (E, E), E)
let a4 = N (E, N (E, E))
let a5 = N (N (E, E), N (E, E))
```

### Question 4.2

```ocaml=
[ N (E, E);
  N (E, N(N (E, E),E));
  N (N (E, E), E);
  N (N (E, E), N (N (E, E),E)) ]
```

### Question 4.3

```ocaml=
let produit t1 t2 =
  let add_e e1 acc e2 = N (e1, e2) :: acc in
  let add_t t2 acc e1 = List.fold_left (add_e e1) acc t2 in
  List.fold_left (add_t t2) [] t1
```
ou
```ocaml=
let produit l1 l2 = List.fold_left(fun acc e1 ->                                 List.fold_left (fun acc e2 ->                                 N(e1,e2)::acc) acc l2) [] l1
```

### Question 4.4

On donne la définition des fonctions mathématiques qui renvoient les ensembles considérés en notant $\times$ le produit tel qu'il a été défini à la question précédente.

Pour $height$ : 

$$ 
height (0) = \{E\} \\
height (n+1) = height (n) \times below(n) \,\bigcup \\
               below (n) \times height (n) \,\bigcup  \\
               height (n) \times height (n)
$$

Pour $below$ : 
$$
below (0) = empty \\
below (n+1) = below (n) \,\bigcup\, height (n)
$$


### Question 4.5

```ocaml=
let rec height n =
  if n = 0 then [E]
  else
    let h = height (n-1) in
    let b = below (n-1) in
    produit h b @ produit b h @ produit h h

and below n =
  if n = 0 then []
  else below (n-1) @ height (n-1)
```

### Question 4.6

Un appel à `height 3` demande de calculer `height 2` et `below 2`, or `below 2` calcule `height 1` et `height 2` calcule aussi `height 1`.

### Question 4.7

Si on n'a qu'une seule table de hachage qui enregistre, pour un `n` donné, une paire composée de `height n` et de `below n` alors, comme après l'appel d'une des deux fonction on n'a qu'un seul des deux résulats, on ne va pas pouvoir enrichir la table.

### Question 4.8

```ocaml=
let tbl_height = Hashtbl.create 17
let tbl_below = Hashtbl.create 17

let rec height n =
  match Hashtbl.find_opt tbl_height n with
  | Some h -> h
  | None -> let res = if n = 0 then [E]
                      else let h1 = height (n-1) in
                           let b = below (n-1) in
                           produit h1 b @ produit b h1 @ produit h1 h1 in
            Hashtbl.add tbl_height n res;
            res

and below n =
  match Hashtbl.find_opt tbl_below n with
  | Some b -> b
  | None -> let res = if n = 0 then []
                      else below (n-1) @ height (n-1) in
            Hashtbl.add tbl_below n res;
            res
```

Version plus proche de ce qui est dans le cours (sans type option) 

```ocaml=
let tbl_height = Hashtbl.create 17
let tbl_below = Hashtbl.create 17

let rec height n =
   try Hashtbl.find tbl_height n with
   Not_found -> let res = if n = 0 then [E]
                      else let h1 = height (n-1) in
                           let b = below (n-1) in
                           produit h1 b @ produit b h1 @ produit h1 h1 in
            Hashtbl.add tbl_height n res;
            res

and below n =
  try Hashtbl.find tbl_below n with 
  Not_found -> let res = if n = 0 then []
                      else below (n-1) @ height (n-1) in
            Hashtbl.add tbl_below n res;
            res
```

