Intelligence Artificielle AI - Prolog : TP 1 Faits, Règles et Requêtes
Télécharger PDFIntroduction à Prolog et Programmation Logique
Prolog est un langage de programmation unique, non pour ses capacités techniques, mais parce qu’il illustre une autre approche de la programmation informatique. Né en France (à Marseille), il a servi de fondement aux recherches japonaises sur les ordinateurs de 5ème génération. Ce qui le rend exceptionnel, c’est que Prolog permet de décrire simplement ce que l’on connaît sur un domaine donné (appelé base de connaissances) sans imposer de structure rigide. Ensuite, en définissant le problème, le langage le résout automatiquement, sans qu’il soit nécessaire de préciser la méthode.
Règles sur les constantes et variables symboliques
Un programme Prolog se compose de règles (sous la forme : conclusion si conditions) et de faits (affirmations précisant ce qui est vrai). Le langage manipule des variables simples (entiers, réels, chaînes de caractères) et des listes, mais pas des tableaux.
Les variables simples incluent les entiers, les réels, les chaînes de caractères (entre guillemets) et les constantes symboliques (chaînes sans espaces ni caractères spéciaux, commençant par une minuscule). Les noms de variables commencent obligatoirement par une majuscule, suivis de lettres, chiffres ou underscores (_). Une variable liée (ou instanciée) contient une valeur, tandis qu’une variable libre reste inconnue.
Exemple de programme simple :
est_un_homme(ahmed). /* l’argument est le sujet */
est_un_homme(omar).
est_le_mari_de(ahmed, leila). /* 1er arg: sujet, puis complément */
est_le_père_de(ahmed, omar).
est_un_homme est un prédicat. Il peut être vrai, faux ou inconnu. Toutes les règles concernant un même prédicat doivent être regroupées.
Pour exécuter ce programme sous SWI-Prolog, enregistrez-le dans un fichier texte (ex: nomfic.pl) puis chargez-le via consult(nomfic). (n’oubliez pas l’extension .pl). Les requêtes s’écrivent comme suit :
?- est_un_homme(ahmed). Réponse : Yes
?- est_un_homme(leila). Réponse : No
?- est_un_homme(jawad). Réponse : No
Prolog cherche à prouver la véracité du but demandé. Si une variable libre est présente, il l’instancie avec toutes les valeurs possibles :
?- est_un_homme(X). Réponse : X = ahmed (appuyez sur ; pour la solution suivante)
X = omar
?- est_le_pere_de(Pere, omar). Réponse : Pere = ahmed
?- est_le_mari(Pere, Mere), est_le_père_de(Pere, omar). Réponse : Pere = ahmed, Mere = leila
Combinaison des buts et différences avec les langages procéduraux
Les buts peuvent être combinés avec les opérateurs logiques et (,), ou (;) et non (not). Par exemple, la règle suivante permet de trouver la mère d’un enfant :
est_la_mere_de(Mere, Enfant) :-
est_le_mari(Pere, Mere),
est_le_père_de(Pere, Enfant).
Le but est_la_mere_de(Mere, omar) renvoie Mere = leila. La même règle peut aussi identifier un enfant : est_la_mere_de(leila, X) renvoie X = omar.
Prolog diffère des langages procéduraux classiques car il est déclaratif : on exprime simplement ce que l’on sait, sans préciser comment le résoudre. En revanche, les langages procéduraux imposent une logique de traitement étape par étape.
Exercice : Modélisation d’un arbre généalogique
À partir de l’arbre généalogique donné, définissez les prédicats suivants :
est_un_homme(H) : H est un homme.
est_une_femme(F) : F est une femme.
est_le_mari_de(M, F) : M est le mari de F.
est_le_père_de(P, E) : P est le père de E.
Puis ajoutez les règles pour les nouveaux prédicats :
est_parent_de(P, E) : P est le père ou la mère de E.
est_le_fils(F, P) : P est le parent de F et F est un homme.
est_la_fille(F, P) : P est le parent de F et F est une femme.
est_le_frère(H, Y) : H est le frère de Y.
est_la_soeur(F, Y) : F est la sœur de Y.
gdparent(X, Y) : X est un grand-parent de Y (grand-père ou grand-mère).
est_la_belle_mère(X, Y) : X est la belle-mère de Y (Y peut être un homme ou une femme).
Testez votre programme avec des requêtes pour valider son fonctionnement.
Entrées/Sorties formatées en Prolog
SWI-Prolog propose des prédicats pour afficher des messages ou des valeurs de variables de manière formatée. Le prédicat write/1 permet d’afficher une constante (nombre, atome, chaîne de caractères entre guillemets) ou une variable instanciée.
Exemples :
write(3) : affiche la constante 3.
write(saad) : affiche l’atome constant saad.
write('le prince saad 3') : affiche la chaîne de caractères le prince saad 3.
write(X) : affiche la valeur de la variable X (si elle est instanciée).
Pour des formats avancés, utilisez writef/2 avec des séquences spécifiques. Par exemple :
writef("ceci %t l’%s %t \n et j’affiche X=%t", [est, "exemple numero", 45, X])
Si X = toto, l’affichage sera :
ceci est l’exemple numero 45 et j’affiche X=toto
Exercice : Affichage formaté des relations de parenté
Modifiez votre programme pour obtenir des réponses formatées en langage naturel. Par exemple :
?- est_le_fils(X, ahmed).
Réponse attendue : omar est le fils de ahmed
Programmation récursive en Prolog
La puissance de Prolog repose sur son moteur d’inférence basé sur la résolution de Robinson. Ce mécanisme permet de déduire de nouvelles connaissances à l’aide de prédicats récursifs.
Exemple : la clause suivante définit les amis d’une personne comme les amis de ses amis (avec précaution pour éviter les boucles infinies) :
ami(X, Y) :- ami(X, Z), ami(Y, Z).
Exercice : Prédicat récursif pour les ancêtres
Créez un prédicat ancêtre(X, Y) qui réussit si X est un ancêtre quelconque de Y (parent, grand-parent, arrière-grand-parent, etc.).
Exercice : Prédicat pour vérifier une même famille
Écrivez un prédicat famille(H1, H2) qui réussit si H1 et H2 partagent au moins un ancêtre commun.
FAQ
Comment instancier une variable libre en Prolog ?
Utilisez une requête avec la variable libre (ex: est_un_homme(X)). Prolog liera automatiquement X à toutes les valeurs possibles qui satisfont la condition.
Quelle est la différence entre un prédicat et une constante symbolique ?
Un prédicat est une relation qui peut être vraie, fausse ou inconnue selon les faits et règles définis. Une constante symbolique est un simple identifiant (ex: ahmed) qui ne représente pas une relation.
Pourquoi éviter la récursivité à gauche en Prolog ?
La récursivité à gauche peut entraîner des boucles infinies car Prolog ne peut pas prouver la condition récursive avant d’avoir instancié la variable. Cela bloque l’exécution.