Vous êtes sur la page 1sur 25

Université de SOUK AHRAS

Faculté des sciences et technologie


Département de Mathématiques et Informatique

Programmation
Logique
Enseignant: Arous Mokdad
Niveau: 3eme Année Informatique
2016/2017
 Les Listes et l'Opérateur de
Coupure en Prolog
1. Les Listes
 La liste est un terme composé particulier de symbole
de fonction " . " et d'arité 2:

 le premier argument est l'élément de tête de la liste,

 et le deuxième argument est la queue de la liste.

 La liste vide est notée: [].

 Le foncteur « . » est le foncteur de liste :


.( a , .( b , [] ) ) est équivalent à: [a, b].
1. Les Listes
 La liste: .(X , L) est également notée: [X|L],

 La liste: .(X1 , .(X2 , L)) est également notée:


[X1, X2 | L],

 La liste: .(X1, .(X2, ... , .(Xn , L)... )) est également


notée: [X1, X2, ... , Xn | L],

 La liste vide est: [].


1. Les Listes
 La liste: [a , b , c] correspond à la liste: .(a,.(b,.(c,[])))
et contient les 3 éléments: a , b et c.

 La liste: [a , b | L] correspond à la liste .(a, .(b, L)) et


contient les 2 éléments: a et b, suivis de la liste
(inconnue): L.

 L'opérateur « | » est un constructeur de liste et peut


servir pour extraire la tête de la liste.
1. Les Listes
?- L = .(a, .(b, .(c, [] ))).
L = [a, b, c].

?- [a | [b, c] ] = L.
L = [a, b, c].

?- [a, b | [c] ] = [a, b, c | [] ].


True.
1. Les Listes
?- [a, b | X ] = [a, b, c | [] ].
X = [c] .

?- [ a, b ] = [ X | Y ].
X=a
Y = [b].
1. Les Listes
?- [a] = [ X | Y ].
X=a
Y = [].

?- [ a, [ b ] ] = [ X | Y ].
X=a
Y = [[b]].
1. Les Listes
?- [a, b, c, d ] = [ X, Y | Z ].
X=a
Y=b
Z = [c, d].

?- [ [a, b, c] , d, e ] = [ X | Y ].
X = [a, b, c]
Y = [d, e].
1. Les Listes
 Une liste est une structure récursive: la liste [X|L] est
composée d'un élément de tête X et d'une queue de liste L
qui est elle-même une liste.
 Par conséquent, les relations Prolog qui "manipulent'' les listes
seront généralement définies par:
 une ou plusieurs clauses récursives, définissant la relation
sur la liste [X|L] en fonction de la relation sur la queue de
liste L,
 une ou plusieurs clauses non récursives assurant la
terminaison de la manipulation, et définissant la relation
pour une liste particulière (par exemple, la liste vide, ou la
liste dont l'élément de tête vérifie une certaine condition...
etc.).
1. Les Listes
1.1. Prédicat member/2
 Ce prédicat permet d'examiner l'appartenance d'un
élément à une liste. Première façon d'écrire ce prédicat:
member(X, [Tete|Queue]) :- X =Tete.
member(X, [Tete|Queue]) :- X \=Tete, member(X, Queue).

 Mais puisque les règles dans Prolog sont exécutées dans


l'ordre qu'elles sont écrites, on peut simplifier la
définition du prédicat comme suit :
member(X, [ X | _ ]).
member(X, [ _ | Queue]) :- member(X, Queue).
1. Les Listes
1.2. Prédicat append/3
 Le prédicat append/3 permet de concaténer deux listes
(ou de vérifier qu'une liste est la concaténation de deux
premières).

append( [], L, L).


append( [X | XS] , YS, [X | Liste]):- append(XS, YS, Liste).
1. Les Listes
1.3. Prédicat length/2
 Ce prédicat permet de détermine la longueur d’une liste:

length( [] ,0).
length( [Tete | Queue] ,N) :- length(Queue, N1), N is N1 + 1.
2. Opérateur de Coupure
 Par défaut Prolog tente de prouver la requête de toutes
les façons possibles (suivant le programme) jusqu’à ce
qu’une preuve soit trouvée.

 Si une preuve échoue, Prolog fait un retour-arrière pour


tenter une autre ligne de preuve.

 Dans certains cas ce retour-arrière peut être nuisible:


1. si le retour-arrière va répéter une solution.
2. si le retour-arrière n’a aucune chance de trouver une
solution.
2. Opérateur de Coupure
Exemple: Soit la fonction "membre" qui vérifie qu’un
élément est bien dans une liste.

 Première solution :
membre1(X, [ Y | L ]) :- X = Y.
membre1(X, [ Y | L ]) :- X \= Y, membre1(X, L).
2. Opérateur de Coupure
Exemple:
 Deuxième solution :
membre2(X, [ X | _ ]).
membre2(X, [ _ | L ]) :- membre2(X, L).
 L’idée ici, c’est que le cas d’égalité a été traité avec la
première règle et que l’on n’a pas à en tenir compte lors
de l’écriture de la deuxième règle.
2. Opérateur de Coupure
Conclusions

— L’écriture du programme a de grosses conséquences sur


son exécution.

— Seule la première occurrence de X dans L nous


intéressait ici. Nous aurions aimé pouvoir spécifier que le
programme devait s’arrêter dès la première occurrence
trouvée.
2. Opérateur de Coupure
1. Signification opérationnelle de la coupure
 La coupure, aussi appelée "cut", est notée " ! ".
 La coupure est toujours "prouvée" avec succès, elle est
utilisée pour "couper" des branches de l'arbre de recherche.
 La "preuve" de la coupure a pour effet de modifier l'arbre de
recherche: elle coupe l'ensemble des branches en attente
créées depuis l'appel de la clause qui a introduit la coupure.
 l'opérateur de la coupure sert donc à restreindre l’arbre de
recherche en empêchant le développement de branches qui
conduisent à des échecs ou à des solutions que l’on n’a pas
besoin de connaître
2. Opérateur de Coupure
Principe :
tete(...) :- pr1(...), pr2(...), ! , pr3(...), pr4(...).
 Si pr1 ne réussit pas, on peut tenter de démontrer tete
avec une autre clause,
 Si pr2 ne réussit pas, on peut annuler l'unification de pr1
et tenter de démontrer pr1 ou tete avec d'autres
clauses,
 Si pr1 et pr2 réussissent, on franchit la coupure (qui
réussit toujours) et les unifications de pr1 et pr2 ne
peuvent être modifiées (par contre si pr4 ne réussit pas,
on peut revenir sur pr3).
2. Opérateur de Coupure
Exemple 1: Considérons l'exemple suivant qui concerne
la constitution du plat principale d'un repas:
poisson(truite).
poisson(daurade).
viande(steak).
viande(escalope).
entree(cresson).
dessert(fraise).
plat(P) :- poisson(P).
plat(V) :- viande(V).
repas(E,P,D) :- entree(E),plat(P),dessert(D).
2. Opérateur de Coupure
 La question:
?- plat(P), viande(P).
fournit en réponse tons les plats qui sont de la viande.

?- plat(P), viande(P).
P = steak ;
P = escalope
2. Opérateur de Coupure
 La question:
?- plat(P), viande(P) , ! .
fournit en réponse le premier plat qui est de la viande.

?- plat(P) , viande(P) , ! .
P = steak
2. Opérateur de Coupure
 La question:
?- plat(P), ! , viande(P).
vérifie si le premier plat est de la viande.

?- plat(P), ! , viande(P).
False
2. Opérateur de Coupure
Exemple 2:
?- repas(E,P,D), poisson(P). /* quels sont tous les repas
comprenant du poisson? */
?- poisson(P), repas(E,P,D). /* idem */
?- 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). /* tous les repas comprenant
du poisson */
2. Opérateur de Coupure
Exemple 3:
 Dans la recherche d’appartenance d’un élément à une
liste, la coupure permet d’arrêter le programme lors de la
découverte de la première solution possible. On peut donc
écrire:

membre(X, [ X | _ ]) :- ! .
membre(X, [ _ | L ]) :- membre(X, L).

Vous aimerez peut-être aussi