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