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.