TP1: Découverte

1 Installation de l'environnement

Ouvrir le fichier .emacs.d/init.el avec emacs. Dans un terminal, taper

emacs ~/.emacs.d/init.el

Ajouter les lignes suivantes dans emacs (copier depuis le navigateur, puis coller avec la combinaison de touches ctrl-y dans emacs):

(customize-set-variable 'package-archives
      '(("gnu"         . "http://elpa.gnu.org/packages/")
        ("melpa"       . "http://melpa.org/packages/")))

(eval-after-load "tuareg"
  '(add-hook
    'tuareg-mode-hook
    (lambda ()
      (unless (file-exists-p "Makefile")
        (set (make-local-variable 'compile-command)
             (let ((file (file-name-nondirectory buffer-file-name)))
               (format "ocamlc graphics.cma -o %s %s"
                       (file-name-sans-extension file)
                       file)))))))

Sauvegarder (ctrl-x ctrl-s), quitter (ctrl-x ctrl-c), et relancer emacs.

Pour installer Tuareg, il faut procéder de la manière suivante, dans emacs:

  • taper la combinaison de touches alt-x puis package-list-packages
  • une liste de paquets disponibles pour emacs s’affiche; taper ctrl-s puis tuareg pour trouver le paquet Tuareg
  • taper i puis x pour demander l’installation de ce paquet
  • si emacs vous demande de sauvegarder des « abbrv_def », répondre oui
  • quand l’installation est terminée, taper q pour sortir du gestionnaire de paquets

Pour vérifier l’installation, télécharger le fichier tp1.ml ici sur votre disque dur (clic droit dans votre navigateur internet), et ouvrez le avec emacs (deuxième icône en haut à gauche ou ctrl-x ctrl-f). La fenêtre d’emacs devrait afficher Tuareg dans le bandeau inférieur.

Dans Tuareg, lorsque l'on a écrit une phrase (commencée par let), on peut l'évaluer en utilisant le menu "Tuareg, Interactive Mode, Evaluate Phrase" (raccourci ctrl-x ctrl-e). Lors de la première évaluation, emacs demande quel toplevel utiliser (en bas de l'écran, en proposant ocaml par défaut), il suffit d'accepter le choix par défaut avec la touche enter.

Si emacs ne répond plus le raccourci clavier ctrl-g permet de reprendre la main.

2 Échauffement

Exprimer les fonctions ayant les comportements suivants.

  1. Étant donné un nombre, rendre ce nombre multiplié par 2.

    val mul2 : int -> int = <fun>
    
  2. Étant donné un nombre, rendre sa valeur absolue.

    val vabs : int -> int = <fun>
    
  3. Étant donné un nombre, indiquer s'il est compris entre 12 et 29 (au sens large : retourner true pour 12 et 29)

    val test1 : int -> bool = <fun>
    
  4. Étant donné un nombre, rendre vrai s'il vaut 2, 5, 9 ou 53, faux sinon.

    val test2 : int -> bool = <fun>
    
  5. Étant donnée une paire d'éléments, indiquer si le premier est 12.

    val test3 : int * 'a -> bool = <fun>
    

3 Années bissextiles

Une année est bissextile si elle est divisible par 4. Une exception à cette règle existe si l'année est divisible par 100 : elle n'est alors par bissextile. Une exception à cette exception existe si l'année est divisible par 400 : elle est alors bissextile. 2016 était une année bissextile, 2100 ne le sera pas, mais 2400 le sera.

Écrire la fonction bissext qui prend en argument une année (un entier) et renvoie true si l'année est bissextile, et false sinon. La fonction infixe mod (http://caml.inria.fr/pub/docs/manual-ocaml/libref/Pervasives.html) pourra vous être utile.

val bissext : int -> bool = <fun>

4 N-uplets et filtrage

  1. Écrire la fonction proj1 et proj23 qui étant donné un triplet \((x,y,z)\) rend \(x\) pour proj1 et rend la paire (y,z) pour proj23.

    val proj1 : 'a * 'b * 'c -> 'a = <fun>
    val proj23 : 'a * 'b * 'c -> 'b * 'c = <fun>
    
  2. Écrire la fonction inv2 qui étant donnée une paire de paires rend uniquement la deuxième paire inversée. Contrôler que le type est bien celui prévu.

    val inv2 : ('a * 'b) * ('c * 'd) -> 'd * 'c = <fun>
    

5 Fonctionnelles

  1. Ecrire la fonction incrpaire qui étant donnée une paire (g,d) rend en résultat la paire (g+1, d+1).

    val incrpaire : int * int -> int * int = <fun>
    
  2. Ecrire la fonctionnelle appliqueapaire qui prend en argument une fonction f et rend une fonction qui étant donnée une paire (g,d) rend en résultat la paire (f g, f d).

    val appliquepaire : ('a -> 'b) -> 'a * 'a -> 'b * 'b = <fun>
    
  3. Créer une fonction incrpaire2 en utilisant la fonction appliqueapaire avec la fonction anonyme \(x \mapsto x+1\) (attention: cette fonction anonyme n'est pas incrpaire).

    val incrpaire2 : int * int -> int * int = <fun>
    
  4. Définir une fonctionnelle rapport qui à toute paire de fonctions \((x \mapsto f\;x, x \mapsto g\;x)\) associe la fonction \(x \mapsto (f\;x)/(g\;x)\).

    val rapport : ('a -> float) * ('a -> float) -> 'a -> float = <fun>
    
  5. Pour connaître le type d’une expression, on peut évaluer

    let _ = expr
    

    et regarder le type retourné. Trouver le type des fonctions sin et cos.

  6. Définir la fonction mytan en utilisant rapport, sachant que \(tan\;x = (sin\;x)/(cos\;x)\).

    val mytan : float -> float = <fun>
    

6 Pour aller plus loin…

Ces questions sont optionnelles

Donnez une fonction premier qui indique si un nombre est premier.

val premier : int -> bool = <fun>

Donnez une fonction n_premier qui, étant donné un entier n, retourne le nième nombre premier.

val n_premier : int -> int = <fun>

7 Instructions pour rendre le travail

Avant de soumettre le travail, vérifier qu’il n’y a pas d’erreur de compilation. Tapez ctrl-c ctrl-c, la commande de compilation ocamlc -o tp1 tp1.ml devrait s’afficher en bas de la fenêtre. Acceptez la en tapant sur enter. Le résultat de la compilation est donné dans une fenêtre. S’il ressemble à ceci, c’est correct.

-*- mode: compilation; default-directory: "~/work/cours_caml_INSA/tps/" -*-
Compilation started at Tue Sep 27 08:42:42

ocamlc -o tp1 tp1.ml

Compilation finished at Tue Sep 27 08:42:42

Déposer ensuite votre fichier sur Moodle, (un fichier par binôme).