Académique Documents
Professionnel Documents
Culture Documents
Prolog
18/05/2023 A. ELKARI 1
Objectifs
• Présenter les bases de la programmation
déclarative à travers l’utilisation du
langage Prolog.
18/05/2023 A. ELKARI 2
Prérequis
• Pour bien comprendre cette séquence sur
Prolog, il est conseillé d’avoir étudier au
préalable la séquence Logique.
• Pour faire tourner vos programmes
Prolog, vous devez installer un
environnement de développement en
Prolog sur votre machine. Nous
utiliserons GNU-Prolog, qui est libre et
tourne sur de nombreuses plate-formes.
18/05/2023 A. ELKARI 3
Plan général
• Chapitre 1 - Introduction, premiers
exemples et syntaxe.
• Chapitre 2- Sémantique opérationnelle,
unification et sémantique déclarative
• Chapitre 3- L’environnement GNU-Prolog
et quelques prédicats prédéfinis
• Chapitre 4- Programmation en Prolog : les
exemples de base
18/05/2023 A. ELKARI 4
Chapitre I
Introduction
premiers exemples
et
syntaxe
18/05/2023 A. ELKARI 5
Introduction
• Prolog (PROgrammation LOGique) est un
langage de l’Intelligence Artificielle (IA)
qui a été inventé à Marseille en 1972. Conçu
à l’origine pour des applications du
traitement automatique du langage naturel
et des grammaires formels, il a ensuite été
utilisé dans de nombreux domaines de l’IA
et a été au cœur du projet d’ « ordinateurs
de la cinquième génération » du ministère
de l’industrie japonais dans les années 80.
18/05/2023 A. ELKARI 6
• Les applications de Prolog en Intelligence
Artificielle concernent le domaine des systèmes
experts, du traitement automatique du langage
naturel, la planification, etc.
18/05/2023 A. ELKARI 7
• Une implémentation efficace de Prolog
basée sur une autre syntaxe (dite syntaxe
Edinbourg) a été développée vers la fin
des années 70 par David Warren. Cette
version de Prolog a eu une diffusion
supérieure et est davantage utilisée de
nos jours. Elle a donné naissance à
plusieurs versions du langage (entre
autres, SWI-Prolog, SICStus Prolog,
Visual Prolog), pouvant différer sur
quelques points tels que le fait de
permettre ou pas la programmation sous
contraintes.
18/05/2023 A. ELKARI 8
• La version que nous utiliserons comme
support de ce cours est le GNU-Prolog
(créé par Daniel Diaz :
http://pauillac.inria.fr/~diaz/ ) qui a
l’avantage de faire l’objet de
développements qui tournent sous des
environnements divers et de permettre
de faire de la programmation sous
contraintes (GNU-Prolog intègre un
solveur de contraintes sur domaine fini
18/05/2023 A. ELKARI 9
Prolog diffère des autres langages par ses principales
caractéristiques :
• C’est un langage déclaratif : écrire un programme revient à
décrire un ensemble de connaissances décomposées sous la
forme d’un ensemble de faits et d’un ensemble de règles
décrivant des relations entre des objets.
• C’est un langage qui raisonne : faire tourner un programme
Prolog revient à lui poser des questions auxquelles il va
répondre en utilisant les connaissances contenues dans le
programme. Pour faire cela, Prolog utilise son « cerveau »,
un moteur d’inférences basé sur le Principe de Résolution
de Robinson.
• C’est un langage non-déterministe, c’est à dire qu’il va
chercher systématiquement toutes les réponses à une
question.
18/05/2023 A. ELKARI 10
1 - Premiers exemples
La programmation en Prolog est basée sur 3 types
d’objets : les faits, les règles et les questions.
• 1.1 - Faits
Voici un exemple de programme Prolog :
Programme menu1 :
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomates).
viande(bœuf).
viande(poulet).
poisson(bar).
poisson(sardine).
dessert(fruit).
dessert(glace).
18/05/2023 A. ELKARI 11
Ce programme ne contient que des faits.
Chaque ligne représente un fait et est
indépendante des autres.
Un fait est constitué d’un prédicat (par
exemple hors_d_oeuvre) et de ses arguments
(0, 1 ou plusieurs - ici par exemple la constante
artichauts), suivi d’un point. L’interprétation
intuitive du fait hors_d_oeuvre(artichauts) est
‘la constante artichauts vérifie la relation
unaire hors_d_oeuvre’.
• Les faits d’un programme sont reliés par
définition par des et. Ce programme dit donc
que la constante artichauts vérifie la relation
unaire hors_d_oeuvre et que la constante
tomates aussi.
18/05/2023 A. ELKARI 12
1.2 – Questions
Faire tourner un programme Prolog revient à lui poser des
questions. Voilà le genre de question que l’on peut poser au
programme 1 et les réponses que Prolog donnera.
18/05/2023 A. ELKARI 14
1.3 - Règles
On peut compléter le programme menu1 avec les règles suivantes :
plat(X) :- viande(X).
plat(X) :- poisson(X).
Chaque ligne contient une règle. Une règle est formée d’une tête
(avant le symbole :- ) et d’une partie droite ou queue (après le
symbole :- ). La tête est formée d’un prédicat et ses arguments, la
partie droite, d’un ou plusieurs prédicats avec leurs arguments
séparés par des virgules. La règle se termine par un point. X désigne
une variable comme dans la question ci-dessus. A l’intérieur d’une
règle, le même symbole (X) désigne la même variable. Par contre, le X
de la première règle et le X de la deuxième ne désignent pas la même
variable (comme deux variables portant le même nom dans deux
formules logiques. Ces deux règles sont donc équivalentes aux deux
suivantes : plat(X) :- viande(X).
plat(Y) :- poisson(Y).
18/05/2023 A. ELKARI 15
L’interprétation intuitive de la première
règle est ‘X est un plat si X est une viande’,
ou bien (ce qui est équivalent) ‘si X est une
viande alors X est un plat’. L’ensemble des
faits et des règles d’un programme Prolog
sont reliés par des ‘et ‘. La combinaison des
deux règles donne donc ‘X est un plat si X
est une viande’ et ‘X est un plat si X est un
poisson’, i.e, ‘X est un plat si X est une
viande ou un poisson’.
18/05/2023 A. ELKARI 16
En utilisant ces règles et les faits ci-dessus, on peut
obtenir des réponses aux questions suivantes :
18/05/2023 A. ELKARI 17
Remarques :
• Le fait que le bœuf est un plat n’est pas un fait
du programme Prolog mais cela est déductible
en utilisant la règle ‘si X est une viande alors X
est un plat’ et le fait ‘le bœuf est une viande’.
On voit ici les effets du raisonnement de
Prolog. Si une question contient plusieurs fois le
même symbole de variables (par exemple X),
c’est alors la même variable. Par exemple, la
question
|?- hors_d_oeuvre(X), poisson(X).
est équivalente à « quels sont les objets X qui
sont des hors d’œuvre et des poissons ? ». Ici,
Prolog répondra aucun.
18/05/2023 A. ELKARI 18
2 - Un peu de syntaxe
Les objets manipulés par un programme Prolog sont des
variables, des constantes ou des termes structurés dont
nous verrons plus loin la syntaxe.
• Variables : Une variable est représentée par une chaîne
alphanumérique commençant obligatoirement par une
majuscule ou par _.
Exemple : X, Var_11, _jour.
Le symbole _ seul représente une variable muette, i.e.
dont on ne souhaite pas connaître la valeur.
• Les constantes sont des nombres (entiers ou réels), des
chaînes de caractères entre guillemets ou des
identificateurs.
• Un identificateur est une chaîne alphanumérique
commençant obligatoirement par une lettre minuscule.
18/05/2023 A. ELKARI 19
• Un atome est constitué d’une relation (un
identificateur) suivie de ses arguments
(variables, constantes ou termes structurés)
entre parenthèses. Par exemple, plat(X),
père_de(jean, marc), etc..
• Un fait est constitué d’un atome suivi d’un point.
• Une règle est constituée d’un membre gauche qui
est un atome, suivi du symbole :- suivi d’une suite
de atomes.
Nous verrons plus loin la syntaxe des atomes
structurés.
18/05/2023 A. ELKARI 20
Partie exercices
• Exercice 1
• Compléter le tableau suivant en utilisant le programme menu du
cours.
18/05/2023 A. ELKARI 21
Partie exercices
• Exercice 2
Trouver 5 questions que l’on peut poser au
programme Menu en français et traduisez-les en
Prolog. Donnez également les réponses en français
et en Prolog.
• Exercice 3
Complétez le programme Menu en ajoutant des faits
décrivant l’ensemble de connaissances suivant :
l’omelette est un plat à base d’œufs et les oeufs au
plat aussi. Et en ajoutant une règle disant que les
plats à base d’œufs sont des plats.
18/05/2023 A. ELKARI 22
Chapitre II
Sémantique opérationnelle,
unification et sémantique
déclarative
18/05/2023 A. ELKARI 23
1 - Sémantique de Prolog
Prolog est un langage de la « programmation logique »
dont l’objectif est de considérer des ensembles de
formules comme des programmes et des procédures
de preuve sur ces formules comme l’exécution de ces
programmes. De ce point de vue, un programme Prolog
est équivalent à un ensemble de formules. En effet,
• un fait Prolog A. affirme une proposition comme vraie,
et est équivalent à la formule atomique A
• une règle Prolog A :- B1, B2, …, Bn signifie A est vraie
si B1 et B2 et…et Bn sont vraies, ce qui équivaut à
l’implication logique B1 et B2 et … Bn -> A.
18/05/2023 A. ELKARI 24
Les variables apparaissant dans un fait ou une
règle Prolog représentent des variables
logiques quantifiées universellement.
18/05/2023 A. ELKARI 25
Remarque
Ces formules ont une forme particulière
: en effet, soit ce sont des atomes, soit
ce sont des implications dont le membre
droit est toujours réduit à un atome.
18/05/2023 A. ELKARI 26
Remarques
1. Une question Prolog est équivalente à une
conjonction de formules atomiques. Si la
question comporte des variables, elles peuvent
être considérées comme quantifiées
existentiellement.
2. La question plat(X). a alors pour sens « existe-
t-il des X tels que plat(X) ? »
3. Poser une question à un programme Prolog
revient à demander à Prolog si l’ensemble de
formules F équivalent au programme démontre
la formule f équivalente à la question.
18/05/2023 A. ELKARI 27
Pour faire, il y a pour cela plusieurs méthodes possibles :
• soit on produit toutes les formules atomiques
démontrables à partir de F et on regarde si f appartient à
cet ensemble. Cette méthode est dite ascendante ou par
chaînage avant. Le problème est qu’elle est trop coûteuse,
voir infinie et n’est donc pas utilisée.
18/05/2023 A. ELKARI 28
2 - Prolog et le principe de Robinson
18/05/2023 A. ELKARI 29
Principe de résolution en logique des
propositions
Système de preuves par résolution
Le principe de résolution est une méthode automatique
pour montrer la validité d'une formule. Nous allons
voir les notions de clauses et de résolvant avant
d'aborder le principe de résolution.
Rappel
• Une clause est une fbf qui a la forme d'une
disjonction de littéraux
Cas particulier : un littéral isolé est une clause.
Exemple de clauses :
A B C D CLAUSE
D CLAUSE
18/05/2023 A. ELKARI 30
Clause résolvante
Si C1 et C2 sont 2 clauses et si L1 = L2 et L1 est dans C1 et L2
est dans C2.
C est la disjonction des clauses restantes après suppression des
littéraux L1 etL2.
Elle est appelée clause résolvante et ou résolvant de C1 et de C2.
L1 et L2 sont les littéraux résolus.
Exemples :
Soient C1 et C2 les deux clauses suivantes :
C1 : E1 E2, C2 : E2 E3
Le résolvant de C1 et de C2 est C : E1 E3
Soient C1 et C2 les deux clauses suivantes :
C1 : P, C2 : P
Le résolvant de C1 et de C2 est C : Ø la clause vide
Le résolvant C de deux clauses C1 et C2 est une conséquence logique
de C1 et de C2
18/05/2023 A. ELKARI 31
Exercice 1
18/05/2023 A. ELKARI 32
Algorithme de résolution
Début
Ecrire la négation de F ;
Mettre F sous forme d'un ensemble de clauses ;
Tant que la clause vide n'est pas rencontrée et qu'il existe des paires
réductibles faire
Début
Chercher des clauses résolvantes ;
Ajouter ce résultat à la liste des clauses ;
Fin tant que ;
Si on trouve la clause vide alors F est valide
sinon F est invalide
Finsi ;
Fin ;
18/05/2023 A. ELKARI 33
Exemple
Soit SF ={P Q R, R , P, T Q , T}
C1 C2 C3 C4 C5
SF est l'ensemble des clauses d'une fbf F.
Montrons que cet ensemble est insatisfiable
C1 = P Q R C6 = P Q
C2 = R
C6 = P Q C7 = Q
C3 = P
C7 = Q C8 = T
C4 = T Q
C8 = T C9 = Ø
C5 = T
A partir de l'ensemble des clauses de la fbf F on a déduit la
clause vide donc on peut conclure que F est insatisfiable et donc
que F est valide.
18/05/2023 A. ELKARI 34
L’idée est donc de démontrer que l’ensemble de
formules F issu du programme Prolog démontre la
formule f issue de la question, en démontrant que
l’ensemble de formules F non(f) est inconsistant et
donc qu’on peut produire la résolvante vide.
18/05/2023 A. ELKARI 36
Appliquer le Principe de Résolution de Robinson de la
manière suivante :
18/05/2023 A. ELKARI 37
Exemple :
• Soit le programme P :
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomates).
viande(boeuf).
viande(poulet).
poisson(bar).
poisson(sardine).
dessert(fruit).
dessert(glace).
plat(X) :- viande(X).
plat(X) :- poisson(X).
18/05/2023 A. ELKARI 38
Formule Fp équivalente à P :
hors_d_oeuvre(artichauts)
hors_d_oeuvre(tomates)
viande(boeuf)
viande(poulet)
poisson(bar)
poisson(sardine)
dessert(fruit)
dessert(glace)
18/05/2023 A. ELKARI 39
Ensemble de clauses Cp équivalent à Fp :
{hors_d_oeuvre(artichauts),
hors_d_oeuvre(tomates),
viande(boeuf),
viande(poulet),
poisson(bar),
poisson(sardine),
dessert(fruit),
dessert(glace),
non(viande(x)) ou plat(x),
non(poisson(y)) ou plat(y) }
18/05/2023 A. ELKARI 40
Soit la question Q :
| ?- hors_d-oeuvre(Z).
Formule équivalente à Q :
$z hors_d_oeuvre(z).
Pour montrer que P démontre Q, on montre
que Fpnon(Fq) est insatisfiable.
Non(Fq) : "z non(hors_d_oeuvre(z))
18/05/2023 A. ELKARI 41
Ensemble de clauses Cq équivalent à non(Fq) :
{non(hors_d_oeuvre(z)) }
1. résolvante produite : résolvante vide en
unifiant z=artichauts. Donc Cq est vide et
c’est un succès.
2. résolvante produite : résolvante vide en
unifiant z=tomates. Donc Cq est vide est
c’est un succès.
Plus de résolvante possible, fin de l’exécution
du programme.
18/05/2023 A. ELKARI 42
Autre question :
|?- plat(Z).
Formule Fq équivalente à Q
$z plat(z).
non(Fq) : "z non(plat(z))
Ensemble de clauses Cq équivalent à non(Fq) :
{non(plat(z))}
1. résolvante produite : non(viande(x)) en unifiant z=x.
Donc Cq={non(viande(x))}
1. résolvante produite : résolvante vide en unifiant x=boeuf.
Donc Cq est vide et Prolog donne comme solution Z=boeuf
2. résolvante produite (remise en question du dernier choix):
résolvante vide en unifiant x=poulet. Donc Cq est vide et
Prolog donne comme solution Z=poulet
18/05/2023 A. ELKARI 43
2. résolvante produite : non(poisson(x)) en
unifiant z=x. Donc Cq={non(poisson(x))}
1. résolvante produite : résolvante vide en unifiant
x=bar. Donc Cq est vide et Prolog donne comme
solution Z=bar
2. résolvante produite (remise en question du dernier
choix): résolvante vide en unifiant x=sardine. Donc
Cq est vide et Prolog donne comme solution
Z=sardine
Cette question produit donc 4 réponses,
correspondant aux 4 constantes vérifiant la
propriété plat.
18/05/2023 A. ELKARI 44
3 - Prolog et l'effacement
18/05/2023 A. ELKARI 45
Utiliser le système de réécriture de la manière
suivante :
1. Essayer d’unifier le premier fait q de Fq et une
tête de règle de P en essayant les règles de P
dans l’ordre.
2. Si ce n’est pas possible, échec
3. Si c’est possible, remplacer, dans Fq, q par la
partie droite de la règle, en conservant l’ordre
et en effectuant les substitutions provenant de
l’unification de q avec la tête de la règle
utilisée, puis recommencer en 1.
18/05/2023 A. ELKARI 46
4. Si l’ensemble Fq est vide, cela veut dire que
tous les faits provenant de la réécriture des
faits de la question ont été effacés. On a donc
un succès. Si la question comportait des
variables, les unifications réduites concernant
ces variables sont données comme résultat.
18/05/2023 A. ELKARI 47
Reprenons le même exemple que précédemment :
Soit le programme P :
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomates).
viande(boeuf).
viande(poulet).
poisson(bar).
poisson(sardine).
dessert(fruit).
dessert(glace).
plat(X) :- viande(X).
plat(X) :- poisson(X).
18/05/2023 A. ELKARI 48
Soit la question Q : | ?- hors_d_œuvre(Z).
Fq={ hors_d_œuvre(Z)}
1. hors_d_œuvre(Z) s’unifie avec
hors_d_œuvre(artichauts) (en unifiant Z=artichauts)
qui se réécrit en vide, donc hors_d_œuvre(Z) s’efface
et Z=artichauts est la première solution.
Backtracking sur l’effacement de hors_d_œuvre(Z).
2. hors_d_œuvre(Z) s’unifie avec hors_d_œuvre(tomate)
(en unifiant Z=tomate) qui se réécrit en vide, donc
hors_d_œuvre(Z) s’efface et Z=tomate est la
deuxième solution
18/05/2023 A. ELKARI 49
Soit la question Q : | ?- plat(Z).
Fq={plat(Z)}
1. plat(Z) s’unifie avec la tête de règle plat(X) (en unifiant Z=X) qui
se réécrit en viande(X).
Reste à effacer viande(X)
1. viande(X) s’unifie avec viande(boeuf) (en unifiant X=boeuf) qui se
réécrit en vide. Donc succès, Prolog affiche la première réponse en
réduisant l’ensemble d’unification Z=X et X=boeuf à Z=boeuf.
Backtracking sur l’effacement de viande(X).
2. viande(X) s’unifie avec viande(poulet) (en unifiant X=poulet) qui
se réécrit en vide. Donc, succès, Prolog affiche la deuxième
réponse en réduisant l’ensemble d’unification Z=X et X=poulet
à Z=poulet.
Plus de backtracking sur l’effacement de viande(X).
Backtracking sur l’effacement de plat(Z).
18/05/2023 A. ELKARI 50
2. plat(Z) s’unifie avec la tête de règle plat(X) (en
unifiant Z=X) qui se réécrit en poisson(X).
Reste à effacer poisson(X)
1. poisson(X) s’unifie avec poisson(bar) (en unifiant X=bar) qui se
réécrit en vide. Donc succès, Prolog affiche la troisième
réponse en réduisant l’ensemble d’unification Z=X et X=bar à
Z=bar.
Backtracking sur l’effacement de poisson(X).
2. poisson(X) s’unifie avec poisson(sardine) (en unifiant
X=sardine) qui se réécrit en vide. Donc, succès, Prolog affiche
la quatrième réponse en réduisant l’ensemble d’unification Z=X
et X=sardine à Z=sardine.
Plus de backtracking sur l’effacement de poisson(X).
Plus de backtracking sur l’effacement de plat(X).
Fin de l’exécution du programme.
18/05/2023 A. ELKARI 51
2. Représentation arborescente de l’effacement
18/05/2023 A. ELKARI 52
Conclusion
Quelles connaissances peut-on représenter
directement par des règles en Prolog ?
toutes celles que l’on peut mettre sous la forme
d’un ensemble de faits atomiques et d’implications
du type : a et b et … et z f
Conséquences :
Si on veut représenter des OU :
- Des OU entre des faits: impossible
- Des OU dans la prémisse d’une implication : c’est
possible car a v b c est une formule équivalente
à (a c) ET (b c). Donc, on écrit 2 règles
Prolog ayant le même membre gauche (la même
tête).
- Des OU dans la conclusion d’une implication :
impossible
18/05/2023 A. ELKARI 53
Si on veut représenter des NON :
- Des NON de fait : impossible en tant que
tel. On remarque cependant qu’en Prolog,
tout ce qui n’est pas dit est considéré
comme faux. C’est une manière d’exprimer
des connaissances négatives.
18/05/2023 A. ELKARI 54
Exercices
Le but de cet exercice est de vous faire utiliser les
2 points de vue introduits plus haut (Principe de
Résolution de Robinson et effacement) pour faire
tourner le programme suivant :
pere_de(jean, paul).
pere_de(marc, jean).
pere_de(marc, jacques).
homme(jean).
homme(paul).
homme(marc).
homme(jacques).
frere_de(X, Y) :- pere_de(Z,X), pere_de(Z,Y), homme(X).
grand_pere(X,Z) :- pere_de(X,Y), pere_de(Y,Z).
18/05/2023 A. ELKARI 55
On pose à ce programme la question :
| ?- frere_de(jean, jacques).
1. Prolog et le Principe de Résolution de
Robinson.
Traduisez ce programme en un ensemble de
clauses et montrer les unifications faites
pour produire des résolvantes vides à partir
de la négation de la question.
2. Prolog et l’effacement.
Dessinez l’arbre d’effacement
18/05/2023 A. ELKARI 56
Chapitre 3
L'environnement GNU-Prolog et
quelques prédicats prédéfinis
18/05/2023 A. ELKARI 57
Introduction
Cette session a pour but de vous
familiariser avec l’environnement GNU-
Prolog. Cet environnement a été développé
par Daniel Diaz
(http://pauillac.inria.fr/~diaz/) Vous
trouverez des informations sur GNU-
Prolog à cette adresse
http://gnuprolog.inria.fr/ ainsi que des
sources téléchargeables selon la plate-
forme que vous utilisez.
18/05/2023 A. ELKARI 58
1 - Manipulations de base
Le principe de base de l’utilisation de
l’interpréteur est d’insérer un programme dans
l’environnement, par exemple en le tapant
directement à partir du terminal Prolog, puis de
l’interroger à partir du terminal.
Exemple 1
GNU Prolog 1.2.16
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- consult(user).
compiling user for byte code...
18/05/2023 A. ELKARI 59
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomate).
viande(boeuf).
viande(poulet).
poisson(bar).
poisson(sardine).
dessert(fruit).
dessert(glace).
user compiled, 8 lines read - 791 bytes written, 57600
ms
(20 ms) yes
| ?- hors_d_oeuvre(artichauts).
yes
| ?- hors_d_oeuvre(radis).
no
| ?-
18/05/2023 A. ELKARI 60
Commentaires :
18/05/2023 A. ELKARI 61
Le programme menu est tapé puis la séquence ctrl-d
est tapée pour indiquer la fin de la consultation. Un
message de Prolog indique que tout s’est bien passé au
niveau de la compilation et que le programme a été
chargé. On peut maintenant interroger ce programme.
La première question posée
(hors_d_oeuvre(artichauts). ) reçoit une réponse
positive (yes). La deuxième reçoit une réponse
négative (no), aucune information dans ce programme
ne permettant de savoir que le radis est un hors
d’œuvre.
18/05/2023 A. ELKARI 62
Exemple 2
| ?- hors_d_oeuvre(X).
X = artichauts ? ;
X = tomates
yes
| ?- hors_d_oeuvre(X).
X = artichauts
yes
| ?-
18/05/2023 A. ELKARI 63
Commentaires :
18/05/2023 A. ELKARI 64
Exemple 3
L’utilisateur peut à tout instant ajouter de
nouveaux faits ou de nouvelles règles dans la
mémoire de l’environnement en relançant une
consultation. Le programme déjà présent en
mémoire est complété sauf si un fait ou une règle
concernant un prédicat déjà présent en mémoire
est ajouté : la nouvelle définition du prédicat
remplace alors l’ancienne. L’utilisateur peut savoir
à tout instant quel est l’état de la mémoire en
tapant la question | ?-listing. (pour voir tout
le programme présent en mémoire) ou bien | ?-
listing(viande). pour voir tous les faits et
règles ayant pour prédicat de tête viande.
18/05/2023 A. ELKARI 65
%gprolog
GNU Prolog 1.2.13
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- consult(user).
compiling user for byte code...
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomate).
viande(boeuf).
viande(poulet).
poisson(bar).
poisson(sardine).
dessert(fruit).
dessert(glace).
18/05/2023 A. ELKARI 66
| ?- viande(X).
X = boeuf ? ;
X = poulet
yes
| ?- consult(user).
compiling user for byte code...
plat(X):-viande(X).
plat(X):-poisson(X).
18/05/2023 A. ELKARI 67
| ?- listing.
viande(boeuf).
viande(poulet).
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomate).
dessert(fruit).
dessert(glace).
poisson(bar).
poisson(sardine).
plat(A) :- viande(A).
plat(A) :- poisson(A).
yes
18/05/2023 A. ELKARI 68
| ?- plat(X).
X = boeuf ? ;
X = poulet ? ;
X = bar ? ;
X = sardine
yes
18/05/2023 A. ELKARI 69
| ?- consult(user).
compiling user for byte code...
viande(agneau)
user compiled, 2 lines read - 230 bytes
written, 13178 ms
(10 ms) yes
| ?- listing(viande).
viande(agneau).
Yes
| ?- plat(X).
X = agneau ? ;
X = bar ? ;
X = sardine
yes
18/05/2023 A. ELKARI 70
Commentaires :
18/05/2023 A. ELKARI 71
Exemple 4
Certains prédicats prédéfinis permettent
d’ajouter ou de supprimer des règles ou des faits
se trouvant en mémoire, à condition que ceux-ci
aient été déclarés comme étant dynamique. Ceci
se fait par l’utilisation de la directive dynamic
suivi entre parenthèse du nom du prédicat et son
arité. Ensuite, les prédicats asserta, retract,
retractall et abolish permettent d’ajouter ou de
modifier un programme, soit en les utilisant en
mode interactif, soit en les appelant dans un
programme
18/05/2023 A. ELKARI 72
% gprolog
GNU Prolog 1.2.13
By Daniel Diaz
Copyright (C) 1999-2002 Daniel Diaz
| ?- consult(user).
compiling user for byte code...
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomate).
:-dynamic(viande/1).
viande(boeuf).
viande(poulet).
:-dynamic(poisson/1).
poisson(bar).
poisson(sardine).
dessert(fruit).
dessert(glace).
18/05/2023 A. ELKARI 73
| ?- listing.
viande(boeuf).
viande(poulet).
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomate).
dessert(fruit).
dessert(glace).
poisson(bar).
poisson(sardine).
18/05/2023 A. ELKARI 74
| ?- asserta(viande(mouton)).
yes
| ?- listing(viande).
viande(mouton).
viande(boeuf).
viande(poulet).
yes
| ?- retract(viande(poulet)).
yes
| ?- listing(viande).
viande(mouton).
viande(boeuf).
18/05/2023 A. ELKARI 75
| ?- retractall(viande(X)).
yes
| ?- listing.
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomate).
dessert(fruit).
dessert(glace).
poisson(bar).
poisson(sardine).
18/05/2023 A. ELKARI 76
| ?- abolish(poisson/1).
yes
| ?- listing.
hors_d_oeuvre(artichauts).
hors_d_oeuvre(tomate).
dessert(fruit).
dessert(glace).
yes
| ?- viande(X).
no
| ?- poisson(X).
uncaught exception:
error(existence_error(procedure,poisson/1),top_level/0
)
| ?-
18/05/2023 A. ELKARI 77
Commentaires :
18/05/2023 A. ELKARI 78
et enfin | ?- abolish(poisson/1). supprime tous les
faits ou règles concernant le prédicat poisson à 1
argument. Les deux questions qui suivent vous
montrent que le comportement du prédicat
retractall et abolish n’est pas tout à fait le
même, puisque dans un cas (suppression avec
retractall), le prédicat viande est toujours connu
de Prolog bien que plus aucun fait ou règle du
programme ne le mentionne, et lorsqu’on pose
la question | ?- viande(X)., la réponse de Prolog
est no.
18/05/2023 A. ELKARI 79
Dans le deuxième cas (suppression avec abolish),
Prolog ne connaît plus du tout le prédicat poisson
et une erreur est affichée. Si ces prédicats sont
utilisés dans un programme, le comportement de
ce programme peut donc être totalement
différent si les faits ou règles supprimés sont
ensuite à nouveau consultés.
Pour finir, quittez l’environnement Prolog en tapant
la question | ?- halt.
18/05/2023 A. ELKARI 80
Chapitre 4
Programmation en Prolog:
les exemples de base
18/05/2023 A. ELKARI 81
1 - Programmation d'exemples simples
18/05/2023 A. ELKARI 82
Exemple :
On veut décrire le catalogue d’une agence
immobilière concernant les villas à la vente.
Chaque produit est décrit par :
- sa superficie
- son nombre de pièces
- son prix
- la présence ou non d’un jardin
- un identifiant permettant de le désigner de
manière unique.
18/05/2023 A. ELKARI 83
On veut décrire l’ensemble du catalogue par des
faits Prolog. Une solution consiste à écrire un
fait par produit, chaque fait regroupant
l’ensemble des informations disponibles pour le
produit.
Exemple :
produit( 60, 3, 100000, oui, pro101).
produit( 75, 4, 150000, non, pro102).
Etc.
18/05/2023 A. ELKARI 84
Une autre solution consiste à séparer les informations
dans plusieurs faits décrivant chacun une partie de
l’information, le lien étant fait par l’identifiant du produit.
Exemple :
superficie(pro101, 60).
superficie(pro102, 75).
nombre_piece(pro101, 3).
nombre_piece(pro102,4).
prix(pro101, 100000).
prix(pro102, 150000).
possede_jardin(pro101,oui).
possede_jardin(pro102,non).
18/05/2023 A. ELKARI 85
Une règle produit peut alors faire la fusion entre
ces différents prédicats pour reproduire les
faits de la première solution :
produit(S, N, P, J, I ) :-
superficie(I,S), nombre_piece(I,N),
prix(I,P) , possede_jardin(I,J).
Il n’y a pas de « meilleure » solution. Comme lorsque
l’on développe une base de données, on peut
décider de tout mettre dans la même table ou
bien dans des tables séparées. Ce choix dépend
essentiellement de l’utilisation qu’on fait ensuite
des informations stockées.
18/05/2023 A. ELKARI 86
On peut par ailleurs décrire les demandes des
clients selon le même principe :
recherche(60, 3, 100000, oui, cl1).
Ce fait indique que le client dont l’identifiant est
cl1 cherche une maison de 60m2, ayant 3 pièces,
coûtant 100000 euros et ayant un jardin.
18/05/2023 A. ELKARI 87
On veut ensuite interroger cette base de faits pour mettre
en relation les clients et les biens correspondant à leur
recherche. Une première solution consiste à interroger
directement les faits par une question Prolog du type :
| ?-recherche(S,N,P,J,cl1),produit(S,N,P,J,X).
Cette question permettra de connaître les identifiants X de
tous les produits correspondant à la recherche du client
dont l’identifiant est cl1. L’utilisation des mêmes variables
dans les appels au prédicat produit et au prédicat
recherche va forcer les valeurs à être unifiables, donc
identiques.
18/05/2023 A. ELKARI 88
18/05/2023 A. ELKARI 89
Mais, en répondant à cette question, Prolog affichera
également la valeur de toutes les autres variables de la
question : superficie, nombre de pièce etc., ce qui peut ne
pas correspondre à l’attente de la personne qui interroge.
Une autre solution consiste à écrire alors une règle
convient(X,Y) qui met en relation les produits X qui
conviennent aux clients Y.
convient(X, Y) :- produit(S, N, P, J, X ) ,
recherche(S, N, P, J, Y).
La question | ?- convient(X, cl1) permettra de ne connaître
que les identifiants X des produits qui conviennent au
client cl1, sans avoir tout le détail de leur descriptif.
18/05/2023 A. ELKARI 90
18/05/2023 A. ELKARI 91
Une solution plus « réaliste » consiste à permettre au
client de décrire sa recherche de manière plus souple, en
indiquant par exemple, non pas la superficie exacte, mais
une superficie minimum, non pas le nombre de pièces exact
mais un nombre minimum, et enfin, non pas un prix exact
mais un prix maximum. De même, un critère laissé variable
indique que le client est indifférent par rapport à ce
critère.
Par exemple, le fait :
recherche(60, 3, 200000,_, cl2).
peut être interprété comme : le client cl2 recherche un
produit ayant une superficie minimum de 60 m2, un nombre
de pièces minimum de 3, un prix maximum de 200000
euros, et avec ou sans jardin (la variable I pouvant
s’unifier avec la constante oui ou la constante non).
18/05/2023 A. ELKARI 92
Dans la règle convient(X,Y), il faut maintenant vérifier non
pas que les valeurs sont identiques dans le produit et dans
la recherche, mais que les valeurs apparaissant dans le
produit vérifient les contraintes imposées dans la
recherche.
convient(X,Y):- produit(S1, N1, P1, J, X ),
recherche(S, N, P, J, Y), S1 @>= S, N1@>=
N,P@>= P1.
L’opérateur utilisé ici (@>=) est un prédicat prédéfini de
Gnu-Prolog. Nous le présentons ainsi que d’autres dans le
chapitre suivant.
18/05/2023 A. ELKARI 93
18/05/2023 A. ELKARI 94
38 ?- trace.
Yes
[trace] 38 ?- convient(X, cl2).
Call: (7) convient(_G471, cl2) ? creep
Call: (8) produit(_L187, _L188, _L189, _L190, _G471) ? creep
Call: (9) superficie(_G471, _L187) ? creep
Exit: (9) superficie(pro101, 60) ? creep
Call: (9) nombre_piece(pro101, _L188) ? creep
Exit: (9) nombre_piece(pro101, 3) ? creep
Call: (9) prix(pro101, _L189) ? creep
Exit: (9) prix(pro101, 100000) ? creep
Call: (9) possede_jardin(pro101, _L190) ? creep
Exit: (9) possede_jardin(pro101, oui) ? creep
Exit: (8) produit(60, 3, 100000, oui, pro101) ? creep
Call: (8) recherche(_L191, _L192, _L193, oui, cl2) ? creep
Exit: (8) recherche(60, 3, 200000, oui, cl2) ? creep
Call: (8) 60@>=60 ? creep
Exit: (8) 60@>=60 ? creep
Call: (8) 3@>=3 ? creep
Exit: (8) 3@>=3 ? creep
Call: (8) 200000@>=100000 ? creep
Exit: (8) 200000@>=100000 ? creep
Exit: (7) convient(pro101, cl2) ? creep
X = pro101
18/05/2023 A. ELKARI 95
2 - Quelques prédicats prédéfinis
2-1 Les listes
2-1-1 Représentation des listes
Les listes sont un outil de programmation très puissant
comme l'atteste le succès du langage LISP (LISP : List
Processor) où toutes les données sont des atomes ou des
listes.
Une liste est une suite ordonnée de termes; ces termes
sont les éléments de la liste. Un cas particulier de liste
est la liste vide, qui est une liste à zéro élément.
Une liste non vide, d'éléments xl, x2,..., xn est notée [xl,
x2,..., xn] en Prolog la liste vide est notée [].
Ainsi, [X, pierre, point(Y, 6), jean] est une liste à 4
éléments : la variable X, l'atome pierre, le terme
point(Y,6) et l'atome jean.
[X] est une liste à un élément, la variable X.
18/05/2023 A. ELKARI 96
Les éléments d'une liste peuvent être des listes, ainsi la
liste [[paul, jean], [toto,X,Y], marie] est une liste à trois
éléments, la liste [paul, jean], la liste [toto,X, Y] et marie.
[[jean, U]] est une liste à un élément, la liste [jean, U].
[[]] est une liste à un élément, cet élément est la liste
vide [].
La notation « | » est prédéfinie et permet d’extraire la
tête et la queue d’une liste. La tête est le 1er élément ; la
queue est la liste restante sans le premier élément.
Quelques exemples :
?- [a, b] = [X | Y]. X = a, Y = [b]
?- [a] = [X | Y]. X = a, Y = []
?- [a, [b]] = [X | Y]. X = a, Y = [[b]]
?- [a, b, c, d] = [X, Y | Z]. X = a, Y = b, Z = [c, d]
?- [[a, b, c], d, e] = [X | Y]. X = [a, b, c], Y = [d, e]
18/05/2023 A. ELKARI 97
2-1-2 Quelques prédicats de manipulation de listes
Certains prédicats de manipulation de listes sont prédéfinis suivant
les variantes de Prolog .
- Le prédicat member/2
Appartenance d’un élément à une liste :
?- member(a, [b, c, a]).
Yes
?- member(a, [c, d]).
No
Exemples d’utilisation
?- member(X, [a, b, c]).
X=a;
X=b;
X=c;
No.
18/05/2023 A. ELKARI 98
- Le prédicat append/3 : Ajout de deux listes :
?- append([a, b, c], [d, e, f], [a, b, c, d, e, f]).
Yes
?- append([a, b], [c, d], [e, f]).
No
?- append([a, b], [c, d], L).
L = [a, b, c, d]
3) Exprimer la relation :
voyage_éco(Ville, Durée, Cat, Prix_max)
"le voyage à Ville .... est économique, c'est à dire a un coût inférieur à Prix_max"
18/05/2023 A. ELKARI 113
Exercice :
Le motard généreux.
Un motard veut offrir une moto identique à chacune de
ses sœurs. Le nombre représentant le coût de l’opération
est, si l’on inverse tous les chiffres, celui qui représente
le prix unitaire d’une moto. Sachant que le motard en
question avait au moins deux sœurs, mais pas plus de 8. Le
prix de la moto offerte se situant entre 10000 et 99999
dirhams.
Ecrire un programme Prolog répondant à la question
suivante : combien le motard a-t-il de sœurs et quel est
le prix d’une moto ?
N.B. Vous pouvez utiliser le prédicat prédéfinit between
Exemple : between (2,8,F) veut dire que F est compris
entre 2 et 8 au sens large.
18/05/2023 A. ELKARI 115
18/05/2023 A. ELKARI 116
Somme des éléments d’une liste
somme_liste([], 0).
somme_liste([Tete|Queue], Somme) :- somme_liste(Queue,
Rest),Somme is Tete + Rest.