2016-07-28 81 views
3

嘿,我正在嘗試創建一個謂詞,用於在PROLOG中嵌套列表上生成深度反轉。PROLOG中的深度反轉 - 列表

目前我得到這個謂詞

reverse(L,A) :- rev(L,[], A). 
rev([],A,A). 
rev([H|L],R,A) :- rev(L,[H|R],A). 

結果看起來是這樣的:

reverse([1,2,3],A). 
A = [3, 2, 1]. 

reverse([[0,1],2,3],A). 
A = [3, 2, [0, 1]]. 

的問題是,內部列表不會逆轉。它應該看起來像這樣:

reverse([[0,1],2,3],A). 
A = [3, 2, [1, 0]]. 

reverse([1,2,[3,4,5,[6,7],8],[9,10],11,12],A). 
A = [12,11,[10,9],[8,[7,6],5,4,3],2,1]. 

感謝您的任何幫助。

回答

1

爲了讓事情儘可能簡單,我們可以添加一個測試,如果被檢查的當前元素是一個列表。如果確實是一個清單,那麼它的元素也應該顛倒過來。因此,在代碼:

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) 
    ). 

而且,不是它真正的問題,只是爲了儘量避免混淆,請注意我如何分別採用ARAccumulatorResult。在你的代碼中,它們當前是交換的,這對我個人而言可能有點混亂,特別是當謂詞變得更長和更復雜時。

無論如何,讓我們來看看你所提供的查詢:

?- 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作爲後續行動這個問題。

+0

嘿,非常感謝。是的,這個答案是確定的 – CrimsonKing

3

你代表你的數據被稱爲defaulty,因爲你的推理超過它時,需要一個默認情況:

  • 它是一個列表? &右箭頭;東西擁有
  • 否則→還有其他的東西。

這樣的表示是麻煩的豐富來源。從另一個答案考慮例如my_reverse/2。它的主要問題是,它過早地錯誤   承諾到的情形之一的,雖然兩種箱子仍然是可能的:

 
?- my_reverse([X], Ls). 
Ls = [X]. 

但是這個答案只適用於其中X是這樣不是的列表!這個問題導致了謂詞的下列行爲怪異:

 
?- my_reverse([X], Ls), X = [1,2,3]. 
Ls = [[1, 2, 3]], 
X = [1, 2, 3]. 

這意味着,即使X是一個列表,其元素是逆轉!

您應始終瞄準更清潔的表示來區分可能出現的情況。

例如,你會說大概有以下方式來表示你的數據:

  • list(Ls)代表列表Ls
  • n(N)代表N

有了這樣的表示,我們可以象徵性地區分這些情況。我將此作爲更具說明性的解決方案的出發點。