Está en la página 1de 5

Programaci on Funcional y L ogica, 2012-1 Nota de clase 3

Favio E. Miranda Perea Lourdes Gonz alez Huesca 22 de septiembre de 2011

1.
1.1.

Mas programas con listas


Usando concat de manera no estandar

Los programas para pertenencia a una lista, prejos, sujos y sublistas pueden denirse sin recurrir a una denici on recursiva, usando la contatenaci on de manera no estandar: Pertenencia a una lista: elem(X,L):-concat(_,[X|_],L). Prejos: prefijo(P,L) :- concat(P,_,L). Sujos sufijo(S,L) :- concat(_,S,L). Sublistas: sublista(S,L) :- concat(AS,_,L), concat(_,S,AS)

1.2.

Permutaciones de una lista

% perm(L,M)/2 <=> M es una permutaci on de L perm([],[]). perm(Ps,[L|Ls]):-elim(L,Ps,Rs),perm(Rs,Ls).

2.
2.1.

Ejemplos usando acumuladores


Suma de n umeros naturales

suma(0,X,X). suma(s(X),Y,Z) :- suma(X,s(Y),Z). 1

2.2.

Suma de elementos de una lista de n umeros

La idea es ir acumulando la suma en cada iteraci on. suml(L,S) :- sumaacc(L,0,S) sumaacc([],Sacc,Sacc) sumaacc([X|Xs], Sacc,S) :- Sn is X+Sacc, sumaacc(Xs,Sn,S)

2.3.

Suma acumulada de una lista

Dada una lista [a1 , . . . , an ] devolver la lista [s1 , . . . , sn ] cuyos elemento i es las suma de valores de la lista anterior hasta dicho elemento, es decir, tal que si = a1 + . . . + ai . Por ejemplo sumaval([1,2,3,4],[1,3,6,10]. sumval(L,S) :- svacc(L,0,S) svacc([],S,[]). svacc([X|Xs],Sacc,[Sp|SXs]) :- Sp is X+Sacc, svacc(Xs,Sp,SXs).

2.4.

Producto escalar de dos listas de n umeros

esc(Xs,Ys,P) :- escacc(Xs,Ys,0,P). escacc([],[],P,P). escacc([X|Xs],[Y|Ys],Pacc,P) :- Pn is Pacc + X*Y, escacc(Xs,Ys,Pn,P).

3.

Algoritmos de ordenamiento en listas


A continuaci on presentamos algunos algoritmos cl asicos de ordenamiento en listas.

3.1.

Ordenamiento Ingenuo

El ordenamiento lento o ingenuo es un algoritmo sumamente ineciente cuya idea es generar todas las permutaciones de una lista y vericar si est an ordenadas. ordlen(L,O):-perm(L,O),esord(O). esord([]). esord([_]). esord([X,Y|T]):-X=<Y,esord([Y|T]).

3.2.

Ordenamiento por inserci on

El ordenamiento por inserci on se sirve de un acumulador.

ordins(L,LO):-oiacc(L,[],LO). oiacc([],Acc,Acc). oiacc([H|T],Acc,LO):-insert(H,Acc,NAcc),oiacc(T,NAcc,LO). insert(X,[Y|T],[Y|NT]):-X>Y,insert(X,T,NT). insert(X,[Y|T],[X,Y|T]):-X=<Y. insert(X,[],[X]).

3.3.

Ordenamiento burbuja

Usando un acumulador. ordbur(List,Sorted):-obacc(List,[],Sorted). obacc([],Acc,Acc). obacc([H|T],Acc,Sorted):-burb(H,T,NT,Max),obacc(NT,[Max|Acc],Sorted). burb(X,[],[],X). burb(X,[Y|T],[Y|NT],Max):-X>Y,burb(X,T,NT,Max). burb(X,[Y|T],[X|NT],Max):-X=<Y,burb(Y,T,NT,Max).

3.4.

Ordenamiento por mezcla

El ordenamiento por mezcla (mergesort) es u til con listas grandes, si se implementa correctamente es muy eciente. ordmez([],[]). ordmez([X],[X]). ordmez([X,Y|L],LOrd):- divide([X,Y|L],L1,L2), ordmez(L1,LOrd1), ordmez(L2,LOrd2), mezcla(LOrd1,LOrd2,LOrd). mezcla([],L,L). mezcla(L,[],L):-L\=[]. mezcla([X|T1],[Y|T2],[X|T]):-X=<Y,mezcla(T1,[Y|T2],T). mezcla([X|T1],[Y|T2],[Y|T]):-X>Y,mezcla([X|T1],T2,T).

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

3.5.

Ordenamiento r apido

El ordenamiento r apido (Quick sort) es uno de los algoritmos m as r apidos. Sin embargo su eciencia depende de la elecci on del elemento pivote el cual se usa para dividir la lista en dos.

3.5.1.

Usando concatenaci on

ordqs([],[]). ordqs([H|T],Ord):- pivote(H,T,L1,L2),ordqs(L1,Ord1), ordqs(L2,Ord2), append(Ord1,[H|Ord2],Ord). pivote(_,[],[],[]). pivote(H,[X|T],[X|L],G):-X=<H,pivote(H,T,L,G). pivote(H,[X|T],L,[X|G]):-X>H,pivote(H,T,L,G). 3.5.2. Usando un acumulador

ordqs2(List,Ord):-ordqs2(List,[],Ord). ordqs2([],Acc,Acc). ordqs2([H|T],Acc,Ord):- pivote(H,T,L1,L2), ordqs2(L1,[H|AccN],Ord), ordqs2(L2,Acc,AccN).

4.

Representaci on de Aut omatas Finitos

Usando listas podemos implementar de manera simple a los aut omatas nitos, considerando al conjunto de cadenas como listas sobre el mismo alfabeto, siendo [] la cadena vac a. La funci on de transici on : Q Q de un AFD se representa como una relaci on ternaria denida mediante hechos, mientras que la funci on de transici on extendida se dene recursivamente. Una transici on (q, a) = p se representa mediante delta(q,a,p). Veamos un ejemplo particular: delta(1,d,2). delta(1,a,3). delta(2,a,3). delta(3,d,4). delta(4,a,3). inicial(1). final(3). final(4). deltaext(Q,[],Q). deltaext(Q,[A|W],P) :- delta(Q,A,Q1), deltaext(Q1,W,P). acepta(W) :- inicial(Q0), deltaext(Q0,W,Q), final(Q). Si se quiere generar todas las palabras aceptadas por el aut omata, se ocurre preguntarnos ?- acepta(X).

Sin embargo aunque la cadena [a] es aceptada el proceso de b usqueda nunca la devolvera, la enumeraci on de acuerdo al orden de las cl ausulas de delta es: [d], [d, a, d], [d, a, d, a], . . . , [a], [a, d], [a, d, a], . . . Si se cambia el orden de las cl ausulas en el programa el problema persiste pues en tal caso ninguna cadena que inicie con d ser a generada. Sin embargo podemos lograr que cualquier cadena se genere en un n umero nito de pasos modicando nuestra meta como sigue: ?- length(X,_), acepta(X). de esta manera se generan patrones de lista de cualquier longitud y despues se verica para que listas de dicha longitud la cadena es aceptada.

También podría gustarte