===== Fondements de la programmation ===== Un objectif de ce cours est de découvrir sur quoi repose la programmation en se basant sur l'étude des programmes et des langages. Les langages révèlent des modes de programmation. Mais qu'est-ce qu'un mode de programmation? * un ensemble de concepts et d'outils mathématiques qui forment un modèle * un certain savoir-faire et un ensemble de méthodes -> génie (logiciel) Dans ce contexte de génie logiciel, un programme ressemble à un "produit" dont on peut estimer (apprécier?) la qualité selon des critères tels que : * performance : temps de calcul, économie de mémoire, etc. * lisibilité : documentation, potentiel de réutilisation * correction : le critère le plus important. Nous allons étudier les programmes selon trois aspects : - __sémantique du langage__ -- quel est la signification possible d'un programme dans le modèle considéré? - __preuve de correction__ par rapport à une spécification (ce terme reste à définir pour l'instant); - __la construction à partir d'une spécification rationnelle__ par des techniques de transformations successives. Ce cours présente un modèle de raisonnement sur les programmes pour les construire, les transformer, les prouver. ==== Contexte ou difficulté de l'étude ==== Un programme est un texte qui relie deux univers de natures très différentes, * l'univers du problème "très descriptif", où la relation entre les données et le résultat est décrite, et * l'univers du programme, "très préscriptif", où les opérations à executer par l'ordinateur sont précisées. C'est cette différence de natures qui nécessite l'introduction d'un modèle de raisonnement adapté. === Exemple === * Problème : "trouver le nombre d'occurrences d'un nombre donné dans un tableau (ou liste) de nombres." * Données : ''t'', un tableau de ''n'' nombres\\ ''x'', un nombre * Résultat : le nombre ''p'' de fois que ''x'' apparaît dans ''t'' === Enoncé qui qualifie le résultat === Ecrit de manière formelle, ce problème peut s'exprimer de la manière suivante, où l'on qualifie le résultat ''p''. * \exists i_1 , \ldots i_p \in [0,\ldots ,n-1] tels que * \forall k\in [1,\ldots ,p] \quad t[i_k]=X * \quad\&\quad \forall i \in [0,\ldots ,n-1]\setminus \left\{i_1,\ldots i_p\right\} \quad t[i] \ne x === Enoncé qui définit le résultat === Une autre forme d'énoncé permet d'exprimer ce problème et définit le résultat ''p'' au sens mathématique, c'est à dire que l'énoncé prend la forme "p=..." où ''p'' est définit cas par cas selon la valeur des données. Dans le cas de notre décompte, la décomposition par cas repose sur la façon de construire le tableau et renvoie à la notion de type (quel est le type de ''t''?) et de constructeur (comment sont construites les valeurs de ce type?). Supposons qu'un tableau est soit un seul élément, soit composé d'un élément et d'un tableau. Il nous faut une notation pour les valeurs des tableaux qui sont contruits. ^ On notera : | ''a::t'' | le tableau à ''n'' éléments ou ''a'' est un élément et ''t'' est un tableau à ''n-1'' éléments. | | p(a, x) = | 1 si '''x=a'' \\ 0 sinon | | p(a::t, x) = | 1 + (t, x) si ''a = x ''\\ p(t, x) sinon | Lorsqu'on définit le résultat (de façon explicite ou constructive) l'énoncé prend la forme d'une définition de fonction récursive (le résultat est fonction des données). On peut se demander si cet énoncé est un programme ou non. Au sens stricte de prescription directe des opération à réaliser (par l'ordinateur), ceci n'est pas encore un programme. On peut simplement dire que cet énoncé prescrit indirectement les opérations à la manière des langages fonctionnels. Certains affirment que ces énoncés sont des spécifications et que le dernier énoncé est (sera) une "spécification exécutable." Un "véritable" programme a plutôt la forme suivante (expression en langage C) : int occur (int * t[], int n, int x) { int i, p=0; for (i=0;i état mémoire ''s' '' tel que //nouvelles conditions// où ''s'' et ''s' '' sont appelés respectivement état initial et état final. La programmation impérative est fondée sur (et caractérisée par) * //variable// au sens informatique * //mode d'exécution// associé : transition d'état N.B. Les types et les constructeurs sont aussi des éléments fondamentaux, mais qui ne sont pas spécifiques à ce mode, ils fondent aussi d'autres modes de programmation. === Programmation Fonctionnelle, Logique === Les autres modes de programmation utilisent des variables qui ont le même sens qu'en mathématiques. Dans ces modes, un énoncé est parfois une "spécification exécutable." La programmation fonctionnelle est fondée sur (et caractérisée par) * fonction * mode d'exécution associé : réduction de λ-calcul La programmation logique est fondée sur (et caractérisée par) * clauses de Horn * mode d'exécution associé : démonstration par réfutation((et jamais déduction? :?: Je ne sais pas, je ne connais pas ces langages.)) après unification nécessaire des termes. ---- A ceux-là on peut rajouter * des modes de programmation fondés sur des théories mathématiques éprouvées * des modes de programmation impérative atypique, qui posent des problèmes plus conséquents. ---- [[semantics_2|]] -0- [[semantics_td_1|]]