Prologue: Vérifier si quelque chose est le dernier élément de la liste?
Je suis nouveau sur le prologue et je suis en fait, d'essayer d'écrire une clause qui permettrait d'évaluer true si un élément donné est le dernier élément dans une liste donnée. Voici ce que j'ai:
last(X,[Y|X]).
last(X,[Y|Z]) :- last(X,Z).
Je pensais que ce serait faire le tour, mais quand je demande prologue:
?- last(c,[a,b,c]).
Prolog renvoie la valeur false. J'ai essayé la requête suivante pour voir ce Prologue pense devrait convenir à ma définition de ce dernier:
?- last(c,X).
X = [_G530|c] ;
X = [_G530, _G533|c] ;
X = [_G530, _G533, _G536|c]
Donc, ce que je ne suis pas sûr à ce sujet est pourquoi le caractère "|" est toujours dans la liste?
Mise à jour: la dernière([c],[a,b,c]), on obtient le comportement souhaité. Cependant, je ne sais pas pourquoi mon 1er argument doit être une liste?
OriginalL'auteur user3295806 | 2014-02-11
Vous devez vous connecter pour publier un commentaire.
Vous pourriez voulez que ce:
La
|
indique une "queue" ou " le reste de la liste.'Avec
?- last(c,X).
Prolog produit des listes (en fonction de votre première définition) qui ont c est le dernier élément.Lorsque vous interrogez
?- last(c,[a,b,c]).
, elle renvoie faux car vous n'avez pas défini un cas pour une liste d'un seul élément[X]
ou[X|[]]
. Donc il échoue lorsque la liste est plus courte que les deux éléments.Cependant,
last([c],[a,b,c])
réussit parce que vous obtenez[b|_29]
ou que ce soit indiquant que la queue pourrait être n'importe quelle liste. Donc, il _29 "peut-être" [c]', satisfaire la première définition commelast([c],[b|[c]]).
Rappelez-vous que une liste non vide dans Prolog est en fait une paire de le premier élément de la liste (de la tête) et une liste de tout le reste (de la queue). Habituellement écrit comme [tête|queue].last(X,[_|Z]) :- last(X,Z).
Vrai. Surtout quand les avertissements pourraient confondre un débutant.
OriginalL'auteur traitor
Pourquoi ne pas voir les choses d'un point de vue grammatical. Alors, quel est le dernier élément dans une liste?
2 ?- last(X, [1,2,3]). <br/> X = 3 ; <br/> false.
. Est-ce prévu?hmm. J'ai attendu qu'elle doit être déterministe, mais maintenant que j'essaie, je ne peux pas le faire sans l'aide d'un coupe -
last(X,[_|B]):- B=[_|_],!, last(X,B).
,last(X,[X]):- !.
. ce qui est inattendu.Ne mélangeons pas logique du déterminisme, une caractéristique de performance. Avec ! comme vous l'indiquez, vous êtes sacrifier la logique de l'exhaustivité d'une "performance".
last(X,[X|Xs])
doit réussir pour une infinité de réponses.ah, je vois. donc, il est inhérent. merci.
Habile utilisation de la ! peut-être, mais c'est un cauchemar, et certainement pas en valeur l'effort. Après tout: Il y a un choix unique point qui est superflu. Il serait autre chose si il y aurait autant de choicepoints en tant qu'éléments dans la liste. Qui serait grave, en effet. Le Prologue de la convention de mettre le récursive dernière règle évite parfois.
OriginalL'auteur false
Pourquoi ne pas utiliser ajouter?
http://www.swi-prolog.org/pldoc/man?predicate=append/3
OriginalL'auteur Dylon Dickinson
Parce que la queue d'une liste est un liste elle-même.
Une liste en Prolog peut être vu comme
[H | T]
, oùH
est le premier élément (la tête), etT
(la queue) est une liste de tous les autres éléments.Votre liste
[a, b, c]
est en fait[a | [b | [c | [] ] ] ]
lorsque vous le décomposer (le dernier de la queue est toujours une liste vide):Ainsi, lorsque vous atteignez le point où vous vous demandez si
last(c, [b, c])
, qui se décompose àlast(c, [b|[c]])
, c'est pourquoi la première clause ne peut pas être instanciée, parce queX
ne peut pas être à la foisc
et[c]
. C'est pourquoi il ne de travail lorsque vous avez demandélast([c],[a,b,c])
.La version proposée par alpha fonctionne, car il prend en compte:
OriginalL'auteur SQB