Pour que les choses restent aussi simples que possible, nous pourrions ajouter un test si l'élément en cours de vérification est une liste ou non. S'il s'agit bien d'une liste, alors ses éléments devraient également être inversés. Ainsi, dans le code:
my_reverse(L,R) :- rev(L,[],R).
rev([],A,A).
rev([H|T],A,R) :-
(is_list(H) -> % If H is a list
rev(H,[],X), % then reverse H as well
rev(T,[X|A],R)
;
rev(T,[H|A],R)
).
En outre, pas que cela importe vraiment, juste pour essayer d'éviter la confusion, notez comment je A
et R
pour respectivement Accumulator
et Result
. Dans votre code, ils sont actuellement échangés, ce qui - pour moi personnellement - peut être un peu déroutant, surtout quand les prédicats deviennent plus longs et plus complexes.
Quoi qu'il en soit, regardons les requêtes que vous avez fournies:
?- my_reverse([[0,1],2,3],R).
R = [3, 2, [1, 0]].
?- my_reverse([1,2,[3,4,5,[6,7],8],[9,10],11,12],R).
R = [12, 11, [10, 9], [8, [7, 6], 5, 4, 3], 2, 1].
Et quelques questions d'ordre général:
?- my_reverse(L,R).
L = R, R = [] ;
L = R, R = [_G2437] ;
L = [_G2437, _G2443],
R = [_G2443, _G2437] ;
L = [_G2437, _G2443, _G2449],
R = [_G2449, _G2443, _G2437] ;
L = [_G2437, _G2443, _G2449, _G2455],
R = [_G2455, _G2449, _G2443, _G2437]
...
?- my_reverse([[X,Y]|T],R), member(a,T), length(X,2).
X = [_G2588, _G2591],
T = [a],
R = [a, [Y, [_G2588, _G2591]]]
;
X = [_G2594, _G2597],
T = [a, _G2588],
R = [_G2588, a, [Y, [_G2594, _G2597]]]
;
X = [_G2594, _G2597],
T = [_G2582, a],
R = [a, _G2582, [Y, [_G2594, _G2597]]]
...
Notez cependant que l'utilisation de ce prédicat, aucune terminaison se produit après avoir trouvé la première réponse à la requête:
?- my_reverse(X,[X]).
X = [X] ;
...
Mais puisque ce n'était pas une exigence/demande La question de OP, j'ai supposé que c'était correct.
EDIT:
S'il vous plaît lire @mat's answer comme suite à ce problème.
Salut, merci beaucoup. Oui, cette réponse est OK – CrimsonKing