• Aucun résultat trouvé

Fonctions sur les ensembles

6.5.1

Ensembles représentés comme des listes

La structure de donnéesetn’existe pas en tant que telle : on utilise la structure de donnée de liste. La différence entre une liste et un ensemble est que, dans un ensemble (c’est-à-dire dans une liste considérée comme un ensemble), l’ordre n’est pas significatif et les éléments sont tous 2 à 2 différents.

(ADJOIN x e) (SET-EQUAL e1 e2) (SUBSETP e1 e2) (UNION e1 e2) (INTERSECTION e1 e2) (DIFFERENCE e1 e2) (REMOVE-DUPLICATES l) (PRODUCT e1 e2) →

Les fonctionsunion,intersectionetproductsont à faire en version binaire et n-aire.

Nombreuses variantes : version naïve, avec marquage, sur des ensembles ordonnés triés (à coupler avec les fonctions de tri), avec une structure de données abstraite [Rey75] ou avec des techniques de hachage.

6.5.2

Ensembles ordonnés représentés comme des listes

Refaire les mêmes fonctions, en se basant sur le fait que la liste est ordonnée pour rendre les traitements plus efficaces.

6.5.3

Le type de données “union d’intervalles”

On se propose de définir le type de données pour une union d’intervalles et de définir la bibliothèque des fonctions nécessaires à leur manipulation.

Une union d’intervalles représente l’union ensembliste des ensembles représentés par chaque inter- valle :

[

i∈[1 n] [xiyi]

On supposera que les intervalles sont fermés, c’est-à-dire que les bornes appartiennent à l’intervalle : l’u- nion de deux intervalles consécutifs (la borne inf de l’un est borne sup de l’autre) est donc un intervalle, et un intervalle dont les bornes sont identiques n’est pas vide. On a donc toujours xi≤ yi.

Une union d’intervalles sera représentée par la liste des bornes de ses intervalles : (x1y1x2... xnyn)

Il n’y a donc pas de structure de donnée particulière pour les intervalles, qui sont un cas particulier d’union d’intervalles avec n = 1. Une union d’intervalles peut éventuellement être vide : cas où n = 0, l’union d’intervalles est().

Des unions d’intervalles différentes peuvent représenter le même ensemble de points. Il faut donc les normaliser. Une union d’intervalles sera normalisée, de façon à ce que sa représentation soit unique de la façon suivante :

– 2 intervalles de l’union sont disjoints ;

– les intervalles sont ordonnés (en ordre croissant).

Dans la suite du problème, on appellera liste d’intervalles, une liste (x1y1x2... xnyn), n ≥ 0 ou chaque (xiyi) est un intervalle, et union d’intervalles ne sera utilisé que pour une liste d’intervalles normalisée.

Toute liste d’intervalles vérifie donc ∀i ∈ [1 n], ui ≤ vi. Une union d’intervalles vérifiera en plus : ∀i ∈ [2 n], vi−1< ui.

Par chance, toutes les opérations usuelles sur les ensembles s’appliquent aux unions d’intervalles en retournant des unions d’intervalles.

6.5 Fonctions sur les ensembles 69

Question 6.5.3.2

Il est possible de faire des unions d’intervalles sur n’importe quel type de donnée totalement ordonné (chaîne, nombre entier, réel — mais pas complexe). Dans cette première question, on supposera qu’il s’agit d’intervalles numériques (type number), en considérant implicitement qu’il s’agit de flottants (cf. question 2).

De façon générale, on vérifiera de façon appropriée que tous les arguments passés aux fonctions sont bien du bon type. Ecrire les fonctions suivantes :

1. le prédicat union-interval-p qui teste si son argument est bien du type union d’inter- valles, tel qu’il est spécifié plus haut ;

2. le prédicat in qui teste si un nombre (premier argument) appartient à une union d’intervalles (second argument) ;

3. la fonction add-interval à deux arguments, qui rajoute un intervalle (c’est-à-dire une union d’un intervalle) à une union d’intervalles et retourne l’union d’intervalles correspondant à cette union (NB C’est la fonction principale) ;

4. la fonction union-intervals qui fait l’union de deux unions d’intervalles pour retourner l’union d’intervalles “union”.

5. la fonction intersect-intervals qui fait l’intersection de deux unions d’intervalles, pour retourner l’union d’intervalles “intersection” ;

6. le prédicat sub-intervals-p qui teste si son premier argument est bien inclus dans le second, les deux étant des unions d’intervalles. NB. On évitera de se servir de la fonction précédente.

7. la fonctionnorm-intervalsqui prend en argument une liste d’intervalles et la normalise pour retourner l’union d’intervalles correspondant.

Pour les deux dernières fonctions, et sur le modèle des fonctions add-interval et union-intervals, on commencera par la fonction analogue qui traite un intervalle unique relativement à une union d’intervalles : on passera ensuite à la fonction qui traite deux unions d’intervalles.

Question 6.5.3.3

Dans cette question, on va essayer d’étendre les fonctions précédentes à un traitement polymorphe de tous les types totalement ordonnés.

1. D’un point de vue mathématique le type considéré a un effet sur les traitements à effectuer sur les bornes : lequel ? On considérera d’un côté le cas des entiers, de l’autre le cas rationels, des réels ou des chaînes : qu’est ce qui est incorrect dans le cas des entiers dans les fonctions qui précèdent ?

2. D’un point de vue informatique y a-t-il une réelle différence de traitement entre ces divers types ? Mais en pratique ?

3. Comment faudrait-il modifier les fonctions précédentes pour qu’elles puissent traiter des in- tervalles de n’importe quel type ? Considérez le cas des fonctionsinetunion-interval-p. 4. En toute généralité, de quelle interface fonctionnelle du type a-t-on besoin ?

Réponse : il y a une différence importante suivant qu’il s’agit d’un ordre discret muni d’une fonction successeurou d’un ordre dense pour lequel entre deux nombres il en existe toujours un troisième. On n’a pas traité cette différence, en se plaçant dans le cas le plus simple, celui d’un ordre dense1.

Question 6.5.3.4

Au lieu d’implémenter les unions d’intervalles comme une liste de longueur paire (x1y1x2... xnyn), on pourrait l’implémenter comme une liste d’intervalles, chaque intervalle étant une cellule dont le carserait la borne inférieure et lecdrserait la borne supérieure : ((x1. y1) (x2... (xn. yn)).

1. refaire les deux questions précédentes avec cette nouvelle représentation. 2. quels sont les avantages et les inconvénients des deux représentations ?

1. Dont les flottants ne sont qu’une approximation : la seule réalisation effective d’un ordre dense est donnée par les rationnels, pour les langages qui en ont une implémentation effective (COMMONLISP, par exemple).