爲了讓事情儘可能簡單,我們可以添加一個測試,如果被檢查的當前元素是一個列表。如果確實是一個清單,那麼它的元素也應該顛倒過來。因此,在代碼:
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)
).
而且,不是它真正的問題,只是爲了儘量避免混淆,請注意我如何分別採用A
和R
爲Accumulator
和Result
。在你的代碼中,它們當前是交換的,這對我個人而言可能有點混亂,特別是當謂詞變得更長和更復雜時。
無論如何,讓我們來看看你所提供的查詢:
?- 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].
和一些通用查詢:
?- 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]]]
...
不過請注意,使用此斷言,沒有終止找到第一個答案後出現查詢:
?- my_reverse(X,[X]).
X = [X] ;
...
但是,由於這不是要求/需求OP的問題,我認爲它沒問題。
編輯:
請仔細閱讀@mat's answer作爲後續行動這個問題。
嘿,非常感謝。是的,這個答案是確定的 – CrimsonKing