2015-04-04 98 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.