2

The example is like this

?- 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]]

The list need to be broken in to a number of non-decreasing sequence of consecutive numbers. My code is:

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

I tried lots of methods, but still do not know how to write it...

Hope someone could help me.

Thanks in advance.

false
  • 10,264
  • 13
  • 101
  • 209
Rui Wang
  • 249
  • 2
  • 4
  • 2
    possible duplicate of [Extracting sequences (Lists) Prolog](http://stackoverflow.com/questions/29405498/extracting-sequences-lists-prolog) – lurker Apr 04 '15 at 12:09

2 Answers2

1

For a logically pure and monotone implementation look at my answer to related question "Extracting sequences (Lists) Prolog".

I present the meta-predicate splitlistIfAdj/3 which is based on if_/3 as proposed by @false in this answer. splitlistIfAdj/3 ensures logical soundness while remaining deterministic when possible.

The predicate passed to splitlistIfAdj/3 has to obey the same convention as (=)/3 and memberd_truth/3. For your case we need a definition of (#>)/3:

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

Let's use splitlistIfAdj/3 and (#>)/3 in the example you gave:

?- 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

Now let's ask a more general query:

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

Last, let's run the query that @lurker suggested in his comment to @rrrfer's answer:

?- 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.
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166
-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]).
rrrfer
  • 34
  • 1
  • 3
  • 2
    It would be good to explain to the OP why theirs failed and your solution works. Also, although this works one direction (as a *function*), it doesn't define a *relation*, so `runs(L, [[3, 4, 5], [4], [2, 7], [5, 6, 6, 8], [3]]).` fails rather than yielding, `L = [3,4,5,4,2,7,5,6,6,8,3]`. – lurker Apr 04 '15 at 13:47
  • How i can resolve this problem? - do you have any example of this technics - it's so interesting for me – rrrfer Apr 04 '15 at 14:22
  • 1
    See the link I provided in the comment to the original question for a couple of examples. – lurker Apr 04 '15 at 14:23