Home > Mobile >  Separate list by first occurence of variable in SWI-Prolog without instantiating the variable itself
Separate list by first occurence of variable in SWI-Prolog without instantiating the variable itself

Time:02-03

I have following source-code:

split_list(List, L, [R1|RN], Condition) :-
   find_first(List, R1, Condition),
   append(L, [R1|RN], List), 
   forall(member(X, L),
   not(call(Condition, X))).

find_first([H|_], H, Condition) :- call(Condition, H), !.
find_first([_|T], X, Condition) :- find_first(T, X, Condition).

This Prolog program splits a list List into two lists L and [R1|RN]. R1 is the first element of List which satisfies the predicate Condition. L contains all elements in List before R1. L does not contain any element satisfying Condition. RN contains all elements which follow R1 in List.

My aim now is to write some predicate, which separates some list [a,b,c,D,d,f,e,f,d] into two lists [a, b, c] and [D, d, f, e, f, d] without instantiating the variable D.

I just tried the call:

split_list([a,b,c,_,d,f,e,f,d], L, R, var).

but this produces much solutions by instantiating _ by a or b or c and so on. How can I solve it?

CodePudding user response:

I found some solution:

split_list(List, L, [R1|RN], Condition) :- member(R1, List), append(L, [R1|RN], List), call(Condition, R1).

CodePudding user response:

From the looks of it, this is a more useful find_first (with argument order changed to be more sensible):

% P means previous, R means remainder
find_first_succ(Cond, L, P, [H|T]) :-
    find_first_succ_(L, Cond, P, [H|T]).

find_first_succ_([H|T], Cond, [], [H|T]) :-
    call(Cond, H), !.
find_first_succ_([H|T], Cond, [H|P], R) :-
    find_first_succ_(T, Cond, P, R).

Result in swi-prolog:

?- find_first_succ(var, [a,b,c,_,d,f,e,f,d], P, R).
P = [a, b, c],
R = [_, d, f, e, f, d].

So, you don't need that problematic append.

  • Related