:- module(_,_,[]).
% :- use_package(sr/bfall).

% Lists 

% Other list examples: 

% list_member(X,L): X is a member of list L
list_member(X,[X|L]) :-
    list(L).
list_member(X,[_|T]) :- 
    list_member(X,T).

% Try:
% ?- list_member(b, [a,b,c]).
% ?- list_member(X, [a,b,c]).
% ?- list_member(a, L). 
% Try also uncommenting above :- use_package(sr/bfall).

% list_length(L,N): N is the length of list L
list_length([],0).
list_length([_|T],s(N)) :-
    list_length(T,N).

% Try:
% ?- list_length([a, b, c], N).
% ?- list_length(L, s(s(s(0)))).
% ?- list_length(L, 3).
% ?- list_length(L, N).

% sumlist(L,N): N is the sum of all elements of L
sumlist([],0).
sumlist([H|T],S) :-
    sumlist(T,ST),
    add(ST,H,S).

% Try:
% ?- sumlist([s(0),s(s(s(0))),s(s(0))],N).
% ?- sumlist(L,s(s(s(0)))).
% ?- sumlist(L,S).
% Try also uncommenting above :- use_package(sr/bfall).

% natlist(L): L is a list of naturals
natlist([]).
natlist([X|Y]) :- 
    nat(X),
    natlist(Y).

% Or, using functional notation:
% :- use_package(fsyntax).
% natlst := [] | [~nat|~natlst].

% Exercises: 
% Define prefix(X,Y): `X` is a prefix of list `Y`.
% E.g.:  prefix([a,b], [a,b,c,d]).
% Define suffix/2, sublist/2, ... 

% Auxiliary preds:

list([]).
list([_|T]) :-
     list(T).

add(0,X,X) :- 
     nat(X).
add(s(X),Y,s(Z)) :- 
     add(X,Y,Z).

nat(0).
nat(s(X)) :- 
     nat(X).
