Langage de Programmation 2 (LP2)
Transcription
Langage de Programmation 2 (LP2)
Langage de Programmation 2 (LP2) Langage de Programmation 2 (LP2) RICM3 Cours 4 Modules, foncteurs, Input Output Pascal Lafourcade Polytech 2010 - 2011 1 / 84 Langage de Programmation 2 (LP2) Programme Cours 1. Bases de OCaml (Objective Categorical Abstract Machine Language) ... 2. Récurrence structurelle 3. Evaluation et compléments en Ocaml. 4. Modules, Foncteurs, Input Output * 5. Exception, flots 6. Inférence de type (Typage) 7. Polymorphisme, référence, mutable. 8. Lambda Calcul 9. Lambda Calcul 10. Mémoire etc ... TP 1. Introduction à OCAML 2. Code de Huffmann 3. Modules, foncteurs, graphes * 4. Analyse lexicale par flots 5. Espace, graphisme : PROJET Doom. 2 / 84 Langage de Programmation 2 (LP2) La dernière fois I Type Produit I Évaluation et valeurs I Type Nommé I Compléments 3 / 84 Langage de Programmation 2 (LP2) Note TP et DM Note finale = 60% Examen + 40% max (Examen,CC) CC = 40 % DM + 60% TP I I I I I I I Pas de partiel Si TOUS les TPs rendus +1 note TP Indentation TESTS Etre honête. Lire l’énoncé.. ! ! Ne pas copier ... Possibilité de rendre d’autres travaux pour correction détaillée. 4 / 84 Langage de Programmation 2 (LP2) Notation DM I 2 moins = -.5 point I Pas de tests, ni commentaire -1 point I (RE)-COPIER = 0 I Inefficace, iutile = -.5 point I Ne respecte pas les noms = -1 point I Ne respecte pas exactement la spécification = -1 point I Ne focntionne pas = 0 point 5 / 84 Langage de Programmation 2 (LP2) Plan Une preuve de raisonnement Compilation Modules Généralités Compilation séparée Exemple de module Foncteurs Input OutPut Complexité Conclusion 6 / 84 Langage de Programmation 2 (LP2) = vs == * let x = 3 ; ; let y = 3 ; ; x =y ; ; - : bool = true x == y ; ; - : bool = true let x = "33" ; ; let y = "33" ; ; x =y ; ; - : bool = true x == y ; ; - : bool = false let f x = 2 ; ; let g x = 2 ; ; f f f f 1 = g 1 ; ; - : bool = true 1 == g 1 ; ; - : bool = true = g ; ; Exception : Invalidargument "equal : functional value". == g ; ; - : bool = false 7 / 84 Langage de Programmation 2 (LP2) = vs == * let x = [] ; ; let y = [] ; ; x =y ; ; - : bool = true x == y ; ; - : bool = true let x = [1] ; ; let y = [1] ; ; x =y ; ; - : bool = true x == y ; ; - : bool = false Utilisez uniquement = Nous y reviendrons plus tard avec les références ... 8 / 84 Langage de Programmation 2 (LP2) Une preuve de raisonnement Notion d’arbre équilibré de hauteur h déf ∀h, eqht h a ⇒ nbc a = 2h − 1 P (a) = = let rec eqht h = function let rec nbc = function | F →h=0 | F →0 | N (g, x, d) → | N (g, x, d) → eqht (h-1) g ∧ eqht (h-1) d nbc g + 1 + nbc d Montrer ∀a P (a) par récurrence structurelle sur a I h=0 ⇒ 0 = 2h − 1, trivial I Soient g et d quelconques, montrons ∀h, eqht h N (g, x , d ) ⇒ nbc N (g, x , d ) = 2h − 1 ? ? Soit h tel que eqht h N (g, x , d ), i.e. eqht (h-1) g et eqht (h-1) d ; par les hypothèses de récurrence : nbc g = 2h−1 − 1 et nbc d = 2h−1 − 1 nbc N (g, x , d ) = nbc g + 1 + nbc d = 2h−1 − 1 + 1 + 2h−1 − 1 = 2h − 1 10 / 84 Langage de Programmation 2 (LP2) Compilation Compilation simple Ocaml produit du bytecode : I indépendant de la machine I interprété par une machine virtuelle Ocaml produit du code natif (machine dépendant). 12 / 84 Langage de Programmation 2 (LP2) Compilation Hello world* Les doubles point-virgules sont facultatifs dans un code source. file.ml -> file.cmi file.cmo output let x=42 let main = print_string "Hello World! \n"; print_int(x); print_newline() $ ocamlc file.ml -o output $ ./output Hello World ! 42 $ a.out 14 / 84 Langage de Programmation 2 (LP2) Compilation Compilation vers du bytecode Le code source ne doit pas contenir de directives du toplevel. #!/usr/bin/ocamlrun Code source réparti dans plusieur fichiers (main.ml, types.ml, fifo.ml ...) appelés unité ou module. 16 / 84 Langage de Programmation 2 (LP2) Modules Généralités Principes généraux Objectifs de la modularité I fourniture des fonctionnalités : indépendance entre fournisseur et utilisateur I rôle pivot de l’interface = joue le rôle de contrat I l’utilisateur n’a pas à connaître les détails de la réalisation I le fournisseur se concentre sur les fonctions promises I abstraction des données I garantie des invariants : il suffit que chaque fonction de l’interface respecte ces invariants 18 / 84 Langage de Programmation 2 (LP2) Modules Généralités Modularité en Ocaml I interface = signature S I réalisation = module M : S I sous-modules : notation pointée M1.M2.M3 (idem signatures) Accés par notation pointée : List.hd 19 / 84 Langage de Programmation 2 (LP2) Modules Généralités Modules et fichiers I cohérence module-fichier : I I fichier.ml ⇒ module, fichier.mli ⇒ signature, I possibilité de déclarer des (sous-)modules et des (sous-)signatures dans un fichier I correspondance fichier.ml ⇒ module Fichier I correspondance fichier.mli ⇒ signature Fichier Attention aux majuscules ! Les noms de modules, d’exceptions et de constructeurs commencent par des majuscules. 20 / 84 Langage de Programmation 2 (LP2) Modules Généralités Interface : .mli .mli donne .cmi file.ml type euros = int type carte = number of int | color let p1 = fun (x,y) -> x exception file.mli → → → type carte = number of int | color val p1 : int -> ’b -> int exception Interface I moins générale : val p1 : ’a -> ’b -> ’a I omission de valeurs et de type (type <abstr> et masquage pour encapsulation) Ne donne pas d’informations sur le TAD Astuce : ocamlc -i file.ml donne une version du .mli 21 / 84 Langage de Programmation 2 (LP2) Modules Compilation séparée Compilation séparée Compilation par dépendence inverse avec “ocamlc -c” des .ml et .mli I main.cmi (compiled interface) : signature de l’unité contenant les types et le typage des fonctions sans leur implémentation. I main.cmo (object bytecode) représentation intermédiaire, non executable Remarque : .ml donne .cmi donne .cmo Liaison/Linkage avec “ocamlc” des .cmo et .cma $ ocamlc types.cmo fifo.cmo main.cmo .cmo cités dans l’ordre inverse de dépendance. Les utilisations croisées de modules sont interdites ! 22 / 84 Langage de Programmation 2 (LP2) Modules Compilation séparée Options option : -linkall Pour inclure toute la bibliothèque d’un .cma lors de la liaison Sinon par défaut que les modules nécessaires. option : -I +threads Donne le chemin des fichiers à inclure + répertoire relatif à la bibliothéque standard. option : -g Ajoute des infos de débug pour ocamldebug 24 / 84 Langage de Programmation 2 (LP2) Modules Compilation séparée Compilation séparée : Exemple * Fichiers .ml et .mli I geometrie.mli, geometrie.ml I affichage.mli, affichage.ml I demo.ml ocamlc .mli -> .cmi + .ml -> .cmo ocamlc ocamlc ocamlc ocamlc ocamlc -c -c -c -c -c geometrie.mli -> geometrie.cmi geometrie.ml -> geometrie.cmo affichage.mli -> ocamlc affichage.cmi affichage.ml -> ocamlc affichage.cmo demo.ml Liaison/Linkage avec “ocamlc” des .cmo et .cma ocamlc -o demo graphics.cma geometrie.cmo affichage.cmo 25 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Écrire un module module Nommodule = (Structure : SIGNATURE) ; ; ou module Nommodule : SIGNATURE = Strucutre ; ; Alternative module Nommodule = (struct let ... type ... end : sig val ... type ... end) ; ; Possibilité de faire des sous-modules. 27 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Exemple : Structure module PrioQueue = struct type priority = int type ’a queue = Empty | Node of priority * ’a * let empty = Empty let rec insert queue prio elt = ... exception Queue_is_empty . . end ; ; PrioQueue.insert PrioQueue.empty 1 "hello";; 29 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Exemple : Interface module type PRIOQUEUE = sig type priority = int type ’a queue val empty : ’a queue ... exception Queue_is_empty end ; ; (* still concrete *) (* now abstract *) #module AbstractPrioQueue = (PrioQueue : PRIOQUEUE) ; ; module AbstractPrioQueue : PRIOQUEUE 31 / 84 #AbstractPrioQueue.insert AbstractPrioQueue.empty 1 "hello" Langage de Programmation 2 (LP2) Modules Exemple de module Exemple : à vous de jouer * Écrire un module complexe (opposé, plus, module, zero, constructeur). module Complex = struct type t = float * float let zero = (0.,0.) let cons r i = (r,i) let oppose (r,i) = (-.r,-.i) let plus (r1 ,i1 ) (r2 ,i2 ) = (r1 +.r2 ,i1 +.i2 ) let modu (r,i) = sqrt (r*.r +. i*.i) end Appel des fonctions du module Complex I de manière explicite, par [Complex.zero] ; I après l’appel à [open Complex], de manière implicite par [zero]. 33 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Masquage * Cacher la définition de t, en forçant le type module de [Complex] : module type Complex = sig type t val zero : t val cons : float -> float -> t val oppose : t -> t val plus : t -> t -> t val modu : t -> float end;; module Complex = struct type t = float * float let zero = (0.,0.) let cons r i = (r,i) 35 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Déclaration en deux fois * module type TComplex = sig type t val zero : t val cons : float -> float -> t val oppose : t -> t val plus : t -> t -> t val modu : t -> float end module Complex : TComplex = struct ... end 37 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Extension de signatures Toute signature peut être cpmplétée par with type. module M0 = (M : SIG) module M0 = (M : SIG with type t = M.t) module M0 = (M : SIG with type t = M.t and u = M.u) 38 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Bilan : Organisation des fichiers I I corps : fichier.ml interface fichier.mli Librairie standard I String I Printf I Stream I Array, Hashtbl I Set, Map I Sys, Arg, Filename I Unix 39 / 84 Langage de Programmation 2 (LP2) Modules Exemple de module Unités et interpréteur I # use “file.ml” ; ; lit, compile et exécute le file.ml I # load "file.cmo" ; ; # load "file.cma" ; ; charge en mémoire un fichier compilé cma : library = a collection of modules cmo : compilation unit = one module Chargement d’une unité compilée en .cmo (.cmi visible) I Pour inclure des fichiers # open List ; ; # include List ; ; 40 / 84 Langage de Programmation 2 (LP2) Foncteurs Modularité avancée : foncteurs* 42 / 84 Langage de Programmation 2 (LP2) Foncteurs Modularité avancée : foncteurs functor : module -> module Un foncteur est un module usuel. Syntaxe : functor ( Nom : signature) -> structure Syntaxe : module Nom (Par1 : SIG1) (Par2 : SIG2) .... = .... 44 / 84 Langage de Programmation 2 (LP2) Foncteurs Exemple simple de foncteur Syntaxe 1 # module Couple = functor ( Q : sig type t end ) -> struct type couple = Q.t * Q.t let first (x1, x2) = x1 let second (x1, x2) = x2 end ; ; Syntaxe 2 module Couple ( Q : sig type t end ) = struct type couple = Q.t * Q.t let first (x1, x2) = x1 let second (x1, x2) = x2 end ; ; Possibilité d’utiliser with type. 46 / 84 Langage de Programmation 2 (LP2) Foncteurs Application de foncteur * module Couplecomplex = Couple(Complexe);; let a=(1.,2.);; Couplecomplex.first a;; Couplecomplex.second a;; module Affine = struct type t = float * float let valeur (a,b) x = a *. x +. b end ;; module Coupleaffine = Couple(Affine);; Coupleaffine.first a;; Coupleaffine.second a;; 48 / 84 Langage de Programmation 2 (LP2) Foncteurs Foncteurs : Exemple Tri * module type TypeOrdonne = sig type t val inferieur : t → t → bool end module type Tri = functor (O : TypeOrdonne) → sig val tri : O.t list → O.t list end 50 / 84 Langage de Programmation 2 (LP2) Foncteurs Foncteurs : Exemple Réalisation * module TriFusion : Tri = functor (O : TypeOrdonne) → struct let rec separe x = function | [] → [],[] | y : : l → . . . if O.inferieur y x then . . . else . . . let end rec tri l = . . . 52 / 84 Langage de Programmation 2 (LP2) Foncteurs Foncteurs : Exemple Utilisation module Oentier = struct type t = int let inferieur = (<=) end module let TriEntier = TriFusion (Oentier) l = TriEntier.tri [3 ; 2 ; 1 ; 4 ; 10] I tout ce qui est déclaré est fourni I typage au moins aussi concret 54 / 84 Langage de Programmation 2 (LP2) Foncteurs Exemple :Piège : masquer à bon escient module Oentier : TypeOrdonne = struct type t = int let inferieur = (<=) end module let (* (* type TriEntier = TriFusion (Oentier) l = TriEntier.tri [3 ; 2 ; 1 ; 4 ; 10] ^ Oentier.t attendu *) *) 56 / 84 Langage de Programmation 2 (LP2) Foncteurs Solution : signature avec contrainte module Oentier : TypeOrdonne with type t = int = struct type t = int let inferieur = (<=) end module let type TriEntier = TriFusion (Oentier) l = TriEntier.tri [3 ; 2 ; 1 ; 4 ; 10] 58 / 84 Langage de Programmation 2 (LP2) Foncteurs Important module P : SemiAnneau = struct ... end Matrices(P) manipule des éléments de type P.t sans pouvoir savoir ce qu’est t. Pour expliciter ce type, il faut ajouter with type t = ... module P : SemiAnneau with type t = ... = struct ... end 60 / 84 Langage de Programmation 2 (LP2) Input OutPut Entrée et sortie standard Input (stdin) # read_line () ; ; hello - : string Output # print_string "hello" ; ; hello- : unit = () 62 / 84 Langage de Programmation 2 (LP2) Input OutPut Autres fonctions Affichage print_string print_int print_char print_float Lecture read_line read_int read_float : : : : : : : string int char float unit unit unit -> -> -> -> -> -> -> unit unit unit unit string int float 63 / 84 Langage de Programmation 2 (LP2) Input OutPut Conversions Bool en plus int_of_string string_of_int float_of_string string_of_float bool_of_string string_of_bool : : : : : : string int string float string bool -> -> -> -> -> -> int string float string bool string 64 / 84 Langage de Programmation 2 (LP2) Input OutPut Lecture input_char : in_channel -> char input_line : in_channel -> string # End_of_file ; ; - : exn = End_of_file output_char : out_channel -> char -> unit output_line : out_channel -> string -> unit 65 / 84 Langage de Programmation 2 (LP2) Input OutPut Canaux # stdin ; ; - : in_channel = <abstr> # stdout ; ; - : out_channel = <abstr> Ouverture d’un fichier en lecture open_in : string -> in_channel # open_in “file” ; ; Ouverture d’un fichier en écriture open_out : string -> out_channel # open_out “file” ; ; Fermeture d’un canal close_in : in_channel -> unit close_out : out_channel -> unit 66 / 84 Langage de Programmation 2 (LP2) Input OutPut Stream # Stream.of_channel - : in_channel -> char Stream.t = <fun> # Stream.of_string ; ; - : string -> char Stream.t = <fun> Permet de passer le contenu d’un fichier comme un stream pour pouvoir le parser. Exemple # [< >] ; ; - : ’a Stream.t = <abstr> # [< ’0 ; ’2 ; ’4 >] ; ; - : int Stream.t = <abstr> # let concat_stream a b = [< a ; b >] ; ; val concat_stream : ’a Stream.t -> ’a Stream.t -> ’a Stream.t = <fun> 67 / 84 Langage de Programmation 2 (LP2) Input OutPut Séquencement Syntaxe (e1 ; e2 ); . . . ; en ou begin e1 ; e2 ; . . . ; en end (e1 ; e2 ) prend la valeur de e2 si pas d’exception. le type de e1 ; e2; . . . en−1 doit être unit. Exemple du début ;-) let x=42 let main = print_string "Hello World! \n"; print_int(x); print_newline() 69 / 84 Langage de Programmation 2 (LP2) Input OutPut Arg comme en C let _= if Array.length Sys.argv < 2 then ( print_endline ("Ce programme prend trois arguments.\n"); exit 1 ) let nom=Sys.argv.(1) and nombre=Sys.arv(2) 71 / 84 Langage de Programmation 2 (LP2) Complexité Exemple Algorithme oter let rec oter x l = match l with [] -> [] |a::e -> if x = a then e else a::(oter x e);; T(n) = c + T(n-1) T(n) = c n 74 / 84 Langage de Programmation 2 (LP2) Complexité Exemple Algorithme Factorielle let rec fact n = match n with | 0 -> 1 | n -> n* (fact (n-1));; T(n) = c + T(n-1) T(n) = c n 76 / 84 Langage de Programmation 2 (LP2) Complexité Exemple Algorithme list minimum let lminimum l = match l with | [] -> (0,[]) | x::e -> let m = minimum e in if (x<= m) then (x,e) else (m, x::(oter m e));; T(n) = cn + T(n-1) cn 78 / 84 Langage de Programmation 2 (LP2) Complexité Exemple Algorithme Tri minimum let rec triminimum l = match l with | [] -> [] | [x] -> [x] | l -> let (mini,reste) = lminimum l in mini::(triminimum r T(n) = cn + T(n-1) T (n) = n 2 80 / 84 Langage de Programmation 2 (LP2) Conclusion Aujourd’hui I Compilation I Modules I Foncteurs I Input Output http ://caml.inria.fr/pub/docs/oreilly-book/html/bookora132.html 82 / 84 Langage de Programmation 2 (LP2) Conclusion Prochaine fois I Exceptions I Flots 83 / 84 Langage de Programmation 2 (LP2) Conclusion Thank you for your attention. Questions ? 84 / 84