/**
   @page tp-UF Structures Union-Find par forêts et application à la segmentation d'image.

   \section tp-UF-1  1 - Objectifs

   L'objectif de ce TP est de vous faire mettre en oeuvre une
   structure de données efficace pour les ensembles disjoints : la
   forêt. On se servira de cette structure pour faire de la
   segmentation d'image, c'est-à-dire une partition de l'image en
   zones d'intérêt.

   [TOC]

   Pour faciliter la visualisation, on utilisera la bibliothèque GTK
   (http://www.gtk.org) comme interface graphique. Elle permet de
   charger les images, de les afficher, d'avoir des boutons et
   sélecteur de paramètres, etc. Vous vous en êtes déjà servi en
   INFO505
   (http://www.lama.univ-savoie.fr/~lachaud/Cours/INFO504/Tests/doc/html/tp3.html)
   pour le TP Tetris graphique.

   Pour vous faire gagner du temps, on vous donne une application de
   base \ref union-find.c , qui charge une image et permet de choisir
   entre deux pixbufs pour la visualisation (l'image en entrée et
   l'image de sortie calculée).

   Prenez d'abord le temps de bien comprendre le code écrit, le source
   est consultable là: \ref union-find.c et est présent dans l'archive,
   le makefile est ci-dessous:

   \include Makefile

   Pour l'exécuter, on pourra lui donner en paramètre un nom de fichier image (JPG, PNG, PGM, etc).
   \verbatim
prompt$ make
prompt$ ./union-find papillon-express.jpg
   \endverbatim

   \subsection tp-UF-11 1.1 Quelques précisions utiles

   GTK, et plus précisément GDK, voit les images sous forme de
   tableaux d'octets (type \c unsigned \c char ou \c guchar), appelé \c GdkPixbuf. Chaque
   pixel est en général codé sur 3 octets :

   - le premier octet code l'intensité de rouge entre 0 (aucun) et 255 (rouge à fond)
   - le deuxième octet code l'intensité de vert entre 0 (aucun) et 255 (vert à fond)
   - le troisième octet code l'intensité de bleu entre 0 (aucun) et 255 (bleu à fond)

   Dans l'image, le \c GdkPixbuf commence par stocker le pixel le plus
   en haut à gauche, puis stocke les pixels ligne par ligne.  Les
   pixels d'une même ligne sont à la suite les uns des autres (donc
   tous les 3 octets). Pour passer d'une ligne à une autre, on ajoute
   \b rowstride octets au début de l'adresse du pixel de la ligne
   précédente.

   On crée un type Pixel pour simplifier l'accès aux pixels. Le bout
   de code ci-dessous montre comment mettre la composante rouge de
   tous les pixels d'une image à fond.

   \code
   // pixbuf est un GdkPixbuf*
   guchar* data        = gdk_pixbuf_get_pixels( pixbuf );          // Pointeur vers le tampon de données
   int rowstride       = gdk_pixbuf_get_rowstride( pixbuf );       // Nombre d'octets entre chaque ligne dans le tampon de données
   for ( int y = 0; y < height; ++y )
    {
      Pixel* pixel = (Pixel*) data;
      for ( x = 0; x < width; ++x ) 
        {
          pixel->rouge = 255; // met le rouge à fond
          ++pixel;
        }
      data += rowstride; // passe à la ligne suivante
    }
   \endcode

   \subsection tp-UF-12 1.2 Réaction à un clic sur un bouton et appel d'une fonction

   On voit que les fonctions selectInput et selectOutput sont des
   fonctions \b "call-back" ou \b réaction qui sont appelés lors d'un
   événement précis. Elles reçoivent en paramètre un pointeur, qui est
   ici le pointeur vers la variable \c contexte. Celle-ci nous
   permet donc d'accéder aux données utiles pour faire la
   segmentation.

   \code
/// Fonction appelée lorsqu'on clique sur "Input".
gboolean selectInput( GtkWidget *widget, gpointer data )
{
  // Récupère le contexte.
  Contexte* pCtxt = (Contexte*) data;
  // Place le pixbuf à visualiser dans le bon widget.
  gtk_image_set_from_pixbuf( GTK_IMAGE( pCtxt->image ), pCtxt->pixbuf_input );
  // Force le réaffichage du widget.
  gtk_widget_queue_draw( pCtxt->image );
  return TRUE;
}
   \endcode


   \subsection tp-UF-13 1.3 Segmentation d'image

   L'objectif de la segmentation d'image est de réaliser une partition de l'image en régions d'intérêt, afin de simplifier son analyse postérieure, notamment pour la reconnaissance ou l'indexation. Une région est souvent définie comme un ensemble de points connexes du plan. Pour faire simple, il y a deux grandes familles de techniques:

   - l'approche par \b homogénéité: on définit les régions comme des zones à
     peu près homogènes, i.e. de couleurs et intensités proches.

   - l'approche par \b hétérogénéité: on définit les frontières entre régions comme des endroits où il y a de fortes variations de la couleur et/ou de l'intensité.

   Evidemment, on fait souvent un mélange de ces deux approches
   duales. Ici, ce que vous allez faire relève des deux approches:

   - l'approche par \b homogénéité: le seuillage regroupe zones claires ensembles et zones sombres ensemble (\ref tp-UF-2) et l'extraction de composantes connexes en définit les régions (\ref tp-UF-3). Souvent, on préférerait faire un K-means ou K-moyennes (http://fr.wikipedia.org/wiki/Algorithme_des_k-moyennes) plutôt qu'un seuillage en première phase.

   - l'approche par \b hétérogénéité: la non-similitude découpe le graphe autour des hétérogénéité et l'extraction de composantes connexes qui suit bloque sur les frontières pour retrouver les régions (\ref tp-UF-5).

   \section tp-UF-2 2 Seuillage de l'image

   On commence par faire un traitement très simple sur l'image, le \b
   seuillage par un niveau de gris \a T entre 0 et 255. Il s'agit tout
   simplement de transformer l'image donnée en entrée en une image
   noir et blanc telle que:
   
   - soit \a g le niveau de gris d'un pixel \a p dans le pixbuf \c input (obtenu par un appel de \ref greyLevel).

   - si \a g est strictement plus petit que \a T, alors le pixel à la
     même position que \a p dans le pixbuf \c output est mis noir
     (appel de \ref setGreyLevel avec 0)

   - sinon le pixel à la même position que \a p dans le pixbuf \c
     output est mis blanc (appel de \ref setGreyLevel avec 255)

   Créer donc un \c GtkScale et un bouton "Seuiller" et rajoutez les
   dans l'IHM pour que l'utilisateur puisse choisir son seuil et lancer le seuillage. 
   L'image seuillée sera placée dans le pixbuf \c output du contexte.

   \code
   // Crée un scale
   GtkWidget* seuil_widget = gtk_hscale_new_with_range( 0, 255, 1 );
   \endcode

   N'oubliez pas de stocker le widget dans le contexte pour que vous
   puissiez accéder à la valeur choisie dans votre réaction \c
   seuillerImage. On utilisera la fonction gtk_range_get_value pour
   récupérer la valeur du widget. Cela donnera quelque chose du genre:

   \image html app-1.gif "Image papillon-express seuillée à T=100"


   \section tp-UF-3 3 Découpage de l'image seuillée en composantes connexes

   On va maintenant coder une structure Union-Find pour calculer les
   composantes connexes de l'image seuillée. A une image seuillée, on
   associe un graphe dont les sommets sont les pixels et les arêtes
   relient deux pixels qui se touchent si ils ont même valeur. On
   cherchera à extraire les composantes connexes de ce graphe,
   c'est-à-dire les parties où il existe un chemin entre pixels. Dans
   un premier temps, on code une structure Union-Find, dans un
   deuxième temps on l'utilisera sur l'image.

   \subsection tp-UF-3-1 3.1 Présentation des structures Union-Find par forêt

   Une présentation plus détaillée est à la fin de la <a
   href="http://www.lama.univ-savoie.fr/pagesmembres/lachaud/Cours/INFO602/Cours/lesson-3.pdf">Leçon
   3</a> d'INFO607. Les \b forêts constituent la structure de données
   la plus \b efficace pour coder les problèmes utilisant les
   ensembles disjoints (i.e. \f$ S = \cup_i S_i \f$ et \f$ \forall i
   \neq j, S_i \cap S_j = \emptyset \f$).

   Chaque sous-ensemble est représenté par un arbre, dont les noeuds
   sont les objets appartenant à l'ensemble et la racine est le
   représentant de l'ensemble. Chaque noeud d'un arbre a donc un
   pointeur vers son parent. La racine pointe vers elle-même et est le
   représentant du sous-ensemble constitué de tous les noeuds de
   l'arbre. Les fonctions sur les ensembles disjoints sont mis en
   oeuvre ainsi:

   - Un appel de `Créer-Ensemble(x)` crée simplement un arbre a un seul
     noeud `x` (coûte \f$ \Theta(1) \f$).
   - La fonction `Trouver(x)` remonte d'un noeud `x` jusqu'à sa racine
     et retourne la racine, ce qui coûte \f$ \Theta(k) \f$ où \a k est
     la profondeur du noeud.
   - La fonction `Union(x,y)` relie la racine de `x` à la racine de
     `y`, si `x` et `y` n'ont pas le même représentant (i.e. la même
     racine). Pour ce faire, il suffit donc de remonter à la racine de
     chaque arbre et de modifier un pointeur.

\code
Action Créer-Ensemble}( E x : Objet );
Debut
  x.pere <- x;
  x.rand <- 1; // servira après
Fin
\endcode
\code
Action Union( E x :  Objet, y : Objet ); // x et y dans 2 ensembles différents
Debut
  u <- Trouver(x);
  v <- Trouver(y);
  u.pere <- v;
Fin
\endcode
\code
Fonction Trouver( E x : Objet ) : Objet;
Debut
  Si x == x.pere Alors retourner x;
                 Sinon retourner Trouver( x.pere );
Fin
\endcode

   Telle quelle, cette implémentation n'est pas plus rapide que celle
   utilisant les listes chaînées. On applique deux heuristiques à cette
   structure de façon à la rendre la plus efficace possible.

   - \b L' \b union \b par \b rang. On stocke dans chaque noeud un majorant
     de la hauteur de son sous-arbre appelé rang (qui vaut 1 lorsque
     l'arbre est réduit à un élément). Lorsqu'on réalise l'union,
     c'est la racine de moindre rang qui pointe vers la racine de rang
     supérieur. C'est seulement lorsque les deux racines ont même rang
     qu'on augmente le rang. Il est clair que cette opération ne
     rajoute pas de surcoût en temps.

\code
// Pseudo-code si union par rang.
Action Union( E x : Objet, y : Objet ); // x et y dans 2 ensembles différents
Debut
  u <- Trouver(x);
  v <- Trouver(y);
  Si u.rang > v.rang Alors v.pere <- u;
                     Sinon u.pere <- v;
  Si u.rang = v.rang Alors v.rang <- v.rang + 1;
Fin
\endcode

   - \b La \b compression \b de \b chemin. Dès que l'on utilise
     `Trouver`, tous les noeuds traversés pour trouver la racine, sont
     modifiés de façon à ce que leur parent soit directement la
     racine. Il est clair que cette opération ne rajoute pas de
     surcoût en temps.

\code
// Pseudo-code si compression de chemin.
Fonction Trouver( E x : Objet ) : Objet;
Debut
  Si x != x.pere Alors x.pere <- Trouver( x.pere );
  Retourner x.pere;
Fin
\endcode

  Ces heuristiques ont un effet très important sur la complexité amortie
  des opérations sur les ensembles disjoints. On a [Tarjan 1975]:

  \b Théorème \b [Tarjan 1975]. Si on utilise les forêts d'ensembles
  disjoints avec les heuristiques d'union par rang et de compression
  de chemin, alors une séquence arbitraire de $m$ opérations
  `Créer-Ensemble`, `Trouver`, `Union` prend un temps \f$O(m
  \alpha(n)) \f$, où \f$ \alpha(n) \f$ est une fonction qui croît
  extrêmement lentement (\f$ n \le 4 \f$ dans tous les cas
  concevables).  

  \note La preuve se fait en utilisant la méthode du potentiel.

  \subsection tp-UF-3-2 3.2 Codage des structures Union-Find par forêt

   La difficulté est de coder la notion abstraite d'\c Objet (ou d'\c Element) définie en cours. L'\c Objet stockera un pointeur vers le pixel associé, son rang et un
   pointeur vers son père. On aura exactement un \c Objet par Pixel. Nous procéderons ainsi:

   \code
/// Un Objet stocke donc un pointeur vers son pixel, son rang et un pointeur vers l'objet père.
typedef struct SObjet {
  Pixel* pixel; // adresse du pixel dans le pixbuf
  int rang;
  struct SObjet* pere;
} Objet;
   \endcode
   
   On va créer autant d'\c Objet que de pixels. On les place dans un grand tableau d'\c Objet, indicés de 0 à width*height-1, dans l'ordre habituel. Au début, chaque \c Objet doit pointer sur le bon pixel, avoir rang 0, et son père c'est lui-même. Ecrivez donc la fonction \c creerEnsembles qui fait ce travail et retourne ce tableau d'\c Objet alloué dynamiquement. Son prototype sera:

   \code
Objet* CreerEnsembles( GdkPixbuf* pixbuf );
   \endcode

\note Cette fonction est délicate. Vérifiez bien que les champs `pixel` et `pere` sont remplis correctement. Au besoin, me demander.

   Il faut ensuite créer les fonctions usuelles:
   \code
// Retourne le représentant de l'objet obj
Objet* Trouver( Objet* obj );
// Réalise l'union des deux arbres contenant obj1 et obj2.
// @pre obj1 et obj2 ne doivent pas avoir les mêmes représentants.
void Union( Objet* obj1, Objet* obj2 );
   \endcode

   Vous créerez les deux versions de `Union` (avec ou sans Union par
   rang), et les deux versions de `Trouver` (avec ou sans compression
   de chemin).

   \subsection tp-UF-3-3 3.3 Utilisation de cette structure pour le découpage en composantes connexes.

   L'image seuillée est vue comme un graphe dont les sommets sont les pixels, et les arêtes relient deux pixels adjacents si ils ont la même valeur. Voilà le graphe (implicite) de la petite image binaire ci-dessous.

   <table>
   <tr>
   <td> \image html pac-v1.png "Image binaire" </td>
   <td> \image html pac-v2.png "Son graphe de connexité induit." </td>
   </tr>
   </table>

   Créez maintenant un nouveau bouton "Composantes connexes" avec une
   réaction \c ComposantesConnexes. Elle réalisera l'algorithme ci-dessous:

\verbatim
0) elle travaillera directement sur le \c pixbuf_output du contexte, en supposant que l'on a déjà appelé \c seuiller dessus.
1) Objet* objets = CreerEnsembles( ... ); // elle commence par créer le tableau d'\c Objet.
2) Soit i = 0, le numero de l'objet courant
3a) Pour toute paire d'objets objets[i] et objets[i+1] adjacents horizontalement,
      si ils ont même valeurs, on fait l'union.
3b) Pour toute paire d'objets objets[i] et objets[i+width] adjacents verticalement,
      si ils ont même valeurs, on fait l'union.
4) On reparcourt tous les objets et on affecte une couleur aléatoire à tous les objets 
   qui sont des représentants
5) On reparcourt tous les objets et on leur affecte la couleur de leur représentant
6) on force le réaffichage pour voir le résultat.
\endverbatim

   Sur l'exemple précédent du papillon seuillée à 100, voilà ce que vous obtenez:

   \image html app-3.gif "Image papillon-express seuillée à T=100, puis dont les composantes connexes ont été extraites."


\note Faites attention aux \b bords de l'image ! (bord droit pour les
adjacences horizontales, bord bas pour les adjacences verticales).

   \section tp-UF-3-4 3.4 Temps d'exécution de Union-Find.

   On vérifiera que l'efficacité de la structure Union-Find est très dépendante des deux heuristiques d'optimisation. Pour mesurer le temps, on pourra utiliser à profit le bout de code suivant (Linux):

   \code
#include <time.h>
...
  struct timespec myTimerStart;
  clock_gettime(CLOCK_REALTIME, &myTimerStart); // Démarre l'horloge
  // mettre ici l'algo de composantes connexes avec les CreerEnsemble, Union, TrouverEnsemble
  ...

  //
  struct timespec current; // Stoppe l'horloge
  clock_gettime(CLOCK_REALTIME, &current); //Linux gettime
  double t = (( current.tv_sec - myTimerStart.tv_sec) *1000 +
              ( current.tv_nsec - myTimerStart.tv_nsec)/1000000.0);
  printf( "time = %lf ms.\n", t );
   \endcode

   Il faudra modifier les deux lignes suivantes dans le Makefile:
\verbatim
CFLAGS=-g -Wall -Werror -pedantic -std=c11 -D_POSIX_C_SOURCE=199309
GTKLIBS:=$(shell pkg-config --libs gtk+-3.0) -lrt
\endverbatim
   
   Vous ferez un tableau où vous mesurerez les temps d'exécution avec
   plusieurs images de tailles différentes croisées avec les 4 algos
   Union-Find possible (Union-Find bête, Union-Find avec union par
   rang, Union-Find avec compression de chemins, Union-Find avec union
   par rang et compression de chemin). Vérifiez que le temps
   d'exécution est quasi-linéaire dans le dernier cas.


   \section tp-UF-4 4 Affichage de la couleur moyenne pour chaque région

   Pour faire plus "joli", plutôt que d'afficher une couleur aléatoire
   pour une région, on va afficher la couleur moyenne de tous les
   pixels de la même région. Pour nous, couleur moyenne sera les
   moyennes respectives de chaque canal de couleur (ce qui est un peu
   faux du point de vue vision humaine). On adapte la fonction
   précédentes \c ComposantesConnexes dans sa deuxième partie. On se
   donne d'abord une structure pour stocker les moyennes de couleur:

\code
typedef struct {
  double rouge;
  double vert;
  double bleu;
  int nb;
} StatCouleur;
\endcode

Ensuite, les points 4), 5) et 6) de l'algorithme précédents sont remplacés par:

\code
// 4) On alloue un tableau de stats de même taille que le nombre de pixels.
StatCouleur* stats = (StatCouleur*) malloc( size * sizeof( StatCouleur ) );
// 5) On initialise ses valeurs à 0 (c'est suffisant de ne le faire que pour les représentants/racines)
...
// 6) Pour chaque Objet i, on cherche son représentant rep. On récupère son indice j pour ensuite cherchez le bon pixel dans le pixbuf input
  guchar* data_input = gdk_pixbuf_get_pixels( pCtxt->pixbuf_input );
  for ( i = 0; i < size; ++i )
    {
      Objet* rep = Trouver( &objets[ i ] );
      long int j = rep - objets;
      Pixel* pixel_src = (Pixel*) ( data_input + ( (guchar*) objets[ i ].pixel - data_output ) );
      // pixel_src est la couleur de ce pixel dans l'image input.
      // On l'ajoute à la stat du représentant j.
      stats[ j ].rouge += pixel_src->rouge;
      stats[ j ].vert  += pixel_src->vert;
      stats[ j ].bleu  += pixel_src->bleu;
      stats[ j ].nb += 1; // On aura donc la somme cumulée
    }
// 7) On reparcourt les pixels pour calculer la moyenne pour chaque représentant en divisant les canaux (rouge, vert, bleu) par le nombre (nb).
// 8) On reparcourt une dernière fois les pixels pour affecter la couleur moyenne du représentant à chaque pixel.
\endcode

   Cela vous donne sur l'exemple papillon un affichage similaire à ci-dessous:

   \image html app-4.gif "Image papillon-express seuillée à T=135, puis dont les composantes connexes ont été extraites et visualisées en couleur moyenne."


   \section tp-UF-5 5 Connexité floue et découpage en composantes connexes floues

   Le seuillage est bien souvent trop limité. En général on utilise des techniques plus évoluées comme les K-means, la segmentation par minimisation d'une énergie, la segmentation supervisée, etc. Nous proposons ici une petite évolution de l'approche précédente, appelée par certains auteurs la \b connexité \b floue.

   On utilise les définitions suivantes. Soit \f$ \rho(x,x') \f$ une fonction appelée \b similitude qui retourne un nombre >= 0 étant donné deux pixels adjacents \a x et \a x'. Plus \f$ \rho \f$ est proche de 0, plus les pixels \a x et \a x' sont similaires. On dit que deux pixels arbitraires \a x et \a y (pas
 forcément adjacents) sont \f$ \alpha \f$-\b connexes (pour \f$ \alpha
 \ge 0 \f$) si et seulement si il existe un chemin de pixels deux à
 deux adjacents entre \a x et \a y tels que chacun de ces pixels
 adjacents ont une similitude inférieure ou égale à \f$ \alpha \f$.

 La relation d'\f$ \alpha \f$-\b connexité est donc une généralisation de la connexité où deux pixels adjacents devaient être identiques (cf \ref tp-UF-2 et \ref tp-UF-3). Maintenant, ils ont seulement besoin d'être similaire. En revanche, l'algorithme Union-Find fonctionnera toujours. 


\verbatim
0) elle travaillera directement sur le \c pixbuf_output du contexte, en supposant qu'on a copié l'input dessus avant.
1) Objet* objets = CreerEnsembles( ... ); // elle commence par créer le tableau d'\c Objet.
2) Soit i = 0, le numero de l'objet courant
3a) Pour toute paire d'objets objets[i] et objets[i+1] adjacents horizontalement,
      si ils sont similaires, on fait l'union.
3b) Pour toute paire d'objets objets[i] et objets[i+width] adjacents verticalement,
      si ils sont similaires, on fait l'union.
4) On calcule la couleur moyenne de chaque région que l'on donne au représentant.
5) On affecte à chaque pixel la couleur moyenne de son représentant.
6) on force le réaffichage pour voir le résultat.
\endverbatim

On peut définir plein de fonctions "similitude". On va en créer une qui se base sur la représentation TSV des couleurs ou Teinte / Saturation / Valeur (http://fr.wikipedia.org/wiki/Teinte_Saturation_Valeur). Cette représentation est un peu plus représentative de notre perception des couleurs (sans être idéale). On représentera une couleur hsv avec le type:

\code
typedef struct {
  int t;    // teinte comme angle en degrés
  double s; // saturation comme nombre entre 0 et 1
  double v; // valeur ou brillance comme nombre entre 0 et 1
} TSVCouleur;
\endcode

En vous inspirant des formules données sur la page wikipedia, vous écrirez une fonction \c tsv ainsi de prototype

\code
TSVCouleur tsv( Pixel* pixel );
\endcode

La similitude sera définie comme une distance pondérées entre teintes, saturations et valeurs des deux pixels:
\code
double similitude( Pixel* p1, Pixel* p2 ) 
{
  TSVCouleur tsv1 = tsv( p1 );
  TSVCouleur tsv2 = tsv( p2 );
  int diff = tsv1.t - tsv2.t;
  while ( diff >= 180 ) diff -= 360;
  while ( diff <= -180 ) diff += 360;
  return abs( (double) diff ) + 5.0 * abs( tsv1.s - tsv2.s ) + 10.0 * abs( tsv1.v - tsv2.v );
}
\endcode

Adaptez donc le code précédent de \c ComposantesConnexesEnCouleurMoyenne pour réaliser cette segmentation. Sur les images \c papillon-express et \c kowloon-1000, cela donne les résultats ci-dessous.

   \image html app-5.gif "Image papillon-express dont les composantes connexes ont été extraites par similitude <= 54 et visualisées en couleur moyenne."

   \image html app-5-bis.gif "Image kowloon-1000 dont les composantes connexes ont été extraites par similitude <= 83 et visualisées en couleur moyenne."

Vous pourrez bien sûr essayer d'autres fonctions similitudes et d'autres images.

\note Faites attention dans les conversions RGB et TSV avec la manipulation des doubles et des entiers en même temps.


   \section tp-UF-6 6. Remise du tp
  
   - Ce TP peut être fait par binôme. 

   - vous déposerez votre travail à la fin de la séance via via <a
     href="http://www.lama.univ-savoie.fr/TPLab">TPLab</a>.  Il faudra
     une archive nommée TP1-[votre ou vos nom(s)] contenant tous les
     fichiers sources, entêtes, makefile. Vous ajouterez un petit
     README.txt indiquant les questions traitées complètement et
     celles traitées partiellement.
     
   - Vous m'enverrez une version finale de votre TP au plus tard une
     semaine après via <a
     href="http://www.lama.univ-savoie.fr/TPLab">TPLab</a>. Il faudra
     une archive nommée TP1-[votre ou vos nom(s)] contenant tous les
     fichiers sources, entêtes, makefile. Vous me ferez un petit \b
     compte-rendu précisant l'état d'avancement (ce qui marche, ce qui
     marche à moitié, et ce qui ne marche pas), qui donnera un tableau
     des temps de calcul de Union-Find, et qui pourra montrer quelques
     exemples de segmentation.

   - Vous pouvez éventuellement mettre des exemples de segmentation
     dans votre compte-rendu.
  
   - Bien entendu, il faut que vos programmes compilent sous Linux.



*/
