prolog je comprend pas le symbole _ et !

a marqué ce sujet comme résolu.
Auteur du sujet

Bonjour,

je suis en train d’étudier le prolog mais je n’arrive pas a comprendre comment les listes fonctionnent dans les fonctions, j’ai 3 exemples :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
last(X,[_|Z]):-
last(X,Z).
 
last(c,[a,b,c]).
 
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
premier(X,L):-
L=[X|_].
 
premier(a,[a,b,c]).
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
appartient(X,[X|_Y]).
appartient(X,[_Z|Y]):- appartient(X,Y).
 
appartient(c,[a,b,c]).

1) je ne voit pas a quoi correspond les [X|Y], [_Z|Y], [X|] si quelqu’un pouvait m’expliquer

2) dans la fonction premier par exemple, je check si X est le premier élement de la liste L, comment retourner X si X est le premier élément de L ? dans la théorie je dois ajouter un 2ieme prédicat et utiliser le symbole "!" ? mais je ne comprend pas ce que veut dire le "!"

voila ce que je ferais (mon code ne marche pas)

1
2
3
4
5
6
7
8
premier(X,L, last_element):-
L=[X|_].
!
 
premier(X,L, last_element):-
last_element=[X|_].
 
premier(a,[a,b,c],last_element).

par avance merci pour votre aide.

Édité par mathema

+0 -0

Le _ signifie "n’importe quoi", un peu comme le * en bash.

Ton prédicat last(x, lst) est censé être vrai quand x est le dernier élément de lst. Du coup écrire last(X, [_|y]) permet de dire à prolog de ne considérer que le dernier élément de la liste. Donc quand tu appelles last(c, [a, b, c]), prolog va tenter d’unifier c avec X et [a, b, c] avec [_|y] : en gros, X va prendre la valeur de l’atome c, _ va matcher [a, b] et y prendra la valeur du dernier élément de la liste (donc c).

Ca fait un petit moment que je n’ai pas fait de prolog, donc je me trompe peut être, mais je crois que tes prédicat ne fonctionneront dans le cas ou tu lui passe une liste contenant un unique élément, puisque _ ne pourra rien matcher, puisqu’il n’y a rien a matcher. Ma solution serait plutôt :

1
2
last(x, [x]). % Vrai si la liste ne contient que x
last(x, [_|x]). % Vrai si le dernier élément de la liste est x

Note qu’ici j’ai demandé a prolog d’unifier mes paramètres sous le même atome, ça permet d’écrire moins de code, et c’est, je trouve plus clair.

+0 -0

Quand tu écris [X | Y] en Prolog, ça ne veut pas dire « une liste dont le dernier élément est Y », mais « une liste dont le premier élément est X et tous les suivants sont la liste Y ». Dans le cas d’une liste à un seul élément, Y sera la liste vide.

+0 -0

Ok, au temps pour moi, comme je l’ai dis au dessus, ça fait un petit moment que je n’ai plus fait de prolog.

Cela étant éclairci, je suis à présent certain que ton prédicat last ne fonctionne pas. Je ferais donc un truc comme ça :

1
2
3
4
last(x, [x]). % Vrai si la liste ne contient que l'atome x

last(x, [_|tail] :-
    last(x, tail). % Appel récursif jusqu'à tomber sur le cas où la liste ne contient qu'un élément.

Du coup, quand tu appellera last(c, [a, b, c]) prolog va procéder de la façon suivante :

  1. L’appel initial : last(c, [a, b, c]).
    • Appel du premier prédicat défini (last(x, [x]))
    • Unification de x et c (ça marche)
    • Unification de [x] et [a, b, c] (ça ne marche pas)
    • Appel du second prédicat défini (last(x, [_|tail]))
    • Unification de x et c (ça marche)
    • Unification de [_|tail] et [a, b, c], ça marche et tail prend la valeur [b, c] (cf. l’explication de Eusèbe au dessus)
  2. Appel récursif last(x, tail), qui est équivalent à last(c, [b, c])
    • Les mêmes étapes que précédemment, sauf que [_|tail] sera unifié avec [b, c], donc tail vaut [c]
  3. Enfin, dernier appel last(x, tail), équivalent à last(c, [c])
    • Prolog est capable de faire l’unification à partir du premier prédicat défini
  4. Donc last(c, [a, b, c]) est vrai

Si mes souvenir sont bons, tu peux récupérer la valeur du dernier élément d’une liste en appelant last(x, [a, b, c]) et prolog va tenter d’unifier x avec la bonne valeur (si x n’a pas déjà de valeur). Du coup x vaudra c.

Tu peux modifier ton prédicat premier de la sorte :

1
2
premier(x, [x]).
premier(x, [x|_]).

Je suis pas sûr de mon coup, il est possible que la première définition soit inutile et qu’on puisse se contenter de la seconde, je n’ai pas d’interpréteur Prolog sous la main pour vérifier. Du coup, comme pour last tu peux récupérer le premier élément d’une liste avec premier(x, [a, b, c]), et Prolog unifiera x avec a.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte