2017-01-04 64 views
1

好了,所以我有一些代碼,連接兩個列表。完全沒有問題,只是我努力去理解它是如何工作的。Prolog的串聯混亂

  • 我知道這對你們中的大多數人來說是微不足道的。

下面是代碼:

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

假設我們有2所列出:[3,4,2]和[9,9],我想來連接。

Step 1: 
H = 3 
L2 = [9, 9] 
L1 = 4,2 

Step 2: 
L2 = [9, 9] 
H = 4 
L1 = [2] 

Step 3: 
L2 = [9, 9] 
H = 2 
L1 = [] 

Step 4: 
L = [9,9] .... Now why does it not just fail? In my brain [9,9] is not equal to [3, 4, 2] 

Step 5: 

L2 = L3 = [9, 9] 
H = 2 
L1 = [] 


Step 6: 

L2 = [9, 9] 
H = 4 
L1 = [2] 
L3 = [2, 9, 9] 

Step 7: 

L2 = [9, 9] 
H = 3 
L1 = [4, 2] 
L3 = [4, 2, 9, 9] And done 

我發現了什麼讓我感到困惑?我必須看到這個錯誤,L2在整個遞歸調用中保持靜態,所以我不明白我們將第一個輸入移動到第三個輸入所取得的成果是什麼?

+0

步驟4不會失敗,因爲你正在用'conc([],[9,9],L)'統一'conc([],L,L)'',它只產生'L = [9,9 ]'。你爲什麼認爲這會失敗? '[3,4,2]在這個統一步驟中甚至不出現在任何地方。 – lurker

回答

2

在你的第4步,你是不是統一[3, 4, 2][9, 9];你正在統一[9, 9]一個自由變量。

你是對的,步驟3中的綁定是L2 = [9, 9]H = 2L1 = []。請注意0​​未被綁定!遞歸調用conc(L1, L2, L3),所以conc([], [9, 9], L3)。這一目標將與conc第一條相結合,引入新的綁定L3 = [9, 9]。這是由於該條款conc([], L, L),這迫使L3與任何L結合了,在這個電話只是[9, 9]統一。

然後用你的第5步評估收益爲你描述。

你的Prolog可能有一個可以幫助你理解的示蹤劑。在SWI-Prolog的跟蹤一個conc目標看起來像這樣(的_Gxxxx是自由變量):

?- trace, conc([a,b], [c,d], Xs). 
    Call: (7) conc([a, b], [c, d], _G2467) ? creep 
    Call: (8) conc([b], [c, d], _G2590) ? creep 
    Call: (9) conc([], [c, d], _G2593) ? creep 
    Exit: (9) conc([], [c, d], [c, d]) ? creep 
    Exit: (8) conc([b], [c, d], [b, c, d]) ? creep 
    Exit: (7) conc([a, b], [c, d], [a, b, c, d]) ? creep 
Xs = [a, b, c, d]. 

注意第三個Call進入一個變量作爲第三個參數和Exit s的變量綁定到一個列表。