Vous êtes sur la page 1sur 48

INF242V: Cours de Prolog

Romain Janvier remerciements ` Xavier Girod et Philippe Morat a 18 avril 2007

Table des mati`res e


I Introduction ` Prolog a
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4
4 4 4 4 5 5 5 5 8 8 8 8 9 9 9 9 9 9 10 10 10 10 10 11 11 11 12 12 12 13 13 13 15

1 Introduction 1.1 Prsentation . . . . . . . . . . . . . . . . . . e 1.1.1 Evolution des langages et historique 1.1.2 Les atouts de Prolog . . . . . . . . . 1.2 Approche intuitive de Prolog . . . . . . . . 1.2.1 PROgrammer en LOGique . . . . . 1.2.2 Un peu de vocabulaire . . . . . . . . 1.2.3 Faits-Questions-R`gles . . . . . . . . e 2 Lunivers de gprolog 2.1 Les termes . . . . . . . . . . . . . 2.1.1 Les atomes . . . . . . . . 2.1.2 Les variables . . . . . . . 2.1.3 Les nombres . . . . . . . 2.1.4 Les termes composs . . . e 2.1.5 Reprsentation des termes e

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

. . . . . .

3 Arithmtique en gprolog e 3.1 Les expressions arithmtiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 3.2 Prdicats arithmtiques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e e 3.3 Le prdicat is/2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 4 Dnition dun programme Prolog e 4.1 Exemples de programmes Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.1.1 Le restaurant (suite) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 4.1.2 Elvation a la puissance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ` 5 Le fonctionnement de Prolog 5.1 Lunication . . . . . . . . . . . . . . . . . . . 5.2 Smantique dclarative . . . . . . . . . . . . . e e 5.3 Smantique procdurale . . . . . . . . . . . . e e 5.3.1 Principe . . . . . . . . . . . . . . . . . 5.3.2 Algorithme de la rsolution (simpli) e e 5.3.3 Exemple de rsolution . . . . . . . . . e 5.4 Exemples de programmes . . . . . . . . . . . 5.4.1 La factorielle . . . . . . . . . . . . . . 5.4.2 Concatnation de listes . . . . . . . . e 1

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

. . . . . . . . .

6 Solution des exercices 6.1 Le restaurant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 La multiplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

16 16 16

II

Concepts algorithmiques

17
17 17 17 17 17 17 18 18 18 18 19 19 19 20 20 21 21 21 21 22 22 22 22 22 24 24 24 25 25 26 26 27 27 27 28 29 29 29 29 30 30 30

7 Spcication de prdicats e e 7.1 Dnition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . e 7.2 Exemples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8 Rcursivit et traitement des listes e e 8.1 Introduction . . . . . . . . . . . . . . . . . . . . . 8.1.1 Dnition rcursive dun prdicat . . . . . e e e 8.1.2 Exemples . . . . . . . . . . . . . . . . . . 8.2 Dnition rcurrente dun type (ou type inductif) e e 8.2.1 Dnition rcurrente . . . . . . . . . . . . e e 8.2.2 Dnition rcurrente des listes dlments e e ee 8.2.3 Dnition rcurrente des entiers naturels . e e 8.3 Analyse rcurrente dun prdicat . . . . . . . . . e e 8.3.1 Exemple sur les listes . . . . . . . . . . . 8.3.2 Exemple sur les entiers . . . . . . . . . . . 8.3.3 Evaluation dun nombre en base 2 . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

. . . . . . . . . . .

9 Structures arborescentes 9.1 Dnition et terminologie . . . . . . . . . . . . . . . . . e 9.1.1 Arbres n-aires, forts . . . . . . . . . . . . . . . . e 9.1.2 Convention de reprsentation . . . . . . . . . . . e 9.1.3 Arbres binaires . . . . . . . . . . . . . . . . . . . 9.1.4 Terminologie et dnition (p96 du bouquin PCS) e 9.2 Arbres en Prolog . . . . . . . . . . . . . . . . . . . . . . 9.2.1 Arbre n-aire, forts . . . . . . . . . . . . . . . . . e 9.2.2 Arbre binaires : les trois mod`les . . . . . . . . . e 9.2.3 Traitement rcursifs des arbres n-aires . . . . . . e 9.3 Exemples . . . . . . . . . . . . . . . . . . . . . . . . . . 9.3.1 Arbre binaires . . . . . . . . . . . . . . . . . . . 9.3.2 Arbre n-aires . . . . . . . . . . . . . . . . . . . . 9.3.3 Arbre de recherche binaire (ARB) . . . . . . . . 10 Contraintes sur les domaines nis 10.1 Introduction . . . . . . . . . . . . . . . 10.2 Classication des contraintes . . . . . 10.2.1 Dnition des domaines . . . . e 10.2.2 Contraintes arithmtiques . . e 10.2.3 Information sur les domaines . 10.2.4 Contraintes dnumration . . . e e 10.3 Exemples dutilisations . . . . . . . . . 10.4 Gnrateur dentiers . . . . . . . . . . e e 10.4.1 Rsolution dquations linaires e e e 10.4.2 La factorielle (le retour) . . . . 10.4.3 SEND+MORE=MONEY . . . 10.4.4 Le carr magique . . . . . . . . e

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . . 2

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

. . . . . . . . . . . .

III

Aspects techniques
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

33
33 33 34 35 35 36 37 38 38 39 39 39 39 39 40

11 Un outil de contrle : le coupe-choix o 11.1 Problmatique . . . . . . . . . . . . . . . . . . . . . . . . . . . e 11.2 Dnition du coupe-choix . . . . . . . . . . . . . . . . . . . . . e 11.3 Utilisations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.3.1 Contrle des solutions dans un processus de gnration . o e e 11.3.2 Conrmation du choix dune r`gle . . . . . . . . . . . . e 11.3.3 Expression de nouvelles structures de contrle . . . . . . o 12 Quelques prdicats prdnis de gprolog e e e 12.1 Entres-sorties . . . . . . . . . . . . . . . e 12.2 Gnration de nombres alatoires . . . . . e e e 12.2.1 Initialisation . . . . . . . . . . . . 12.2.2 Tirage . . . . . . . . . . . . . . . . 12.3 Trouver toutes les solutions . . . . . . . . 12.3.1 findall/3 . . . . . . . . . . . . . 12.3.2 bagof/3 et setof/3 . . . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

. . . . . . .

IV

Applications ` la programmation logique a

41
41 41 41 41 41 42 42 43 43 44 44 45 45 45 46 47 47

13 Introduction 14 Probl`mes de gnration-test (generate & test) e e e 14.1 Principe dun programme de gnration et test . . . e e 14.2 Exemples . . . . . . . . . . . . . . . . . . . . . . . . 14.2.1 Nombres entiers multiples de 3 entre 0 et 100 14.2.2 Voyelles dun mot . . . . . . . . . . . . . . . 14.2.3 LES MUTANTS . . . . . . . . . . . . . . . . 14.2.4 Tri par permutation . . . . . . . . . . . . . . 14.2.5 Les huit Reines . . . . . . . . . . . . . . . . . 14.2.6 Le labyrinthe . . . . . . . . . . . . . . . . . . 14.2.7 Conversion nombre Romain/Nombre arabe . 14.2.8 Le fermier, la poule , le renard et le grain . . 15 Solution des exercices 15.1 Les huit Reines . . . . . . . . . . . . . . . 15.2 Le labyrinthe . . . . . . . . . . . . . . . . 15.3 Conversion nombre romain/nombre arabe 15.4 Le fermier, la poule, le renard et le grain .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . . . . . . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

Premi`re partie e

Introduction ` Prolog a
1
1.1

Introduction
Prsentation e

Rfrence Prolog : ee Prolog : F. Giannesini, H. Kanoui, R. Pasero, M. Van Caneghem. InterEditions 1985 Programmer en Prolog : W.F. Clocksin, C.S. Mellish. Editions Eyrolles 1985 Prolog : Fondements et Applications : CONDILLAC. Editions Masson. LART DE Prolog : L. Sterling & E. Shapiro. Editions Masson 1990. Prolog III : Manuel de Rfrence et dUtilisation. PrologIA, 1990. ee GProlog : http ://pauillac.inria.fr/ diaz/gnu-prolog/ GProlog manual : http ://pauillac.inria.fr/ diaz/gnu-prolog/manual/index.html 1.1.1 Evolution des langages et historique

n Langage paradigme autres langages style 1 PASCAL,C impratif ou actionnel e Fortran, ADA,JAVA Fais a c 2 LISP,Scheme applicatif ou fonctionnel Caml, ML Evalue ca 3 Prolog dclaratif ou relationnel C-prolog, Prolog3, SQL que penses tu de a ? e c Degr dexpressivit : n e e Degr de contrle (exprim par le programmeur) : 1/n e o e Nombre de concepts de base utilis (implique une grammaire du langage tr`s simple) : 1/n e e Attention : lexpression dense est souvent peu accessible (5 page de Pascal, 1/2 page Lisp, quelques lignes de Prolog) n Paradigme le programme est son excution consiste ` e a un ensemble dactions dclencher les actions et e 1 impratif e squentielles e modier ltat de variables e une fonction valuation de la fonction e 2 applicatif (composition) avec des param`tres eectifs e un ensemble de r`gles e lancer une rsolution en tenant compte e 3 dclaratif e et de faits des r`gles et de ltat de la base de faits e e Prolog est n dans les annes 70. Il est issu des travaux de Alain Colmerauer a lUniversit de Marseille e e ` e LUMIGNY pour les aspect analyse et conception du langage ; et des travaux sur la logique thorique de e Warren a Edimburgh. ` Le 1er syst`me Prolog interprt a vu le jour a Marseille en 1973, sous la forme dun dmonstrateur de e ee ` e thor`mes. e e ` A lheure actuelle : Plusieurs dialectes et interpr`tes de Prolog existent. Deux coles se retrouvent ici : e e la syntaxe dEdimburgh et le langage associ : C-Prolog (Delphia Prolog, quintus, gprolog, SWI-Prolog) e la syntaxe de Marseille : Prolog II , Prolog III, (Prolog IV) Le syst`me Prolog a lui mme volu : prise en compte de retardement (freeze) en Prolog II, et introduction e e e e des contrainte (numrique, boolenne et sur les arbres) en Prolog III et mme Prolog IV (contraintes sur e e e les rels , contraintes non linaires ). e e 1.1.2 Les atouts de Prolog

aspect dclaratif : la formulation est plus proche des spcications. De plus les connaissances, donne e e e par lutilisateur, sont bien spares du contrle, ralis par linterpr`te. En Prolog III, la mise en place e e o e e e des contraintes (conditions devant tre satisfaites par les composants du programme) permet de se e dgager un peu plus de laspect contrle. e o syst`me complet : le syst`me Prolog se prsente sous la forme dun environnement proposant un ine e e terpr`te, un debuggeur et une batterie de prdicats prdnis. Lutilisateur lance lenvironnement et e e e e droule une session Prolog (comme pour CAML). e 4

Puissance : le syst`me est tr`s puissant du fait des structures de contrle (Moteur dinfrence) de Prolog. e e o e Dans Prolog III, linterpr`te sait rsoudre des syst`mes dquation linaire ` variables rationnelles et e e e e e a des syst`mes boolens. e e Plus quun langage, on peut considrer Prolog comme un syst`me de dmonstration et de rsolution de e e e e syst`mes de contraintes. e

1.2
1.2.1

Approche intuitive de Prolog


PROgrammer en LOGique

Avec Prolog on utilise la logique (syst`me formel) comme langage de programmation. Par analogie, le e syst`me formel ` la base de SCHEME est le -calcul. e a Dans le syst`me formel de la logique on distingue des objets : Jean, la logique ; des proprits sur les e ee objets : heureux ; des relations : aime. qui aime la logique est heureux Exemple : Jean est heureux Jean aime la logique 1.2.2 Un peu de vocabulaire

Dnition 1 Un prdicat est une proprit ou une relation. e e ee Dnition 2 Un argument (de prdicat) est un objet sur lequel porte un prdicat e e e Exemple : heureux(jean). aime(jean,la logique). Dnition 3 Une clause est une phrase du syst`me exprimant que des conditions entranent des conclue e sions. Exemple : si jean aime la logique, alors il est heureux ou fatigu. e Dnition 4 Une clause de Horn est une clause constitue au plus dune conclusion. e e Ce sont les clauses manipules par Prolog. e Dnition 5 La partie conclusion est appel tte de clause, lensemble de conditions est appel queue e e e e de clause. TETE QUEUE Jean est heureux sil aime la logique Prolog III heureux(jean) -> aime(jean,la logique) ; C-Prolog heureux(jean) :- aime(jean,la logique). Remarque : on peut lire la clause de droite a gauche : Si Jean aime la logique alors il est heureux ` Programmer en Prolog (version 1) : cest dcrire ` laide de clause de Horn, les connaissances e a ncessaires pour rsoudre un probl`me. Linterprteur se charge ensuite de trouver les solutions. e e e e 1.2.3 Faits Faits-Questions-R`gles e La proposition : lavocat peut tre consomm en entre nonce une proprit sur lobjet. e e e e e e Exemple :

Dnition 6 Un fait est une relation sur des objets considre comme vraie. e e e Il se note : entree(avocat). calories(avocat,200).

Dnition 7 Une base de faits est un ensemble de faits dcrivant une connaissance donne. e e e Exemple :

entree(salade). entree(avocat). entree(huitre). viande(steak). viande(escalope). calories(salade,15). calories(avocat,220). calories(huitre,70). calories(truite,98). calories(daurade,90).

dessert(raisin). dessert(melon).

poisson(truite). poisson(daurade). calories(raisin,70). calories(melon,27). calories(steak,203). calories(escalope,105).

blanc(sauterne). rouge(lichine). blanc(chablis). rouge(vougeot). Prolog consid`re comme vrai tout fait (prdicat) cit dans la base de faits du programme, et consid`re e e e e comme faux tout ce qui ne peut pas en tre dduit. e e Corollairement, si le programme ne comporte que des faits, tout fait non prsent dans la base est considr e e e comme faux. Questions et variables Une base de fait constitue un programme Prolog, on peut en demander une excution en posant une Question. e Dnition 8 Une Question est un prdicat Prolog dont on cherche ` savoir sil est vri ou non. e e a e e est-il vrai que lavocat est une entre e entree(avocat). Prolog cherche dans sa base la prsence de ce fait, il rpond vrai, yes, sil est prsent, faux, no, sinon. e e e Exemple : quel est le nombre de calories de 100 grammes de steak calories(steak,C). Prolog rpond : C=203 e yes remarque : C (lettre seule) est une variable Prolog, cest a dire une entit non encore dtermine qui ` e e e peut donc prendre une valeur an de permettre de rendre vraie une formule (analogie avec les inconnues dquation en maths). e Exemple : Mcanisme utilis pour rpondre ` une question (approche informelle) Prolog tente de faire e e e a correspondre la question avec les faits disponibles. Si un fait saccorde avec la question alors les variables de la question prennent les valeurs ncessaires. On dit que lon unie la question avec le fait et que les e variables sont instancies. Cette instanciation se fait par construction dune substitution qui est un e ensemble des couples (variable, valeur), gnralement reprsent sous la forme {V ar1 = V al1 , ..., V arn = e e e e V aln }. Exemple (on reprsente les prdicat par des arbres) : e e

QUESTION calories Q= steak C F =

FAIT calories

steak

203

Q et F sont uniables par la substitution = {C = 203}. Dnition 9 Deux prdicat P 1 et P 2 sont Uniables si on peut trouver une substitution telle que e e P 1 = P 2. Dnition 10 Une Substitution est une liste de couples (v, t) tels que le premier lment est une e ee variable et le second un terme Prolog contenant ventuellement des variables. e 6

Dnition 11 Instancier un prdicat P avec une substitution (not P ), cest remplacer dans P e e e toutes les occurrences dune variables de par son expression associe dans . e Dans lexemple prcdent en instanciant Q par , cest ` dire en remplaant dans Q les variables par e e a c leurs valeurs dans la substitution , on obtient : Q = calories(steak, C){C = 203} = calories(steak, 203) = F Exemple : soit P 1 = aime(jean, A) et P 2 = aime(B, laLogique). La substitution = {A = laLogique, B = jean} permet dunier P 1 et P 2. R`gles Un programme Prolog comporte des faits et des r`gles. Les r`gles expriment des relations e e e conditionnelles entre les objets (clauses de Horn). Exemple : le plat principal est soit de la viande soit du poisson Cet nonc conduit a la dnition de deux r`gles Prolog : e e ` e e r1 : plat(V) :- viande(V). r2 : plat(P) :- poisson(P). Remarque : il y a un ou implicite entre r1 et r2. La tte de la r`gle exprime la consquence, la queue exprime une conjonction de conditions (ET e e e implicite). Autrement dit une r`gle : e Tete :- Queue . peut se lire : Pour que Tete soit vrie il faut que les direntes conditions de Queue soient vries. e e e e e On remarquera quil existe une disjonction (OU implicite) entre les deux r`gles r1 et r2. e Pour complter notre exemple nous pouvons exprimer la notion de repas que ce dbut dexemple suscite e e en exprimant quil est constitu dune entre dun plat principal et dun dessert. e e r3 : repas(E,P,D) :- entree(E),plat(P),dessert(D). Remarque : il y a un et implicite entre entree(E), plat(P) et dessert(D) : Un repas est constitu e dune entre ET dun plat ET dun dessert. e En ajoutant les r`gles r1, r2 et r3 (ou clauses) a la base de Prolog, on peut maintenant construire des e ` repas. Des questions peuvent tre : e ?- repas(crepes,escalope,raisin). Peut-on avoir un repas comportant des crpes, de lescalope et du raisin ? e no, rponse NON e ?-repas(E,escalope,D). quels sont les repas comportant de lescalope ? E=salade D=raisin ? ; E=salade D=melon ? ; E=avocat D=raisin ? ; E=avocat D=melon ? ; E=huitre D=raisin ? ; E=huitre D=melon ? 6 solutions de repas avec de lescalope Remarque : Lorsque gprolog pense quil peut y avoir dautres rponses possibles, il demande ` lutilisateur e a sil doit continuer lexploration en utilisant le caract`re ?. Si lutilisateur appuie sur ;, gprolog e cherche la rponse suivante. Sil en trouve une autre il lache sinon il ache no pour dire quil ny en e a pas dautres. Si lutilisateur appuie sur Entre, gprolog arrte lexploration. Enn il est galement e e e possible dappuyer sur a pour obtenir toutes les autres solutions1 . Les questions peuvent tre elles-mmes des conjonctions : e e
1 Attention

le nombre de solutions est ventuellement tr`s grand, voir inni ! e e

?- repas(E,P,D),poisson(P). Cette question demande lensemble des repas qui comportent comme plat principal du poisson. Si dans le principe cette question est semblable ` poisson(P),repas(E,P,D) du point de vue de lexcution elles a e se direncient par leur valuation (et leur cot). e e u On remarquera que la rsolution des buts de la question se fait de gauche a droite. e `

repas(E,P,D),poisson(P) {} entree(E),plat(P),dessert(D),poisson(P) {E=Salade} plat(P),dessert(D),poisson(P) {E=Salade} {E=Salade}

viande(P),dessert(D),poisson(P) poisson(P),dessert(D),poisson(P) {E=salade,P=steak} dessert(D),poisson(P) {E=salade,P=truite} dessert(D),poisson(P)

{E=salade,P=steak,D=raisin} {E=salade,P=truite,D=raisin} poisson(P) ECHEC poisson(P) ECHEC poisson(P) SUCCES {E=salade,P=truite,D=raisin}

2
2.1

Lunivers de gprolog
Les termes

Le domaine de gprolog est constitu dobjets appels termes. Il y a quatre sortes de termes : les atomes, e e les variables, les nombres et les termes composs. e 2.1.1 Les atomes

Un atome est soit : Une cha de caract`res faite de majuscules, minuscules de chires et du blanc soulign, qui commence ne e e par une minuscule. Par exemple : marylin monroe, joe123. Une suite arbitraire de caract`res entre guillemets simples. Par exemple Je suis un atome, e l"arbre. Evidemment il nest pas possible de mettre de guillemets simples dans un atome. Une suite de caract`res spciaux. Par exemple : , et :- sont des atomes qui ont un sens prdni. e e e e Notons que si un atome peut scrire sans guillemets simples, il est considr comme identique au mme e e e e atomes sans les guillemets : abcd=abcd et =<==<. 2.1.2 Les variables

Une variable est une suite de majuscules, de chires et de blancs souligns qui commence par une mae juscule ou par un blanc soulign. Par exemple X, Y, Liste, tag, X 67 sont des variables. e La variable est appele la variable anonyme. Elle indique a Prolog que lon ne sintresse pas ` la valeur e ` e a de cette variable. Par exemple la requte entree( ) demande juste sil existe une entre, peut importe e e son nom.

2.1.3

Les nombres

On peut utiliser les entiers ou les rels (ottants) : 33, -33, 33.0, 33E+02. e 2.1.4 Les termes composs e

Les termes sont dnis selon la grammaire suivante : e Terme ::= Atome | Variable | Nombre | Terme-compos e Terme-compos::= Atome(Terme{, Terme}) e Latome qui dbute un terme compos est le foncteur du terme. Par exemple calorie est le foncteur de e e calorie(salade,15). Larit dun prdicat est le nombre darguments des ttes de clauses dnissant ce prdicat. Par exemple e e e e e entree est darit 1 et calorie est darit 2. Il est possible de dnir plusieurs prdicats darits direntes e e e e e e mais avec le mme foncteur. On les distingue alors en utilisant la notation Prdicat/Arit, reprsentant e e e e le prol du prdicat ou du terme. Par exemple calorie/2 est le prol du prdicat calorie(X,Y). e e Il est possible de tester ` quelle catgorie appartient un terme en utilisant les prdicats prdnis suivants : a e e e e atom/1, var/1, nonvar/1, integer/1, float/1, number/1, atomic/1, compound/1 et callable/1. 2.1.5 Reprsentation des termes e

Gnralement les termes composs sont reprsents sous forme darbre. Ainsi le terme f1(f2(a1,a2),a3) e e e e e est reprsent par larbre suivant : e e

f1 f2 a1 a2 a3

3
3.1

Arithmtique en gprolog e
Les expressions arithmtiques e

Une expression arithmtique est un terme fait de nombre et de foncteurs ou oprations reprsentant des e e e fonctions arithmtiques. Les principaux oprateurs sont : +, -, *, / (division relle), // (division enti`re), e e e e rem (reste) et ** (puissance).

3.2

Prdicats arithmtiques e e

Les oprateurs suivants permettent de manipuler les expression arithmtiques : e e 1. Expr1 =:= Expr2 russit si les valeurs des deux expressions sont gales. Par exemple 2*3=:=1+5 e e russit mais 2*3=:=5 choue. e e Il ne faut pas confondre ce prdicat avec le prdicat dunication =. Par exemple 2*3=6 choue e e e parce que les deux termes ne sont pas uniables. Le terme 2*3 est un terme compos (en fait il e correspond au terme *(2,3)) alors que 6 est un entier. 2. Expr1 =\= Expr2 russit si les valeurs des deux expressions sont direntes. e e 3. Expr1 < Expr2 russit si la valeur de Expr1 est strictement infrieure a celle de Expr2. e e ` 4. Expr1 =< Expr2 russit si la valeur de Expr1 est infrieure ou gale a celle de Expr2. e e e ` 5. Expr1 > Expr2 russit si la valeur de Expr1 est strictement suprieure a celle de Expr2. e e ` 6. Expr1 >= Expr2 russit si la valeur de Expr1 est suprieure ou gale a celle de Expr2. e e e ` Pour chacun de ces prdicats, si une des deux expressions nest pas valuable parce quelle contient des e e variables non instancies, gprolog retourne un message derreur. La requte X=:=3 produit un message e e derreur alors que la requte X=3,X=:=1+2 russit. e e Les prdicats = et \= permettent de tester si des termes sont uniables ou non. La faon dont gprolog e c g`re les unications est prsente dans la section 5.1. e e e

3.3

Le prdicat is/2 e

La requte R is Expr russit si la valeur de Expr sunie avec R. Ce prdicat sert gnralement ` donner e e e e e a une valeur a une variable. Par exemple la requte X is 2+3 donne a X la valeur 5 et X is Y+1 donne a X ` e ` ` la valeur de Y plus 1 si Y a une valeur. Si Y na pas encore de valeur, gprolog produit un message derreur. Attention la requte 2+3 is 5 choue puisque le terme 2+3 (correspondant en fait au terme +(2,3)) e e ne sunie pas avec 5.

Dnition dun programme Prolog e

Un programme Prolog correspond a un prdicat. Il est compos dun ensemble de clauses qui sont soit ` e e des faits, soit des r`gles. On parle aussi de paquet de clauses. Toutes les ttes des clauses dun programme e e Prolog doivent avoir le mme prol, cest a dire le mme foncteur et la mme arit. e ` e e e Les clauses : fct(0,1). fct(X,Y) :- ... . constituent un mme programme, correspondant au prdicat fct/2 alors que les clauses suivantes e e dnissent 2 programmes dirents : e e fct(X,Y) :- ... . fct(X,Y,Z) :- ... .

4.1
4.1.1

Exemples de programmes Prolog


Le restaurant (suite)

Soit la base de faits Prolog suivante : entree(artichauts). viande(grillade). dessert(sorbet). entree(avocat). viande(poulet). dessert(fraise). entree(cresson). poisson(dorade). poisson(bar). et les r`gles : e plat(P) :- viande(P). plat(P) :- poisson(P). repas(E,P,D) :- entree(E),plat(P),dessert(D). repasCal(E,P,D,C) :- repas(E,P,D),calories(E,C1),calories(P,C2),calories(D,C3), C is C1+C2+C3. Exercice : 1. Ecrire la clause qui dcrit un repas de rgime hypocalorique (valeur calorique < 600). e e 2. Complter le programme repas en ajoutant une boisson a choisir parmi le vin blanc (meursault, e ` chablis), le vin rouge (vougeot, cornas) et leau (vals, evian). Ajouter les r`gles qui permettent e de ne servir que du vin rouge avec la viande et du vin blanc ou de leau avec le poisson. 4.1.2 e Elvation ` la puissance a

On ralise un prdicat puissance darit 3 : puissance(X,N,P), signiant que XN = P. e e e On sappuie sur la dnition rcurrente : e e 1. X 0 = 1 do` le programme Prolog suivant : u puissance( ,0,1). puissance(X,N,P) :- N>0, N1 is N-1, puissance(X,N1,P1) , P is P1*X. On remarquera lutilisation de la variable anonyme dans la premi`re r`gle. Cest parce que la valeur du e e premier param`tre na aucune importance dans le cas o` le deuxi`me vaut 0. Si nous utilisons une variable e u e non anonyme telle que X, gprolog ache un avertissement disant que X nappara quune fois dans la t r`gle. Il faut alors se demander si X peut tre remplac par la variable anonyme ou si on a juste oubli e e e e dutiliser X ailleurs dans la r`gle. e 10 2. X n = X n1 X, avec n > 0

5
5.1

Le fonctionnement de Prolog
Lunication

Lunication est lopration lmentaire que ralise Prolog pour rendre deux termes identiques. Cette e ee e opration consiste a tablir une substitution (ensemble de couples (variable, valeur)) qui permettra dobe `e tenir une quivalence des deux termes. Cette substitution peut tre assimile ` un ensemble de contraintes e e e a que lon fait porter sur les variables de la substitution. Cette opration peut chouer si aucune substitue e tion ne permet dobtenir cette quivalence. Lunication est dpendante du fait quapparaissent ou non e e des variables dans les termes, que les termes soient atomiques ou non. Deux termes atomiques sont uniables sils sont identiques, une variable libre sunie toujours en sinstanciant a lautre terme, ` une variable instancie se comporte comme son terme, e lunication de deux variables libres les lie, toutes les variables lies ne peuvent sinstancier quau mme terme, e e deux termes composs sunient composant a composant. e ` Terme 1 Terme 2 ?ok substitution commentaire deux termes atomiques sont aa aa oui {} uniables sils sont identiques aa bb non si un des deux termes est une variable libre, lunication A bb oui {A=bb} est toujours possible

a b a X Y a X Y a b d c X X b c b c Y c a Y d X Y a

a
oui

{X=c,Y=b}

b X

oui

{X=c,Y=c}

les variables X et Y sont lies e

b X a

non

{X=Y, X=c, Y=d}

lunication de X avec c ncessiterait e lunication des deux termes atomiques c et d.

oui

{X=b, Y=c(d,b)}

on donne la valeur de Y en remplaant X c par sa valeur

En gprolog lunication de deux termes se note en utilisant le prdicat terme1 = terme2 et la non e unication se note en utilisant terme1 \= terme2.

5.2

Smantique dclarative e e

On utilise Prolog avec une approche relationnelle. Prolog permet dtablir des relations entre des objets. e Si dans la question on utilise des variables, alors Prolog va fournir la substitution (ensemble de valeurs des variables) qui permet de former une relation dductible de la base initiale. e

11

5.3
5.3.1

Smantique procdurale e e
Principe

On peut considrer le moteur de la rsolution de Prolog comme une boite noire qui reoit en entre e e c e une question et produit en sortie soit un chec soit un succ`s constitu par un ensemble de substitutions. e e e Pour obtenir les solutions a la question pose Prolog utilise la base initiale pour prouver les armations ` e non directement prsentes dans la base en faisant des unications. e 5.3.2 Algorithme de la rsolution (simpli) e e

Une question est reprsente par une rsolvante qui est constitue dune conjonction de termes. La e e e e cardinalit dune rsolvante est le nombre de termes qui la compose. e e T1 (A1 , ..., A1 ), T2 (A2 , ..., A2 ), ..., TK (...) 1 N 1 M Prolog va chercher a eacer tous les termes de la rsolvante. Il essaie par drivation successive dobtenir ` e e une rsolvante vide (de cardinalit 0). Sil y arrive alors il y a succ`s et la substitution obtenue donne e e e les conditions de succ`s. Sil ny parvient pas il y a alors chec. Si on note Ri une rsolvante, on peut e e e schmatiser le principe de Prolog de la mani`re suivante : R1 est la rsolvante initiale correspondant a la e e e ` question. R1 R2 R3 ... RN

Leacement dun terme se fait en remplaant le terme par un quivalent, on peut parler de rcriture. c e ee Les rcritures sont dcrites par les faits et les r`gles introduites dans la base initiale. La r`gle T :- Q. ee e e e tablit que T peut tre remplac par Q. Le fait T. tablit que T se remplace par vide (). e e e e a e Pour passer de la rsolvante Ri ` la rsolvante Ri+1 Prolog doit choisir un terme pour essayer de leacer. e Prolog fonctionne de gauche ` droite et en profondeur dabord. Il choisit donc de rcrire le terme a ee T1 et place la rcriture du terme T1 en tte de la nouvelle rsolvante. La substitution i obtenue pour ee e e e e e a e unier T1 avec la tte de la r`gle choisie est applique ` tous les autres termes de la rsolvante : Ri = T1 (A1 ...A1 ), T2 (A2 ...A2 ), ..., T K (...) 1 1 N M Ri+1 = Q, T2 (A2 , ..., A2 )i , ..., TK (...)i 1 M Leacement dun terme ` laide dun fait est tel que Q = et donc : a On peut donc comprendre que Prolog ne drive vers la rsolvante vide que par lutilisation de faits de la e e base initiale. Leacement dun terme ` laide dune r`gle est tel que Q = et donc : a e card(Ri+1 ) card(Ri ) e Pour eectuer leacement du terme T1 Prolog recherche dans la base initiale un clause dont la tte sunie avec le terme T1 . Si une telle clause nexiste pas, il ne peut pas y avoir eacement et donc Prolog ne peut driver vers la rsolvante vide ce qui conduit a un chec. Si une telle clause existe : e e ` e 1 1 T1 (U1 ...UN ) :- Q. 1 1 la substitution i permettant lunication de T1 (U1 ...UN ) et de T1 (A1 ...A1 ) est mmorise. En cas de e e 1 N russite de la rsolution, la substitution permettant le succ`s est construite ` partir de toutes les e e e a e e substitutions i utilises lors des drivations. Prolog tant un langage non dterministe, il cherche ` produire toutes les solutions (syst`me de e e a e contraintes) qui permettent de satisfaire la question. Il va donc chercher a raliser tous les eacements ` e possibles pour un terme de la rsolvante et va parcourir un arbre de rsolution. Il fait ce parcours en e e profondeur dabord. An deacer le terme T1 = pre(A1, ...An), Prolog parcourt lensemble des clauses correspondant au programme pre/n dans lordre dans lequel elles ont t dnies dans la base initiale. Cet ordre a donc ee e une tr`s grande inuence sur le comportement ` lexcution dune rsolution. Lorsque Prolog ne peut e a e e e pas trouver de clause pour rcrire T1 il backtrack (retourne en arri`re) pour explorer un autre chemin ee de rsolution. Il le fait aussi lorsquil a obtenu une rsolvante vide (une solution) pour fournir les autres e e solutions potentielles. Prolog explore donc un arbre de rsolvante dont les feuilles sont soit des rsolvantes e e vides soit des rsolvantes dont le premier terme (gauche) ne peut tre eac. Lorsquil backtrack dune e e e rsolvante ` la rsolvante prcdente Prolog dfait toutes les substitutions introduites lors des unications e a e e e e successives produites a partir de cette rsolvante. ` e 12 card(Ri+1 ) = card(Ri ) 1

5.3.3

Exemple de rsolution e

Prenons lexemple du calcul de la multiplication dun entier naturel X par un entier Y par additions successives (multiplication Egyptienne). Nous donnons volontairement une expression de lalgorithme qui nest pas rduite. e r1 mlt(X,Y,R) :- Y<0,Y1 is -Y,mlt(X,Y1,R1),R is -R1. e r2 mlt( ,0,0). /* 0 est elment absorbant de la multiplication */ r3 mlt(X,1,X). /* 1 est elment neutre de la multiplication */ e r4 mlt(X,Y,R) :-Y1 is Y-1,Y1>0,mlt(X,Y1,R1),R is R1+X. Puisque ce programme est rcursif, la mme r`gle peut tre utilise plusieurs fois dans la rsolution. An e e e e e e dviter toute confusion sur les variables telles que X, Y et R qui pourraient tre appara plusieurs fois, e e tre e nous eectueront des renommage du type iX, iY et iR. Ce renommage est eectu en interne par le moteur de rsolution de Prolog. e mlt(10,-2,A) tentative dunication avec r1 russie 1 = { 1X = 10, 1Y = 2, 1R = A} e -2<0, 1Y1 is --2,mlt(10, 1Y1, 1R1),A is - 1R1 -2<0 et 1Y1 is --2 sliminent et produisent 2 = { 1Y1 = 2} e mlt(10,2, 1R1),A is - 1R1 tentative dunication avec r1 russie avec 3 = { 2X = 10, 2Y = 2, 2R = 1R1} e 2<0, 2Y1 is -2,mlt(10, 2Y1, 2R1), 1R1 is - 2R1,A is - 1R1 backtrack car 2<0 est faux. mlt(10,2, 1R1),A is - 1R1 tentative dunication avec r2 choue 2 nest pas nul e tentative dunication avec r3 choue 2 nest pas gal a 1 e e ` tentative dunication avec r4 russie 3 = { 3X = 10, 3Y = 2, 3R = 1R1} e 3Y1 is 2-1, 3Y1>0,mlt(10, 3Y1, 3R1), 1R1 is 3R1+10,A is - 1R1 limination des deux premi`res clauses avec la substitution 4 = { 3Y1 = 1} e e mlt(10,1, 3R1), 1R1 is 3R1+10,A is - 1R1 tentative dunication avec r1 russie avec 5 = { 4X = 10, 4Y = 1, 4R = 3R1} e 1<0, 4Y1 is -1,mlt(10, 4Y1, 4R1), 4R1 is - 3R1, 1R1 is 3R1+10,A is - 1R1 backtrack car 1<0 est faux. mlt(10,1, 3R1), 1R1 is 3R1+10,A is - 1R1 tentative dunication avec r2 choue 2 nest pas nul e tentative dunication avec r3 russie avec 6 = { 3R1 = 10} e 1R1 is 10+10,A is - 1R1 limination des deux derniers termes avec 7 = { 1R1 = 20, A = 20} e russite avec la solution A=-20. e En exercice : 1. Vriez quil ny a pas dautres solutions possibles. e 2. Ecrivez une version de mlt avec seulement 3 r`gles. e

5.4
5.4.1

Exemples de programmes
La factorielle

Plusieurs programmes peuvent tre la solution a un mme probl`me. Prolog ne droge pas a cette constae ` e e e ` tation, et nous allons dans cet exemple donner plusieurs versions pour crire le calcul de la factorielle. e Factorielle que nous dnoterons fac est un prdicat qui associe un entier positif ou nul et un entier e e positif tel que le second est gal a la factorielle du premier. e ` Voici une premi`re version du programme : e fac(0,1). fac(N,R) :- N1 is N-1,fac(N1,R1),R is R1*N. Cette dnition Prolog est tr`s proche de la dnition rcurrente que lon fait de la factorielle. La premi`re e e e e e clause du programme correspond au cas de base de la rcurrence et exprime que la factorielle de 0 est 1. e La seconde clause du programme exprime que la factorielle de N est gale a R1 N o` R1 est la factorielle e ` u de N 1. Ayant introduit ce programme dans la base initiale, on peut poser des questions concernant ce prdicat. e

13

?- fac(0,1). true ? yes On a dans cet exemple pos une question sans variable, le syst`me Prolog va donc rpondre vrai (true) e e e si la relation exprime dans cette question est vriable ou faux (no) sinon. Ici la solution est simple e e puisquun fait de la base initiale exprime directement cette relation. Nanmoins puisque le terme de la e question peut sunier avec la deuxi`me r`gle de fac, Prolog demande sil doit continuer lexploration e e pour trouver une autre solution. En appuyant sur Entre on lui dit darrter l` et il rpond yes car il e e a e a trouv une solution. Sinon en appuyant sur ; il cherche dautres solutions et rpond no puisquil ny e e en a pas dautres. On peut bien videmment obtenir une rponse similaire par dduction comme dans lexemple suivant : e e e ?- fac(4,24). true ? yes On peut poser une question qui comporte des variables, Prolog rpond alors en fournissant les contraintes e portant sur ces variables. dans lexemple suivant fac(4,F) est une relation valide si F est gale a 24. e ` ?- fac(4,F). F=24 ? yes Prolog tant relationnel dans un prdicat les arguments ne sont pas direnciables comme dans un e e e syst`me fonctionnel o` il y a des arguments en entre et dautres en sortie. cela veut dire que nimporte e u e quel argument dune question peut tre remplac par une variable . Nanmoins ce programme ne marche e e e pas si le premier argument est une variable : ?- fac(N,6). uncaught exception : error(instantiation eror,(is)/2) Cela vient du prdicat is/2 qui a besoin davoir a droite une expression valuable. Or dans ce cas, N e ` e tant libre, N-1 nest pas valuable. Nous verrons plus tard dans le cours une autre version de fac qui e e marche si le premier param`tre est une variable. e Ce programme pose un autre probl`me : il ne termine pas si on lui demande de chercher une autre e solution : ?- fac(0,1). true ? ; Fatal Error : local stack overflow Observons le droulement de la rsolution : e e fac(0,1) limination du terme par unication avec la premi`re r`gle e e e demande dune autre solution, donc retour au terme prcdent e e fac(0,1) unication avec la seconde r`gle avec 1 = { 1N = 0, 1R = 1} e 1N1 is 0-1,fac( 1N1, 1R1),1 is 1R1*0 limination du is avec 2 = { 1N1 = 1} e fac(-1, R1),1 is 1R1*0 application de la premi`re r`gle impossible e e unication avec la seconde r`gle avec 3 = { 2N = 1, 2R = R1} e 2N1 is -1-1,fac( 2N1, 2R1), R1 is 2R1*-1,1 is 1R1*0 limination du is avec 4 = { 2N1 = 2} e fac(-2, 2R1), R1 is 2R1*-1,1 is 1R1*0 ... Lexcution est innie puisqu` chaque fois lunication russie avec la seconde r`gle et quil nest plus e a e e possible dunier avec la premi`re r`gle, qui est la seule pouvant arrter le calcul. La mmoire explose e e e e parce que la clause grossit ` chaque fois. a Le probl`me vient du fait que rien nempche lutilisation de la seconde r`gle avec des valeurs ngatives e e e e pour le premier param`tre. Or la factorielle nest dnie que pour les valeur positives. Il faut donc rajouter e e ce test dans le programme. Nous obtenons donc : fac(0,1). fac(N,R) :- N>0,N1 is N-1,fac(N1,R1),R is R1*N.

14

Remarque : lajout du test a la n de la queue nempcherait pas la non terminaison. Lordre dans lequel ` e sont donns les termes de la queue est donc tr`s importante. e e 5.4.2 Concatnation de listes e

Dans gprolog les listes sont reprsentes en extension, par exemple [X1,X2,X3] pour une liste de longueur e e 3, ou par lajout dun lment a gauche, sous la forme [X|L], o` X est ajout ` la liste L. Une prsentation ee ` u ea e plus compl`te se trouve dans la section 8. e Il sagit dun exemple classique dutilisation de laspect relationnel de Prolog. concat est un prdicat qui e poss`de 3 arguments qui sont des listes tel que le 3-i`me argument est la concatnation des 2 premiers. e e e concat([],Z,Z). concat([X|Y],Z,[X|R]) :- concat(Y,Z,R). On peut envisager 4 situations distinctes dutilisation de ce prdicat en fonction de la nature variable ou e constant des arguments. Situation 1 : tous les arguments sont instancis. e On vrie que les 3 arguments respectent la spcication de la concatnation. e e e ?- concat([a,b,c],[d,e,f],[a,b,c,d,e,f]). yes ?- concat([1,2],[3],[1,2,3,4]). no Prolog rpond juste avec yes ou no. e Situation 2 : un des arguments est libre. Prolog cherche alors une substitution permettant de satisfaire la spcication du prdicat : e e ?- concat([1,2],[3],Z). Z=[1,2,3] yes ?- concat([1,2],Z,[1,2,3]). Z=[3] yes ?- concat(Z,[1,2,3],[1,2,3]). Z=[] ? yes Remarquez que dans le dernier cas Prolog ne se rend pas compte tout seul quil ny a pas dautres possibilits. Cela vient du fait que pour discriminer les clauses qui ne permettront pas de donner de e solutions, Prolog essaie juste dinstancier le premier argument du premier terme. Dans ce cas Z pouvant sunier avec [] pour la premi`re clause et avec [X|Y] pour la seconde clause, Prolog pense que la e deuxi`me clause peut peut-tre donner une autre solution. e e Situation 3 : deux des arguments sont des variables. Prolog va chercher une substitution pour ce couple de variables. On peut distinguer trois sous cas suivant quel est largument constant. 1. Le troisi`me argument est constant e ?- concat(X,Y,[1,2,3]). X = [] Y = [1,2,3] ? ; X = [1] Y = [2,3] ? ; X = [1,2] Y = [3] ? ; X = [1,2,3] Y = [] ? ; no Prolog num`re toutes les substitutions telles que [1,2,3] est la concatnation de X et Y. e e e 2. Le premier argument est constant ?- concat([1,2,3],X,Y). Y = [1,2,3|X] yes Il ny a quune solution mais dans laquelle X est une liste quelconque. 3. Le second argument est constant 15

?- concat(X,[1,2,3],Y). X = [] Y = [1,2,3] ? ; X = [A] Y = [A,1,2,3] ? ; X = [A,B] Y = [A,B,1,2,3] ? yes Il y a une innit de solutions. e Situation 4 : tous les arguments sont des variables ?- concat(X,Y,Z). X = [] Z = Y?; X = [A] Z = [A|Y] ? ; X = [A,B] Z = [A,B|Y] ? ; X = [A,B,C] Z = [A,B,C|Y] ? yes Prolog fournit toutes les solutions formelles.

6
6.1

Solution des exercices


Le restaurant
1. Repas hypocalorique : regime(E,P,D) :-repasCal(E,P,D,C),C<600. 2. Ajout des boissons : eau(vals). eau(evian). rouge(vougeot). rouge(cornas). blanc(meursault). blanc(chablis). boisson(B) :- rouge(B). boisson(B) :- blanc(B). boisson(B) :- eau(B). repas(E,P,D,B) :- repas(E,P,D),boisson(B). Choix des boissons : repas2(E,P,D,B) :- repas(E,P,D,B),poisson(P),blanc(B). repas2(E,P,D,B) :- repas(E,P,D,B),poisson(P),eau(B). repas2(E,P,D,B) :- repas(E,P,D,B),viande(P),rouge(B).

6.2

La multiplication

Version simplie : e mlt( ,0,0). /* 0 est elment absorbant de la multiplication */ e mlt(X,Y,R) :- Y>0,Y1 is Y-1,mlt(X,Y1,R1),R is R1+X. mlt(X,Y,R) :- Y<0,Y1 is -Y,mlt(X,Y1,R1),R is -R1.

16

Deuxi`me partie e

Concepts algorithmiques
7
7.1

Spcication de prdicats e e
Dnition e

La spcication est une description permettant de dnir le rle et les conditions dutilisation dun e e o prdicat. e Elle tablit un contrat entre lutilisateur du prdicat (de la fonction, du programme) - appel le client, e e e et celui qui ralise le prdicat - le fournisseur. e e Pour le client : la spcication nonce les conditions qui doivent tre satisfaite par le client avant la e e e rsolution et dnit les conditions quon peut en attendre en retour. e e Pour le fournisseur : la spcication dnit les conditions que lon est sur davoir en entre et les conditions e e e de sortie qui doivent tre satisfaites. e En Prolog : soit un prdicat de prol P/n, cest a dire qui se reprsente sous la forme : e ` e P(a1,a2,...,an) La spcication doit prciser : e e les domaines de dnitions de chacun des param`tres e e les conditions dinstanciation des dirents param`tres avant lappel, appels modes : e e e +a : indique le param`tre doit tre instanci e e e -a : indique que le param`tre doit tre libre e e ?a : instanciation indirente e (rem : on peut dnir plusieurs modes ex : P(+a,-b), P(-a,+b)) e la relation dnie par le prdicat (rle du prdicat) e e o e enn, on peut avoir a prciser si le prdicat est backtrackant, cest a dire sil peut conduire a plusieurs ` e e ` ` solutions.

7.2

Exemples

factorielle : /* N entier >=0, R entier fact(+N, ?R) : R est la factorielle de N */ concatnation : e /* A, B, C : listes dlments e e concat( ?A, ?B, ?C) : C est la concatnation de A et B (C=A.B) e concat(-A,-B, ?C), concat(-A, ?B,-C) sont backtrackants */

8
8.1

Rcursivit et traitement des listes e e


Introduction

` (cf cours dinfo langages et programmation Scholl & al. THEME 1- notation fonctionnelle) Dnition 12 La rcursivit cest la possibilit de dnir une entit, un objet, un type, une fonction, e e e e e e un prdicat ... en terme de lui-mme. e e Exemple : un entier naturel se dnit par : e 0 ou n+1 o` n est un entier naturel. u Elle fait appel au raisonnement par rcurrence (maths) e 8.1.1 Dnition rcursive dun prdicat e e e

La dnition dun prdicat est dite rcursive si au moins une r`gle du programme Prolog correspondant e e e e comporte dun sa queue au moins une occurrence du prdicat. Sil y a plusieurs occurrence du prdicat, e e on parle de rcursivit multiple. e e 17

Rcursivit directe : e e P(a,b) :- Q(c,d), P(e,f). Rcursivit croise : e e e P(a,b) :- Q(c,d). Q(a,b) :- P(c,d).

8.1.2

Exemples

les prdicats fact, concat, mult vus prcdemment. e e e Suite de Fibonacci : dnition rcurrente : e e F(0) = F(1) = 1 F(N+2) = F(N+1)+F(N), N0 n: 012345 F(n) : 112358 Programme Prolog : /* N et R entiers >=0 fibo(+N, ?R) : R est le Ni`me nombre de la suite de Fibonacci */ e (r1) fibo(0,1). (r2) fibo(1,1). (r3) fibo(N,R) :- N>=2, N1 is N-1, N2 is N-2, fibo(N1,R1),fibo(N2,R2),R is R1+R2.

8.2

Dnition rcurrente dun type (ou type inductif) e e

Un prdicat rcursif sappuie sur les dnitions rcurrentes des domaines des objets (types) quil manipule. e e e e Rappel sur le types : un type est un ensemble dobjets munis doprations (constructeurs, testeurs, e slecteurs). e Exemple : le type date (heure, minute, seconde) constructeur date(H,M,S,D) : D est la date construite avec H, M et S testeurs : avant(D1,D2) : la date D1 est avant la date D2 slecteur : heure(D,H) : H est lheure de la date D etc... e Un type peut se dnir en extension ou en comprhension (par ex. pour les entiers naturels impairs e e e I : extension : I= {1,3,5,7,...}, comprhension : I= {x |(x + 1) est divisible par 2}) ou de mani`re e rcurrente. e 8.2.1 Dnition rcurrente e e

On dnit lensemble de base et lensemble des r`gles de rcurrence : e e e base : ensemble des lments de base qui permettent de construire les autres lments. ee ee r`gles de rcurrence : r`gles qui dnissent la mani`re de construire un lment de lensemble a partir e e e e e ee ` dautres lments. ee Pour I : base= {1} rcurrence= si x I , alors x + 2 I. e Pour toute dnitions rcurrentes il faut : e e dcrire la base e dcrire les r`gles de rcurrence e e e sassurer que les r`gles permettent datteindre tous les lments e ee 8.2.2 Dnition rcurrente des listes dlments e e ee

Une liste dlments est un ensemble ordonn dlments, pas forcment du mme type. Exemple [1,2,3] ee e ee e e et [2,1,3] sont des listes direntes. e Par exemple un texte est une liste dentier, correspondant au code ASCII des caract`res : e "abs"=[97,98,99] Dnitions rcurrentes : e e 18

1. base : [] rcurrence : si L est une liste alors X.L est une liste (ajout ` gauche) e a ex : [1,2,3]=1.(2.(3.[])) 2. base : [] rcurrence : si L est une liste alors L.X est une liste (ajout ` droite) e a 3. base : [], [X], pour tout lment X. ee rcurrence : si L est une liste alors X.L.Y est une liste (ajout ` gauche et ` droite) e a a ex : [1,2,3] = 1.[2].3 [1,2,3,4] = 1.(2.[].4).3 Dans Prolog cest la premi`re dnition qui est utilise. Lajout dun lment a gauche est not .(X,L), e e e ee ` e ou plus gnralement [X|L]. Lajout de plusieurs lments se note [X1,X2,X3|L]. e e ee 8.2.3 Dnition rcurrente des entiers naturels e e

Dans les dnitions 1) et 2) il ny a quune faon dobtenir un entier donn : e c e Dans la dnition 3) il y en a plusieurs (un entier est la somme de plusieurs couples dentiers). e 5 = 2 2 + 1 = 2 (2 1) + 1 = 2 (2 (2 0 + 1)) + 1

1. base : 0 rcurrence : x x + 1 e 2. base : 0 rcurrence : x 2x et 2x + 1 e 3. base : {0, 1} rcurrence : {x, y} x + y e

8.3

Analyse rcurrente dun prdicat e e

On sappuie sur la dnition rcurrente dun ou plusieurs param`tre pour faire une analyse par cas. Ces e e e dirents cas conduisent ` autant de r`gles Prolog. Pour les r`gles rcursives, on utilise la dnition e a e e e e rcurrente des types des param`tres pour dcomposer ces param`tres (lappel rcursif devant converger, e e e e e cest ` dire que lon fait appel a un lment du type qui permet de se rapprocher de la base). a ` ee 8.3.1 Exemple sur les listes

la premi`re dnition rcurrente des listes conduit a une analyse en deux cas (liste vide, liste non vide) e e e ` et ` une dcomposition premier/n. La n dune liste correspondant a la liste prive de son premier a e ` e lment. ee 1. longueur dun liste dentiers /* L : liste dentiers, Y : entier longueur( ?L, ?Y) : Y est la longueur (nbre dlments) de L e e longueur(-L,-Y) est backtrackant */ (1) longueur([],0). (2) longueur([ |L],Y) :- longueur(L,Y1), Y is Y1+1. Ce qui se lit : la longueur de la liste vide est zro (base de la rcurrence), soit Y1 la longueur de L e e (hypoth`se de rcurrence), alors la longueur de [ |L] est Y1+1. e e Exemple dutilisation : longueur([1,2,3],Y). Remarque : ce prdicat boucle si on demande une autre solution dans le cas longueur(-L,+N). En e exercice, trouvez pourquoi. En Prolog le prdicat longueur est length/2. e 2. lment maximum dune liste dentiers ee /* L : liste dentiers non vide, M : entier max(+L, ?M) : M est llment maximum de la liste L*/ e e (r1) max([X],X). /* liste a un seul lment */ ` e e (r2) max([X,Y|L],X) :-max([Y|L],M),X>=M. (r3) max([X,Y|L],M) :-max([Y|L],M),M>X. e e Remarque : le prdicat max list/2 est prdni en Prolog. e 19

3. comparaisons de deux listes /* L1,L2 : des listes dlments e e egalList( ?L1, ?L2) : L1 et L2 sont des listes identiques egalList(-L1,-L2) est backtrackant */ remarques : ici le rsultat tant boolen on nutilise pas de param`tre supplmentaire le rsultat e e e e e e tant donn par le succ`s ou lchec du prdicat. dans ce cas lanalyse rcurrente conduit a 4 cas e e e e e e ` (2 par param`tres). e (r1) egalList([],[]). /* cas de deux listes vides */ (r2) egalList([],[X|L]) :- fail. /* on fait echouer le prdicat, en fait on peut e omettre la r`gle ce qui aura le m^me effet */ e e (r3) egalList([X|L],[]) :- fail. /* idem */ (r4) egalList([X|L],[X1|L1]) :- egalList(L,L1) , X=X1. o` u (r4bis) egalList([X|L],[X|L1]) :- egalList(L,L1). Remarque : ce prdicat scrit plus simplement L1=L2. e e 8.3.2 Exemple sur les entiers

1. un entier est-il pair ? avec la dnition 1 des entiers e /* pair(+X) : X est pair */ (r1) pair(0). (r2) pair(X) :- X>1,Y is X-2,pair(Y). 2. multiplication gyptienne (dichotomique) e avec la def 1 puis avec def 2 des entiers /* mult(+X,+Y,R) avec la def 1 */ mult( ,0,0). mult(X,Y,R) :- Y > 0, Y1 is Y-1, mult(X,Y1,R1), R is R1+X. /* mult(+X,+Y, ?R) avec la def 2 */ mult( ,0,0). mult(X,Y,R) :- Y > 0, pair(Y), Y1 is Y//2, mult(X,Y1,R1), R is R1*2. mult(X,Y,R) :- Y > 0, Y1 is Y-1, pair(Y1), Y2 is (Y-1)//2, mult(X,Y2,R2), R is 2*R2+X. En exercice : dnir les programmes mult(+X,-Y,+Z) et mult(-X,+Y,+Z) e arbre de rsolution de mult(3,5,R) et mult(3,5,10) e 8.3.3 Evaluation dun nombre en base 2

/* B : une liste non vide dentiers 0 ou 1. V : entier valeur(+B, ?V) <-> V est la valeur dcimale du nombre binaire reprsent par B */ e e e exemple : valeur([1,0,1],5) 1. dcoupage a gauche e ` on se base sur la relation suivante : si R est la valeur en base 10 de B alors R+X*2longueur(B) est la valeur de [X|B] valeur([X],X). /* par hypoth`se X est soit 0 soit 1 */ e valeur([X|B],V) :- length(B,L), L>0, valeur(B,V1), puiss(2,L,P), V is V1+X*P. 2. dcoupage a droite e ` On utilise le schma de Horner : e an 2n + an1 2n1 + ... + a2 22 + a1 21 + a0 = ((...(an 2 + an1 ) 2 + ...a2 ) 2 + a1 ) 2 + a0 20

Pour cela on suppose que la liste B est inverse, cest ` dire B=[a0,...,an].Puis on utilise un e a dcoupage a gauche : sur notre liste : si R est la valeur en base 10 de B alors R*2+X est la valeur e ` [X|B] do` : u valeur2([X],X). valeur2([X|B],R) :- valeur(B,R1),R is 2*R1+X. On dnit ensuite valeur en utilisant reverse(B,B1) qui est vrai si et seulement si B1 est la liste e obtenue en inversant la liste B. valeur(B,V) :-reverse(B,B1),valeur(B1,V). En exercice : crire puiss (avec def1 et def2 des entiers) e

Structures arborescentes

Intrts des arbres : temps dacc`s, structuration des donnes, hirarchisation des donnes. e e e e e e exemple : temps dacc`s e liste : O(n) arbre binaire : O(log2 (n)) arbre k-aire : O(logk (n))

9.1

Dnition et terminologie e

cf. livre Cours dinformatique : langages et programmation PC Scholl & al. 9.1.1 Arbres n-aires, forts e

terminologie : racine (nud)-> foncteur liste des ls -> arguments Chaque ls est un arbre n-aire, un arbre est constitu de sous-arbres. e Dnition 13 Une fort est une liste darbres. e e 9.1.2 Convention de reprsentation e

graphiques : patates (ensembles partition des ls), sous forme de graphe (nuds, arcs) exemples avec :

B D E F

C G H I

Attention : notion dordre (entre les ls) est importante A(B, C) = A(C, B). textuelles : Par exemple avec des indentations A B D E F C G H I Ou encore de faon parenthse : c e e prxe A(B(D, E, F ), C(G, H(I))) - (Prolog) e 21

postxe : ((D, E, F )B, (G, (I)H)C)A 9.1.3 Arbres binaires

Arbre pour lesquels chaque nud a au plus 2 sous-arbres (ls). Notion de ls gauche , ls droit. 9.1.4 Terminologie et dnition (p96 du bouquin PCS) e

Terminologie des graphes nud : lment dun arbre ee arc : relie deux nuds Gnalogie e e relation p`re/ls e fr`re,cousin e Nature racine, feuille Dnition 14 chemin (entre deux nuds) = liste unique (si elle existe) des arcs (donc de nuds) e selon la relation p`re-ls pour aller de N1 a N2 (corollaire : N1 doit tre un ascendant de N2) e ` e degr dun nud : arit = nb de ls ; degr de larbre = arit de la racine e e e e niveau dun nud : longueur du chemin de la racine a ce nud (racine=niveau 1) ` profondeur dun arbre : niveau maximal de larbre largeur dun niveau : nb de nuds de ce niveau largeur de larbre : largeur maximale des niveaux

9.2
9.2.1

Arbres en Prolog
Arbre n-aire, forts e

On utilise directement la notion darbre (termes) de Prolog. tout terme non atomique est un arbre R(A,B,C) (notation standard) [R,A,B,C] (notation gnralise) e e e Une fort est une liste darbres. e Contraintes sur les listes : a=b (unication) a\=b (non unication) functor(A,R,N) (N : arit de larbre A de racine R) e Remarque 1 : functor(a,a,0) atom(a) a est une feuille (arit 0). e Remarque 2 : Les arbres dont les nuds sont des entiers ne peuvent pas tre reprsents sous la e e e forme r(f1,...,fn) en gprolog puisque les nombres ne sont pas des atomes. Il faut utiliser la forme [r,f1,...,fn]. Par exemple [5,[3,[1],[2]],[4]] pour larbre :

5 3 1 2 4

Le prdicat =.. permet de passer dune reprsentation sous forme de terme ` une reprsentation sous e e a e forme de liste. Le terme T = r(f1, ..., fn) est transform en une liste L = [r, f1, ..., fn]. Ce prdicat est e e utile pour manipuler des termes dont on ne conna pas la racine ou le nombre darguments. t 9.2.2 Arbre binaires : les trois mod`les e

Un arbre binaire est tel que tous ses nuds sont de degr = 2. e Exemple darbre binaire complet : aa(bb(cc, dd), ee(f f, gg))

22

aa bb cc dd ee gg

7 nuds arbre binaire complet de profondeur n = 2n 1 nuds Arbre incomplet : 1. Mod`le 0 : aa(bb(cc), dd) e pb : cc est-il ls gauche ou ls droit ?

aa bb cc ee bb

aa ee cc

si distinction inutile OK sinon : mod`le 1 ou 2 (cf ci-dessous) e Dcomposition rcursive dun arbre A en mod`le 0 : e e e cas de base : feuille ; arbre A tel que atom(A) cas rcursif 1 : ls unique ; arbre A tel que A=R(F) e cas rcursif 2 : 2 ls ; arbre A tel que A=R(G,D) e Remarque : pas de notion darbre vide Exemple : Nombre dlments ee /* nbElt(+A, ?N) <-> N est le nombre dlments significatif de larbre binaire A e e */ nbElt(A,1) :- atom(A). nbElt(A,N) :-A=..[ |[F]],nbElt(F,M), N is M+1. nbElt(A,N) :-A=..[ |[G,D]],nbElt(G,N1), nbElt(D,N2),N is N1+N2+1. Exemple dappel : ?- nbElt(aa(bb(cc),dd),N). N=4 2. Mod`le 1 e On compl`te larbre : tous les nuds sont binaires, toutes les feuilles sont dsignes par un lment e e e ee particulier appel larbre vide ([]) e aa(bb(cc([], []), []), dd([], [])) ou aa(bb([], cc([], [])), dd([], []))

aa bb cc dd ee gg

[] [] [] [] [] [] [] []
inconvnient : beaucoup de feuilles inutiles, les vraies feuilles nen sont pas (nuds binaires) e avantage : dcomposition rcursive simple (pas de nud unaire, toute feuille est larbre vide) e e Dcomposition rcursive dun arbre A en mod`le 1 : e e e cas de base : arbre vide A=[] cas rcursif : arbre binaire A=R(G,D) e Exemple : nbElt([],0). nbElt(A,N) :- A=..[ |[G,D]],nbElt(G,N1), nbElt(D,N2),N is N1+N2+1. 23

Exemple dappel : ?- nbrElt(aa(bb(cc([],[]),[]),dd([],[])),N) . N=4 3. Mod`le 2 e On compl`te uniquement les nuds de degr 1 par larbre vide (pour lever lambigu e ls gauche/ls e e t droit)

aa bb cc [] ee [] bb

aa ee cc

avantage : pas de feuilles vide inutile inconvnient : dcomposition rcursive moins simple e e e Dcomposition rcursive dun arbre A en mod`le 2 e e e cas de base : feuille non vide atom(A) (A = [] inutile par construction) cas rcursif 1 : nud unaire gauche A = R(G, []) , (par construction G = []) e cas rcursif 2 : nud unaire droit A = R([], D), (par construction D = []) e cas rcursif 3 : nud binaire A = R(G, D), G = [] et D = [] e Exemple : nbrElt(A,1) :- atom(A). nbrElt(A,N) :- A=..[ |[G,[]]],nbrElt(G,N1),N is N1+1. nbrElt(A,N) :- A=..[ |[[],D]],nbrElt(D,N1),N is N1+1. nbrElt(A,N) :- A=..[ |[G,D]],G\=[],D\=[], nbrElt(G,N1), nbrElt(D,N2),N is N1+N2+1. Remarque : ce dernier programme peut scrire plus simplement : e nbrElt([],0). // fausse feuille nbrElt(A,1) :- atom(A),A\=[]. // vraie feuille nbrElt(A,N) :- A=..[ |[G,D]],nbrElt(G,N1), nbrElt(D,N2),N is N1+N2+1. 9.2.3 Traitement rcursifs des arbres n-aires e

Un arbre n-aire A=R(f1,...,fn) peut galement scrire A=[R,f1,...,fn] o` bien A=[R|[f1,...,fn]]. e e u On en dduit les dcompositions rcursives suivantes dun arbre n-aire A : e e e cas de base : feuille : A est un atome. cas rcursif : arbre gnral A=[R|F] o` F est la liste des ls (fort) non vide e e e u e on applique une dcomposition rcursive ` la liste des ls : e e a sous cas 1 : A=[R|[f1]] (un seul ls) (rq : on peut directement crire A=R(f1) ) e sous cas 2 : A=[R|[f1,f2|F]] (au moins deux ls )

9.3
9.3.1

Exemples
Arbre binaires

1. Nombre dlments de valeur e ee /* nbe(+E,+A, ?N) <-> N est le nombre doccurrences de la valeur E dans un arbre binaire A (mod`le 1) */ e nbe( ,[],0). nbe(E,A,N) :- A=..[E|[G,D]],nbe(E,G,N1),nbe(E,D,N2),N is N1+N2+1. nbe(E,A,N) :- A=..[X|[G,D]],X\=E,nbe(E,G,N1),nbe(E,D,N2),N is N1+N2. 2. Minimum dun arbre binaire dentiers Rappel : Les arbres dont les nuds sont des entiers doivent tre reprsents sous la forme e e e [R,f1,...,fn]. /* min(+A, ?M) <-> M est la valeur minimum des elments de larbre binaire A e (mod`le 2) */ e

24

min([R],R). min([R|[G,[]]],M) :- min(G,M1),min2(M1,R,M). min([R|[[],D]],M) :- min(D,M1),min2(M1,R,M). min([R|[G,D]],M) :- G\=[],D\=[],min(G,M1),min(D,M2), min2(M1,M2,M3),min2(M3,R,M). avec min2(A,B,A) :- A=<B. min2(A,B,B) :- B<A. 9.3.2 Arbre n-aires

Nombre dlments dun arbre n-aire ee /* nbrEltNaire(+A,N) <-> N est le nombre dlments de larbre n-aire A */ e e version 1 : introduction dun prdicat intermdiaire e e nbrEltNaire(A,1) :- atom(A) . // A est une feuille nbrEltNaire(A,N) :- A=..[ |F],F\=[],nbrEltForet(F,N1),N is N1+1. // F est la fort des ls e /* nbrEltForet(+F,N) <-> N est le nombre dlments total de tous les arbres de la e e for^t F */ e nbrEltForet([],0). nbrEltForet([F1|F],N) :- nbrEltForet(F,N1),nbrEltNaire(F1,N2),N is N1+N2. rem : rcursivit croise dont la convergence est assure par les proprits suivantes : e e e e ee nbrEltNaire descend dun niveau ` chaque appel (donc converge vers les feuilles) a nbrEltForet parcourt la liste des ls de chaque racine donc converge vers [] version 2 : sans prdicat intermdiaire e e nbrEltNaire(A,1) :- atom(A) . nbrEltNaire(A,N) :- A=..[R|[F1|F]],T=[R|F],nbrEltNaire(T,N1), nbrEltNaire(F1,N2),N is N1+N2. // la racine sera compte ` la n e a version 3 : traitement dune fort e nbrEltForet([],0). nbrEltForet([A|L],N) :-A=..[ |F],nbrEltForet(F,N1),nbrEltForet(L,N2),N is N1+N2+1. do` : u nbrEltNaire(A,N) :- nbrEltForet([A],N). // fort rduite ` A e e a 9.3.3 Arbre de recherche binaire (ARB)

Dnition 15 Un ARB (BST : Binary Search Tree en anglais) est un arbre binaire A tel que : e pour tout noeud r de A, pour tout noeud g appartenant au ls gauche de r et pour tout noeud d appartenant au ls droit de r : gr<d dnition rcurrente : [] est un ARB , [X] est un ARB (une feuille est un ARB) e e [R|[G,D]] est un ARB ssi G est un ARB D est un ARB max(G) R (si G = []) R < min(D) (si D = []) reprsentation en Prolog : Il faut un mod`le dans lequel les arbres unaires gauches et droit peuvent e e se distinguer : mod`le 1 ou 2 mais pas mod`le 0. e e exemple darbre :

25

4 4 2 1 3 5 6 [] 1 2 3 6 5 []

[] [] [] [] [] []
mod`le 1 : e [4,[2,[1,[],[]],[3,[],[]]],[6,[5,[],[]],[]]]

mod`le 2 : e [4,[2,[1],[3]],[6,[5],[]]]

traitements sur les ARB : Intrt : structurer une collection dinformation ordonne pour optimiser e e e les temps dacc`s. e Exemple1 : minimum dun ARB 1. Rappel arbre non ARB (mod`le 2) 9.3.1 c) ci-dessus e 2. ARB min([A],A). min([R,[], ],R). min([ ,G, ],M) :- G\=[],min(G,M). Comparaison de 1) et 2) : 1. parcours tout larbre pour trouver le minimum : soit n le nombre dlment : algorithme en O(n) ee 2. parcours quune branche, au maximum algo en ordre de la profondeur de larbre. Si larbre est complet O(log2 (n + 1)). rq : 1000 lments 1) mille appels rcursifs. 2) < 10 appels rcursifs (1024 = 210 ) ee e e Exemple2 : appartenance 1. arbre non ARB (mod`le 1) e /* E : un elment possdant un relation dordre, A un arbre binaire e e app( ?E,+A) <=> E est un nud de larbre A */ (r1) /* app(E,[]) :- fail. */ (r2) app(E,[E]). (r3) app(E,[E, , ]). (r4) app(E,[R,G, ]) :- app(E,G),E\=R. (r5) app(E,[R, ,D]) :- app(E,D),E\=R. Rq : Dans les r`gles r4 et r5, le test entre E et R est apr`s lappel de app an de garantir que E a e e une valeur sinon E\=R choue chaque fois que E est une variable. e 2. ARB (1) app(E,[E]). (2) app(E,[E, , ]). (3) app(E,[R,G, ]) :- E < R,app(E,G). (4) app(E,[R, ,D]) :- R < E,app(E,D). Autres oprations : ajout, squence extraite trie (parcours inxe), probl`me de la suppression, tri en e e e e arbre.

10
10.1

Contraintes sur les domaines nis


Introduction

A quoi sert la programmation avec contraintes La programmation avec des contraintes est une technique logicielle en dveloppement pour la description et la rsolution de probl`mes importants, pare e e ticuli`rement combinatoires dans les domaines de la planication et de lordonnancement. e Elle est employe avec succ`s dans les domaines suivants e e applications graphiques, pour exprimer des relations gomtriques entre divers lments dune sc`ne e e ee e traitement des langues naturelles (pour amliorer la performance des analyseurs) e syst`me de base de donnes (pour assurer ou restaurer la cohrence des donnes) e e e e 26

probl`mes de recherche oprationnelle (en particulier les probl`mes doptimisation) e e e et bien dautres domaines non cits. e Prolog et les contraintes Le langage Prolog est n en 1970. Son apoge a eu lieu dans les annes e e e 80, en liaison avec des applications au traitement des langues naturelles et a lintelligence articielle. Son ` dclin provisoire est suivi dune rsurrection avec lintroduction des contraintes dans le langage. e e Une contrainte cest une relation entre des variables, chacune prenant une valeur dans un domaine donn. e Une contrainte restreint les valeurs possibles que les variables peuvent prendre. Donnons un exemple tir de gprolog. La contrainte fd domain([X,Y,Z],1,10) impose que ces trois e variables prennent des valeurs enti`res entre 1 et 10, la conjonction de cette premi`re contrainte et de la e e contrainte X+Y #= Z restreint les domaines de X et Y ` lintervalle ferm 1..9 (car X est au plus gal au a e e maximum de Z moins le minimum de Y) et le domaine de Z ` lintervalle ferm 2..10 (car le minimum a e de Z est au moins la somme des minimums de X et de Y). Prolog et les contraintes ouvre le nouveau domaine de la programmation logique avec contraintes (PLC) : Prolog est tendu avec des rsolveurs de contraintes, travaillant sur des donnes qui peuvent tre des e e e e entiers, des boolens, des domaines nis dentiers, des rationnels, des intervalles de rationnels. e Les rsolveurs de contraintes peuvent tre ajouts ` dautres langages que Prolog, mais lalgorithme e e e a dunication de Prolog est dj` un rsolveur des contraintes dgalit sur les termes, donc la rsolution ea e e e e de contraintes sint`gre naturellement a Prolog. e `

10.2
10.2.1

Classication des contraintes


Dnition des domaines e

fd domain(LVars,Bi,Bs) Lvars est une liste de variables, la russite de la requte lie chacune des variables e e de la liste ` lintervalle Bi..Bs bornes comprises. Bi et Bs doivent tre des entiers. a e ?- fd_domain([X, Y],1, 4). X = _#3(1..4) Y = _#25(1..4) La rponse doit tre interprte ainsi : X et Y sont des variables dont la valeur est comprise entre 1 et 4. e e ee 10.2.2 Contraintes arithmtiques e

Principe des rductions de domaine Commenons par des exemples. e c ?- fd_domain([X,Y],0,7),X * Y #= 6, X + Y #=5, X #< Y. X = 2 Y = 3 Le domaine initial des variables X et Y est x, puis il est rduit au fur et a mesure de laccumulation e e ` des contraintes. Lordre des contraintes est indirent. e On nindique pas lalgorithme qui rduit les domaines, mais on donne des indications sur son principe de e fonctionnement. 1. Dapr`s la premi`re contrainte X et Y sont entre 0 et 7. e e 2. Dapr`s la deuxi`me contrainte X et Y ne sont pas nuls donc valent au moins 1, dapr`s cette e e e deuxi`me contrainte X et Y valent au plus 6. e 3. Dapr`s la troisi`me contrainte et les bornes prcdentes, X vaut au plus 5 moins la valeur minimum e e e e de Y, donc au plus 4, et de mme pour Y. e 4. Rutilisons ` nouveau la deuxi`me contrainte, X est au moins gal a 6/4, donc X vaut au moins e a e e ` 2. Rutilisons ` nouveau la troisi`me contrainte, puisque X vaut au moins 2, Y vaut au plus 3. En e a e changeant les rles de X et Y, on voit quapr`s les 3 premi`res contraintes X et Y sont entre 2 et e o e e 3. Donc la derni`re contrainte donne la solution e En prsence dun ensemble de contraintes, lalgorithme utilise chaque contrainte en eectuant les e rductions de domaine, jusquau moment o` plus aucune contrainte ne peut rduire le domaine des e u e variables. Rduction partielle des domaines Le signe caractristique des contraintes ` domaine ni est le #. e e a La liste des prdicats utilisables est : #=, #\=, #<, #=<, #>, #>= e

27

Ces prdicats peuvent tre crits entre leurs oprandes qui sont des expressions arithmtiques et nous e e e e e avons dj` vus plusieurs exemples de leurs utilisations. ea On en prsente un exemple surprenant qui met en vidence que gprolog utilise deux reprsentations des e e e domaines nis. ?- fd_domain([X],1,1000), X#\=3. X = _#3(1..2:4..127@) Apr`s la premi`re contrainte, la valeur de X est comprise entre 1 et 1000. Cet intervalle est reprsent e e e e par un couple dentiers. Apr`s la deuxi`me contrainte, la valeur de X doit tre dirente de 3. Gprolog e e e e reprsente alors X par un vecteur de 128 bits. Le signe @ indique que des valeurs ont t perdues suite ` e ee a ce changement de reprsentation. e En rsum, il y a deux reprsentations des domaines nis e e e 2. par un vecteur de bits dindice entre 0 et une valeur vector max. Initialement vector max = 127. Il est possible par la contrainte fd set vector max(+integer) de changer la valeur de vector max, ce qui est le premier moyen dviter de perdre des valeurs. e Comment chaque contrainte est-elle utilise ? Soit X une variable de domaine DX, Y une variable de e domaine DY, lexcution de la contrainte r(X,Y) peut enlever de DX les valeurs v telles que r(v,Y) nest e vrie pour aucune valeur de Y dans le domaine DY et peut rduire de mme le domaine DY. Par e e e e exemple : ?- fd_domain([X,Y],1,10), X#\=2, X+Y#=5. X = _#3(1:3..4) Y = _#25(1..4) Noter que la rduction opre par la derni`re contrainte est partielle. Puisque X est dirent de 2, dapr`s e e e e e e la derni`re contrainte, Y ne peut pas tre gal a 3, mais cette valeur nest pas enleve du domaine de Y. e e e ` e Les contraintes de rductions partielles (avec un seul #) ne permettent que la rduction des intervalles e e entre les valeurs minimum et maximum des variables. Rduction e compl`te e des domaines La liste des prdicats e utilisables est : #=#, #\=#, #<#, #=<#, #>#, #>=# Reprenons lexemple prcdent avec la rduction compl`te : e e e e ?- fd_domain([X,Y],1,10), X#\=2, X+Y#=#5. X = _#3(1:3..4) Y = _#25(1..2:4) Comparons sur dautres exemples la rduction partielle et compl`te e e | ?- fd_domain([X,Y],1,100),X*Y #= 51. X = _#3(1..51) Y = _#25(1..51) yes | ?- fd_domain([X,Y],1,100),X*Y #=# 51. X = _#3(1:3:17:51) Y = _#25(1:3:17:51) yes La rduction compl`te prend plus de temps que la rduction partielle. Si votre probl`me na besoin que e e e e dintervalles, il est inutile de lutiliser. 10.2.3 Information sur les domaines 1. par un intervalle entre Bi et Bs avec 0 Bi et Bs 228 1

Mod`les des prdicats e e fd_min(+fd_variable, ?integer) fd_max(+fd_variable, ?integer) fd_size(+fd_variable, ?integer) fd_dom(+fd_variable, ?integer_list) Description 1. fd_min(X, N) russit si N est la valeur minimale du domaine de X e 28

2. fd_max(X, N) russit si N est la valeur maximale du domaine de X e 3. fd_size(X, N) russit si N est le nombre dlments du domaine actuel de X e ee 4. fd_dom(X, Values) russit si Values est la liste des valeurs du domaine actuel de X e 10.2.4 Contraintes dnumration e e

Mod`les des prdicats e e fd_labeling(+fd_variable_list) fd_labelingff(+fd_variable_list) Description 1. fd_labeling(Vars) aecte une valeur ` chaque variable de la liste Vars. a ?- fd_domain([X],1,2),fd_labeling([X]). X = 1 ?; X = 2 yes 2. fd_labelingff(Vars) aecte une valeur ` chaque variable de la liste Vars en choisissant dabord a la variable de plus petit domaine et entre deux variables de mme plus petit domaine, celle la plus e a ` gauche. ?- fd_domain([X],1,3), fd_domain([Y],1,2),fd_labelingff([X, Y]). X = 1 Y = 1 ? a X = 2 Y = 1 X = 3 Y = 1 X = 1 Y = 2 X = 2 Y = 2 X = 3 Y = 2 Attention la variable Y, qui a le plus petit domaine, est bien numr dabord : pour Y = 1, X prend e e e les valeurs 1, 2, 3 puis on recommence avec Y = 2. Le prdicat fd_labeling peut tre utilis avec des options qui modient lordre dnumration. Lordre e e e e e dnumration est tr`s important dans la rsolution des probl`mes combinatoires, puisque, par exemple, e e e e e le choix dune valeur pour une variable qui entre dans beaucoup de contraintes, va conduire plus vite a ` lchec ou au succ`s des contraintes comportant cette variable. e e Nous renvoyons a la documentation gprolog pour complter les informations sur les contraintes. En par` e ticulier nous navons pas voqu ci-dessus les contraintes dites symboliques (comme fd_all_different e e qui gure dans les exemples) qui posent des contraintes sur des listes de variables.

10.3 10.4

Exemples dutilisations Gnrateur dentiers e e

Une application des contraintes en domaine ni parmi les plus classique est la gnration dentiers dans e e un intervalle par backtrack : /* enum(-V,+N1,+N2) <-> russit si V prend une valeur entre N1 et N2 */ e enum(X,N1,N2) :-fd domain(X,N1,N2),fd labeling(X). 10.4.1 Rsolution dquations linaires e e e

Il est galement possible de rsoudre des quations linaires. Par exemple : e e e e ?- X+Y#=2,X+2*Y#=3. X=1 Y=1 yes Il est parfois ncessaire de forcer lnumration des solutions : e e e ?- X+Y+Z#=6,X+2*Y+Z#=8,X+Y+2*Z#=9,fd\_labeling([X,Y,Z]). X=1 Y=2 29

Z=3 ?; no 10.4.2 La factorielle (le retour)

Lutilisation de contraintes sur les domaines nis permet de faire une version de la factorielle qui est inversible, cest a dire qui peut tre appel en mode fac(-N,+R). ` e e fac(0,1). fac(N,R) :- 0#<N,N#=<R,N1#=N-1,R#=R1*N,fac(N1,R1). 10.4.3 SEND+MORE=MONEY

Cet exemple est typique de programme Prolog dont la dnition est tr`s proche de lexpression formelle. e e On veut rsoudre le syst`me dquations reprsent par SEND+MORE=MONEY. Il sagit dassocier e e e e e aux dirents caract`res des chires tels que lopration arithmtique correspondante soit correcte. La e e e e r`gle impose quune lettre ne soit associe qu` un seul chire, que deux lettres direntes soient associes e e a e e a ` deux chires dirents et que toutes les lettres soient associes. On peut tout dabord exprimer les e e premi`res proprits nonces. Nous nommerons le prdicat sendmory compos de lensemble des variables e ee e e e e de ce syst`me dquations. On sait dj` que tous les lments de la solution sont dirents deux ` deux e e ea ee e a ee e e (prdicat fd all different) et que tous les lments sont des chires (prdicat fd domain). Le syst`me e de contraintes du prdicat quivaut au syst`me dquations que lon cherche ` rsoudre et qui correspond e e e e a e au principe de laddition en base 10. sendmory([S,E,N,D,M,O,R,Y]) :- fd domain([S,E,N,D,M,O,R,Y],0,9), fd all different([S,E,N,D,M,O,R,Y]), equationValide([S,E,N,D,M,O,R,Y]), fd labeling([S,E,N,D,M,O,R,Y]). equationValide([S,E,N,D,M,O,R,Y]) :- M=1, /* par dfinition */ e Send #= 1000*S+100*E+10*N+D, More #= 1000*M+100*O+10*R+E, Money #= 10000*M+1000*O+100*N+10*E+Y, Money #= More+Send. Remarques : Le prdicat sendmory trouve la solution [S,E,N,D,M,O,R,Y] = [9,5,6,7,1,0,8,2] en 3s de CPU environ. e larbre de rsolution principal est bas sur 10 possibilits pour 8 variables (810 = 1073741824). Cee e e pendant toutes ne sont pas explores car toutes les variables doivent tre direntes et le syst`me de e e e e contraintes limite lexploration de certains sous-ensembles de combinaisons. 10.4.4 Le carr magique e

Un carr magique est une matrice 3x3 dentiers telle que les sommes des lignes, colonnes et diagonales e soient gales. e /* carremagique(Carre,Somme) : Carre est un carre magique, Somme est la valeur de chaque ligne, colonne et diagonale */ carremagique(Carre,Somme) :- /* Contraintes */ Carre=[C11,C12,C13,C21,C22,C23,C31,C32,C33], fd domain(Carre,1,9),fd all different(Carre), Somme#=C11+C12+C13, Somme#=C21+C22+C23, Somme#=C31+C32+C33, Somme#=C11+C21+C31, Somme#=C12+C22+C32, Somme#=C13+C23+C33, Somme#=C11+C22+C33, Somme#=C13+C22+C31, /* Gnration */ e e fd labeling(Carre), /* Affichage */ 30

nl,outcarre(Carre,1,3). /* outcarre(C,R,T) : affiche la liste C en allant a la ligne lorsque R=T */ ` outcarre([], , ). outcarre([E|S],Taille,Taille) :- write(E),nl,outcarre(S,1,Taille). outcarre([E|S],Rang,Taille) :- Rang<Taille,write(E),Rang1 is Rang+1, outcarre(S,Rang1,Taille).

31

32

Troisi`me partie e

Aspects techniques
11
11.1

Un outil de contrle : le coupe-choix o


Problmatique e

PROLOG ore un niveau dexpression tr`s puissant : description de la solution dun probl`me sous e e forme de relations et de contraintes. Linconvnient est que lutilisateur ne poss`de pas le contrle de la e e o rsolution comme dans un langage impratif (C, JAVA) par exemple. Les seuls oprateurs de contrle sont e e e o le choix : alternatives oertes par les clauses dun mme prdicat ; et le et squentiel entre les buts de e e e la partie droite dune clause ou dune question. La combinaison des ces deux oprateurs permet dobtenir e des structures classiques. On doit tout de mme remarquer que lintroduction de la notion de contraintes e dans un langage comme Prolog est un outil qui permet de raliser un contrle sur le droulement de la e o e rsolution (exclusivit des clauses en particulier). e e Exemple : on dsire raliser la structure de contrle de choix exclusif (partitionnement de lensemble des e e o possibilits pour les conditions). Cette structure de contrle doit permettre de se protger des backtrack e o e intempestifs. solution 1 : exprimer le choix dans la tte de clause e Exemple avec pair : pair(0). pair(succ(succ(N))) :- pair(N). pair(0) et pair(succ(succ(N))) ne sont pas uniables, ils forment une disjonction exclusive de lensemble des termes {pair(X)}. Soit P , le but a rsoudre, la rsolution revient a excuter lalgo suivant : ` e e ` e CHOIX P sunie a pair(0) : vrai ` P sunie a pair(succ(succ(N))) : rsoudre pair(N) ` e FINCHOIX Le backtrack est de facto impossible car un terme qui sunie ` la premi`re clause ne pourra sunier a a e ` la seconde. solution 2 : exprimer le choix dans les contraintes de la clause appartient(X,[Y|L]) :- X=Y. appartient(X,[Y|L]) :- X\=Y,appartient(X,L). Le choix est assur par lexclusivit des contraintes. Le backtrack entre les deux clause est possible e e (unication), mais le syst`me chouera sur la contrainte. On peut aussi combiner cette solution avec la e e solution prcdente. e e appartient(X,[X|L]). appartient(X,[Y|L]) :- appartient(X,L). solution 3 : exprimer le choix dans les buts de la queue de clause union([],E2,E2). union([X|E1],E2,E3) :- appartient(X,E2),union(E1,E2,E3). union([X|E1],E2,[X|E3]) :- not appartient(X,E2),union(E1,E2,E3). avec : not appartient(X,[]). not appartient(X,[Y|R]) :- X\=Y,not appartient(X,R). Le choix est assur par lexclusivit des buts (` la charge du programmeur). Attention : le but dterminant e e a e doit tre plac en tte de la queue de clause. e e e e e e Inconvnient : les prdicats appartient et not appartient sont excuts systmatiquement pour une e e liste initial non vide (redondance).

33

solution 4 : interdire le backtrack quand une clause a t choisie Pour cela on utilise un e e prdicat particulier appel coupe-choix ou coupure ou encore cut not !. e e e /* N entier positif ou nul, fact(+N, ?R) <-> R est la factorielle de N */ fact(0,1) :- !. fact(N,R) :- N>0,N1 is N-1,fact(N1,R1),R is R1*N. Le backtrack, thoriquement possible, est inhib par le coupe-choix. Cela revient ` la smantique suivante : e e a e si P sunie a fact(0,1) ` alors vrai ( et cest ni) sinon si P sunie a fact(N,R) ` alors N>0,N1 is N-1,fact(N1,R1),R is R1*N sinon chec e

11.2

Dnition du coupe-choix e

Le coupe-choix est un prdicat prdni qui russit toujours. Il a cependant un eet de bord en intervenant e e e e sur la rsolution elle-mme. e e On peut comparer le coupe-choix ` une porte dote dun mcanisme de tringlerie qui fait que lorsquon a e e e a franchit la porte2 cela ferme celles qui sont accroches ` la tringle supprimant ainsi des chemins dexploration. La tringle est accroche aux portes franchies antrieurement. Pour mieux comprendre son e e fonctionnement nous tudions son eet quand il appara dans une question puis dans une r`gle. e t e 1. Le coupe choix dans une question Soit la question : C, !,D. avec C= c1,c2,...,cn et D=d1,d2,...,dk Prolog rsout dabord les buts de C, en utilisant le mcanisme de backtrack si besoin, e e d`s quune solution est trouve pour C, le coupe-choix est rsolu et coupe tous les choix pendants e e e de la rsolution de C, e D est ensuite rsolu, e si lun des buts de D choue ou si D russit, le backtrack sur les buts de D est lanc, e e e quand aucun backtrack nest plus possible sur les buts d1,d2,...,dk, le coupe-choix empche le e backtrack dans les buts de C3 . On ne peut plus trouver de solutions. 2. Le coupe choix dans une clause On peut insrer un coupe-choix dans une clause. La smantique est la mme pour les buts de la e e e queue de clause que la smantique dune question avec en plus les deux r`gles suivantes : e e le coupe-choix COUPE LES CHOIX relatifs aux alternatives de la clause en cours (1) C :- C1, !,C2. (2) C :- C3. Si C1 est rsolu, le ! coupe lalternative restante pour C (2), ainsi bien sur que tous les autres choix e possible pour la rsolution de C1. e Si C1 nest pas rsolu, le ! nest pas eac, le backtrack est possible sur (2). e e Le coupe-choix NAFFECTE PAS les rsolutions englobant la clause le contenant e C :- C1,C2. C1 :- D1. C1 :- D2. C2 :- C3, !,C4. C2 :- D3. e le coupe choix empche un backtrack sur C3 et la 2eme r`gle de C2 mais pas sur C1 e 3. Exemple Reprenons un sous-ensemble des r`gles de lexemple du menu qui concerne la constitution e du plat principal dun repas. Nous avons les clauses lies au plat et celles lies aux viandes et aux e e poissons. poisson(truite). poisson(daurade). viande(steak). viande(escalope).
peut schmatiser leacement dun terme dans une rsolvante comme le franchissement dune tape de rsolution e e e e reprsente par une porte. e e 3 Le coupe-choix est un prdicat ` eet de bord puisque son franchissement en sens inverse ne restitue pas la situation e a antrieure ` son franchissement initial. e a
2 On

34

plat(P) :- poisson(P). plat(V) :- viande(V). Dessinons larbre de rsolution de la question plat(P),viande(P) qui fournit en rponse tous les e e plats qui sont de la viande.

plat(P),viande(P) poisson(P),viande(P) viande(truite) echec {P=truite} viande(dorade) echec {P=dorade} viande(P),viande(P) viande(steak) succes {P=steak} viande(escalope) succes {P=escalope}

Dessinons larbre de rsolution de la question plat(P),viande(P), ! qui fournit en rponse le 1er e e plat qui est de la viande.

plat(P),viande(P), ! poisson(P),viande(P), ! {P=truite} {P=dorade} viande(P),viande(P), ! {P=steak}

viande(truite), ! viande(dorade), ! viande(steak), ! echec echec ! succes


Dessinons larbre de rsolution de la question plat(P), !,viande(P) qui ne fournit aucune rponse. e e

plat(P), !,viande(P) poisson(P), !,viande(P) !,viande(truite) viande(truite) echec 11.3 Utilisations {P=truite}

Le coupe-choix doit tre utilis avec prcaution du fait de son eet sur la rsolution. Les cas dutilisation e e e e sont bien dtermins et devront tre observs. En particulier il est souvent incompatible avec les prdicats e e e e e fonctionnant en mode gnration. e e 11.3.1 Contrle des solutions dans un processus de gnration o e e

Comme nous lavons vu ci-dessus, le cut permet daner une question. Exemple : repas(E,P,D),poisson(P). /* quels sont les repas comprenant du poisson ? */ poisson(P),repas(E,P,D). /* idem */ 35

repas(E,P,D), !,poisson(P). /* le premier repas de la base comprend-il du poisson ? */ poisson(P), !,repas(E,P,D). /* construire un repas avec le premier poisson de la base */ repas(E,P,D),poisson(P), !. /* quel est le premier repas contenant du poisson ? */ poisson(P),repas(E,P,D), !. /* idem */ !,repas(E,P,D),poisson(P). /* idem sans cut */ De faon gnrale, tant donn que PROLOG rend toutes les solutions a la question pose, on pourra c e e e e ` e lorsque lon ne dsire quune seule rponse ajouter un cut a la question : e e ` q(X1,X2,...,Xn) Quel est lensemble des toutes substitutions solutions de la question Q q(X1,X2,...,Xn) , ! Quelle est la premi`re substitution solution de la question Q, premi`re au sens de la smantique e e e procdurale de Prolog. e 11.3.2 Conrmation du choix dune r`gle e

Comme nous lavons vu ci-dessus, le coupe-choix permet de rendre des r`gles exclusives. On ins`re le ! e e apr`s la squence de but qui permet de dterminer que la r`gle choisie est la bonne. e e e e union([],E2,E2) :- !. union([X|E1],E2,E3) :- appartient(X,E2), !,union(E1,E2,E3). union([X|E1],E2,[X|E3]) :- union(E1,E2,E3). Attention : ce programme nest pas strictement quivalent au premier. Considrons la question : e e union(E,[1,2],[1,2]). Le premier programme qui ne comporte pas de coupe-choix rpond : e ?- union(E,[1,2],[1,2]). E=[] ? ; E=[1] ? ; E=[1,1] ? yes Le second programme rpond : e ?- union(E,[1,2],[1,2]). E=[] ? ; no Le premier programme ne termine pas car il ne prcise pas quil faut que les listes ne contiennent plusieurs e fois les mmes lments. e ee Un prdicat contenant des coupe-choix a un comportement en mode gnration dirent de la version sans e e e e coupe-choix. En gnral lintroduction dun coupe-choix fait perdre le caract`re relationnel du prdicat. e e e e remarque : la r`gle : union([X|E1],E2,E3) :- !,appartient(X,E2),union(E1,E2,E3) conduit a une e ` erreur, le cut plac avant le prdicat dterminant le choix de la bonne r`gle conduira a ne jamais utiliser e e e e ` la r`gle 3. e Autre exemple : Exemple : prdicat appartient avec et sans cut : e /* version avec exclusivit assure par des contraintes */ e e appartient(X,[X| ]). appartient(X,[Y|L]) :- appartient(X,L),X\= Y. ?- appartient(X,[1,2,3]). X=1 ? ; X=2 ? ; X=3 ? yes /* version avec exclusivit assure par le cut */ e e appartient(X,[X| ]) :- !. appartient(X,[ |L]) :-appartient(X,L). ?- appartient(X,[1,2,3]) X=1 ? ; no

36

11.3.3

Expression de nouvelles structures de contrle o

La ngation par coupe-choix e Soit le prdicat voyelle(L) dnit les les voyelles de lalphabet : e e voyelle(a). voyelle(e). voyelle(i). voyelle(o). voyelle(u). voyelle(y). On dsire crire le consonne(L) qui dnit les consonnes de lalphabet. On peut le faire comme pour e e e les voyelles par une dnition en extension. Ceci est cependant assez fastidieux. On peut remarquer que e les sous-ensembles des voyelles et des consonnes forment une partition de lensemble des caract`res de e lalphabet permettant de dnir lun comme tant le complmentaire de lautre. Nous allons utiliser le e e e fait quune consonne est un caract`re qui nest pas une voyelle pour dnir lensemble de consonne en e e comprhension. e consonne(L) :- voyelle(L), !,fail. consonne(L) :- lettre(L). avec : lettre(L) :-char code(L,X),X>96,X<123. De faon gnrale le prdicat de ngation de but not scrira : c e e e e e not(P) :- P, !,fail. not( ). Exemple dutilisation : consonne(L) :- not(voyelle(L)), lettre(L). Attention : Lutilisation dun tel prdicat avec des variables libres peut conduire a des rsultats inattendus. e ` e Ceci est d a ce que lon consid`re que la non rsolution est une ngation. Ceci nest vrai que lorsquon u` e e e travaille sur des variables instancies ou avec un syst`me de contraintes. e e ?- consonne(X). no ?- consonne(z). yes On remarque que tel quil est dni le prdicat consonne nest pas gnrateur. Pour le rendre gnrateur e e e e e e et par la mme rsoudre le probl`me ci-dessus, nous crivons une nouvelle version du prdicat consonne. e e e e e consonne(L1) :- char code(a,A),char code(z,Z),fd domain(L,A,Z), fd labeling(L),char code(L1,L),not(voyelle(L1)). Ecriture du si-alors-sinon Le coupe-choix peut servir pour construire les structures contrle classique des langages traditionnels o (conditionnelle,...). si( condition, alors, sinon) :- condition, !, alors. si( condition, alors, sinon) :- sinon. Exemple : si x est carnivore alors x mange de la viande, sinon x rumine si(carnivore(x),mange viande(x), rumine(x)) ou union([],E2,E2) :- !. union([X|E1],E2,U) :- union(E1,E2,E3),si(appartient(X,E2),U=E3,U=[X|E3]). Structure de choix (selon) choix Cond1 : But1 Cond2 : But2 ... Condn : Butn nchoix En Prolog : choix([[Cond1,But1],[Cond2,But2],...,[Condn,Butn]]). avec :

37

choix([[C,B]| ]) :- C, !,B. /* si la premi`re condition est vraie, on rsout le but associ */ e e e choix([ |Reste]) :- choix(Reste). /* sinon on recommence avec la deuxi`me */ e /* remarque : si aucune condition nest vraie, le choix choue */ e Exercice : version avec cas balai (else ou sinon) Remarque : Gprolog poss`de des prdicats capables de reproduire ces structures. Le prdicat C1 :- C2 e e e correspond a si C1 alors C2. En utilisant ;, qui correspond au ou logique, nous pouvons crire C1 :` e C2 ; C3 qui signie si C1 alors C2 sinon C3. Structure itrative : tantque Cond faire But e En Prolog : tantque(Cond,But) tantque(C,B) :- C, !,B,tantque(C,B). tantque( , ). Attention : il faut que la condition C puisse svaluer a faux (donc dpend du contexte du programme e ` e eet de bord)

12
12.1

Quelques prdicats prdnis de gprolog e e e


Entres-sorties e

Gprolog poss`de plusieurs prdicats permettant linteraction avec lutilisateur au cours de la rsolution. e e e Le prdicat write/1 permet dacher un terme ` lcran pendant une rsolution. e a e e ?- write(bonjour). bonjour yes ?- write(vive(prolog)). vive(prolog) yes ?- write(X). 16 yes ?- X=3,write(X+Y). 3+ 20 yes ?- write(Votez pour moi). Votez pour moi ! yes Le prdicat nl/0 permet daller a la ligne. e ` ?- write(bonjour),nl,write(` tous). a bonjour a ` tous yes Le prdicat read/1 permet de lire des termes ` lcran. La lecture sarrte lorsque lutilisateur appuie sur e a e e . puis Entre. e ?- read(X). bonjour. X=bonjour yes ?- read(X). Une petite phrase.. X=Une petite phrase. yes ?- read(X). Y. yes ?- read(X). aa(Y,Z). 38

X=aa( , ). yes Les prdicats read atom/1, read integer/1, read number/1 sont similaires a read/1 mais nacceptent e ` que des termes dun certain type. Pour ces prdicats l`, il sut dappuyer sur Entre pour valider la e a e saisie. Lutilisation de . ` la n de la saisie est optionnelle. a

12.2

Gnration de nombres alatoires e e e

Gprolog poss`de des prdicats permettant la gnration de nombres alatoires. e e e e e 12.2.1 Initialisation

Le gnrateur alatoire utilise une graine pour choisir les valeurs. Une fois la graine xe la liste des e e e e valeurs gnres est dterministe. Cette graine est par dfaut initialise ` 1. Par consquent a chaque e e e e e e a e ` utilisation de gprolog, les nombres sont gnrs dans le mme ordre. An dviter cela, il faut modier la e e e e e graine. Le prdicat set seed/1 prend en entre un entier qui sera la nouvelle valeur de la graine. Il est galement e e e possible dutiliser le prdicat randomize/0 qui choisit une graine en fonction de lheure du syst`me. e e 12.2.2 Tirage

Les tirages se font en utilisant les prdicats random/1 et random/3. e Le prdicat random/1 lie la variable donne en param`tre avec un nombre pris alatoirement suprieure e e e e e ou gale a 0 et strictement infrieure a 1. e ` e ` ?- random(X). X = 0.80871582031 yes Le prdicat random/3 prend en argument deux nombres et une variables et russit si le premier nombre e e est plus petit que le second et lie la variable avec une valeur choisie au hasard suprieure ou gale au e e premier nombre et strictement infrieure au second nombre. Si les deux nombres sont entiers, la valeur e tire sera enti`re. e e ?- random(1,2.1,X). X = 1.0873443604 yes ?- random(1,5,X). X = 2 yes

12.3

Trouver toutes les solutions

Il est parfois utile davoir acc`s ` lensemble des rponses ` un probl`me donn. Par exemple on peut e a e a e e vouloir conna le nombre de repas contenant de la salade. Prolog poss`de trois prdicats permettant tre e e de faire cela. 12.3.1 findall/3

Le prdicat findall(V,But,L) russit si L est la liste des valeurs que peut prendre V pour rsoudre le e e e but But. ?- findall(X,repas(X,truite,melon),L). L = [salade,avocat,huitre] yes Les valeurs sont donnes dans lordre dans lesquelles elles sont trouves lors de lexploration de larbre e e de rsolution. e Remarque : But peut tr`s bien contenir des variables libres : e ?- findall(X,repas(X,Y,melon),L). L = [salade,salade,salade,salade,avocat,avocat,avocat,avocat,huitre,huitre,huitre,huitre] yes

39

Dans cet exemple puisque dans larbre de rsolution X obtient une valeur avant Y, cette valeur est duplique e e 4 fois, puisque Y peut ensuite prendre 4 valeurs. Enn il est possible dinstancier V avec une liste de variables : ?- findall([X,Y],repas(X,Y,melon),L). L = [[salade,steak],[salade,escalope],[salade,truite],[salade,daurade],[avocat,steak], [avocat,escalope],[avocat,truite],[avocat,daurade],[huitre,steak],[huitre,escalope], [huitre,truite],[huitre,daurade]] yes 12.3.2 bagof/3 et setof/3

Ces deux prdicats sutilisent comment findall/3. Le prdicat bagof di`re de findall lorsquil y a e e e des variables libres dans But. Ils sparent les rsultats en fonctions des valeurs de ces variables : e e ?- bagof(X,repas(X,Y,melon),L). L = [salade,avocat,huitre] Y = daurade ? ; L = [salade,avocat,huitre] Y = escalope ? ; L = [salade,avocat,huitre] Y = steak ? ; L = [salade,avocat,huitre] Y = truite yes Le prdicat setof/3 est similaire mais en plus il trie la liste des rsultats et limine les doublons. e e e

40

Quatri`me partie e

Applications ` la programmation logique a


13 Introduction
La programmation logique , ` travers un langage comme PROLOG, permet daborder de nouveaux a probl`mes, ou en tout cas , permet de traiter des probl`mes avec une nouvelles approche. e e Le style de programmation dclaratif, proche des mathmatiques, les possibilits dexploration des soe e e lutions (backtrack), la programmation par contraintes permet de dcrire des solutions rapidement et de e mani`re lgante. Dans certains cas bien sr, lecacit nest pas au rendez-vous. Mais l` nest pas notre e ee u e a propos. En dehors des probl`mes classiques mettant en jeu les types inductifs et la rcursivit, PROLOG permet e e e de rsoudre des probl`mes de types varis : gnration et test, calcul formel, traitement des langages, e e e e e intelligence articielle...

14

Probl`mes de gnration-test (generate & test) e e e

Cette classe de probl`mes se caractrise par le fait quon peut les rsoudre avec un mcanisme de e e e e gnration de solution puis de test. e e On produit lensemble des possibilits de solutions (phase de gnration) puis on ltre celles qui sont des e e e bonnes solutions (phase de test) pour obtenir le sous-ensemble des solutions au probl`me. e Bien s r du point de vue du langage , la possibilit de backtrack sera utilise pour la gnration des u e e e e solutions.

14.1

Principe dun programme de gnration et test e e

Tous les probl`mes de gnration et test sont btis sur le mme moule : e e e a e /* solution(S) <-> S est une solution du probl`me pos. Si S est libre, toutes les e e solutions possibles sont gnres par backtrack */ e e e solution(S) :- generer(S),tester(S) . Mcanisme : e generer(S) est appel avec une variable libre (S) , il gn`re une premi`re solution. e e e e tester(S) est appel avec une variable instancie (une proposition de solution S fournie par generer) e e et teste la validit de la solution. e Apr`s lchec ou le succ`s de tester, le backtrack est lanc sur gnrer qui fournit une autre solution, et e e e e e e ainsi de suite. Remarque : lordre est important car tester doit recevoir une variable instancie, sauf si tester ne met e en place que des contraintes, dans ce cas il peut tre intressant de mettre tester avant pour des raisons e e decacit (generer est arrt d`s que les contraintes sont violes). e ee e e

14.2
14.2.1

Exemples
Nombres entiers multiples de 3 entre 0 et 100

Quels sont les nombres entiers multiples de 3 entre 0 et 100 ? multiple3(N) :- generer(N),tester(N). generer(N) :- enum(N,0,100). /* num`re par backtrack tous les entiers entre 0 et 100 */ e e tester(N) :- 0 is N rem 3. /* N est gal a 0 mod 3 */ e ` Remarque : il existe ici une solution plus simple : gnrer directement les multiples de 3 (donc pas de e e test) multiple3(N) :- enum(M,0,33),N is 3*M.

41

14.2.2

Voyelles dun mot

voyelleMot(M,V) :- generer(M,V),tester(V). generer(M,V) :- name(M,M0),length(M0,T),T2 is T-1,enum(T1,0,T2), length(M1,T1),concat(M1,[V0| ],M0),name(V,[V0]). tester(a). tester(e). tester(i). tester(o). tester(u). tester(y). 14.2.3 LES MUTANTS

Cet exemple est typique du mode gnration/test. On cherche ` crire un prdicat mutant(M) tel que M e e ae e est uni ` un identicateur (nom dun animal mutant) construit par concatnation avec recouvrement ea e de deux noms danimaux normaux. Par exemple avec alligator et tortue on construit le mutant alligatortue. On pourra, dans une version ultrieure, xer la taille minimum du recouvrement. e Pour cela on dispose dune base danimaux normaux qui servira a la production des mutants. ` animal(alligator) . animal(bouquetin) . animal(caribou) . animal(cheval) . animal(chevre) . animal(hibou) . animal(lapin) . animal(lapine) . animal(pintade) . animal(rat) . animal(ratonlaveur) . Le prdicat mutant engendre par backtrack tous les mutants possibles. La premi`re version que lon donne e e nutilise que peu le mcanisme de contraintes, la seconde version en fait un meilleur usage. On pourra e en listant la forme dcompile des prdicats sapercevoir que certaines contraintes sur les arbres sont e e e ralises par lintroduction de buts associs. e e e /* mutant(M) : M est un animal mutant, construit par combinaison de deux animaux. Le premier se terminant comme le dbut du dernier, avec au moins une lettre en commun. */ e mutant(M) :/* GENERATION */ animal(A1),animal(A2), /* transformation des identificateurs en listes pour manipulation */ name(A1,S1),name(A2,S2), /* construction dun mutant */ concat(D1,F1,S1), /* gn`re toutes les couples D1,F1 tels que S1=D1.F1 */ e e concat(D2,F2,S2), /* gn`re toutes les couples D2,F2 tels que S2=D2.F2 */ e e concat(S1,F2,S M), /* construit le mutant */ /* transformation de la liste mutant en identificateur */ name(M,S M), /* TEST */ F1=D2, D1\=[], F1\=[],F2\=[]. ?- mutant(N). N = alligatorat ? ; N = alligatoratonlaveur ? ; N = caribouquetin ? ; N = chevalligator ? ; N = chevalapin ? ; N = chevalapine ? ; N = hibouquetin ? ; N = lapintade ? ; N = ratonlaveurat ? ; N = ratonlaveuratonlaveur Variante en xant le nombre minimal de lettres en commun /* mutant(M,N) : M est un animal mutant, construit par combinaison de deux animaux. Le premier se terminant comme le dbut du dernier, avec au moins N lettres en commun. */ e

42

mutant(M,N) :/* GENERATION */ animal(A1),animal(A2), /* transformation des identificateurs en listes pour manipulation */ name(A1,S1),name(A2,S2), /* construction dun mutant */ concat(D1,F1,S1), /* gn`re toutes les couples D1,F1 tels que S1=D1.F1 */ e e concat(D2,F2,S2), /* gn`re toutes les couples D2,F2 tels que S2=D2.F2 */ e e concat(S1,F2,S M), /* construit le mutant */ /* transformation de la liste mutant en identificateur */ name(M,S M), /* TEST */ F1=D2, D1\=[], F1\=[],F2\=[],length(F1,L),L>=M. ?- mutant(N,2). N = caribouquetin ? ; N = chevalligator ? ; N = hibouquetin ? ; N = lapintade ?- mutant(N,3). N = caribouquetin ? ; N = hibouquetin ? ; N = lapintade ?- mutant(N,4) no 14.2.4 Tri par permutation

On se propose de raliser un tri en cherchant parmi toutes les permutations dune liste donne, celle qui e e correspond a la liste ordonne. ` e /* tri par generation et test */ /* tri(T,T1) : T1 contient tous les elments de T dans lordre croissant */ e tri(T,T1) :- permut(T,T1),ordonne(T1) , !. Remarque : le cut permet de sortir d`s quon a trouv une solution (il peut y en avoir plusieurs en cas e e de doublons). /* GENERATION : on gn`re dans T1 par backtrack toute les permutations de la liste e e donne*/ e permut([],[]). permut([X1|T1],[X2|T2]) :- selectionner(X2,[X1|T1],T3),permut(T3,T2). /* selectionner(X,T1,T2) : slection avec backtrack dun X dans T1, T2=T1 priv de X e e */ /* version1 rcursive */ e selectionner(X,[X|T],T). selectionner(X,[Y|T],[Y|T1]) :- selectionner(X,T,T1). /* ou version2 avec concat */ selectionner(X,T,T0) :- concat(T1,[X|T2],T),concat(T1,T2,T0). /* TEST : est-ce que la liste est ordonne ? */ e ordonne([ ]). ordonne([X,Y|T]) :- ordonne([Y|T]) , X =< Y. 14.2.5 Les huit Reines

Le probl`me est de placer 8 reines sur un chiquier de 8X8 cases de mani`re ` ce quaucune dentre-elles e e e a ne soit en prise (on ne peut avoir deux pi`ces sur une mme ligne : horizontale, verticale ou diagonale). e e

43

14.2.6

Le labyrinthe

Un grand palais est constitu de chambres communicant par des portes. Les chambres et les portes e dnissent un labyrinthe : e

a f k j

b e g i

c d h

Ce palais est reprsent par les passages entre chaque pi`ce (la pi`ce a reprsente lextrieur) : e e e e e e porte(a,b). porte(b,c). porte(i,j). porte(b,e). porte(c,d). porte(d,h). porte(d,e). porte(e,f). porte(e,g). porte(g,k). porte(h,i). Une personne arrive en a et cherche ` tlphoner. Le tlphone se trouve dans une pi`ce j. On notera ce a ee ee e fait : telephone(j). On veut trouver un itinraire qui permet a la personne de parvenir au tlphone. Pour cela on utilise e ` ee lalgorithme simple qui consiste ` explorer les chambres en notant sur une feuille de papier les chambres a visites : e 1. Aller jusqu` la porte dune chambre C. a 2. Si C est sur la liste, ignorer cette chambre et retourner ` ltape 1. a e Sil ny a pas de nouvelle chambre en vue, revenir a la chambre prcdente et chercher une autre ` e e chambre. 3. Sinon, entrer dans la chambre C et lajouter a la liste. ` 4. Sil ny a pas de tlphone dans la chambre, retourner a ltape 1. Sinon arrter, la liste contient ee ` e e litinraire qui conduit a la chambre. e ` 1.1 On rdigera une premi`re version du programme qui imprime les messages du type : e e jentre dans la pi`ce P, jai trouv le tlphone dans la pi`ce q et Zut ! il ny a pas de tlphone e e ee e ee dans ce palais selon les cas. 1.2 Dans une deuxi`me version, le syst`me doit produire litinraire trouv. e e e e Peut-on trouver dautres chemins avec ce programme ? Si oui, modier le programme pour nen obtenir quun seul. 1.3 On rappelle le prdicat prdni bagof(X,But,Ens) qui russit si lensemble Ens est non vide avec : e e e e Ens= {X|But est vrai}. e Exemple : dans la base de faits sur les repas, ` la question bagof(X,plat(X),Les plats) Prolog rpond a yes avec Les plats = [grillade,poulet,dorade,bar]. Ecrire le programme Prolog qui produit litinraire le plus court pour trouver le tlphone. e ee e e On commencera par dnir le prdicat ca passe(X,Y) qui veut dire que les pi`ces X et Y sont relies par e e une porte et que lon peut passer de lune ` lautre. ca passe(X,Y) :- porte(X,Y). a ca passe(X,Y) :- porte(Y,X). 14.2.7 Conversion nombre Romain/Nombre arabe

Les nombres romains sont dnis par les symboles suivants : e I=1 V=5 IV=4 IX=9 X=10 L=50 XL=40 XC=90 C=100 D=500 CD=400 CM=900 M=1000 Pour crire un nombre il faut assembler les symboles dans lordre dcroissant par rapport a leur valeur. e e ` 44

La valeur du nombre est la somme des valeurs des symboles. Enn il faut utiliser le nombre minimum de symboles, cest ` dire quil faut utiliser, par exemple : IV a la place de IIII. a ` Par exemple 1498=1000+400+90+5+3=MCDXCVIII. Nous utilisons les cha nes de caract`res pour coder les nombres romains an vit toute ambigu e avec e e e t les variables Prolog. Dans Prolog les cha nes de caract`res sont reprsents par les listes dentier, chaque e e e entier correspondant au code ASCII dune lettre. Pour lire un nombre romain il faut lire symbole par symbole, en commenant par la droite tout en testant c que le nombre restant est valide. Par exemple apr`s IX il ne peut rien y avoir et apr`s CM il ne peut y e e avoir quun nombre strictement plus petit que 100. 14.2.8 Le fermier, la poule , le renard et le grain

Un fermier va au march avec un sac de grain, une poule et un renard. Il doit traverser une rivi`re avec e e une barque, mais cette barque na que deux places. En son absence, il ne peut laisser la poule et le grain ensemble sur une mme rive, ni le renard et la poule. Trouver la squence des traverses en barque pour e e e que tu le monde puisse passer la rivi`re sans probl`me. e e Un tat est dcrit par un liste [L1,L2,B] o` L1 reprsente la liste des prsents sur la rive 1 et L2 la liste e e u e e des prsents sur la rive 2, B est la rive ou se trouve le bateau. e Lorsquon ralise une traverse de la rive 1 ` la rive 2 il faut sassurer de 2 choses : e e a on na pas laiss un couple interdit (loup-poule ou poule-grain) e on ne retombe pas sur un tat pass , sinon on tourne en rond. e e Pour cela on stockera dans une liste les tats dj` visits. e ea e

15
15.1

Solution des exercices


Les huit Reines

/* reines(L) : L est un placement qui rsout le pb des 8 reines. L est une permutation e des entiers de 1 a 8 avec la signification suivante : le i`me lment de L est le n de ` e e e ligne ou placer la reine dans la i`me colonne. e rq : par def toute solution au pb est telle quil ny a quune seule dame sur chaque ligne et une seule dame sur chaque colonne. */ reines(L) :- /* GENERATION */ liste(8,L1),permut(L1,L), /* gnration de la liste des entiers e e de 1 a 8 dans un ordre quelconque */ ` /* TEST */ placementOK(L) . /* liste(N,L) construit une liste L contenant les N premiers entiers (de 1 a N) */ ` liste(1,[1]). liste(N, [N|L]) :- N>1,M is N-1,liste(M,L). /* permutat : cf. ci-dessus */ /* placementOK(L) : le placement reprsent par L est une solution au pb des 8 reines */ e e placementOK([]) . placementOK([R|L]) :- placementOK(L),not(attaque(R,L)) . /* attaque(R,L) la reine R (R est la ligne, colonne=1) attaque lune des reines de L */ attaque(R,L) :- selectRang(L,R1,N),diff(R,R1,N), !. /* selectRang(L,R,N) : slectionne par backtrack e un elment R quelconque de L, N est son rang */ e selectRang(L,R,N) :- concat(T1,[R| ],L),length(T1,N1),N is N1+1. /* abs(R-R1) = N */ diff(R,R1,N) :- R1 is R-N. 45

diff(R,R1,N) :- R1 is R+N. Solution : ?- reines(L), !. rsolution en 63 millisecondes e L = [8,4,1,3,6,2,7,5] remarque : il existe dautres solutions (92) En exercice : programme pour N reines (chiquier NxN), attention : pour N=2 et N=3, il ny pas de e solution.

15.2

Le labyrinthe

Voici les 3 versions du programme : /* VERSION 1 */ /* telephoner(Piece) : on a russit ` trouver le tlphone en partant de Piece */ e a e e telephoner(Piece) :aller(Piece,P,[Piece]), /* il faut gagner toutes les pi`ces possible e depuis la pi`ce de dpart */ e e telephone(P), /* et vrifier si un telephone sy trouve */ e !, /* si oui , on arr^te les recherches */ e nl,write(j ai trouv le tel dans la pi`ce ), e e write(P),nl . /* on a russi */ e e e e telephoner( ) :- write(zut ...). /* on na pas pas trouv le tlphone */ /* aller(X,Y,T) : aller de la pi`ce X ` la pi`ce Y. e a e T est lensemble des pi`ce visites */ e e aller(X,X, ). aller(X,Y,T) :- ca passe(X,Z), /* on passe par Z */ not(appartient(Z,T)), /* on na pas visit Z */ e write(j entre dans la pi`ce ),write(Z),nl, e aller(Z,Y,[Z|T]). /* VERSION 2*/ telephoner(Piece,I) :- /* I est litinraire suivi */ e telephone(P),aller(Piece,P,[Piece],I),affichage(I). /* aller(X,Y,L1,L2) : L2 est le chemin pour aller de X a Y ` L1 est lensemble des pi`ces visites pour arriver en X */ e e aller(X,X, ,[X]) :- !. aller(X,Y,T,[X|S]) :ca passe(X,Z), not(appartient(Z,T)), aller(Z,Y,[Z|T],S). /* affichage de litinraire */ e affichage([X]) :write(j ai trouv le tel dans la pi`ce ),write(X),nl. e e affichage([X,Y|I]) :write(je passe par la pi`ce ),write(X),nl,affichage([Y|I]). e /* VERSION 3 */ /* en gardant "aller" et "affichage" de la version 2 */ telephoner(Piece,I) :- /* I est litinraire suivi */ e telephone(P), bagof(I,aller(Piece,P,[Piece],I),S), /* S est lensemble des chemins */ min liste(S,I),affichage(I). /* I est le plus petit chemin */ /* min liste(LL,L) : L est la plus petite liste de L */ min liste([L],L). min liste([L1,L2|R],L3) :-

46

length(L1,N),min liste([L2|R],L3),length(L3,M),N>M, !. min liste([L1,L2|R],L1). /* L1 est forcement le min */

15.3

Conversion nombre romain/nombre arabe

/* romain(M,S) : M est une cha^ne de caract`res correspondant a un chiffre romain e ` valant S */ romain([],0) . /* "CM"=[67,77] */ romain([67,77|S],S1) :- romain(S,S0),S0<100,S0>=0,S1 is S0+900. /* "CD"=[67,68] */ romain([67,68|S],S1) :- romain(S,S0),100>S0,S0>=0,S1 is S0+400. /* "XC"=[88,67] */ romain([88,67|S],S1) :- romain(S,S0),10>S0,S0>=0,S1 is S0+90. /* "XL"=[88,76] */ romain([88,76|S],S1) :- romain(S,S0),10>S0,S0>=0,S1 is S0+40. romain("IX",9). romain("IV",4). /* "M"=[77] */ romain([77|S],S1) :- romain(S,S0),3000>S0,S0>=0,S1 is S0+1000. /* "D"=[68] */ romain([68|S],S1) :- romain(S,S0),400>S0,S0>=0,S1 is S0+500. /* "C"=[67] */ romain([67|S],S1) :- romain(S,S0),300>S0,S0>=0,S1 is S0+100. /* "L"=[76] */ romain([76|S],S1) :- romain(S,S0),40>S0,S0>=0,S1 is S0+50. /* "X"=[88] */ romain([88|S],S1) :- romain(S,S0),30>S0,S0>=0,S1 is S0+10. /* "V"=[86] */ romain([86|S],S1) :- romain(S,S0),4>S0,S0>=0,S1 is S0+5. /* "I"=[73] */ romain([73|S],S1) :- romain(S,S0),3>S0,S0>=0,S1 is S0+1.

15.4

Le fermier, la poule, le renard et le grain

/* laGrandeTraversee(L) : L est la liste des etats par lesquels passer pour faire traverser tous les animaux */ laGrandeTraversee(L) :- etatInitial(E1),etatFinal(E2),traversee(E1,E2,[E1],L). /* etatInitial et etatFinal donne les etats de dpart et darrive */ e e etatInitial([[poule,renard,grain],[],1]). etatFinal([[],[poule,renard,grain],2]). /* traversee(E1,E2,L1,L2) : E1 est ltat actuel, E2 ltat darrive, e e e L1 est la liste des etats parcourus pour arriver en E1, L2 est la liste des etats permettant de passer de E1 a E2 */ ` traversee(E1,E1, ,[E1]). traversee(E1,E2,T,[E1|T1]) :/* choix du prochain etat */ transition(E1,E3), /* vrification que cet etat na pas encore et visit */ e e e not boucle(E3,T), /* passage de E3 a E2 */ ` traversee(E3,E2,[E3|T],T1). /* transition(E1,E2) : passage de E1 a E2 en un voyage ` On vrifie quon a pas laiss seuls de couple "interdits" */ e e /* passage dune rive a lautre en emportant quelque chose */ ` transition([L1,L2,1],[L3,L4,2]) :- sur(L3),length(L1,N1),N1>0,N3 is N1-1, length(L3,N3),concat(L1,L2,L5),permut(L5,L6), 47

concat(L3,L4,L6),inclus(L3,L1). transition([L1,L2,2],[L3,L4,1]) :- sur(L4),length(L1,N1),N1<3,N3 is N1+1, length(L3,N3),concat(L1,L2,L5),permut(L5,L6), concat(L3,L4,L6),inclus(L1,L3). /* passage a "vide" */ ` transition([L1,L2,1],[L1,L2,2]) :- sur(L1). transition([L1,L2,2],[L1,L2,1]) :- sur(L2). e e a /* not boucle(E,L) : ltat E nest pas dj` dans la liste L */ not boucle( ,[]). not boucle(E1,[E2|T]) :-not(equiv(E1,E2)),not boucle(E1,T). /* equiv(E1,E2) : deux etats sont equivalents sil le fermier est sur la m^me e berge et que sur la m^me berge il y a les m^me choses a une permutation pr`s : e e ` e [renard,grain]/[grain,renard] */ equiv([L1, ,B],[L2, ,B]) :- permut(L1,L2). /* sur(L) : les lments de la liste L peuvent etre laisss ensembles sans e e ^ e surveillance */ sur([]). sur([poule]). sur([renard]). sur([grain]). sur([renard,grain]). /* inclus(L1,L2) : la liste L1 est incluse dans L2 */ inclus([], ). inclus([X|T],L) :-appartient(X,L),inclus(T,L).

48