• Aucun résultat trouvé

Les listes

2.4 EXEMPLES D’APPLICATION

2.4.4 Les systèmes experts

2.4.4.a Introduction

Les systèmes experts sont des logiciels fournissant dans un domaine particulier les mêmes conclusions qu’un homme expert en ce domaine : fournir un diagnostic médical à partir d’une liste de symptômes, ou classer des espèces animales ou végé-tales à partir d’observations par exemple.

Un système expert doit donc :

• enregistrer les faits initiaux (les symptômes d’un malade, les observations sur l’animal en cours d’examen),

• et appliquer des règles générales pour en déduire de nouveaux faits non connus initialement.

Cet exemple est donné pour illustrer l’utilisation des listes, et non pour expliquer les systèmes experts en détail. Les règles mentionnées ci-dessous sont données à titre indicatif, sans prétention quant au domaine de l’expert, mais sur deux exemples de règles pour montrer l’indépendance du logiciel d’inférence (de déduction) de règles avec le domaine traité. Ce logiciel de déduction de nouveaux faits est habi-tuellement appelé moteur d’inférence.

Figure 27 Principe de la mémorisation des faits et des règles dans un système expert.

Voir le détail de l’implémentation sur les figures suivantes.

La première liste de la Figure 27 contient les faits initiaux 1, 2, 3, 4, 5. La seconde liste mémorise les règles A, B, C, D. Chaque règle est constituée de son nom, d’une

3 / 6 / 1

7 8 /

9 / 5

10 /

11 / 1

2 /

10 /

A B C D /

1 2 3 4 5 /

03Chap_02 Page 61 Samedi, 17. janvier 2004 10:36 10

62 2 Les listes

liste d’hypothèses (1, 7, 8 pour la règle B) et d’une liste de conclusions (9 pour la règle B). Il pourrait y avoir plusieurs conclusions. Les faits hypothèses et conclu-sions sont indiqués par leur numéro. Les deux tableaux ci-dessous permettent de passer à une application plus concrète et font correspondre un libellé à un numéro.

Le premier tableau fait référence à un système expert de diagnostic médical, le second à une classification d’animaux.

La règle B pourrait se formuler comme suit :

B – si

l’animal allaite ses petits et l’animal est couvert de poils et l’animal a quatre pattes alors

l’animal est un mammifère

À partir des faits initiaux 1, 2, 3, 4, 5, et en appliquant les règles, on peut ajouter pour la règle A dont l’hypothèse 3 est donnée comme fait initial, le fait conclusion 6.

La règle B ne s’applique pas, seule l’hypothèse 1 est vérifiée. La règle C ne s’applique pas, seule l’hypothèse 5 est vérifiée. La règle D s’applique, car les hypo-thèses 1 et 2 sont données comme faits initiaux. Le fait 10 est ajouté à la liste de faits. Il faut refaire un parcours des règles et voir si, suite à l’adjonction de nouveaux faits, de nouvelles règles ne sont pas vérifiées.

C’est le cas de la règle C qui est vérifiée au deuxième passage car le fait 10 a été ajouté par la règle D. Le fait 11 est donc ajouté. Un nouveau parcours des règles n’entraîne aucun ajout. Cette façon de procéder s’appelle le chaînage avant. Si les règles sont nombreuses, on risque de déduire de nombreux faits nouveaux, difficile-ment exploitables.

Une autre façon de procéder consiste à demander si le système ne peut pas démontrer un fait. Sur la Figure 27, peut-on démontrer le fait 11 ? Si le fait 11 n’est pas donné comme fait initial, il faut trouver une règle qui a 11 pour conclusion, et

1 a de la fièvre 1 allaite ses petits

2 a le nez bouché 2 a des crocs développés

3 a mal au ventre 3 vit en compagnie de l’homme

4 a des frissons 4 grimpe aux arbres

5 a la gorge rouge 5 a des griffes acérées

6 a l’appendicite 6 est domestiqué

7 a mal aux oreilles 7 est couvert de poils

8 a mal à la gorge 8 a quatre pattes

9 a les oreillons 9 est un mammifère

10 a un rhume 10 est un carnivore

11 a la grippe 11 est un chat

03Chap_02 Page 62 Samedi, 17. janvier 2004 10:36 10

2.4 • Exemples d’application 63

© Dunod – La photocopie non autorisée est un délit.

essayer de démontrer ses hypothèses. Pour démontrer 11, il faut démontrer 5 et 10 (règle C). 5 est un fait initial, reste à démontrer 10. Pour démontrer 10 (règle D), il faut démontrer 1 et 2 qui sont des faits initiaux. Donc 11 est vrai (démontré). Cette méthode s’appelle le chaînage arrière (voir Figure 28).

Démontrer le fait 11 sur les deux exemples donnés consiste à démontrer que l’animal est un chat, ou que le patient à la grippe.

2.4.4.b Listes de faits et liste de règles

Les structures de données de la Figure 27 sont décrites ci-dessous, ainsi que les fonc-tions de gestion des faits initiaux et des règles. Le module de gestion de liste est utilisé sans modification pour les listes de faits (faits initiaux, hypothèses, conclusions) et pour la liste des règles. Le champ marque pour une règle est vrai si la règle s’est déjà exécutée ; il est alors inutile de la tester lors des passages suivants. creerRegle() initia-lise une règle à l’aide de son nom, la règle n’ayant aucune hypothèse ni aucune conclu-sion. ajouterFait() ajoute un fait à une liste de faits comme par exemple la liste des faits initiaux, la liste des faits hypothèses ou la liste des faits conclusions. listerFait() et listerLesRegles() sont des parcours de listes.

// systexpert.cpp système expert

#include <stdio.h>

#include <string.h>

#include "liste.h"

typedef char ch3 [3];

char* message (int n); // fournit le libellé du fait n typedef Liste ListeFaits;

typedef Liste ListeRegles;

void ajouterFait (ListeFaits* listF, int n);

void listerFaits (ListeFaits* listF);

ListeFaits* creerListeFaits ();

11

5

10

1

2 Figure 28 Chaînage arrière dans un système expert.

03Chap_02 Page 63 Samedi, 17. janvier 2004 10:36 10

64 2 Les listes

// LES REGLES typedef struct { ch3 nom;

booleen marque;

ListeFaits* hypotheses;

ListeFaits* conclusions;

} Regle;

// constructeur d'une règle à partir de son nom;

// les listes hypothèses et conclusions sont vides Regle* creerRegle (ch3 nom) {

Regle* regle = new Regle();

strcpy (regle->nom, nom);

regle->hypotheses = creerListeFaits();

regle->conclusions = creerListeFaits();

regle->marque = faux;

return regle;

}

// ajouter le fait n aux hypothèses de la règle "regle"

void ajouterHypothese (Regle* regle, int n) { ajouterFait (regle->hypotheses, n);

}

// ajouter le fait n aux conclusions de la règle "regle"

void ajouterConclusion (Regle* regle, int n) { ajouterFait (regle->conclusions, n);

}

// lister la règle "regle"

void listerUneRegle (Regle* regle) { printf ("\nRègle : %s\n", regle->nom);

printf (" hypothèses\n");

listerFaits (regle->hypotheses);

printf (" conclusions\n");

listerFaits (regle->conclusions);

}

liste des hypothèses

liste des conclusions

A B

Figure 29 Détails de l’implémentation d’une règle.

03Chap_02 Page 64 Samedi, 17. janvier 2004 10:36 10

2.4 • Exemples d’application 65

© Dunod – La photocopie non autorisée est un délit.

// lister toutes les règles

void listerLesRegles (ListeRegles* lr) { ouvrirListe (lr);

while (!finListe(lr) ) {

Regle* ptc = (Regle*) objetCourant (lr);

listerUneRegle (ptc);

}

printf ("\n");

}

Figure 30 Détails de l’implémentation d’une liste de faits.

// LES FAITS typedef struct { int numero;

} Fait;

// constructeur de Fait Fait* creerFait (int n) { Fait* nouveau = new Fait();

nouveau->numero = n;

return nouveau;

}

// LES LISTES DE FAITS

ListeFaits* creerListeFaits() { return creerListe();

}

// ajouter le fait n à la liste de faits listF void ajouterFait (ListeFaits* listF, int n) { Fait* nouveau = creerFait (n);

insererEnFinDeListe (listF, nouveau);

}

// lister les faits de la liste listF void listerFaits (ListeFaits* listF) { ouvrirListe (listF);

while (!finListe(listF) ) {

Fait* ptc = (Fait*) objetCourant (listF);

printf (" %s\n", message (ptc->numero));

} }

Remarque : si on veut mémoriser le numéro de l’entier dans le champ refe-rence, plutôt que le pointeur vers l’entier (voir Figure 30), il suffit de remplacer :

/

1 2 3 4 5

03Chap_02 Page 65 Samedi, 17. janvier 2004 10:36 10

66 2 Les listes

Fait* creerFait (int n) {

return (Fait*) n; // n doit être considéré comme un pointeur }

et de remplacer :

ptc->numero par (int)ptc ptc doit être considéré comme un entier Exercice 8 - Systèmes experts : les algorithmes de déduction

• Écrire la fonction : booleen existe (ListeFaits* listF, int num) ; qui indique si le fait num existe dans la liste listF.

• Écrire la fonction : int appliquer (Regle* regle, ListeFaits* listF) ; qui vérifie si la règle pointée par regle s’applique, et ajoute les conclusions de cette règle à la liste de faits listF si les hypothèses de la règle sont vérifiées.

• Écrire la fonction : void chainageAvant (ListeRegles* listR, ListeFaits* listF) ; qui à partir de la liste de faits listF et de la liste des règles listR, ajoute à listF les conclu-sions des règles vérifiées.

• Écrire la fonction récursive : booleen demontrerFait (ListeRegles* listR, ListeFaits*

listF, int num, int nb) ; qui en utilisant la liste de faits listF et la liste des règles listR, démontre le fait num ; nb est utilisé pour faire une indentation (au fil des appels récursifs) comme sur le schéma de la Figure 28.

• Écrire le programme principal qui crée les structures de données de la Figure 27, liste les faits et les règles, effectue le chaînage avant et le chaînage arrière.