Mais comment utiliser Prolog !
L’interprète de prolog :
Différents interpréteurs Prolog sont disponibles, aussi bien sous ...
Sur ce qui vient nous verrons en détails les différentes caractéristiques de Prolog.
Pour l’instant, nous nous contenteron...
Les Variables :
Nous allons introduire la notion de variables.
Question 3: quels sont tous les animaux ?
?- animal(X).
La ...
Dans le code source nous indiquons que :
alice est l'épouse de luc
luc est le père de jean
de telles affirmations sont app...
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 luci...
Exemple :
Soit le programme source suivant :
pere(abraham,isaac).
pere(isaac,jacob).
pere(jacob,joseph).
ancetre(X,Y):-per...
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...
Test de l'appartenance à une liste :
Le programme source est :
appartient_a(X,[X|_]).
appartient_a(X,[_|L]) :- appartient_...
Le problème est que cet appel récursif ne s'arrête jamais, et affiche toutes les valeurs négatives sans fin :
?- afficher(...
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|...
?- repeter(3,(write('prolog'),nl)).
prolog
prolog
prolog
true.
Remarque : Pour passer plusieurs prédicats dans le second p...
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 ...
Prochain SlideShare
Chargement dans…5
×

5 installation de prolog

1 052 vues

Publié le

Publié dans : Technologie
0 commentaire
0 j’aime
Statistiques
Remarques
  • Soyez le premier à commenter

  • Soyez le premier à aimer ceci

Aucun téléchargement
Vues
Nombre de vues
1 052
Sur SlideShare
0
Issues des intégrations
0
Intégrations
3
Actions
Partages
0
Téléchargements
17
Commentaires
0
J’aime
0
Intégrations 0
Aucune incorporation

Aucune remarque pour cette diapositive

5 installation de prolog

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

×