Premiers pas avec le langage Prolog
Programmation de la base de données
Prolog catégorise tout en :
- Atomes - Toute séquence de caractères qui ne commence pas par un alphabet majuscule. Par exemple - ‘a’, ‘b’, ’d’accord’
- Numéros - Il n’y a pas de syntaxe spéciale pour les nombres, aucune déclaration n’est requise. Par exemple,
1
,22
,35.8
- Variables - Une chaîne commençant par une majuscule ou un trait de soulignement (
_
). Par exemple, ‘X’, ‘Y’, ‘Abc’, ‘AA’ - Termes complexes - Ils sont constitués d’un foncteur et d’une suite d’arguments. Le nom d’un terme complexe est toujours un atome, tandis que les arguments peuvent être des atomes ou des variables. Par exemple,
père(jean, biche)
,parent(e)
,mère(X,Y)
.
Une base de données logique contient un ensemble de faits et de règles.
Un terme complexe avec uniquement des atomes comme arguments est appelé un fait, tandis qu’un terme complexe avec des variables comme arguments est appelé une règle.
Exemple de faits en Prolog :
father_child(fred, susan).
mother_child(hillary, joe).
Exemple de règle en Prolog :
child_of(X,Y):-
father_child(Y,X)
;
mother_child(Y,X).
Notez que le ;
ici est comme l’opérateur or
dans d’autres langages.
Prolog est un langage déclaratif et vous pouvez lire cette base de données comme suit :
fred est le père de susan
Hillary est la mère de Joe.
Pour tout
X
etY
,X
est un enfant deY
siY
est père deX
ouY
est mère deX
.
En fait, un ensemble fini de faits et ou de règles constitue un programme logique.
L’utilisation d’un tel programme est démontrée en faisant des requêtes. Les requêtes vous permettent de récupérer des informations à partir d’un programme logique.
Pour charger la base de données dans l’interpréteur (en supposant que vous avez enregistré la base de données dans le répertoire dans lequel vous exécutez l’interpréteur), vous entrez simplement :
?- [nameofdatabase].
en remplaçant le nameofdatabase
par le nom de fichier réel (notez qu’ici nous excluons l’extension .pl
du nom de fichier).
Exemple de requêtes dans l’interpréteur pour le programme ci-dessus et les résultats :
?- child_of(susan,fred).
true
?- child_of(joe,hillary).
true
?- child_of(fred,susan).
false
?- child_of(susan,hillary).
false
?- child_of(susan,X).
X = fred
?- child_of(X,Y).
X = susan,
Y = fred ;
X = joe,
Y = hillary.
Les questions ci-dessus et leurs réponses peuvent être lues comme suit :
Susan est-il un enfant de Fred ? - vrai
Joe est-il un enfant d’Hillary ? - vrai
est-ce que fred est un enfant de susan ? - faux
Susan est-il un enfant d’Hillary ? - faux
de qui susan est-elle l’enfant ? - Fred
C’est ainsi que nous programmons la logique en Prolog. Un programme logique est plus formellement : un ensemble d’axiomes, ou de règles, définissant des relations (c’est-à-dire des prédicats) entre des objets. Une autre façon d’interpréter la base de données ci-dessus d’une manière logique plus formelle est :
La relation “père_enfant” tient entre fred et susan
La relation
mother_child
tient entre hillary et joe
Pour tous
X
etY
la relationchild_of
est vraie entreX
etY
si la relationfather_child
est vraie entreY
etX
, ou la relationmother_child
est vraie entreY
etX
.
Bonjour le monde
Hello, World dans l’interpréteur interactif
Pour imprimer “Hello, World!” dans l’interpréteur Prolog (ici, nous utilisons swipl
, le shell pour SWI Prolog):
$ swipl
<...banner...>
?- write('Hello, World!'), nl.
?-
est l’invite système : elle indique que le système est prêt à ce que l’utilisateur entre une séquence de buts (c’est-à-dire une requête) qui doit se terminer par un .
(point).
Ici, la requête write('Hello World!'), nl
a deux objectifs :
write('Hello World!')
:'Hello World!'
doit être affiché et (,
)- une nouvelle ligne (
nl
) doit suivre.
write/1
(le /1
est utilisé pour indiquer que le prédicat prend un argument) et nl/0
sont des prédicats intégrés (la définition est fournie à l’avance par le système Prolog). Les prédicats intégrés fournissent des fonctionnalités qui ne peuvent pas être obtenues par une définition Prolog pure ou pour éviter au programmeur d’avoir à les définir.
Le résultat:
Bonjour, Monde !
oui
se termine par “oui” signifiant que la requête a réussi. Dans certains systèmes, “true” est imprimé à la place de “yes”.
Hello, World à partir d’un fichier
Ouvrez un nouveau fichier appelé hello_world.pl
et insérez le texte suivant :
:- initialization hello_world, halt.
hello_world :-
write('Hello, World!'), nl.
La directive initialization
spécifie que le goal hello_world, halt
doit être appelé lorsque le fichier est chargé. halt
quitte le programme.
Ce fichier pourra ensuite être exécuté par votre exécutable Prolog. Les drapeaux exacts dépendent du système Prolog. Si vous utilisez SWI Prolog :
$ swipl -q -l hello_world.pl
Cela produira la sortie Hello, World!
. Le drapeau -q
supprime la bannière qui s’affiche généralement lorsque vous appelez run swipl
. Le -l
spécifie un fichier à charger.
Installation ou configuration
SWI-Prolog
Windows et Mac :
- Téléchargez SWI-Prolog sur le site officiel
- Installez simplement en suivant les instructions d’installation.
Linux (PPA):
-
Ajoutez le PPA
ppa:swi-prolog/stable
aux sources logicielles de votre système (les développeurs peuvent choisirppa:swi-prolog/devel
) :-
Open a terminal (Ctrl+Alt+T) and type:
sudo add-apt-repository ppa:swi-prolog/stable
-
Afterwards, update the package information:
sudo apt-get update
-
-
Installez maintenant SWI-Prolog via le gestionnaire de packages :
sudo apt-get install swi-prolog
-
Vous pouvez maintenant démarrer SWI-Prolog via la ligne de commande avec la commande
swipl
ajouter/3
append([], Bs, Bs).
append([A|As], Bs, [A|Cs]) :-
append(As, Bs, Cs).
append/3
est l’une des relations Prolog les plus connues. Il définit une relation entre trois arguments et est vrai si le troisième argument est une liste qui dénote la concaténation des listes qui sont spécifiées dans les premier et deuxième arguments.
Notamment, et comme c’est généralement le cas pour un bon code Prolog, append/3
peut être utilisé dans plusieurs directions : il peut être utilisé pour :
-
append deux listes entièrement ou partiellement instanciées :
?- A = [1, 2, 3], B=[4, 5, 6], append(A, B, Y) Output: A = [1, 2, 3], B = [4, 5, 6], Y = [1, 2, 3, 4, 5, 6].
-
vérifier si la relation est vraie pour trois listes entièrement instanciées :
?- A = [1, 2, 3], B = [4, 5], C = [1, 2, 3, 4, 5, 6], append(A, B, C) Output: false
-
générer toutes les manières possibles d’ajouter deux listes à une liste donnée :
?- append(A, B, [1, 2, 3, 4]). Output: A = [], B = [1, 2, 3, 4] ; A = [1], B = [2, 3, 4] ; A = [1, 2], B = [3, 4] ; A = [1, 2, 3], B = [4] ; A = [1, 2, 3, 4], B = [] ; false.
Contraintes CLP(FD)
Les contraintes CLP(FD) sont fournies par toutes les implémentations sérieuses de Prolog. Ils nous permettent de raisonner sur des entiers de manière pure.
?- X #= 1 + 2.
X = 3.
?- 5 #= Y + 2.
Y = 3.