Ce papier explique en détail et de manière pédagogique comment résoudre des problèmes en intelligence artificielle à l'aide du langage Prolog. Les classiques du loup, chèvre et chou, et de la tour de Hanoï sont expliqués en détail. On décrit comment appliquer l'approche "general problem solver" en Prolog
Rapport de stage de perfectionnement au sien de l'institut supérieur des études technologiques de mahdia durant ce stage je crée une site web dynamique pour une société de vente des appareil mobile en utilise les site respective avec la framework bootstarp
Représentation sous forme de graphe d'états
Global Problem Solver
Algorithmes de Recherche Aveugles
Algorithmes de Recherche Informés
Depth First Search
Breadth First Search
Best First Search
A, A*
Fonction heuristique, Fonction heuristique admissible
L’optimisation par essaims de particuleschagra bassem
L’optimisation par essaim de particules est une méthode d’optimisation
stochastique, pour des fonctions non-linéaires, basée sur la reproduction d’un comportement social.
This document explains how to build a deductive inference engine for rule-based systems, business rules. It leads to a useful architecure for Complex Event Processing and Data streams
15 Insects and Arachnids Which You Can Have for DinnerBeatris Johnson
These 15 edible insects and arachnids are considered to be a great meal in many countries around the world. Find out where you can grab a snack or how to cook them on your own.
Rapport de stage de perfectionnement au sien de l'institut supérieur des études technologiques de mahdia durant ce stage je crée une site web dynamique pour une société de vente des appareil mobile en utilise les site respective avec la framework bootstarp
Représentation sous forme de graphe d'états
Global Problem Solver
Algorithmes de Recherche Aveugles
Algorithmes de Recherche Informés
Depth First Search
Breadth First Search
Best First Search
A, A*
Fonction heuristique, Fonction heuristique admissible
L’optimisation par essaims de particuleschagra bassem
L’optimisation par essaim de particules est une méthode d’optimisation
stochastique, pour des fonctions non-linéaires, basée sur la reproduction d’un comportement social.
This document explains how to build a deductive inference engine for rule-based systems, business rules. It leads to a useful architecure for Complex Event Processing and Data streams
15 Insects and Arachnids Which You Can Have for DinnerBeatris Johnson
These 15 edible insects and arachnids are considered to be a great meal in many countries around the world. Find out where you can grab a snack or how to cook them on your own.
Ce second cours d'algorithmique présente des techniques utilisées en intelligence artificielle pour trouver une solution à un problème de recherche. La première partie définit un problème de recherche : état, action, arbre d'exécution, espace d'états, cout, objectif et formalisation. La deuxième partie présente plusieurs algorithmes de recherche : non informé (BFS, UCS, DFS, DLS, ID-DFS, BS), informé (BFS, A*) et avec adversaire (Minimax, Alpha-Beta Pruning). Enfin, la troisième partie présente deux librairies Python qui implémentent des algorithmes de recherche.
Ce cours introduit à l'intelligence artificielle. La première partie du cours présente et définit ce qu'est l'intelligence et décrit les notions d'agent rationnel et d'environnement et leurs propriétés. Ces deux concepts permettent d'offrir un cadre de réflexion sur l'intelligence. La fin de la première partie présente les neufs formes d'intelligence selon Howard Gardner. La seconde partie du cours présente et définit l'intelligence artificielle, initiée par Marvin Minsky et John McCarthy au MIT. Elle présente également le test de Turing, test permettant de déterminer si une machine peut penser. Cette partie se termine en présentant les six grands domaines de l'intelligence artificielle.
2016 Thumbtack Small Business Friendliness SurveyThumbtack, Inc.
Today, we released our fifth annual Thumbtack Small Business Friendliness Survey. 12,169 U.S. small business owners participated in the 2016 study, collectively grading 35 states and 78 cities on the government policies that affect their businesses. The skilled professionals we surveyed operate in a variety of industries, including as electricians, music teachers, wedding planners, wellness professionals, and more. It is the largest continuous study of small business perceptions of government policy in the United States.
De l'IA au Calcul Littéraire: Pourquoi j'ai zappé le Web Sémantique Jean Rohmer
Je parle en tant que chercheur, programmeur et utilisateur de mes développements
Je fais de l’informatique depuis 44 ans
Je suis déçu par l’évolution de l’informatique
Depuis 40 ans on n’a presque rien trouvé de neuf en logiciel
Le logiciel n’est pas réductible à de l’ingénierie
J’essaie de construire des Amplificateurs d’Intelligence
J’écris du contenu sémantique chaque jour depuis 1997
Le nœud du problème est le langage: langage de programmation et langage naturel
Etymologiquement, programmer veut dire « écrire à l’avance »
Le futur n’est pas écrit, donc la programmation n’a pas de futur
La programmation n’a pas de passé: on a oublié les meilleurs langages (Lisp, APL, Prolog) et l’Intelligence Artificielle des années 80.
Il est très difficile de développer des applications intelligentes avec les langages à la mode
On a oublié ce qu’était une application intelligente
« Software Engineering » est une contradiction dans les termes
Il y a deux sortes de langages de programmation: ceux faits pour programmer les machines (à la mode), ceux faits pour résoudre des problèmes difficiles (oubliés)
En partenariat avec ADEO à Lille, retrouvez les slides de la conférence "UseCases Blockchain & Retail" présenté par Romain Vailleux (OCTO), Benoit Lafontaine (OCTO) & Régis Mertz (Leroy Merlin)
yseop est le premier moteur d’intelligence artificielle qui sait rédiger comme un être humain et à la vitesse de milliers de pages par seconde.
Il s’agit d’une innovation unique qui permet entre autre d’automatiser et de personnaliser la Relation Client. Cette technologie, issue de vingt années de recherche, sait raisonner (intelligence artificielle), dialoguer en langage naturel et rédiger des textes structurés et non répétitifs.
Yseop applique des règles métier à des données structurées (données connues de chaque client ou collectées de façon interactive pendant un dialogue) et exprime sa logique de raisonnement et ses conclusions en langage naturel, c’est-à-dire en français, anglais, allemand et espagnol.
http://yseop.com/FR/demos.php?section=2
WTF - Why the Future Is Up to Us - pptx versionTim O'Reilly
This is the talk I gave January 12, 2017 at the G20/OECD Conference on the Digital Future in Berlin. I talk about fitness landscapes as applied to technology and business, the role of unchecked financialization in the state of our politics and economy, and why technology really wants to create jobs, not destroy them. (There is a separate PDF version, but some readers said the notes were too fuzzy to read.)
Bienvenue en GAFAMIE !
La boucle est bouclée :
Sur les articles critiquant l’usage du cloud Microsoft pour héberger le « Health Data Hub », s’affiche … de la pub pour le cloud Microsoft …
De la pub microsoft dans les articles sur le health data hubJean Rohmer
Bienvenue en GAFAMIE !
La boucle est bouclée :
Sur les articles critiquant l’usage du cloud Microsoft pour héberger le « Health Data Hub », s’affiche … de la pub pour le cloud Microsoft …
Les 40 ans de l'Institut Fredrik Bull avec liens video: 40 ans d'informatique...Jean Rohmer
Une journée exceptionnelle avec les grands noms de l'informatique française, pour faire un retour sur les 40 dernières années et donner une vision du futur
Utiliser le langage d'intelligence artificielle PROLOG pour résoudre des jeux mathématiques et géométriques: combien y-a-t-il de de triangles dans une figure ?
Arithmetics with symbolic Artificial Intelligence and Prolog: it's a child's...Jean Rohmer
We illustrate what is symbolic artificial intelligence using arithmetic knowledge, and the PROLOG AI language. Two lines of Prolog are enough to tell a machine what is an addition and how ti perform it. We show how it relates to children knowledge about counting.
L'informatique n'est pas l'amie des donnéesJean Rohmer
Voici la présentation que j'ai faire au colloque GREC-O "Les systèmes complexes face au tsunami exponentiel du numérique".
Pour moi, une donnée est une phrase entière, un énoncé.
J'y explique que l'ordinateur "matériel" n'a pas été fait pour traiter les données, les langages de programmation non plus.
Et que cela handicape beaucoup les utilisations de l'informatique.
Expériences de gestion des connaissances avec IDELIANCE: supprimons le document!Jean Rohmer
Cet article tire quelques leçons de la conception et
de l’usage de l’outil IDELIANCE depuis une di-
zaine d’années. Idéliance est un outil de gestion de
réseaux sémantiques développé à partir de 1993,
c’est à dire à une époque où Internet était encore
très peu répandu dans l’industrie, et le Web sé-
mantique tout à fait in
existant. Nous résumons
brièvement les caractéristiques de Idéliance, et
nous nous intéressons surtout aux applications in-
dustrielles qui en ont été faites. Ceci est l’occasion
de s’interroger sur les
motivations des « cols
blancs » vis à vis de la gestion des connaissances,
que nous opposerons ici à la gestion documen-
taire.
Mots clés :
Ingénierie des connaissances ; représen-
tation des connaissances ; attitudes personnelles et
collectives face à la gestion des connaissances
Artificial Intelligence Past Present and FutureJean Rohmer
A presentation from IFIP Congress 2004, where I give my vision of the evolution of AI, reasons of AI winter, and belief that it is the monly way to improve Information Processing in the future
Semantic networks, business rules, inference engines, and complex event proc...Jean Rohmer
Theses slides describe the principles of semantic networks (or triples) as a general and flexible representation format. We introduce the notion of deduction rules / inferences on semantic networks / triples. The detailed design of an inference engine -forward chaining- is introduced. It uses the so-called "delta driven computing" to optimise inference. The gereralization to forward chaining is provided, using the "Alexander Method". Principles of the implementation in Java are introduced, with appropriate methods on matrix operations, inparticular relational Join operations. FInally, we show how we can implement "Complex Event processing" and trigger mechanisms.
Ideliance is a precursor of so-called Semantic Web. FIrst version was developped in 1993. It allows individuals and groups to organize their personal or collective / corporate knowledge as a semantic network. This document is a presentation of the product written in year 2000. Ideliance has been marketed for large companies like Air LIquide, France Telecom, PSA, CEA, EDF, GDF, Danone, Merckk. It has been used in Military Intelligence applications. It has been designed by Sylvie Le Bars (Arkandis.com) Jean Rohmer, and implemented mainly by Stéphane Jean and Denis Poisson.
Applying standards and methods is a must in modern society. However, in the domain of
information processing systems or of computer-automated systems, we have observed that
misuse or abuse of standards and methods can lead to very negative effects. We consider that
contemporary misuse of standards may offend elementary scientific and technical ethics.
Litteratus Calculus is a proposal to use concise natural language sentences to represent information and knowledge, instead of crippling software engineering models and formats. We propose it as an alternative to W3C Semantic Web. Models and ontology emerge by graph computation and topology from sentences rather than being frozen by advance.
Intelligence Artificielle: résolution de problèmes en Prolog ou Prolog pour les nuls
1. RESOLUTION DE PROBLEMES EN INTELLIGENCE ARTIFICIELLE
L’APPROCHE « GENERAL PROBLEM SOLVER » EN PROLOG
Jean Rohmer
jean.rohmer@devinci.fr
ESILV
ECOLE SUPERIEURE D’INGENIEURS LEONARD DE VINCI
PARIS LA DEFENSE
COURS INTELLIGENCE ARTIFICIELLE DE 3 ème Année
Mars 2013
Avertissement : cet article est à vocation pédagogique. Dans ce but, certaines solutions sont d’abord
proposées sous des formes incomplètes, simplifiées (et donc parfois inexactes). Mais que les puristes
se rassurent, tout s’arrange à la fin, et la rigueur scientifique est sauve…
Sur l’histoire de l’approche « General Problem Solver », commencer par :
http://en.wikipedia.org/wiki/General_Problem_Solver
Il n’est pas nécessaire de connaître Prolog pour le lire. C’est au contraire une occasion de découvrir
Prolog en même temps que la notion de « general problem solver ».
---------------------------------------
La description d’un problème, la recherche d’une solution, peuvent être vues comme le passage
d’une situation de départ à une situation d’arrivée, à travers la réalisation d’un certain nombre
d’actions, qui chacune aboutit à une nouvelle situation.
Par exemple, si votre problème est d’aller de Paris au Camping de la Plage à Ajaccio, vous partez de
la situation initiale « je suis à Paris », et suite à un certain nombre d’actions (prendre un train,
prendre un ferry, faire du stop, conduire une voiture, prendre un bus, …) vous vous retrouvez dans la
situation finale « je suis au Camping de la Plage à Ajaccio ».
Vous allez passer par une suite de situations et une suite d’actions qui vont alterner. Voilà une
solution possible :
Situation initiale: je suis à Paris
Action A1 : je prends le TGV Paris-Lyon
Situation S1 : je suis à Lyon
Action A2: je fais du stop jusqu’à Marseille
Situation S2: je suis à Marseille
2. Action A3: je prends un ferry
Situation S3: je suis à Ajaccio
Action A4: je prends un bus
Situation finale: je suis au Camping de la Plage à Ajaccio
Pour résoudre votre problème, vous avez accompli une suite de 4 actions :
[TGV Paris-Lyon, je fais du stop jusqu’à Marseille, je prends un ferry, je prends un bus]
Vous êtes passés par 5 situations successives [Situation de départ, S1, S2, S3, situation finale]
Et il y a beaucoup d’autres solutions possibles, compte-tenu de tous les modes de transport
disponibles.
On a résolu le problème en le décomposant en une suite d’étapes élémentaires, plus simples. Une
étape est caractérisée par trois choses : la situation initiale, l’action, la situation d’arrivée.
NB : Pour rendre une machine capable de résoudre automatiquement un problème, il faut lui
communiquer des connaissances dans un langage formel, plus précis que le langage naturel. Prolog
est un tel langage formel, qui, par certains aspects, ressemble au langage des mathématiques.
Dans ce qui suit, nous écrirons donc en bleu des formules –obéissant à certaines règles- en
utilisant l’essentiel du langage Prolog, mais sans entrer dans le détail du langage.
Nous allons donc résoudre des problèmes en Prolog, mais sans faire un cours de Prolog. En fait, à la
fin de cet article, vous aurez non seulement résolu des problèmes, mais aussi découvert et compris
l’essentiel du langage Prolog. Ceci vous aidera à apprendre plus vite Prolog, sans vous en dispenser.
Attendez l’énoncé des programmes Prolog complets (en rouge) pour avoir un code correct
exécutable.
Commençons par exprimer qu’une étape permet de passer d’une situation à une autre suite à une
action.
Etape(je suis à Marseille, je prends un ferry, je suis à Ajaccio)
Si on connaît toutes les étapes possibles, la solution est une suite d’étapes, telle que le point
d’arrivée de l’une d’elles est le point de départ de la suivante, et telle que la première étape parte de
la situation de départ, et la dernière étape arrive à la situation finale:
Etape(situation initiale, A1, S1), Etape(S1,A2,S2) …. Etape (Sn-1,An,situation finale)
La solution est un itinéraire possible composé d’une suite d’étapes.
Posons-nous un autre problème : je suis en terminale S (c’est ma situation initiale) et je veux devenir
Ingénieur (c’est ma situation finale). Là aussi, j’ai à ma disposition un certain nombre d’étapes :
Etape(je suis candidat au concours d’entrée , je réussis le concours, je suis admis ).
Etape(je suis admis à une école, je choisis cette école, je suis étudiant à cette école)
3. Il faut bien distinguer les situations et les actions. Une action –on pourrait dire aussi parfois un
évènement- est ce qui fait passer d’une situation à une autre.
Dans notre voyage vers le camping, les étapes étaient de vraies étapes de voyageur, mais dans notre
parcours scolaire, on peut aussi parler d’étapes.
Quel que soit le problème à résoudre, on va chercher à construire une solution comme une suite
d’étapes qui chacune nous fait passer d’une situation à une autre qui nous rapproche de l’objectif
final.
On décrira une solution comme ça :
Solution(situation initiale, situation finale, suite des actions)
Exemple :
Solution(je suis à Paris, je suis au Camping, [TGV Paris-Lyon, Auto Stop, Ferry, Autobus]).
Comment construire une solution ?
Supposons que l’on connaisse toutes les étapes possibles, et que je veuille passer de la situation
initiale SI à la situation finale SF.
Le cas le plus simple est celui où je peux aller de SI à SF en une seule étape. On va dire ça ainsi:
Solution(SI,SF,[A]) :- Etape(SI,A,SF).
Qui va se lire comme :
Si j’ai une étape directe de SI à SF avec l’action A alors j’ai une solution pour aller de SI à SF par la
suite d’actions [A] (uns suite d’actions qui ne contient qu’une action).
C’est le :- qui exprime que la formule à gauche du :- est vraie si la formule à droite est vraie.
NB : on voit qu’on décrit une suite en mettant ses éléments entre crochets, séparés par des virgules :
• [A,B,C] est une suite de 3 éléments
• [A] est une suite d’un seul élément
• [] est une suite qui est vide : elle ne contient aucun élément
On peut lire ça aussi comme :
Pour avoir une solution qui permet de passer de SI à SF par la suite d’action [A], il suffit qu’il existe
une étape directe qui passe de SI à SF par l’action A :
Pour avoir ce qui est à gauche du :- ,il suffit d’avoir ce qui est à droite.
4. Mais en général, il nous faudra plus d’une étape pour atteindre la situation finale, et on ne sait pas
combien à l’avance, cela dépend des étapes à notre disposition.
Pour résoudre ça, on va « saucissonner » la solution, la décomposer, on va procéder pas à pas, en
nous disant que pour partir de la situation initiale vers la situation finale, on va commencer par
chercher une étape qui nous mène de la solution initiale à une solution intermédiaire. Puis une fois
arrivés à ce point intermédiaire, on se repose le problème de trouver une solution qui nous mène à la
situation finale.
Autrement dit, si je veux voyager de SI à SF, je peux commencer par
une étape de SI à Premier_Arret, puis voyager de Premier_Arret à SF.
Ce qui peut s’exprimer ainsi :
Solution(SI, SF, [Premiere_Action|Actions_Restantes]) :-
etape(SI, Premiere_Action, Premier_Arret),
Solution(Premier_Arret, SF, Actions_Restantes).
On dit qu’une solution peut toujours être vue comme une première étape suivie d’une solution
couvrant le reste du chemin.
Un voyage, c’est une première étape, suivie d’un autre voyage.
A noter l’usage de la barre verticale | dans :
[ Premiere_Action | Actions_Restantes ]
Ceci représente la suite constituée de l’élément Premiere_Action ajouté à la suite Actions_Restantes.
(la barre verticale « saucissonne » les suites en isolant leur premier élément).
Sachant qu’on a aussi dit que, dans le cas le plus simple, une étape peut être un voyage à elle toute
seule :
Solution(SI,SF,[A]) :- Etape(SI,A,SF).
(Ceci est une version simplifiée de « solution », la version finale est donnée plus loin dans le code
source en rouge)
Voilà donc comment il faut procéder pour résoudre un problème :
1) Décrire toutes les étapes faisant passer d’une situation à une autre via une action
2) Construire une solution comme une suite d’étapes
Et nous avons expliqué comment construire de longues solutions en les « saucissonnant » :
une première étape qui part du début, suivie d’une solution qui arrive à la fin.
5. Pour résoudre un problème donné, il nous suffit donc de décrire, d’énumérer toutes les étapes
possibles, la construction de la solution étant toujours la même –une suite d’étapes- quelles que
soient ces étapes.
Comment décrire les étapes pour un problème donné.
Il y a deux grands cas de figure :
A) Celui où il est possible de faire la liste complète de toutes les étapes : c’est le cas si on
dispose des horaires de trains, de bus, de lignes aériennes.
C’est aussi le cas si on connaît les conditions d’admission à toutes les écoles et leurs règlements
pédagogiques
Faire l’inventaire de toutes les étapes, ça veut dire deux choses : établir la liste de toutes les
situations et établir toutes les actions qui peuvent faire passer d’une situation à une autre
B) Mais dans la vie courante, il y a des problèmes trop complexes pour faire l’inventaire de
toutes les situations et de toutes les étapes possibles.
Par exemple, si on veut résoudre un problème en terme de jeux, (jeux de cartes, jeux d’échec,
tactiques sportives, situations dans des jeux video) : le nombre des situations est astronomique, et se
mesure avec des nombres à plusieurs dizaines de chiffres.
Il n’est plus question d’énumérer à la main. Il va falloir explique à la machine quelles sont les étapes
possibles à partir d’une situation donnée, en donnant des règles générales. En quelque sorte donner
les règles du jeu. (De même que l’on ne décrit pas le jeu d’échecs en faisant la liste de toutes les
situations, mais en donnant des règles générales de comportement des pièces).
Nous allons maintenant traiter deux cas célèbres : le paysan, le loup, la chèvre et le chou, et les tours
de Hanoï.
Le paysan, le loup, la chèvre et le chou
Un paysan est sur la rive gauche d’une rivière, avec un loup, une chèvre, et un chou.
Il dispose d’une barque
Son problème est de faire passer tout le monde (loup, chèvre, chou) ainsi que lui-même sur la rive
droite, en faisant des allers et retour sur les deux rives.
Les contraintes sont les suivantes :
Dans la barque, le paysan peut avoir au plus un passager (loup, chèvre ou chou).
Si le loup et la chèvre se trouvent sur une même rive sans le paysan, le loup mange la chèvre.
6. Si la chèvre et le chou se trouvent sur une même rive sans le paysan, la chèvre mange le chou.
Pour donner des règles générales décrivant les étapes possibles, il faut :
Décider comment définir la situation à un instant donné
Décider ce que c’est qu’une action, comment la définir, et comment une action fait passe d’une
situation « avant » à une situation « après »
Comment définir la situation.
A un instant donné, les quatre interlocuteurs sont répartis entre trois lieux :
La rive gauche
La rive droite
La barque
Donc on pourrait décrire la situation en disant qui est où, en représentant trois ensembles
correspondant à ces trois lieux.
Mais on peut faire plus simple : une fois la barque partie d’une rive, elle arrive forcément sur l’autre
rive pour décharger ses passagers. On peut donc se contenter de considérer les situations une fois la
barque accostée à une rive, après une traversée, au moment où la barque est vide.
Ensuite, pour connaître l’état du système, il suffit de savoir ce qu’il y a sur une seule rive, puisque on
sait que les autres sont nécessairement sur l’autre rive.
Décidons donc que la situation va être décrite par les présences sur la rive gauche.
Donc le problème à résoudre est :
Situation initiale : tout le monde sur la rive gauche
Situation finale : personne sur la rive gauche
Maintenant il faut définir ce qu’est une action : c’est une traversée ; elle est donc définie par le
contenu de la barque.
Ce qu’il faut exprimer maintenant, c’est la notion d’étape, donc dans notre cas :
Une certaine situation sur la rive gauche avant la traversée
Une traversée
La situation sur la rive gauche après la traversée (on parle de cette même rive gauche puisque
c’est elle que nous avons choisi pour représenter la situation)
Il faut distinguer deux types d’étapes :
-celles où la barque quitte la rive gauche (on appellera ce cas « aller »)
-celles où la barque revient sur la rive gauche (on appellera ce cas « retour »)
Cas Aller :
Les passagers de la barque quittent la rive gauche et vont sur la rive droite
7. Etape(RG1,Passagers,RG2)
Attention : RG1, ce n’est pas la rive de départ, et RG2 ce n’est pas la rive d’arrivée. RG1
c’est la situation de la rive gauche avant l’action, et RG2 la situation de la rive gauche
après l’action, les déplacements de la barque se faisant de rive à rive dans les deux sens.
Il faut dire que RG2 c’est : RG1 moins les Passagers
Cas Retour :
Les passagers de la barque viennent s’ajouter sur la rive gauche
Etape(RG1,Passagers,RG2)
Il faut dire que RG2 c’est RG1 plus les Passagers
Il nous faut donc définir une sorte d’opération faisant la somme entre des ensembles :
Somme(E1,E2,E3) qui signifiera que les éléments de E3 sont la somme de ceux de E1 et de ceux de
E2
Dans le cas aller, on aura donc :
Somme(RG2,Passagers,RG1) : RG2 diminue par rapport à RG1
Et dans le cas retour :
Somme(RG1,Passager,RG2) : RG2 augmente par rapport à RG1
Donc à l’aller, on définit l’étape ainsi :
Etape(RG1,Passagers,RG2) :- somme(RG2, Passagers, RG1)
Et au retour :
Etape(RG1,Passagers,RG2) :-somme(RG1, Passagers, RG2)
Il faut imposer aussi les contraintes sur la composition d’une rive (personne ne mange personne) et
sur la composition des passagers.
A l’aller :
Le paysan quitte la rive gauche, il faut imposer qu’il laisse une rive paisible
Etape(RG1,Passagers,RG2) :- somme(RG2, Passagers, RG1),
bonnerive(RG2),
bonnebarque(Passagers).
Ce n’est pas la peine de dire que la rive RG1 est bonne, on en est sûr puisque le paysan y était.
8. Au retour :
Le paysan revient sur la rive gauche, et abandonne la rive droite, qu’il doit laisser dans un état
paisible. Il faut donc savoir qui est présent sur cette rive. Ce sont ceux qui ne sont pas dans RG2, ce
qu’on peut exprimer comme
Somme(RG2,Rive_Droite,Tous_les_Quatre), bonnerive(Rive_Droite)
On exprime ainsi que la Rive_Droite est le complément de la rive gauche, pour réunir tout le
monde.
Finalement, voilà la définition d’une étape de retour :
Etape(RG1,Passagers,RG2) :- somme(RG1, Passagers, RG2),
bonnebarque(Passagers),
Somme(RG2,Rive_Droite,Tous_les_Quatre),
bonnerive(Rive_Droite).
Nous avons choisi des représentations de la situation et de l’action ; nous avons expliqué comment
une action changeait la situation, et nous avons imposé les contraintes sur la nature des passagers et
la composition d’une rive paisible.
Il nous reste à définir en détail les contraintes : somme, bonnebarque, bonnerive.
Elles opèrent toutes sur des ensembles contenant tout ou partie de nos quatre « individus » : paysan,
loup, chèvre et chou. De même, notre situation sur la rive gauche est représentée par un ensemble.
Une manière bien connue de représenter des sous- ensembles est la « fonction caractéristique »,
qui dit, pour chaque élément possible, s’il appartient ou non au sous-ensemble.
Ici , l’ensemble total est paysan, loup, chèvre, chou
On représente un sous-ensemble par un 0 si l’élément est absent et un 1 si il est présent.
On fixe l’ordre : « paysan, loup, chèvre, chou ».
• L’ensemble complet est représenté par : [1,1,1,1] (ce que nous avons appelé plus haut
« Tous_les_quatre »)
• L’ensemble vide par : [0,0,0,0]
• Le sous-ensemble loup, chou par : [ 0,1,0,1]
Définition des bonnes barques.
Elles contiennent toujours le paysan, et au plus un passager.
9. Donc on a :
Bonnebarque([1,0,0,0]).
Bonnebarque([1,0,0,1]).
Bonnebarque([1,0,1,0]).
Bonnebarque([1,1,0,0]).
Définition des bonnes rives
Une rive est paisible si le paysan est présent.
Si le paysan est absent, une rive est paisible :
Si elle ne contient qu’un seul autre élément ou aucun élément
Si seuls le loup et le chou sont présents (le loup ne mange pas le chou, ni le chou le loup)
On va écrire :
Bonnerive[1, _,_,_]
Le caractère « _ » signifiant que la valeur à cet endroit n’a pas d’importance, sorte de joker : il suffit
que le paysan soit là, le reste n’a pas d’importance
Bonnerive[0,0,0,0]
Bonnerive[0,0,0,1]
Bonnerive[0,0,1,0]
Bonnerive[0,1,0,0]
Bonnerive[0,1,0,1]
Définition de la somme
Il s’agit de dire que somme(E1,E2,E3) signifie que l’ensemble E3 est la réunion des ensembles E1 et
E2.
Exemple : somme([0,0,1,0],[1,0,0,1],[1,0,1,1])
Le travail s’effectue élément par élément, selon la règle suivante
somme(0,0,0)
somme(0,1,1)
somme(1,0,1)
10. NB : le cas somme(1,1,1) ne se présente jamais ici car un élément n’est jamais dans deux ensembles
à la fois.
D’où :
Somme([X1,X2,X3,X4],[Y1,Y2,Y3,Y4],[Z1,Z2,Z3,Z4]) :-
Somme(X1,Y1,Z1), Somme(X2,Y2,Z2), Somme(X3,Y3,Z3),Somme(X4,Y4,Z4)
Pour distinguer entre les deux cas que nous avons vus plus haut (celui où la barque quitte la rive
gauche, et celui où elle y revient), on va pouvoir procéder ainsi :
Etape(RG1,Passagers,RG2) :- RG1 = [1,_,_,_],
somme(RG2, Passagers, RG1),
bonnerive(RG2),
bonnebarque(Passagers).
Etape(RG1,Passagers,RG2) :- RG1= [0,_,_,_],
somme(RG1, Passagers, RG2),
bonnebarque(Passagers),
Somme(RG2,Rive_Droite,Tous_les_Quatre),
bonnerive(Rive_Droite).
Les ajouts de RG1 = [1,_,_,_] et RG1 = [0,_,_,_] permettent de distinguer les cas aller et
retour.
Finalement, avec ces conventions, pour résoudre notre problème, il suffira de l’exprimer ainsi :
Solution([1,1,1,1], [0 ,0,0,0], Liste_Actions).
afin de trouver toutes les listes d’actions qui permettent de passer à :
Situation = [1,1,1,1] : tout le monde sur la rive gauche
à
Situation = [0,0,0,0] : personne sur la rive gauche
11. Voilà le programme Prolog complet qui correspond à cette approche.
etape(RG1,P,RG2):-RG1 = [1,_,_,_], bonnebarque(P), somme(RG2,P,RG1), bonnerive(RG2).
etape(RG1,P,RG2):- RG1 = [0,_,_,_],
bonnebarque(P),somme(RG1,P,RG2),somme(RG2,RIVE_DROITE,[1,1,1,1]),bonnerive(RIVE_
DROITE).
somme([X1,Y1,Z1,T1],[X2,Y2,Z2,T2],[X3,Y3,Z3,T3]):-
somme(X1,X2,X3),somme(Y1,Y2,Y3),somme(Z1,Z2,Z3),somme(T1,T2,T3).
somme(0,0,0).
somme(0,1,1).
somme(1,0,1).
bonnebarque([1,0,0,0]).
bonnebarque([1,1,0,0]).
bonnebarque([1,0,1,0]).
bonnebarque([1,0,0,1]).
bonnerive([1,_,_,_]).
bonnerive([0,1,0,1]).
bonnerive([0,0,0,0]).
bonnerive([0,1,0,0]).
bonnerive([0,0,1,0]).
bonnerive([0,0,0,1]).
nonmember(_,[]).
nonmember(X, [Y|Ys]):-X = Y,nonmember(X,Ys).
solution(A,B,[ACT],_):-etape(A,ACT,B).
solution(A,B,[ACT|L],Deja):-etape(A,ACT,C),nonmember(C,Deja),solution(C,B,L,[C|Deja]).
solution(A,B,L):-solution(A,B,L,[A]).
12. On voit dans ce code que « solution » a été modifiée par rapport à la version donnée plus haut. La
première version partirait dans des boucles infinies si une action nous ramenant dans une situation
déjà visitée (par exemple des aller-retour à l’infini avec le même passager).
Avant de se diriger vers une nouvelle étape, il faut savoir par quelles situations où on est déjà passé,
et vérifier que l’on n’y retourne pas. D’où une version de « situation » avec un 4 ème paramètre, qui
contient la suite des situations rencontrées (appelée Déjà). Si la situation C n’est pas déjà rencontrée
(usage de « nonmember », bien connue en Prolog), alors on peut continuer, et on ajoute C à Déjà,
par [C|Deja].
Vous pouvez l’exécuter par exemple avec le logiciel libre SWI Prolog.
Les tours de Hanoï
Le problème est bien expliqué dans Wikipedia : http://fr.wikipedia.org/wiki/Tours_de_Hano%C3%AF
« Le problème des tours de Hanoï est un jeu de réflexion imaginé par le mathématicien français
Édouard Lucas, et consistant à déplacer des disques de diamètres différents d'une tour de « départ »
à une tour d'« arrivée » en passant par une tour « intermédiaire », et ceci en un minimum de coups,
tout en respectant les règles suivantes :
on ne peut déplacer plus d'un disque à la fois,
on ne peut placer un disque que sur un autre disque plus grand que lui ou sur un emplacement vide.
On suppose que cette dernière règle est également respectée dans la configuration de départ. »
On aborde habituellement ce problème dans les cours de programmation, pour illustrer la notion
d’algorithme récursif, et pour trouver le meilleur algorithme de résolution du problème.
Mais ici notre démarche est toute autre : on ne veut pas trouver le meilleur algorithme pour
résoudre le problème, on est plus paresseux : on veut juste décrire les étapes possibles d’une
situation à une autre, et laisser la machine trouver des solutions.
Comment définir la situation :
13. C’est bien évidemment la composition de chaque tour, c’est à dire l’empilement des disques.
Appelons nos tours t1, t2, t3
Appelons nos disques 1, 2, 3, 4 …
1 est le plus petit, puis 2, puis 3 …
Par exemple, avec trois disques, la situation de départ est la suivante :
t1 = [1, 2, 3]
t2 = [] (vide)
t 3 = []
et la situation d’arrivée est :
t1 = []
t2 = [1, 2, 3]
t3 = []
etape(S1, A, S2) signifie :
Partant de la situation S1, je fais l’action A et je me retrouve dans la situation S2.
Comment définir une action
Qu’est-ce qu’une action ? C’est le déplacement d’un sommet d’une tour à une autre.
Elle se représente naturellement par le nom de la tour de départ et le nom de la tour d’arrivée, par
exemple : [t1, t3]
La forme générale d’une étape est donc :
etape( S1, [T1,T2], S2)
Les contraintes pour qu’une étape soit possible sont :
• il doit y avoir au moins un disque sur la tour T1, soir D1.
• il faut que D1 soit plus petit que le sommet D2 de T2 (ou que T2 soit vide).
Pour passer de S1 à S2, il faut changer la composition des tours : enlever un élément à T1, en rajouter
un à T2.
Comment représenter la situation
La situation globale est complètement décrite par la situation de chaque tour.
La situation d’une tour est la suite des disques qui la composent.
On peut le formuler ainsi :
14. [t1, [ 2, 3]] : dans la tour T1, il y a 2 en sommet , puis 3 en-dessous
La situation globale est donc la suite des situations des tours.
Exemple : situation de départ :
[ [t1, [1,2,3]] , [t2, [ ]] , [t3, [ ]] ]
Exemple : situation d’arrivée :
[ [t1, [ ]] , [t2, [1, 2, 3]] , [t3, [ ]] ]
Comment passer d’une situation à une autre
On doit enlever le sommet de la tour T1 et l’ajouter à la tour T2.
Donc dans la description de la situation de départ S1, il faut remplacer la description de la tour T1
par un contenu plus petit (le sommet en moins). Ceci nous conduira à une nouvelle situation S3.
Puis il faut remplacer dans S3 le contenu de T2 par un contenu plus grand (un sommet en plus), ce
qui nous conduira à S2.
On voit que pour passer de S1 à S2, on passe par une situation intermédiaire, S3, qui correspond au
moment où on a enlevé le sommet de T1 sans encore l’avoir mis dans T2.
On va utiliser une opération « remplacer », qui, dans une suite, remplace un élément par un autre.
Remplacer( S1,X1,X2,S2)
Signifiera que la suite S2 est la suite S1 dans laquelle tous les X1 ont été remplacés par X2.
Exemple :
Remplacer([10, 20, 30, 20, 40,] 20, 200, [10, 200, 30, 200, 40])
Etape(S1, [T1,T2],S2) peut alors être réalisée par deux remplace successifs :
Remplacer(S1,[T1,[D1|L1],[T1,L1],S3)
qui enlève le sommet de T1
Puis
Remplacer(S3,[T2,L2],[T2,[D1|L2]],S2)
Qui ajoute un sommet à T2
Commentaires.
On voit apparaître la notation :
[D1|L1]
15. La barre verticale permet de décrire la structure d’une suite comme composée d’un premier
élément suivi du reste de la suite.
S = [P |S1] signifiera que P est le premier élément de S et S1 le reste de la suite.
suite = [ premier élément de la suite | reste de la suite ]
Exemples :
S = [1,2,3,4]
S = [P | S1] donne P = 1 et S1 = [2,3,4]
A noter que P est un élément, et S1 une suite
S =[3]
S = [P | S1] donne P = 3 et S1 = [ ] (la suite vide)
Donc
Remplacer(S1,[T1,[D1|L1],[T1,L1],S3)
Signifie bien : je cherche dans S1 la description de la tour T1 ; soit D1 son sommet, et L1 le reste de la
liste, et je vais remplacer cette description par juste L1, pour obtenir la situation intermédiaire S3
De même
Remplacer(S3,[T2,L2],[T2,[D1|L2]],S2)
Signifie : je cherche dans S3 la description de la tout T2, soit L2 son contenu, je la remplace en
ajoutant D1 en tête de L2, pour obtenir la situation S2
Voilà donc la formule pour l’étape des tours de Hanoï
Etape(S1, [T1,T2], S2) :-
Remplacer(S1,[T1,[D1|L1],[T1,L1],S3)
Remplacer(S3,[T2,L2],[T2,[D1|L2]],S2).
Il nous manque la contrainte qui dit que dans une tour un disque ne peut pas être au-dessus d’un
disque plus petit.
Cela revient à vérifier que la composition de T2, à laquelle on vient d’ajouter D1, est valide.
Deux cas sont à considérer :
16. A) T2 était vide avant, et contient maintenant juste un disque. Et c’est une situation valide, que
l’on formulera comme :
Tour_Valide([X]) (toute suite d’un seul élément est valide)
B) T2 contient après au moins deux éléments, et il faut que le plus haut soit inférieur celui en
dessous :
Tour_Valide([S1| [S2 | L]]) :- S1 < S2
S1 est le premier élément de la suite, et S2 le premier élément de la liste moins S1.
D’où la formule finale pour l’étape des tours de Hanoï :
Etape(S1, [T1,T2], S2) :-
Remplacer(S1,[T1,[D1|L1],[T1,L1],S3)
Remplacer(S3,[T2,L2],[T2,[D1|L2]],S2)
Tour_Valide([D1|L2]).
On trouvera plus loin dans le programme Prolog complet la formule de « remplacer ».
Finalement, avec ces conventions de représentation, le problème des tours de Hanoï s’exprimera
ainsi :
Solution([[t1,[1,2,3]],[t2,[]],[t3,[]]], [[t1,[]],[t2,[1,2,3]],[t3,[]]), Liste_Actions).
NB : Il y a 2808 solutions …
Ceux qui ont déjà étudié la programmation des tours de Hanoï de manière classique ont été surpris :
elle ne donne qu’une seule solution.
Car la solution classique est la programmation d’un algorithme, qui est imaginé et construit par
une intelligence humaine. C’est l’intelligence humaine qui comprend qu’il existe un algorithme
récursif permettant de déplacer N disques de la tour A à la tour B en :
--déplaçant N-1 disques de la tour A à la Tour C
--puis en déplaçant le sommet de A à B
--puis en déplaçant N-1 disques de C à B
Dans notre cas, nous n’avons pas eu besoin d’imaginer et de construire un algorithme, nous avons
juste décrit les contraintes du problème : on ne peut que déplacer un sommet d’une tour qui n’est
pas vide que vers une tour vide ou dont le sommet est plus grand que le disque déplacé.
17. Or l’énoncé de ces contraintes ne figure même pas dans l’algorithme ! C’est bien la preuve que
l’intelligence est restée dans la tête humaine, et pas du tout dans la machine.
Dans notre solution, les contraintes sont données à la machine, et c’est la machine qui s’en
débrouille. On est passé d’une intelligence humaine à une intelligence artificielle, de nature très
différente.
Il faut noter que la machine trouve 2808 solutions (2808 suites de déplacements d’une tour à une
autre), alors que l’algorithme ne donne que la plus courte de ces suites.
A ce sujet il faut faire les remarques fondamentales suivantes :
L’algorithme est apparemment « optimal »
Mais qu’est-ce qui vous prouve que l’algorithme respecte les contraintes, puisqu’elles ne
figurent pas dans son texte ? L’intelligence humaine a peut-être trouvé un algorithme optimal,
mais encore faudrait-il le prouver formellement ! Ce qui n’est en général jamais fait …
Les 2807 solutions non optimales que l’on trouve s’égarent en quelque sorte du chemin
optimal, prennent le chemin des écoliers … Mais supposons que le monde des tours ne soit
pas parfait, qu’à certains moments une tour soit « défaillante », qu’un déplacement d’une tour
à l’autre soit interdit … alors l’algorithme devient inutile, et nos solutions pourront peut-être
trouver « à tâtons » un détour, une suite de mouvements qui nous tirera d’affaire. La solution
algorithmique est aveugle, purement automatique. Dit autrement, elle ne s’applique que dans
un monde idéal loin de la complexité potentielle de la réalité
Plus généralement, il y a peu de problèmes dans le monde réel qui soient suffisamment
« carrés » pour qu’un algorithme existe pour les résoudre. (De même qu’il y a peu d’équations
qui soient solubles purement mathématiquement). L’approche que nous avons programmée
s’oppose à la notion d’algorithme : les contraintes d’un problème sont communiquées à la
machine qui va chercher elle-même des solutions.
Ceci caractérise bien la démarche « intelligence artificielle » par opposition à la démarche
algorithmique. En Intelligence artificielle, l’important devient la représentation de connaissances
/ contraintes qui caractérisent un problème.
Voilà le programme Prolog complet qui correspond à notre approche.
Il peut être appelé avec la commande :
hanoi_debut(E1),hanoi_fin(E2),solution(E1,E2,X),imprime(X).
etape(E1,[T1,T2],E2):-tour(T1),tour(T2),T1 =T2,remplacer(E1,[T1,[S1|L1]],[T1,L1],E3),
remplacer(E3,[T2,L2],[T2,[S1|L2]],E2),tour_valide([S1|L2]).
(les « tour » au début servent à générer les étapes pour toutes les combinaisons de tours
différentes possibles)
tour_valide([_]).
18. tour_valide([S1|[S2|_]]):-number(S1),number(S2),S1<S2.
(on vérifie que S1et S2 sont bien des entiers avant de les comparer, sinon SWI Prolog a des
problèmes pour une raison qu’un lecteur pourra peut-être m’indiquer …)
remplacer([],_,_,[]).
remplacer([X|L],X,X1,[X1|L1]):-remplacer(L,X,X1,L1).
remplacer([Y|L],X,X1,[Y|L1]):-Y =X,remplacer(L,X,X1,L1).
(la fonction remplacer est générale : remplacer X par X1 dans une liste)
tour(t1).
tour(t2).
tour(t3).
hanoi_debut([[t1,[1,2,3]],[t2,[]],[t3,[]]]).
hanoi_fin([[t1,[]],[t2,[1,2,3]],[t3,[]]]).
nonmember(_,[]).
nonmember(X, [Y|Ys]):-X = Y,nonmember(X,Ys).
solution(A,B,[ACT],_):-etape(A,ACT,B).
solution(A,B,[ACT|L],Deja):-etape(A,ACT,C),nonmember(C,Deja),solution(C,B,L,[C|Deja]).
solution(A,B,L):-solution(A,B,L,[A]).
imprime([]).
imprime([X|L]):-print(X),imprime(L).
------------------------------------------
Merci aux lecteurs de nous faire suivre toutes leurs questions ou remarques pouvant améliorer cet
article.
Jean.rohmer@devinci.fr
Jean.rohmer@orange.fr