Está en la página 1de 24

Programacin Lgica

Acumuladores
Captulo 8, The Art of Prolog

Instituto de Computacin - Facultad de Ingeniera

ACUMULADORES

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Iteracin y recursin
Prolog utiliza la recursin para especificar algoritmos iterativos y recursivos. Recursin:
Mantenimiento del stack frame por cada llamada recursiva inconclusa. N llamadas requieren un espacio de memoria de orden N.

Iteracin:
Utiliza espacio de memoria constante independiente del nmero de iteraciones.

Ventaja de iteracin sobre recursin: eficiencia.


Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Iteracin y recursin
Prolog maneja variables lgicas, no variables de almacenamiento. Para implementar algoritmos iterativos, que guardan resultados intermedios, se agregan nuevos argumentos a los procedimientos: acumuladores. Uno de los valores intermedios constituye el resultado de la iteracin. Este valor unifica con la variable resultado en la clusula unitaria del procedimiento.
Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Iteracin y recursin
Factorial iterativo:
factorial(N); I is 0; T is 1; while I < N do I is I + 1; T is T * I; end; return T.

Factorial en Prolog:
% factorial(+N, ?F) % F es el factorial % del entero N. factorial(N, F) :factorial(0,N,1,F). factorial(I,N,T,F) :I < N, I1 is I+1, T1 is T*I1, factorial(I1,N,T1,F). factorial(N,N,F,F).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Iteracin y recursin
Factorial en Prolog:
Fase de inicializacin. La reduccin de cada objetivo corresponde a una iteracin del loop while.
% factorial(+N, ?F) % F es el factorial % del entero N. factorial(N, F) :factorial(0,N,1,F). factorial(I,N,T,F) :I < N, I1 is I+1, T1 is T*I1, factorial(I1,N,T1,F). factorial(N,N,F,F).

Termina cuando el contador I iguala a N.

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Tail Recursion Optimization


Es posible implementar programas recursivos eficientes en el manejo del espacio de memoria. Durante su ejecucin, el espacio utilizado se mantiene constante respecto al nmero de llamadas recursivas. La tcnica de implementacin se denomina Tail Recursion Optimization. En Prolog: Last Call Optimization. Depende de la implementacin del intrprete.

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Tail Recursion Optimization


Considerar la reduccin del objetivo A usando la clusula A' B1,B2,,Bn con el mgu . La optimizacin es potencialmente aplicable a Bn. Consiste en reutilizar el rea originalmente asignada a A para re-asignrsela al nuevo objetivo Bn. Precondicin:
No existen clusulas pendientes que unifiquen con A. La computacin de (B1,B2,,Bn-1) es determinstica.
Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Tail Recursion Optimization


Length no optimizado: Length optimizado:
largo([],0). largo([_|Xs],N) :largo(Xs, N1), N is N1+1. length(Xs,N) :length(Xs,0,N). length([_|Xs],A,N) :A1 is A+1, length(Xs,A1,N). length([],N,N).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Tail Recursion Optimization


length(Xs,N) :length(Xs,0,N). length([_|Xs],A,N) :A1 is A+1, length(Xs,A1,N). length([],N,N).
lengt h([a, b],N) length ([a,b], 0,N) _G245 is 0+1, length([b],_G24 5,N) {_G245=1} lengt h([b], 1,N) _G246 is 1+1, length([],_G24 6,N) {_G246=2} lengt h([], 2,N) lengt h([], 2,2)

Programacin Lgica | InCo | FIng | UDELAR

tr u e

Output: N=2

Acumuladores

Tail Recursion Optimization


Precondiciones: -En la resolucin del ltimo objetivo, nunca quedan choice points pendientes.
lengt h([a, b],N) length ([a,b], 0,N) _G245 is 0+1, length([b],_G24 5,N) {_G245=1} lengt h([b], 1,N) _G246 is 1+1, length([],_G24 6,N) {_G246=2} lengt h([], 2,N) lengt h([], 2,2)

Programacin Lgica | InCo | FIng | UDELAR

tr u e

Output: N=2

Acumuladores

Reverso de una lista


Reverse sin acumuladores:
reverse([],[]). reverse([X|Xs],Zs) :reverse(Xs,Ys), append(Ys,[X],Zs).

Reverse con acumuladores:


reverse(Xs,Ys) :reverse(Xs,[],Ys). reverse([X|Xs],A,Ys) :reverse(Xs,[X|A],Ys). reverse([],Ys,Ys).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Producto interno
Producto interno sin acumuladores:
inprod([X|Xs],[Y|Ys],IP) :inprod(Xs,Ys,IP1), IP is X*Y+IP1. inprod([],[],0).

Producto interno con acumuladores:


inprod(Xs,Ys,IP) :inprod(Xs,0,Ys,IP). inprod([X|Xs],A,[Y|Ys],IP) :A1 is X*Y+A, inprod(Xs,A1,Ys,IP). inprod([],IP,[],IP).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Fibonacci
Fibonacci sin acumuladores:
fib(1,1). fib(2,2). fib(N,M) :N1 is N-1, N2 is N-2, fib(N1,M1), fib(N2,M2), M is M1+M2.

Fibonacci con acumuladores:


fib(1,1). fib(2,2). fib(N,M) :N>2, fib(N,2,1,2,M). fib(N,I,A,B,M) :I < N, I1 is I+1, B1 is A+B, fib(N,I1,B,B1,M). fib(N,N,_,M,M).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Fibonacci
Fibonacci iterativo:
fib(N); if N == 1 return(1); else if N == 2 return(2); else A = 1; B = 2; for I = 1 to N aux = A+B; A = B; B = aux; end return(B); end

Fibonacci con acumuladores:


fib(1,1). fib(2,2). fib(N,M) :N>2, fib(N,2,1,2,M). fib(N,I,A,B,M) :I < N, I1 is I+1, B1 is A+B, fib(N,I1,B,B1,M). fib(N,N,_,M,M).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos sin ciclos


a b c d e edge(a,b). edge(a,c). edge(a,d). edge(a,e). edge(c,f). edge(c,g). edge(f,h). edge(f,i). edge(d,j). edge(e,k). edge(h,i).

h i

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos sin ciclos


Camino
% % % % path(X,Y,Path) Path es el camino entre dos nodos X e Y en el grafo dirigido sin ciclos definido por la relacin edge/2.

path(X,X,[X]). path(X,Y,[X|P]) :- edge(X,N), path(N,Y,P).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos sin ciclos


Camino
% % % % path(X,Y,Path) Path es el camino entre dos nodos X e Y en el grafo dirigido sin ciclos definido por la relacin edge/2.

path(X,X,[X]). path(X,Y,[X|P]) :- edge(X,N), path(N,Y,P). ?- path(a,i,X). X = [a,c,f,h,i] ; X = [a,c,f,i] ; false. Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos con ciclos


x y z edge(x,y). edge(y,z). edge(y,u). edge(z,x). edge(z,v).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos con ciclos


Camino
% % % % path(X,Y,Path) Path es el camino entre dos nodos X e Y en el grafo dirigido con ciclos definido por la relacin edge/2.

path(X,Y,P) :- path(X,Y,[X],P). path(X,Y,V,P) :edge(X,N), notmember(N,V), path(N,Y,[N|V],P). path(X,X,V,V).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos con ciclos


Camino
?- path(x,u,Path). Path = [u, y, x] ; false

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos con ciclos


Camino
% % % % path(X,Y,Path) Path es el camino entre dos nodos X e Y en el grafo dirigido con ciclos definido por la relacin edge/2.

path(X,Y,[X|P]) :- path(X,Y,[X],P). path(X,Y,V,[N|P]) :edge(X,N), notmember(N,V), path(N,Y,[N|V],P). path(X,X,_,[]).

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos con ciclos


Camino
?- path(x,u,Path). Path = [x, y, u] ; false

Programacin Lgica | InCo | FIng | UDELAR

Acumuladores

Grafos dirigidos con ciclos


path(X,Y,[X|P]) :path(X,Y,[X],P). path(X,Y,V,[N|P]) :edge(X,N), notmember(N,V), path(N,Y,[N|V],P). path(X,X,_,[]). edge(x,y). edge(y,z). edge(y,u). edge(z,x). edge(z,v).
path(x,u,P)

{P=[x|_G235]}
path(x,u,[x],_G235)

{_G235=[_G236|_G237]}
edge(x,_G236), notmember(_G236,[x]), path(_G236,u,[_G236|[x]],_G237)

{_G236=y}
path(y,u,[y,x],_G237)

{_G237=[_G238|_G239]}
edge(y,_G238), notmember(_G238,[y,x]), path(_G238,u,[_G238|[y,x],_G239)

{_G238=z}
path(z,u,[z,y,x],_G239)

{_G238=u}
path(u,u,[u,y,x],_G239)

{_G239=[_G240|_G241]}
edge(z,_G240), notmember(_G240,[z,y,x]), path(_G240,u,[_G240|[z,y,x]],_G241)

{_G239=[]}
path(u,u,[u,y,x],[])

{_G240=x}
notmember(x,[z,y,x]) f

{_G240=v}
path(x,u,[v,z,y,x],_G241) f

Programacin Lgica | InCo | FIng | UDELAR

tr u e

Output: P=[x,y,u]

También podría gustarte