Peter Ivanics
Peter Ivanics

Reputation: 368

How can I split a list in Prolog to several lists containing 3 items?

My problem is, that I want to make a rule for splitting a list to several lists, containing only 3 items from the original, in order.

For example:

/*original list:*/ 
Fruits=[apple,banana,orange,pear, lemon, melon]

?-Split(Fruits).

/*results:*/ 
[apple,banana,orange];
[banana,orange,pear];
[orange,pear,lemon];
[pear,lemon,melon].

Is there any way to do this? :S

Upvotes: 3

Views: 2773

Answers (2)

user502187
user502187

Reputation:

Prolog is excellent for this task. Just observe that append/3 can be used in various directions:

 % append(+List,+List,-List)
 % append(-List,-List,+List)
 append([], X, X).
 append([X|Y], Z, [X|T]) :-
     append(Y, Z, T).

Now simply define split/2 as follows. It will find _1 and _2 such that L = _1 ++ S ++ _2, where ++ is the list concatenation:

 % split(+List,-Sublist)
 split(L, S) :-
     append(_, H, L),
     append(S, _, H).

And here you go with your problem:

 ?- Fruits=[apple,banana,orange,pear,lemon,melon], Split=[_,_,_], split(Fruits,Split).
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [apple,banana,orange] ;
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [banana,orange,pear] ;
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [orange,pear,lemon] ;
 Fruits = [apple,banana,orange,pear,lemon,melon],
 Split = [pear,lemon,melon] ;
 No

Bye

Best Regards

Upvotes: 3

m09
m09

Reputation: 7493

You can refer to this excellent answer @false provided some times ago.

Quickly adapting his solution, you could write:

seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).

split_3(List, Result) :-
    length(Result, 3),
    phrase((seq(_),seq(Result),seq(_)),List).

Note that you could achieve the same thing with append/2 (or append/3 with one more call):

split_3(List, Result) :-
    length(Result, 3),
    append([_, Result, _], List).

But append/2 is not really intended for such manipulations. DCG use difference lists, which are more efficient.

Upvotes: 3

Related Questions