SlideShare una empresa de Scribd logo
1 de 12
Descargar para leer sin conexión
Mais comment utiliser Prolog !
L’interprète de prolog :
Différents interpréteurs Prolog sont disponibles, aussi bien sous Windows que sous Linux, parmi lesquels :
- SWI-Prolog (www.swi-prolog.org).
- SICStus Prolog (www.sics.se/sicstus).
- Open Prolog (www.cs.tcd.ie/open-prolog).
- GNU-Prolog (http://www.gprolog.org/).
- Visual Prolog (http://www.visual-prolog.com/). … etc.
Dans la suite on va travailler avec l’interpréteur SWI-Prolog, c’est le plus conseillé, d’ailleurs un sondage sur
le site http://www.developpez.com/ le montre très bien.
SWI-Prolog qui est un interpréteur Prolog gratuit et disponible pour Windows et pour Linux.
Pour installer SWI-Prolog sous Windows téléchargez la dernière version stable sur le site
http://www.swi-prolog.org
Ou cliquez sur le lien suivant pour télécharger la version 6.2.2 datant de 2012 :
Télécharger SWI-Prolog 6.2.2 (version 2012) pour Windows :
http://www.gecif.net/articles/linux/swi-prolog.exe
Étapes pour programmer en Prolog :
On va avoir besoin d’un éditeur de texte et de la console SWI-prolog.
1 - Créer un fichier avec Bloc-notes ou WordPad qu’on nommeras par exemple ( exProlog ) avec
l’extension ‘.pl’.
2 - Lancer l’interpréteur SWI-Prolog en cliquant directement sur le fichier ou sinon par la commande
appropriée (généralement pl). Dans le deuxième cas, charger le fichier en tapant « [Le chemin d’accès au
fichier exProlog.pl]. »
Si vous avez mis une majuscule à l’initiale du nom de fichier, vous devrez mettre entre apostrophes :
['ExProlog'].
Le signal d'invite ‘?-‘ attend que vous saisissiez un but que le moteur de résolution Prolog tentera de
satisfaire.
3 - Recharger le fichier après chaque modification.
4 - Pour sortir: halt. ou Ctrl-D
Dans l'interprète, vous pouvez obtenir une aide sur tout prédicat prédéfini à l'aide du prédicat help.
Par example help(halt).
Pour interrompre une exécution problématique (et passer à une autre commande ou question) : Ctrl C
(puis a - pour "abort").
Un manuel de référence très détaillé est disponible sur le site de SWI-Prolog :
(http://www.swi-prolog.org/pldoc/refman/ ).
Sur ce qui vient nous verrons en détails les différentes caractéristiques de Prolog.
Pour l’instant, nous nous contenterons de nous familiariser avec le Langage.
Exemple Pratique :
1 - Éditons un nouveau fichier texte nommé ‘Fichier1’ (avec l’éditeur de test Bloc-Note par exemple) et
enregistrons le avec l’extension .pl.
Voici le code source en Prolog de ce programme qui se contente de déclarer un ensemble de faits :
animal(ours).
animal(chat).
prenom(hypathie).
prenom(alex).
prenom(bissette).
poss_ani(bissette,chat).
poss_ani(alex,chat).
*Veuillez consulter le fichier [Exemples/Fichier1.pl] du CD.
Un tel fichier s’appelle base de faits, parce qu’il regroupe des faits que l’on déclare être vrais.
Voici les faits affirmés par notre programme :
- ours et chat sont des animaux.
- hypathie, alex et bissette sont des prénoms.
2 - Ouvrons le programme source Prolog.pl dans l'interpréteur Prolog en tapant :
[‘CheminD’accèsFichier1.pl’]. ou consult(‘CheminD’accèsFichier1’). , l'extension .pl n'est pas
indiquée dans l'instruction consult.
Ceci dit qu’il faut charger le programme.
Nous n'allons pas maintenant "exécuter" le programme comme on le fait d’habitude, mais nous
allons plutôt poser à l'interpréteur Prolog un ensemble de questions pour lesquelles l'interpréteur consultera
les faits et les règles inscrits dans le programme du fichier ‘Fichier1.pl’, nous allons donc interroger notre
base de connaissance. Dans la terminologie Prolog, on les appelle des requêtes ou buts.
Question 1: hypathie est-il un prénom ?
?- prenom(hypathie).
Remarque : On doit Vérifiés en Particulier :
1. Que nous n’avons pas pour l’instant utilisé aucune majuscule.
2. Que tous les faits et votre requête se terminent par un point.
L'interpréteur nous répond true : hypathie est bien un prénom dans la base des faits inscrits dans le
programme.
Question 2: ouria est-il un prénom ?
?- prenom(ouria).
L'interpréteur nous répond false : ouria n'est pas un prénom dans la base des faits inscrits dans le
programme.
Les Variables :
Nous allons introduire la notion de variables.
Question 3: quels sont tous les animaux ?
?- animal(X).
La variable X va prendre pour valeur chaque nom d'animal. Pour passer d'un valeur à une autre il
faut appuyer sur la touche point-virgule. Une fois que la liste est terminée, Prolog la fini par un point. Le
résultat est alors :
X = ours;
X = chat.
Question 4: quels sont tous les prenoms ?
?- prenom(X).
Cette fois la variable X va prendre pour valeur chaque prénom. Le point-virgule permet toujours de
passer d'une réponse à la suivante. Le résultat final est alors :
X = hypathie;
X = alex;
X = bissette.
Question 5: existe-t-il des animaux ?
?- animal(_).
Cette fois l'expression animal(_) sera vraie chaque fois que Prolog rencontre un animal (peu-importe
lequel) dans la base des faits du programme. Comme Prolog rencontre 2 animaux, la réponse à notre
question est :
true ;
true.
Ici, Prolog vérifie l’existence d’une valeur pour cette variable (une substitution) mais ne cherche pas à
énumérer les valeurs Possibles.
Les Conjonctions :
Nous nous sommes pour l’instant limités à satisfaire un seul but à la fois, mais on peut aussi tenter de
les combiner : si l’on entre plusieurs buts séparés par des virgules, Prolog essaiera de tous les satisfaire
simultanément.
?- animal(X),poss_ani(alex,X).
Nous donne bien le X = chat .
?− animal(X) ,prenom(X) .
Nous donne heureusement False.
Maintenant nous allons introduire la notion de Règles:
Exemple 1 : l'arbre généalogique
Les données du problème sont : Alice et Luc sont mariés. Luc est le père de Jean.
La problématique à résoudre est : Qui est la mère de Jean ?
Dans le code source nous indiquons que :
alice est l'épouse de luc
luc est le père de jean
de telles affirmations sont appelées des faits
Puis nous indiquons à Prolog que si un père est marié à une femme, alors cette dernière est la mère du fils :
Une telle déclaration est appelée une règle.
Le symbole :- dans une règle se lit "si".
Le symbole , (virgule) dans une règle se lit "et".
% les faits :
epouse(alice,luc). % alice est l'épouse de luc
pere(luc,jean). % luc est le père de jean
% les règles :
mere(M,E) :- pere(P,E) , epouse(M,P). % M est la mère de E si P est le père de E et si M est l'épouse de P
*Veuillez consulter le fichier [Exemples/Fichier2.pl] du CD.
Remarque : en Prolog tout ce qui suit le caractère % sur une ligne est un commentaire.
Après avoir ouvert le programme dans l'interpréteur Prolog (par la commande consult), posons-lui quelques
questions :
Question 1 : qui est l'épouse de luc ?
?- epouse(X,luc).
X = alice.
Question 2 : qui est l'époux d'alice ? (qui a pour épouse alice)
?- epouse(alice,X).
X = luc.
Question 3 : qui est le père de jean ?
?- pere(X,jean).
X = luc.
Question 4 : qui est le fils de luc ? (qui a pour père luc)
?- pere(luc,X).
X = jean.
Remarque : pour répondre à ces 4 premières questions Prolog n’à utiliser que les faits, sans utiliser la règle
définissant la mère.
Question 5 : qui est la mère de jean ?
?- mere(X,jean).
X = alice.
Question 6 : qui est le fils d'alice ? (qui a pour mère alice)
?- mere(alice,X).
X = jean.
Remarque : pour répondre à ces 2 dernières questions Prolog à utiliser cette fois la règle définissant la
mère.
Question 7 : qui est le fils de jean ? (qui a pour père jean)
?- pere(jean,X).
false.
Question 8 : qui est le fils de lucienne ? (qui a pour mère lucienne)
?- mere(lucienne,X).
false.
Remarque : Prolog n'a pas la réponse à ces 2 dernières questions : il répond alors false.
Question 9 : qui est la mère de qui ?
?- mere(X,Y).
X = alice,
Y = jean.
Question 10 : combien de liens de parenté "mère/fils" existe-t-il ?
?- mere(_,_).
1 seul
true.
Question 11 : existe-t-il une personne qui est sa propre mère ?
?- mere(X,X).
NON
false.
Remarque : en Prolog le nom des variables commencent toujours par une lettre majuscule (exemple : X,
Voiture, NUMERO, etc.).
Pour bien comprendre les étapes de résolution de cette requêtes, SWI-Prolog nous propose
le ‘Débogage’ :
Pour comprendre ce qui se passe, nous allons utiliser les capacités de débogage de SWI-Prolog.
On va entrer la commande :
trace , prenom(X).
Ceci va donc lancer la requête prenom(X)., mais en demandant en plus une trace d’exécution. Prolog
répondra Call: (7) prenom(_G156) ?, ce qui signifie qu’il a projet d’appeler le prédicat prenom avec une
variable comme argument.
Pour savoir quelles sont vos possibilités à ce moment précis, tapons ‘h’. Prolog nous donnera alors la liste des
commandes disponibles. Pour l’instant, nous désirons simplement continuer l’exécution :
Tapons la barre d’espacement (ou enter).
Continuons à suivre pas à pas l’exécution de notre programme en frappant la barre d’espacement,
chaque fois que nécessaire, jusqu’à la fin de l’exécution.
SWI-Prolog (dans sa version pour Windows seulement) propose aussi une version graphique du
débogueur. Dans le menu ‘Debug’ choisissons ‘Graphical Debugger’ (ou tapons simplement guitracer.),
puis relancez la commande trace , prenom(X).
Une belle fenêtre apparaît nous permettant de suivre l’exécution du programme.
Enfin, la commande halt permet de sortir de l'interpréteur Prolog : ?- halt.
Exemple :
Soit le programme source suivant :
pere(abraham,isaac).
pere(isaac,jacob).
pere(jacob,joseph).
ancetre(X,Y):-pere(X,Y).
ancetre(X,Y):-pere(X,Z),ancetre(Z,Y).
C’est un programme récursif, et donc la trace va faire apparaître l'arbre des appels.
La question est : ?- ancetre(abraham,joseph). La réponse est donc : true
Voici donc les étapes que SWI-Prolog exécute avant de nous donner cette réponse :
Comme on l’a déjà expliqué, on doit entrer la commande : ?- trace, ancetre(abraham,joseph).
1- Lancement de la trace :
Lorsque le calcul se termine, Prolog este en "mode trace", et le manifeste en demandant [trace] ?-
au lieu de ?-
Pour revenir à la boucle d'interaction ordinaire, dites :
[trace] ?- notrace, nodebug.
true.
3 ?-
2- Le littéral-but est considéré comme placé dans une boîte munie de 2 entrées et de 2 sorties (globalement appelées les 4
ports)
Call désigne le lancement de la démonstration
Fail signifie que tout espoir de démontrer le but doit être abandonné
Exit annonce une démonstration réussie (mais il peut s'en trouver d'autres...)
Redo signale qu'on essaie une nouvelle fois de démontrer le but, en essayant la clause suivante dans le paquet de clauses
compétent.
Dans le cas d'un prédicat évaluable comme tab, write ou nl, Call est immédiatement suivi de Exit.
Dans celui d'un prédicat défini par un paquet de clauses, chaque Call vise une clause du paquet, et il est suivi d'une
séquence de Calls aux différents littéraux qui composent le corps de la clause.
Ces appels correspondent à une descente dans l'arbre des appels récursifs à l'exécuteur, et la profondeur courante est
affichée entre parenthèses.
Utilisation des listes :
Les tableaux tels qu'on les connaît dans les langages impératifs n'existent pas en Prolog. Ils sont
remplacés par les listes.
Une liste en Prolog s'écrit entre crochets. Exemple : [a,b,c] est une liste contenant les 3 éléments a, b et
c. A l'intérieur d'une liste les éléments sont séparés par une virgule lorsqu’ils sont énumérés un à un.
La liste vide est représentée par [].
L'opérateur | (barre verticale) permet de définir une liste constituée de :
- Son premier élément (à gauche de l'opérateur |)
- La suite de la liste (c'est une liste, placée à droite de l'opérateur |)
[X|L] est une liste obtenue en ajoutant l'élément X au début de la liste L.
Par exemple les écritures suivantes sont toutes équivalentes : [a|[b,c]] = [a|[b|[c]]] = [a|[b|[c|[]]]] = [a,b,c]
Affichage de tous les éléments d'une liste :
Le programme source est :
afficher_liste([X|L]) :- writeln(X), afficher_liste(L).
Après avoir ouvert ce programme simple dans l'interpréteur Prolog (par la commande consult),
utilisons la fonction afficher_liste :
Question 1 : ?- afficher_liste([a,b,c]).
a
b
c
false.
Question 2 : ?- afficher_liste([a|[b|[c|[]]]]).
a
b
c
false.
Test de l'appartenance à une liste :
Le programme source est :
appartient_a(X,[X|_]).
appartient_a(X,[_|L]) :- appartient_a(X,L).
Après avoir ouvert ce programme simple dans l'interpréteur Prolog (par la commande consult),
utilisons la fonction appartient_a :
Question 1 : ?- appartient_a(a,[a,b,c]).
true
Question 2 : ?- appartient_a(c,[a,b,c]).
true
Question 3 : ?- appartient_a(e,[a,b,c]).
false
Veuillez consulter le fichier [Exemples/Fichier3.pl] du CD.
Utilisation de la coupure :
La coupure est un prédicat prédéfini très important qui a pour effet de stopper la recherche de Prolog
dès qu'il aura trouvé une solution (permettant d’agir sur le comportement de l’interprète Prolog lors du
retour arrière).
Ce prédicat permet de contrôler l'espace de recherche et d'économiser le travail de Prolog en limitant
l'exploration de l'arbre de recherche.
La coupure se note ! (un point d'exclamation) dans la plupart des versions de Prolog.
Rappelons que le prédicat prédéfini is est l'opérateur d'affectation en Prolog : il affecte à la variable de
gauche la valeur de l'expression de droite, après avoir évalué cette expression. Par exemple, X is A+2.
Évalue en un premier temps l'expression A+2 puis affecte le résultat à la variable X.
Example simple:
?- X is 2, Y is X+3.
X = 2,
Y = 5.
Passons à 3 exemples d’utilisation concrète de la coupure en Prolog.
Exemple 1 de la coupure : affichage de tous les entiers de N à 1 dans l'ordre décroissant.
L'idée de base est d'écrire un prédicat afficher(N) qui s'appelle récursivement en passant en
paramètre au prédicat appelé la valeur N-1 :
afficher(N):-writeln(N),K is N-1,afficher(K). *Veuillez consulter le fichier [Exemples/Fichier4.1.pl] du CD.
Le problème est que cet appel récursif ne s'arrête jamais, et affiche toutes les valeurs négatives sans fin :
?- afficher(5).
5
4
.
.
.
-3
-4
.
.
.
etc. sans arrêt ...
Une solution pour arrêter l'affichage en dessous de zéro est de rajouter une condition dans le prédicat
afficher(N) :
afficher(N):-N>0,writeln(N),K is N-1,afficher(K). *Veuillez consulter le fichier [Exemples/Fichier4.2.pl] du CD.
Cela stop en effet l'affichage à 1, mais Prolog répond alors par la négation (false) en sortant lorsque
N=0 car la condition N>0 n'est pas vérifiée :
?- afficher(5).
5
4
3
2
1
false.
La solution pour stopper l'affichage lorsque N=0 tout en répondant positivement (true) est d'utiliser la
coupure : on stoppe positivement la recherche lorsque N=0, c'est-à-dire lorsque le prédicat afficher() reçoit 0
en paramètre :
afficher(0):-!. % ne fait rien et arrête la recherche en répondant true
afficher(N):-writeln(N),K is N-1,afficher(K). % appel récursif du prédicat afficher()
*Veuillez consulter le fichier [Exemples/Fichier4.3.pl] du CD.
Et le résultat est :
?- afficher(5).
5
4
3
2
1
true.
Exemple 2 de la coupure : affichage de tous les éléments d'une liste.
L'idée de base est d'écrire un prédicat afficher([X|Y]) qui affiche le premier élément X puis qui appelle
récursivement le prédicat afficher en lui passant en paramètre le reste Y de la liste:
afficher([X|Y]):-writeln(X),afficher(Y). *Veuillez consulter le fichier [Exemples/Fichier5.1.pl] du CD.
Mais là encore Prolog répond par la négation (false) lorsqu'il n'y a plus rien à afficher, c'est-à-dire
lorsque la liste reçue en paramètre par le prédicat afficher est vide :
?- afficher([a,b,c,d]).
a
b
c
d
false.
La solution consiste donc à préciser grâce à la coupure que si la liste reçue est vide, on arrête la
recherche et on répond positivement :
afficher([]):-!. % arrête si la liste est vide
afficher([X|Y]):-writeln(X),afficher(Y). % appel récursif si la liste n'est pas vide
*Veuillez consulter le fichier [Exemples/Fichier5.2.pl] du CD.
Et le résultat est :
?- afficher([a,b,c,d]).
a
b
c
d
true.
Exemple 3 de la coupure : répétition d'une proposition quelconque.
Le prédicat repeter(N,P) suivant répète N fois la proposition P :
repeter(0,_):-!. % arrête si N=0 quelque soit la proposition P
repeter(N,P):-P,X is N-1,repeter(X,P). % exécute P puis appel récursif
*Veuillez consulter le fichier [Exemples/Fichier6.pl] du CD.
Exemples d'utilisation :
?- repeter(5,write('bonjour ')).
bonjour bonjour bonjour bonjour bonjour
true.
?- repeter(2,repeter(1,writeln('3Info'))).
3Info
3Info
true.
?- repeter(3,(write('prolog'),nl)).
prolog
prolog
prolog
true.
Remarque : Pour passer plusieurs prédicats dans le second paramètre de repeter on les a encadrés par des
parenthèses. le prédicat nl affiche un retour à la ligne sur la sortie standard, il est équivalent à writeln('') :
?- repeter(4,(write('prolog'),writeln(''))).
prolog
prolog
prolog
prolog
true.
Exemple 4 de la coupure : se limiter à la première réponse dans le cas de réponses multiples.
Nous retrouvons un arbre généalogique très simple : jean est le père de 3 enfants :
pere(jean,luc). % jean est le père de luc
pere(jean,remi). % jean est le père de rémi
pere(jean,laurent). % jean est le père de laurent *Veuillez consulter le fichier [Exemples/Fichier7.pl] du CD.
Posons quelques questions à l'interpréteur avec ou sans coupure :
Qui est le père de laurent ? Réponse : jean :
?- pere(X,laurent).
X = jean.
Qui est le fils de jean (qui a pour père jean) ? Réponse : jean a 3 fils luc, rémi et laurent, il y a donc 3
solutions :
?- pere(jean,X).
X = luc ;
X = remi ;
X = laurent.
Rémi a-t-il un père ? Réponse : oui :
?- pere(_,remi).
true.
Jean est-il un père ? Et là encore la réponse est triple puisque l'interpréteur a trouvé 3 fois la réponse à la
question :
?- pere(jean,_).
true ;
true ;
true.
Si on veut juste savoir si Jean est un père ou pas, peu importe le nombre de fils. Dans ce cas on va
poser la question en utilisant la coupure afin de s'arrêter dès la première réponse positive :
?- pere(jean,_),!.
true.
Ainsi l'interpréteur arrête sa recherche dès le premier fils trouvé, sans perdre de temps à se
demander si jean a d'autres fils, ce qui n'a aucune importance pour répondre à la question "Jean est-il un
père ?".
De même, si on pose la question "Qui sont les fils de jean ?" avec une coupure à la fin, l'interpréteur
arrêtera la recherche dès la première solution trouvée :
?- pere(jean,X),!.
X = luc.
La question précédente peut alors se formuler ainsi : "Donnez-moi un fils de jean et un seul, peu importe
lequel".
NB : Nous détaillerons ses points dans les exemples qui suivent.

Más contenido relacionado

La actualidad más candente

Boas práticas de django
Boas práticas de djangoBoas práticas de django
Boas práticas de djangoFilipe Ximenes
 
実践多クラス分類 Kaggle Ottoから学んだこと
実践多クラス分類 Kaggle Ottoから学んだこと実践多クラス分類 Kaggle Ottoから学んだこと
実践多クラス分類 Kaggle Ottoから学んだことnishio
 
Juliaで前処理
Juliaで前処理Juliaで前処理
Juliaで前処理weda654
 
オンラインゲームのRails複数db戦略
オンラインゲームのRails複数db戦略オンラインゲームのRails複数db戦略
オンラインゲームのRails複数db戦略Yasutomo Uemori
 
Hack言語に賭けたチームの話
Hack言語に賭けたチームの話Hack言語に賭けたチームの話
Hack言語に賭けたチームの話Yuji Otani
 
目で見る過学習と正則化
目で見る過学習と正則化目で見る過学習と正則化
目で見る過学習と正則化y-uti
 
「今日から使い切る」 ための GNU Parallel による並列処理入門
「今日から使い切る」ための GNU Parallelによる並列処理入門「今日から使い切る」ための GNU Parallelによる並列処理入門
「今日から使い切る」 ための GNU Parallel による並列処理入門Koji Matsuda
 
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門Kohki Miki
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング道化師 堂華
 
ある工場の Redmine 2017
ある工場の Redmine 2017ある工場の Redmine 2017
ある工場の Redmine 2017Kohei Nakamura
 
Homebrewによるソフトウェアの実装 (3)
Homebrewによるソフトウェアの実装 (3)Homebrewによるソフトウェアの実装 (3)
Homebrewによるソフトウェアの実装 (3)Yoshihiro Mizoguchi
 
Overview of tree algorithms from decision tree to xgboost
Overview of tree algorithms from decision tree to xgboostOverview of tree algorithms from decision tree to xgboost
Overview of tree algorithms from decision tree to xgboostTakami Sato
 
構造方程式モデルによる因果探索と非ガウス性
構造方程式モデルによる因果探索と非ガウス性構造方程式モデルによる因果探索と非ガウス性
構造方程式モデルによる因果探索と非ガウス性Shiga University, RIKEN
 
RStanとShinyStanによるベイズ統計モデリング入門
RStanとShinyStanによるベイズ統計モデリング入門RStanとShinyStanによるベイズ統計モデリング入門
RStanとShinyStanによるベイズ統計モデリング入門Masaki Tsuda
 
Rで学ぶ離散選択モデル
Rで学ぶ離散選択モデルRで学ぶ離散選択モデル
Rで学ぶ離散選択モデル宏喜 佐野
 

La actualidad más candente (20)

Boas práticas de django
Boas práticas de djangoBoas práticas de django
Boas práticas de django
 
実践多クラス分類 Kaggle Ottoから学んだこと
実践多クラス分類 Kaggle Ottoから学んだこと実践多クラス分類 Kaggle Ottoから学んだこと
実践多クラス分類 Kaggle Ottoから学んだこと
 
Juliaで前処理
Juliaで前処理Juliaで前処理
Juliaで前処理
 
オンラインゲームのRails複数db戦略
オンラインゲームのRails複数db戦略オンラインゲームのRails複数db戦略
オンラインゲームのRails複数db戦略
 
Hack言語に賭けたチームの話
Hack言語に賭けたチームの話Hack言語に賭けたチームの話
Hack言語に賭けたチームの話
 
目で見る過学習と正則化
目で見る過学習と正則化目で見る過学習と正則化
目で見る過学習と正則化
 
Cours JavaScript
Cours JavaScriptCours JavaScript
Cours JavaScript
 
「今日から使い切る」 ための GNU Parallel による並列処理入門
「今日から使い切る」ための GNU Parallelによる並列処理入門「今日から使い切る」ための GNU Parallelによる並列処理入門
「今日から使い切る」 ための GNU Parallel による並列処理入門
 
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
cocos2d-x 3.0 + C++11で始めるゲーム開発超入門
 
エラーハンドリング
エラーハンドリングエラーハンドリング
エラーハンドリング
 
ある工場の Redmine 2017
ある工場の Redmine 2017ある工場の Redmine 2017
ある工場の Redmine 2017
 
Homebrewによるソフトウェアの実装 (3)
Homebrewによるソフトウェアの実装 (3)Homebrewによるソフトウェアの実装 (3)
Homebrewによるソフトウェアの実装 (3)
 
BFPRT algorithm
BFPRT algorithmBFPRT algorithm
BFPRT algorithm
 
Overview of tree algorithms from decision tree to xgboost
Overview of tree algorithms from decision tree to xgboostOverview of tree algorithms from decision tree to xgboost
Overview of tree algorithms from decision tree to xgboost
 
Bonfire API #1 APIのリトライ処理
Bonfire API #1 APIのリトライ処理Bonfire API #1 APIのリトライ処理
Bonfire API #1 APIのリトライ処理
 
Xtext入門
Xtext入門Xtext入門
Xtext入門
 
構造方程式モデルによる因果探索と非ガウス性
構造方程式モデルによる因果探索と非ガウス性構造方程式モデルによる因果探索と非ガウス性
構造方程式モデルによる因果探索と非ガウス性
 
RStanとShinyStanによるベイズ統計モデリング入門
RStanとShinyStanによるベイズ統計モデリング入門RStanとShinyStanによるベイズ統計モデリング入門
RStanとShinyStanによるベイズ統計モデリング入門
 
Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)
 
Rで学ぶ離散選択モデル
Rで学ぶ離散選択モデルRで学ぶ離散選択モデル
Rで学ぶ離散選択モデル
 

Destacado

Formulario proyecto nov
Formulario proyecto novFormulario proyecto nov
Formulario proyecto novannsand.ana
 
La edicion científica (Scientific communication)
La edicion científica (Scientific communication)La edicion científica (Scientific communication)
La edicion científica (Scientific communication)Ernest Abadal
 
#mardiDD - Colloque Développement Durable Québec
#mardiDD - Colloque Développement Durable Québec#mardiDD - Colloque Développement Durable Québec
#mardiDD - Colloque Développement Durable QuébecHughes Chandonnet
 
Les espaces majeurs de production et d'évahnges web
Les espaces majeurs de production et d'évahnges webLes espaces majeurs de production et d'évahnges web
Les espaces majeurs de production et d'évahnges webCéline Langlet
 
Cours tp2 eculture2012
Cours tp2 eculture2012Cours tp2 eculture2012
Cours tp2 eculture2012luctrouche
 
Guide LinkedIn
Guide LinkedInGuide LinkedIn
Guide LinkedInHugo Clery
 
Sensibilisation précoce et conscience plurilingue
Sensibilisation précoce et conscience plurilingueSensibilisation précoce et conscience plurilingue
Sensibilisation précoce et conscience plurilingueProjetPluriL
 
L’île de Bréhat
L’île de BréhatL’île de Bréhat
L’île de BréhatSaqqarah 31
 
Pascua sor Ester Muñoz
Pascua sor Ester MuñozPascua sor Ester Muñoz
Pascua sor Ester MuñozChinca FMA
 
Analyse financiere
Analyse financiereAnalyse financiere
Analyse financiereKHALOUF
 
Aspectos legales del acceso abierto
Aspectos legales del acceso abiertoAspectos legales del acceso abierto
Aspectos legales del acceso abiertoErnest Abadal
 
Pharmacie naturelle
Pharmacie naturellePharmacie naturelle
Pharmacie naturellehannibale
 
Stage de fin d’études – dotcloud
Stage de fin d’études – dotcloudStage de fin d’études – dotcloud
Stage de fin d’études – dotcloudJoffrey Fu Hrer
 
Extension du Musée d'Unterlinden Colmar DP
Extension du Musée d'Unterlinden Colmar DPExtension du Musée d'Unterlinden Colmar DP
Extension du Musée d'Unterlinden Colmar DPBâle Région Mag
 

Destacado (20)

Formulario proyecto nov
Formulario proyecto novFormulario proyecto nov
Formulario proyecto nov
 
La edicion científica (Scientific communication)
La edicion científica (Scientific communication)La edicion científica (Scientific communication)
La edicion científica (Scientific communication)
 
Schéma régional 2012 2014
Schéma régional 2012 2014Schéma régional 2012 2014
Schéma régional 2012 2014
 
#mardiDD - Colloque Développement Durable Québec
#mardiDD - Colloque Développement Durable Québec#mardiDD - Colloque Développement Durable Québec
#mardiDD - Colloque Développement Durable Québec
 
Dissemblables
Dissemblables Dissemblables
Dissemblables
 
Les espaces majeurs de production et d'évahnges web
Les espaces majeurs de production et d'évahnges webLes espaces majeurs de production et d'évahnges web
Les espaces majeurs de production et d'évahnges web
 
Cours tp2 eculture2012
Cours tp2 eculture2012Cours tp2 eculture2012
Cours tp2 eculture2012
 
Guide LinkedIn
Guide LinkedInGuide LinkedIn
Guide LinkedIn
 
Precentacion GameDraw
Precentacion GameDrawPrecentacion GameDraw
Precentacion GameDraw
 
Sensibilisation précoce et conscience plurilingue
Sensibilisation précoce et conscience plurilingueSensibilisation précoce et conscience plurilingue
Sensibilisation précoce et conscience plurilingue
 
Guia racismo
Guia racismoGuia racismo
Guia racismo
 
L’île de Bréhat
L’île de BréhatL’île de Bréhat
L’île de Bréhat
 
Pascua sor Ester Muñoz
Pascua sor Ester MuñozPascua sor Ester Muñoz
Pascua sor Ester Muñoz
 
Analyse financiere
Analyse financiereAnalyse financiere
Analyse financiere
 
Aspectos legales del acceso abierto
Aspectos legales del acceso abiertoAspectos legales del acceso abierto
Aspectos legales del acceso abierto
 
Pérdida del conocimiento
Pérdida del conocimientoPérdida del conocimiento
Pérdida del conocimiento
 
Pharmacie naturelle
Pharmacie naturellePharmacie naturelle
Pharmacie naturelle
 
Stage de fin d’études – dotcloud
Stage de fin d’études – dotcloudStage de fin d’études – dotcloud
Stage de fin d’études – dotcloud
 
2012 health fr
2012 health fr2012 health fr
2012 health fr
 
Extension du Musée d'Unterlinden Colmar DP
Extension du Musée d'Unterlinden Colmar DPExtension du Musée d'Unterlinden Colmar DP
Extension du Musée d'Unterlinden Colmar DP
 

Similar a 5 installation de prolog (11)

8 gl1
8 gl18 gl1
8 gl1
 
Le langage Prolog
Le langage PrologLe langage Prolog
Le langage Prolog
 
Tp1 ia
Tp1 iaTp1 ia
Tp1 ia
 
Td sem2 badache_lynda
Td sem2 badache_lyndaTd sem2 badache_lynda
Td sem2 badache_lynda
 
Cours de Génie Logiciel / ESIEA 2016-17
Cours de Génie Logiciel / ESIEA 2016-17Cours de Génie Logiciel / ESIEA 2016-17
Cours de Génie Logiciel / ESIEA 2016-17
 
4 histoir
4 histoir4 histoir
4 histoir
 
La programmation par contraintes avec Choco3 (Java)
La programmation par contraintes avec Choco3 (Java)La programmation par contraintes avec Choco3 (Java)
La programmation par contraintes avec Choco3 (Java)
 
3 intro
3 intro3 intro
3 intro
 
Cours fichiers
Cours fichiersCours fichiers
Cours fichiers
 
Cours fichiersdiapo
Cours fichiersdiapoCours fichiersdiapo
Cours fichiersdiapo
 
Actuariat et Données
Actuariat et DonnéesActuariat et Données
Actuariat et Données
 

Más de Siham Rim Boudaoud

Más de Siham Rim Boudaoud (13)

12 quelques prédicats prédéfinis de swi
12  quelques prédicats prédéfinis de swi12  quelques prédicats prédéfinis de swi
12 quelques prédicats prédéfinis de swi
 
11 library
11 library11 library
11 library
 
10 chapitre 4 listes et récursivité
10 chapitre 4 listes et récursivité10 chapitre 4 listes et récursivité
10 chapitre 4 listes et récursivité
 
9 gl2
9 gl29 gl2
9 gl2
 
8 arbre généalogique
8 arbre généalogique8 arbre généalogique
8 arbre généalogique
 
7
77
7
 
6 unification
6 unification6 unification
6 unification
 
2
2 2
2
 
2 sommaire
2  sommaire2  sommaire
2 sommaire
 
1 page de garde
1 page de garde1 page de garde
1 page de garde
 
13 conclusion
13  conclusion13  conclusion
13 conclusion
 
Diapo. ite web dynamique sous JEE, application aux entreprises de production ...
Diapo. ite web dynamique sous JEE, application aux entreprises de production ...Diapo. ite web dynamique sous JEE, application aux entreprises de production ...
Diapo. ite web dynamique sous JEE, application aux entreprises de production ...
 
Mémoire de Licence, site web dynamique sous JEE, application aux entreprises ...
Mémoire de Licence, site web dynamique sous JEE, application aux entreprises ...Mémoire de Licence, site web dynamique sous JEE, application aux entreprises ...
Mémoire de Licence, site web dynamique sous JEE, application aux entreprises ...
 

5 installation de prolog

  • 1. Mais comment utiliser Prolog ! L’interprète de prolog : Différents interpréteurs Prolog sont disponibles, aussi bien sous Windows que sous Linux, parmi lesquels : - SWI-Prolog (www.swi-prolog.org). - SICStus Prolog (www.sics.se/sicstus). - Open Prolog (www.cs.tcd.ie/open-prolog). - GNU-Prolog (http://www.gprolog.org/). - Visual Prolog (http://www.visual-prolog.com/). … etc. Dans la suite on va travailler avec l’interpréteur SWI-Prolog, c’est le plus conseillé, d’ailleurs un sondage sur le site http://www.developpez.com/ le montre très bien. SWI-Prolog qui est un interpréteur Prolog gratuit et disponible pour Windows et pour Linux. Pour installer SWI-Prolog sous Windows téléchargez la dernière version stable sur le site http://www.swi-prolog.org Ou cliquez sur le lien suivant pour télécharger la version 6.2.2 datant de 2012 : Télécharger SWI-Prolog 6.2.2 (version 2012) pour Windows : http://www.gecif.net/articles/linux/swi-prolog.exe Étapes pour programmer en Prolog : On va avoir besoin d’un éditeur de texte et de la console SWI-prolog. 1 - Créer un fichier avec Bloc-notes ou WordPad qu’on nommeras par exemple ( exProlog ) avec l’extension ‘.pl’. 2 - Lancer l’interpréteur SWI-Prolog en cliquant directement sur le fichier ou sinon par la commande appropriée (généralement pl). Dans le deuxième cas, charger le fichier en tapant « [Le chemin d’accès au fichier exProlog.pl]. » Si vous avez mis une majuscule à l’initiale du nom de fichier, vous devrez mettre entre apostrophes : ['ExProlog']. Le signal d'invite ‘?-‘ attend que vous saisissiez un but que le moteur de résolution Prolog tentera de satisfaire. 3 - Recharger le fichier après chaque modification. 4 - Pour sortir: halt. ou Ctrl-D Dans l'interprète, vous pouvez obtenir une aide sur tout prédicat prédéfini à l'aide du prédicat help. Par example help(halt). Pour interrompre une exécution problématique (et passer à une autre commande ou question) : Ctrl C (puis a - pour "abort"). Un manuel de référence très détaillé est disponible sur le site de SWI-Prolog : (http://www.swi-prolog.org/pldoc/refman/ ).
  • 2. Sur ce qui vient nous verrons en détails les différentes caractéristiques de Prolog. Pour l’instant, nous nous contenterons de nous familiariser avec le Langage. Exemple Pratique : 1 - Éditons un nouveau fichier texte nommé ‘Fichier1’ (avec l’éditeur de test Bloc-Note par exemple) et enregistrons le avec l’extension .pl. Voici le code source en Prolog de ce programme qui se contente de déclarer un ensemble de faits : animal(ours). animal(chat). prenom(hypathie). prenom(alex). prenom(bissette). poss_ani(bissette,chat). poss_ani(alex,chat). *Veuillez consulter le fichier [Exemples/Fichier1.pl] du CD. Un tel fichier s’appelle base de faits, parce qu’il regroupe des faits que l’on déclare être vrais. Voici les faits affirmés par notre programme : - ours et chat sont des animaux. - hypathie, alex et bissette sont des prénoms. 2 - Ouvrons le programme source Prolog.pl dans l'interpréteur Prolog en tapant : [‘CheminD’accèsFichier1.pl’]. ou consult(‘CheminD’accèsFichier1’). , l'extension .pl n'est pas indiquée dans l'instruction consult. Ceci dit qu’il faut charger le programme. Nous n'allons pas maintenant "exécuter" le programme comme on le fait d’habitude, mais nous allons plutôt poser à l'interpréteur Prolog un ensemble de questions pour lesquelles l'interpréteur consultera les faits et les règles inscrits dans le programme du fichier ‘Fichier1.pl’, nous allons donc interroger notre base de connaissance. Dans la terminologie Prolog, on les appelle des requêtes ou buts. Question 1: hypathie est-il un prénom ? ?- prenom(hypathie). Remarque : On doit Vérifiés en Particulier : 1. Que nous n’avons pas pour l’instant utilisé aucune majuscule. 2. Que tous les faits et votre requête se terminent par un point. L'interpréteur nous répond true : hypathie est bien un prénom dans la base des faits inscrits dans le programme. Question 2: ouria est-il un prénom ? ?- prenom(ouria). L'interpréteur nous répond false : ouria n'est pas un prénom dans la base des faits inscrits dans le programme.
  • 3. Les Variables : Nous allons introduire la notion de variables. Question 3: quels sont tous les animaux ? ?- animal(X). La variable X va prendre pour valeur chaque nom d'animal. Pour passer d'un valeur à une autre il faut appuyer sur la touche point-virgule. Une fois que la liste est terminée, Prolog la fini par un point. Le résultat est alors : X = ours; X = chat. Question 4: quels sont tous les prenoms ? ?- prenom(X). Cette fois la variable X va prendre pour valeur chaque prénom. Le point-virgule permet toujours de passer d'une réponse à la suivante. Le résultat final est alors : X = hypathie; X = alex; X = bissette. Question 5: existe-t-il des animaux ? ?- animal(_). Cette fois l'expression animal(_) sera vraie chaque fois que Prolog rencontre un animal (peu-importe lequel) dans la base des faits du programme. Comme Prolog rencontre 2 animaux, la réponse à notre question est : true ; true. Ici, Prolog vérifie l’existence d’une valeur pour cette variable (une substitution) mais ne cherche pas à énumérer les valeurs Possibles. Les Conjonctions : Nous nous sommes pour l’instant limités à satisfaire un seul but à la fois, mais on peut aussi tenter de les combiner : si l’on entre plusieurs buts séparés par des virgules, Prolog essaiera de tous les satisfaire simultanément. ?- animal(X),poss_ani(alex,X). Nous donne bien le X = chat . ?− animal(X) ,prenom(X) . Nous donne heureusement False. Maintenant nous allons introduire la notion de Règles: Exemple 1 : l'arbre généalogique Les données du problème sont : Alice et Luc sont mariés. Luc est le père de Jean. La problématique à résoudre est : Qui est la mère de Jean ?
  • 4. Dans le code source nous indiquons que : alice est l'épouse de luc luc est le père de jean de telles affirmations sont appelées des faits Puis nous indiquons à Prolog que si un père est marié à une femme, alors cette dernière est la mère du fils : Une telle déclaration est appelée une règle. Le symbole :- dans une règle se lit "si". Le symbole , (virgule) dans une règle se lit "et". % les faits : epouse(alice,luc). % alice est l'épouse de luc pere(luc,jean). % luc est le père de jean % les règles : mere(M,E) :- pere(P,E) , epouse(M,P). % M est la mère de E si P est le père de E et si M est l'épouse de P *Veuillez consulter le fichier [Exemples/Fichier2.pl] du CD. Remarque : en Prolog tout ce qui suit le caractère % sur une ligne est un commentaire. Après avoir ouvert le programme dans l'interpréteur Prolog (par la commande consult), posons-lui quelques questions : Question 1 : qui est l'épouse de luc ? ?- epouse(X,luc). X = alice. Question 2 : qui est l'époux d'alice ? (qui a pour épouse alice) ?- epouse(alice,X). X = luc. Question 3 : qui est le père de jean ? ?- pere(X,jean). X = luc. Question 4 : qui est le fils de luc ? (qui a pour père luc) ?- pere(luc,X). X = jean. Remarque : pour répondre à ces 4 premières questions Prolog n’à utiliser que les faits, sans utiliser la règle définissant la mère. Question 5 : qui est la mère de jean ? ?- mere(X,jean). X = alice. Question 6 : qui est le fils d'alice ? (qui a pour mère alice) ?- mere(alice,X). X = jean. Remarque : pour répondre à ces 2 dernières questions Prolog à utiliser cette fois la règle définissant la mère.
  • 5. Question 7 : qui est le fils de jean ? (qui a pour père jean) ?- pere(jean,X). false. Question 8 : qui est le fils de lucienne ? (qui a pour mère lucienne) ?- mere(lucienne,X). false. Remarque : Prolog n'a pas la réponse à ces 2 dernières questions : il répond alors false. Question 9 : qui est la mère de qui ? ?- mere(X,Y). X = alice, Y = jean. Question 10 : combien de liens de parenté "mère/fils" existe-t-il ? ?- mere(_,_). 1 seul true. Question 11 : existe-t-il une personne qui est sa propre mère ? ?- mere(X,X). NON false. Remarque : en Prolog le nom des variables commencent toujours par une lettre majuscule (exemple : X, Voiture, NUMERO, etc.). Pour bien comprendre les étapes de résolution de cette requêtes, SWI-Prolog nous propose le ‘Débogage’ : Pour comprendre ce qui se passe, nous allons utiliser les capacités de débogage de SWI-Prolog. On va entrer la commande : trace , prenom(X). Ceci va donc lancer la requête prenom(X)., mais en demandant en plus une trace d’exécution. Prolog répondra Call: (7) prenom(_G156) ?, ce qui signifie qu’il a projet d’appeler le prédicat prenom avec une variable comme argument. Pour savoir quelles sont vos possibilités à ce moment précis, tapons ‘h’. Prolog nous donnera alors la liste des commandes disponibles. Pour l’instant, nous désirons simplement continuer l’exécution : Tapons la barre d’espacement (ou enter). Continuons à suivre pas à pas l’exécution de notre programme en frappant la barre d’espacement, chaque fois que nécessaire, jusqu’à la fin de l’exécution. SWI-Prolog (dans sa version pour Windows seulement) propose aussi une version graphique du débogueur. Dans le menu ‘Debug’ choisissons ‘Graphical Debugger’ (ou tapons simplement guitracer.), puis relancez la commande trace , prenom(X). Une belle fenêtre apparaît nous permettant de suivre l’exécution du programme. Enfin, la commande halt permet de sortir de l'interpréteur Prolog : ?- halt.
  • 6. Exemple : Soit le programme source suivant : pere(abraham,isaac). pere(isaac,jacob). pere(jacob,joseph). ancetre(X,Y):-pere(X,Y). ancetre(X,Y):-pere(X,Z),ancetre(Z,Y). C’est un programme récursif, et donc la trace va faire apparaître l'arbre des appels. La question est : ?- ancetre(abraham,joseph). La réponse est donc : true Voici donc les étapes que SWI-Prolog exécute avant de nous donner cette réponse : Comme on l’a déjà expliqué, on doit entrer la commande : ?- trace, ancetre(abraham,joseph). 1- Lancement de la trace : Lorsque le calcul se termine, Prolog este en "mode trace", et le manifeste en demandant [trace] ?- au lieu de ?- Pour revenir à la boucle d'interaction ordinaire, dites : [trace] ?- notrace, nodebug. true. 3 ?-
  • 7. 2- Le littéral-but est considéré comme placé dans une boîte munie de 2 entrées et de 2 sorties (globalement appelées les 4 ports) Call désigne le lancement de la démonstration Fail signifie que tout espoir de démontrer le but doit être abandonné Exit annonce une démonstration réussie (mais il peut s'en trouver d'autres...) Redo signale qu'on essaie une nouvelle fois de démontrer le but, en essayant la clause suivante dans le paquet de clauses compétent. Dans le cas d'un prédicat évaluable comme tab, write ou nl, Call est immédiatement suivi de Exit. Dans celui d'un prédicat défini par un paquet de clauses, chaque Call vise une clause du paquet, et il est suivi d'une séquence de Calls aux différents littéraux qui composent le corps de la clause. Ces appels correspondent à une descente dans l'arbre des appels récursifs à l'exécuteur, et la profondeur courante est affichée entre parenthèses. Utilisation des listes : Les tableaux tels qu'on les connaît dans les langages impératifs n'existent pas en Prolog. Ils sont remplacés par les listes. Une liste en Prolog s'écrit entre crochets. Exemple : [a,b,c] est une liste contenant les 3 éléments a, b et c. A l'intérieur d'une liste les éléments sont séparés par une virgule lorsqu’ils sont énumérés un à un. La liste vide est représentée par []. L'opérateur | (barre verticale) permet de définir une liste constituée de : - Son premier élément (à gauche de l'opérateur |) - La suite de la liste (c'est une liste, placée à droite de l'opérateur |) [X|L] est une liste obtenue en ajoutant l'élément X au début de la liste L. Par exemple les écritures suivantes sont toutes équivalentes : [a|[b,c]] = [a|[b|[c]]] = [a|[b|[c|[]]]] = [a,b,c] Affichage de tous les éléments d'une liste : Le programme source est : afficher_liste([X|L]) :- writeln(X), afficher_liste(L). Après avoir ouvert ce programme simple dans l'interpréteur Prolog (par la commande consult), utilisons la fonction afficher_liste : Question 1 : ?- afficher_liste([a,b,c]). a b c false. Question 2 : ?- afficher_liste([a|[b|[c|[]]]]). a b c false.
  • 8. Test de l'appartenance à une liste : Le programme source est : appartient_a(X,[X|_]). appartient_a(X,[_|L]) :- appartient_a(X,L). Après avoir ouvert ce programme simple dans l'interpréteur Prolog (par la commande consult), utilisons la fonction appartient_a : Question 1 : ?- appartient_a(a,[a,b,c]). true Question 2 : ?- appartient_a(c,[a,b,c]). true Question 3 : ?- appartient_a(e,[a,b,c]). false Veuillez consulter le fichier [Exemples/Fichier3.pl] du CD. Utilisation de la coupure : La coupure est un prédicat prédéfini très important qui a pour effet de stopper la recherche de Prolog dès qu'il aura trouvé une solution (permettant d’agir sur le comportement de l’interprète Prolog lors du retour arrière). Ce prédicat permet de contrôler l'espace de recherche et d'économiser le travail de Prolog en limitant l'exploration de l'arbre de recherche. La coupure se note ! (un point d'exclamation) dans la plupart des versions de Prolog. Rappelons que le prédicat prédéfini is est l'opérateur d'affectation en Prolog : il affecte à la variable de gauche la valeur de l'expression de droite, après avoir évalué cette expression. Par exemple, X is A+2. Évalue en un premier temps l'expression A+2 puis affecte le résultat à la variable X. Example simple: ?- X is 2, Y is X+3. X = 2, Y = 5. Passons à 3 exemples d’utilisation concrète de la coupure en Prolog. Exemple 1 de la coupure : affichage de tous les entiers de N à 1 dans l'ordre décroissant. L'idée de base est d'écrire un prédicat afficher(N) qui s'appelle récursivement en passant en paramètre au prédicat appelé la valeur N-1 : afficher(N):-writeln(N),K is N-1,afficher(K). *Veuillez consulter le fichier [Exemples/Fichier4.1.pl] du CD.
  • 9. Le problème est que cet appel récursif ne s'arrête jamais, et affiche toutes les valeurs négatives sans fin : ?- afficher(5). 5 4 . . . -3 -4 . . . etc. sans arrêt ... Une solution pour arrêter l'affichage en dessous de zéro est de rajouter une condition dans le prédicat afficher(N) : afficher(N):-N>0,writeln(N),K is N-1,afficher(K). *Veuillez consulter le fichier [Exemples/Fichier4.2.pl] du CD. Cela stop en effet l'affichage à 1, mais Prolog répond alors par la négation (false) en sortant lorsque N=0 car la condition N>0 n'est pas vérifiée : ?- afficher(5). 5 4 3 2 1 false. La solution pour stopper l'affichage lorsque N=0 tout en répondant positivement (true) est d'utiliser la coupure : on stoppe positivement la recherche lorsque N=0, c'est-à-dire lorsque le prédicat afficher() reçoit 0 en paramètre : afficher(0):-!. % ne fait rien et arrête la recherche en répondant true afficher(N):-writeln(N),K is N-1,afficher(K). % appel récursif du prédicat afficher() *Veuillez consulter le fichier [Exemples/Fichier4.3.pl] du CD. Et le résultat est : ?- afficher(5). 5 4 3 2 1 true.
  • 10. Exemple 2 de la coupure : affichage de tous les éléments d'une liste. L'idée de base est d'écrire un prédicat afficher([X|Y]) qui affiche le premier élément X puis qui appelle récursivement le prédicat afficher en lui passant en paramètre le reste Y de la liste: afficher([X|Y]):-writeln(X),afficher(Y). *Veuillez consulter le fichier [Exemples/Fichier5.1.pl] du CD. Mais là encore Prolog répond par la négation (false) lorsqu'il n'y a plus rien à afficher, c'est-à-dire lorsque la liste reçue en paramètre par le prédicat afficher est vide : ?- afficher([a,b,c,d]). a b c d false. La solution consiste donc à préciser grâce à la coupure que si la liste reçue est vide, on arrête la recherche et on répond positivement : afficher([]):-!. % arrête si la liste est vide afficher([X|Y]):-writeln(X),afficher(Y). % appel récursif si la liste n'est pas vide *Veuillez consulter le fichier [Exemples/Fichier5.2.pl] du CD. Et le résultat est : ?- afficher([a,b,c,d]). a b c d true. Exemple 3 de la coupure : répétition d'une proposition quelconque. Le prédicat repeter(N,P) suivant répète N fois la proposition P : repeter(0,_):-!. % arrête si N=0 quelque soit la proposition P repeter(N,P):-P,X is N-1,repeter(X,P). % exécute P puis appel récursif *Veuillez consulter le fichier [Exemples/Fichier6.pl] du CD. Exemples d'utilisation : ?- repeter(5,write('bonjour ')). bonjour bonjour bonjour bonjour bonjour true. ?- repeter(2,repeter(1,writeln('3Info'))). 3Info 3Info true.
  • 11. ?- repeter(3,(write('prolog'),nl)). prolog prolog prolog true. Remarque : Pour passer plusieurs prédicats dans le second paramètre de repeter on les a encadrés par des parenthèses. le prédicat nl affiche un retour à la ligne sur la sortie standard, il est équivalent à writeln('') : ?- repeter(4,(write('prolog'),writeln(''))). prolog prolog prolog prolog true. Exemple 4 de la coupure : se limiter à la première réponse dans le cas de réponses multiples. Nous retrouvons un arbre généalogique très simple : jean est le père de 3 enfants : pere(jean,luc). % jean est le père de luc pere(jean,remi). % jean est le père de rémi pere(jean,laurent). % jean est le père de laurent *Veuillez consulter le fichier [Exemples/Fichier7.pl] du CD. Posons quelques questions à l'interpréteur avec ou sans coupure : Qui est le père de laurent ? Réponse : jean : ?- pere(X,laurent). X = jean. Qui est le fils de jean (qui a pour père jean) ? Réponse : jean a 3 fils luc, rémi et laurent, il y a donc 3 solutions : ?- pere(jean,X). X = luc ; X = remi ; X = laurent. Rémi a-t-il un père ? Réponse : oui : ?- pere(_,remi). true. Jean est-il un père ? Et là encore la réponse est triple puisque l'interpréteur a trouvé 3 fois la réponse à la question : ?- pere(jean,_). true ; true ; true.
  • 12. Si on veut juste savoir si Jean est un père ou pas, peu importe le nombre de fils. Dans ce cas on va poser la question en utilisant la coupure afin de s'arrêter dès la première réponse positive : ?- pere(jean,_),!. true. Ainsi l'interpréteur arrête sa recherche dès le premier fils trouvé, sans perdre de temps à se demander si jean a d'autres fils, ce qui n'a aucune importance pour répondre à la question "Jean est-il un père ?". De même, si on pose la question "Qui sont les fils de jean ?" avec une coupure à la fin, l'interpréteur arrêtera la recherche dès la première solution trouvée : ?- pere(jean,X),!. X = luc. La question précédente peut alors se formuler ainsi : "Donnez-moi un fils de jean et un seul, peu importe lequel". NB : Nous détaillerons ses points dans les exemples qui suivent.