简体   繁体   中英

Prolog: Create a List from a selection of a given List

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM