\documentclass[a4paper]{article}
\usepackage[frenchb]{babel}
\usepackage[T1]{fontenc}
\usepackage{lmodern}
\usepackage[utf8]{inputenc}
\usepackage{verbatim}
\usepackage{listings}
\usepackage{color}

\begin{document}

\lstset{language=Ada,basicstyle=\small,keywordstyle=\color{black}\bfseries,breaklines=true,extendedchars=true,numbers=left,numberstyle=\tiny}

\section{Exercice 1}

\subsection{Indice\_De}

La fonction Correspond est une fonction auxiliaire utilisée par \verb!Indice_De!. Elle prend en arguments deux chaînes (\verb!Chaine! et \verb!Dans!) qui sont les entrée de \verb!Indice_De! et deux entiers (\verb!Position_Chaine! et \verb!Position_Dans!) qui correspondent aux positions de la recherche du motif dans le mot.

Elle renvoie vrai si \verb!Chaine(Position_Chaine..Chaine'Last)! apparait à la position \verb!Position_Dans! dans \verb!Dans!.

Exemple : \verb!Correspond("tu",1,"voiture",4)! retourne vrai.

Cette fonction est récursive. Lorsque le $i^{ème}$ caractère de Chaine correspond au $n^{ième}$ caractère de \verb!Dans!, on réitere jusqu'a ce que l'on arrive au bout de l'une des deux chaînes.

\begin{lstlisting}
function Correspond (Chaine : String; Position_Chaine : Natural;
                     Dans : String; Position_Dans : Natural) return Boolean is
begin
   if Position_Dans > (Dans'Last+1)
   then
      return(False);
   elsif Position_Chaine > Chaine'Last
   then
      return(True);
   elsif Chaine(Position_Chaine) /= Dans(Position_Dans)
   then
      return(False);
   else
      return(Correspond(Chaine, (Position_Chaine+1), Dans, Position_Dans+1));
   end if;
end Correspond;
\end{lstlisting}

\verb!Indice_De! utilise \verb!Correspond! sur tout les indices de \verb!Dans!.

Cette méthode de recherche n'est pas optimale mais à l'avantage d'être facile à coder.

\begin{lstlisting}
function Indice_De (Chaine : String; Dans : String) return Natural is
   begin
   for I in 1..Dans'Last
   loop
      if Correspond (Chaine, 1, Dans, I)
      then
         return(I);
      end if;
   end loop;
   return(0);
end Indice_De;
\end{lstlisting}

\newpage

\subsection{Remplacement}

Remplacement fait d'abord des tests sur les arguments puis remplace la chaine De par la chaîne par.

\begin{lstlisting}
function Remplacement (De : String; Par : String; Dans : String) return String is
   Resultat : String := Dans;
   Indice_De_De : Integer;
begin
   if De'Last /= Par'Last
   then
      raise Taille_Differente;
   end if;
   Indice_De_De := Indice_De(De, Dans) - 1;
   if Indice_De_De = -1
   then
      raise Motif_Non_Present;
   end if;
   for I in 1..(De'Last)
   loop
      Resultat(I+Indice_De_De) := Par(I);
   end loop;
   return(Resultat);
exception
   when Taille_Differente =>
      Put_Line("Les entrees " & De & " et " & Par & " doivent etre de meme longueur.");
      raise Taille_Differente;
   when Motif_Non_Present =>
      Put_Line(De & " n'apparait pas dans " & Dans & ".");
      raise Motif_Non_Present;
end Remplacement;
\end{lstlisting}

\subsection{Problèmes}
Si l'on veut que le remplacement soit effectué quel que soit les longueurs des chaînes, cela implique qu'il faut faire un décalage dans \verb!Dans!.

Par exemple : remplacer \verb!Ind! par \verb!Indice! dans \verb!Ind_De! doit renvoyer \verb!Indice_De!. Il faut donc calculer la longueur de la nouvelle chaîne puis recopier l'ancienne avec un décalage à gauche ou à droite puis enfin remplacer.

Cela nécessite donc de coder plusieurs autres fonctions.\\

Pour remplacer toutes les occurences d'une chaînes dans une autre, il faut modifier \verb!Indice_De! pour que cette fonction ne renvoie non plus une seule occurence mais plusieurs (par exemple avec une liste chaînée d'occurence). Puis modifier \verb!Remplacement! pour que la fonction prenne compte de la liste que renvoie \verb!Indice_De!.

\newpage

\section{Exercice 2}

\subsection{Structure de donnée}

Les notes sont des réels qui vont de 0 à 6. On suppose que l'on ne conserve que deux chiffres significatifs.

\begin{lstlisting}
   type T_Note is digits 2 range 0.0..6.0;
   package Note_IO is new Float_IO(T_Note);
   use Note_IO;

   subtype T_Matiere is String(1..20);
\end{lstlisting}

Il n'y a pas plus de quarante étudiants à gérer. On déclare donc un tableau indexé de 1 à 40.

\begin{lstlisting}
   type T_Tableau_De_Note is array (Positive range 1..40) of T_Note;
\end{lstlisting}

On utilise un \verb!record! pour le type \verb!T_Eleve!.

\begin{lstlisting}
   subtype T_Nom is String(1..20);

   type T_Eleve is
      record
         Nom : T_Nom := (others =>' ');
         Prenom : T_Nom := (others =>' ');
         Id : Positive;
      end record;
\end{lstlisting}

\verb!T_Filiere! est une liste chaînée qui contient comme information une matière et le tableau de note correspondant à cette matière.

\begin{lstlisting}
   type Element;
   type T_Filiere is access Element;
   type Element is record
      Matiere : T_Matiere;
      Note : T_Tableau_De_Note;
      Suiv : T_Filiere;
   end record;
\end{lstlisting}

\newpage

\subsection{Fonctions}

Fonction récursive qui renvoie vrai si une matière et dans une filière et faux sinon.

\begin{lstlisting}
   function Fait_Partie (Matiere : T_Matiere; Filiere : T_Filiere) return Boolean is
   begin
      if Filiere = null
      then
         return(False);
      elsif Filiere.all.Matiere = Matiere
      then
         return(True);
      else
         return(Fait_Partie(Matiere, Filiere.all.Suiv));
      end if;
   end Fait_Partie;
\end{lstlisting}

Fonction qui vérifie qu'une matière n'est pas simultanément dans deux filiere

\begin{lstlisting}
   function Ne_Fait_Pas_Partie (Matiere : T_Matiere; Filiere1 : T_Filiere; Filiere2 : T_Filiere) return Boolean is
   begin
      return(not(Fait_Partie(Matiere,Filiere1) and then Fait_Partie(Matiere,Filiere2)));
   end Ne_Fait_Pas_Partie;
\end{lstlisting}

\end{document}
