Brefs rappels sur les listes. INF121: Algorithmique et Programmation Fonctionnelle

Documents pareils
# let rec concat l1 l2 = match l1 with [] -> l2 x::l 1 -> x::(concat l 1 l2);; val concat : a list -> a list -> a list = <fun>

Cours de Programmation 2

Classes et Objets en Ocaml.

length : A N add : Z Z Z (n 1, n 2 ) n 1 + n 2

Algorithmique et Programmation, IMA

Recherche dans un tableau

TP3 : Manipulation et implantation de systèmes de fichiers 1

modules & compilation

Expression des contraintes. OCL : Object C o n t r a i n t L a n g u a g e

IN Cours 1. 1 Informatique, calculateurs. 2 Un premier programme en C

Programmation C++ (débutant)/instructions for, while et do...while

1 de 46. Algorithmique. Trouver et Trier. Florent Hivert. Mél : Florent.Hivert@lri.fr Page personnelle : hivert

Machines virtuelles fonctionnelles (suite) Compilation ML Java

OCL - Object Constraint Language

introduction Chapitre 5 Récursivité Exemples mathématiques Fonction factorielle ø est un arbre (vide) Images récursives

INF 232: Langages et Automates. Travaux Dirigés. Université Joseph Fourier, Université Grenoble 1 Licence Sciences et Technologies

Limites finies en un point

Logiciel Libre Cours 3 Fondements: Génie Logiciel

Cours 1 : La compilation

Algorithmique et programmation : les bases (VBA) Corrigé

Cours d introduction à l informatique. Partie 2 : Comment écrire un algorithme? Qu est-ce qu une variable? Expressions et instructions


Initiation à la Programmation en Logique avec SISCtus Prolog

Théorie de la Programmation

TP 1. Prise en main du langage Python

1 Recherche en table par balayage

Les arbres binaires de recherche

Cours de C++ François Laroussinie. 2 novembre Dept. d Informatique, ENS de Cachan

MISE A NIVEAU INFORMATIQUE LANGAGE C - EXEMPLES DE PROGRAMMES. Université Paris Dauphine IUP Génie Mathématique et Informatique 2 ème année

Une dérivation du paradigme de réécriture de multiensembles pour l'architecture de processeur graphique GPU

Chapitre 2. Eléments pour comprendre un énoncé

Résolution de systèmes linéaires par des méthodes directes

Quelques Algorithmes simples

Initiation à la programmation en Python

Quelques algorithmes simples dont l analyse n est pas si simple

STAGE IREM 0- Premiers pas en Python

Vérification de programmes et de preuves Première partie. décrire des algorithmes

Les structures de données. Rajae El Ouazzani

Logiciel Libre Cours 2 Fondements: Programmation

Rappel. Analyse de Données Structurées - Cours 12. Un langage avec des déclaration locales. Exemple d'un programme

Exo7. Matrice d une application linéaire. Corrections d Arnaud Bodin.

Les algorithmes de base du graphisme

Suivant les langages de programmation, modules plus avancés : modules imbriqués modules paramétrés par des modules (foncteurs)

Apache Camel. Entreprise Integration Patterns. Raphaël Delaporte BreizhJUG

Langage SQL : créer et interroger une base

Bases de programmation. Cours 5. Structurer les données

Dualité dans les espaces de Lebesgue et mesures de Radon finies

Correction Code nécessaire à la compilation : let bs ="\\" let nl = "\n" ;; let appliquer = List.map ;; (* affichage d'un noeud *)

Cours No 3 : Identificateurs, Fonctions, Premières Structures de contrôle.

Problèmes de Mathématiques Filtres et ultrafiltres

F. Barthélemy. 17 mai 2005

Chapitre 5 : Flot maximal dans un graphe

Plan. Exemple: Application bancaire. Introduction. OCL Object Constraint Language Le langage de contraintes d'uml

Cours d algorithmique pour la classe de 2nde

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

Paginer les données côté serveur, mettre en cache côté client

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

PROJET ALGORITHMIQUE ET PROGRAMMATION II

Découverte de Python

3. Conditionnement P (B)

UEO11 COURS/TD 1. nombres entiers et réels codés en mémoire centrale. Caractères alphabétiques et caractères spéciaux.

Exercices Corrigés Premières notions sur les espaces vectoriels

Une introduction rapide à Coq

Informatique Théorique : Théorie des Langages, Analyse Lexicale, Analyse Syntaxique Jean-Pierre Jouannaud Professeur

UML et les Bases de Données

Algorithmique, Structures de données et langage C

INTRODUCTION AUX SYSTEMES D EXPLOITATION. TD2 Exclusion mutuelle / Sémaphores

Licence Bio Informatique Année Premiers pas. Exercice 1 Hello World parce qu il faut bien commencer par quelque chose...

Licence Sciences et Technologies Examen janvier 2010

ACTIVITÉ DE PROGRAMMATION

Exercices du Cours de la programmation linéaire donné par le Dr. Ali DERBALA

Centre CPGE TSI - Safi 2010/2011. Algorithmique et programmation :

Grandes lignes ASTRÉE. Logiciels critiques. Outils de certification classiques. Inspection manuelle. Definition. Test

Utilisation d objets : String et ArrayList

(51) Int Cl.: H04L 29/06 ( ) G06F 21/55 ( )

Corrigé des exercices sur les références

Suites numériques 3. 1 Convergence et limite d une suite

1/24. I passer d un problème exprimé en français à la réalisation d un. I expressions arithmétiques. I structures de contrôle (tests, boucles)

Chapitre 2 Le problème de l unicité des solutions

Vérification formelle de la plate-forme Java Card

Réalisabilité et extraction de programmes

Les deux points les plus proches

LMI 2. Programmation Orientée Objet POO - Cours 9. Said Jabbour. jabbour@cril.univ-artois.fr

Principes des langages de programmation INF 321. Eric Goubault

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

Conventions d écriture et outils de mise au point

De même, le périmètre P d un cercle de rayon 1 vaut P = 2π (par définition de π). Mais, on peut démontrer (difficilement!) que

Prénom : Matricule : Sigle et titre du cours Groupe Trimestre INF1101 Algorithmes et structures de données Tous H2004. Loc Jeudi 29/4/2004

Cours d Algorithmique-Programmation 2 e partie (IAP2): programmation 24 octobre 2007impérative 1 / 44 et. structures de données simples

Table des matières. Introduction

Résolution du Problème du Voyageur de Commerce Métaheuristique

Manuel d utilisation 26 juin Tâche à effectuer : écrire un algorithme 2

CREATION D UNE EVALUATION AVEC JADE par Patrick RUER (

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

Glossaire des nombres

Algorithmes récursifs

Évaluation d une architecture de stockage RDF distribuée

Cours de Génie Logiciel

Définitions. Numéro à préciser. (Durée : )

Transcription:

Brefs rappels sur les listes INF121: Algorithmique et Programmation Fonctionnelle Cours 8 : Listes (suite et fin) Une liste c est : une suite finie, ordonnée, de valeurs de même type pouvant contenir un nombre arbitraire d éléments Le type liste_de_t est défini par un type (union) récursif : la constante Nil représente la liste vide le constructeur Cons(e,l) représente l ajout en tête de e à l Cons (expr1, Cons (expr2,...cons (exprn, Nil)...)) Année 2015-2016 Un élément du type list_de_t est une valeur (comme une autre!) On peut définir des listes d entiers, booléens, réels, fonctions, etc. On peut considérer d autres constructeurs, selon la forme des listes souhaitées (ajout en queue, listes non vides, de longueur impaire, etc.) 1 / 14

Le type prédéfini pour les listes en Ocaml OCaml fournit un constructeur de type list prédéfini Nil est noté [ ] Cons est exprimé par un opérateur infixé :: Exemple : Listes en notation OCaml Cons (2, Nil) correspond à 2::[ ] Cons (4,Cons (9, Nil)) correspond à 4::(9::[ ]) Quelques raccourcis de notation : v1::(v2::...::(vn::[ ])) peut être noté v1::v2::...vn::[ ] v1::v2::... vn::[ ] peut être noté [v1;v2;...;vn] Exemple : Cons (4,Cons (9, Cons (5, Nil))) se note [4;9;5] Le type liste d éléments de type t se note t list Retour sur le pattern-matching Rien ne bouge... Comment effectuer un traitement par cas en filtrant certaines formes de listes? comme pour un type récursif à 2 constructeurs Cons et Nil, mais avec une nouvelle syntaxe : ensembles de valeurs attendues filtre liste vide... liste non vide... liste à un seul ĺélément... liste d entier commençant par 42......... DEMO: liste d entiers, de couples, de couleurs, de listes, etc. 2 / 14 3 / 14

Et les listes non vides? Pas de type CAML prédédini... Ecrire une fonction f telle que f : liste non vide d entiers t? (exemple : le dernier élément d une liste d entier) Plusieurs alternatives : 1. ne pas considérer le cas où la liste est vide dans la fonction ( accepter le warning émis par l interpréteur) on suppose que l appelant respectera la spécification... 2. générer une exception en cas d appel avec une liste vide (en utilisant failwith ou assert) 3. définir et utiliser un type spécifique : le type liste non-vide type intlist_non_vide= Elt of int Cons of int intlist_non_vide 4. renvoyer un booléen en plus du résultat indiquant si celui-ci est pertinent l utilisation du résultat est conditionnée par ce booléen... Retour sur les exercices du cours précédent Avec ces nouvelles notations Pour des listes d entiers : somme : renvoie la somme des éléments d une liste appartient : indique si un élément appartient à une liste dernier : renvoie le dernier élément d une liste minimum : renvoie le minimum d une liste d entiers pairs : renvoie la liste des entiers pairs d une liste d entiers (variante : renvoie la liste des entiers de rang pair) supprime : supprime une/toutes les occurrences d un élément concatene : concaténation de deux listes partition : partitionne une liste en deux sous-listes selon un critère donné est_croissante : indique si une liste est croissante DEMO: Implémentation de certaines de ces fonctions 4 / 14 5 / 14

Comment écrire une fonction à paramètres de type liste? Quelques schémas assez fréquents... Pour écrire une fonction portant sur un type récursif, on peut s aider de la définition de ce type! Fonction à 1 seul paramètre l de type liste (f : t1 list t2) exemples : longueur, appartient, partition, pair, supprime, est_croissant,... 1. Cas de base : valeur de f pour la liste vide : f([]) =... 2. Exprimer f sous forme récursive découper la liste en isolant : son premier élément e et son suffixe s : f(e::s) = (g e (f s)) ou ses deux premiers éléments e1, e2 et son suffixe s : f([e1]) =... (cas de la liste à un element) f(e1::e2::s) = (g e1 e2 (f (e2::s))) etc. Implémentation en CAML par filtrage : let rec somme (l : int list) : int = match l with [] 0 (* liste vide *) e::s e + (somme s) (* liste non vide *) Comment écrire une fonction à paramètres de type liste (suite)? Fonction à 2 paramètres de type liste (f : t1 list t2 list t3) exemple : concaténation Approche 1 : on raisonne sur les 2 liste 4 cas possibles 1. valeur de f pour les deux liste vide : f([], []) =... 2. valeur de f pour une liste vide, l autre non vide f(l1, []) =... et f([], l2) =... 3. valeur de f pour les deux listes non vides (cas récursif) découpage de chaque liste en premier(s) élément(s) et suffixes f(e1::s1, e2::s2) =... let rec concat (l1 : t list) (l2 : t list) : t list = match l1, l2 with [], [] [] [], l2 l2 l1, [] l1 e1::s1, e2::s2 e1::(concat s1 (e2::s2)) 6 / 14 7 / 14

Comment écrire une fonction à paramètres de type liste (fin)? Fonction à 2 paramètres de type liste (f : t1 list t2 list t3) exemple : concaténation Approche 2 : on raisonne sur une seule des deux listes (p. ex. l1) 1. cas de base : valeur de f lorsque l1 est vide f([], l2) =... 2. cas récursifs : on découpe l1 en premier(s) élément(s) et suffixe f(e1::s1, l2) =... Rq : on peut être amené à distinguer plusieurs cas en fonction de l2. Implémentation en CAML par filtrage : let rec concat (l1 : t list) (l2 : t list) : t list = match l1 with [] l2 e1::s1 e1::(concat s2 l2) Liste génériques Certaines fonctions sur les listes ne dépendent pas du type des éléments... Exemples : longueur, dernier, appartient, supprime, concatene,... minimum, est_croissante, partition,... (en considérant l ordre induit par l opérateur <) on peut définir des listes génériques (à élts de type quelconque ) notation CAML : a list Exemple : Appartenance d un élément à une liste générique let rec appartient (x: α)(l : α list) : bool = match l with [] false e::s e=x (appartient x s) (appartient 2 [5;8;4;5;2;1]) = true (appartient true [false;false;true]) = true (appartient u [ z ; x ; w ]) = false (se prononce α-liste ) 8 / 14 9 / 14

Exercices Fermeture-Eclair zip: prend en paramètre un couple de liste (de même taille) et renvoie la liste des couples correspondants Exemples : zip [1; 3; 8] [2; 9; 8] est la liste [(1,2); (3,9); (8,8)] zip [1; 3; 8; 10] [2; 9] n est pas défini... variante : compléter avec le dernier élt de la liste la plus courte zip [1; 3; 8 ; 10] [2; 9] = [(1,2) ; (3, 9) ; (8, 9) ; (10, 9)] Une liste est-elle une sous-liste d une autre? Exemples : [ e2 ; e4 ; e5 ] est une sous-liste de [e1 ; e2 ; e3 ; e4 ; e5 ; e6] [ e2 ; e4 ; e5 ; e7 ] n est pas une sous-liste de [e2 ; e3 ; e4 ; e5 ; e6] [ e4 ; e2 ; e5 ] n est pas une sous-liste de [e1 ; e2 ; e3 ; e4 ; e5 ; e6] Analyse : ce predicat prend deux listes l1 et l2 en paramètre l2 doit être obtenue en supprimant certains éléments de l1 Quelques opérateurs prédéfinis sur le type OCaml list let l1 = [3; 8; 7; 1] Description Opérateur Exemple nième élément List.nth List.nth l1 2 = 7 longueur List.length List.length l1 = 4 tête List.hd List.hd l1 = 4 fin List.tl List.tl l1 = [8;7;1] inverse List.rev List.rev l1 = [1;7;8;3] concaténation @ l1 @ [2;3] = [3; 8; 7; 1; 2; 3] Plus de détails sur caml.inria.fr/pub/docs/manual-ocaml/libref/list.html 10 / 14 11 / 14

Listes, Ensembles et Multi-ensembles... Trois notions à ne pas confondre! Liste les éléments peuvent être dupliqués : [1;9;7] [1;9;9;7] l ordre des éléments est important : [1;9;7] [1;7;9] implémentation directe à l aide du type list... Ensemble les éléments ne sont pas dupliqués : {1, 9, 7} = {1, 9, 9, 7} l ordre des éléments ne compte pas : {1, 9, 7} = {1, 7, 9} implémentation possible à l aide du type list, mais : ne pas dupliquer les éléments (ou définir correctement la supression!) ordonner les éléments (ou définir correctement l égalité!) Multi-ensemble les éléments peuvent être dupliqués : {1, 9, 7} = {1, 9, 9, 7} l ordre des éléments ne compte pas : {1, 9, 7} = {1, 7, 9} implémentation possible à l aide du type list, mais : dupliquer les éléments, ou utiliser des couples (elt, nbre_occurrence) ordonner les éléments (ou définir correctement l égalité!) 12 / 14 Tris de listes Motivations Trier ranger les éléments d une liste selon un ordre donné : Exemple [2;1;9;4] Motivations? tri (l : α list) : α list liste quelconque tri liste triée selon la relation < tri [1;2;4;9] type person = Toto Titi Tata [Titi;Tata;Toto] tri [Toto;Titi;Tata] représentation canonique du (multi-)ensemble des elts d une liste certains traitements seront plus efficaces une étape nécessaire dans de nombreux algorithmes plus généraux nombreux algorithmes de tri, qui diffèrent par : leur efficacité (en temps d exécution, en mémoire) leur difficulté à programmer, à prouver 13 / 14

Exemple 1 : tri par insertion (tri_insertion (l : α list) : α list) Exemple 2 : tri par sélection (tri_selection (l : α list) : α list) Algorithme Algorithme si l=[], le résultat est la liste vide... si l=e::s? trier (récursivement!) s et insérer e (à sa place!) dans la liste résultat si l=[], le résultat est la liste vide... sinon? soit min le minimum de l et s la liste l privée de min on ajoute min (en tête!) de la liste s triée (récursivement!) liste courante e::s (insere e (tri_insertion s)) e s <e e >=e liste courante l min::s >=min min >=min min >=min (min,s) = (sup_min l) Insérer un élément à sa place dans une liste triée? let rec inserer (e:α) (l:α list):α list= (* l est croissante, le resultat est croissante *) match l with [] [e] x::s if e<x then e::l else x::(inserer e s) DEMO: tri par insertion 14 / 14 Extraire d une liste son minimum et le reste de la liste? sup_min : α list (α α list) sup_min (l) renvoie (min,s) tel que min est un élément minimum de la liste non vide l et s est la liste l privée de min. DEMO: tri par sélection 15 / 14

Exemple 3 : tri rapide (tri_rapide (l : α list) : α list) Algorithme si l=[], le résultat est la liste vide... si l=e::s alors on partitionne s en s1 (elts de s < e) et s2 (elts de s e) on trie (récursivement!) s1 et s2, on insère e entre ces 2 listes triées e liste courante e::s s (s1,s2) = (partition e s) (tri_rapide s1) <e e (tri_rapide s2) Partitionner une liste en fonction d un pivot? partition : α α list (α list α list) (partition p l) renvoie (l1,l2) tel que l1 contient les élts de l strictements inférieurs à p et l2 ceux supérieurs à p. >=e DEMO: tri rapide Comment s assurer qu une fonction récursive est correcte? Une solution : prouver qu elle calcule bien le résultat attendu paramètre de type récursif preuve par récurrence sur sa structure Principe Pour montrer une propriété P sur une liste l 1. Cas de base : montrer que P([]) est vrai 2. Récurrence : montrer que P(e::s) est vrai, en suposant P(s) vrai Plus formellement Pour tout prédicat P sur une liste l Remarques : P([]) e, s, P(s) P(e::s) se généralise à tous les types récursifs... } l, P(l) la récurrence sur les entiers est un cas particulier 16 / 14 17 / 14

Exemple de preuve : somme de éléments d une liste Conclusion let rec somme (l : int list) : int = match l with [] 0 e::s e + (somme s) Prouver que, pour toute liste d entiers l = [e1;e2;...; en], Les listes : un type de données incontournable Peuvent être définies explicitementt par un type union (récursif) : constructeurs Cons et Nil first-class citizens toutes les règles de typage s appliquent, pattern-matching, etc. P(l) def (somme l) = Σ n i=1e i 1. Cas de base (pour la liste vide) : (somme []) = 0 et Σ i=0 i=1[] = 0, donc P([]) est vrai 2. Récurrence structurelle On suppose que pour toute liste s = [e1;e2;...;en] on a P(s) : (somme s) = Σ n i=1ei (hyp. de récurrence) On a alors, pour la liste e0::s = [e0;e1;e2;... ;en] : En pratique : on utilise plutôt le type list de OCaml ::, [], [v1;v2;...;vn], @,... fonctions récursives sur les listes : identifier et définir le(s) cas de base identifier et définir le(s) cas de récurrence 2 algorithmes de tri : tri par insertion et tri par sélection notion de preuve (par récurrence) de fonctions récursives or, (somme e0::s) = e0 + (somme s) (def. de la fonction somme) e0 + somme s = e0 + Σ n i=1ei (par hyp. de récurrence) = Σ n i=0 ei On en déduit donc que P(e::s) est vrai. 18 / 14 Important Vérifiez que vous savez écrire les fonctions vues dans ce cours Jetez un coup d oeil aux opérateurs prédéfinis du type List... 19 / 14

19 / 14