%LP 2011-2012  DCC-FCUP

lista([]).
lista([X|Y]):- lista(Y).

member(X,[X|T]).
member(X,[Y|T]):- member(X,T).


lenght([],0).
lenght([X|Y],N):- lenght(Y,N1), N is N1+1.

lenght0(L,N):- lenght1(L,0,N).

lenght1([],A,A).
lenght1([X|Y],A,N):- A1 is A+1, lenght1(Y,A1,N).

prod_ex([],[],0).
prod_ex([X|Xs],[Y|Ys],S):- prod_ex(Xs,Ys,S1), S is S1 + X*Y.

prod_ex1(X,Y,N):- prodaux(X,Y,0,N).

prodaux([],[],A,A).
prodaux([X|Xs],[Y|Ys],S1,S):- S0 is S1 + X*Y, prod_ex(Xs,Ys,S0,S). 


max([X|Y],M):- max1(Y,X,M).

max1([],X,X).
max1([X|Y],M,M1):- X > M, max1(Y,X,M1).
max1([X|Y],M,M1):- X =< M, max1(Y,M,M1).


sumlist(X,S):- sumaux(X,1,S).

sumaux([],A,A).
sumaux([X|Y],A,N):- A1 is A+X, aux(Y,A1,N).

append([],L,L).
append([X|Y],L,[X|L1]):- append(Y,L,L1).

n_rev([],[]).
n_rev([X|Y],R):- n_rev(Y,Y1), append(Y1,[X],R).

rev(L,L1):- rev0(L,[],L1).

rev0([],A,A).
rev0([X|Y],A,R) :- rev0(Y,[X|A],R).


delete([],X,[]).
delete([X|Xs],X,Y):- delete(Xs,X,Y).
delete([X|Xs],Z,[X|Y]):- X\=Z,delete(Xs,Z,Y).


square([],[]).
square([X|Y],[X1|Y1]):- X1 is X*X, square(Y,Y1).

map([],[]).
map([X|Y],[X1|Y1]):- transform(X,X1), map(Y,Y1).

transform(X,X1):- X1 is X*X.

% só funciona se o primeiro argumento estiver instanciado
sem_dup([],[]).
sem_dup([X|T],L):- member(X,T), sem_dup(T,L).
sem_dup([X|T],[X|L]):- sem_dup(T,L).


% usando diferenças
app(A-B,B-C,A-C).


