langage de programmation 2 (lp2)plafourc/teaching/lp2_ricm3_2010_2011/cours… · langage de...
TRANSCRIPT
Langage de Programmation 2 (LP2)
Langage de Programmation 2 (LP2)RICM3Cours 4
Modules, foncteurs, Input Output
Pascal Lafourcade
Polytech
2010 - 20111 / 84
Langage de Programmation 2 (LP2)
ProgrammeCours
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 ProduitI Évaluation et valeursI 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 Pas de partielI Si TOUS les TPs rendus +1 note TPI IndentationI TESTSI Etre honête.I Lire l’énoncé.. ! !I 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 pointI Pas de tests, ni commentaire -1 pointI (RE)-COPIER = 0I Inefficace, iutile = -.5 pointI Ne respecte pas les noms = -1 pointI Ne respecte pas exactement la spécification = -1 pointI Ne focntionne pas = 0 point
5 / 84
Langage de Programmation 2 (LP2)
Plan
Une preuve de raisonnement
Compilation
ModulesGénéralitésCompilation séparéeExemple de module
Foncteurs
Input OutPut
Complexité
Conclusion
6 / 84
Langage de Programmation 2 (LP2)
= vs == *
let x = 3 ; ; let y = 3 ; ;
x =y ; ; - : bool = truex == y ; ; - : bool = true
let x = "33" ; ; let y = "33" ; ;
x =y ; ; - : bool = truex == y ; ; - : bool = false
let f x = 2 ; ; let g x = 2 ; ;
f 1 = g 1 ; ; - : bool = truef 1 == g 1 ; ; - : bool = truef = g ; ; Exception : Invalidargument "equal : functional value".f == g ; ; - : bool = false
7 / 84
Langage de Programmation 2 (LP2)
= vs == *
let x = [] ; ; let y = [] ; ;
x =y ; ; - : bool = truex == y ; ; - : bool = true
let x = [1] ; ; let y = [1] ; ;
x =y ; ; - : bool = truex == 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 hP(a) déf
== ∀h, eqht h a ⇒ nbc a = 2h − 1let rec eqht h = function
| F →h=0| N (g, x, d) →
eqht (h-1) g ∧ eqht (h-1) d
let rec nbc = function| F →0| N (g, x, d) →
nbc g + 1 + nbc dMontrer ∀a P(a) par récurrence structurelle sur a
I h=0 ⇒ 0 = 2h − 1, trivialI 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) get 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 machineI 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=42let main =
print_string "Hello World! \n";print_int(x);print_newline()
$ ocamlc file.ml -o output$ ./outputHello 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 fournisseuret utilisateur
I rôle pivot de l’interface = joue le rôle de contratI l’utilisateur n’a pas à connaître les détails de la réalisationI le fournisseur se concentre sur les fonctions promisesI abstraction des donnéesI 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 SI réalisation = module M : SI 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 fichier.ml ⇒ module,I fichier.mli ⇒ signature,
I possibilité de déclarer des (sous-)modules et des(sous-)signatures dans un fichier
I correspondance fichier.ml ⇒ module FichierI correspondance fichier.mli ⇒ signature Fichier
Attention aux majuscules !
Les noms de modules, d’exceptions et de constructeurscommencent par des majuscules.
20 / 84
Langage de Programmation 2 (LP2)Modules
Généralités
Interface : .mli
.mli donne .cmifile.ml file.mlitype euros = inttype carte type carte= number of int | color → = number of int | colorlet p1 = fun (x,y) -> x → val p1 : int -> ’b -> intexception → exception
Interface
I moins générale : val p1 : ’a -> ’b -> ’aI 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é contenantles 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 liaisonSinon 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.mlI affichage.mli, affichage.mlI demo.ml
ocamlc .mli -> .cmi + .ml -> .cmo
ocamlc -c geometrie.mli -> geometrie.cmiocamlc -c geometrie.ml -> geometrie.cmoocamlc -c affichage.mli -> ocamlc affichage.cmiocamlc -c affichage.ml -> ocamlc affichage.cmoocamlc -c demo.ml
Liaison/Linkage avec “ocamlc” des .cmo et .cma
ocamlc -o demo graphics.cma geometrie.cmo affichage.cmodemo.cmo
25 / 84
Langage de Programmation 2 (LP2)Modules
Exemple de module
Écrire un module
module Nommodule = (Structure : SIGNATURE) ; ;oumodule Nommodule : SIGNATURE = Strucutre ; ;
Alternativemodule Nommodule =(struct
let ...type ...
end : sigval ...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 = inttype ’a queue = Empty | Node of priority * ’a *let empty = Emptylet 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 (* still concrete *)type ’a queue (* now abstract *)val empty : ’a queue...exception Queue_is_empty
end ; ;
#module AbstractPrioQueue = (PrioQueue : PRIOQUEUE) ; ;module AbstractPrioQueue : PRIOQUEUE
#AbstractPrioQueue.insert AbstractPrioQueue.empty 1 "hello" ; ;- : string AbstractPrioQueue.queue = <abstr>
31 / 84
Langage de Programmation 2 (LP2)Modules
Exemple de module
Exemple : à vous de jouer *
Écrire un module complexe(opposé, plus, module, zero, constructeur).
module Complex = structtype t = float * floatlet 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 =sigtype tval zero : tval cons : float -> float -> tval oppose : t -> tval plus : t -> t -> tval modu : t -> float
end;;module Complex =structtype t = float * floatlet 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;;
35 / 84
Langage de Programmation 2 (LP2)Modules
Exemple de module
Déclaration en deux fois *
module type TComplex = sigtype tval zero : tval cons : float -> float -> tval oppose : t -> tval plus : t -> t -> tval 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 corps : fichier.mlI interface fichier.mli
Librairie standard
I StringI PrintfI StreamI Array, HashtblI Set, MapI Sys, Arg, FilenameI 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 modulescmo : compilation unit = one moduleChargement 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
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.tlet first (x1, x2) = x1let second (x1, x2) = x2 end ; ;
Syntaxe 2
module Couple ( Q : sig type t end ) =struct type couple = Q.t * Q.tlet first (x1, x2) = x1let 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 = structtype t = float * floatlet 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 tval inferieur : t → t → bool
end
module type Tri = functor (O : TypeOrdonne) →sig
val tri : O.t list → O.t listend
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 rec tri l = . . .end
52 / 84
Langage de Programmation 2 (LP2)Foncteurs
Foncteurs : Exemple Utilisation
module Oentier =struct
type t = intlet inferieur = (<=)
end
module TriEntier = TriFusion (Oentier)
let l = TriEntier.tri [3 ; 2 ; 1 ; 4 ; 10]
I tout ce qui est déclaré est fourniI 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 = intlet inferieur = (<=)
end
module type TriEntier = TriFusion (Oentier)
let 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 = intlet inferieur = (<=)
end
module type TriEntier = TriFusion (Oentier)
let 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 pouvoirsavoir 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
Affichageprint_string : string -> unitprint_int : int -> unitprint_char : char -> unitprint_float : float -> unit
Lectureread_line : unit -> stringread_int : unit -> intread_float : unit -> float
63 / 84
Langage de Programmation 2 (LP2)Input OutPut
Conversions
Bool en plusint_of_string : string -> intstring_of_int : int -> stringfloat_of_string : string -> floatstring_of_float : float -> stringbool_of_string : string -> boolstring_of_bool : bool -> string
64 / 84
Langage de Programmation 2 (LP2)Input OutPut
Lecture
input_char : in_channel -> charinput_line : in_channel -> string# End_of_file ; ;- : exn = End_of_fileoutput_char : out_channel -> char -> unitoutput_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 lectureopen_in : string -> in_channel
# open_in “file” ; ;
Ouverture d’un fichier en écritureopen_out : string -> out_channel
# open_out “file” ; ;
Fermeture d’un canalclose_in : in_channel -> unitclose_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 pourpouvoir 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=42let 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 reste);;
T(n) = cn + T(n-1)T (n) = n2
80 / 84
Langage de Programmation 2 (LP2)Conclusion
Aujourd’hui
I CompilationI ModulesI FoncteursI Input Output
http ://caml.inria.fr/pub/docs/oreilly-book/html/book-ora132.html
82 / 84