Vous êtes sur la page 1sur 7

HE Arc

IARTI 2008 2009

Aller un peu plus loin avec Prolog


Dans ce TP, nous allons tudier plus en dtail le fonctionnement de Prolog et la manire den tirer parti pour rsoudre des problmes.

1 Unication
Dans le TP prcdent, nous avons utilis des variables sans trop nous poser de question, mais le mcanisme de gestion des variables en Prolog est assez diffrent de ce dont on a lhabitude. Ouvrez linterprteur Prolog et tapez
? X = 2 .

Prolog vous rpondra X=2, ce qui ne devrait pas trop vous tonner. Pourtant, ce que vous venez de faire nest pas proprement parler une affectation de variable. Vous navez pas dcrt Je dcide que X vaut 2, mais vous avez demand Prolog En fonction de ce que tu sais dj, se peut-il que X=2 ?. Pour mieux comprendre ce phnomne essayons dautres tentatives1 :
? X=Y .

La rponse de Prolog est que la valeur X et Y doit tre la mme, mais quelle nest pas dtermine. Plus difcile :
? X=Y , Y = 2 .

Dans un langage traditionnel, on aurait ici une erreur : La valeur de Y est utilise avant dtre dnie. Prolog, lui, se souvient que les deux variables doivent avoir la mme valeur et lorquune des deux reoit une valeur, lautre aussi !
? X=Y , Y =2 , X = 3 .

Cet ensemble daffectations est incohrent. La rponse de Prolog est donc Fail. Ceci met en vidence une caractristique de Prolog : les variables sont immuables. Une fois une valeur affecte, il nest plus possible den changer pour toute la dure de vie de la variable (i.e. la requte). Ceci peut paratre surprenant, mais la rexion cest cohrent : si les affectations sont au fait des questions du genre est-il possible que X prenne telle valeur ?, il est normal que la valeur ne puisse pas changer. Le mcanisme qui permet de grer les valeurs des variables sappelle unication. Au fait, X=Y se lit X sunie Y. Mais lunication peut faire plus que tester si 2=3. Elle inclut un puissant mcanisme de Pattern Matching. Essayez
? X+Y = 1 + 2 . ? X+Y=f ( x ) * 2 + 3 * 4 . ? X * 3=2 * Y .
1 Notez

que les liaisons de variables ne portent que sur la requte en cours ; chacune de ces requtes est donc indpendante.

1/7

distribu sous licence creative common | dtails sur www.matthieuamiguet.ch

HE Arc Par contre, ce pattern matching peut causer des surprises :


? X = 2 + 3 .

IARTI 2008 2009

Pour forcer lvaluation arithmtique de la partie droite, on doit utiliser is :


? X i s 2 + 3 .

Comme vous le voyez, cela force lvaluation de la partie droite, puis tente lunication avec la partie gauche. Exercice Que rpond Prolog lors des tentatives dunications suivantes ? essayez de deviner, puis vriez dans linterprteur. 1. bread = bread 2. Bread = bread 3. bread = bread 4. Bread = bread 5. bread = sausage 6. food(bread) = bread 7. food(bread) = X 8. food(X) = food(bread) 9. food(bread,X) = food(Y,sausage) 10. food(bread,X,beer) = food(Y,sausage,X) 11. food(bread,X,beer) = food(Y,kahuna_burger) 12. food(X) = X 13. meal(food(bread),drink(beer)) = meal(X,Y) 14. meal(food(bread),X) = meal(X,drink(beer)) Prdicats relatifs lunication x=y russit si x et y sont uniables. Dans ce cas, lunication est ralise. x\=y russit si x et y ne sont pas uniables var(x) russit si x est une variable non instantie nonvar(x) russit si x nest pas une variable non instantie x==y russit si x et y sont gaux (sans forcer lunication) x\==y russit si x et y ne sont pas gaux (sans forcer lunication) Prdicats relatifs larithmtique Pour tous les prdicats suivants, les parties values doivent tre entirement instancies. Par exemple
? X =2 , 2 =:= X .

russit alors que


? 2 =:= X , X = 2 .

provoque une erreur.

2/7

distribu sous licence creative common | dtails sur www.matthieuamiguet.ch

HE Arc

IARTI 2008 2009

x is y est dcrit ci-dessus x=:=y est utilis pour tester lgalit de deux nombres ou de deux expressions arithmtiques. Force lvaluation arithmtique des deux expressions avant la comparaison. x<y, x=<y, x>y, x>=y forcent lvaluation artihmtique des deux cts et russit si la comparaison est vraie. Exemple : la drivation Pour illustrer le mcanisme dunication, nous allons implmenter une esquisse de drivation de fonctions. Nous voudrons implmenter les rgles de drivation suivantes : 1. 2. 3. 4. 5.
d dx x = 1 d dx C = 0 d n n1 dx x = nx d d d dx (u(x) + v(x)) = dx u(x) + dx v(x) du(x) dv(x) d dx (u(x)v(x)) = dx v(x) + u(x) dx

Comment implmenter ceci ? la premire question qui se prsente est la suivante : les prdicats Prolog peuvent russir ou chouer, mais ne retournent pas de valeur. . . Nous implmenterons donc la drivation comme une relation entre la fonction, la variable et la f (x) drive : d(f(x),x,g(x)) signiera : d dx = g(x) La premire rgle pourrait donc simplmenter ainsi :
d ( X , Y , Z ) : X=Y , Z = 1 .

Mettez cette rgle dans un chier et lancez-le ; interrogez votre base en entrant
? d ( x , x , R ) .

Si tout va bien, Prolog devrait vous rpondre R=1, qui est bien la rponse quon attend ! Mais comme lunication nest pas une affectation de variables, on peut aussi utiliser ce prdicat pour vrier un calcul : ? d(x,x,1) . devrait donner true. pour intgrer, cest dire inverser le processus de drivation : ? d(F,x,1) . nous donne F=x. Pour les mmes raisons, on peut crire notre rgle de manire plus conomique. Ouvrez votre chier et remplacez son unique rgle par le fait
d(X , X , 1 ) .

Ceci devrait fonctionner de la mme manire quavant ! La deuxime rgle fait intervenir le prdicat atomic, qui russit si son argument est. . . atomique (i.e. un nombre ou une constante). Les suivantes ne posent pas de problme particulier et font plein usage du pattern matching :
d ( C , X , 0 ) : a t o m i c ( C ) , C \ = X . d ( X ^ N , X , D ) : N1 i s N 1 , D=N * X ^ N1 . d ( U+V , X , DU+DV ) : d ( U , X , DU ) , d ( V , X , DV ) . d ( U * V , X , U * DV+V * DU ) : d ( U , X , DU ) , d ( V , X , DV ) .

Vous pouvez maintenant tester une drivation :


? d ( 3 * x ^ 2 + 5 , x , R ) .

Le rsultat nest pas trs simpli, mais il est correct. Remarque Malheureusement, le code ci-dessus ne peut pas tre utilis lenvers pour intgrer ; en effet, lopration is de la rgle 3 ne marche que dans un sens et la rgle numro 2 ne peut pas tre retourne (innit de solutions !).

3/7

distribu sous licence creative common | dtails sur www.matthieuamiguet.ch

HE Arc

IARTI 2008 2009

2 Le moteur en chanage arrire


La page http://cs.union.edu/~striegnk/learn-prolog-now/html/node20.html dcrit trs bien le fonctionnement de Prolog lorsquon lance une requte. Lisez ce document maintenant.

2.1 Exercice (sur papier)2


Considrons la base prolog suivante :
1 2 3 4 5 6 direct_flight ( hongkong , beijing ) . direct_flight ( beijing , tokyo ) . direct_flight ( tokyo , sanfrancisco ) . direct_flight ( sanfrancisco , hongkong ) . flight ( X , Y ) : direct_flight ( X , Y ) . flight ( X , Y ) : direct_flight ( X , Z ) , flight ( Z , Y ) .

Dessinez un arbre de recherche pour la requte


flight ( hongkong , X ) .

Dveloppez votre arbre de recherche jusqu la cinquime rponse de Prolog (incluse !). Votre arbre de recherche devra indiquer 1. Les faits et rgles utiliss (notez le n de la ligne) 2. Les unications effectues. Les variables intermdiaires seront nommes _1, _2, _3, etc. Pour conomiser de la place, vous pourrez utiliser les abrviations suivantes : ight f direct_ight df hongkong hk tokyo tk beijing bj sanfrancisco sf

2.2 Exercice (sur ordinateur)


Vous aurez donc compris que Prolog cherche (en profondeur) une combinaison de lattribution des variables qui satisfasse toutes les contraintes exprimes. Ceci permet de rsoudre certains problmes de type combinatoire trs facilement. La gure 1 prsente un mot crois simple 6 mots. Il sagit de trouver un placement cohrent des 6 mots dans la grille. Indication Commencez par dnir la liste des mots considrs et donner les lettres qui les composent. . .
word ( abalone , a , b , a , l , o , n , e ) word ( abandon , a , b , a , n , d , o , n ) word ( enhance , e , n , h , a , n , c , e ) word ( anagram , a , n , a , g , r , a , m ) word ( connect , c , o , n , n , e , c , t ) word ( elegant , e , l , e , g , a , n , t )
2 inspir

. . . . . .

de http://www.cs.ust.hk/~oscarau/comp251_2006/notes/prolog_ex1.htm

4/7

distribu sous licence creative common | dtails sur www.matthieuamiguet.ch

HE Arc

IARTI 2008 2009

Mots placer : abalone abandon enhance anagram connect elegant

F IG . 1: Un mot crois. . . . . . puis crivez un prdicat crossword(V1,V2,V3,H1,H2,H3) qui permet de trouver le placement des mots dans la grille.

3 Structures de donnes et rcursivit


3.1 Listes
Nous lavons vu, Prolog connat les nombres entiers (2, -3) et rels (1.2, -1.3e5) et les atomes (a, toto, . . .). Il y a aussi videmment les chanes de caractres (ceci est une chane) et nous avons rencontr quelques structures comme f(a(b,c)). En dehors de cela, la structure de donnes fondamentale de Prolog est la liste : [a,1,toto,2.3, hello]. La manire standard daccder une liste en Prolog est la suivante : si L est une liste, [H|R] sunie L en uniant H au premier lment de L et R tout le reste de L. Essayez
? [ 1 , 2 , 3 ] = [ H | R ] . ? [ H | R ] = [ 1 ] . ? [ H | R ] = 1 .

3.2 Rcursivit
Prolog ne propose pas de structures de contrle telles que les boucles for, while, etc. Comme dans la plupart des langages fonctionnels et logiques, la manire ofcielle de grer le contrle est la rcursivit. Par exemple, pour crire les nombres de 0 N :
print_numbers ( 0 ) : w r i t e ( 0 ) , n l . print_numbers ( N ) : N1 i s N 1 , print_numbers ( N1 ) , write (N) , nl .

(o write a un sens vident et nl (newline) passe la ligne).

5/7

distribu sous licence creative common | dtails sur www.matthieuamiguet.ch

HE Arc

IARTI 2008 2009

3.3 Accs rcursif aux listes


La manire standard de manipuler des listes en Prolog est donc dutiliser la rcursivit et la notation [H|R]. Par exemple, un prdicat pour accder au nime lment dune liste :
nth ( 0 , [ H | _ ] , H ) . nth ( N , [ _ | R ] , X ) : N1 i s N 1 , nth ( N1 , R , X ) .

Ce prdicat peut de nouveau tre utilis dans plusieurs sens : nth(2,[a,b,c ], X) permet de rcuprer llment 2 de la liste, nth(2,[a,b,c ], c) permet de vrier que llment 2 est bien c, et nth(2,L,c) permet de construire une liste partiellement instancie : tout ce quon sait de L est que son lment 2 est c !3

3.4 Exercices
3.4.1 Listes En utilisant la notation [H|R] et la rcursivit, crire 1. Un prdicat4 double/2 qui ddouble tout les lments dune liste :
? double ( [ a , b , c ] , D ) . D = [a , a , b , b , c , c]

Peut-on utiliser ce prdicat pour effectuer lopration inverse (ie retrouver [a,b,c] partir de [a, a, b, b, c, c]) ? Si oui, comment faire ? 2. Un prdicat zip/3 qui combine deux listes de la manire suivante :
? zip ( [ a , b , c ] , [ 1 , 2 , 3 ] , Z ) . Z = [ [ a , 1] , [b , 2] , [c , 3]]

3. Un prdicat myMember/2 qui se comporte comme la primitive member/2, cest--dire qui permet de dterminer si un lment aparat dans une liste :
? myMember ( a , [ b , a , c ] ) . true ? myMember ( a , [ b , d , c ] ) . fail

4. Un prdicat enumerate/1 qui numre sur la sortie standard les lments dune liste :
? enumerate ( [ 1 , 2 , 3 ] ) . 1 2 3 true .

3 Il

4 La

y aurait encore un sens dutilisation (lequel ?) mais il ne fonctionne pas (pourquoi ?). notation name/n signie un predicat nomm name et prenant n arguments.

6/7

distribu sous licence creative common | dtails sur www.matthieuamiguet.ch

HE Arc 3.4.2 Somme des n premiers nombres crire un prdicat qui fait la somme des n premiers nombres entiers :
? somprem ( 5 , S ) . S = 15

IARTI 2008 2009

Pourriez-vous utiliser ce prdicat pour faire lopration inverse (retrouver 5 partir de 15) ? Si oui, comment ? si non, pourquoi ? 3.4.3 Rendre la monnaie crire un programme Prolog qui, tant donn un montant pay et un prix, dtermine comment rendre la monnaie. Exemple :
? rend ( 1 0 A rendre : 1 piece de 1 piece de 1 piece de true ,7.45) . 0.05 0.5 2

Indications : 1. Commencer par dclarer les types de pices disponibles. . .


... piece ( 1 ) . piece ( 0 . 5 ) . ...

2. . . . puis crire le prdicat rend de manire rcursive.

7/7

distribu sous licence creative common | dtails sur www.matthieuamiguet.ch