\documentclass{tp-caml}

\tp{
  title=Lorem ipso,
  number=Neuvième,
  date=Vendredi 27 mai 2011,
  class=HX4 \& HX1
}

\begin{document}

\begin{abstract}
\begin{flushright}
\begin{quotation}Solum reperesimunum ali pos pras bellis cum et minemisciennicessenes stritimena.\end{quotation}
\end{flushright}
\end{abstract}

\begin{corpus}

\begin{exod}
Récupérer sur internet la fonction texte et réussir à la faire marcher. Récupérer les textes 0 à 7.
\end{exod}

\section{Quel langue parlez-vous ?}
\subsection{Vecteur de fréquence}

\begin{exo}
Écrire une fonction \textbf{intchar} qui envoie `a`..`z` sur 0..25
\end{exo}
\begin{solc}
let intchar c = 
  if c >= `a` && c <= `z` 
  then int_of_char c - int_of_char `a`
  else failwith "n'existe pas"
;;
\end{solc}

\begin{exo}
Écrire une fonction qui prend un mot et une position et rajoute dans un tableau \textbf{freq} le nombre d'occurrences de chaque lettre. On suppose que le tableau est déclaré à l'extérieur de la fonction.
\end{exo}
\begin{solc}
 let rec do_freq s i = 
    if i < string_length s
    then t.(intchar s.[i])<-t.(intchar s.[i])+1
  in
\end{solc}

\begin{exo}
En déduire une fonction \textbf{frequence} qui prend une liste de mot et qui renvoie un tableau comptant le nombre d'occurrences de chaque lettre.
\end{exo}
\begin{solc}
let freq y = 
  let t = make_vect 26 0 in
  let rec do_freq s i = 
    if i < string_length s
    then t.(intchar s.[i])<-t.(intchar s.[i])+1
  in
  let rec foo = function 
    | [] -> ()
    | a::q -> do_freq a 0; foo q
  in
foo y ; t
;;
\end{solc}

\subsection{Retrouver la langue d'un texte}

Pour retrouver la langue des textes, on va se contenter de comparer les fréquences d'apparition de chacune des lettres. Pour cela, il faut être capable de normaliser le tableau renvoyé par \textbf{frequence}.

\begin{exo}
Écrire une fonction \textbf{somme2} qui prend un tableau d'entiers et renvoie sa norme $\mathcal{L}^2$.
\end{exo}
\begin{solc}
let sum t = 
  let rec foo i = 
    if vect_length t = i then 0 else t.(i)+foo (i+1)
  in
foo 0;;
\end{solc}

\begin{exo}
Écrire une fonction \textbf{normalise} qui normalise un vecteur donné en entrée.
\end{exo}
\begin{solc}
let normalize t = 
  let tot = (sum2 t) in
  let res = make_vect (vect_length t) 0. in
  let rec foo i =
    if i < vect_length t 
    then (res.(i) <- float_of_int t.(i) /. tot ; foo (i+1))
  in
  foo 0 ; res
;;
\end{solc}

\begin{exo}
Écrire la fonction \textbf{distance} qui donne le carré de la distance (norme 2) entre deux vecteurs.
\end{exo}

\begin{exo}
Écrire une fonction qui prend un ensemble de textes (sous la forme que vous voulez) et affiche les textes qui sont proches (mettons à distance inférieure à 0.1). 
\end{exo}
\begin{solc}
let proches txt = 
  let e = map_vect (fun x -> normalize (freq x)) txt ;;
  for i = 0 to vect_length e - 2 do
    for j = i+1 to vect_length e - 1 do 
      if (dist e.(i) e.(j))<0.13 then (print_int i ; print_string " <-> "; print_int j ; print_string " " ; print_float (dist e.(i) e.(j)); print_newline ())    
    done;
  done;;
\end{solc}

\section{Générer des mots}

\subsection{Trigrammes}

\begin{exo}
Écrire une fonction qui prend un texte et qui renvoie un tableau tridimensionnel contenant toutes les occurrences de trigrammes apparaissant dans le texte, avec répétition. Les deux premières dimensions servent à caractériser les deux premières lettres des trigrammes tandis que la troisième sert juste à indicer. La troisième lettre du trigramme est la valeur dans le tableau. Par exemple si abc apparait dans notre texte, on aura c dans la case t.(intcar a).(intcar b).($i$) pour un certain $i$. D'autres part, on allonge (virtuellement) les mots par des espaces. Aussi dans le mot eau on a les trigrammes \_\_e, \_ea,eau,au\_,u\_\_.  On pourra commencer par faire une fonction qui prend un mot et rajoute ses trigrammes à un tableau.
\end{exo}
\begin{solc}let make_trigramme t =
  let res = make_matrix 27 27 [] in
  let rec do_mot p1 p2 m i =
    let c = if i = string_length m 
      then ` ` 
      else  (do_mot p2 (intchar m.[i]) m (i+1);m.[i]) in
    res.(p1).(p2) <-c::res.(p1).(p2)
  in
  let rec do_text = function
    | [] -> ()
    | a::q -> do_mot 26 26 a 0; do_text q 
  in
  do_text t ; map_vect (map_vect vect_of_list) res
;;

\end{solc}

\begin{exo}
Écrire une fonction qui affiche un mot au hasard en respectant les probabilités d'apparition des trigrammes d'un texte donné.
\end{exo}
\begin{solc}
let rec write_mot t a b = 
  let r = random__int (vect_length t.(a).(b)) in
  let c =  t.(a).(b).(r) in
  print_char c ; 
  if c <> ` ` then write_mot t b (intchar c) 
  ;;
\end{solc}

\begin{exo}
En déduire une fonction qui affiche un nombre arbitraire de mot.
\end{exo}
\begin{solc}
let rec write t n = 
  if n > 0 
  then
    (
      write_mot t 26 26;
      write t (n-1)
    )
  else print_newline()
;;
\end{solc}

\begin{exo}
Générer des phrases aléatoirement dans diverses langues.
\end{exo}

\section{Pour ceux qui s'ennuient}

\begin{exo}
Reconnaitre les langues en fonction des trigrammes.
\end{exo}

\end{corpus}


\end{document}
	
