2015-04-04 96 views
2

的示例是這樣的prolog-打破列表

?- runs([3,4,5,4,2,7,5,6,6,8,3], RunList). 
RunList = [[3, 4, 5], [4], [2, 7], [5, 6, 6, 8], [3]] 

列表需要在到了一些非遞減的連續編號的順序被打破。我的代碼是:

next([],0). 
next([H|_],R):- 
    R is H. 

runs1([],[]). 
runs1([H|T],R):- 
    runs1(T,R1), 
    next(T,X), 
    H=<X, 
    R = [H|R1]. 
runs1([H|T],R):- 
    runs1(T,R1), 
    next(T,X), 
    H>X, 
    R = [[H]|R1]. 

我試過很多方法,但還是不知道怎麼寫呢?

希望有人能夠幫助我。

在此先感謝。

+2

可能重複(http://stackoverflow.com/questions/29405498/extracting-sequences-lists-prolog) – lurker 2015-04-04 12:09:54

回答

-1
runs([], []):-!. 
runs([H|T], S):- 
    runs(T, TS), 
    ins(H, TS, S). 

ins(E, [], [[E]]):-!. 
ins(E, [[H|T]|TL], [[E, H|T]|TL]):- 
    H >= E, !. 
ins(E, TL, [[E]|TL]). 
+2

這將是很好的,爲什麼他們沒有解釋到OP和你的解決方案。此外,儘管這個方向是作用於一個方向的(作爲*函數*),它並沒有定義*關係*,所以'runs(L,[[3,4,5],[4],[2,7]), [5,6,6,8],[3]])。'失敗而不是屈服',L = [3,4,5,4,2,7,5,6,6,8,3]'。 – lurker 2015-04-04 13:47:29

+0

我該如何解決這個問題? - 你有沒有這種技術的例子 - 對我來說太有意思了 – rrrfer 2015-04-04 14:22:32

+1

查看我在幾個例子中對原始問題的評論中提供的鏈接。 – lurker 2015-04-04 14:23:22

1

對於邏輯純單調實現看看 my answer相關問題 「Extracting sequences (Lists) Prolog」。

我介紹了基於if_/3的meta-predicate splitlistIfAdj/3,這是由@false在this answer中提出的。 splitlistIfAdj/3確保邏輯健全性,同時儘可能保持確定性。

傳遞給splitlistIfAdj/3的謂詞必須服從與(=)/3memberd_truth/3相同的慣例。 對於你的情況,我們需要的(#>)/3一個定義:

#>(X,Y,Truth) :- X #> Y #<==> B, =(B,1,Truth). 

讓我們用splitlistIfAdj/3(#>)/3在你給的例子:

?- splitlistIfAdj(#>,[3,4,5,4,2,7,5,6,6,8,3],Pss). 
Pss = [[3,4,5],[4],[2,7],[5,6,6,8],[3]].   % succeeds deterministically 

現在,讓我們問一個更一般的查詢:

?- splitlistIfAdj(#>,[A,B],Pss). 
Pss = [[A],[B]], A#>=_X,  B+1#=_X ; 
Pss = [[A,B]], A#>=_Y#<==>_Z, B+1#=_Y, _Z in 0..1, dif(_Z,1). 

最後,讓我們在@rrrfer的回答中運行@lurker建議的查詢:

[提取序列(列表)序言]的
?- splitlistIfAdj(#>, Ls, [[3,4,5],[4],[2,7],[5,6,6,8],[3]]). 
Ls = [3,4,5,4,2,7,5,6,6,8,3] ; 
false.