chainage Prolog: Rotation de la liste n fois à droite



avant artificielle (1)

Travaillant sur un prédicat, rotate(L,M,N) , où L est une nouvelle liste formée en tournant M à droite N fois.

Mon approche consistait simplement à ajouter la queue de M à sa tête N fois.

rotate(L, M, N) :- 
   (  N > 0,
      rotate2(L, M, N)
   ;  L = M
   ).

rotate2(L, [H|T], Ct) :- 
   append(T, [H], L), 
   Ct2 is Ct - 1, 
   rotate2(L, T, Ct2).

Actuellement, mon code retourne L égal à l'original M , peu importe ce que N est défini. On dirait que quand je suis récursive, la queue n'est pas correctement déplacée à la tête.


Answer #1

Vous pouvez utiliser l' append à des listes séparées et la length pour créer des listes:

% rotate(+List, +N, -RotatedList)
% True when RotatedList is List rotated N positions to the right
rotate(List, N, RotatedList) :-
    length(Back, N),           % create a list of variables of length N
    append(Front, Back, List), % split L
    append(Back, Front, RotatedList).

Note: ceci ne fonctionne que pour N <= longueur (L). Vous pouvez utiliser l'arithmétique pour résoudre ce problème.

Modifier pour plus de clarté Ce prédicat est défini pour les arguments List et N qui ne sont pas des variables lorsque le prédicat est appelé. J'ai réordonné par inadvertance les arguments de votre question initiale, car dans Prolog, la convention est que les arguments strictement entrée doivent venir avant les arguments de sortie. Donc, Liste et N et arguments d'entrée, RotatedList est un argument de sortie. Donc, ce sont des requêtes correctes:

?- rotate([a,b,c], 2, R).
?- rotate([a,b,c], 1, [c,a,b]).

mais ça:

?- rotate(L, 2, [a,b,c]).

ira dans la récurrence infinie après avoir trouvé une réponse.

Lors de la lecture de la documentation SWI-Prolog, recherchez les arguments de prédicat marqués d'un "?", Comme en length . Ils peuvent être utilisés comme indiqué dans cet exemple.