Objectifs et moyens

L'objectif de cette dernière séance de programmation logique est de mettre en place un système automatique de dialogue grâce à un système de filtrage symbolique, motivé par l'un des premiers défis posés à l'Intelligence Artificielle : le test de Turing. L'environnement choisi est toujours celui de SWI-Prolog (http://www.swi-prolog.org/).

Cette séance est organisée en 2 séquences (filtres et Eliza) supposées durer 3h au total, mais surveillez l'heure tout de même. En fin de séance, vous devrez envoyer par mél les prédicats que vous avez définis.

Ce T.P. est fortement inspiré du cours donné en Licence Mention Informatique de l'Université des Sciences et Technologies de Lille, par Jean-Christophe Routier.

Filtres (pattern-matching)

Avant de développer le système de dialogue en tant que tel, nous allons mettre en place des mécanismes de filtre sur des phrases fournies au système.

Définition

On appelle filtres des listes pouvant contenir :

  • des symbôles,
  • des termes de la forme joker(Variable)Variable est une variable Prolog éventuellement anonyme,
  • le caractère spécial **.

Le problème que l'on se pose est de déterminer si une phrase est conforme à un filtre donné. On dit alors qu'elle est filtrée par ce filtre. Une phrase P sera filtrée par le filtre F , si les deux listes correspondent en respectant les règles suivantes :

  • deux symboles constants différents ne correspondent pas,
  • une variable dans un terme joker filtre exactement un symbole quel qu'il soit,
  • si une variable est présente plusieurs fois dans le même filtre, elle doit toujours correspondre au même symbole
  • le joker ** peut filtrer un nombre quelconque de symboles (y compris 0)

Exemples

  • pour le filtre F=[tim,o,leon]
    • la phrase P=[tim,o,leon] est filtrée
    • la phrase P=[tim,x,leon] n'est pas filtrée
  • pour le filtre F=[tim,joker(X),leon]
    • la phrase P=[tim,o,leon] est filtrée et X s'unifie avec o
    • la phrase P=[tim,o,leon,truc] n'est pas filtrée
    • la phrase P=[tim,truc,leon] est filtrée et X s'unifie avec truc
    • la phrase P=[tim,leon] n'est pas filtrée
  • pour le filtre F=[tim,joker(X),leon,joker(X)]
    • la phrase P=[tim,o,leon,o] est filtrée et X s'unifie avec o
    • la phrase P=[tim,o,leon,truc] n'est pas filtrée car X ne peut

à la fois s'unifier à o et à truc

  • pour le filtre F=[tim,**,leon]
    • la phrase P=[tim,o,leon] est filtrée
    • la phrase P=[tim,o,a,b,leon] est filtrée
    • la phrase P=[tim,leon] est filtrée
    • la phrase P=[tim,leon,est,leon] est filtrée

Exercice 1

Écrire un prédicat est_filtree_par(+Phrase,+Filtre) qui indique si la phrase Phrase est filtrée par le filtre Filtre ; Phrase et Filtre étant donnés. Compte tenu de la forme des filtres, il y a plusieurs cas possibles à considérer : le cas où le filtre ne commence pas par un joker, puis celui où il commence par un joker de type joker(X) et enfin le cas du joker **. Ce dernier cas revient à considérer que ce joker "consomme" soit 0 soit au moins 1 mot de Phrase.

Exercice 2

Testez votre prédicat !

Programmer Eliza

Présentation

Eliza est l'un des premiers programmes d’intelligence artificielle. Ce programme simule un psychothérapeute rogérien. Il est constitué d'un ensemble de couples (filtre, reponse). Après chaque énoncé de l'utilisateur (le patient), le programme (le psy) compare les différents filtres avec cet énoncé et imprime, en fonction du premier filtre qui convient, une réponse, en reprenant éventuellement une partie de l'énoncé du patient.

Un exemple de fonctionnement est présenté ci-après.

Filtres et réponses

Le principe de fonctionnement d'Eliza s'appuie sur des motifs de phrases types. Pour chaque phrase du "patient", on cherche le motif prédéfini correspondant. À chaque motif est associée une réponse type, celle-ci est alors fournie. Afin d'accroître l'aspect réaliste des réponses, celles-ci peuvent reprendre des éléments de la phrase initiale du patient.

Exemples de couples (filtre, réponse)

filtreréponse
[au,revoir][]
[stop][]
[non][vous,êtes,bien,négatif]
[**,prolog,**][alors,vous,savez,programmer]
[un,joker(X),est un,joker(X)][hmmm,très,pertinent,parlez,encore,de,X]
[joker(X),et,joker(Y),sont,**][parlez-moi,plus,de,X,et,Y]
[**,ans,**][remontez,plus,loin,dans,vos,souvenirs]
[**,années,**][cela,fait,bien,longtemps]
[joker(_)][c,est,un,peu,court]
[**,je,ne,suis,pas,joker(X)][pourquoi,pensez,vous,que,vous,n'êtes,pas,X]
[**,suis,joker(X)][pourquoi,pensez,vous,que,vous,êtes,X]
[**,ne,**][vous,en,êtes,sûr]
[**,non,**][vous,êtes,très,négatif]
[**,vous,**][concentrez,vous,sur,votre,problème,svp]
[**,moi,**][racontez,m'en,plus,sur,votre,famille]
[**,je,**][comment,cela,se,manifeste-t-il]
[**,j'ai,**][ce,n'est,pas,la,quantité,qui,compte]
[joker(_),joker(_),joker_)][hmmm]
[**][je,ne,vous,suis,pas,très,bien]

Exemple de dialogue

Voici un exemple de dialogue (dans les crochets et virgules) possible à l'aide de ces quelques règles (que vous pouvez compléter) :

?- eliza.
|: [bonjour].
 c est un peu court 
|: [je,ne,suis,pas,court].
 pourquoi pensez vous que vous n etes pas court 
|: [parce,que].
 je ne vous suis pas tres bien 
|: [vous,n,ecoutez,pas].
 concentrez vous sur votre probleme svp 
|: [mon,probleme,est,mon,probleme].
 je ne vous suis pas tres bien 
|: [vous,vous,repetez].
 concentrez vous sur votre probleme svp 
|: [je,le,fais,depuis,des,annees].
 comment cela se manifeste t il 
|: [je,suis,fatigue].
 pourquoi pensez vous que vous etes fatigue 
|: [depuis,des,annees,je,dros,beaucoup].
 cela fait bien longtemps 
|: [en,effet].
 je ne vous suis pas tres bien 
|: [au,revoir].

true
?- 

Programmation

Les couples filtre/réponse sont représentés par des faits :

filtre_reponse(ListeDuFiltre,ListeDeLaReponse).

Par exemple :

filtre_reponse([un,joker(X),est un,joker(X)],[hmmm,tres,pertinent,parlez,encore,de,X]).

Le fichier filtres.pl contient les définitions des faits filtre_reponse correspondant au tableau ci-dessus. Vous pouvez évidemment compléter ces définitions pour enrichir les dialogues possibles.

Exercice 3

Écrire un prédicat filtrage(+Phrase,-Reponse) qui examine les filtres définis en premier paramètre des faits filtre_reponse et unifie Reponse avec la réponse associée (second paramètre) au premier des filtres (dans l'ordre d'écriture des faits) par lequel Phrase est filtrée. Par exemple, pour les filtre_reponse définis dans le fichier fourni, on a :

?- filtrage([c,est,sur,prolog,c,est,chouette],Reponse).
Reponse = [alors,vous,savez,programmer]
?- filtrage([pincemi,et,pincemoi,sont,dans,un,bateau],Reponse).
Reponse = [parlez,moi,plus,de,pincemi,et,pincemoi]

Exercice 4

Écrire un prédicat affiche/1 dont l'argument est une liste de termes représentant une phrase (cf. argument 2 de filtre_reponse/2). Ce prédicat doit écrire la phrase à l'écran, chacun des termes étant séparés par un caractère « espace ».

Exercice 5

Écrire un prédicat eliza qui permet d'exécuter le programme. Il faut lire une phrase (liste de mots), chercher le filtre qui convient, afficher la réponse associée et recommencer si la réponse n'est pas « [] ». On saisira la phrase sous forme d'une liste. Une trace d'exécution correspondant à l'exemple suivant pourrait donc ressembler à :

?- eliza.
vous : [depuis,trois,années,je,vis,avec,Marie].
eliza : cela fait bien longtemps
vous : [pas,du,tout].
eliza : hmmm
vous : [elle,ne,m,aime,plus].
elisa : vous en etes sur
etc.

Attention à ne pas oublier le « . » à la fin d'une saisie. Vous pourrez utiliser les prédicats prédéfinis read/1 et write/1 après avoir consulté l'aide à leur sujet.

Exercice 6

Afin de rendre la saisie des phrases au clavier plus conviviale, vous pouvez utiliser le prédicat lire_phrase/1 fourni dans le fichier ./eliza-utils.pl. Modifiez votre prédicat eliza afin d'utiliser cette fonctionnalité.

Envoi de vos travaux

Envoyez vos sources à picard@emse.fr à la fin de la séance.


Philippe Beaune, Gauthier Picard, Laurent Vercouter, February 2012