Vous êtes sur la page 1sur 127

SYSTEME EXPERT

Prolog

18/05/2023 A. ELKARI 1
Objectifs
• Présenter les bases de la programmation
déclarative à travers l’utilisation du
langage Prolog.

• Permettre d’implémenter en Prolog des


systèmes experts.

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.

• Il existe différentes versions de Prolog. Tout


d’abord, on sépare le Prolog «marseillais» et sa
syntaxe. Sa version la plus répandue est
PrologII+ qui a été suivie de Prolog III puis
Prolog IV, qui sont des versions orientées vers la
programmation sous contraintes

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.

Le symbole | ?- est le prompt de Gnu Prolog, il ne fait pas partie de la question.


18/05/2023 A. ELKARI 13
Commentaires :
• Une question interroge sur une connaissance. Si cette
connaissance est présente dans le programme ou bien si
elle est déductible du programme, la réponse sera
positive. Sinon, la réponse sera négative. Tout ce qui n’est
pas dit dans le programme est considéré par Prolog
comme faux.
• Une question peut être une conjonction de questions
simples. Par exemple,
| ?- hors_d_oeuvre(artichauts),poisson(sardine).
Veut dire « est-ce que les artichauts sont un hors
d’œuvre et la sardine, un poisson. » La réponse ici sera
oui.

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.

Un programme Prolog représente donc un


ensemble de formules de la logique du premier
ordre reliées par des et.

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.

• Soit on utilise une technique de chaînage arrière qui


consiste à partir de la formule à démontrer, remonter
jusqu’aux formules qui la démontrent. C’est cette
approche qui est utilisée dans Prolog. On présente le
chaînage arrière comme une application du Principe de
Résolution de Robinson

18/05/2023 A. ELKARI 28
2 - Prolog et le principe de Robinson

Pour bien comprendre cette partie, il faut


avoir vu la partie logique qui présente le
Principe de Résolution de Robinson, les notions
de clauses et de résolvante.

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

Trouver la clause résolvante dans les cas suivants :


a) C1 = Q P C2 = R P S
b) C1 = Q P C2 = Q
c) C1 = P Q C2 = P S R
d) C1 = P Q C2 = R P

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 SF ={P Q R, R , P, T Q , T}
C1 C2 C3 C4 C5
SF 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.

En logique du premier ordre, les clauses ne


contiennent pas que des propositions mais également
des termes et une résolvante est calculée en
cherchant à unifier un littéral avec le littéral opposé.
L’unification est un processus qui essaye de rendre
égaux deux termes en effectuant des substitutions
sur les variables; par exemple, le terme p(X,a) peut
s’unifier avec le terme p(f(b),Y) si X est substitué à
f(b) et Y à a.
18/05/2023 A. ELKARI 35
Le fonctionnement de Prolog peut être alors décrit
par l’algorithme suivant :

Soit P un programme Prolog, soit Cp l’ensemble de


clauses équivalent à ce programme.
Soit Q une question, soit Cq l’ensemble de clauses
équivalent à la négation de cette question.
Les clauses dans Cp et Cq sont ordonnées en fonction
de l’ordre des règles dans P et de l’ordre des
questions dans Q.

18/05/2023 A. ELKARI 36
Appliquer le Principe de Résolution de Robinson de la
manière suivante :

1. Essayer de produire une résolvante à partir de c la première


clause de Cq et en essayant les clauses de Cp dans l’ordre.
2. Si ce n’est pas possible, échec
3. Si c’est possible, remplacer, dans Cq, c par la résolvante
produite, en conservant l’ordre et en effectuant les
substitutions provenant de l’unification faite lors de la
production de la résolvante, puis recommencer en 1.
4. Si l’ensemble Cq est vide, cela veut dire que toutes les clauses
provenant de la négation de la question ont été démontrées en
produisant des résolvantes vides. 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 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 Fpnon(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

Le fonctionnement de Prolog peut être décrit


par l’algorithme d’effacement (ou réécriture)
suivant :
Soit P un programme Prolog.
Soit Fq l’ensemble formé des faits q1, q2, …, qn
d’une question Q.
Les règles dans P et les faits dans Fq sont
ordonnés (en fonction de leur ordre
d’apparition dans P et dans Q).

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.

5. Appliquer l’algorithme de backtracking pour


produire tous les effacements possibles.

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

Le comportement du programme ci-dessus peut-être


représenter sous forme arborescente de la manière
suivante:

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.

- Des NON dans la prémisse d’une


implication : impossible (équivalent à des OU
entre des faits).
- Des NON dans la conclusion d’une
implication : impossible.

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 :

Après le lancement, le prompt de Prolog | ?- apparaît


et l’interpréteur attend une question. Un certain
nombre de règles et de faits sont prédéfinis et
permettent d’utiliser l’environnement. C’est le cas du
prédicat consult qui compile et charge un programme
en mémoire. Ce programme peut soit se trouver dans
un fichier (c’est alors le nom du fichier qu’il faut
donner en argument du prédicat consult) soit être
directement tapé au clavier (c’est le mot user qu’il
faut alors donner en argument du prédicat) : c’est ce
que nous montrons dans l’exemple 1.

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

Si la question contient des variables :

| ?- hors_d_oeuvre(X).

X = artichauts ? ;
X = tomates
yes

| ?- hors_d_oeuvre(X).
X = artichauts
yes

| ?-

18/05/2023 A. ELKARI 63
Commentaires :

On pose 2 fois la même question (hors_d_oeuvre(X).).


Dans le premier cas, après l’affichage par Prolog de la
première solution possible (X=artichauts), l’utilisateur a
tapé un ‘ ;’ qui signifie ‘donnez-moi la solution suivante s’il
y en a’. Prolog affiche alors la deuxième solution
(X=tomates) et, s’étant rendu compte que c’est la
dernière solution possible, termine l’exécution en
affichant yes. Dans le deuxième cas, l’utilisateur a tapé
retour-chariot après l’affichage de la première solution,
ce qui signifie ‘ne me donnez pas les autres solutions,
même s’il y en a’. Prolog termine alors l’exécution en
affichant yes. Le prompt apparaît à nouveau, Prolog
attend de nouvelles questions.

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).

user compiled, 3 lines read - 285 bytes


written, 25566 ms

(20 ms) yes

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 :

On voit dans l’exemple ci-dessus que les règles


concernant la définition du prédicat plat ont
été ajoutées au programme déjà présent en
mémoire, mais que l’ajout du fait
viande(agneau). a provoqué la suppression
des autres faits concernant le prédicat
viande.

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).

user compiled, 11 lines read - 854 bytes written, 3317


ms
(30 ms) yes

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).

(10 ms) yes

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).

(10 ms) yes

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).

(10 ms) yes

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 :

La ligne :-dynamic(viande/1) rend le prédicat viande à 1


argument dynamique et donc modifiable par programme.
La question | ?-asserta(viande(mouton)). ajoute le fait
viande(mouton) dans le programme avant tous les autres
faits concernant ce prédicat.
| ?- retract(viande(poulet)). Enlève du programme le
premier fait ou la première règle qui s’unifie avec
viande(poulet).
| ?- retractall(viande(X)). Enlève tous les faits ou règles
s’unifiant avec viande(X),

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

Les exemples simples à programmer en Prolog


consistent en général en des déclarations de
connaissances sous forme de faits puis en
descriptions de liens entre ces faits. On peut
dire que c’est une programmation de type « base
de données ».

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]

?- append(L, [c, d], [a, b, c, d]).


L = [a, b]

?- append(L1, L2, [a, b, c]).


L1 = [], L2 = [a, b, c] ;
L1 = [a], L2 = [b, c] ;
etc., avec toutes les combinaisons
- Le prédicat intersection/3 : intersection de deux listes :
intersection([a,b,c],[d,b,e,a],L). L=[a,b]
18/05/2023 A. ELKARI 99
- Le prédicat delete/3
Efface un élément d’une liste.
La syntaxe est : delete(Liste, Élément, ListeSansÉlément).
Exemple :
| ?- delete([a,b,c], a, L).
L = [b,c]
yes
- Le prédicat reverse/2
Inverse l’ordre des éléments dans une liste.
| ?- reverse([a,b,c], L).
L = [c,b,a]

18/05/2023 A. ELKARI 100


2-2 Arithmétique et opérateurs
Évaluer un terme représentant une expression arithmétique revient à
appliquer le prédicat prédéfini is/2.
?- X = 1 + 1 + 1.
X = 1 + 1 + 1.
?- X = 1 + 1 + 1, Y is X.
X = 1 + 1 + 1, Y = 3.
?- X is 1 + 1 + a.
erreur (a pas un nombre)
?- X is 1 + 1 + Z.
erreur (Z non instancié à un nombre)
?- Z = 2, X is 1 + 1 + Z.
Z=2
X=4
?- X is 2.4+5.7*4.
X = 25.2

18/05/2023 A. ELKARI 101


Si on essaie
?- 1 + 2 < 3 + 4.
Il y a évaluation des 2 termes de gauche et de
droite avant la comparaison. Il importe de bien
distinguer les opérateurs arithmétiques des
opérateurs littéraux, ainsi que de l’unification
Numérique Littérale(terme à terme)

Opérateur d’égalité =:= ==


Opérateur d’inégalité =\= \==
Plus petit < @<
Plus petit ou égal =< @=<
Plus grand > @>
Plus grand ou égal >= @>=

18/05/2023 A. ELKARI 102


Par exemple :
?- 1 + 2 =:= 2 + 1.
Yes.
?- 1 + 2 = 2 + 1.
No.
?- 1 + 2 = 1 + 2.
Yes.
?- 1 + X = 1 + 2.
X = 2.
?- 1 + X =:= 1 + 2.
Erreur.
?- 1 + 2 == 1 + 2.
Yes.
?- 1 + 2 == 2 + 1.
No.
?- 1 + X == 1 + 2.
No.
?- 1 + a == 1 + a.
Yes.

18/05/2023 A. ELKARI 103


Exercice :
Faire un programme prolog calculant la factorielle
d’un nombre entier quelconque.

18/05/2023 A. ELKARI 104


fact(0,1).
fact(N,M) :- N > 0, N1 is N-1, fact(N1,M1), M is M1*N.
• _____________________________________________________
• [trace] 6 ?- fact(3,Xa).
• Call: (7) fact(3, _G430) ? creep
• ^ Call: (8) 3>0 ? creep
• ^ Exit: (8) 3>0 ? creep
• ^ Call: (8) _L187 is 3-1 ? creep
• ^ Exit: (8) 2 is 3-1 ? creep
• Call: (8) fact(2, _L188) ? creep
• ^ Call: (9) 2>0 ? creep
• ^ Exit: (9) 2>0 ? creep
• ^ Call: (9) _L206 is 2-1 ? creep
• ^ Exit: (9) 1 is 2-1 ? creep
18/05/2023 A. ELKARI 105
Call: (9) fact(1, _L207) ? creep
^ Call: (10) 1>0 ? creep
^ Exit: (10) 1>0 ? creep
^ Call: (10) _L225 is 1-1 ? creep
^ Exit: (10) 0 is 1-1 ? creep
Call: (10) fact(0, _L226) ? creep
Exit: (10) fact(0, 1) ? creep
^ Call: (10) _L207 is 1*1 ? creep
^ Exit: (10) 1 is 1*1 ? creep
Exit: (9) fact(1, 1) ? creep
^ Call: (9) _L188 is 1*2 ? creep
^ Exit: (9) 2 is 1*2 ? creep
Exit: (8) fact(2, 2) ? creep
^ Call: (8) _G430 is 2*3 ? creep
^ Exit: (8) 6 is 2*3 ? creep
Exit: (7) fact(3, 6) ? creep
Xa =6

18/05/2023 A. ELKARI 106


18/05/2023 A. ELKARI 107
Partie exercices
Exercice 1
Une agence de voyages propose à ses clients des séjours de 1
ou 2 semaines à Rome, Londres ou Tunis. Le catalogue de
l'agence contient, pour chaque destination, le prix du
transport (indépendant de la durée) et le prix d'une
semaine de séjour qui varie selon la destination et le
niveau de confort choisi : hôtel, chambre chez l'habitant
ou camping. 1) Écrire l'ensemble des assertions qui
décrivent ce catalogue
2) Exprimer la relation voyage(v,d,h,s) qui s'interprète par :
le voyage dans la ville v, pendant d semaines avec
l'hébergement h coûte s francs.
3) Compléter par voyage_economique(v,d,h,s,s_max) qui
exprime que le coût s de ce voyage doit être inférieur à
s_max francs.
18/05/2023 A. ELKARI 108
sejour(rome,Cat1,1400).
sejour(rome,Cat2,2000).
sejour(londres,Cat1,1800).
sejour(londres,Cat2,2500).
sejour(tunis,Cat1,1000).
sejour(tunis,Cat2,1800).
transport(rome,1200).
transport(londres,600).
transport(tunis,1500).
duree(1).
duree(2).
duree(3).
somme(X,Y,S) :-S is X+Y.
produit(X,Y,P):-P is X*Y.
voyage(V,D,H,S):-sejour(V,H,Y), duree(D), transport(V,X),
produit(D,Y,P), somme(X,P,S).
voyage_economique(V,D,H,S,S_MAX):-voyage(V,D,H,S),S@<S_MAX.

18/05/2023 A. ELKARI 109


Exercice 2
Un stock d'un grand magasin est un ensemble de produits décrits chacun
par un ensemble de propriétés : leur nom (pelle), leur catégorie (outil),
leur prix (63 euros) et la quantité présente dans le stock (35).
1°) Décrivez un tel stock par des assertions Prolog.
2°) Posez les questions suivantes en Prolog :
- Quels sont les produits ?
- Est-ce qu'il y a des pioches dans ce stock ?
- Quels sont les outils ?
- Est-ce qu'il y a plus de 20 marteaux dans le stock ?
- Quels sont les produits de la catégorie alimentation qui coûtent
plus de 21 euros ?
- Est-ce que les pioches sont dans la catégorie outil ?
Commentez vos réponses. Si vous avez des difficultés pour avoir des
réponses correspondant exactement à la question (par exemple des
réponses en oui ou non, plutôt que des valeurs de variables),
définissez de nouvelles règles spécifiques.

18/05/2023 A. ELKARI 110


TP
"Trois personnes, de nationalités différentes et pratiquant
des sports différents, habitent dans trois maisons de
couleurs distinctes. Ces trois maisons sont situées dans la
même rue ; une des maisons est située au début de la rue,
l'autre au milieu et la troisième au bout de la rue. Sachant
que dans la maison verte on pratique la natation, que la
maison verte est située dans la rue avant la maison de
l'espagnol, que l'anglais habite la maison blanche, qui est
située dans la rue avant celle où on pratique le football et
que le tennisman habite au début de la rue, quel sport
pratique le français et quelle est la nationalité de la
personne qui habite la maison bleue ?

18/05/2023 A. ELKARI 111


Le but de ce TP est de réaliser la décomposition en facteurs premiers
d’un entier. Ainsi, au nombre « 12 », nous voulons que ProLog associe la
décomposition : « 2 * 2 * 3 ».
Dans tout le sujet nous supposerons que nous ne manipulons que des
entiers strictement positifs.
1. Un nombre est premier s’il n’est divisible que par 1 et par lui-même. ´
Écrivez un prédicat nonpremier qui est vrai si et seulement si le
nombre qui lui ait passé en argument n’est pas premier, c’est-`a-dire
si et seulement si ce nombre admet un diviseur non trivial, ou est égal
à un.
Exemples d’utilisation :
?- nonpremier(1).
No
?- nonpremier(7).
No
?- nonpremier(12).
Yes

18/05/2023 A. ELKARI 112


Exercice :
Une agence de voyage propose des voyages de 1, 2 ou 3 semaines à Rome,
Londres et Tunis.
Le catalogue comprend pour chaque destination le prix du transport et le prix
d'une semaine de séjour dans un hôtel de catégorie 1 ou 2. Les prix sont les
suivants :

1) En utilisant les prédicats transport(Ville,Prix) et sejour(Ville,Cat,Prix), écrire la


base des faits décrivant le catalogue ci-dessus.

2) Exprimer la relation (par "voyage" on entend un ensemble transport + séjour) :


voyage(Ville, Durée, Cat, Prix) "le voyage dans la Ville, pendant Durée (exprimée
en nombre de semaines) dans un hôtel de catégorie Cat, revient à Prix"

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 :

18/05/2023 A. ELKARI 114


Problème :

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.

18/05/2023 A. ELKARI 117


Somme des carrés des éléments d’une liste
% Cas de base : la somme des carrés d'une liste vide est 0
sum_of_squares([], 0).

% Récursivement, calcule la somme des carrés des éléments


restants de la liste
sum_of_squares([Head|Tail], Sum) :- sum_of_squares(Tail,
TailSum),Sum is TailSum + Head * Head.

18/05/2023 A. ELKARI 118


18/05/2023 A. ELKARI 119
Explication :
•La première règle gcd(X, 0, X) indique que le PGCD de deux
nombres est le premier nombre si le deuxième nombre est égal à 0.
•La deuxième règle gcd(X, Y, R) :- Y > 0, Z is X mod Y, gcd(Y, Z,
R) calcule récursivement le PGCD de deux nombres. Le PGCD de X
et Y est égal au PGCD de Y et du reste de la division euclidienne de X
par Y.
•La troisième règle : gcd_list([X], X) calcule le PGCD d'une liste
contenant un seul nombre, qui est simplement ce nombre lui-même.
•La quatrième règle : gcd_list([X, Y | Rest], R) :- gcd(X, Y, G),
gcd_list([G | Rest], R) calcule le PGCD d'une liste en calculant
d'abord le PGCD des deux premiers éléments de la liste à l'aide de la
règle gcd(X, Y, G), puis en continuant à calculer récursivement le
PGCD de la liste avec le résultat obtenu, jusqu'à ce qu'il ne reste plus
qu'un seul élément dans la liste.
18/05/2023 A. ELKARI 120
Exemple d'utilisation :
Supposons que nous
voulions calculer le PGCD
des nombres 12, 8, et 30.
Nous pouvons appeler le
prédicat pgcd/2 avec une
liste contenant ces nombres
:

?- pgdc([12, 28, 30], R).


R = 2.

18/05/2023 A. ELKARI 121


18/05/2023 A. ELKARI 122
Le premier predicat ppmc/3 calcule le PPMC de deux
nombres en utilisant le PGCD (Plus Grand Commun
Diviseur). Il utilise la formule mathématique :
PPMC(A, B) = (A * B) / PGCD(A, B).
Le second predicat ppmc_liste/2 calcule le PPMC d'une
liste de nombres en utilisant le predicat ppmc/3. Il
commence par calculer le PPMC des deux premiers nombres
de la liste, puis continue récursivement jusqu'à ce qu'il n'y
ait plus qu'un seul nombre dans la liste.
Le troisième predicat pgcd/3 calcule le PGCD de deux
nombres en utilisant l'algorithme d'Euclide.

18/05/2023 A. ELKARI 123


18/05/2023 A. ELKARI 124
EXERCICE
Énoncé de l'énigme : Il y a trois amis : Alice, Bob et Claire.
Chacun d'entre eux a un animal de compagnie différent :
chat, chien et lapin. Utilisez Prolog pour déterminer l'animal
de compagnie de chaque ami en utilisant les indices suivants
:
1.Bob n'a pas de chat comme animal de compagnie.
2.Claire a un chien.
3.Alice n'a pas de lapin.
Posez la question : Quel est l'animal de compagnie de
chaque ami ?

18/05/2023 A. ELKARI 125


% Les animaux possibles sont le chat, le chien et le lapin
animal(chat).
animal(chien).
animal(lapin).
% Les amis sont Alice, Bob et Claire
ami(alice).
ami(bob).
ami(claire).
% Prédicat pour déterminer si un ami a un certain animal
aPourAnimal(Ami, Animal) :- ami(Ami), animal(Animal).
% Règles pour résoudre l'énigme
solution(Alice_C, Bob_C,Claire_C) :-
% Chaque ami a un animal différent
aPourAnimal(alice, Alice_C), aPourAnimal(bob, Bob_C), aPourAnimal(claire, Claire_C),
different(Alice_C, Bob_C), different(Alice_C, Claire_C), different(Bob_C, Claire_C),
% Bob n'a pas de chat
Bob_C \= chat,
% Claire a un chien
Claire_C = chien,
% Alice n'a pas de lapin
Alice_C \= lapin,
write('Animal de compagnie de Alice: '),write(Alice_C),nl,
write('Animal de compagnie de Bob: '),write(Bob_C),nl,
write('Animal de compagnie de Claire: '),write(Claire_C).
% Prédicat pour vérifier si deux éléments sont différents
different(X, Y) :- X \= Y.
18/05/2023 A. ELKARI 126
Exercice

Un fermier doit transporter une chèvre, un loup et un chou de l'autre


côté d'une rivière. Il possède une petite barque dans laquelle il ne
peut transporter qu'un seul de ces éléments à la fois, en plus de lui-
même. Cependant, s'il laisse le loup seul avec la chèvre, le loup la
mangera, et s'il laisse la chèvre seule avec le chou, la chèvre le
mangera.
•Comment le fermier peut-il transporter les trois éléments de l'autre
côté de la rivière sans qu'aucun ne soit mangé ?"
•L'énigme repose sur la logique et la recherche d'une solution
permettant de faire traverser tous les éléments en évitant les
situations où la chèvre serait seule avec le loup ou avec le chou.

18/05/2023 A. ELKARI 127

Vous aimerez peut-être aussi