programme

(bas latin programma, du grec programma, écrit public)

Ensemble d'instructions et de données représentant un algorithme et susceptible d'être exécuté par un ordinateur.

INFORMATIQUE

L'intelligence artificielle

Introduction

Élaborer des programmes d'ordinateur pour imiter, simuler ou modéliser le comportement humain : tel est le rôle de l'intelligence artificielle (I.A.). Alors que l'informatique classique procède par traitement séquentiel des données à l'aide d'algorithmes de résolution, l'intelligence artificielle manipule directement des symboles : non seulement des objets concrets – ou des « empreintes » d'objet comme la forme d'un signal sonore ou visuel – mais aussi des idées, des concepts, des procédures… Cette programmation symbolique ou « par objets » privilégie les aspects déclaratifs ou descriptifs de l'information tandis que le traitement utilise des procédures heuristiques (d'un mot grec signifiant « trouver en cherchant ») pour obtenir rapidement la solution au problème posé.

En informatique traditionnelle, l'analyste-programmeur décompose préalablement son problème avant de le coder sous la forme d'un programme exécutable par l'ordinateur ; le spécialiste en intelligence artificielle – le cogniticien – raisonne différemment : « J'ai un problème qu'a priori je ne sais pas résoudre. Voici les lois qui régissent le domaine concerné et voici les faits. L'ordinateur va trouver la solution et indiquer la façon dont il résout ce problème. » Cette démarche implique la formalisation préalable du raisonnement humain et justifie l'appellation d'ingénierie de la connaissance, ou génie cognitif, donnée à ces techniques d'intelligence artificielle. Les recherches avancées s'orientent vers les réseaux neuronaux – structures multiprocesseurs dont le fonctionnement cherche à imiter celui du cerveau – et vers la logique floue, méthode logicielle qui rend plus conviviale la relation homme-machine en restituant la part d'imprécision et d'ambiguïté qui caractérise la prise de décision humaine.

Les applications les plus concrètes de l'intelligence artificielle sont les systèmes experts, logiciels d'aide à la décision utilisables dans de nombreux domaines où l'on peut mémoriser la connaissance de spécialistes. Leur emploi s'est diversifié de l'industrie à la médecine en passant par la banque, la finance et les assurances ainsi que la simulation, les jeux stratégiques, la maintenance des équipements…

De Lisp à la logique floue

À la fin des années 1950, deux ans après la naissance du langage Fortran, John McCarthy définit au MIT une nouvelle méthode de programmation logique : son langage, Lisp, prend en compte des listes de données structurées en arborescences. Mathématicien, le père de Lisp cherche ainsi à faciliter les traitements d'équations matricielles mais il répond aussi aux besoins d'une discipline émergente qui jusqu'alors a buté sur la représentation algorithmique classique : l'intelligence artificielle. Dans Lisp, les listes de symboles sont agencées en arbres avec des fonctions automatiques de sélection ou d'aiguillage entre les branches : le concepteur est libéré des entraves techniques de la construction des programmes complexes. Au cours des années 1970, chercheurs, logiciens et informaticiens écrivent de nombreuses versions de Lisp sur des ordinateurs spécifiques à l'intelligence artificielle. En 1982, aux États-Unis, sous l'impulsion du département de la Défense, une normalisation de ces langages est engagée avec le standard Common Lisp.

En France, à l'Inria (Institut national de recherche en informatique et en automatique), un nouveau Lisp est créé en 1981 par l'équipe de Jérôme Chailloux : on souhaite s'affranchir de l'utilisation des coûteuses machines spécialisées en intelligence artificielle pour porter Lisp sur des ordinateurs classiques, notamment les nouvelles stations de travail graphiques. Ces travaux français conduisent en 1988 à la version européenne EU-Lisp, appelée à converger avec la voie américaine Common Lisp vers une norme unique internationale, ISO-Lisp en 1992.

Second langage de l'intelligence artificielle, Prolog est d'origine française. Conçu en 1973 par l'équipe d'Alain Colmerauer à l'université d'Aix-Marseille, il est retenu par les chercheurs japonais pour leur ambitieux programme d'ordinateur de « cinquième génération ». Prolog est aussi à l'origine de nouvelles méthodes de programmation par contraintes qui simplifient l'écriture des systèmes experts : ces « contraintes » caractérisent un domaine d'application, en définissent les limites ou les règles d'appartenance ou d'exclusion…

De nouveaux langages « orientés objets » ont été développés pour faciliter la programmation et apporter une meilleure convivialité mais les recherches les plus avancées concernent la logique floue, fondée sur la théorie mathématique des ensembles flous élaborée en 1965 par Lotfi A. Zadeh à l'université californienne de Berkeley. Elle prend en compte les notions d'incertitude, d'imprécision et d'ambiguïté qui caractérisent le comportement humain. Associée aux réseaux neuronaux – systèmes informatiques dont l'architecture est calquée sur le fonctionnement des neurones de notre cerveau –, cette nouvelle logique devrait davantage « humaniser » l'intelligence artificielle, la rendre moins rigide, plus conviviale.

Les systèmes experts

Faciliter la résolution d'un problème ou apporter une aide à la décision : tel est le rôle des systèmes experts. Ces logiciels à base de connaissance sont utilisés dans de nombreux domaines. Voici quelques exemples réels de problèmes qu'ils peuvent simplifier ou prendre en charge en totalité : évaluer un risque d'avalanche, prévoir la présence d'une nappe de brouillard ; affecter un quai à un train lors de son entrée en gare, optimiser la circulation urbaine aux heures de pointe ; assister le médecin lors d'un diagnostic, ou le malade, par exemple le diabétique, pour le suivi d'un traitement médicamenteux ; interpréter des images de télédétection prises par satellites ou celles issues des appareils d'imagerie médicale : radiographie, scanographie, échographie… ; évaluer un bilan financier, faciliter un placement bancaire, gérer un portefeuille boursier, choisir un contrat d'assurance, rédiger un appel d'offres administratif ; concevoir des gammes d'usinage, réduire les encours en gestion de production, programmer l'implantation des machines-outils et robots, gérer un atelier flexible de production ; détecter une erreur de conception sur une carte électronique, tester par simulation les fonctions logiques d'un microcircuit, déceler des vibrations sur un turboalternateur, gérer la maintenance d'une machine ou d'une installation ; élaborer les séquences nécessaires à la synthèse d'une macromolécule organique, contrôler la croissance de cristaux d'arséniure de gallium ; préparer des scénarios tactiques et stratégiques sur les champs de bataille ; assister les contrôleurs d'opérations aériennes, traiter des alarmes dans la salle de contrôle-commande d'une centrale électronucléaire ; aider l'éleveur de bétail ; corriger des textes en plusieurs langues ; concevoir un scénario de film…

Des ordinateurs à l'image du cerveau

L'intelligence artificielle s'est jusqu'à présent développée dans la seule voie du logiciel grâce à des procédures logiques pour imiter les capacités de raisonnement d'un expert humain. Il était donc tentant de simuler ce comportement directement sur un processeur de calcul fonctionnant à la manière de notre cerveau. Amorcées au cours de la Seconde Guerre mondiale sur la base des études en neurophysiologie, les recherches sur les réseaux électroniques de neurones ont débouché en 1960 à l'université américaine de Cornell, avec le Perceptron, « rétine » électronique de 400 photo-récepteurs…

Dans les années 1960, cette voie est éclipsée par l'avènement de l'intelligence artificielle, alors considérée comme plus prometteuse. Il faudra attendre les travaux de John H. Hopfield du California Institute of Technology en 1982 et l'élaboration d'algorithmes d'apprentissage pour remettre en lumière les systèmes neuromimétiques – qui imitent le fonctionnement des neurones. Ces recherches bénéficient alors des progrès de la microélectronique et des techniques de traitement de l'information avec des processeurs en parallèle.

Les réseaux neuronaux sont constitués d'un très grand nombre d'éléments de calcul, appelés neurones artificiels et fortement interconnectés en réseaux : d'où le nom de « machines connexionnistes » donné à ces systèmes. Ils travaillent en parallèle selon des procédures particulières : soumis à une simulation externe – par exemple des signaux numériques résultant de l'analyse spectrale d'un son, d'une image ou d'une matrice de données –, le réseau modifie spontanément l'ensemble de ses connexions neuronales jusqu'à un état stable. Après cette phase d'apprentissage, il sera capable de reconnaître très rapidement des modèles en réagissant à des signaux identiques.

Plusieurs machines ont été construites sur ce principe et certaines commercialisées dès la fin des années 1980, comme la Connection Machine, utilisée pour le traitement d'images. Des sociétés spécialisées, souvent créées par des chercheurs et des spécialistes de ce domaine, diffusent également des logiciels pour simuler sur des micro-ordinateurs le comportement d'un réseau de neurones. Les efforts de recherche se poursuivent dans le monde entier, notamment avec le programme communautaire Brain (Basic Research in Adaptative Intelligence and Neurocomputing) lancé en 1987 dans le cadre du programme Esprit : 30 laboratoires européens y participent et les investissements mobilisent plus de 7 milliards de francs.

Aide au diagnostic médical

Mis au point dès 1976 à l'université américaine de Stanford par Edward Shortliffe, Mycin est l'un des tout premiers systèmes experts pour le diagnostic des maladies infectieuses du sang. Depuis cette date, de nombreuses applications de l'intelligence artificielle à la médecine ont été expérimentées. La médecine est pour cette nouvelle science de l'ingénierie des connaissances un vaste champ d'investigation et d'application : le savoir thérapeutique évolue vite, la pharmacopée s'enrichit chaque semaine… D'où l'utilisation des systèmes experts pour l'enseignement : grâce à leur capacité d'autoexplication, ces logiciels peuvent indiquer à chaque étape de leur « raisonnement » les règles qu'ils déclenchent et en justifient même l'application.

L'aide au diagnostic est en plein développement : le système expert ne saurait remplacer le médecin mais il aide le généraliste confronté à des pathologies rares ou complexes : artériopathies, rétinopathies diabétiques, désordres thyroïdiens… Autre assistance, l'interprétation des clichés issus d'appareils d'imagerie médicale : radiographie, scanographie, échographie, imagerie par résonance magnétique.

L'aide à la prescription par voie télématique permet aussi de diffuser auprès des généralistes – et parfois directement auprès des patients – l'expertise de spécialistes du domaine considéré : cancer, diabète, hypertension… Après ses premiers travaux sur les maladies bactériennes, Edward Shortliffe s'est intéressé à la cancérologie avec Oncocyn, système expert pour la gestion des protocoles anticancéreux, notamment pour le dosage en chimiothérapie. Des travaux sont également conduits en France, notamment à la fondation Bergognié de Bordeaux pour le cancer du sein, au centre François-Baclesse de Caen pour celui de l'ovaire et de l'utérus et au centre anticancéreux Gustave-Roussy de Villejuif. Enfin, les diabétiques peuvent utiliser le Minitel pour résoudre les problèmes qui se posent au cours de leur traitement : des systèmes experts mis au point au Centre hospitalo-universitaire de la Pitié-Salpêtrière et à l'Hôtel-Dieu de Paris donnent des conseils pour optimiser l'administration quotidienne d'insuline.

Les langages de programmation

Introduction

La caractéristique principale des ordinateurs est leur capacité à mémoriser à la fois les données à traiter et le traitement que l'on veut leur faire subir. Cette double faculté permet de décrire une fois pour toutes les traitements à réaliser et de les ranger en mémoire. Il ne reste plus qu'à introduire les données dans la machine pour la voir répéter fidèlement les instructions qui lui ont été fournies.

Il est donc nécessaire de pouvoir décrire les séquences d'opérations envisagées (les programmes). On procède, dans un premier temps, à l'analyse du problème à résoudre et des solutions à apporter en employant des notations qui conduisent à une description indépendante des machines : l'algorithme. On passe ensuite à la programmation proprement dite, qui consiste à adapter un algorithme à une machine donnée. On range sous le nom d'algorithmique la connaissance des algorithmes classiques (solutions connues et éprouvées à des problèmes habituels) et les techniques de conception d'algorithmes.

Cette description se fait à l'aide d'un langage de programmation. On distingue, parmi les langages de haut niveau, les langages spécialisés, conçus pour un domaine particulier : simulation, calcul symbolique, commande numérique, C.F.A.O. (conception et fabrication assistées par ordinateur), et les langages généraux, utilisables pour tout type d'application. Il existe un grand nombre de langages, qui se différencient sur des critères tels que la généralité, la simplicité d'apprentissage, la facilité de lecture et l'existence d'outils d'aide à l'écriture de programmes corrects.

Dates clés des langages de programmation

          

DATES CLÉS DES LANGAGES DE PROGRAMMATION

1956Fortran (FORmula TRANslator), premier langage de haut niveau, destiné au calcul scientifique.
1960Algol 60, (ALGOrithmic Language), premier langage défini de façon rigoureuse.
Cobol (COmmon Business Oriented Language), langage spécialisé pour la gestion.
Lisp (LISt Processor), langage de traitement de listes.
1961APT III (Automatic Programming Tool), langage pour la commande numérique des machines-outils.
1962APL (A Programming Language), langage pour le traitement des matrices.
1965Basic (Beginners'All purpose Symbolic Instruction Code), langage de haut niveau d'une grande simplicité d'apprentissage.
PL/1 (Programming Language/1), langage de programmation universel (scientifique et de gestion).
1968Reduce, langage pour le calcul formel. Snobol 4, langage spécialisé pour le traitement de chaînes de caractères.
1969Pascal, langage fortement structuré, très utilisé pour l'enseignement.
1972C, langage pour le développement de grands systèmes.
1975Prolog, premier langage de programmation en logique.
1979Ada, langage à vocation universelle, aboutissement des langages impératifs.
1980Smalltalk 80, archétype des langages orientés objet.

 

La représentation des informations

Pour qu'un programme puisse être exécuté, il faut qu'il soit rangé dans la mémoire principale de l'ordinateur avec les données qu'il soit traiter. Ainsi cohabitent dans la mémoire le programme, les données de départ, les résultats (intermédiaires ou définitifs) et le système d'exploitation. Celui-ci est un programme chargé, entre autres, d'assurer l'enchaînement des travaux, de gérer les mémoires principales et secondaires, de charger en mémoire en temps utile les programmes de service tels que compilateurs et interpréteurs.

Un programme est constitué par une suite d'instructions élémentaires, rangées dans des emplacements contigus. Une fois donnée l'adresse de la première instruction, la suite des instructions est parcourue à l'aide du compteur ordinal. Les données sont localisées, lors de l'exécution d'une instruction, par décodage de la partie adresse, qui repère les opérandes à traiter.

Avec n positions binaires (ou bits), on représente 2n objets différents. Les données sont représentées en mémoire en utilisant des codes. Par exemple, on utilise les codes ASCII (American Standard Code for Information Interchange), EBCDIC (Extended Binary Coded Decimal Interchange Code) ou DCB (Décimal Codé Binaire) pour représenter les caractères. Les différences portent sur le nombre de bits utilisés et la disposition des séries de 0 et de 1 pour un caractère donné. Il existe aussi plusieurs codes pour représenter les nombres. On représente par exemple les nombres entiers à l'aide d'un signe et de leur valeur absolue, ou par l'emploi du complément à 2.

Les niveaux de langages

Les langages de programmation permettent d'écrire les programmes qui seront exécutés par la machine. On distingue des niveaux de langages suivant leur degré d'indépendance par rapport à la machine utilisée.

Un programme en langage machine est constitué de suites de 0 et de 1, codant directement les instructions et les données. Ce langage dépend de la machine et est le seul qu'elle comprend directement, de par la structure des circuits constituant l'unité centrale. Le jeu d'instructions diffère d'une machine à l'autre par la taille des mots utilisés, le nombre d'instructions, le nombre d'opérandes par instruction, l'existence potentielle de registres. Les modes d'adressage jouent également un grand rôle dans cette diversité.

L'écriture directe d'un programme en langage machine est une opération fastidieuse et source de nombreuses erreurs potentielles. Tout programme devant cependant être implanté en mémoire sous forme de langage machine, on a inventé des langages s'éloignant du langage machine, mais traduisibles automatiquement. C'est ainsi que, pour un langage d'assemblage, on utilise un codage symbolique des instructions et des données. Chaque code opération se voit affecter un mnémonique permettant de le coder sans erreur. Les adresses sont données soit directement par leur numéro, soit à l'aide d'identificateurs, appelés en général étiquettes. On peut ainsi utiliser des variables. Les données sont codées en fonction de leur nature (nombres, chaînes de caractères). Un programme de traduction se charge de transposer ces ensembles de codes en leur équivalent en langage machine. Ce programme est appelé assembleur. Un langage d'assemblage dépend étroitement d'une machine, dans la mesure où il est le reflet fidèle du répertoire d'instructions et de la structure de cette machine. Son emploi apporte une plus grande sécurité, puisque l'usage de mnémoniques et la gestion automatique des adresses enlèvent un grand nombre de possibilités d'erreur. L'inconvénient majeur est qu'il faut réécrire complètement un programme si l'on change de machine.

On a donc recherché des langages assurant l'indépendance par rapport à la machine : ce sont les langages de haut niveau. L'objectif idéal de ces langages est d'offrir un moyen d'exprimer un algorithme à l'aide de notations précises, non ambiguës, mais les plus proches possibles de l'expression habituelle. Cet objectif est loin d'être atteint aujourd'hui : les langages actuels sont encore très contraignants par leur syntaxe et la faiblesse de leur sémantique. Ils permettent cependant d'entreprendre l'écriture de programmes (ou logiciels) d'une grande complexité, inimaginables avec les seuls langages machine ou d'assemblage. Les langages de haut niveau permettent d'écrire des programmes indépendants des machines sur lesquelles ils sont appelés à être exécutés (on parle de portabilité des programmes). Ces langages font en général l'objet de normes, codifiant à la fois leur syntaxe et les effets attendus lors de l'exécution de leurs instructions.

La traduction des langages

Les programmes écrits en langage d'assemblage nécessitent une phase de traduction, assurée par un programme, l'assembleur. Celui-ci effectue une traduction automatique du programme source (programme à traduire) en programme objet, ensemble d'instructions en langage machine. Ce programme doit être complété (par des modules prédéfinis, par exemple) et mis en place dans la mémoire, afin de pouvoir être exécuté directement (programme exécutable). Cette phase est appelée édition de liens. Le programme à exécuter a donc figuré successivement en tant que données (programme source) puis comme résultat du programme assembleur (programme objet). Le programme objet est à son tour devenu données de l'éditeur de liens, le résultat étant le module exécutable.

Ce schéma est identique pour les langages de haut niveau lorsqu'ils sont traduits (on dit alors qu'ils sont compilés). Cependant, tous les programmes écrits en langage de haut niveau ne sont pas traduits. On emploie parfois une technique d'analyse ligne à ligne du programme source. Tout se passe comme s'il y avait simulation d'une machine de haut niveau : on parle alors d'interprétation. Il n'y a que le programme interpréteur qui s'exécute dans la mémoire de la machine, le programme source jouant toujours le rôle de données. Un programme interprété est plus facile à mettre au point qu'un programme compilé, mais s'exécute plus lentement. Il existe cependant des compilateurs incrémentiels qui permettent de réaliser des traductions et des exécutions ligne à ligne, ce qui permet de réunir les avantages des deux techniques.

Quelques langages

Plusieurs méthodologies de programmation ont vu le jour, ayant pour objectif d'assurer une meilleure lisibilité, des techniques de preuve de la correction, et une plus grande facilité de maintenance par découpage en modules. Elles ont conduit à la création de langages généraux qui leur sont directement rattachés.

La programmation impérative fait appel à des primitives algorithmiques qui permettent de décrire de manière précise l'ensemble des traitements à appliquer aux différentes variables utilisées. L'écriture des programmes se fait de manière assez automatique, en se donnant des règles de traduction des algorithmes tenant compte de la machine ou du langage visé. Cette technique permet d'assurer une certaine normalisation de l'écriture, qui a une grande importance pour les phases de mise au point et de maintenance. Ce style de programmation a conduit à des langages comme Fortran, Cobol, Basic, Pascal ou Ada.

Fortran a été conçu pour permettre la formulation concise des problèmes numériques. Cobol est un langage orienté vers la gestion, le traitement de fichiers, l'édition d'états. Basic, langage facile à apprendre, est très répandu sur les micro-ordinateurs. Pascal a été inventé pour faciliter la mise en œuvre des principes de la programmation disciplinée. Ada permet de définir des modules (appelés paquetages) en séparant la spécification fonctionnelle (objets traités et accès à ces objets) du corps du traitement (traitements et structures de données). L'existence de tâches communicantes se synchronisant par rendez-vous permet de programmer des processus parallèles.

La programmation fonctionnelle est une technique de conception dirigée par les procédures. Les programmes sont des suites d'appels de procédures ou de fonctions agissant sur des données passées en paramètres. Ce mode de programmation fait appel à des langages offrant des opérateurs de haut niveau permettant de ne plus décrire en détail les traitements à réaliser sur les données. C'est ainsi que le langage Lisp offre des opérateurs de traitement des listes et que le langage APL s'applique sur des tableaux et des matrices.

La programmation logique s'intéresse au calcul sur des propositions logiques (ou prédicats). À partir de bases de règles et de faits, de nouveaux faits sont déduits, qui permettent de vérifier ou d'invalider les propositions que l'on cherche à démontrer. Le langage le plus connu de cette classe est Prolog. Il permet de construire notamment des systèmes experts et des démonstrateurs de théorèmes.

La programmation par objets est une méthodologie dirigée par les données. Les objets sont des entités logiques composées à la fois de données et de méthodes (traitements, calculs) que l'on peut appliquer à ces objets. Un programme est constitué par une suite de messages destinés aux différents objets qu'il souhaite employer. Les objets peuvent être regroupés en classes, sur des critères logiques communs. Les classes peuvent être organisées en structures hiérarchiques. La notion d'héritage permet alors de faire partager une même propriété à tous les objets appartenant à une telle structure. La programmation par objets a pour conséquence de conduire à un découpage en modules indépendants, ce qui facilite le travail de développement de gros logiciels. En particulier, elle conduit à la réalisation de boîtes à outils, bibliothèques d'objets et de méthodes dans lesquelles il suffit de puiser pour construire un programme. C'est ainsi que le langage Smalltalk 80 offre un ensemble d'environ 1 000 méthodes.