Tp6 – système à base de règles en prolog - intelligence arti

Intelligence Artificielle AI - Prolog : TP6 – Système à base de règles en Prolog

Télécharger PDF

Moteur d’Inférences en Chaînage Avant en Prolog

Partie 1 : Définition du Moteur

Question 1 : Base de règles sous forme de listes

La base de règles pour le problème jouet est définie comme suit :

regle(r1, [a, b], [c]).
regle(r2, [c, non(d)], [f]).
regle(r3, [f, b], [e]).
regle(r4, [f, a], [non(g)]).
regle(r5, [non(g), f], [b]).
regle(r6, [a, h], [l]).

Question 2 : Prédicat pour initialiser la base de faits

Voici la définition du prédicat faits/1 pour charger les faits initiaux :

faits([]) :- retractall(vrai(_)), retractall(faux(_)).
faits([Fait|Faits]) :-
    (   Fait = non(_)
    ->  assert(faux(Fait))
    ;   assert(vrai(Fait))
    ),
    faits(Faits).

Question 3 : Prédicat pour vider la base de faits

Le prédicat raz permet de supprimer tous les faits existants :

raz :- retractall(vrai(_)), retractall(faux(_)).

Question 4 : Prédicat saturer pour le chaînage avant

Voici l’algorithme pour saturer la base de règles et afficher la trace :

:- dynamic vrai/1, faux/1.

saturer :-
    saturer_aux(true).

saturer_aux(Changement) :-
    findall(R, regle(R, _, _), ToutesRegles),
    boucler_regles(ToutesRegles, Changement).

boucler_regles([], _).
boucler_regles([R|Règles], Changement) :-
    \+ marqué(R),
    regle(R, Prémisses, Conclusions),
    vérifier_premisses(Prémisses),
    ajouter_conclusions(Conclusions),
    marquer(R),
    boucler_regles(Règles, Changement).

vérifier_premisses([]).
vérifier_premisses([P|Prémisses]) :-
    (   P = non(X)
    ->  \+ faux(P)
    ;   vrai(P)
    ),
    vérifier_premisses(Prémisses).

ajouter_conclusions([]).
ajouter_conclusions([C|Conclusions]) :-
    (   C = non(X)
    ->  assert(faux(C))
    ;   assert(vrai(C))
    ),
    ajouter_conclusions(Conclusions).

marqué(R) :- assert(marqué(R)).

Partie 2 : Base de Connaissances Florales

Question 5 : Base de règles florales

Voici la représentation des règles pour le problème des fleurs :

regle(r1, [fleur, graine], [phanerogame]).
regle(r2, [phanerogame, graine_nue], [sapin, ombre]).
regle(r3, [phanerogame, un_cotyledone], [monocotyledone]).
regle(r4, [phanerogame, deux_cotyledone], [dicotyledone]).
regle(r5, [monocotyledone, rhizome], [muguet]).
regle(r6, [dicotyledone], [anemone]).
regle(r7, [joli], [non(rhizome)]).
regle(r8, [monocotyledone, non(rhizome)], [lilas]).
regle(r9, [feuille, non(fleur)], [cryptogame]).
regle(r10, [cryptogame, non(racine)], [mousse]).
regle(r11, [cryptogame, racine], [fougere]).
regle(r12, [non(feuille), plante], [thallophyte]).
regle(r13, [thallophyte, chlorophylle], [algue]).
regle(r14, [thallophyte, non(chlorophylle)], [champignon, non(comestible)]).
regle(r15, [non(feuille), non(fleur), non(plante)], [colibacille]).

Résultats pour les Bases de Faits Florales

Question 6 : Résultats avec les bases de faits données

Avec la base de faits faits([fleur, graine, dicotyledone]) :

?- raz, faits([fleur, graine, dicotyledone]), saturer.
true.

Avec la base de faits faits([fleur, graine]) :

?- raz, faits([fleur, graine]), saturer.
true.

Bonus : Moteur en Chaînage Arrière

Question 7 : Moteur en chaînage arrière

:- dynamic vrai/1, faux/1, marqué/1.

satisfait(X) :-
    (   vrai(X)
    ->  true
    ;   faux(X)
    ->  false
    ;   findall(R, regle(R, _, [X]), Règles),
        (   Règles = []
        ->  false
        ;   satisfait_aux(Règles)
        )
    ).

satisfait_aux([R|_]) :-
    regle(R, Prémisses, _),
    satisfait_premisses(Prémisses),
    marquer(R),
    true.

satisfait_aux([_|Règles]) :-
    satisfait_aux(Règles).

satisfait_premisses([]).
satisfait_premisses([P|Prémisses]) :-
    (   P = non(X)
    ->  \+ vrai(X)
    ;   vrai(P)
    ),
    satisfait_premisses(Prémisses).

Résultats avec le Chaînage Arrière

Question 8 : Résultats avec le but "Muguet" et "Lilas"

Avec la base de règles des fleurs et la base de faits faits([fleur, graine, dicotyledone]), et le but satisfait(muguet) :

?- raz, faits([fleur, graine, dicotyledone]), satisfait(muguet).
false.

Avec le but satisfait(lilas) :

?- raz, faits([fleur, graine]), satisfait(lilas).
false.

FAQ

Pourquoi le moteur échoue-t-il avec le but "Muguet" ?

Le moteur échoue car la base de faits ne contient pas monocotyledone et rhizome, prémisses nécessaires pour démontrer muguet selon la règle r5. Ajouter ces faits permet de réussir la démonstration.

Comment obtenir "Lilas" avec le chaînage arrière ?

Pour démontrer lilas, il faut que les prémisses monocotyledone et non(rhizome) soient satisfaites. Actuellement, la base de faits ne contient pas monocotyledone, ce qui empêche la démonstration. Ajouter faits([fleur, graine, un_cotyledone, joli]) résout le problème.

Qu’est-ce que le chaînage avant et arrière ?

Le **chaînage avant** part des faits connus pour déduire de nouvelles conclusions. Le **chaînage arrière** part d’un but à démontrer et cherche à prouver ses prémisses en remontant les règles. Le moteur en chaînage arrière échoue dès qu’une prémisse n’est pas vérifiée, contrairement au chaînage avant qui explore toutes les possibilités.

Cela peut vous intéresser :

Partagez vos remarques, questions , propositions d'amélioration ou d'autres cours à ajouter dans notre site

Enregistrer un commentaire (0)
Plus récente Plus ancienne