user3928256
user3928256

Reputation: 993

How to split list in Prolog?

I want to write a predicate split(List, Pivot, Result) holds when Result is a list of sublists that List divided by Pivot. For example split(['_', '_', '#', '_', '#', '_'], '#', [['_','_'], ['_'], ['_']]) is true.

My code is like this and it doesn't work:

split(List, Pivot, Result) :-
split(List, Pivot, _, _, Result).

split(List, Pivot, Left, Right, X|Xs) :-
    append(Left, [Pivot|Right], List),
    !,
    member(Pivot, Right)
    ->  X = [Left],
        split(Right, Pivot, _, _, Xs)
    ;   X = [[Left]|[Right]].

I don't think my approach is clever either. Can someone give me some advice? Thank you.

Upvotes: 2

Views: 4297

Answers (3)

christian quart
christian quart

Reputation: 1

Another way to do it:

list('#', ['_', '_', '#', '_', '#', '_']).
main:- list(Pivot, L), 
       split(Pivot, L, [['_','_'],['_'],['_']]),!.

split(_,[],[]).
split(Pivot, L, [R|R1]):-  append(R, [Pivot|Rest], L), 
                           split(Pivot,Rest,R1),!.
split(_, L, [L]).


line 1: example list to divide line 2: we read the list, call the split/3 predicate line 3: base case list L empty, we return empty list. line 4: recursive case the list L is not empty, append/3, R contains the sublist of elements before the pivot, Rest contains the rest of the elements of L. line 5: is the case in which L is a list without pivots

Upvotes: 0

repeat
repeat

Reputation: 18726

We can preserve and get the job done in no time, simply by using the right tools!

Let's use the splitlistIf/3 and the reified equality predicate (=)/3 in a query:

?- Xs = ['_','_',#,'_',#,'_'], splitlistIf(=(#),Xs,Ys).
Xs = [ '_','_' ,#,'_',#,'_' ]
Ys = [['_','_'], ['_'],['_']].      % succeeds deterministically

Upvotes: 3

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726489

Here is one way of doing it:

split(L,P,R):-split(L,P,[],R).
split([],_,[],[]).
split([],_,S,[S]) :- S \= [].
split([P|T],P,[],R) :- split(T,P,[],R).
split([P|T],P,L,[L|R]) :- L \= [], split(T,P,[],R).
split([H|T],P,S,R) :- H \= P, append(S, [H], S2), split(T,P,S2,R).

Demo.

split/4 predicate adds a parameter at position 3 which means "list constructed so far". split/3 is a simple redirection with the "list so far" set to [].

Clauses on lines 2 and 4 handle situations when two Pivots are in a row, and when the pivot is detected at the end of the sequence. These clauses prevent insertion of empty lists.

Upvotes: 1

Related Questions