% define a predicate app(Xs,Ys,Zs) <=> ZS contains all elements
% if Xs and Ys in the same order.
% e.g., app([1,2],[3,4],[1,2,3,4]) is true
%app([],Ys,Zs) :- Ys=Zs.
app([],Ys,Ys).
app([X|Xs],Ys,[X|Zs]) :- app(Xs,Ys,Zs).

% if the first list is given: search space has one element, i.e.,
% the execution is deterministic!

% ?- app([a,b],[c],[a,b,c]).
%  |- (2nd. clause)
% ?- app([b],[c],[b,c]).
%  |- (2nd clause)
% ?- app([],[c],[c]).
%  |- (1nd clause: fact!)
% ?- .

% add_list(Xs,X,Ys) <=> Ys is Xs plus X as last element
add_list(Xs,X,Ys) :- app(Xs,[X],Ys).

% last(Xs,X) <=> X is the last element of Xs
%last(Xs,X) :- add_list(_,X,Xs).
last(Xs,X) :- app(_,[X],Xs).

% elem(X,Xs) <=> X is a member of the list Xs
elem(X,Xs) :- app(_,[X|_],Xs).

% delete(Xs,X,Ys) <=> X is a member of Xs and Ys is Xs without this X
delete(Xs,X,Ys) :- app(As,[X|Bs],Xs), app(As,Bs,Ys).

% sublist(Xs,Ys) <=> Xs is a part of the list Ys
sublist(Xs,Ys) :- app(_,Bs,Ys), app(Xs,_,Bs).
