Home > OS >  Prolog: Create a List from a selection of a given List
Prolog: Create a List from a selection of a given List

Time:01-27

I want to write a predicate in Prolog, which creates a all possible segments of a given Size of a given List and returns the un-selected elements as a List.

My Code so far:

select_seg(List, Segment, Rest, Size ):-
    select_seg(List, Segment, Rest, Size, Size).

select_seg(_,_,_,_, 0):- !.
    select_seg(List, [Head_Segs|Tail_Segs],[Head_Rest|Tail_Rest], Size,Acc ):-
        select(Head_Segs, List, Head_Rest),
        Acc >= 0, 
        New_Acc is Acc  - 1,
        select_seg(Head_Rest, Tail_Segs, Tail_Rest, Size, New_Acc).

When I call this predicate with:

select_seg([1,2,3,4,5,6,7,8,9], Seg, R ,3 ).

It returns:

Seg = [1, 2, 3|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [[2, 3, 4, 5, 6, 7, 8, 9], [3, 4, 5, 6, 7, 8, 9], [3, 4, 6, 7, 8, 9]|_] ;

This is desired output, except that the list of remaining elements contain three lists for each element in the Segment the List of remaining elements, but should only contain the last one as following:

Seg = [1, 2, 3|_],
R = [4, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 4|_],
R = [3, 5, 6, 7, 8, 9]|_] ;
Seg = [1, 2, 5|_],
R = [3, 4, 6, 7, 8, 9]|_] ;

I tried everything, but I am not able to come up with the right solution.

CodePudding user response:

It's combining select with a variant of select:

select_len_seg(Len, L, Seg, Rem) :-
    length(Seg, Len),
    select_len_seg_(Seg, L, L, Rem).

select_len_seg_([], _, R, R).
select_len_seg_([H|T], F, R, Rem) :-
    % Preventing "duplicates" such as [3,2,1]
    select_forward(H, F, F0),
    select(H, R, R0),
    select_len_seg_(T, F0, R0, Rem).

select_forward(E, [H|T], F) :-
    select_forward_(T, H, E, F).

select_forward_(T, H, H, T).
select_forward_([H|T], _, E, F) :-
    select_forward_(T, H, E, F).

Results in swi-prolog:

?- select_len_seg(3, [1,2,3,4,5,6,7,8,9], S, R).
S = [1, 2, 3],
R = [4, 5, 6, 7, 8, 9] ;
S = [1, 2, 4],
R = [3, 5, 6, 7, 8, 9] ;
...
S = [6, 7, 9],
R = [1, 2, 3, 4, 5, 8] ;
S = [6, 8, 9],
R = [1, 2, 3, 4, 5, 7] ;
S = [7, 8, 9],
R = [1, 2, 3, 4, 5, 6] ;
false.
  • Related