Home | News | Hacking | Sciences | Technology | Ti 92 | Programming | Free articles | Links | Webmaster

Virus & Artificial Life

Homepage / TS / Virus & Artificial Life

|       |- /Les Virus sont-ils vivants ?

|       |- /AntiVirus

|       |- /Types de virus

|       |- /Worms

|       |- /Réseau de Neurones

|       |- /Algorithmie Génétique

|       |- /Présentation de l'Intelligence Artificielle

|       |- /Théorie des Jeux

|       |- /Principes d'Informatique Linguistique

|       |- /Self-Organization in Large Population of Mobile Robots

|       |- /Introduction au Connexionisme

|       |- /Minds and Machine : Behaviorism, Dualisme and Beyond

|- /Coding

|- /System

|- /Hacking & Network

|- /Cracking

|- /Phreaking & Waves

Bible des Interruptions Assembleur

 

Les virus sont-ils vivants ?

L’observateur ingénu peut affirmer que les virus informatiques ont l’air vivants. Ils donnent l’impression d’être doués d’une volonté propre et leur comportement au sein des ordinateurs ne dépend pas des souhaits de l’ordinateur. Ils se reproduisent et certains d’eux se sont montres très habiles à se propager d’un PC à un autre. Ils se présentent sous les formes les plus variés : pittoresques ou sournois, dangereux ou inoffensifs, actifs ou en sommeil.

Mais sont-ils pour autant vivants ?

Ne seraient-ils que de bonnes imitations du genre caniche mécaniques jappant dans un magasin de jouets en plus sophistique, c’est-à-dire rien de plus que des machineries charmantes (question de point de vue) ?

Ne faut-il pas reformuler la question : dans quelle acception du terme les virus sont-ils des êtres vivants ?

Ils ne sont certainement pas organiques comme nous autres. Mais dans le monde scientifique où nous vivons, nous serions sots et bornes de ne vouloir qualifier de vivants que les organismes relevant de la chimie organique. Lorsque nous explorons les confins de notre univers à la recherche de nouvelles formes de vie, que ce soit par observation directe en envoyant (ou tentant d’envoyer) des sondes sur Mars ou par tentative indirecte en cherchant à capter des signaux radio intelligibles (SETI Project), nous nous efforçons d’élargir nos horizons. Nous devons approfondir la question pour nous demander « Quelles sont les caractéristiques de la vie ? » Ce n’est qu’à partir du moment où nous aurons détermine ces caractéristiques que nous pourrons prendre en considération une entité quelconque, chercher en elle des signes de vie avant de décider de la qualifier de vivant.

Le phénomène des virus informatiques ramène cette question à nos portes. Ils sont parmi nous, ici et maintenant. Nous sommes capable de les isoler et de les soumettre à expérimentation. Et, que cela nous plaise ou non, nous devons nous en préoccuper au quotidien. Les formes de vie extraterrestres en revanche ne sont pas aussi aisément accessibles.

Je pense pour ma part qu’il est très important de profiter de l’aubaine que représentent les virus pour élargir notre compréhension du phénomène de la vie. Je crois que nous ne pouvons que faire progresser notre connaissance de la vie telle qu’elle l’est en l’étudiant aussi telle qu’elle pourrait l’être. L’homme moderne est un être présomptueux qui généralement en sait moins sur l’univers qu’il ne le prétend. Cette forme de vantardise est particulièrement manifeste lorsqu’il s’agit de systèmes aussi complexes que les organismes vivants. En vérité, nos connaissances actuelles de la vie sont très limitées. Nous en savons certes plus long qu’au siècle dernier mais nous ne devrions pas nous bercer d’illusions en pensant que nous approchons du but. Les difficultés auxquelles nous sommes confrontées lorsque nous cherchons à synthétiser des organismes vivants, par exemple, limitent considérablement nos capacités à réaliser des expériences qui nous permettraient de mieux comprendre comment le codage de l’ADN (génotype) affecte nos caractéristiques physique (phénotype) d’un organisme vivant. Même si nous parvenons à synthétiser à volonté des brins d’ADN et à construire la mécanique complexe qui doit les accompagner pour créer des organismes vivants, nous n’en aurons peut-être pas envie de peur de donner naissance à des monstres qui ferais passer la peste bubonique pour une vulgaire varicelle. La vie simulée par ordinateur – c’est-à-dire la Vie Artificielle (VA) – peut présenter une solution pratique pour étudier en toute sécurité cette relation génotype/phénotype.

De plus, si un jour nous devrions découvrir une forme de vie sur un corps céleste, ne devrions-nous pas faire en sorte d’être prêt à l’identifier comme telle pour pouvoir agir en connaissance de cause ? A l’heure actuelle, si nous découvrions une forme de vie inorganique, nous serions probablement incapable de la reconnaître. Quelles en seraient les conséquences ? L’anéantirions nous sans même nous en rendre compte ? Où l’offenserions nous à un tel point qu’elle n’ait plus qu’une seule envie : nous éradiquer de la face de l’univers ? Certains pensent que nous n’aurions aucune peine à reconnaître une forme de vie extraterrestre et à la traiter avec respect ( si nous ne la combattons pas) si nous en trouvions. Ce n’est que de la science-fiction naïve. Il y a à peine un siècle et demi, nos ancêtres possédaient des esclaves noirs. Il leur arrivait de les battre à mort, convaincus de ne commettre aucune faute puisque les nègres n’avaient pas le statuts d’êtres humains. Certains d’entres eux en étaient intimement persuades ! Ne pas croire que cela est possible ,e change rien à l’affaire car nous ne sommes pas mieux lotis aujourd’hui lorsqu’il s’agit d’explorer l’univers en quête de traces de vie. Cette situation doit évoluer ; à défaut, nous serions mieux avises de rester sur notre bonne vieille Terre sans rien dire.

Chaque fois que nous avons entrepris d’explorer notre monde, nous avons beaucoup de peine à appréhender nos découvertes. Nos plus grands esprits se sont échinés toute leur vie à décortiquer une parcelle de connaissance ici ou là. Même ces génies sont restes loin d’une compréhension totale des phénomènes étudiés. Ces découvertes parcellaires se sont faites au prix d’efforts inouïs : travail acharnes, recherche laborieuse, essais et erreurs, renoncements, reprise de la quête et enfin illumination. Lorsqu’ils voulaient faire profiter l’humanité de ces bribes de connaissance, ils étaient souvent accueillis par le rejet et la persécution parce qu’il forçait leurs condisciples à remettre en question leurs hypothèses philosophiques par rapport à eux-mêmes et au monde qui les entourait.

Pourquoi une connaissance plus approfondie de la vie donnerait-elle des résultats différents ? Il n’y a aucun doute que nous ayons du faire preuve d’opiniâtreté pour apprendre ce que nous savons de la vie terrestre. Si nous tentons d’appréhender la vie sous un angle plus abstrait, nous serons à nouveau poussez vers nos limites. Nous serons à nouveau confronte à des points délicats et des faits obtus. Pourquoi ne pas adopter une attitude plus responsable et nous attaquer à cette question des maintenant plutôt que d’attendre de commettre une gaffe majeur en éradiquant une civilisation entière faute de l’avoir perçue ou de provoquer l’anéantissement de notre civilisation pour avoir marche sur les pieds d’autrui ?

Des que nous posons la question « Qu’est ce que la vie ? », force est d’admettre que notre conception même de la vie est totalement inadaptée à tout objectif scientifique. « Qu’est c que la vie ? » est une question fort épineuse à laquelle il n’existe aucune réponse claire et tranchée. En un sens, la vie est un concept métaphysique qui nous est familier de par notre expérience quotidienne mais reste difficile à fondre dans un moule scientifique.

C’est la mode actuellement dans les milieux scientifiques de tenter d’occulter toutes considérations métaphysiques lorsqu’on étudie la vie. On se contente d’affirmer que la vie n’est  rien de plus qu’une machine hautement complexe organisée à partir de molécules organiques et qu’il ne se distingue fondamentalement que très légèrement des autres systèmes moléculaires. Cette hypothèse acceptée, la question de la définition de la vie se ramener à une simple question de fonctions. Si vous concevez une machine dotée des fonctions adéquates, vous pourrez la considérer comme vivante. Voilà brosse à grands traits la philosophie et les objectifs des chercheur en VA.

Bien entendu, une telle affirmation, tant qu’elle n’est pas démontrée, n’est rien de plus qu’une considération métaphysique en elle-même venant enrichir notre panoplie. Et la considérer comme acquise ne conduit qu’à éluder la question de la définition de la vie au lieu de la confronter. En fait, il peut même s’avérer théoriquement impossible de démontrer qu’un organisme vivant n’est qu’une machine hautement complexe qui pourrait être entièrement comprise à partir des lois connues de la physique. La seule façon de prouver cette affirmation consiste à résoudre l’équation d’un organisme vivant complexe et de prédire son comportement avec précision. Un nombre colossale d’obstacles se dressent devant nous qui nous empêchent d’y parvenir :

1-      Il y a tout lieu de croire que la forme la plus poussée de la théorie des catastrophes (l’idée qu’un papillon battant des ailes au Japon puisse provoquer une tornade au Kansas) doit être prise en compte pour déterminer le comportement des organismes vivants. Si l’on raisonne en terme de physique pure, pourquoi un séquence de vibrations sonores sur le tympan d’un être humain provoque-t-elle un sourire et une poignée de mains, alors qu’une autre séquence (les mêmes mots prononces sur un ton différent) provoque une empoignade ? Si de telles conséquences résultent uniquement de lois physiques, il nous faudra recourir à des calculs d’une précision époustouflante pour produire des conclusions significatives.

2-       Si une conclusion dépend trop largement des conditions et des informations de départ, il faut absolument prendre en compte la théorie du champ quantifié relativiste. On ne peut la négliger si l’on veut effectuer des calculs d’un niveau de précision acceptables. Or, nous maîtrisons mal les lois physiques dans ce domaines. Quand bien même serait-ce le cas, les incertitudes inhérentes à cette théorie nous empêcheraient d’obtenir une réponse tranchée.

3-       La simple ampleur des calculs (à un niveau donne de précision) pour un organisme même monocellulaire exclut toute possibilité de modélisation informatique. Il y a tout bonnement trop d’informations à traiter et tous les ordinateurs connus ont un mémoire finie.

C’est pourquoi l’idée qu’un organisme vivant n’est rien de plus qu’une machine complexe risque bien de demeurer à l’état de sujet métaphysique et d’être débattue, à coups d’arguments pour et contre, jusqu’à la fin des temps. De fait, l’idée que la vie ne serait qu’une machine n’a rien de neuf : elle a été l’objet de controverse depuis la Grèce Antique.

Compte tenu de la complexité de cette question de la vie, je ne souhaite pas me rallier à une solution de faciliter en la réduisant à une simple mécanique. Agir ainsi ne serait pas honnête sur le plan intellectuel même si la chose est très courante et même acceptée à l’heure actuelle. Je me refuse également, bien entendu, à adopter une définition purement métaphysique de la vie (genre « un être vivant est un être dote d’un esprit ») et balayer le problème d’un revers de manche. Tout candidat au label « vivant » doit être capable d’exécuter certaines fonctions que nous associons spontanément aux organismes vivants. Toutefois, la notion de fonction doit être replacée dans le cadre plus large de notre connaissance métaphysique et philosophique de la vie et non pas être considérée comme constituant ce cadre.

En affirmant cela, nous savons que nous nous dissocions de la communauté des chercheurs en VA. Nous craignons que ces chercheurs n’aient aborde la question de la vie avec la candeur habituelle propre à tous les scientifiques. Ils affirment que la vie n’est qu’une questions d’atomes et de lois physiques, la définissent strictement en terme de fonctions pour ensuite s’atteler à construire des modèles dotes des fonctions adéquates. Ils suggèrent alors avec une prudence mesurée que ces modèles sont vivants. Cette approche est éminemment dangereuse car elle nous élevé au rang de « Dieu créateur » et rabaisse la vie au niveau de vos pouvoirs de création. L’idée de devenir un créateur est exaltante mais, à partir du moment ou l’on se retrouve à déclarer que « la flamme d’une bougie est une forme de vie », il faut mieux se prendre pour un exaltes avant que d’autres ne vous affublent de ce qualificatif. L’orgueil naïf débouche souvent sur la sottise.

Nous aboutissons, au bout du compte, à deux conclusions importantes. Premièrement, notre connaissance métaphysique de la vie a une influence directe sur notre connaissance scientifique de celle-ci. Ces deux aspects sont inséparables. Deuxièmement, les virus informatiques sont importants non seulement pour leurs caractéristiques fonctionnelles mais également pour des raisons philosophiques. Ils peuvent nous donner l’occasion de nous confronter à des questions métaphysiques – et peut-être même les résoudre – si nous sommes prêts à admettre que de telles questions existent bien (elles continueront d’exister que nous le voulions ou pas).

C’est pour l’ensemble des ces raisons que nous souhaitons poser la question « Qu’est-ce que la vie ? »

La vie présente de nombreux aspects mécaniques qui apportent chacun leur pierre à notre perception de ce qu’elle est. Un grand nombre d’organismes biologiques sont dotes de l’ensemble de ces propriétés, bien que l’on puisse citer des exceptions à chacune d’elles. C’est pourquoi on ne peut appliquer aucune propriétés mécaniques comme test discriminatoire pour distinguer ce qui est vivant de ce qui ce qui ne l’est pas. Il n’en demeure pas moins que toutes ces propriétés semblent intimement liées à la vie et qu’elles contribuent à préciser notre idée de ce qu’est la vie d’un point de vue mécanique.

Il faut toutefois émettre une restriction : lorsque nous discutons des propriétés mécaniques de la vie (aptitude et méthode de reproduction, concept de comportement émergent, possession d’un métabolisme, aptitude à fonctionner et à interagir avec l’environnement, aptitude à l’évolution), nous ne pouvons faire abstraction des questions philosophiques qui s’y rattachent. Tracer une ligne de partage nette entre auto-reproduction et reproduction dirigée par des lois physiques est une entreprise plus délicate que prévue. De même ; le concept de comportement émergent perd de sa substance des qu’on le décortique. Nous devons nous demander si l’émergence appliquée à l’ordinateur ne serait pas un concept totalement différent de l’émergence du monde réel.

Les êtres humains ont la fâcheuse tendance de chercher à se raccrocher à des manifestations visibles qui viennent renforcer leurs hypothèses pour échafauder des principes ou construire des modèles. Toutefois, si nous prétendons être des scientifiques dignes de ce nom, nous devons démonter impitoyablement toutes les apparences pour découvrir si elles cachent une véritable substance.

Nous pouvons néanmoins déclarer d’ores et déjà que les virus informatiques répondent bien aux conditions mécaniques que nous avons posées, bien que nous ayons notes certaines lacunes dans les comportement émergent. Ces lacunes proviennent, nous semble-t-il, des limites intrasèques des systèmes d’exploitation mono-utilisateur. Un virus implantés dans un OS multitâche comme OS/2 serait probablement plus à même de nous révéler des indices de comportement émergent. Nonobstant, puisque nous ne recherchons pas à tout crin un critère discriminatoire, nous ne rejetons pas un virus donne s’il ne répond pas à tous nos critères en particulier si ceux-ci sont sujet à caution. Nous ne qualifions d’ailleurs pas non plus ce virus de vivant s’il répond à nos critères. Nous nous contentons d’affirmer qu’il a plus ou moins de raisons de revendiquer ce qualificatif. Sur le plan mécanique, nous pouvons des lors affirmer sans grand risque que les virus informatiques ont fortement le droit de revendiquer le qualificatif de « vivant ».

 

Antivirus

A) Définition générale

Un antivirus est, de par son nom déstiné à combattre les virus. C'est le seul moyen existant de détecter et de détruire les virus.
Les Virus étant de plus en plus sophistiqués, les antivirus ont dû, au fil du temps s'adapter et devenir de plus en plus performants sous peine de devenir obsolètes. En effet, avec l'accroissement constant du nombre de virus, les développeurs d'anti-virus doivent sans cesse actualiser leur base de données.

B) Pourquoi des antivirus ?

Pour Sécuriser les ordinateurs et préserver l'intégrité des données d'un ordinateur, qui peuvent être d'une importance énorme (par exemple, la base de données d'une banque ne doit sous aucun prétexte être modifiée par un virus...).

II) Aspects techniques des antivirus

Les antivirus rivalisent souvent d'ingéniosité pour combattre les virus. Cependant ces derniers trouvent souvent la parade. Nous allons parler ici des différentes techniques utilisées par les antivirus pour combattre leur raison de vivre.

A) Principales techniques de recherche de virus

Nous présenterons quatre techniques majoritairement utilisées par les antivirus pour localiser les virus. Il s'agit du scanning du moniteur de comportement, du contrôleur d'intégrité et de la recherche heuristique. Brièvement présenté, le scanneur recherche dans tous les fichiers ou en RAM un code spécifique qui est censé indiquer la présence d'un virus. Le moniteur de comportement surveille les actions habituellement menées par les virus, les contrôleurs d'intégrité signalent les changement intervenus dans les fichier et enfin la recherche heuristique recherche des instructions généralement utilisées par les virus.

1) Recherche de la signature (scanning)

C'est la méthode la plus ancienne et la plus utilisée, Son avantage est qu'elle permet de détecter les virus avant leur exécution en mémoire. Son principe est de rechercher sur le disque dur toute chaîne de caractères identifiée comme appartenant à un virus. Cependant comme chaque virus a sa propre signature, il faut, pour le détecter avec un scanneur que le concepteur de l'antivirus ait déjà été confronté au virus en question et l'ait intégré à une base de données. Un scanneur n'est donc pas en mesure de détecter les nouveaux virus ou les virus polymorphes (car ceci changent de signature à chaque réplication.)
Cette méthode est à la fois la plus simple à programmer mais aus Cette méthode est à la fois la plus simple à programmer mais aussi la plus longue à mettre en oeuvre car elle n'est utile que si elle recense tous les virus existant. Cela représente une somme de travail considérable et est quasiment impossible à réaliser. C'est pour ça que les concepteurs d'antivirus proposent des mises à jour de la base de donnée tous les mois sur leur site Web, c'est le seul moyen pour le scanneur de détecter les nouveaux virus.

2) Utilisation d'un contrôleur d'intégrité des fichiers

Schématiquement, un contrôleur d'intégrité va construire un fichier contenant les noms de tous les fichiers présents sur le disque dur auxquels sont associés quelques caractéristiques. Ces dernières peuvent prendre en compte la taille, la date et l'heure de la dernière modification ou encore un checksum(somme de contrôle).Un CRC (code de redondance cyclique), ou un algorithme de checksum avec un système de chiffrement propriétaire pourra détecter toute modification ou altération des fichiers en recalculant le checksum à chaque démarrage de l'ordinateur(si l'antivirus n'est pas résident), ou dès qu'un fichier exécutable est ouvert par un programme (si l'antivirus est résident); en effet si le checksum d'un programme avant et après son exécution est différent, c'est qu'un virus a modifié le fichier en question, l'utilisateur en est donc informé.
D'autre part l'antivirus peut aussi stocker la date et la taille de chaque fichier exécutable dans une base de données, et tester les modifications éventuelles au cours du temps. Il est en effet rare de modifier la taille ou la date d'un fichier exécutable. La parade pour les virus est de sauvegarder la date du fichier avant la modification et de la rétablir après.

3) Moniteur de comportement

Les moniteurs de comportement ont pour rôle d'observer l'ordinateur à la recherche de toute activité de type virale, et dans ce cas de prévenir l'utilisateur. Typiquement, un moniteur de comportement est un programme résident que l'utilisateur charge à partir du fichier AUTOEXEC.BAT et qui reste actif en arrière plan, surveillant tout comportement inhabituel. Les différentes manifestations d'un virus pouvant être détectées sont :
  • Les tentatives d'ouverture en lecture/écriture des fichiers exécutables.
  • Les tentatives d'écriture sur les secteurs de partitions et de démarrage.
  • Les tentatives pour devenir résident.

Pour repérer ces tentatives les antivirus détournent les principales interruptions de l'ordinateur et les remplacent par l'adresse de leur code. Les interruptions détournées son l'int 13H (disque dur), l'int 21H (DOS).Ainsi dès qu'un virus tente d'écrire sur le secteur de Boot, c'est l'antivirus qui est d'abord appelé, et qui peut ainsi prévenir l'utilisateur qu'un virus tente de modifier le secteur de Boot. L'antivirus peut alors éliminer le virus de la mémoire enregistrer une partie de son code dans la base de donnée et lancer un scanning pour repérer la/les souche(s) sur le disque disque dur et les détruire.

4) démarche heuristique

Fondamentalement, l'analyse heuristique concerne la recherche de code correspondant à des fonctions virales. Elle est différente dans son principe d'un moniteur de comportement qui surveille des programmes ayant une action de type virale. L'analyse heuristique est comme le scanning, passive. Elle considère le code comme une simple donnée, et n'autorise jamais son jamais son exécution. Un analyseur heuristique va donc rechercher du code dont l'action est suspecte s'il vient à être exécuté. L'analyse heuristique permet par exemple, pour les virus Polymorphes de chercher une routine de déchiffrement. En effet une routine de déchiffrement consiste à parcourir le code pour ensuite la modifier. Ainsi lors de l'analyse heuristique, l'antivirus essaie de rechercher non pas des séquences fixes d'instructions spécifiques au virus mais un type d'instruction présent sous quelque forme que ce soit. Pour en revenir à notre exemple de virus polymorphes, l'antivirus cherche une suite d'instructions de lecture suivie d'une suite d'instruction d'écriture.
Cette méthode est donc un peu plus intelligente que les autres: car elle vise à analyser les fonctions et instructions les plus souvent présentes et que l'on retrouve dans la majorité des virus. Cette méthode permet ainsi, contrairement au scanning, de détecter des nouveaux virus dont la signature n'a pas été ajoutée à la base de données.

5) Analyse spectrale

Tout code généré automatiquement est supposé contenir des signes révélateurs du compilateur utilisé. De même, au contraire, Il est impossible de retrouver dans un vrai programme exécutable compilé certaines séquences de code. C'est grâce à ce principe qu'entre en jeu l'analyse spectrale. Cette analyse vise à repérer les virus polymorphes qui sont indétectables autrement (leur signature changeant à chaque réplication). En effet, lorsqu'un virus polymorphe crypte son code, la séquence en résultant contient certaines associations d'instructions que l'on ne trouve pas en temps normal; c'est ce que détecte l'analyse spectrale. Par exemple, si dans un programme exécutable, l'antivirus trouve une instruction de lecture d'un octet au delà de la taille limite de la mémoire, on sera probablement en présence de code crypté, donc d'un virus polymorphe.

B) Principales techniques d'éradication de virus.

Une fois un virus détecté, que ce soit en mémoire ou sur le disque dur, il reste à le supprimer. Une fonction primordiale des antivirus est donc la suppression des virus. Leur but est de débarrasser l'utilisateur de ce programme malveillant. Mais il n'est pas si simple que l'on croit de les éradiquer et de récupérer le programme original. En effet cela est impossible dans le cas de virus avec recouvrement : ils détruisent une partie du programme sain lors de sa duplication. La seule solution est la destruction des fichiers infectés ou carrément le formatage du disque dur. Pour les autres, même si ce n'est pas irréalisable, la tache est cependant très ardue : il faut savoir très précisément où est localisé, dans le fichier, le virus en question sachant qu'il peut être composé de plusieurs parties, ensuite il faut le supprimer, et enfin aller chercher la partie du programme dont le virus avait pris la place et la restaurer. Toutes ces manipulations nécessitent une connaissance parfaite du virus et de son mode d'action. Cette éradication se faisant par une recherche (du virus, de la partie déplacée), toutes les caractéristiques des différents virus doivent être répertoriées dans une base de donnée mise à jour pratiquement quotidiennement.

Types de virus

Virus de fichiers

Ces virus ajoutent leur code à celui de fichiers exécutables (portant l'extension ".EXE", ".COM"...). Ils s'installent généralement en mémoire centrale sous une forme résidante, et de là, peuvent interférer avec le fonctionnement de la machine et se multiplier.
Certains de ces virus de fichiers ne modifient pas le fichier infecté. Le fonctionnement de ces virus dits compagnons nécessitent une petite explication.
Lorsque sous DOS vous lancer l'exécution d'un fichier sans préciser son extension, le système exécute d'abord le fichier portant l'extension ".COM".
Ainsi, les virus compagnons recherchent des ".EXE", créent un fichier".COM" du même nom ou il s'y implante. Lorsque l'utilisateur tente de lancer le programme ".EXE", le virus ".COM" est tout d'abord exécuté. Afin que sa présence ne soit pas décelée, le virus lancera le programme ".EXE" demandé.
Un virus compagnon peut également profiter de l'organisation des répertoires déclarés dans le PATH du DOS pour s'installer.


Virus de boot

A la mise sous tension, le PC exécute tout d'abord le programme contenu dans la ROM (mémoire morte de l'ordinateur), l'EPROM ou la Flash EPROM qui teste les différentes unités physiques à la recherche d'un disque dur.
Une fois localisé, le système charge en RAM le premier secteur du disque dur afin de l'exécuter. Ce secteur d'amorce est appelé la MBR (Master Boot Record). Cette zone est créée par le formatage du disque.
Ce secteur est donc exécuté en tout premier après la ROM ; c'est pour cela que les virus systèmes cherchent à recopier leur code dans cette partie du disque dur ou de la disquette.
Ces virus remplacent l'amorce par leur propre code, déplacent cette amorce sur le disque, et se chargent ensuite en premier en mémoire centrale, dès le premier accès au disque.


Virus des tables de partition de disque dur

Un disque dur physique peut-être divisé en disques logiques, appelé également partitions. Cette organisation du disque physique est sauvé dans la table de partitions, qui est lue avec le premier accès au disque. Des virus peuvent se cacher dans cette zone. Ces virus sont donc résistants à un reformatage de haut-niveau.

Virus furtifs

Ces virus tente d'échapper à leur détection en détournant les commandes permettant de connaître la taille des fichiers. En effet, pour savoir si un fichier est infecté, il est possible de vérifier si sa taille s'est accrue. Ainsi en détournant ces commandes, le virus dissimule sa présence.

Virus cryptés

Les virus cryptés modifient leur propre code par cryptage afin de compliquer leur détection. Ces virus sont toutefois obligés de laisser leur routine de décryptage en clair.

Virus mutants

Les virus mutants modifient leur aspect, leur signature, leur code d'identification, à chaque fois qu'ils contaminent un nouveau fichier.

Virus de blocs

Les virus de blocs modifient les entrées dans le répertoires et dans la FAT de façon qu'à l'appel du programme, le répertoire pointe vers le virus.

Virus pièges

Le virus piège associe un virus connu à un virus encore inconnu. Vous détectez le premier et, tout heureux vous l'éliminez en le détruisant mais le second subsiste.

Rétrovirus

Le rétrovirus est un virus spécialement créé pour contrer et déjouer les fonctions d'un logiciel anti-virus connu.

Virus de macro

Les Macro-virus cherchent à infecter les documents créés par les logiciels de bureautique les plus courants.

Ces documents, que l'on considérait il y a quelques années comme de simples fichiers textes, sont maintenant capables de contenir accessoirement des listes d'instructions qui peuvent prendre un caractère malveillant.
On trouve des macro-virus principalement sous Microsoft Word, Excel. Étant donné que ces logiciels existent sous Windows NT/3.1/95 OS/2 et Macintosh, ces virus sont dits multi-platesformes.

Le principe de fonctionnement des virus de macros est le suivant :
- Le virus contamine l'environnement de travail par le biais de macros automatiques
- Il infecte les documents par le biais d'instructions standard redéfinies

- détournement de macros standards,
- remplacement de menus,
- redéfinition de boutons ou de touches de fonctions,
- modification des modèles de documents.

Worm, la vie artificielle sur les réseaux

Extrait de OrganiKs #2

Introduction

Un worm est un fascinant exemple de "vie artificielle", et n'est aucunement dédié à des fins destructrices, mais à des fins éducatives et d'expérimentation.
Le fait de lâcher un worm sur Internet ou tout autre réseau public peut vous attirer de graves ennuis, que ce soit par le(s) gouvernement(s) ou des organismes privés. Un worm étant avant tout un objet de recherche
expérimentale (comme un virus), son "utilisation" doit être exclusivement restreinte à un réseau privé.

Cet article se veut avant tout théorique, et vise à analyser le fonctionnement des worms en général, dans le but de les comprendre et de pouvoir en concevoir avec des outils existants, ou de pouvoir mettre en oeuvre les parades pour les éviter.

Définition d'un Worm

Un worm est un programme similaire à un virus, c'est à dire qu'il s'exécute tout seul, qu'il évolue tout seul, et peut se reproduire. La différence avec un virus, c'est qu'au lieu de se propager dans des fichiers, un worm se propage entre les hôtes d'un réseau - des worms peuvent exister sur tous les types de réseaux - en exploitant les trous de sécurité de ces hôtes. Un worm, si il ne se propage pas, est donc une sorte de robot, car il utilise
un ou des services réseaux donnés, sans utilisateur qui le commande. En fait, il n'existe pas UN worm, mais DES worms, tout comme il n'existe pas qu'un seul virus.
Le terme worm désigne les worms en général, et les comportements que je citerais, loin d'être les seuls, sont soit les plus communs, soit les plus efficaces.

Le premier d'entre eux fut créer par Robert Morris, fils du directeur de la NSA, en 1988. Internet Worm sema la panique sur le tout jeune réseau qu'était Internet car bien qu'il ne fasse aucuns dégâts, tous les serveurs furent mis en quarantaine pour vérification. Tous le réseau fut paralysé en moins de 24 heures. C'est à la suite de cet événement qu'apparut le CERT et que débuta la course à la sécurité que nous connaissons.

Utilité des Worms

Intrinsèquement , un worm ne sert pas à grand chose de plus qu'un virus, si ce n'est explorer les capacités d'une forme de Vie Artificielle primitive. Morris avait lancé son worm dans le but d'explorer le net.
Aujourd'hui, on peut encore explorer les réseaux avec un worm, les administrateurs peuvent les utiliser afin de vérifier la sécurité de leurs réseaux face à certaines attaques, les hackers peuvent pour lancer une intrusion de manière automatique et autonome, enfin, c'est un bon sujet de Travaux Pratiques pour les futurs ingénieurs réseau. Bref, les worms sont très bénéfiques excepté lorsque l'un d'eux devient incontrôlable et qu'il paralyse un réseau. Bien sur, des administrateurs paranoïaques voient dans les worms une nouvelle menace pour leur réseau. Ce sont les personnes qui font circuler des hoax, investissent des sommes faramineuses en logiciels de sécurité, et pour qui un hacker n'est rien d'autre qu'un terroriste informatique.
Mais il faut tout de même reconnaître qu'un worm, si il est mal contrôlé ou programmé, peut vraiment faire des dégâts préjudiciables !

Description des Worms

Un worm se décompose généralement en 2 parties :

-
le vecteur, ou bootstrap, est la partie "active" du worm. C'est cette partie qui va la recherche et l'infection, ainsi que la transmission de la seconde partie.

-
l'archive en réalité une copie du vecteur, qui sera envoyée et exécutée sur l'hôte victime. Elle peut se trouver sous forme de sources, pour infecter plusieurs architectures différentes sans distinction, ou sous forme binaire, destinée à un type de victime particulier.

Ces 2 solutions ont leurs avantages et inconvénients.

- la
forme binaire ne peut infecter qu'une architecture de système particulière. Ainsi, si le-dit système n'est pas très répandu, le worm et ses descendants sont pour ainsi dire voués à une disparition à court terme. Par exemple, en 1988, le worm de Morris était archivé sous forme de binaires exécutables sur VAX, d'autres sur SUN3, et aussi sous forme de sources.
Cette diversité assura à la génération de worms une propagation rapide et efficace.
Parmi d'autres avantages, la forme binaire n'a pas besoin d'un compilateur sur le système à envahir, et, de plus, elle est généralement bien plus compacte que la forme source. Elle peut ainsi infecter des systèmes embarqués ou fonctionnant en milieux hostiles.

- la
forme source, quant à elle, pourra pénétrer beaucoup plus de systèmes différents. Par exemple, si elle répond strictement aux normes tel POSIX, et qu'elle implémente une compilation conditionnelle (avec des #define,...), elle pourra infiltrer la majeure partie des Unix comme Solaris, Linux, *BSD, AIX, QNX..., dans la mesure où le critère d'infection exploité est bien présents sur tous les systèmes cibles. En contrepartie, il lui faut absolument disposer d'un compilateur sur la machine cible afin d'effectuer sa propre compilation, sous peine de devenir rapidement inefficace. Une idée consiste à utiliser des codes de cross-compilation permettant ainsi d'expédier une version binaire ou source selon la cible. Enfin, l'archivage sous forme de sources prend plus de place que les binaires et nécessite la plupart du temps une compression.

Il est aussi possible d'utiliser un code interprété, comme du Perl, du Java, ou du script shell, qui permettra au worm ainsi programmer de fonctionner sur un maximum de systèmes (notamment grâce à l'extrême portabilité des JVM), sans pour autant nécessiter de compilation, dans la mesure où l'interpréteur est présent sur la cible.

Fonctionnement d'un worm

Le fonctionnement décrit est en réalité celui du vecteur.
L'action du vecteur est divisée en plusieurs parties distinctes :

-
L'initialisation, qui dit bien ce qu'elle est. Elle dépend de l'implémentation. Ca peut aller de la création de fichiers temporaires à la précompilation de certaines parties archivées...

-
La recherche de l'hôte. Le worm cherche une machine susceptible de l'accueillir, soit dans son voisinage direct, soit d'une façon aléatoire ou incrémentale (incrémentation des IP). A chaque IP, on regarde si l'hôte est up ou down. Si celui-ci est down, on continue à chercher, si il est up, on passe a l'étape suivante.

Tout d'abord une méthode purement aléatoire. On prend une adresse de départ au hasard dans le réseau, et on incrémente jusqu'à trouver un hôte valide et up, avant de passer à son identification.

Un exemple en C, avec une adresse IPv4 (peut facilement être amélioré pour tenir compte des classes de réseaux)

/*---------------------------------- Cut Here ---------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <netinet/in.h>

struct in_addr *find_valid_host(void)
{
struct in_addr *address = (struct in_addr *)malloc(sizeof(struct in_addr));

srand(time(NULL)); /* on initialise le générateur aléatoire */
address->s_addr = rand();

while (!isup(*address))
(address->s_addr)++;
/* ici, on utilise la routine isup() de nmap pour voir si la cible est up */

return address;
}
/*--------------------------------- Cut Here ----------------------------------*/


Cette méthode peut aussi être réalisée avec un scanner d'IP comme Nmap et un générateur aléatoire comme ci-dessus, le tout appelé depuis un script shell.

Une autre méthode consiste à utiliser des répertoires d'IP, soit locaux, comme /etc/hosts, le résultat d'un showmount, ou un hosts.byaddr si la machine possède NIS, soit dans des répertoires sur le web, genre netcraft, ou encore par la modification en mode promiscous d'une carte Ethernet ou bien par l'utilisation de Neighbor Discovery Protocol sous IPv6.
La méthode par netcraft à l'avantage d'avoir une plus grande rapidité de réussite, dans la mesure ou l'on cherche des machines existantes, mais d'un autre côté est moins intéressante pour l'expérimentation, car la propagation peut être plus facilement prévisible.

-
L'identification de l'hôte. le worm cherche a savoir si sa future victime est vulnérable à la ou l'une des failles utilisées. Cela commence généralement par un port mapping, de check rpc, stack fingerprinting, interrogation et version des services réseaux et des démons en fait, tout ce qui peut indiquer qu'une vulnérabilité connue du worm est présente sur le système. Si l'hôte n'est pas vulnérable, on retourne à la phase de recherche.

Une fois la cible potentielle découverte, le worm doit savoir si elle est susceptible d'être investie, donc vulnérable. Un port mapping et une identification de la stack IP feront l'affaire (ici encore, Nmap peut se révéler très utile, quoique un peu encombrant...), de même qu'un scan des services potentiellement exploitables par les exploits dont dispose le worm...

-
L'attaque. Dans cette phase, le worm tente d'obtenir un accès sur sa victime. C'est ici qu'il exploite les vulnérabilités qu'il a détectées dans la phase précédente.
A la fin de cette opération, le worm doit posséder un shell non-interactif, ou tout autre moyen d'exécuter des commandes et d'accéder au système de fichier de l'hôte pour pouvoir continuer. Cet accès n'est pas obligatoirement un accès root bien qu'il soit plus pratique que ce soit le cas.

-
L'invasion. A cet instant, le worm a pris pied sur le système, mais n'y est pas encore actif. Les opérations sont toujours dirigées depuis le système de départ. Durant cette phase, le worm va effectuer une série d'opérations visant à faciliter sa reproduction (ajout d'un login pour le worm, vérification de la présence d'un compilateur...)

Maintenant que le worm a trouvé une cible, et que celle-ci répond aux critères de pénétration (OS, services vulnérables...), on peut commencer l'invasion, en lancant un ou plusieurs exploits remote, sur la victime, le but étant de récupérer une session (un shell) non-interactive (un root n'est pas indispensable) sur celle-ci.
Une fois le shell obtenu, il faut vérifier qu'on peut récupérer et exécuter l'archive. Un test genre 'configure' fera l'affaire...
Si l'hôte a NIS ou bien n'est pas shadow, et que l'on a pas d'accès root, on peut tenter de cracker un ou deux accounts pour, par exemple, uploader l'archive en FTP...
A partir de ce moment, le worm n'est pas encore actif sur la victime, car c'est son image présente sur la victime précédente qui tient les commandes de l'invasion.

A ce stade, on est sur que le worm est reproductible sur la victime et qu'on va pas griller du temps et de la bande passante à uploader l'archive pour rien. L'upload peut se faire de plusieurs manières mais il ya principalement 2 tendances :
- Le worm emporte son archive avec lui, l'uploadant de victime en victime
- Ou il n'a pas d'archive "embarquée", et il download son archive sur un ou des sites fixes sur le net, par FTP ou HTTP

La seconde solution est bien sur la plus simple à réaliser, car elle dispense le worm de trimballer son archive, ainsi que le sous-système permettant de la transmettre. Elle a par contre l'inconvénient de dépendre d'un système extérieur, empêchant la propagation si celui-ci venait à être down, et elle permet également aux victimes de retracer plus facilement l'auteur de l'invasion...

Dans la première option, on a encore le choix entre deux possibilités. On peut soit uploader l'archive directement par une socket dédiée que l'on dirige sur un nouveau fichier sur la victime (cette opération est simplifiée si on dispose de netcat ou d'un prog similaire), soit utiliser un protocole standard comme FTP ou HTTP si la victime ou la base de départ disposent d'un serveur pour ce(s) service(s).

Attention au format de l'archive. Pour infecter un Unix, on est tenté de la transporter dans un .tar.gz, mais attention, gzip n'est pas si répandu qu'il n'y parait... il faut préférer le format 'compress' (.Z), qui, lui est présent sur quasi tous les systèmes, mais compresse moins bien. Par contre, tar ne pose aucun problème, car il est standard à tous les Unix. Pour les autres OS, utiliser un format dont on est sur qu'il se trouve sur le système (ne pas hésiter à vérifier sa présence pendant la phase d'abordage).

Pour activer l'archive, décompression et unpackage, compilation s'il s'agit d'une source, ou alors passage direct a la phase suivante si c'est un binaire ou un interpréteur...

-
La reproduction. C'est ici que le vecteur et son archive se distinguent. Le vecteur va faire parvenir l'archive sur le système hôte afin de l'activer, et d'engendrer un nouveau worm autonome. Le transfert peut s'effectuer de diverses façons, pouvant être un stream TCP pour un worm autonome, ou un transfert FTP d'un système fixe, pour un worm dépourvu d'archive. Une fois l'archive copiée, on procède à l'activation du worm fils, soit directement s'il s'agit d'une archive binaire ou interprétée, soit après compilation si c'est une archive source. Le nouveau worm est alors prêt à se propager à son tour.

C'est après la reproduction que se dessinent 2 tendances :

- La première est de tuer le worm père sur la machine de départ, et de laisser le worm reproduit faire comme son prédécesseur, simulant ainsi le déplacement d'une entité unique.

- La seconde est de laisser le worm parent en vie, et de lui faire recommencer le cycle de propagation, ce qui produira un effet exponentiel, et potentiellement beaucoup plus dangereuse que la première solution.

Puis, le cycle se répète...

Traçabilité du Worm

Lancer un worm sans savoir ou il est allé n'est pas très amusant. On peut donc ajouter un moyen de savoir dans quels systèmes il est allé, par quel faille il a pu rentrer, etc.
Ca peut s'avérer utile pour récupérer des accounts un peu partout sans se fatiguer ou, plus philanthropiquement, pour prévenir l'administrateur concerné que son système est vulnérable. Pour faire cela, on peut faire des choses plus ou moins complexes, allant de l'envoi d'un simple packet vers un serveur fixe, jusqu'au mail contenant le log complet de l'attaque...
Mais ATTENTION ! l'ajout de cette fonctionnalités permettra aux différentes victimes de vous retrouver plus rapidement !

Défense face aux worms

Le meilleur moyen de se prémunir contre les worms, c'est d'éviter de se faire hacker : vérifier les advisories fréquemment et patcher rapidement les trous de sécurité, faire confiance à un minimum de systèmes pour le NFS, NIS et tous les services de partages de fichiers ou encore utiliser les IDS sachant qu'un worm reste un programme et se trouve donc très prévisible.

Rajout d'eberkut pour coller à l'actualité :

A worm, as defined by some authorities, is a self-replicating program that does not alter files but resides in active memory and duplicates itself by means of computer networks. Worms use facilities of an operating system that are meant to be automatic and invisible to the user. It is common for worms to be noticed only when their uncontrolled replication consumes system resources, slowing or halting other tasks. A new class of worm, such as Worm.ExploreZip, resides in your system's memory and self-replicates, but also contains a malicious payload. 

Protection against a worm is like protection against other network faults, depending on intelligent recognition of suspicious patterns of events before a problem can interfere with essential functions. 


http://www.software.com.pl/newarchive/misc/Worm/darbyt/pages/worm.html 
http://www.whitehats.com/library/worms/ramen/index.html 
http://tfm.profm.ro/ramen.html 
http://www.sans.org/y2k/ramen.htm 
http://www.whitehats.com/library/worms/lion/index.html 
http://www.sans.org/y2k/lion.htm 
http://www.ciac.org/ciac/bulletins/l-067.shtml 
http://www.sans.org/y2k/adore.htm 

Réseau de Neurones : Vers un cerveau de synthèse

Par Pierrick Faure

Pour résoudre les problèmes complexes, l’homme s’est presque toujours inspiré de la nature : les robots les plus mobiles, par exemple, ressemblent à s’y méprendre aux insectes les plus communs. Pourquoi ne pas appliquer ce principe à la création d’une véritable intelligence artificielle ?

Concevoir une machine intelligente est un vieux rêve de l’être humain ; les applications d’une telle machine seraient en effet infinies, que ce soient dans le domaine de la recherche, de la robotique, ou même de la philosophie. Néanmoins, la création d’une intelligence artificielle semblable à celle d’un être vivant est un problème qui apparaît aujourd’hui difficilement accessible d’un point de vue algorithmique : les travaux actuels en logique informatique et en programmation semblent en effet ne pas permettre la réalisation d’une véritable intelligence.

L’idée d’un réseau de neurones

C’est en cherchant un autre moyen d’aborder le problème que, en dès 1943, Warren McCulloch et Walter Pitts, créèrent le premier modèle de réseaux de neurones artificiel. Ils pensaient alors que leur modèle décrivait assez fidèlement le fonctionnement interne du cerveau humain et, même si leur description restait incomplète et fut amélioré des années plus tard, leurs travaux sont encore aujourd’hui à la base de toute recherche en intelligence artificielle. Les expériences de Rosenblatt, en 1950, débouchèrent sur la première application des réseaux de neurones, le Perceptron, une machine qui était capable d’améliorer son fonctionnement grâce à une modification de ses éléments internes lorsqu’elle renvoyait une réponse fausse et par un renforcement dans le cas contraire. Néanmoins, le Perceptron souffrait de grande limitations et le domaine des réseaux de neurones fut quelque peu abandonné par la scène scientifique jusqu’à un regain d’intérêt dans les années 80. Depuis les travaux de McCulloch et Pitts, les scientifiques ont toujours cherché à se rapprocher le plus possible du fonctionnement d’un véritable cerveau humain et la théorie du connexionisme s’est imposée petit à petit. Le connexionisme consiste à s’intéresser aux relations et aux connexions inter-neurones plutôt qu’aux neurones eux-mêmes. Un neurone peut être modélisé assez simplement en une fonction mathématique alors que ses interconnexions avec les autres sont beaucoup plus difficiles à modéliser.

La solution est dans l’architecture

Pourtant, le mystère de l’intelligence se réfugie sans doute au sein des structures complexes qui composent les cerveaux des êtres vivants. En effet, les neurones ont ce caractère particulier de faire émerger une intelligence de leur structure. Toute à la manière des fourmis par exemple : une fourmi considérée toute seule incarne un élément simple et doté de quelques fonctions primaires. En revanche, quand on les met ensemble, plusieurs milliers de fourmis peuvent alors développer une intelligence de groupe. Les caractères de cette intelligence dépendent alors de l’efficacité de l’échange d’information entre les éléments. En l’occurrence, les fourmis utilisent des molécules chimiques pour se parler et ainsi se montrer les sources de nourriture. Plus une fourmi suit un chemin, plus celui-ci se verra marqué de molécules chimiques et plus il se trouvera emprunté par d’autres fourmis. Pour les neurones, le principe reste le même : un signal électrique passe à travers les liens entre 2 neurones, ce passage fortifie le lien et si le lien se répète, le lien s’affermit peu à peu. En revanche, dans le cas où le signal ne se trouve pas réitéré, s’il n’est pas encouragé en quelque sorte, le lien s’atrophie puis disparaît au bout d’un certain temps. Ce processus de sélection des bons liens s’appelle tout simplement l’apprentissage. C’est comme cela que le cerveau apprend à ne pas commettre plusieurs fois la même erreur : lorsqu’une erreur est faites, une connotation négative ressort de l’expérience vécue. Par exemple, lorsque vous voyez un objet mais que vous n’arrivez pas à le reconnaître quelqu’un va vous signaler que vous vous êtes trompé et vous donner le vrai nom de l’objet. Votre cerveau, constatant l’erreur, va alors délaisser les connexions qui ont provoqué la mauvaise identification ; ces connexions vont peu à peu se détériorer et d’autres seront, en revanche, stimulés. Ainsi, lorsque vous verrez à nouveau l’objet, il est fort probable que vous l’identifiez immédiatement. Cette très grande faculté de modification de sa propre architecture fait que le cerveau humain sait s’adapter et qu’il est capable d’apprendre. En fait, les phénomènes qui entrent en jeu sont plus complexes mais l’idée générale peut se voir exprimée de cette façon.

Le problème de la multitude

Même si la théorie du connexionisme semble prendre un avantage certain, il ne faut pas oublier le rôle primordial d’un neurone dans toutes ces étapes. Le neurone peut transmettre et recevoir les signaux de plusieurs autres neurones. En général, on dit qu’il effectue une opération de sommation, c’est-à-dire qu’il réunit les signaux qu’il reçoit, et lorsque la somme de ces signaux dépasse une certain seuil, il envoie alors à son tour un signal plus ou moins fort à un autre neurone. A ce sujet, il est bon de savoir que le codage des signaux s’effectue en fréquence (plus la fréquence du signal est importante plus le signal est fort). Le point important reste que le cerveau d’un être vivant est souvent constitué de plusieurs milliards de neurones… Il s’agit là d’un problème de taille dans la conception de réseaux de neurones, car pour imiter le fonctionnement d’un cerveau, il faut donc disposer d’une très grande quantité de neurones artificiels. Si, par exemple, on voulait simuler dans la mémoire d’un ordinateur un réseau d’un million de neurones, soit un réseau minuscule à côté de ce que nous propose la nature, cela occuperait une quantité de mémoire absolument énorme : il faudrait stocker pour chaque neurone l’état, les connexions et le seuil. Et il s’agit d’un minimum. De surcroît, pour chaque connexion, il faudrait stocker énormément d’informations comme l’état de la connexion, la fréquence à laquelle elle est sollicitée, etc. Tout cela représente une quantité de mémoire absolument gigantesque. Si l’on considère alors qu’un cerveau simple est entre 2000 et 3000 fois plus complexe, on comprend vite pourquoi il est aujourd’hui très dur de mettre en œuvre de tels réseaux de neurones. Enfin, il ne faut pas oublier que lors d’une simulation informatique chaque signal est traité tour à tour alors que toutes ces étapes s’effectuent simultanément dans la nature. Les réseaux de neurones programmés sont donc bien plus lents que leurs homologues biologiques…

Les approches alternatives

Pour contrer le problème de la multitude, on peut restreindre le cerveau l’activité qui nous intéresse le plus. Par exemple, si l’on veut mettre au point un réseau capable de reconnaître les caractères, il n’est pas nécessaires de mettre sur pied une énorme structure et l’on peu se limiter à un nombre raisonnable de neurones. Il suffit alors de réaliser un programme d’apprentissage afin que le logiciel atteigne un certain niveau et qu’il devienne utilisable. Par la suite, il se perfectionnera à chaque emploi et se révèlera chaque jour plus perspicace. On a aussi la possibilité d’utiliser des neurones électroniques et fabriquer un réseau restreint en les interconnectant par de simples fils de cuivres. Sur 1000 neurones, cette opération est tout à fait réalisable et permet d’effectuer toute série d’expériences. L’avantage est qu’avec ce type de construction, le fonctionnement en terme de vitesse est tout à fait identique à celui d’un réseau naturel.

Enfin, et il s’agit de la possibilité la plus spectaculaire, certains chercheurs se tournent vers la cybernetique afin de relier de véritable neurones à un circuit électrique classique. Après tout, et comme cela est très bien exprimé dans le film Matrix, l’intelligence et la pensée ne sont qu’une suite de signaux électriques…

Programmation génétique

Également appelée programmation automatique, cette technique de développement consiste à demander la réalisation d'une tâche à un ordinateur sans lui expliquer au préalable comment y parvenir. Elle traite génétiquement une série de programme basiques par l'intermédiaire des lois de la sélection naturelle de Darwin et s'appuie sur quelques opérations directement issues de la biologie et de la génétique. Ces opérations sont la reproduction, le cross-over, la mutation et certaines modification d'architecture qui interviennent dans la nature après la duplication des gènes.

Théories Évolutionnistes

Les algorithmes génétiques sont directement inspirés du néo-darwinisme. Nous vous proposons de vous résumer les principales théories évolutionnistes qui ont eu un rôle dans les algorithmes génétiques.

Le darwinisme

Un voyage autour du monde, et plus particulièrement l'étude de certaines espèces spécifiques de l'archipel de Galapagos, et la lecture de Malthus permit à Charles Darwin(1809-1882) d'établir la théorie de la sélection naturelle.

L'une des premières théories évolutionnistes, la théorie de la sélection naturelle ou darwinisme stipule que les espèces descendent les unes des autres au cours d'évolution lente à travers le temps.

En effet, Il remarqua dans l'archipel des Galapagos des animaux ayant des caractéristiques communes avec des espèces se trouvant sur d'autres îles ou sur les continents. Seulement, ils avaient aussi suffisamment de différence pour ne pas les classer dans la même espèce. Les animaux varient. Ces variations pouvaient être héritées et tous les animaux étaient sujets à une lutte intense pour l'existence qui favorisait nécessairement, par sélection naturelle, la préservation des variations avantageuses.

Il proposait donc une évolution matérialiste où la main de Dieu n'intervenait plus. Seulement elle présentait néanmoins des défauts en particulier sa théorie n'explique pas l'origine et le mode de transmission de la variabilité.


Le mendélisme

Les lois de Mendel (1822-1884) "redécouvertes" en 1900 par Carl Correns (1864-1933), Eric von Tschermak (1871-1962) et Hugo de Vries (1848-1935) mirent en évidence le mutationnisme. C'est à dire l'apparition brutale d'un caractère héréditaire.

Le néo-darwinisme

Les idées sur l'indépendance entre le " germen ", et le " soma " , la non-héridité des caractères acquis défendu par l'embryologiste August Weismann (1834-1914) ajouté à la sélection naturelle créèrent le néo-darwinisme.

Plus tard, le néo-darwinisme sera complété par les lois de Mendel, et par le mutationnisme. La génétique chromosomique de morgan couronnera en apportant quelques modifications l'édifice théorique construit par le naturaliste allemand.

Il serait intéressant que notre système ait une capacité d'évolution néo-darwinienne et qu'il prenne en compte au moins partiellement le principe de sélection naturelle. En effet, un écosystème ne peut subsister que par une adaptation aux différents changements telle que les changements climatiques, le nombre d'espèces, du nombre d'individus, etc.

La population de départ

Pour pouvoir initier un tel développement, il faut tout d'abord créer une population de départ, constituée de milliers d'algorithmes basiques et générer aléatoirement. Ces algorithmes utilisent de simples opérations arithmétiques, des opérateurs conditionnels (and, or...), quelques variables et des constantes aléatoires. Ces programme sont de taille très différente et peuvent comporter des fonctions primaires. Ils sont tous exécutables.

Le déroulement d'une génération

La programmation génétique utilise cette population et la fait évoluer à travers une série de générations jusqu'à l'émergence d'un algorithme qui répond au problème posé au départ. Le passage d'une génération se produit en plusieurs étapes distinctes. Tout d'abord, la capacité à résoudre le problème de chaque programme est évaluée, ensuite la sélection darwinienne intervient et les algorithmes les plus adaptés sont choisis. Enfin, les événements génétiques sont appliqués à cette sélection ainsi qu'à un petit groupe de programmes moins adaptés afin de créer d'autres possibilités. Puis, l'opération recommence jusqu'à l'apparition d'une solution au problème posé. L'important ici est donc la préférence apportées au meilleurs individus. Le principe utilisé est le même que l'évolution naturelle avec une fréquence d'événements génétiques beaucoup plus importantes afin d'accélérer l'apparition de nouvelles fonction et donc de solutions possibles. Par exemple, le cross-over, qui est la substitution d'un morceau d'algorithme par un autre provenant d'un individu différent, se produit relativement rarement dans la nature. La probabilité utilisé pour cet événement est de 85 à 90% dans la programmation génétique. Ainsi, étant donné que le cross-over est effectué préférentiellement entre les programmes les mieux adaptés, les chances de voir des algorithmes combinés des qualités héritées de 2 parents sont plus importantes. La génération se termine par une phase de reproduction durant laquelle les meilleurs programmes engendrent plusieurs copies d'eux-mêmes alors que les algorithmes les plus mauvais ne sont pas recopiés et disparaissent tout simplement de la population. 

Modifications de structure

Les programmes simples sont constitués d'une seule partie qui va évoluer au cours des générations mais il existe des programmes plus compliqués structurés autour de fonctions d'itérations, de procédures récursives, de boucles ou encore d'un quantité fixe d'espace mémoire. Il est bien sur possible de spécifier dès le départ la structure de ce programme, le nombre de paramètres pour les fonctions, les conditions de boucles, la taille de mémoire, etc. Néanmoins, le problème est parfois à chercher dans l'architecture. par exemple, L'évolution d'un programme peut être compromise par le manque de mémoire (un besoin de davantage de mémoire que ce qui a été fixé au départ), une condition de boucle inefficace, etc. C'est pour cela que la programmation génétique permet la gestion dynamique de la structure des programmes. Cela signifie que certains programmes seront altérés au niveau structurel pendant une génération. Le même principe est utilisé : les meilleurs programmes ont plus de chances de devenir la cibles d'une telle modification. La probabilité de modification de structure est plus faible, environ 0,5 à 1%. Pour s'assurer que la modification débouche sur un résultat valide une méthode élégante est utilisée : lors d'une modification d'architecture, une fonction déjà existante est dupliquée et renommée. Ensuite, les appels à cette fonction sont dupliqués à leur tour et l'un des 2 appels obtenus est modifié de façon à pointer sur la nouvelle fonction. Les 2 fonctions divergeront plus tard au fur et à mesure des générations. D'autres opérations de modifications d'architecture peuvent se produire ; une fonction peut, par exemple, disparaître, voir son nombre d'arguments modifiés ou être créée de toutes pièces. De telles opérations diversifient énormément la taille et la forme de programmes de la population, ce qui permet dans bien des cas de créer de nouvelles possibilités.

Outils de la programmation génétique

Ce type de manipulation requiert évidemment une très grande puissance de calcul ainsi qu'une grosse quantité de mémoire. Le but est de développer un très grand nombre de générations sur un très grand nombre d'individus et ce le plus rapidement possible. L'idéal pour la programmation automatique, reste le cluster qui permet d'atteindre une puissance confortable à un coût relativement réduit. Actuellement, plusieurs systèmes dédies à la programmation génétique sont fonctionnels. Par exemple, il existe un ensemble de 70 DEC Alpha à 533MHz disposé en cluster Beowulf. Récemment, un tout nouveau cluster a été fabriqué. Composé de 1000 processeurs Pentium II à 350MHz (500 cartes mère bi-processeur), celui-ci permet de réaliser 96 générations d'une population de 30 millions d'individus par jour. Le système est doté au total de 64 Go de mémoire vive, soit 64 Mo par processeur. Chaque machine fonctionne avec Linux (ce qui garantit une économie certaine ainsi qu'une grande fiabilité), se voit réduite au strict minimum, et est dotée d'une carte réseau qui lui permet de communiquer avec les autres et avec un serveur sur lequel sont stockés toutes les informations. La fiabilité du système reste très grande et lors de la résolution du problème, le cluster de 70 DEC Alpha a tourné pendant 14 mois, 24H/24H 7j/7j, en ne comptabilisant que 3 défaillances.

Succès enregSuccès enregistrés

Jusqu'à présent, la programmation génétique a permit d'obtenir 25 résultats qui peuvent être comparés à ceux des humains. Ainsi en 1998, un programme d'intelligence artificielle pour jouer au football, issu de la programmation génétique, s'est classé au milieu de 34 autres programmes créé par des humains lors de la Robo Cup. Il a donc surpassé certains algorithmes qui avaient pourtant demandé un lourd travail à leurs créateurs. Ce résultat démontre le lien étroit qui existe entre l'intelligence artificielle et la programmation automatique. Plus récemment, en 1999, plusieurs circuits électriques ont été créé de cette manière : un thermomètre électronique, un convertisseur Digital vers Analogique et un convertisseur Analogique vers Digital. Ces 3 circuits sont parfaitement opérationnels, ce qui sous-entend que la programmation génétique sera peut-être un point essentiel dans l'évolution du design des processeurs, même si cela semble encore difficile à obtenir. Pour l'instant, le blocage provient de la puissance de calcul ; il faut toujours plusieurs mois pour parvenir à un résultat stable. De la même façon que sont apparues les espèces complexes sur Terre, la programmation génétique pourrait donner des résultats impressionnants en faisant évoluer des populations dans lesquelles l'intelligence est privilégiée. Bien sur, la création d'un programme vraiment intelligent n'est pas encore concevable, néanmoins, le simple fait de savoir que cela est théoriquement possible nous montre l'incroyable potentiel de la programmation génétique. Encore une fois, on s'aperçoit que le meilleur moyen de rendre une machine intelligente est d'essayer de copier la nature. C'est pour cela qu'on ne pourra peut-être jamais réellement faire mieux.  

Une présentation de l'Intelligence Artificielle

Dernière mise a jour : 27/11/96
AUTEUR : baillie@magic.fr

INTRODUCTION

Le but de cette petite présentation est d'offrir au lecteur un panorama relativement complet de l'Intelligence Artificielle actuelle. Je ne parlerai donc pas des aspects historiques.
Pour chaque thème abordé je me suis efforcé de présenter le problème à travers un exemple simple qui, s'il ne donne pas une description complète des possibilités de traitement du problème, permet de comprendre l'esprit de la démarche employée.

RÉSEAUX DE NEURONES

Les réseaux de neurones sont les systèmes d'Intelligence Artificielle les plus proches dans leur structure du cerveau. Il sont constitués d'un réseau d'automates à seuil modélisant les neurones. Comment cela fonctionne? Chaque neurone est constitué par une série de dendrites IN d'entrée et une série de dendrites OUT de sortie :

Tous les neurones sont donc plus ou moins interconnectés puisque les IN des uns sont les OUT des autres. Chaque connexion est caractérisée par un poids w(i,j) du neurone i vers le neurone j. Les dendrites OUT ne peuvent qu'avoir un état commun 0 ou 1. On le note O(i) pour le neurone i. Pour savoir si le neurone i est dans l'état 0 ou 1,on calcule la somme sur j dans IN des S(i)=w(i,j)O(j). On dit ensuite que O(i)=f(S(i)) où f est soit une fonction seuil (f(x)=0 pour x plus petit que S et f(x)=1 si x dépasse S) soit une fonction sigmoïde (dans ce dernier cas, O(i) devient un réel dans [0,1]).

Ainsi, on peut calculer de proche en proche l'état de sortie de chaque neurone. Notons tout de suite que ce qui va caractériser le comportement du réseau c'est l'ensemble des poids w(i,j).
Il existe ensuite plusieurs façons de disposer ces neurones :

Réseaux multi-couches

Dans ces réseaux, on place d'abord une couche de neurones en entrée puis une série de couches internes et enfin une couche de sortie :

Les neurones de la couche i sont tous interconnectés avec ceux de la couche i+1 et i-1.
Dans ces réseaux, on dispose un signal en entrée (1001011011 par exemple), on le propage jusqu'à la sortie où l'on obtient une réponse (1000001001). On la compare avec une réponse attendue et on répercute les différences via un algorithme de rétro propagation sur les poids des liaisons du réseau. Cette procédure converge après quelques exemples et le réseau finit par donner la bonne réponse et ceci même s'il y a du bruit dans le signal de départ.

Réseaux de Hopfield

Dans ces réseaux, les neurones sont disposés en grille (comme une sorte d'échiquier où l'on place un neurone dans chaque case). A la différence des réseaux multi-couches, ici chaque neurone est relié à tous les autres (n² poids pour n neurones). On "dessine" par exemple une lettre dans ce quadrillage. On déclenche ensuite la procédure de propagation en calculant les O(i) de chaque neurone. On réitère cette opération jusqu'à convergence de l'ensemble (on discrétise le temps pour effectuer ces itérations). Là encore, les différences se répercutent sur les poids grâce à un algorithme d'apprentissage.
Il est intéressant de constater qu'avec les réseaux de Hopfield on peut être confronté à des oublis catastrophiques si on effectue une trop longue période d'apprentissage (le réseaux ne converge plus du tout et se met à se comporter comme s'il n'avait jamais rien appris).

Les cartes de Kohonen

Les réseaux de Kohonen sont des réseaux à deux couches. La première contient n neurones (n=2 en général pour simplifier). La deuxième contient des neurones organisés d'une certaine façon dans l'espace. Par exemple en mailles carrées (quadrillage). On définit une topologie sur la deuxième couche c'est a dire que l'on précise le voisinage d'un neurone donné (un cercle de rayon R convient par ex). Ce voisinage devra décroître avec le temps jusqu'à ne plus contenir que le neurone central. On dispose les résultats dans un plan où chaque neurone est figuré par un vecteur de coordonnées égales aux poids w0 et w1 le reliant aux deux neurones d'entrée. On relie à l'écran les neurones adjacents dans la topologie initiale. Une entrée sera représentée par un vecteur d'entrée I dans le plan. Le neurone dont le vecteur poids est le plus proche du vecteur I est sélectionné ainsi que son voisinage et on va rapprocher le vecteur de poids de ces neurones du vecteur I d'entrée (en ajoutant 0.5(W-I) par exemple). En envoyant aléatoirement des entrées I sur un quadrillage, on arrive à organiser les neurones de sortie de manière a calquer le quadrillage.
L'utilité de ces réseaux est qu'à une entrée I0 proche d'une autre entrée I1, on va faire correspondre deux neurones activés différents mais proches au sens de la topologie utilisée. C'est un comportement que l'on retrouve dans le cerveau : Si l'on voit un chat, on sait qu'un neurone chat va s'allumer dans une région "chat" du cerveau.
Il existe également des applications au problème du voyageur de commerce mais je n'en parle pas ici (topologie linéaire avec vecteurs I placés sur les villes).
Je vous propose deux programmes en C illustrant ces réseaux : Kohonen.exe et Voyageur de commerce. N'oubliez pas le fichier egavga.bgi nécessaire au C graphique sous DOS. Je peux vous fournir les sources si vous me le demandez par mail.

Illustration

Je dispose d'un petit programme de démonstration (pour PC) illustrant très bien ces trois types de réseaux et leurs applications. Cliquez ici pour le charger sur votre disque dur.
NB : Ce fichier doit être décompacté. Si vous ne l'avez pas, chargez pkunzip.exe . C'est en tapant 'pkunzip neurone' que vous décompacterez le tout!
Pour lancer le programme (une fois le tout décompacté), tapez 'demo'.

RECONNAISSANCE DE FORMES, VISION ARTIFICIELLE

En pratique, il s'agit ici de l'application des réseaux de neurone. La version la plus simple de la reconnaissance de formes consiste en une reconnaissance de caractères (par un réseau de Hopfield par exemple).
Des applications plus élaborées permettent des reconnaissances bien plus complexes (pieces usinées sur une chaine de montage, cubes posés sur le sol,...). Il n'en reste pas moins que pour toutes ces applications, le réseau de neurones n'est qu'un outil parmi d'autres. En effet, pour comprendre un mot on doit très souvent le replacer dans le contexte de la phrase où il a été écrit (c'est une règle vraie pour les être humains également). Ce qui signifie que l'ordinateur doit être capable de traiter le sens. A l'échelle où ils sont construits et tels qu'ils se présentent, les réseaux de neurones classiques en sont incapables.

Il est intéressant de réfléchir à la représentation 3D de l'espace environnant un robot par exemple. On aura là tout intérêt à coupler des senseurs classiques (radar, infra rouge,...) avec des réseaux de neurones.
A noter également les travaux en matière d'analyse de scènes. Il s'agit de déterminer les contours significatifs d'une scène donnée. On peut les calculer en évaluant les variations brutales de contraste qui traduisent le passage sur une ligne. Il reste à gérer le problème des ombres...
On peut également intégrer dans ces travaux de reconnaissance de formes tous les problèmes de compréhension du langage parlé.

PROLOG, SNARK ET LES SYSTÈMES EXPERTS

PROLOG

Je vais commencer par décrire brièvement le fonctionnement de PROLOG.
Un programme PROLOG est constitué de faits et de règles . Un fait est quelque-chose comme : age(pierre,22) qui signifie que Pierre a 22 ans. Les règles sont par exemple :
si age(X,A) et supérieur(A,18) alors majeur(X). Cette règle nous dit que toute personne X dont l'âge A est supérieur à 18 est majeure. Voyons un exemple très classique de programme :


Faits

père(marc,jean);
père(jean,paul);
mère(jean,annie);

Règles

SI père(X,U) et père(U,Y)
ALORS grand_père(X,Y).

SI père(X,Y) ou mère(X,Y) ou grand_père(X,Y) ALORS membre_de_la_famille(X,Y).

On va alors pouvoir poser des questions du genre : grand_père(marc,X), le programme répondra X=paul. L'algorithme qui gère les déductions est appelé moteur d'inférences.
On a affaire ici à une logique mathématique pure. Notons qu'il existe des moyens de traiter ces données à l'aide de logique "floue". On affecte à chaque fait un coefficient de vraisemblance entre 0 et 1. 0 signifie que le fait est faux,1 qu'il est sûr à 100%.
Il existe des règles de calcul permettant de déduire la vraisemblance accordée à la conclusion d'une règle en fonction des vraisemblances des prémisses. On peut ainsi propager l'incertitude au cours du raisonnement.
A noter également l'un des intérêts majeurs de PROLOG qui peut détailler son raisonnement et démontrer ses conclusions en précisant simplement la liste des règles utilisées.
J'ai programmé une version de PROLOG que je mets à votre disposition. En particulier, vous trouverez un fichier NOTICE.DOC qui détaille plus complètement le fonctionnement de PROLOG.

SNARK

SNARK est un langage comme PROLOG mais très peu connu. Ce sont tous les deux des langages déclaratifs (et non des langages procéduraux comme C ou Pascal où il faut "tout dire" à l'ordinateur). Il ne présente pas d'interêt particulier en soit si ce n'est une particularité qui le distingue de PROLOG et qui est très intéressante. C'est pourquoi j'en parle ici.

Un fait en SNARK met chaque élément au même niveau : 'père(marc,jean)' devient '(père marc jean)'. Cette facilité permet de traiter les prédicats (comme père) au même titre que les paramètres. Voyons ce que deviendrait notre programme PROLOG en SNARK :


Faits

(père marc jean)
(père jean paul)
(mère jean annie)
(lien_de_parenté père)
(lien_de_parenté mère)
(lien_de_parenté grand_père)

Règles

SI (père X U) et (père U Y)
ALORS (grand_père X Y)

SI (REL X Y) et (lien_de_parenté REL) ALORS (membre_de_la_famille X Y)

Cet exemple d'école nous montre que SNARK ne fait pas état de la nature sémantique de 'père'. Il peut être tantôt un prédicat, tantôt un argument. On voit comment la notion de lien de parenté est traitée de manière plus souple qu'en PROLOG.

SYSTÈMES EXPERTS

Les systèmes experts sont l'application principale des langages de la famille de PROLOG. Un système expert est un programme contenant des milliers de faits et des milliers de règles sur un sujet très précis (diagnostique médical, identification de champignons, démonstration de théorèmes,...).
On pose ensuite des questions précises au système qui fournit des réponses argumentées et pondérées de coefficients de vraisemblance. Il se pose d'emblée un problème pour constituer la base de faits et de règles. On consulte généralement une série d'experts qui doivent faire un effort pour tenter de systématiser leur démarche. Cette méthode pose le problème de la cohérence de la base : un expert peut affirmer deux choses qui sont indirectement contradictoires (via le mécanisme des déductions). Il peut aussi dire deux fois la même chose sans se rendre compte de l'équivalence de ses affirmations.

Une autre méthode fait appel à un autre domaine de l'IA : la compréhension de texte. Cette fois c'est l'ordinateur qui pose les questions à l'expert et celui-ci répond dans un langage simplifié mais proche de sa langue naturelle. L'ordinateur doit ensuite extraire le sens et demander confirmation.

Les systèmes experts sont l'une des grandes réussites de l'IA actuellement. Ils sont utilisés avec succès dans de nombreux domaines. Un certain système expert géologique aurait même prédit contre l'avis de tous la présence d'un gisement à un endroit inattendu. Ces programmes pèchent cependant par excès de spécialisation. Ils sont complètement incompétents dès lors qu'on s'éloigne un peu du sujet pour lequel ils ont été construits.

RÉSEAUX SÉMANTIQUES

Il s'agit d'une représentation de la connaissance très riche utilisée pour stocker du sens en général. Un réseau sémantique s'apparente à un graphe dont les nœuds sont des objets ou concepts élémentaires. Les arcs qui relient ces nœuds sont des relations.

On dispose pour ces réseaux de propriétés d'héritage engendrées par des arcs 'sorte_de'. De ce fait, les réseaux sémantiques peuvent être vu comme une représentation graphique de Programmation Orienté Objet. Ce type de programmation structure la connaissance en objets. Un objet peu hériter d'un autre ce qui signifie qu'il en est une particularisation. La forme terminale de ces particularisations est appelée une instance. On ne peut hériter d'une instance et l'instance représente souvent une réalité concrète à la différence des objets proprement dits qui sont plutôt des concepts. Les mécanismes d'héritage sont très riches et permettent en particulier de gérer les problèmes de valeur par défaut et de sous-entendu. Vous trouverez une présentation simplifiée des objets dans la doc de la version de PROLOG que je vous propose au paragraphe précédent.
Les réseaux sémantiques sont utilisés (sous leur forme Orientée Objet) dans le codage du sens des phrases ou l'interprétation de scènes vidéo où l'image est décrite en termes de relations entre objets.

AUTRES RAISONNEMENTS : TEMPOREL, PAR ANALOGIE, PAR CAS

Ils existe d'autres formes de raisonnement. Je citerai sans plus de précisions les raisonnements temporels et les raisonnements pas analogie. Le premier intègre dans son analyse des notions de temps qui s'écoule. Le second permet d'inférer des propriétés par comparaison avec les données existantes. Il fonctionne par analogie.

Une des formes de ce raisonnement est le raisonnement par cas. L'ordinateur dispose d'une bibliothèque de problèmes dont il connaît la solution. Lorsqu'on lui pose un nouveau problème, il tâche de déterminer quel est le problème de sa base qui s'approche le plus au sens d'une certaine distance du problème posé. Une fois ce problème similaire sélectionné, il va procéder à une phase d'adaptation du problème où les données sont transformées dans le problème initial pour retrouver la forme du problème type. On peut ainsi espérer résoudre le nouveau problème à l'aide de la démarche du problème connu. Si cela fonctionne, le nouveau problème est stocké dans la bibliothèque de problèmes et ainsi de suite.

GÉNÉRATEURS DE PLAN D'ACTION

Les générateurs de plan d'action permettent de générer une suite d'actions élémentaires permettant d'aller d'un état initial donné vers un état final.
L'exemple classique pour illustrer le fonctionnement d'un GPA (Générateur de Plan d'Action) est celui du monde des blocs. Dans ce monde simplifié, les objets sont des blocs qui sont empilés les uns sur les autres. En voici un exemple

On décrit cet état initial à l'aide de faits (un peu comme en PROLOG) que l'on inscrit dans une base de faits :

sur (SOL,A) sur(SOL,B)
sur(B,C)
sur(C,D)

Ensuite on donne au programme des actions. Par exemple :

detruire(X)

conditions : sur(X,rien)
conséquences :
enlever : sur(?,X)

mettre_sur(X,Y)

conditions : sur(X,rien) et sur(Y,rien)
conséquences :
enlever : sur(?,Y)
ajouter : sur(X,Y)

Supposons que je demande :

mettre_sur(C,A)

La première condition est vérifiée car il n'y a rien sur A. Mais sur C il y a D. Le moteur d'inférence va donc essayer de déclencher une action qui contienne en 'conséquences' 'enlever sur(C,D)'
Deux possibilités : ou il détruit D ou il tente de mettre D sur n'importe quoi. On voit tout de suite qu'il peut y avoir un problème s'il décide de mettre D sur A pour libérer C! Il faut donc élaborer un système plus sophistiqué qui évite les bouclages infinis comme celui-ci.
C'est essentiellement ce problème que l'on étudie avec les GPA.
Le principe du GPA est séduisant. En effet, pour les tours de Hanoï par exemple, il suffirait d'entrer les règles du jeu en précisant l'action 'mettre_sur' et l'ordinateur saurait jouer sans qu'on lui ai rien appris. Le problème que l'on rencontre souvent si on se contente de l'approche que j'ai expliqué est un problème d'optimisation. Le bouclage récursif peut être très long.

SYSTÈMES MULTI-AGENTS

Cette branche de l'IA est fortement liée au domaine plus général de l'informatique distribuée ou multitâche. Dans ce modèle, il s'agit de faire travailler ensemble un grand nombre d'agents dont la spécialisation est soit quasi nulle soit très faible.
L'intelligence du système va naître de la coopération de ces agents. La question est de préciser comment ces agents communiquent entre eux. Plusieurs modèles existent.


Modèle du tableau noir

Dans ce modèle, les agents disposent d'un tableau noir commun. Lorsqu'un agent a besoin par exemple de linéariser une expression mais qu'il ne sait pas le faire, il écrit sur le tableau noir " j'ai besoin de linéariser log(1+x²) ". Parmi les autres agents, qui lisent constamment le tableau, certains savent linéariser log(1+x²) et vont donc effectuer la tâche. Ils écriront le résultat sur le tableau noir. L'agent demandeur n'a plus qu'à lire le résultat de sa demande. Cette coopération suppose que les agents ne se connaissent pas entre eux.

Modèle de connexion directe

Dans ce modèle, les agents se connaissent tous entre eux. Ils s'envoient donc des messages directement et à la bonne adresse. Ces systèmes sont plus rapides mais moins évolutifs (si on ajoute un agent, personne ne saura qu'il existe si on ne modifie pas l'annuaire des agents préexistants).
On peut envisager une solution hybride où les agents fréquemment en contact se connaissent mais pas les autres. On peut même créer dynamiquement des liens entre agents en fonction de la fréquence de leur communication.

Remarquons que les réseaux de neurones, les systèmes PROLOG et SNARK et les GPA sont des systèmes multi-agents ayant des granularités différentes. Cependant, la communication entre agents reste sous entendue puisque intégrée à un algorithme.

AIDE A LA TRADUCTION, CONTRACTION DE TEXTE

Aide à la traduction

On a cru il y quelques années, pendant le big bang de l'IA, que les progrès rapide dans se domaine allaient permettre d'ici peu de traduire automatiquement des textes. On est vite revenu à la réalité car ce problème est hautement complexe. On se propose aujourd'hui de construire simplement des aides à la traduction.

Comment cela fonctionne-t-il en théorie? On veut traduire une langue A en une langue B. Il s'agit dans un premier temps de traduire A dans une langue L commune à tous les langages et porteuse du sens (L est par exemple un réseau sémantique). Ensuite on peut traduire L dans B. Ces deux phases sont bien distinctes et ne font pas appel aux mêmes mécanismes. On voit qu'il est nécessaire pour bien traduire A en L d'avoir un grand nombre de connaissances de type contextuel. C'est le même problème que l'on rencontre en reconnaissance vocale. La structure qui me semble la plus prometteuse pour traiter ces problèmes est une structure multi-agents par tableau noir où des agents de traduction côtoient des agents de compréhension. Plus le système sera diversifié et meilleure sera l'analyse des phrases.

Contraction de textes

La contraction de texte est une traduction de A vers A. La différence est que l'intermédiaire L doit être comprimé. Il s'intercale donc un module de contraction de sens. Ce module doit tenir compte de deux choses importantes pour résumer efficacement un texte :

- La connaissance initiale du sujet (inutile de résumer ce que l'on sait déjà)
- Quel est le sujet qui m'intéresse dans le texte à résumer. Par exemple, l'économie ou plutôt l'aspect historique?

On voit que la contraction de texte est de loin l'un des sujets les plus difficiles de l'Intelligence Artificielle. C'est un sujet que l'on ne peut aborder que partiellement (grammaire réduite, vocabulaire simplifié,...).

Compréhension du langage naturel

Il s'agit ici de comprendre des phrases écrites par un utilisateur en langage naturel. Le but peut être par exemple la commande d'une machine, d'un processus. On peut également désirer interroger une base de données. En fait, il existe de nombreux domaines d'application, partout où l'interface Homme-machine parlée est plus aisée ou souhaitable.

Sur la Théorie des Jeux

Par Bernard Guerrien

La microéconomie ne sert à rien - sauf à quelques uns auxquels elle donne l’occasion de multiplier les "analyses" des "comportements" de consommateurs et d’entreprises fictifs, évoluant dans un monde tout aussi fictif, généralement sous la houlette d’un "commissaire-priseur" bénévole mais passablement autoritaire.

Face à ce constat, il est fréquent d’entendre dire : " ’accord, mais tout cela est maintenant dépassé, notamment grâce à la théorie des jeux, qui fournit de nouveaux outils et permet d’avoir une vision plus complexe des interactions, basée sur les stratégies, etc.". Qu’en est-il exactement ?

Une "théorie" qui est loin d’être nouvelle

La théorie des jeux est, d’une certaine façLa théorie des jeux est, d’une certaine façon, née avant la microéconomie (dans les années 30). Ses textes fondateurs, ceux de Von Neumann et Morgenstern et Nash, datent de la fin des années 40, comme ceux de la microéconomie (de Samuelson à Debreu). Pourquoi donc l’avoir mise en veilleuse pendant 30 ans (disons entre 1950 et 1980), en privilégiant la microéconomie telle que nous la connaissons encore, alors que ceux qui ont développé celle-ci connaissaient parfaitement celle-là - la première démonstration d’existence d’au moins un équilibre général, par Arrow et Debreu, considère l’économie comme un jeu, au sens de la théorie des jeux. A cause de problèmes rencontrés sur le plan mathématique, qu’on aurait (enfin) résolus ? Pas vraiment, puisque le principal résultat de la théorie des jeux, le théorème d’existence de Nash, a été établi au début des années 50. Depuis, une bonne partie de l’activité des théoriciens des jeux a consisté à proposer ce qu’ils appellent des " raffinements " de l’équilibre de Nash, face aux problèmes posés par celui-ci. En fait, ces problèmes sont apparus très rapidement (ils sont déjà largement évoqués dans le livre publié en 1957 par Luce et Raiffa, avec le titre significatif Game Theory : Introduction and Critical Survey) et ils sont insolubles, non pas pour des raisons mathématiques, mais en raison de la nature même de la théorie des jeux (le fait que chacun décide en cherchant à anticiper ce que les autres vont faire - en cherchant eux-mêmes à anticiper, etc. - conduit à envisager une multitude d’issues possibles, avec souvent à la clé "dilemmes" et "paradoxes").

La théorie des jeux traite-t-elle de ce qui est ou ce qui doit être ?

Une théorie est, selon l’acception courante, un ensemble d’hypothèses ayant trait au monde tel qu’il est (ou tel que le conçoit le théoricien), dans le but d’en expliquer (ou de décrire, ou de prédire) tel ou tel aspect. Toutefois, en sciences humaines - et tout particulièrement en économie - le théoricien s’en tient très rarement à ce qui est : il ne peut s’empêcher de dire ce qui doit être - sa démarche est normative. Alors, quid de la théorie des jeux ? La confusion règne à son propos, certains auteurs prétendant qu’elle cherche à expliquer les phénomènes observés, ou à faire des prédictions, d’autres qu’elle est prescriptive (normative), d’autres encore qu’elle est l’une et l’autre, d’autres (bien moins nombreux) enfin ne se prononçant pas. Quelques exemples.

- Version descriptive :

Eric Rasmussen : "C’est là exactement le paradigme de la théorie des jeux : celui qui construit le modèle attribue des fonctions de gain et des stratégies aux joueurs, puis OBSERVE ce qui se passe lorsqu’ils choisissent des stratégies pour obtenir le gain maximum" (Jeux et informations, 1994, Basil Blackwell).

Ken Binmore : "La théorie (des jeux), telle qu’elle est développée actuellement, est surtout la DESCRIPTION de ce qui se passe lorsque des personnes interagissent rationnellement".

David Kreps : "l’objet de la théorie des jeux est d’aider les économistes à COMPRENDRE et à PRÉDIRE ce qui se produit dans différentes situations économiques" (Théorie des jeux et modélisation économique, Dunod, 1992).

- Version normative :

Van Damme :  "Game Theory is a normative theory : it aims to prescribe what each player in a game should do in order to promote his interests optimally".

Luce et Raiffa : "Il est essentiel, pour nous, que le chercheur en sciences humaines sache que la théorie des jeux n’est pas DESCRIPTIVE, mais plutôt (conditionnellement) NORMATIVE. Elle n’établit ni comment les gens se comportent, ni comment ils devraient le faire pour atteindre certains buts. Elle prescrit, avec des hypothèses données, des types d’action qui conduisent à des issues ayant un certain nombre de propriétés qui relèvent de l’ ‘optimalité’" (italiques et guillemets sont des auteurs).

- Mélange des deux :

Encyclopedia Britannica : "A solution to a game PRESCRIBES the decision the players should make and DESCRIBES the game’s appropriate outcome. Game theory serves as a guide for players and as a tool for PREDICTING the outcome of a game"

- Ambigüité :

Osborne et Rubinstein : "Game theory is a bag of analytical tools designed to HELP US UNDERSTAND the penomena that we OBSERVE when decision makers interact". "Aider à comprendre" est modeste, "observe" suggérant néanmoins qu’on est dans le domaine du descriptif.

- Vague

Robert Aumann (New Palgrave) : "This discipline concerns the behaviour of decision makers (players) whose decisions affect each other". Aumann parle de "décideurs", mais inclut ensuite les ordinateurs, les animaux et... les plantes parmi les joueurs possibles. Binmore en fait autant. Comprenne qui pourra...

- Encore plus vague

La théorie des jeux permettrait d’ "éclairer", ou de faire avancer la réflexion, sur certains problèmes.(le mot anglais "insights", difficile à traduire, est fréquemment utilisé). Par exemple : Myerson, après avoir dit que la théorie de jeux "provides general mathematical techniques for analysing situations in which two or more individuals make decisions that will influence one another’s welfare", précise : "as such, game theory offers insights of fundamental importance for scholars of the social sciences" (Game Theory and Analysis of Conflict).

On retrouve l’argument de repli des microéconomistes : la théorie permet de "faire réfléchir" sur les problèmes, même si c’est avec des agents fictifs, dans un monde encore plus fictif. Peut être. Mais alors qu’on ne nous parle pas d’ "outils" - tout aussi fictifs que le monde où ils sont utilisés - ou des problèmes que la théorie des jeux permettrait de "résoudre" - dans des mondes non fictifs.

Cette cacophonie à propos de la nature de la théorie des jeux - sur ce qu’elle "fait" ou permettrait de faire - n’est pas accidentelle : elle découle de ce que, en règle générale, elle ne "résout" rien et ne "propose" rien aux joueurs. Essentiellement, elle attire l’attention sur les problèmes que posent les choix d’individus rationnels en interaction, lorsque toutes les hypothèses des modèles sont spécifiées.

Le cas de l’équilibre de Nash et le (trop ?) célèbre "dilemme des prisonniers" sont, de ce point de vue, très significatifs.

L’équilibre de Nash est-il "la" solution ?

Si les équilibres sont, en règle générale, des situations privilégiées par le modélisateur, c’est parce qu’ils sont, par définition, des situations non éphémères, considérées comme des "points d’attraction" du système (vers lesquels il tend ou "autour desquels" il se "maintient").

Or les théoriciens des jeux utilisent le mot "équilibre" pour désigner leur principal concept de solution : l’équilibre de Nash, ce qui revient en fait à désigner celui-ci comme "la" solution qui va de soi - quand on a trouvé les équilibres d’un modèle, celui-ci est "résolu", pour l’essentiel. Mais qu’en est-il exactement ? Car si un équilibre de Nash satisfait la condition minimale de rationalité - chaque joueur maximise... compte tenu de ce qu’il pense que les autres feront - il n’a rien des caractéristiques d’un équilibre, tel qu’on l’entend habituellement. En effet, s’il y a "équilibre", c’est parce que chacun anticipe correctement ce que les autres vont faire. En outre, les choix sont faits une seule fois et simultanément : l’idée d’un "processus" menant à l’équilibre - par modifications successives des anticipations - n’a pas de sens dans ce contexte (car si processus il y avait, des joueurs rationnels en tiendraient compte dans leurs choix, ce qui modifierait le processus - si tel n’était pas le cas, alors cela voudrait dire qu’on est ... à l’équilibre !).

Prenons l’exemple phare de la concurrence imparfaite : le modèle du duopole de Cournot. Chaque entreprise fait une offre en anticipant celle de l’autre (et en pensant qu’elle ne la modifiera pas), sans rien connaître à son propos. L’équilibre de Cournot-Nash du modèle est tel que chaque entreprise fait son offre en prévoyant exactement l’offre de sa concurrente sans rien savoir sur elle. Que peut alors prédire le modèle ? Rien, si ce n’est que l’équilibre n’aura jamais lieu - sauf cas très exceptionnel (où chaque entreprise tombe par hasard sur l’offre de l’autre). Le théoricien va-t-il "prescrire" cet équilibre aux entreprises ? Non, puisqu’elles peuvent toutes deux gagner plus en se concertant. Autrement dit, l’équilibre de Nash ne représente ni ce qui est (ou pourrait être), ni ce qui devrait être (du point de vue du profit des entreprises)...

Si on prend l’autre modèle classique du duopole, celui de Bertrand, où les entreprises proposent des prix, alors on peut dire que l’équilibre de Nash n’aura jamais lieu. En effet, l’équilibre de ce modèle est tel que chaque entreprise propose le même prix, égal au coût moyen (supposé constant). Comme à ce prix, leur profit est nul, elles ont toutes deux intérêt à proposer un prix supérieur à ce coût, avec une chance sur deux de faire un profit strictement positif (plutôt que nul) : par conséquent aucune d’entre elles ne choisira la stratégie d’équilibre ! Que peut alors prédire le théoricien ? N’importe quelle combinaison de stratégies peut avoir lieu, SAUF celle qui est un équilibre de Nash ! Il est difficile, dans ces conditions de voir dans celui-ci un "point d’attraction" du système. Sur le plan normatif, le seul conseil que peut donner le théoricien est : "proposez un prix supérieur à celui de l’équilibre de Nash" ! Une fois de plus, celui-ci ne dit ni ce qui est, ni ce qui doit être.

Mais, dira-t-on, ces conclusions n’ont lieu que dans des jeux "simples", à un seul coup. Pourquoi ne pas supposer des situations plus compliquées, dans lesquelles l’équilibre de Nash "émergerait", en tant que solution ? Le dilemme des prisonniers répété a été proposé par les théoriciens des jeux pour détruire les illusions à ce propos.

Équilibre de Nash et dilemme des prisonniers

Il est difficile, si ce n’est impossible, d’ouvrir un traité de théorie des jeux - ou un ouvrage de microéconomie qui cherche à présenter celle-ci - sans tomber sur une variante ou une autre du "dilemme des prisonniers" (pour beaucoup, en sciences sociales, théorie des jeux et dilemme des prisonniers sont presque des synonymes). Il est quand même symptomatique qu’une théorie mette en avant un dilemme - par nature, insoluble - dès sa présentation ! Le dilemme tient ici au fait que les stratégies de l’équilibre de Nash apparaissent aux joueurs comme des choix " évidents " (ce sont des stratégies dominantes, chacun le sachant) et pourtant elles ne peuvent être recommandées, car elles résultent en une issue sous-optimale, au sens de Pareto. D’où l’idée de répéter le jeu, pour essayer de sortir de ce dilemme. Mais, ce faisant, on le rend encore plus problématique, puisque tant que les répétitions ont lieu un nombre fini de fois, le seul équilibre de Nash est également sous-optimal - et ce d’autant plus que le jeu est répété un grand nombre de fois. Il devient donc encore plus difficile de recommander les stratégies d’équilibre. Outre le fait qu’elles ne correspondent pas à ce qui doit être, ces stratégies ne représentent pas ce qui est ; en effet, il découle des innombrables expériences faites avec des joueurs en chair et en os, que personne ne choisit la stratégie d’équilibre, si le jeu est répété quelques fois.

Il est vrai que ce "dilemme" peut être levé en supposant que le jeu de base est répété indéfiniment. Mais on se trouve alors devant un nouveau dilemme : le jeu obtenu comporte une infinité d’équilibres (c’est le célèbre "folk theorem"). Comment, et pourquoi privilégier l’un d’entre eux ? Sur quelle base ? On tombe alors sur un des autres problèmes lancinants de la théorie des jeux : la multiplicité des équilibres. A nouveau, tout dépend des croyances de chacun sur ce que l’autre (ou, plus compliqué encore, les autres) fera (feront). En fait, tout peut arriver, comme on peut le voir à travers l’exemple d’un jeu très simple, qui rentre dans la catégorie des jeux de coordination.

Équilibre et coordination

Cet exemple est décrit par le tableau suivant, où on voit que les deux joueurs, A et B, ont intérêt à se "coordonner" sur (a1,b1) ou (a2,b2) plutôt que de ne pas se coordonner (car alors leur gain à tous deux est nul), mais en même temps A préfère l’issue (a1,b1) (où il gagne 2) à (a2,b2) (où il ne gagne que 1), alors que c’est le contraire pour B.

 

b1

b2

a1

(2,1)

(0,0)

a2

(0,0)

(1,2)

Que peut-on prédire sur le choix des joueurs ? Rien ou ... tout ! Car tout dépend de ce que chacun pense de l’autre. Ainsi, si A croit que B est plutôt du genre " dégonflé ", il optera pour a1 ; si sa croyance est correcte, il y aura équilibre de Nash, mais s’il se trompe, alors c’est l’issue la pire qui prévaudra (gain nul pour les deux joueurs). Tout dépend donc des croyances des joueurs, qui sont un paramètre hors modèle (non spécifié par celui-ci). Selon ce que croit chacun sur l’autre, n’importe laquelle des issues peut se réaliser, les joueurs ayant un comportement rationnel. Le modèle n’a pas de " solution " qui s’impose, d’une façon ou une autre.

Quid d’un point de vue normatif ? Là aussi, on ne peut rien dire : le "conseil" que peut donner le modélisateur à A, par exemple, dépend de ce qu’il croit sur B. La seule chose qu’il peut leur dire : vous avez intérêt à vous "coordonner". Mais sur quoi ? Il n’y a pas de réponse à cette question.

Aller plus loin ?

Nous avons ici évoqué des jeux très simples (Cournot, Bertrand, dilemme du prisonnier, jeu de coordination), à deux joueurs (on évite ainsi le problème, complexe, des coalitions possibles), et chaque fois nous avons pu constater que la théorie des jeux ne propose nullement de "solution" - positive ou normative - à ces modèles. D’où la question : comment une théorie qui ne peut résoudre, quelque soit le sens qu’on donne à ce mot, des problèmes (modèles) très simples pourrait-elle le faire pour des problèmes plus compliqués ? La réponse est évidente ... Pourtant, tout le monde parle de théorie des jeux (même si c’est à 90% des fois à propos du dilemme des prisonniers), il y a de gros traités et même des revues qui portent sur elle. On se dit : ce n’est pas possible, cela doit bien " résoudre " quelque chose. Et bien non ! Ou alors si solution il y a, c’est au sens mathématique. Par exemple, on va construire un modèle plus ou moins compliqué - qui est éventuellement censé représenter une situation concrète (forcément simple) - puis on se posera la question : est-ce qu’il a (au moins) un équilibre (en stratégies mixtes) ? Pour cela on utilisera des théorèmes mathématiques plus ou moins compliqués (du genre point fixe). Supposons que l’existence ait été établie. On pourra alors se demander si l’équilibre est unique - ce qui est l’exception plutôt que la règle - et chercher à le caractériser, voir quelle est sa sensibilité aux variations des divers paramètres du modèle (statique comparative), etc. Voilà de quoi publier, divertir les mathématiciens. Le problème, c’est que beaucoup d’énergie est ainsi consacrée à étudier sous toutes ses coutures une entité particulière, l’équilibre, sans qu’il n’y ait aucune raison - d’ordre positif ou normatif - qui le justifie (le fait de l’appeler équilibre est trompeur, de ce point de vue, comme nous l’avons signalé plus haut). On peut aussi essayer de voir, parmi tous les équilibres, si certains sont plus justifiés que d’autres du point de vue des croyances qui les sous-tendent, ce qui conduit à introduire ce que les théoriciens des jeux appellent des " raffinements " de l’équilibre de Nash. Qui dit croyances, dit distribution de probabilités, et donc complications supplémentaires au niveau du traitement mathématique. Ces croyances peuvent être plus ou moins élaborées et donc donner lieu à des développements d’une grande complexité. Toutefois, elles ne sont généralement que le produit de l’imagination du théoricien (dont l’imagination est souvent sans limites !), et non le fruit d’une observation quelconque (les expériences menées, avec ces jeux fictifs, montrent des comportements fort éloignés de ce que suppose la théorie).

Normes, conventions et autres "rationalité limitée"

Tout cela est parfaitement connu des "vrais" théoriciens des jeux - ceux qui maîtrisent effectivement les modèles, sans se contenter de parler d’ "outils" et "solutions", tout en restant dans le vague. Pour essayer de sortir du piège - notamment le fait que la théorie ne fait pas de prédictions, sauf cas exceptionnel -, il faut rajouter "autre chose" dans les modèles, un deus ex machina. Parmi il y a le "point focal" de Schelling : les individus se "coordonneraient " spontanément, du fait de référence communes (d’ordre culturelle, ou autre). Par exemple, des personnes s’étant donné rendez-vous dans un aéroport, sans autre précision, iraient devant le panneau d’affichage des départs, ou à la cafétéria, ou ... Ou alors, oh paradoxe !, on introduit une certaine dose d’incertitude ou d’ "irrationalité" (ou de croyance en l’irrationalité) dans le modèle. C’est ainsi qu’on essaye de "résoudre" le "dilemme" des prisonniers, surtout lorsqu’il est répété un certain nombre de fois ; mais alors, la " solution " (floue) proposée n’est pas un équilibre de Nash, le but étant d’essayer d’expliquer les comportements effectivement observés, lors d’expériences avec des joueurs en chair et en os (qui ne se comportement pratiquement jamais comme la théorie le prédit). La leçon de l’histoire : un peu - ou beaucoup - d’incertitude ou d’irrationalité peut être une bonne chose pour tout le monde ! Voilà de quoi faire douter de la pertinence des modèles de la microéconomie habituelle, et du discours sur les bienfaits des interactions des comportements rationnels (égoïstes), via la "main invisible" !

De façon plus générale, il est devenu usuel chez les théoriciens des jeux les plus réputés (par exemple; Aumann, Kreps, Rubinstein) d’affirmer que la seule issue pour la théorie des jeux, si elle veut quelque peu rendre compte de ce qu’on observe dans le monde économique, est de faire appel à la " rationalité limitée ", notion d’abord proposée par Herbert Simon (qui, depuis longtemps, nie toute pertinence et intérêt à la théorie des jeux), et dont la définition est d’ailleurs passablement floue. N’est-ce pas là avouer clairement que la théorie des jeux, dont le point de départ était le postulat de rationalité des individus, ne sert à rien, si ce n’est à montrer le peu de pertinence des analyses qui veulent expliquer les phénomènes économiques et sociaux en se basant sur ce seul postulat ?

A quoi sert la théorie des jeux ? D’abord et avant tout, à permettre de publier articles et livres. Ensuite, à dire : les relations sociales sont d’une très grande complexité, et peuvent mener à n’importe quoi, en théorie. Avait-on besoin de cette "théorie" pour arriver à une telle conclusion ? Ici encore, la réponse est évidente ... Mais soyons sûrs que beaucoup de gens continueront à écrire "la théorie des jeux fait ci, fait ça", "la théorie des jeux permet de résoudre tel ou tel problème", "maintenant, nous disposons des ‘avancées’ de la théorie des jeux". On attend des preuves, des exemples précis...

Génotypes

Darwinian Genetic Mutation Engine

(Coming Someday)

Trident Polymorphic Engine

(Coming Someday)

Stomper-101 génotype

Melissa génotype

I Love You génotype

search > W95/CIH
  > Brain
  > KAK.Worm.D
  > PalmOS/PHAGE