29/9/2005 © 2005 P. Van Roy. All rights reserved. 1 FSAB 1402: Informatique 2 Récursion sur les Entiers Peter Van Roy Département dIngénierie Informatique,

Slides:



Advertisements
Présentations similaires
LES NOMBRES PREMIERS ET COMPOSÉS
Advertisements

[number 1-100].
Qualité du Premier Billot. 2 3 Défauts reliés à labattage.
La Méthode de Simplexe Standardisation
Module Systèmes d’exploitation
Portée des variables VBA & Excel
Fonctions & procédures
Calculs de complexité d'algorithmes
Cours n°2M2. IST-IE (S. Sidhom) UE 303 Promo. M2 IST-IE 2005/06 Conception dun système d'information multimédia Architecture trois-tiers : PHP/MySQL &
ESIEE Paris © Denis BUREAU I N Initiation à la programmation avec le langage Java.
Introduction à la programmation (420-PK2-SL) cours 15 Gestion des applications Technologie de linformation (LEA.BW)
Mr: Lamloum Med LES NOMBRES PREMIERS ET COMPOSÉS Mr: Lamloum Med.
FSAB1402: Informatique 2 Techniques de Programmation Orientée Objet
18/10/2004 P. Van Roy, InfoT4, S5 1 Informatique T4 Solutions au Test du 18 octobre Peter Van Roy Département dIngénierie Informatique, UCL
1 Cours numéro 3 Graphes et informatique Définitions Exemple de modélisation Utilisation de ce document strictement réservée aux étudiants de l IFSIC.
Récursivité.
12/10/2004 P. Van Roy, InfoT4, S4 1 Informatique T4 (FSAC1450) Récursion sur les Entiers Peter Van Roy Département dIngénierie Informatique, UCL
© 2007 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 La Concurrence Déclarative Peter Van Roy Département dIngénierie Informatique, UCL
Les structures de données arborescentes
Cours de physique générale I Ph 11
Sémantique axiomatique
18/05/ Utiliser le cahier de texte en ligne avec lapplication SPIP Adresse du site du lycée :
1.2 COMPOSANTES DES VECTEURS
Titre : Implémentation des éléments finis sous Matlab
© 2007 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java et les Exceptions Peter Van Roy Département dIngénierie Informatique,
© 2007 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 Sémantique Formelle Peter Van Roy Département dIngénierie Informatique, UCL
Académie de Créteil - B.C Quest-ce quune Inscription 1)1 action + 1 stagiaire + 1 client 2)Parcours individuel (avec son Prix de Vente) 3)Un financement.
Projet poker 1/56. Introduction Présentation de léquipe Cadre du projet Enjeux Choix du sujet 2.
LES NOMBRES PREMIERS ET COMPOSÉS
© 2005 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 LEtat et lAbstraction de Données Peter Van Roy Département dIngénierie Informatique,
© 2005 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 Algorithmes sur les Listes Peter Van Roy Département dIngénierie Informatique, UCL
2/11/2004 P. Van Roy, InfoT4, S7 1 Informatique T4 (FSAC1450) Sémantique Peter Van Roy Département dIngénierie Informatique, UCL
© 2007 P. Van Roy. All rights reserved. 1 FSAB 1402: Informatique 2 Récursion sur les Entiers Peter Van Roy Département dIngénierie Informatique, UCL
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
RACINES CARREES Définition Développer avec la distributivité Produit 1
Expressions régulières et hash tables
Représentation des systèmes dynamiques dans l’espace d’état
Représentation des systèmes dynamiques dans l’espace d’état
© 2007 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 Récursion sur les Listes Peter Van Roy Département dIngénierie Informatique, UCL
© 2007 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 Enregistrements et Arbres Peter Van Roy Département dIngénierie Informatique, UCL
FSAB 1402: Informatique 2 Complexité Calculatoire
FSAB1402: Informatique 2 L’État et l’Abstraction de Données
P. Van Roy, LINF LINF1251: Algorithmes sur les Listes Peter Van Roy Département dIngénierie Informatique, UCL
© 2005 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 Enregistrements et Arbres Peter Van Roy Département dIngénierie Informatique, UCL
26/10/2004 P. Van Roy, InfoT4, S6 1 Informatique T4 (FSAC1450) Récursion sur les Listes Peter Van Roy Département dIngénierie Informatique, UCL
Peter Van Roy Département d’Ingénierie Informatique, UCL
P. Van Roy, LINF1251 LINF1251: Le Langage Java Peter Van Roy Département dIngénierie Informatique, UCL
1.1 LES VECTEURS GÉOMÉTRIQUES
Chapitre 9 Les sous-programmes.
Chapitre 3 Syntaxe et sémantique.
Titre : Implémentation des éléments finis en Matlab
Partie II Sémantique.
Inéquations du premier degré à une inconnue
Équipe 2626 Octobre 2011 Jean Lavoie ing. M.Sc.A.
P. Van Roy, LINF LINF1251: Sémantique Formelle Peter Van Roy Département d’Ingénierie Informatique, UCL
Procédures et fonctions
Mise en forme en Mathématiques
Traitement de différentes préoccupations Le 28 octobre et 4 novembre 2010.
Expressions régulières et hash tables
LES PILES ET FILES.
Suites numériques Définitions.
Université de Sherbrooke
Un survol du language C.
© 2005 P. Van Roy. All rights reserved. FSAB1402: Informatique 2 Le Langage Java Peter Van Roy Département d’Ingénierie Informatique, UCL
Le langage Racket (Lisp)
LINF 1251: Introduction à l’Algorithmique et la Programmation II
6/10/2005 © 2005 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 Récursion sur les Listes Peter Van Roy Département d’Ingénierie Informatique,
LINF 1251: Récursion sur les Listes
Algorithmique Boucles et Itérations
Chap. 3 Récursion et induction. Les définitions par récurrence consistent à construire des objets finis, à partir d'autres, selon certaines règles. Les.
Transcription de la présentation:

29/9/2005 © 2005 P. Van Roy. All rights reserved. 1 FSAB 1402: Informatique 2 Récursion sur les Entiers Peter Van Roy Département dIngénierie Informatique, UCL

29/9/2005© 2005 P. Van Roy. All rights reserved.2 Ce quon va voir aujourdhui Résumé du premier cours Récursion sur les entiers Introduction aux listes

29/9/2005© 2005 P. Van Roy. All rights reserved.3 Suggestions de lecture pour le deuxième cours Transparents sur le site Web du cours Dans le livre Chapitre 1 (1.3) - Fonctions Chapitre 2 (2.1.1) - Syntaxe des langages Chapitre 2 (2.4.1) - Procédures et références externes Chapitre 3 (3.2) - Calcul itératif Chapitre 3 (3.3) - Calcul récursif

29/9/2005 © 2005 P. Van Roy. All rights reserved. 4 Résumé du premier cours

29/9/2005© 2005 P. Van Roy. All rights reserved.5 Une question de portée… local P Q in proc {P} {Browse 100} end proc {Q} {P} end local P in proc {P} {Browse 200} end {Q} end Quest-ce qui est affiché par ce petit programme? Utilisez la définition de portée lexicale: chaque occurrence dun identificateur correspond à une déclaration précise!

29/9/2005© 2005 P. Van Roy. All rights reserved.6 Procédures et portée lexicale local P Q in proc {P} {Browse 100} end proc {Q} {P} end local P in proc {P} {Browse 200} end {Q} end Une procédure ou une fonction se souvient toujours de lendroit de sa naissance Donc, la définition de Q utilise la première définition de P Portée lexicale: dans la définition de Q, de quel P sagit-il? La seconde définition de P, à côté de lappel de Q, nest pas utilisée!

29/9/2005© 2005 P. Van Roy. All rights reserved.7 Un autre raisonnement… Souvenez-vous de la définition du modèle déclaratif Un programme qui marche aujourdhui marchera demain Un programme est un ensemble de fonctions Chaque fonction ne change jamais son comportement, tout comme chaque variable ne change jamais son affectation Donc, lappel de Q donnera forcément toujours le même résultat Comment cela est-il implémenté? Avec lenvironnement contextuel: un environnement qui fait partie de la définition de la procédure et qui mémorise les identificateurs de la définition

29/9/2005© 2005 P. Van Roy. All rights reserved.8 Identificateurs et variables Souvenez-vous des deux mondes: le programmeur et lordinateur Un identificateur est un nom textuel, fait pour le programmeur Une variable (en mémoire) est ce quutilise lordinateur pour faire ses calculs Une variable nest jamais vu directement par le programmeur, mais indirectement par lintermédiaire dun identificateur Le rôle clé de lenvironnement Un même identificateur peut désigner des variables différentes à des endroits différents du programme

29/9/2005© 2005 P. Van Roy. All rights reserved.9 Fonctions, procédures et le langage noyau Souvenez-vous: comment est-ce quon peut comprendre un langage riche, avec un grand nombre doutils pour le programmeur? On utilise un langage simple, le langage noyau Le langage riche est traduit vers le langage noyau Exemple: dans notre langage noyau, il ny a que des procédures, pas de fonctions Une fonction est traduite vers une procédure avec un argument de plus fun {Inc X} X+1 end proc {Inc X Y} Y=X+1 end A={Inc 10} {Inc 10 A}

29/9/2005 © 2005 P. Van Roy. All rights reserved. 10 Récursion sur les entiers

29/9/2005© 2005 P. Van Roy. All rights reserved.11 Récursion Idée: résoudre un grand problème en utilisant des solutions aux problèmes plus petits Il faut savoir ranger les solutions selon la taille du problème quils résolvent Pour aller de Barbe 91 à Louvain-la-Neuve au restaurant Hard Rock Café à Stockholm Découpe en de problèmes plus petits et solubles: voyage de Louvain-la-Neuve à Zaventem (train), voyage Bruxelles- Stockholm (avion), voyage aéroport Stockholm-centre ville (train), voyage au Hard Rock Café (métro) Il faut savoir résoudre les problèmes les plus petits directement! (train, métro, avion, voiture)

29/9/2005© 2005 P. Van Roy. All rights reserved.12 Exemple: calcul de factorielle declare fun {Fact N} if N==0 then 1 else N * {Fact N-1} end end Grand problème: {Fact N} Problème plus petit: {Fact N-1} Solution directe: {Fact 0} = 1

29/9/2005© 2005 P. Van Roy. All rights reserved.13 Une autre factorielle En utilisant un invariant: n! = i! * a On commence avec i=n et a=1 On réduit i et on augmente a, tout en gardant vrai linvariant Quand i=0 cest fini et le résultat cest a Exemple avec n=4: 4! = 4! * 1 4! = 3! * 4 4! = 2! * 12 4! = 1! * 24 4! = 0! * 24

29/9/2005© 2005 P. Van Roy. All rights reserved.14 Le programme declare fun {Fact2 I A} if I==0 then A else {Fact2 I-1 I*A} end end declare F={Fact2 4 1} {Browse F}

29/9/2005© 2005 P. Van Roy. All rights reserved.15 Linvariant Voici linvariant quon a utilisé: n! = i! * a Un invariant est une formule logique qui est vrai à chaque appel récursif (par exemple, {Fact2 I A}) pour les arguments de cet appel (ici, I et A) Linvariant contient à la fois des informations globales (n) et locales (les arguments i et a)

29/9/2005© 2005 P. Van Roy. All rights reserved.16 Les accumulateurs Dans Fact2, on accumule le résultat petit à petit dans A Largument A de Fact2 est donc appelé un accumulateur Quand on utilise un invariant pour faire un programme, cela fait apparaître des accumulateurs Dans la programmation déclarative, on utilise souvent des invariants et des accumulateurs Les invariants sont les mêmes quon utilise dans les boucles des langages impératifs comme Java Une fonction récursive qui utilise un accumulateur est comme une boucle en langage impératif! Une boucle en langage impératif une fonction récursive avec accumulateur

29/9/2005© 2005 P. Van Roy. All rights reserved.17 Comparaison de Fact et Fact2 Quand on regarde lappel récursif dans les deux cas, on voit une différence: Dans Fact: N*{Fact N-1} Dans Fact2: {Fact2 I-1 I*A} Dans Fact, après lappel récursif on doit revenir pour faire la multiplication avec N Dans Fact2, on ne doit pas revenir après lappel récursif

29/9/2005© 2005 P. Van Roy. All rights reserved.18 Limportance des accumulateurs Quand on regarde lappel récursif dans les deux cas, on voit une différence: Dans Fact: N*{Fact N-1} Dans Fact2: {Fact2 I-1 I*A} Cest une grande différence! Pendant lexécution, Fact doit garder en mémoire des informations sur tous les appels récursifs, jusquà la fin des appels récursifs Fact2 ne doit garder en mémoire que lappel récursif actuellement en cours, ce qui est une économie importante Pour lefficacité, lappel récursif doit être la dernière instruction! Alors la taille de mémoire sera constante (comme une boucle) Cest pourquoi les accumulateurs sont importants (On rendra cette intuition plus exacte quand on verra la sémantique)

29/9/2005© 2005 P. Van Roy. All rights reserved.19 La récursion terminale On appelle récursion terminale quand la dernière instruction est lappel récursif Parce quon ne doit pas revenir de lappel récursif, la taille de la pile est constante Lexécution est aussi efficace quune boucle en langage impératif Attention: certains systèmes reviennent quand même de lappel récursif, et ne gagnent donc rien de la récursion terminale Cest le cas pour certaines implémentations de Java et de C++: il faut vérifier la documentation! Tous les langages symboliques (Scheme, ML, Haskell, Oz, Prolog, …) implémentent bien la récursion terminale

29/9/2005 © 2005 P. Van Roy. All rights reserved. 20 Racine carrée avec la méthode de Newton

29/9/2005© 2005 P. Van Roy. All rights reserved.21 La racine carrée avec la méthode itérative de Newton On va utiliser une méthode itérative, la méthode de Newton, pour calculer la racine carrée Cette méthode est basée sur lobservation que si g est une approximation de sqrt(x), alors la moyenne entre g et x/g est une meilleure approximation: g = (g + x/g)/2

29/9/2005© 2005 P. Van Roy. All rights reserved.22 Pourquoi la méthode de Newton marche Pour vérifier que lapproximation améliorée est meilleure, calculons lerreur e: e = g - sqrt(x) Alors: e = g - sqrt(x) = (g + x/g)/2 - sqrt(x) = e 2 /2g Si on suppose que e 2 /2g 0 Cette condition est toujours vraie (parce que g>0) Cest donc toujours vrai que lerreur diminue!

29/9/2005© 2005 P. Van Roy. All rights reserved.23 Itération générique Nous allons utiliser un itérateur générique: fun {Iterate Si} if {IsDone Si} then Si else local Sj in Sj={Transform Si} {Iterate Sj} end end end Cet itérateur utilise un accumulateur Si Il faut remplir IsDone et Transform

29/9/2005© 2005 P. Van Roy. All rights reserved.24 Lamélioration dune approximation (Transform) fun {Transform Guess} (Guess + X/Guess) / 2.0 end Attention: X nest pas un argument de Transform! X est un identificateur libre dans Transform qui doit être défini dans le contexte de Transform (Petite remarque: X, Guess et 2.0 sont tous des nombres en virgule flottante. Pour garder lexactitude des entiers, il ny a aucune conversion automatique avec les entiers.)

29/9/2005© 2005 P. Van Roy. All rights reserved.25 La fin de litération (IsDone) fun {IsDone Guess} {Abs (X-Guess*Guess)}/X < end De nouveau, X est un identificateur libre dans IsDone La fonction Abs fait partie des modules de base de Mozart Lerreur relative est câblée dans la routine; on peut en faire un paramètre (exercice!) Attention: X doit être différent de 0.0!

29/9/2005© 2005 P. Van Roy. All rights reserved.26 Définition complète fun {NewtonSqrt X} fun {Transform Guess} (Guess + X/Guess)/2.0 end fun {IsDone Guess} {Abs X-Guess*Guess}/X < end fun {Iterate Guess} if {IsDone Guess} then Guess else {Iterate {Transform Guess}} end end in {Iterate 1.0} end

29/9/2005© 2005 P. Van Roy. All rights reserved.27 Spécification de NewtonSqrt S={NewtonSqrt X} satisfait: Les arguments S et X sont des nombres en virgule flottante; lentrée X et la sortie S sont positifs (>0.0) La relation entre eux est: |x-s*s|< Exercice: étendre la fonction pour satisfaire à une spécification où X=0.0 est permis

29/9/2005© 2005 P. Van Roy. All rights reserved.28 Structure de NewtonSqrt Vous remarquez que Transform, IsDone et Iterate sont des fonctions locales à NewtonSqrt Elles sont cachées de lextérieur Transform et IsDone sont dans la portée de X, elles connaissent donc la valeur de X Dautres définitions sont possibles (voir le livre)! Par exemple, vous pouvez mettre leurs définitions à lextérieur de NewtonSqrt (exercice!) Avec local … end, vous pouvez quand même cacher ces définitions du reste du programme (comment?)

29/9/2005 © 2005 P. Van Roy. All rights reserved. 29 Calcul récursif de la puissance

29/9/2005© 2005 P. Van Roy. All rights reserved.30 Une récursion un peu plus compliquée: la puissance Nous allons définir une fonction {Pow X N} qui calcule X N (N0) avec une méthode efficace Définition mathématique naïve de x n : x 0 = 1 x n = x*x (n-1) si n>0 Cette définition donne la fonction suivante: fun {Pow X N} if N==0 then 1 else X*{Pow X N-1} end end Cette définition est très inefficace en espace et en temps! Pourquoi?

29/9/2005© 2005 P. Van Roy. All rights reserved.31 Une autre définition de X N Voici une autre définition de x n : x 0 =1 x 2n+1 =x * x 2n x 2n =y 2 où y=x n (n>0) Comme la première définition, nous pouvons programmer cette définition tout de suite! Les deux définitions sont aussi des spécifications Ce sont des définitions purement mathématiques La deuxième définition est plus élaborée que la première, mais cest quand même une spécification

29/9/2005© 2005 P. Van Roy. All rights reserved.32 Définition de {Pow X N} fun {Pow X N} if N==0 then 1 elseif N mod 2 == 1 then X*{Pow X (N-1)} else Y in Y={Pow X (N div 2)} Y*Y end

29/9/2005© 2005 P. Van Roy. All rights reserved.33 Pow avec un accumulateur La définition précédente nutilise pas daccumulateur Est-ce quon peut faire une autre définition avec un accumulateur? Il faut dabord un invariant! Dans linvariant, une partie accumulera le résultat et une autre partie tendra à disparaître Quest-ce qui est accumulé dans Pow?

29/9/2005© 2005 P. Van Roy. All rights reserved.34 Pow avec un accumulateur Voici un invariant: x n = y i * a Cet invariant peut être représenté par un triplet (y,i,a) Initialement: (y,i,a) = (x,n,1) Il faut faire diminuer i, tout en gardant vrai linvariant Il y a deux types ditérations: (y,i,a) devient (y*y,i/2,a) (si i est pair) (y,i,a) devient (y,i-1,y*a) (si i est impair) Quand i=0 le résultat est a

29/9/2005© 2005 P. Van Roy. All rights reserved.35 Définition de {Pow X N} avec un accumulateur fun {Pow2 X N} fun {PowLoop Y I A} if I==0 then A elseif I mod 2 == 0 then {PowLoop Y*Y (I div 2) A} else {PowLoop Y (I-1) Y*A} end end in {PowLoop X N 1} end

29/9/2005 © 2005 P. Van Roy. All rights reserved. 36 Introduction aux listes

29/9/2005© 2005 P. Van Roy. All rights reserved.37 Introduction aux listes Une liste est une structure composée avec une définition récursive: Une liste est une liste vide ou un élément suivi par une autre liste Voici une règle de grammaire en notation EBNF: ::= nil | T | représente une liste déléments de type T et T représente un élément de type T Attention à la différence entre | et |

29/9/2005© 2005 P. Van Roy. All rights reserved.38 Notation pour les types représente un entier; plus précisément lensemble de toutes les représentations syntaxiques de tous les entiers > représente lensemble de toutes les représentations syntaxiques des listes dentiers T représente lensemble des représentations syntaxiques de tous les éléments de type T; nous disons que T est une variable de type

29/9/2005© 2005 P. Van Roy. All rights reserved.39 Syntaxe pour les listes (1) Syntaxe simple (lopérateur | au milieu) nil, 5|nil, 5|6|nil, 5|6|7|nil nil, 5|nil, 5|(6|nil), 5|(6|(7|nil)) Sucre syntaxique (la plus courte) nil, [5], [5 6], [5 6 7]

29/9/2005© 2005 P. Van Roy. All rights reserved.40 Syntaxe pour les listes (2) Syntaxe préfixe (lopérateur | devant) nil |(5 nil) |(5 |(6 nil)) |(5 |(6 |(7 nil))) Syntaxe complète nil, |(1:5 2:nil) |(1:5 2:|(1:6 2:nil)) |(1:5 2:|(1:6 2:|(1:7 2:nil)))

29/9/2005© 2005 P. Van Roy. All rights reserved.41 Opérations sur les listes Extraire le premier élément L.1 Extraire le reste de la liste L.2 Comparaison L==nil L1==L2

29/9/2005© 2005 P. Van Roy. All rights reserved.42 Longueur dune liste La longueur dune liste est le nombre déléments dans la liste On peut la calculer avec une fonction récursive: fun {Longueur L} if L==nil then 0 else 1+{Longueur L.2} end end Exercice: faire une version de Longueur avec accumulateur!

29/9/2005© 2005 P. Van Roy. All rights reserved.43 Résumé Récursion sur les entiers Spécification dune fonction La définition mathématique de la fonction; parfois inductive A partir dune spécification on peut faire une implémentation en langage de programmation Invariant dune fonction Une formule logique qui est toujours vraie pour les arguments à chaque appel récursif de la fonction Boucle Quand lappel récursif est la dernière instruction (récursion terminale), la mémoire utilisée est constante. Dans ce cas, la fonction récursive est une boucle. Attention: il existe des systèmes qui nont pas implémenté cette propriété (surtout parmi les implémentations des langages impératifs). Pour les systèmes qui ont ce défaut, la récursion est à utiliser avec modération. Accumulateur Utiliser un accumulateur est une bonne technique pour faire une boucle Un accumulateur est toujours lié à un invariant Liste et fonction récursive sur une liste