[a,b,c] = .(a,.(b,.(c,[])))
lista vacia = []
lista en general: [H|T] (H = head, T = Tail)
[H|T] = [a,b,c] => H = a, T = [b,c] = [a|[b,c]] = [a,b|[c]] = [a,b,c|[]] [a,b,c,d,e] = [a,b,c|T] => T = [d,e]
Podemos definir lista como:
es_lista([]). es_lista([H|T]) :- es_lista(T). anade(El,Lista,[El|Lista]). elemento(X,[X|T]). elemento(X,[_|T]):- elemento(X,T). (usos) quita(El,[El|L],L). quita(El,[H|T],[H|R]):- quita(El,T,R).También para anadir un elemento en diferentes lugares:
quita(a,L,[b,c,d]) elemento(El,L) :- quita(El,L,_). anade(El,Lista1,Lista2) :- quita(El,Lista2,Lista1). prefijo([],L). prefijo([X|T],[X|R]):- prefijo(T,R). (usos) sufijo(L,L). sufijo(L,[H|T]):- sufijo(L,T). (usos) sublista(L1,L2):- prefijo(L3,L2), sufijo(L1,L3). sublista(L1,L2):- prefijo(L1,L3), sufijo(L3,L2). sublista(L1,L2):- prefijo(L1,L2). sublista(L1,[H|T]):- sublista(L1,L2). append([],L,L). append([H|L1],L2,[H|L3]):- append(L1,L2,L3). (usos) adyacentes(X,Y,L) :- append(_,[X,Y|_],L). prefijo(L1,L2):- append(L1,X,L2). sufijo(L1,L2):- append(X,L1,L2). sublista(L1,L2) :- append(X,Y,L2), append(L1,Z,Y). sublista(L1,L2):- append(X,Y,L2), append(Z,L1,X). member(X,L) :- append(Y,[X|Z],L). member(X,L) :- sublista([X,L). last(X,[X]). last(X,[_|T]):- last(X,T). last(X,L) :- append(Y,[X],L). long([],0). long([H|T],s(N)):- long(T,N).
Si queremos guardar las acciones que hace el mono podemos añadir un argumento extra:
come(edo(_,_,_,si),[]). come(Edo1,[Acc|Resto]) :- mov(Edo1, Acc, Edo2), come(Edo2,Resto).
Permutación:
permuta([],[]). permuta([El|L],Perm):- permuta(L,LP), anade(El,LP,Perm).
permuta([],[]). permuta(L,[El|R]):- quita(El,L,L2), permuta(L2,R).
Si preguntamos: permuta(L,[a,b,c]).
(A) nos da las primeras 6 soluciones y despues se cicla
(B) nos da solo la primera y despues se cicla
Voltea una lista:
voltea([],[]). voltea([H|T],Vol):- voltea(T,TVol), append(TVol,[H],Vol).Sin embargo, ocupa mucha memoria. Un ``truco'' común en Prolog (y Lisp) es inlcuir un argumento extra para ir guardando los resultados parciales (un acumulador) y volverla tail recursive.
voltea(L,LV) :- voltea(L,[],LV). voltea([],L,L). voltea([H|T],Acum,Vol):- voltea(T,[H|Acum],LVol).Palindrome lo podemos definir asi:
palin([]). palin([_]). palin([H|T]):- append(EnMedio,[H],T), palin(EnMedio).Alternativamente:
palin(L) :- voltea(L,L).
Aplana:
aplana([],[]). aplana([H|T],Res) :- aplana(H,HP), aplana(T,TP), append(HP,TP,Res). aplana(X,[X]).Podemos hacer una version con una lista intermedia para evitar el ``append''
aplana(List,ListPl) :- aplana(List,[],ListPl). aplana([],L,L). aplana([H|T],L1,L3) :- aplana(H,L1,L2), aplana(T,L2,L3). aplana(X,S,[X|S]).