2015-04-04 47 views
2

這是第看起來像Prolog如何評估此條款?

splits(L, ([],L)). 
splits([X|L],([X|S],E)):- splits(L, (S,E)). 

分裂應該在每一個可能的點分成兩個部分列表L,而應返回做好一切準備。 可能的查詢是
split([1,2,3],Res)

結果是

Res = ([], [1,2,3]); 
Res = ([1], [2,3]); 
Res = ([1,2], [3]); 
Res = ([1,2,3], []); 
No 

我的問題是,我不明白是如何拆分工作。我爲上述案例寫下了它,但我仍然不知道。如果有人能解釋我,我將不勝感激。

+0

什麼是你不明白? – 2015-04-04 21:10:59

+0

@PaulButcher:我不明白的是,它一般如何工作。我一步一步寫下來,但我不知道* Res *是如何產生的。 – tumbler 2015-04-04 21:24:30

+0

@PaulButcher:對於S和E的例子相當混亂。 – tumbler 2015-04-04 21:26:47

回答

2

爲了得到更好的理解,首先嚐試使用一些描述性的(或至少常規)變量名:

splits(L, ([], L)). 
splits([Head|Tail], ([Head|Tail2], Remainder)):- 
    splits(Tail, (Tail2, Remainder)). 

所以,你的Res,它的零元素之前分割的第一個版本,應該是顯而易見:它是一個空列表和整個列表,它與第一個子句匹配。

對於後續結果,Prolog會回溯,直到它能夠找到之前沒有采用過的替代路線。鑑於[1,2,3]是一個帶有頭部和尾部的列表,它與另一個子句中的[Head|Tail]相匹配。 Head1Tail[2,3]

所以我們現在再次圍繞這個序列,但是這一次,以[2,3]作爲第一個參數。在第一個實例中綁定(Tail2, Reminder)([], [2,3]),這意味着([Head|Tail2], Remainder)(即在您的查詢中爲Res)因此綁定到([1 | []],[2,3])[1|[]]只是[1]。所以你會得到你的第二個迴應。

然後以相同的方式推導後續結果,每次發生回溯時選擇一個不同的子句。