UE ELFE - Programmation Logique SWI-Prolog

Transcription

UE ELFE - Programmation Logique SWI-Prolog
USTL
Licence mention Informatique
UE ELFE - Programmation Logique
Le but de cette première séance de T.P. est de vous familiariser avec l’environnement P ROLOG que
nous utiliserons au cours de nos prochaines séances, par la création de requêtes et de prédicats simples, ainsi qu’une approche de la récursivité. Nous utiliserons SWI-Prolog freeware de P ROLOG de
l’université d’Amsterdam.
Vous pouvez récupérez des distributions (linux, windows ou Max OS X) de SWI-Prolog librement sur
le site www.swi-prolog.pl.
SWI-Prolog
• Pour lancer l’interprète de SWI-Prolog, tapez pl dans une console. Le signal d’invite “?-” attend que vous
saisissiez un but que le moteur de résolution P ROLOG tentera de satisfaire.
• Pour quitter SWI-Prolog, taper halt. (avec le “.” !).
• Dans l’interprète, vous pouvez obtenir une aide sur tout prédicat prédéfini à l’adire du prédicat help. Par
exemple tester “help(halt).”.
Exercice 1 : Quelques questions simples
Une liste d’employés travaillant dans des entreprises d’informatique vous est fournie sous la forme des deux
tableaux 1 et 2.
Nom
Jean
Jacques
Anne
Fabienne
Eric
Marc
Julie
Sonia
Franck
Odette
Age
23
32
45
30
49
25
24
35
45
40
Sexe
Homme
Homme
Femme
Femme
Homme
Homme
Femme
Femme
Homme
Femme
Entré en
2000
1991
1993
2002
1984
2000
2001
1996
1999
1994
à
IBM
BULL
BULL
XEROX
BULL
XEROX
IBM
IBM
IBM
BULL
Echelon
1
4
3
1
5
2
1
3
2
4
Table 1: Liste des employés par société.
Salaires
IBM
BULL
XEROX
Ech. 1
2000
1600
2500
Ech. 2
3000
3000
4500
Ech. 3
4500
4500
5500
Ech. 4
5500
6000
6000
Ech. 5
7500
7500
7000
Table 2: Correspondances échelons/salaires.
Des requêtes simples. . .
On rappelle qu’en P ROLOG tout identificateur commençant par une majuscule est considéré
comme une variable, et que les prédicats avec paramètres doivent être immédiatement suivis
d’une parenthèse ouvrante (il ne doit pas y avoir d’espace entre la fin du nom du prédicat et
cette parenthèse).
Q 1 . Saisissez dans un fichier1 les données présentes dans les tableaux 1 et 2, en écrivant un ensemble de faits
sous la forme de prédicats :
employe( ?Nom, ?Age, ?Sexe, ?Entree, ?Entreprise, ?Echelon)
salaire( ?Entreprise, ?Echelon, ?Salaire)
1 Utilisez l’éditeur de textes que vous souhaitez : emacs, KWrite, Kate, etc. Kate (c’est le cas de Emacs aussi mais il demande un peu plus
de temps d’apdaptation), vous permet d’avoir dans une même fenêtre l’éditeur et un shell dans lequel vous pouvez exécuter SWI-Prolog
Commencez la saisie (les 3 premiers employés et les salaires de Xerox) puis allez consulter et récupérer le
fichier tp1-employes-partiel accessible depuis le portail ((http://www.fil.univ-lille1.fr/
Licence → S5→ELFE → Semainier) contient une partie des informations
Rappel : en P ROLOG, toute clause se termine pas un point.
Sur une ligne tout ce qui se trouve après le symbole % est considéré comme un commentaire et donc ignOré.
Donnez à votre fichier l’extension .pl.
Q 2 . Chargez votre fichier. Pour cela vous utiliserez le prédicat consult (essayez help(consult)), en lui
donnant en paramètre le nom de votre fichier qui doit avoir l’extension .pl : “consult(<nom de fichier>).”
(vous pouvez regarder l’aide pour les commande chdir et pwd éventuellement, vous pouvez encadrer les noms
de fichiers ou de répertoires d’apostrophe dans ces commandes).
Au chargement, votre fichier est évalué syntaxiquement par l’interprète P ROLOG, toute erreur de syntaxe éventuelle
est alors annoncée.
Vous pouvez également simplement tapez “ [<nom de fichier>].”
Lorsqu’un fichier est chargé (par consult) les clauses qui exsitaient précédemment pour les prédicats définis
dans ce fichier sont “oubliées”. Donc un “consult” réinitialise la définition des prédicats définis dans le fichier
“consulté”.
Q 3 . Premier but.
Le but employe(Nom,Age,Sexe,Annee,Entreprise,Echelon). permet de d’interroger le programme
sur les informations sur les employés.
Saisissez ce but. L’interprète annonce la première réponse (en fait substitution réponse en indiquant la valeur pour
chaque variable. En saisissant ; après la première réponse (quand il y en a une), le moteur de résolution vous
propose la réponse suivante quand il y en a une, et ainsi de suite jusqu’à ce qu’il n’y ait plus de réponse ce que
l’interprète annonce par No.
Si après un succès (= une réponse) vous tapez a (comme abort) ou les touche Espace ou Entree, vous sortez de
la phase de résolution du but sans obtenr les éventuelles autres réponses.
Testez ces différents points.
Q 4 . Trouvez et testez les buts (ou questions) permettant d’obtenir l’énumération :
1. des employés d’IBM par nom, âge, . . . , échelon.
2. des femmes par nom et âge uniquement.
3. des hommes de moins de 25 ans par nom et âge.
4. des salaires de la société IBM par échelon.
5. des hommes de moins de 25 ans par nom uniquement.
Q 5 . Quel problème se pose pour la dernière question ?
Des prédicats simples. . .
Q 6 . Écrivez puis testez les prédicats suivants :
1. jeune employe( ?Nom, ?Ent) Nom correspondant au nom de l’employé, et Ent au nom de l’entreprise. On
considérera qu’un employé est jeune s’il a moins de 25 ans.
Les opérateurs de relation d’ordre numérique classique sont des prédicats prédéfinis sous forme d’opérateur :
>, =<, etc. (Utilisez help...).
Faites les tests permettant de répondre aux questions :
“Quels sont les jeunes employés d’ibm ?”, “Jacques est il un jeune employe ?”, “Marc est il un jeune employe
de chez XEROX ?”,...
D’une manière générale, vous veillerez à faire des tests dans lesquels vous varierez les paramètres qui sont
en variables (non instanciées) et ceux qui sont instanciés par des concstantes.
2. cadre( ?Nom) Un employé est un cadre s’il est au moins au second échelon.
3. paye( ?Nom, ?Salaire)
4. jeune cadre( ?Nom)
5. anciennete( ?Nom, ?Anc) L’ancienneté est bien sûr le nombre d’années passées dans l’entreprise (à comparer avec l’année en cours).
On peut demander au moteur de résolution de réaliser un calcul numérique en utilisant l’opérateur is. Ainsi
l’expression : X is 1 + 2 unifiera X avec la valeur 3. Dans ce contexte l’expression Y is X + 1
unifiera Y à 4. Cette dernière expression génère une erreur si la valeur X n’est pas liée à une valeur constante
(numérique bien sûr).
6. collegues( ?Nom1, ?Nom2) Deux employés sont collègues s’ils travaillent dans la même entreprise.
Pour éviter d’avoir deux foi sle même nom, on peut tester la différence d’unification entre deux variables en
utilisant le prédicat \== (utilisez help).
7. plus ancien que( ?Nom1, ?Nom2) On se base sur l’ancienneté dans l’entreprise.
8. plus ancien collegue que( ?Nom1, ?Nom2)
9. gagne plus que( ?Nom1, ?Nom2, ?Salaire) Salaire représentant la différence de salaire entre les deux
employés uniquement si le premier gagne plus que le second.
10. superieur( ?Nom1, ?Nom2) Un employé est le supérieur d’un autre s’il travaille dans la même entreprise,
mais à un échelon strictement supérieur.
11. echelon normal( ?Nom, ?Ech) L’échelon normal d’un employé se calcule comme suit : lorsque l’on arrive
dans l’entreprise on est à l’échelon 1, puis on gagne un échelon tous les quatre ans jusqu’à atteindre l’échelon
5, qu’on ne peut dépasser.
L’opérateur de division entière est // (utilisez help)
12. victime( ?Nom) Un employé est une victime si un de ses collègues ayant moins d’ancienneté que lui est son
supérieur.
13. est exploite( ?Nom) Un employé est exploité s’il a un échelon inférieur à son échelon normal.
14. a plaindre( ?Nom, ?Raison) La variable Raison pourra prendre ses valeurs dans l’ensemble suivant :
{victime, exploite, lesDeux}, sachant qu’un employé est à plaindre s’il est soit une victime, soit exploité,
soit les deux à la fois. (nécessite l’opérateur de négation “\+”).
Exercice 2 : Autre exemple et introduction à la récursivité simple : L’arbre généalogique
On dispose de la généalogie décrite dans l’arbre de la figure 1.
Jean
Paule
Marcelle
Luc Cathy
Audrey
Bertand
Marc
Henri
Nancy
Annie
Tom
Sylvie
Francis Corinne
Jules
Anne
Sam
Aude Thomas
Nicolas
Figure 1: Arbre généalogique utilisé
Q 1 . Le fichier tp1-genealogie-donnees.pl contient les faits permettant de définir cet arbre généalogique
à partir des prédicats :
individu( ?Nom, ?Sexe)
pere( ?Nom1, ?Nom2) , Nom1 est le père de Nom2
mere( ?Nom1, ?Nom2) , Nom1 est la mère de Nom2
Il est disponible depuis le portail de la licence (http://www.fil.univ-lille1.fr/Licence → S5→ELFE
→ Semainier).
Q 2 . Écrivez les prédicats suivants :
1. parent( ?Nom1, ?Nom2) : Nom1 est le père ou la mère de Nom2.
2. est frere de( ?Nom1, ?Nom2) : Nom1 est le frère de Nom2.
3. est soeur de( ?Nom1, ?Nom2) : Nom1 est la sœur de Nom2.
4. sont frere et soeur( ?Nom1, ?Nom2) .
5. est demi frere de( ?Nom1, ?Nom2) : Nom1 est le demi-frère de Nom2.
6. est demi soeur de( ?Nom1, ?Nom2) : Nom1 est le demi-frère de Nom2.
7. sont cousins( ?Nom1, ?Nom2) : Nom1 est Nom2 sont cousin(e)s, càd deux de leurs parents sont frère ou
sœur.
Q 3 . En utilisant la récursivité, écrivez les prédicats suivants :
1. ancetre( ?Nom1, ?Nom2) :Nom1 est ancêtre de Nom2.
2. descendant( ?Nom1, ?Nom2) :Nom1 est un descendant de Nom2.
3. sont apparentes( ?Nom1, ?Nom2) . Deux individus sont apparentés s’ils ont au moins un ancêtre commun.