2017-10-21 17 views
1

Je commence avec prolog, et comme un exercice j'essaie d'inverser une liste.Inverser la liste dans Prolog

Par exemple, inv([1,2,3], S) devrait donner S = [3,2,1]. Voici ce que partenaire et moi avons déjà fait:

conc([], L, L). 
conc([X|L1], L2, [X|L3]) :- conc(L1, L2, L3). 

tail([X|Y], S) :- conc([], Y, S). 

inv([X|Y], S) :- tail([X|Y], TAIL), inv(TAIL, R_TAIL), conc(R_TAIL, X, S). 
inv([], []). 

Les trois premières lignes fonctionnent très bien. Mais ne comprends vraiment pas ce qui se passe avec les deux derniers, et donc comment y remédier. Je veux juste trouver la queue (cela fonctionne, quand je viens d'utiliser la fonction tail) de la liste, inverser, puis l'ajouter à la tête de la liste. Pourriez-vous m'aider les gars?

+0

Votre problème est que vous essayez de résoudre tout avec votre conc/3 prédicat (qui est habituellement appelé append/3). Pensez à votre queue/2 prédicat. Qu'est-ce que ça fait? Il supprime le premier élément d'une liste et concatène la liste vide à la fin de la liste afin d'obtenir la queue de la liste. C'est superflu. la variable Y contient déjà la queue de la liste. Ainsi, si vous avez vraiment besoin d'un prédicat de queue que le simple fait 'tail ([_ X | Y], Y) .' fait le travail. –

+0

Votre code ne fonctionne pas, car dans la deuxième ligne, vous écrivez 'conc (R_TAIL, X, S)' où R_TAIL est une liste et X est un élément de liste. Ainsi, vous essayez de concaténer un élément avec une liste (avec 'conc (R_TAIL, [X], S)' cela fonctionnerait). Essayez de toujours regarder la trace d'une requête simple (par exemple 'inv ([1,2], X)'), afin de comprendre ce qui se passe. –

+0

@JoanC Ouais, ça a marché :). Merci pour la réponse. Je commence vraiment avec prolog et cette syntaxe bien les problèmes .. Je pense qu'il est censé m'arriver: p –

Répondre

1

Votre code ne fonctionne pas pour moi.

Essayez cette façon à la place:

?- reverse([1,2,3],Xs), write(Xs). 

reverse(Xs,Ys) :- reverse(Xs,[],Ys). 

reverse([],A,A). 
reverse([H|T],R,A) :- reverse(T,[H|R],A). 
+1

Pourquoi utiliser 'write/1' sur [tag: prolog-toplevel]? – repeat

+1

@repeat - C'est juste pour afficher la valeur de 'Xs' sur la console. Ce n'est pas nécessaire pour le calcul. – Enigmativity

+1

Je ne comprends pas très bien. Le toplevel montre quand même les bindings de variables alors pourquoi utiliser 'write/1'? – repeat

2

solution foldl/4 Alternative:

prepend_element(E, L, [E|L]). 

inv(List, Reversed) :- 
    foldl(prepend_element, List, [], Reversed).