diff --git a/tp/tp4.md b/tp/tp4.md
index 1bcb105371447aadbd257b3abf7a94432a03ce71..cfe00063d5fc251f87d9efaf36309971a1334939 100644
--- a/tp/tp4.md
+++ b/tp/tp4.md
@@ -20,7 +20,7 @@ Un noeud contiendra donc simplement une forêt.
 >
 > Définir quelques arbres pour pouvoir tester.
 >
-> Donner deux exemples d'arbres ne contenant **aucun** éléments.
+> Donner deux exemples d'arbres ne contenant **aucun** élément.
 >
 > Quel est le type inféré par OCaml pour ces arbres ? Pourquoi ?
 
@@ -29,7 +29,8 @@ Un noeud contiendra donc simplement une forêt.
 On souhaite maintenant pouvoir calculer la hauteur d'un arbre.
 Comme un arbre peut contenir une forêt, il faut deux fonctions mutuellement récursives: une fonction qui donne la hauteur d'un arbre et une autre qui donne la hauteur maximale des arbres dans une forêt.
 
-> Coder `hauteur_arbre` et `hauteur_foret`, deux fonctions mutuellement récursives qui calculent respectivement la hauteur d'un arbre et la hauteur maximale des arbres d'une forêt. Tester avec `assert`.
+> Coder `hauteur_arbre` et `hauteur_foret`, deux fonctions mutuellement récursives qui calculent respectivement la hauteur d'un arbre et la hauteur maximale des arbres d'une forêt.
+> Tester avec `assert`.
 
 ### 1.3. Éléments d'un arbre
 
@@ -42,11 +43,13 @@ Comme un arbre peut contenir une forêt, il faut **deux fonctions mutuellement r
 Par ailleurs on veut éviter de faire des concaténations qui vont s'avérer coûteuses, on va donc écrire ces fonctions en **s'appuyant sur un accumulateur**.
 Les fonctions vont ainsi ajouter les éléments de l'arbre/de la forêt à l'accumulateur.
 
-> Coder deux fonctions mutuellement récursives `list_of_arbre_aux` et `list_of_foret` qui vont prendre un arbre / une forêt en argument, ainsi qu'une liste d'éléments `acc` qui vont ajouter en tête de `acc` les éléments de l'arbre / de la forêt. Vous pouvez aussi commencer par écrire une version **sans** accumulateur et la modifier ensuite.
+> Coder deux fonctions mutuellement récursives `list_of_arbre_aux` et `list_of_foret` qui vont prendre un arbre / une forêt en argument, ainsi qu'une liste d'éléments `acc` qui vont ajouter en tête de `acc` les éléments de l'arbre / de la forêt.
+> Vous pouvez aussi commencer par écrire une version **sans** accumulateur et la modifier ensuite.
 >
 > Tester avec `assert`.
 >
-> Placer la définition des deux fonctions à l'intérieur d'une fonction `list_of_arbre` (via un `let ... in ...`). Le code de `list_of_arbre` fera ensuite simplement appel à `list_of_arbre_aux` avec un accumulateur initial vide.
+> Placer la définition des deux fonctions à l'intérieur d'une fonction `list_of_arbre` (via un `let ... in ...`).
+> Le code de `list_of_arbre` fera ensuite simplement appel à `list_of_arbre_aux` avec un accumulateur initial vide.
 >
 > Modifier les tests précédents pour tester `list_of_arbre` et pas `list_of_arbre_aux` (qui est maintenant masquée).
 
@@ -56,10 +59,13 @@ On veut maintenant extraire _l'élément minimal d'un arbre_.
 Attention, si l'arbre est vide, le minimal n'est **pas** défini, le résultat sera donc un `'a option`.
 Il faudra prendre en compte cette spécificité lors du traitement des appels récursifs, typiquement en faisant un pattern matching sur le résultat de l'appel récursif.
 
-Remarque : la fonction `min` est prédéfinie en OCaml. Son type est `'a -> 'a -> 'a`. On l'utilisera pour obtenir le minimum de deux éléments de l'arbre.
-On évitera cependant de l'utiliser directement avec des `option` car elle ne donnera pas le résultat voulu. Par exemple, `min None (Some 3)` vaut `None`.
+**Remarque :** la fonction `min` est prédéfinie en OCaml. Son type est `'a -> 'a -> 'a`.
+On l'utilisera pour obtenir le minimum de deux éléments de l'arbre.
+On évitera cependant de l'utiliser directement avec des `option` car elle ne donnera pas le résultat voulu.
+Par exemple, `min None (Some 3)` vaut `None`.
 
-> Définir deux fonctions mutuellement récursives `minimum` et `minimum_foret` qui donne le minimum d'un arbre / d'une forêt. Tester avec `assert`.
+> Définir deux fonctions mutuellement récursives `minimum` et `minimum_foret` qui donne le minimum d'un arbre / d'une forêt.
+> Tester avec `assert`.
 
 ### 1.5. Reduce
 
@@ -67,15 +73,20 @@ On peut remarquer que dans le code de `minimum` et `minimum_foret`, la fonction
 On pourrait donc généraliser ce code pour qu'il fonctionne avec **n'importe quelle fonction de combinaison des résultats**.
 La fonction généralisée est souvent appelée `reduce`.
 
-On veut donc coder les fonctions `reduce` et `reduce_foret` qui généralisent `minimum`. Elles prendront un argument supplémentaire `f` qui est la fonction de combinaison des résultats. Dans le code de ces fonctions, `f` sera utilisée à la place de `min`. Si l'arbre / la forêt contient des éléments de type `'a`, alors le type de `f` sera `'a -> 'a -> 'a`.
+On veut donc coder les fonctions `reduce` et `reduce_foret` qui généralisent `minimum`.
+Elles prendront un argument supplémentaire `f` qui est la fonction de combinaison des résultats.
+Dans le code de ces fonctions, `f` sera utilisée à la place de `min`.
+Si l'arbre / la forêt contient des éléments de type `'a`, alors le type de `f` sera `'a -> 'a -> 'a`.
 
-> Coder `reduce` et `reduce_foret`. Tester en reprenant les cas de test utilisés pour `minimum`, en utilisant `min` comme valeur pour `f`.
+> Coder `reduce` et `reduce_foret`.
+> Tester en reprenant les cas de test utilisés pour `minimum`, en utilisant `min` comme valeur pour `f`.
 
 Si ce n'est pas déjà fait, définir quelques exemples arbres dont le contenu sera de type `int`.
 
 > Tester `reduce` et `reduce_foret` avec un fonction qui fait l'addition (en `int`) de ses deux arguments, ou le produit des éléments, le maximum etc.
 
-**Remarque** : le type de l'addition est `int -> int -> int`. Cela fonctionne car le type de `reduce` est `('a -> 'a -> 'a) -> 'a arbre_n -> 'a option`, donc `reduce` a aussi le type `(int -> int -> int) -> int arbre_n -> int option`.
+**Remarque** : le type de l'addition est `int -> int -> int`.
+Cela fonctionne car le type de `reduce` est `('a -> 'a -> 'a) -> 'a arbre_n -> 'a option`, donc `reduce` a aussi le type `(int -> int -> int) -> int arbre_n -> int option`.
 
 ## 2. FIFOs basées sur des listes
 
@@ -91,7 +102,7 @@ Une autre technique consiste à utiliser **deux** listes.
 La première (à gauche) est destinée à recevoir les nouveau éléments, alors que la seconde à droite sera utilisée pour stocker les éléments à retirer :
 
 - dans la liste de gauche, les éléments sont stockés dans l'ordre **inverse** de leur insertion : le dernier élément inséré est en tête de liste.
-- dans la liste de droite, les éléments sont stocké dans l'ordre où ils doivent être récupérés, c'est à dire **le plus ancien en tête de liste**.
+- dans la liste de droite, les éléments sont stocké dans l'ordre où ils doivent être récupérés, c'est-à-dire **le plus ancien en tête de liste**.
 
 Reste à transférer des éléments entre la liste de gauche et celle de droite.
 C'est là que cette technique trouve son efficacité : on transfère de la gauche à la droite lorsque l'on essaie de retirer un élément de la liste de droite alors qu'elle est vide.
@@ -204,11 +215,18 @@ flowchart LR
 
 ### 2.2 Type FIFO et ajout d'éléments
 
-> Définir un type `'a fifo` avec un seul constructeur contenant deux listes dont les éléments sont de type `'a`. Définir quelques exemples d'éléments de ce type.
+> Définir un type `'a fifo` avec un seul constructeur contenant deux listes dont les éléments sont de type `'a`.
+> Définir quelques exemples d'éléments de ce type.
+
+<!-- pour séparer les citations -->
 
-> Définir une fonction `push_fifo` qui prend en argument un élément `e` et une fifo `f` et renvoie la fifo contenant les éléments de `f` puis `e` en insérant `e` en tête de la liste de gauche. Tester avec `assert` et les fifos exemples créées précédement.
+> Définir une fonction `push_fifo` qui prend en argument un élément `e` et une fifo `f` et renvoie la fifo contenant les éléments de `f` puis `e` en insérant `e` en tête de la liste de gauche.
+> Tester avec `assert` et les fifos exemples créées précédement.
 
-> Définir une fonction `push_list_fifo` qui prend une liste d'éléments `l` et une fifo `f` et renvoie la fifo contenant tous les éléments de `f` suivis de tous les éléments de `l` insérés dans l'ordre de `l` (i.e. l'élément en tête de `l` avant les autres). Tester avec `assert` et les fifos exemples créées précédement.
+<!-- pour séparer les citations -->
+
+> Définir une fonction `push_list_fifo` qui prend une liste d'éléments `l` et une fifo `f` et renvoie la fifo contenant tous les éléments de `f` suivis de tous les éléments de `l` insérés dans l'ordre de `l` (i.e. l'élément en tête de `l` avant les autres).
+> Tester avec `assert` et les fifos exemples créées précédement.
 
 ### 2.3 Récupération des éléments et transfert
 
@@ -224,4 +242,6 @@ Le résultat de `pop_fifo` sera une paire contenant d'une part la fifo sans l'é
 
 > Coder la fonction `pop_fifo` et la tester avec `assert` et les fifos exemples créées précédement.
 
+<!-- Séparateur de citation -->
+
 > Coder la fonction `pop_all_fifo` qui prend une fifo `f` et renvoie la liste contenant tous les éléments dans l'ordre de `f`, c'est à dire qu'on veut le premier élément retiré de `f` en tête de la liste résultat. Tester avec `assert` et les fifos exemples créées précédement.