Types, Expressions, Fonctions et constructions du langages ocaml

Transcription

Types, Expressions, Fonctions et constructions du langages ocaml
Université
Joseph
Fourier
UFR IMAG
Département
Licence Sciences
et Technologie
LICENCE SCIENCES & TECHNOLOGIES
1re année
INF121
ALGORITHMIQUE ET PROGRAMMATION FONCTIONNELLE
Introduction
Vous connaisssez le langage C, pourquoi apprendre un nouveau langage ?
langage
Ce n'est pas le
ocaml en lui-même qui est intéressant mais le modèle de programmation qui lui correspond :
la programmation fonctionnelle. Ce modèle de programmation induit une nouvelle façon de décomposer
et de résoudre un problème.
Pour un informaticien il est important de connaître plusieurs modèles de programmation pour choisir
celui qui est le plus adapté au problème qu'il doit résoudre, c'est-à-dire celui qui donnera le programme
le plus simple, le plus élégant avec le moins d'eort et de risque d'erreur.
Il n'y a pas de langage meilleur qu'un autre, ils sont tous aussi puissants : on sait que tout ce qu'on
peut faire dans l'un peut être fait dans l'autre. Mais la solution s'exprime peut-être plus simplement
dans l'un que dans l'autre. Par exemple,
s'il s'agit de programmer une carte vidéo et de manipuler des tableaux ; C sera bien adapté.
s'il s'agit de programmer des algorithmes qui ne travaillent pas sur des tableaux mais sur des structures récursives ; ce sera plus simple en
.
pour d'autes types de problèmes qui nécessitent de résoudre des contraintes ; le modèle de programmation logique par contrainte sera plus approprié.
Ce ne sont que quelques exemples parmi la dizaine de modèles de programmation connus à ce jour.
ocaml
La programmation fonctionnelle en ocaml est-elle diérente de la programmation impérative en C ? Le langage C est un représentant parmi d'autres (Java,Pascal,...) des langages dits
impératifs. Ils sont nommés ainsi pour indiquer que la programmation impérative consiste à donner des
ordres à la machine, par exemple :
x=3 : met la valeur 3 en mémoire dans la variable x !
for(i=0 ; i<5 ; i=i+1){...} : répète 5 fois . . . !
Le langage
ocaml fait partie des langages dits foncionnels, nommés ainsi pour indiquer que la pro-
grammation fonctionnel consiste à dénir des fonctions.
Dans les langages fonctionnels, l'aectation et les itérations (for,while) n'existent pas. Les seuls points
communs avec les langages impératifs sont le branchement conditionnel if...then...else... et la
dénition de fonctions. Les langages fonctionnels sont issues de la collaboration entre mathématiciens
et informaticiens :
ils ont la rigueur des mathématiques ;
ils reposent sur peu de concepts (type,fonction,récursivité) mais très puissants ;
ils sont aussi expressifs que les autres langages ;
ils insistent sur la dénition de types et la vérication de type permet d'éviter de très nombreuses
erreurs de programmation ;
ils apprennent à programmer en réechissant mathématiquement au problème.
ils résolvent élégamment certains problèmes compliqués.
Types, expressions, fonctions
et constructions du langage ocaml
2
Table des matières
1 Les types de base
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
Les booléens . . . . . . . . . . . . . . . . . . . . . .
Les nombres . . . . . . . . . . . . . . . . . . . . . .
Les caractères . . . . . . . . . . . . . . . . . . . . .
Les types séquences . . . . . . . . . . . . . . . . . .
Le type Texte . . . . . . . . . . . . . . . . . . . . .
1.5.1 Opérations sur les données de type Texte . .
1.5.2 Généralisation des opérations sur les textes
Le type Chaîne . . . . . . . . . . . . . . . . . . . .
Opérations de conversion entre Texte et Chaîne . .
Opérateurs de comparaison . . . . . . . . . . . . .
2 Dénition de types complexes
2.1
2.2
2.3
2.4
Dénir et nommer un type . . . .
Dénir un type par énumération
Construire un produit de types .
Construire une somme de types .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3.1
3.2
3.3
3.4
3.5
4.1
4.2
4.3
4.4
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
Expression conditionnelle . . . . . . . . . . . . . . . . .
Nommage d'une expression . . . . . . . . . . . . . . . .
Expression de ltrage . . . . . . . . . . . . . . . . . . . .
Expression de ltrage avec condition . . . . . . . . . . .
Filtrage avec condition versus conditionnelles imbriquées
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4 Dénition de fonctions
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3 Constructions du langage Ocaml
.
.
.
.
.
.
.
.
.
.
.
.
.
.
La spécication : un contrat entre l'utilisateur et le programmeur
Le programmeur est aussi l'utilisateur de ses propres fonctions . .
Dénition de fonctions partielles = fonctions avec condition . . .
Respectez la spécication laisse malgré tout de la liberté . . . . .
3
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
5
6
6
7
8
8
9
11
11
12
13
15
15
16
17
19
23
23
23
25
26
27
29
30
31
32
33
4
Chapitre 1
Les types de base
définition (Type d'une expression)
Les ordinateurs n'apprécient pas les ambiguités. Ils font la
distinction entre l'entier naturel 1 et le réel 0.99999... . En mathématique les deux versions sont égales,
tandis que pour un ordinateur, ces données sont de nature diérente1 , on dit qu'elles sont de type
diérent.
Notation
Toutes les expressions manipulées en informatique sont typées et on utlise la notation e
pour indiquer que l'expression e est de type T.
: T
Un type en informatique correspond à un ensemble de valeurs en mathématiques. Les mathématiciens et les informaticiens utilisent un vocabulaire et des notations diérentes mais équivalentes. On
peut donc indiéremment parler de types ou d'ensembles.
Remarque
mathématique
e∈T
informatique
se lit
e : T
se lit
la valeur de e appartient à l'ensemble T la valeur de l'expression e est de type T
Exemples
Z
2×n∈Z
5 : int
5∈
2 * n : int
mathématique informatique
Bool
bool
Z
R
int
float
Car
Chaîne
char
string
Les types de base sont limités mais il est possible de dénir de nouveaux types. On peut alors donner
très précisement le type d'une fonction comme on le fait en mathématique.
L'objectif de ce chapitre est de présenter les moyens de construire des types.
1
L'ordinateur n'utilise pas les mêmes quantités de mémoires pour stocker un entier ou un réel.
5
1.1 Les booléens
Les booléens vrai et faux qui appartiennent à l'ensemble mathématique Bool sont notées true et false
en
et sont de type bool.
ocaml
Opérations
Ocaml dénies sur les booléens
français
mathématique informatique type Ocaml des opérateurs
a
et
b
a∧b
a && b
bool → bool → bool
a
ou
b
a∨b
a || b
bool → bool → bool
a
¬a
not a
bool → bool
b1 = b2
(b1 = b2)
bool → bool → bool
b1 6= b2
(b1 <> b2)
bool → bool → bool
non
égalité
diérence
Exercice 1.1
Construire les tables de vérités des opérateurs et , ou , non . Vériez vos tables de
vérité en tp en tapant les expressions dans l'interpréteur Ocaml.
1.2 Les nombres
Z
Ocaml
Z
En
, les entiers relatifs ( ) sont notés int. Contrairement à qui est inni, int est un ensemble
ni : il contient uniquement les entiers représentables sur 32 ou 64 bits selon les processeurs. La taille
des entiers int est donc limitée par les capacités du processeur.
En
, les réels ( ) sont notés float. Une donnée de type float a une taille et une précision
limitée par la capacité du processeur.
Pour raisonner nous utiliserons les ensembles mathématiques suivants :
R
Ocaml
DÉFINITION MATHÉMATIQUE D'ENSEMBLES
déf
déf
déf
déf
déf
déf
N = Z+
N∗ = N \ {0}
Z∗ = Z \ {0}
R∗ = R \ {0}
R+ = {r | r ∈
R− = {r |
...
∧ r > 0}
...........
et aussi
déf
déf
N = {2k |
2N + 1 = {
2
..
∈
∧
N}
............
|
..........
}
les entiers naturels . . . . . . . . . .
...........
les entiers naturels impairs
}
6
Opérations
Ocaml dénies sur les entiers et les réels
mathématique informatique type Ocaml des opérateurs
français
addition
a + b
int → int → int
a +. b
float → float → float
a - b
int → int → int
a -. b
float → float → float
a * b
int → int → int
a *. b
float → float → float
a
b
a /. b
float → float → float
a÷b
a / b
int → int → int
a mod b
a mod b
int → int → int
a+b
soustraction
a−b
multiplication
a×b
division réelle
division entière
modulo
1.3 Les caractères
L'ensemble des caractères est noté Car. Cet ensemble mathématique rassemble tous les caractères. Il
correspond au type char en
. En mathématique et en informatique les valeurs de type caractère
sont notées entre guillemets simples (ex. 'c'). Pour faciliter le raisonnement on distingue plusieurs sous
ensembles de caractères.
Ocaml
DÉFINITION MATHÉMATIQUE D'ENSEMBLES
déf
Minuscule = {'a', . . . , 'z'}
déf
Majuscule = {'A', . . . , 'Z'}
déf
Lettre = Minuscule ∪ Majuscule
déf
Chire = {'0', . . . , '9'}
déf
Espace = {' ', '\t'}
déf
Saut de ligne = {'\n'}
déf
Symbole = les autres caractères du clavier
déf
Car = Lettre ∪ Chire ∪ Espace ∪ Symbole ∪ Saut de ligne
Opérations sur les données de type caractère
Les seuls opérateurs binaires associés au type caractère sont les opérations de comparaison (<=,<,>,>=),
le test d'égalité (=) et le test de diérence (<>) qui sont de type Car → Car → Bool.
Nous utiliserons aussi les fonctions suivantes :
SPÉCIFICATION MATHÉMATIQUE
Code ascii d'un caractère
Prol
int-of-char : Car → N
Sémantique : int-of-char (c) est le numéro du caractère c dans la table ascii
7
Exemples
1. int-of-char ('0') = 48
2. int-of-char ('a') = 97
SPÉCIFICATION MATHÉMATIQUE
Caractère correspondant à un code ascii
Prol
char-of-int : N → Car
Sémantique : char-of-int (n) est le neme caractère de la table ascii
Exemples
1. char-of-int (49) = '1'
2. char-of-int (65) = 'A'
1.4 Les types séquences
Les mathématiciens français et les informaticiens anglo-saxons utilisent un vocabulaire diérent pour
parler des séquences :
mathématique
informatique
séquence
list
séquence de caractères, en français character list, en anglais
char list en Ocaml
notée Séq (Car) en math
exemple :
[ 'o' ; 'c' ; 'a' ; 'm' ; 'l']
séquence d'entiers, en français
notée Séq (Z) en math
exemple :
integer list,
int list
en anglais
en Ocaml
[ 1; 3; 5; 7; 9 ]
La séquence vide est notée [ ]
L'ensemble des séquences non vide d'éléments de type T est noté Séq (T )∗ .
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Séq (T )∗ = Séq (T ) \ { [ ] }
1.5 Le type Texte
Texte désigne l'ensemble des séquences de caractéres (ex. ['o' ;'c' ;'a' ;'m' ;'l']).
Le texte vide est noté [ ].
Texte∗ désigne l'ensemble des textes privé du texte vide.
Plus précisement, on dénit l'ensemble Texte comme l'ensemble des séquences de caractères.
8
Texte
DÉFINITION MATHÉMATIQUE DE L'ENSEMBLE
déf
Texte = Séq (Car)
On traduit ensuite la dénition mathématique en un type informatique.
DÉFINITION INFORMATIQUE DU TYPE
texte
type texte = char list ;;
1.5.1 Opérations sur les données de type Texte
Le type Texte est muni des opérations dénies pour toute séquence (voir chapitre 2).
- Concaténation
L'opération de concaténation de deux séquences, noté @ permet de coller deux
textes. L'opérateur ( @ ) a pour type
..........
→
..........
→ Texte.
Exemple
['o' ;'c'] @ ['a' ;'m' ;'l'] = ['o' ;'c' ;'a' ;'m' ;'l']
Question
L'opération de concaténation peut-elle donner un texte vide ?
- Ajout à gauche
L'opérateur ( :: ) permet d'ajouter un caractère à gauche d'un texte,
il a pour type
→ Texte →
Exemple
.......
..
..........
.
'o' :: ['c' ;'a' ;'m' ;'l'] = ['o' ;'c' ;'a' ;'m' ;'l']
Quels que soient c une valeur de type Car et t une valeur de type Texte,
on a l'égalité c :: t = [c] @ t
Propriété
Autrement dit, ajouter un . . . . . . . . . . . . . . . à . . . . . . . . . . . d'un texte avec l'opérateur . . . . donne le
même résultat que . . . . . . . . . . . . . . .er le texte . . . . fait d'un . . . . . . caractère et le . . . . . . . . t à l'aide
de l'opérateur @ .
- Tête
La fonction hd est l'abbréviation du mot anglais head qui signie tête.
SPÉCIFICATION MATHÉMATIQUE
Premier caractère d'un texte
Prol
hd : Texte∗ → . . . . . . .
Sémantique : hd (t) est le premier caractère du texte t
Exemples
1. hd ['o'; 'c'; 'a'; 'm'; 'l'] = 'o'
2. hd [ ] provoque une erreur
- Queue
La fonction tl est l'abbréviation du mot anglais tail qui signie queue.
SPÉCIFICATION MATHÉMATIQUE
Texte sans son premier caractère
Prol
tl : Texte . . → . . . . . . . . . .
Sémantique : tl (t) est le texte t privé de son premier caractère
9
Exemples
1. tl
2. tl
['o'; 'c'; 'a'; 'm'; 'l'] = ['c'; 'a'; 'm'; 'l']
[]
provoque une erreur
Complétez les pointillés avec les types des expressions.
∀t ∈ Texte, on a l'égalité t = hd (t) :: tl (t)
Propriété
| {z }
......
- Dernier
|{z}
.........
SPÉCIFICATION MATHÉMATIQUE
Prol
dernier : . . . . . . . . . . . . → Car
Sémantique : dernier (t) est le dernier caractère du texte t
Exemples
1. dernier
['o'; 'c'; 'a'; 'm'; 'l'] =
2. dernier
[]
- Début
......
.....................................
SPÉCIFICATION MATHÉMATIQUE
Prol
debut : . . . . . . . . . . . . → Texte
Sémantique : debut (t) est le texte t privé de son dernier caractère
Exemples
1. debut
['o'; 'c'; 'a'; 'm'; 'l'] = [ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ]
2. debut . . .
provoque une erreur
Complétez les pointillés avec les types des expressions pour trouver l'opérateur manquant.
......
z }| {
∗
∀t ∈ Texte , on a l'égalité t = debut (t) . . . . [ dernier (t) ]
Propriété
| {z }
.........
|
{z
.........
}
Les fonctions hd, tl, dernier et début ne doivent pas être appliquées à un texte vide. Cela
provoquerait une erreur d'exécution du programme signalée par Exception : message d'erreur .
Remarque
10
Complétez les pointillés avec les types des expressions, trouvez les opérateurs manquants, en
déduire la spécication de la fonction coeur et réaliser la fonction coeur à l'aide des fonctions précédentes
sur les textes.
Exercice
.......
∀t ∈ Texte,
on a l'égalité
t
|{z}
z }| {
= hd (t)
....
Prol
coeur :
. . . . . . dernier (t) . .
z
|
..........
SPÉCIFICATION MATHÉMATIQUE
..........
Texte
z }| {
coeur (t)
}|
{z
{
..........
}
de la fonction coeur
............ → ..........
Sémantique : coeur (t) retourne le texte t . . . . . . . . . de . . . . . . . . . . . . . . . . . . . . . . et de . . . . . . . . . . . . . . . . . . .
................
RÉALISATION INFORMATIQUE
Algorithme : coeur (t) = . . . ( . . . . . . . . . . ( t ))
1.5.2 Généralisation des opérations sur les textes
Les textes sont des séquences de caractères.
Les opérations précédentes sur les textes peuvent s'appliquer à tout sorte de séquences. Par exemple,
l'opération d'ajout à gauche peut s'appliquer à des séquences contenant des valeurs d'un type T quelconque.
Exercice
Prol
( :: ) : T → Séq (T ) → Séq (T )
En vous inspirant de cet exemple, complétez les prols génériques des opérateurs et des fonctions suivantes :
. . . . . . . . . . . . . → . . . . . . . (T ) → Séq ( . . . )
Prol
(@) :
Prol
hd : Séq (T )∗ → . . .
Prol
tl : . . . . . . . . . . . . . . . → Séq ( . . . )
Prol
debut : . . . . . . . . . . . . . . . → Séq ( . . . )
Prol
dernier : . . . . . . . . . . . . .
∗
→
...
1.6 Le type Chaîne
Pour programmer on utilise souvent les chaînes de caractères qui ore une notation plus compacte
que les séquence de caractères. Les chaînes de caractères sont notées entre des guillemets doubles (").
L'ensemble des chaînes de caractères est noté Chaîne. Le type
correspondant à l'ensemble
Chaîne est string.
Ocaml
11
Opération de concaténation sur les données de type Chaîne
SPÉCIFICATION MATHÉMATIQUE
concaténation de chaînes de caractères
( ˆ ) : Chaîne → Chaîne → Chaîne
Prol
Exemples :
1. ("o" ˆ "caml") = ("oc" ˆ "aml") = . . . = ("oca" ˆ "ml") = ("ocam" ˆ "l") = "ocaml"
2. ("" ˆ "ocaml") = "ocaml" = ("ocaml" ˆ "")
Propriété
∀ch ∈ Chaîne, on a l'égalité ("" ˆ ch) = ch = (ch ˆ "")
1.7 Opérations de conversion entre Texte et Chaîne
Il ne faut pas confondre les chaînes de caractères de type Chaîne et les séquences de caractères de type
Texte. Ce sont des données de nature diérente. Retenez que Chaîne 6= Texte.
; 'm'; 'l']
"ocaml"
| {z } 6= |['o'; 'c'; 'a'
{z
}
Chaîne
Texte
En revanche les fonctions ci-apprès permettent de passer des chaînes de caractères aux séquences de
caractères et vice-versa.
texte vers chaine
tvc : Texte → Chaîne
SPÉCIFICATION MATHÉMATIQUE
Prol
Exemples :
1. tvc ['o' ;'c' ;'a' ;'m' ;'l'] = "ocaml"
2. tvc [ ] = ""
chaine vers texte
cvt : Chaîne → Texte
SPÉCIFICATION MATHÉMATIQUE
Prol
Exemples :
1. cvt "ocaml" = ['o' ;'c' ;'a' ;'m' ;'l']
2. cvt "" = [ ]
Propriété
Complétez les pointillés avec le type des expressions.
.............
1.
∀t ∈ Texte,
on a l'égalité
z }| {
cvt (
tvc (t)
|
{z
..........
)= .
}
|{z}
Texte
Texte
2.
∀c ∈
............. ,
on a l'égalité
z }| {
. . . . . . ( . . . . . . (c) ) =
|
{z
Chaîne
12
}
c
|{z}
.............
Remarque
Prenez garde à ne pas confondre, le caractère 'a'
Chaîne et ['a'] qui est de type Texte, c'est-à-dire Séq (Car).
de type Car avec "a" qui est de type
1.8 Opérateurs de comparaison
Les opérateurs de comparaison (<=,<,>,>=), le test d'égalité (=) et le test de non-égalité (6=) noté <>
en
sont dénis pour tous les types
et sont automatiquement créés lorsqu'on dénit un
nouveau type
. Ils ont donc un prol générique : T → T → Bool.
ocaml
ocaml
ocaml
13
14
Chapitre 2
Dénition de types complexes
2.1 Dénir et nommer un type
Les dénition de types permettent de décrire des données très complexes manipulées par un programme
et de leur donner des noms simples et intuitifs qui rendront les programmes plus compréhensibles.
L'utilisation de noms bien choisis facilite la conception, la mise au point, la lecture, la maintenance et
la réutilisation des programmes.
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Nom du type = ensemble mathématique
DÉFINITION INFORMATIQUE D'UN TYPE
type nom du type =
|
{z
}
une construction de type ocaml ;;
en minuscule
Le type Texte que nous avons déjà utilisé n'est pas un type prédéni du langage ocaml. On
dénit l'ensemble des textes comme l'ensembles des séquences de caractères.
Exemple
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Texte = Séq (Car)
DÉFINITION INFORMATIQUE D'UN TYPE
type texte = char list ;;
Mathématiquement un Alphabet est une séquence de lettres minuscules. Complétez les dénitions ci-dessous.
Exercice
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Alphabet = Séq ( . . . . . . . . . . . . . . . . . . . )
15
DÉFINITION INFORMATIQUE D'UN TYPE
type ................ = minuscule ........ ;;
2.2 Dénir un type par énumération
On peut dénir un ensemble en énumérant tous ses éléments. On peut dénir un type de la même
manière.
Exemple 1
Le type des booléens est déni par une énumération nie.
DÉFINITION MATHÉMATIQUE DE L'ENSEMBLE
déf
Bool
Bool = {vrai , faux }
DÉFINITION INFORMATIQUE DU TYPE
Le type bool est déjà déni en
type bool = true | false ;;
caml
Le type énuméré famille correspond à l'ensemble Famille de cartes est déni par l'énumération de ses éléments :
Exemple 2
DÉFINITION MATHÉMATIQUE DE L'ENSEMBLE
déf
Famille
F amille = {♥, ♦, ♠, ♣}
DÉFINITION INFORMATIQUE DU TYPE
type famille =
famille
Coeur | Carreau | Pique | Trefle
|
{z
}
;;
Les noms de constantes symboliques doivent commencer par une Majuscule
Exemple 3
Le type Mois est déni par énumération.
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Mois = {Jan, Fev, Mar, Avr, Mai, Juin, Jul, Aou, Sep, Oct, Nov, Dec}
DÉFINITION INFORMATIQUE D'UN TYPE
type mois = Jan | Fev | Mar | Avr | Mai | Juin | Jul | Aou | Sep | Oct | Nov | Dec ;;
Jan, Fev, . . . , Dec sont des constantes symboliques qui n'ont pas de valeur.
Il ne faut pas confondre les constantes du type énuméré Mois avec les textes "Jan","Fev",...,"Dec".
Remarque importante
"Jan"
| {z } 6=
chaîne
Jan
|{z}
6=
constante symbolique
16
['J' ;'a' ;'n']
|
{z
}
séquence de caractères
2.3 Construire un produit de types
définition
(Vecteurs et produit cartésien d'ensembles
vs. n-uplets
et produit de
Les informaticiens et les mathématiciens utilisent un vocabulaire diérent pour parler de la
même chose. Il faut connaître les deux terminologies. Les vecteurs des mathématiques sont appelés
n-uplets en informatique où n indique la taille du vecteur.
types)
mathématique
le vecteur (π, 0)
appartient à R × R
le produit cartésien d'ensemble
informatique
le 2-uplet (3.14159,0.0)
est de type float * float
le produit de type
Z × Minuscule × Bool
contient le vecteur (1,
int * minuscule * bool
'a', vrai )
accepte le 3-uplet (1,'a',true)
Z
Les éléments du produit cartésien d'ensembles × Minuscule × Bool sont les vecteurs à 3 composantes
constitués d'un entier, d'une lettre minuscule et d'un booléen. Le type correspondant à cet ensemble
est le type produit int * minuscule * bool dont les éléments sont des 3-uplets.
Exemple 1 : le type Coordonnées Les coordonnées des points du plan sont des couples (x, y) qui appartiennent à R2 . On peut dénir le Coordonnées qui traduira notre intention de modéliser des coordonnées
par des couples de réels.
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Coordonnées = R × R
DÉFINITION INFORMATIQUE D'UN TYPE
type coordonnees = float * float ;;
On peut alors dénir et utiliser des variables de type coordonnées
mathématique
posons
c ∈ Coordonnées = (0.5, 2.1)
informatique
let (c : coordonnees) = (0.5,2.1) ;;
l'interpréteur
caml répond
val c : c = (0.5, 2.1)
Ensuite, il est possible de décomposer c an de retrouver ses composantes
posons
let (x,y) = c ;;
(x, y) = c
l'interpréteur
vaut donc 0.5
y vaut donc 2.1
caml répond
val x : float = 0.5
x
val y : float = 2.1
17
Une date peut être représentée sous la forme d'un vecteur (j, m, a) où j
indique le numéro du jour dans le mois, m est le mois et a l'année. Cette représentation correspond à la
dénition mathématique d'un ensemble produit :
Exemple 2 : le type Date
DÉFINITION MATHÉMATIQUE D'ENSEMBLES
déf
Jour = {1, . . . , 31}
déf
Mois = {Jan, Fev, Mar, Avr, Mai, Juin, Jul, Aou, Sep, Oct, Nov, Dec}
déf
Année = Z
déf
Date = Jour × Mois × Année
DÉFINITION INFORMATIQUE DE TYPES
type
type
type
type
jour
mois
annee
date
=
=
=
=
int ;; (* {1,...,31} *)
Jan | Fev | Mar | Avr | Mai | Juin | Jul | Aou | Sep | Oct | Nov | Dec
int ;;
jour * mois * annee ;;
;;
Les valeurs de type date sont donc des 3-uplets constitués d'un entier (restreint à {1, ..., 31}),
d'un mois dont les valeurs sont des constantes et d'un entier. Voici quelques exemples de
valeurs de type date :
(31,Dec,-5000) et (1,Jan,2008) sont de type date et respectent les contraintes indiquées en commentaire.
(64,Oct,2008) est acceptée par le type date mais ne respecte pas les contraintes indiquées en commentaire.
Remarque
On a choisi de représenter l'ensemble Jour par le type int en prenant soin d'ajouter en
commentaire une contrainte qui précise qu'on considère uniquement les entiers entre 1 et 31. Dans ce cas
l'interprète Ocaml considerera tout entier comme un jour acceptable et ne signalera pas d'erreur si on
utilise 999 comme un numéro de jour. On aurait pû faire un autre choix et dénir jour comme un type
énuméré :
DÉFINITION INFORMATIQUE D'UN TYPE
type jour = J1 | J2 | J3 | J4 | ... | J29 | J30 | J31 ;;
ocaml
Dans ce cas
peut faire des vérications très précise mais on ne peut plus faire de
calculs sur les jours car J1, . . . , J31 ne sont pas des nombres, ce sont justes des noms de
constantes.
Voici quelques exemples de valeurs de type date correspondant à cette seconde dénition :
(J31,Dec,-5000) et (J1,Jan,2008) sont de type date
(J64,Oct,2008) n'est pas accepté par le type date
Que dire de (J31,Fev,2000) ?
Exemple 3 : les types Valeur et Figure On aimerait dénir l'ensemble des cartes à jouer. On distingue
l'ensemble des Figures (As, Rois, Dames, Valets) et celui des Valeurs de 7 à 10 pour les diérentes familles
possibles ♥, ♦, ♠, ♣.
18
DÉFINITION MATHÉMATIQUE D'ENSEMBLES
déf
Famille = {♥, ♦, ♠, ♣}
déf
Tête = {As, Roi, Dame, Valet}
déf
De7à10 = {7, 8, 9, 10}
déf
Figure = Tête × Famille
As, ♥), (Roi, ♥), (Dame, ♥), (Valet, ♥), . . . , (Valet, ♣)}
= {(
déf
Valeur = De7à10 × Famille
= {(7, ♥), . . . , (10, ♥), (7, ♦), . . . , (10, ♦), (7, ♠), . . . , (10, ♠), (7, ♣), . . . , (10, ♣)}
DÉFINITION INFORMATIQUE DE TYPES
type famille = Coeur | Carreau | Pique | Trefle ;;
type tete
= As | Roi | Dame | Valet ;;
type de7a10 = V7 | V8 | V9 | V10 ;;
type figure = tete * famille ;;
type valeur = de7a10 * famille ;;
2.4 Construire une somme de types
On peut dénir un type comme la réunion de plusieurs types à condition de nommer chacuns des types
que l'on souhaite réunir. On dit qu'on fait la somme des types.
Exemple 1
On aimerait dénir le type Nombre comme l'union de l'ensemble des entiers et de celui
des réels. C'est inacceptable en informatique car les entiers et les réels ne sont pas de même nature.
Les ordinateurs doivent distinguer les entiers et les réels car les opérations sur les réels
et celles sur les entiers sont eectuées par des parties diérentes du processeur : le calculateur pour les
calculs ottants est diérent du calculateur utilisé pour les calculs sur les entiers.
Pour réunir les entiers et les réels en un seul type Nombre il faut faire la somme des types à l'aide de
constructeurs.
On crée un constructeur Entier qui prend en argument une donnée de type Z et construit une
donnée de type Nombre .
Le constructeur Entier est de type : Z → Nombre.
Entier(7) est une donnée de type Nombre .
On crée un constructeur Reel qui prend en argument une donnée de type R et construit une donnée
de type Nombre .
Le constructeur Reel est de type : R → Nombre.
Reel(3.14) est une donnée de type Nombre .
Les deux constructeurs Entier et Reel construisent des Nombres.
Le nom du constructeur permet à l'interprète Ocaml de distinguer si le nombre est un entier ou un
réel bien que Entier(7) et Reel(3.14) soient deux données du même type Nombre .
Grâce aux constructeurs on a donc réussi à réunir les types entiers et réels tout en préservant leurs
diérences.
Remarque
19
Les ensembles { Entier(e) | e ∈ Z} et
Nombres donc on peut en faire l'union.
{
Reel(r) | r ∈ R} sont tous deux des ensembles de
DÉFINITION MATHÉMATIQUE DE L'ENSEMBLE
déf Nombre = { Entier(e) | e ∈ Z}
∪
{
Nombre
Réel(r) | r ∈ R}
DÉFINITION INFORMATIQUE DU TYPE
nombre
type nombre = Entier of int
| Reel of float ;;
À retenir
Pour réunir des types incompatibles,
on utilise un procédé qui consiste à ajouter le nom du type devant ses valeurs. On dénit un nouveau
type qui fait la somme des types en utilisant des constructeurs.
Principe de construction d'un type somme
Exemple 2
On aimerait maintenant dénir le type Carte comme l'union des ensemble Valeur et
Figure dénis précédemment. C'est impossible car les éléments de ces ensembles ne sont pas de même
nature :
et (As, ♥) sont de type diérent : De7à10 × Famille 6= Tête × Famille
La seconde composante est de type Famille dans les deux cas mais la première composante est de type
entier dans (7, ♥) tandis qu'elle est de type Tête dans (As, ♥).
Pour réunir les ensembles Valeur et Figure il faut faire la somme des types à l'aide de constructeurs.
On crée un constructeur Valeur qui prend en argument une donnée de type Valeur et construit
une donnée de type Carte .
Le constructeur Valeur est de type : Valeur → Carte.
(7, ♥)
est une donnée de type Valeur ; Valeur(7, ♥) est une donnée de type Carte .
On crée un constructeur Figure qui prend en argument une donnée de type et construit une donnée
de type Carte .
Le constructeur Figure est de type : Figure → Carte.
(7, ♥)
As, ♥) est une donnée de type Figure ; Figure(As, ♥) est une donnée de type Carte .
Les deux constructeurs Valeur et Figure construisent des Cartes.
Les ensembles { Valeur(v) | v ∈ Valeur} et { Figure(f ) | f ∈ Figure} sont tous deux des
(
ensembles de Cartes donc on peut en l'union.
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf Carte = { Valeur(v) | v ∈ Valeur}
∪ { Figure(f ) | f ∈ Figure}
DÉFINITION INFORMATIQUE D'UN TYPE
type carte = Valeur of valeur
| Figure of figure ;;
On aurait pû dénir le type Carte directement sans dénir les types Valeur et Figure . Voici ce qu'on
écrirait dans ce cas. Le deux solutions sont totalement équivalentes.
20
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf Carte = { Valeur(v) | v ∈ {7, . . . , 10} × Famille}
∪ { Figure(f ) | f ∈ Tête × Famille}
DÉFINITION INFORMATIQUE D'UN TYPE
type carte = Valeur of de7a10 * famille
| Figure of tete * famille ;;
Exercice
a) Dénissez
mathématiquement l'ensemble Jeu de carte comme l'ensemble des séquences de cartes puis
le type Ocaml correspondant.
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Jeu de carte = . . . . . . . ( . . . . . . . . . . )
DÉFINITION INFORMATIQUE D'UN TYPE
type jeu_de_carte = .......... ........ ;;
b)
Dénissez les-carreaux comme la séquence des cartes de la famille ♦.
SPÉCIFICATION MATHÉMATIQUE
posons les-carreaux = [Valeur(7, ♣) ; . . . ;
Valeur(10, ♣) ; Figure(Valet, ♣) ;
RÉALISATION INFORMATIQUE
let (les_carreaux : ........................) =
[ Valeur(7,Carreau) ; .................................. ;
.................................. ; ............(10,Carreau) ;
............(Valet,Carreau) ; Figure(........,Carreau) ;
]
;;
...................................... ; ....................................
21
... ;
Figure(As, ♣)]
22
Chapitre 3
Constructions du langage
Ocaml
définition
On appelle expression les constructions du langage qui ont une valeur. Les constructions qui n'ont pas de valeur sont des instructions.
Exemple
L'aectation x ← 2 des langages impératifs est une instruction : x ← 2 n'a pas de valeur.
x+1 est une expression : x+1 représente une valeur.
Remarque
Dans les langages fonctionnels purs toutes les constructions ont une valeur, ce sont des
expressions. En particulier, l'aectation n'existe pas !
3.1 Expression conditionnelle
Le branchement conditonnel est exprimé par la construction
(if cond then expr1 else expr2 )
C'est une expression qui a pour valeur celle de l'expression expr1 ou de l'expression expr2 selon la
valeur de la condition booléenne cond. Précisement :


expr1 si cond vaut true
(if cond then expr1 else expr2 ) =
 expr si cond vaut false
2
Règle de typage
La construction (if ..then ..else ..) doit respecter les contraintes de typage :
(if
cond
| {z }
then expr1 else expr2 )
| {z }
| {z }
........
|
...
{z
...
}
...
La construction (if cond then expr1 ) sans partie else est interdite car lorsque cond
vaut false, l'expression (if cond then expr1 ) n'a pas de valeur.
Remarque
3.2 Nommage d'une expression
Les mathématiciens utilisent abondamment la construction
posons
x ∈ T = expression
qui permet de donner un nom x à une expression. On utilise alors le nom x plutôt que de réécrire
expression (qui peut être complexe ou pénible à écrire). Cette construction existe en Ocaml et se note
en anglais :
23
let (x : t) = expression ;;
Ocaml. On dit que la dénition
Le x de type t ainsi déni peut être utilisé partout dans le programme
de x a une portée globale, c'est-à-dire qu'elle porte sur tout le programme.
Exemple
SPÉCIFICATION MATHÉMATIQUE
RÉALISATION INFORMATIQUE
posons π ∈ R = 3, 141592653589
let (pi:float) = 3.141592653589 ;;
Restriction de la portée d'une dénition
Lorsqu'on veut utiliser la valeur de x uniquement dans
une expression on peut limiter la portée de la dénition de x. On utilise pour cela la construction :
posons
qui se note en
x = expression
Ocaml :
dans
expr
où expr est une expression utilisant x
let x = expression in expr ;;
Principe d'évaluation
suivante :
La construction let ... in ... est une expression qui s'évalue de la manière
1. on commence par évaluer l'expression,
2. on remplace dans expr toutes les occurrences de x par la valeur de expression,
3. on évalue expr.
Exemple
let x = max (3,4) in x + max (5, x)
est équivalent à
max (3,4) + max (5, max (3,4))
Règle de typage
La construction let ... in ... doit respecter les constraintes de type :
(let |{z}
x = expression in expr utilisant x)
| {z }
|
{z
}
...
|
...
....
{z
}
....
Cette construction a l'avantage de n'évaluer qu'une fois l'expression expr.
Le nom x introduit est local à la construction let ... in ..., c'est-à-dire que x n'est pas connu en dehors de
la partie expr. On dit que la portée du nom x se limite à la partie expr.
Remarque 1
Remarque 2
Il est possible d'imbriquer les expressions let ... in ... et d'eectuer plusieurs nommages
simultanément (let x1 = expr1 and x2 = expr2 in ...).
La construction let utilisée de la manière suivante :
let (x,y) = v ;;
permet de décomposer un vecteur v en chacunes de ses composantes x, y, comme dans l'exemple du type
Coordonnées du Ÿ2.3 et l'exercice sur les relations entre intervalles.
Remarque 3
24
3.3 Expression de ltrage
Le ltrage permet d'associer des valeurs à des motifs reconnaissables. Pour réaliser un ltrage en
on utilise la construction (match .. with ..) que l'on peut traduire par (reconnaître .. parmi
..).
Ocaml
Notation et principe d'évaluation
(match expr with
| motif 1 -> expr1
| ...
| motif n -> exprn
)
Cette construction s'évalue de la manière suivante : on compare la valeur de l'expression expr avec le
premier motif motif 1 , si ce motif reconnaît expr le résultat de la construction (match .. with ..)
est la valeur de l'expression expr1 ; sinon on passe au motif suivant. Si aucun motif n'a reconnu la
valeur expr, l'évaluation échoue et provoque une erreur.
Exemple 1
Le ltrage permet d'associer le nombre de jour à une variable m de type Mois (voir 2.2).
Chaque motif essaie de reconnaître la valeur m et rend le nombre de jour correspondant. Remarquez
qu'on peut regrouper les motifs qui rendent le même résultat.
(match
| Fev
| Avr
| Jan
)
m with
-> 28
| Juin | Sep -> 30
| Fev | Mar | Mai | Jul | Aou | Oct | Dec -> 31
Vous constatez que le programmeur a oublié le mois de novembre. L'interprète
toutes les valeurs possibles du type mois ;
il découvre qu'il manque le mois de novembre et ache le message suivant1 :
Remarque 1
Ocaml détecte cet oubli : il vérie que les motifs couvrent
Warning: this pattern-matching is not exhaustive.
Here is an example of a value that is not matched: Nov
La vérication de l'exhaustivité du ltrage permet à
programmeur de la corriger.
Ocaml de détecter une erreur et permet au
Vous constatez que le programmeur a mis deux fois le mois de février et donne deux
valeurs diérentes pour Fev : 28 et 31. L'interprète Ocaml détecte cette incohérence, souligne le motif
qui pose probléme (le second Fev) et ache le message suivant2 :
Remarque 2
Warning: this match case is unused.
La vérication de l'exhaustivité du ltrage permet à
programmeur de la corriger.
Ocaml de détecter une erreur et permet au
À retenir
Lorsqu'on utilise une expression de ltrage, il faut qu'elle soit exhaustive, c'est-àdire qu'elle comporte un motif pour chaque valeur possible de expr. Dans le cas contraire, l'interprète
Ocaml signalera une erreur.
L'expression de ltrage suivante associe à la variable c de type Carte (voir page 19) un
nombre de points correspondant à son rang.
Exemple 2
1
(Traduction) Attention : cette reconnaissance de motif n'est pas complète. Voici un exemple de valeur qui n'est pas
reconnue : Nov
2
(Traduction) Attention : ce motif n'est jamais utilisé.
25
(match c with
| Valeur(v,f) -> v
| Figure(Valet,f) -> 11
| Figure(Dame,f) -> 12
| Figure(Roi,f) -> 13
| Figure(As,f) -> 14
)
Exemple 3
minuscule.
L'expression de ltrage suivante vaut vrai
si et seulement si
la variable l est une voyelle
(match l with
| 'a' | 'e' | 'i' | 'o' | 'u' | 'y' -> true
| _ -> false
)
Le motif - est le motif universel. Il reconnaît toutes les expressions et les accepte
sans condition. Il faut donc toujours le placer en dernier.
D'autre part, lorsqu'on utilise -, le ltrage est forcément exhaustif et cela empêche caml de détecter
des oublis du programmeur. Il faut donc utiliser - avec précaution et parcimonie ; uniquement quand
l'énumération est très très longue ou impossible.
Remarque
Règle de typage
La construction (match .. with ..) doit respecter les contraintes de typage :


T


















z }| {

match expr with 

| motif 1 -> expr1 
| {z } 
| {z }


0

T
T



| ...


| motif n -> exprn 
| {z } 
| {z }

T
est de type T 0
T0
3.4 Expression de ltrage avec condition
La construction motif when condition -> résultat permet d'ajouter une condition à une reconnaissance par motif.
Notation et principe d'évaluation
(match expression with
| motif 1 when condition1 -> expr1
| ...
| motif n when conditionn -> exprn
)
Une branche du ltrage match expression with sera prise uniquement
sont réunies :
1. L'expression est reconnue par le motif
2. L'évaluation de la condition associée donne vrai
26
quand les deux conditions
L'expression de ltrage ci-dessous permet de calculer le nombre de point correspondant à une
variable c de type Carte en tenant compte de la variable atout de type Famille (voir page 19).
Exemple 4
Implantation à l'aide de motifs avec condition
match c with
| Valeur(9,f) when f = atout -> 15
| Figure(Valet,f) when f = atout -> 30
| Valeur(v,_) -> v
| Figure(Valet,_) -> 11
| Figure(Dame,_) -> 12
| Figure(Roi,_) -> 13
| Figure(As,_) -> 14
;;
Dans une expression de ltrage on peut avoir des motifs avec et des motifs sans condition.
On ajoute des conditions au motifs uniquement lorsque c'est nécessaire.
Remarque
Exemple 5
dénis par :
L'expression de ltrage ci-dessous doit donner le Signe de l'entier x parmi les trois cas possibles
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
Signe = {Negatif, . . . . . . . . , Positif}
DÉFINITION INFORMATIQUE D'UN TYPE
type signe = .............. | Nul | Positif ;;
Implantation incorrecte
match x with
| x when x>0 -> Positif
| x when x<0 -> Negatif
;;
Remarque
Il est important que l'expression de ltrage soit exhaustive. Ici, le programmeur a oublié un
cas. Si x = 0 l'évaluation de l'expression de ltrage produira une erreur : Exception: Match_failure.
qui signie erreur de ltrage.
Implantation correcte
match x with
| x when x>0 -> Positif
| x when x<0 -> Negatif
| _ -> ......
;;
27
3.5 Filtrage avec condition versus conditionnelles imbriquées
Le ltrage avec conditions permet de réaliser des if...then...else... imbriqués. Il n'y a pas une solution
qui soit systématiquement meilleure que l'autre. Il faut choisir celle qui est la plus élégante.
On reprend l'exemple du signe d'un entier x ∈ Z et on souhaite écrire une fonction signe-de
qui donne le signe de x.
Exemple
SPÉCIFICATION MATHÉMATIQUE
Prol
signe-de : Z → Signe
Sémantique : signe-de (x) est le signe de l'entier x
Exemples
1. signe-de (0) = Nul
2. signe-de (1) = Positif
3. signe-de (-1) = Negatif
RÉALISATION INFORMATIQUE
Implantation 1 à l'aide de if...then...else... imbriqués
let (signe-de : int -> signe) =
function x -> if x<0 then ...............
else if ...... then Positif
else (* x=0 *) ......
;;
Implantation 2 à l'aide d'un ltrage avec condition
let (signe-de : int -> signe) =
function x -> match x with | x when x<0 -> ...............
| x when ...... -> Positif
| x when x=0 -> ......
;;
Remarque
La partie encadrée est inutile en caml et on peut se contenter d'écrire :
Implantation 2' : autre notation acceptée par caml
let (signe-de : int -> signe) =
function
| x when x<0 -> ...............
| x when ...... -> Positif
28
;;
| x when x=0 -> ......
Remarquez que la partie x -> match x with est optionnelle.
L'implantation 2' se lit de la manière suivante : signe-de est une fonction qui donne Negatif quand x < 0,
qui donne Positif quand x > 0 et Nul quand x = 0.
29
30
Chapitre 4
Dénition de fonctions
En informatique la dénition d'une fonction doit comporter deux parties :
1. une spécication c'est-à-dire une description mathématique de la fonction présentée ainsi :
SPÉCIFICATION MATHÉMATIQUE
Prol
nom de la fonction : type de la fonction
Sémantique : rôle de la fonction
2. une réalisation de la fonction dans un langage de programmation présentée ainsi :
RÉALISATION INFORMATIQUE
Algorithme : l'algorithme décrit le principe utilisé pour réaliser la fonction
Implantation (en caml dans ce cours)
let (nom de la fonction : type de la fonction ) = function ...
Exemple 1 : maximum de deux entiers
SPÉCIFICATION MATHÉMATIQUE
(fournie par l'utilisateur au programmeur)
Prol
max2 : Z × Z → Z
Sémantique : max2 (x, y) est le plus grand des entiers x et y
Exemple :
max2 (0, 1) = 1
Propriétés
1.
2.
Z
∀x ∈ Z, max2 (x, −x) = |x|
∀x ∈ , max2 (x, x) = x
31
RÉALISATION INFORMATIQUE
Algorithme : max2 (x, y) =
(mise au point par le programmeur de manière à
respecter la spécication de l'utilisateur)



 x
si
x>y
y si x < y



x (ou y) si x = y
Implantation en caml
let (max2 : int * int -> int) =
function (x , y) ->
if (x>y) then x else y
;;
4.1 La spécication : un contrat entre l'utilisateur et le programmeur
En informatique, on distingue deux parties dans la dénition d'une fonction :
1. la spécication mathématique de la fonction. Elle décrit :
les conditions d'utilisations de la fonction (son prol), c'est-à-dire quels paramètres il faut lui donner :
combien et de quels types, quels résultats elle rend : combien et de quels types ;
ce que fait la fonction (sa sémantique), c'est-à-dire quel résultat elle rend et les propriétés de ce
résultat (les exemples et les propriétés).
2. la réalisation informatique de la fonction. Elle décrit le principe (l'algorithme) qui permet de produire le résultat attendu et fournit une version de l'algorithme écrit un langage de programmation
(l'implantation).
La spécication mathématique est destinée à l'utilisateur de la fonction qui veut savoir comment il l'utiliser.
La réalisation informatique est faîte par le programmeur qui doit trouver et implanter un algorithme qui
respecte la spécication informatique. La spécication informatique joue le rôle d'un contrat entre un client
(l'utilisateur ) et le fournisseur (le programmeur ).
Exemple 2 : on réutilise le type Mois déni page 16. Imaginons qu'un utilisateur ait besoin d'une
fonction juste-avant qui prend un couple de Mois (m1 , m2 ) et qui vaut vrai si le mois m1 est exactement
le mois avant m2 . On convient que le mois de décembre est avant le mois de janvier de l'année suivante.
L'utilisateur s'adresse à vous, programmeur caml. Il vous donne la spécication et vous devez réaliser la
fonction.
SPÉCIFICATION MATHÉMATIQUE
Prol
juste-avant : Mois × Mois → Bool
Sémantique : juste-avant (m1 , m2 ) est vraie si et seulement si m1 est le mois qui précède m2
Exemple :
Les exemples servent à préciser le résultat attendu dans les cas particuliers, comme :
juste-avant (Dec, Jan) = vrai
Propriété
∀m ∈ Mois, juste-avant (m, m) = faux
32
RÉALISATION INFORMATIQUE
Algorithme c'est la description du principe qui permet d'arriver au résultat : On énumère l'ensemble des . . . . couples (m1 , m2 ) qui satisfont la relation est juste avant :
Jan, Fev), (Fev, Mar),
{(
Dec, Jan)}
..., (
Implantation c'est la traduction du principe dans un langage de programmation
let (juste_avant : mois * mois -> ........) =
function
( m1 , m2 ) ->
match (m1,m2) with
| (Jan,Fev) | .................. | ..................
| ..................
| .................... | .................... | .................... | ....................
| (......,......) | (......,......)
;;
| (......,......)
| (Dec,Jan)
-> ........
| _ -> ..........
4.2 Le programmeur est aussi l'utilisateur de ses propres fonctions
Souvent les programmeurs travaillent en équipe : ils utilisent les fonctions des autres et pour cela ils lisent les
spécications an de savoir comment bien utiliser la fonction d'un autre ou bien ils écrivent la spécication
d'une fonction et c'est un autre programmeur qui la réalisera. Un programmeur est aussi l'utilisateur de ses
propres fonctions et la spécication est utile pour se souvenir rapidement de ce que fait une fonction qu'il
a écrite des mois ou des années auparavant. Dans tous ces cas il est utile d'écrire la spécication pour se
souvenir de la bonne manière d'utiliser une fonction.
Exemple 3 : on réutilise le type Nombre déni page 19. Imaginons qu'en tant qu'utilisateur vous ayez
besoin d'une fonction qui prend en paramètre deux Nombre et les additionne. On commence par rédiger la
spécication an de décire le rôle de la fonction avant de la réaliser.
SPÉCIFICATION MATHÉMATIQUE
Prol
addition : . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . → Nombre
Sémantique : addition (n1 , n2 ) est le nombre Entier ou Reel correspondant à l'addition la plus
précise possible des valeurs représentées par n1 et n2
Exemples :
1. addition (Entier(e1 ), Entier(e2 )) = Entier(e1 + e2 )
2. addition (Entier(e), Reel(r)) = Reel( . . . . . . . . . . . . . . . . . . . . . (e) +. r)
|
{z
on convertit e en
}
.....
RÉALISATION INFORMATIQUE
Algorithme : Selon le type de n1 et de celui n2 on choisit l'opérateur d'addition à utiliser parmi
33
Prol
(+) : int → int → int
Prol
(+.) : float → float → float
Lorsque c'est nécessaire on convertit un entier en réel grâce à la fonction
Prol
float-of-int : int → float
Cette convertion ne perd pas de précision car
Z . . . R.
Implantation
let (addition : nombre * ............ -> ............) =
function
(n1 , n2)
->
match (n1,n2) with
| (Entier(e1), Entier(e2)) -> ............( e1 + e2 )
;;
| (........(r1) , Réel(r2))
-> ........( r1 +. r2 )
| (............(e), Réel(r))
-> ........( (float_of_int e) .... r )
| (........(r) , Entier(e)) -> ........( r +. ................................ )
4.3 Dénition de fonctions partielles = fonctions avec condition
Une fonction partielle sur les entiers est une fonction qui n'est pas dénie pour tous les entiers possibles. C'est
par exemple le cas de la division euclidienne de a par b qui est dénie uniquement b > 0. La construction
when permet de signaler dans l'implantation de la fonction div que c'est une fonction partielle.
Exemple 5
La division euclidienne d'un entier a par un entier b doit donner un quotient q et un reste r
tels que : a = b × q + r avec q, r ∈ N et r < b.
On dit que la fonction div est partielle puisqu'elle n'est pas dénie pour tous les entiers b possibles. Elle n'a
de sens que pour b > 0.
DÉFINITION MATHÉMATIQUE D'UN ENSEMBLE
déf
N∗ = {n ∈ Z | n >0 }
DÉFINITION INFORMATIQUE D'UN TYPE
type nat_positif = int (* >0 *)
SPÉCIFICATION MATHÉMATIQUE
Prol
div : Z × N∗ → N × N
Sémantique : div(a, b) est le couple (quotient,reste) de la division euclidienne de a par b
34
Exemples
1.
2.
3.
div(5, 3) = (1, 2)
div(5, 0) = erreur : la fonction n'est pas dénie dans le cas b = 0
div(5, −3) = erreur : la fonction n'est pas dénie dans le cas b < 0
La construction function .. when condition permet de préciser que la fonction est dénie uniquement lorsque b > 0. La condition b > 0 correspond à la condition
encadré de l'ensemble N∗ et du type nat_positif.
RÉALISATION INFORMATIQUE
Implantation
let(div: int * nat_positif -> nat * nat) =
function (a,b) when b>0 -> let q = a/b
and r = a mod b
in (q,r)
;;
L'utilisation de la fonction div avec b = −3 ou b = 0 provoque une erreur Match_failure.
Ce n'est pas une faute du programmeur ; au contraire, c'est voulu et le programmeur a parfaitement fait
son travail puisque la fonction div est conforme à la spécication qui prévenait dans le prol de div et dans
les exemples qu'il ne fallait pas utiliser div avec un b ≤ 0.
Remarque
4.4 Respectez la spécication laisse malgré tout de la liberté
La spécication est un contrat entre l'utilisateur et le programmeur. Pour que l'utilisateur ne soit pas surpris
par les résultats de votre implantation il faut veiller à bien respectez la spécication.
Exemple 6 : Réalisation du prédicat est-voyelle par ltrage sur le type énuméré des caractères
Imaginons qu'en tant que programmeur vous ayez besoin d'un prédicat est-voyelle qui indique si une lettre
minuscule est une voyelle. Spéciez puis réalisez le prédicat est-voyelle .
définition (prédicat)
Un prédicat est une fonction qui rend un booléen.
du prédicat est-voyelle
Prol
est-voyelle : Minuscule → . . . . . . . .
Sémantique : est-voyelle (l) est . . . . . . . si et seulement si l ∈ {'a', 'e', 'i', 'o', 'u', 'y'}
SPÉCIFICATION MATHÉMATIQUE
Exemples
1. est-voyelle ('a') = . . . . . . . .
2. est-voyelle ( . . . . . . ) = faux
3. est-voyelle ('A') n'est pas prévu par le type Minuscule
Dans cette spécication le comportement de la fonction est-voyelle n'est déni que pour les minuscules, il
n'est pas précisé pour les lettres majuscules.
35
Conclusion Le programmeur est donc libre de choisir le comportement de la fonction est-voyelle pour
les majuscules : il peut rendre soit vrai , soit faux . Mais il peut aussi choisir de ne pas dénir la fonction
pour les lettres majuscules et dans ce cas la fonction retournera Match_failure.
Plusieurs implantations possibles Nous allons examiner des implantations diérentes qui ne rendent
pas les mêmes résultats et qui pourtant respectent toutes cla spécication. Avant cela examinons comment
sont dénis les caractères.
DÉFINITION MATHÉMATIQUE DE L'ENSEMBLE
des caractères, par énumération nie
déf Car = {'a', . . . , 'z', 'A', . . . , 'Z', '@', '#', '$', . . . , '%'}
DÉFINITION INFORMATIQUE DU TYPE
type char = 'a' | . . . 'z' | 'A' | . . . | 'Z' | '@' | '#' | '$' | . . . | '%' ;;
Le type char est prédéni en caml sous la forme d'un type énuméré.
Puisque le type char est un type énuméré on peut utiliser le ltrage match ... with... sur les caractères
et caml indiquera si on a oublié des cas. On peut donc dénir la fonction par énumération.
RÉALISATION INFORMATIQUE
Algorithme : On énumère les lettres minuscules qui satisfont la condition être une voyelle.
Implantation 1
let (est_voyelle : minuscule -> bool) =
function l -> match l with
| 'a' | 'e' | 'i' | 'o' | 'u' | 'y' -> true
| _ -> false
;;
Implantation 1' : autre notation acceptée par caml
let (est_voyelle : minuscule -> bool) =
function
| 'a' | 'e' | 'i' | 'o' | 'u' | 'y' -> true
| _ -> false
;;
Remarquez que la partie l -> match l with est optionnelle.
L'implantation 1' se lit de la manière suivante : est-voyelle est une fonction qui à chaque lettre
'a', 'e', 'i', 'o', 'u', 'y' associe true et qui associe false aux autres lettres (y compris les voyelles en
majuscule).
Les implantations 1 et 10 ci-dessus respectent la spécication puisqu'elles rendent vrai pour les voyelles en
minuscule. On propose maintenant une autre implantation.
36
Exercice 1
L'implantation 2 ci-dessous respecte-elle la spécication de est-voyelle ?
Implantation 2
let (est_voyelle : char -> bool) =
function
| 'a' | 'e' | 'i' | 'o' | 'u' | 'y'
| 'A' | 'E' | 'I' | 'O' | 'U' | 'Y' -> true
| _ -> false
;;
. . . . . . puisque la spécication ne . . . . . . . . . . . . pas ce qu'il faut . . . . . . . . . . . . . . . . comme résultat pour les
lettres . . . . . . . . . . . . . . . . . . . donc le programmeur est libre de . . . . . . . . . . . la valeur à rendre pour les voyelles
en . . . . . . . . . . . . . . . . . . .
Exercice 2
Proposez une nouvelle spécication plus précise qui correspond à l'implantation 2.
SPÉCIFICATION MATHÉMATIQUE
du prédicat est-voyelle
est-voyelle : . . . . . . . . . . . → . . . . . . . .
Prol
Sémantique : est-voyelle (l) est . . . . . . . si et seulement si
l ∈ {'a', 'e', 'i', 'o', 'u', 'y'} . . { . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . }
Exemples :
1. est-voyelle ('a') = . . . . . . . .
= est-voyelle ('A')
2. est-voyelle ('z') = . . . . . . . .
= est-voyelle ('Z')
Propriété
∀l ∈
. . . . . . . . . . . , est-voyelle (l) . . . est-voyelle (majuscule( . ))
37