Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. ·...

45
Lazy Functional Prolog: a Practical Approach J. Rodr´ ıguez-Hortal´ a, J. S´ anchez-Hern´ andez Dep. Sistemas Inform´ aticos y Computaci´ on Universidad Complutense de Madrid PROLE 2007, Zaragoza 12-14 Septiembre 2007 J. Rodr´ ıguez-Hortal´ a, J. S´ anchez-Hern´ andez Lazy Functional Prolog: a Practical Approach

Transcript of Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. ·...

Page 1: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Lazy Functional Prolog: a Practical Approach

J. Rodrıguez-Hortala, J. Sanchez-Hernandez

Dep. Sistemas Informaticos y ComputacionUniversidad Complutense de Madrid

PROLE 2007, Zaragoza 12-14 Septiembre 2007

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 2: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Motivacion (Programacion Logico Funcional)

Actualmente, PLF (Curry, Toy)

Haskell+

indeterminismo, vars. logicasrestricciones, . . .

Otra vision de PLF

Prolog+

funciones, orden superiorλ-abstracciones, pereza

Diferencia?

inclusion de Prolog en sentido propio: sintaxis de primer orden,corte, metaprogramacion, entrada salida de Prolog, etc

no hay tipos!!

Ademas: respetamos el mecanismo operacional de Prolog, pero

admitimos pereza anotada

Implementacion = traduccion de funciones a codigo Prolog(expansor Prolog).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 3: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Motivacion (Programacion Logico Funcional)

Actualmente, PLF (Curry, Toy)

Haskell+

indeterminismo, vars. logicasrestricciones, . . .

Otra vision de PLF

Prolog+

funciones, orden superiorλ-abstracciones, pereza

Diferencia?

inclusion de Prolog en sentido propio: sintaxis de primer orden,corte, metaprogramacion, entrada salida de Prolog, etc

no hay tipos!!

Ademas: respetamos el mecanismo operacional de Prolog, pero

admitimos pereza anotada

Implementacion = traduccion de funciones a codigo Prolog(expansor Prolog).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 4: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Motivacion (Programacion Logico Funcional)

Actualmente, PLF (Curry, Toy)

Haskell+

indeterminismo, vars. logicasrestricciones, . . .

Otra vision de PLF

Prolog+

funciones, orden superiorλ-abstracciones, pereza

Diferencia?

inclusion de Prolog en sentido propio: sintaxis de primer orden,corte, metaprogramacion, entrada salida de Prolog, etc

no hay tipos!!

Ademas: respetamos el mecanismo operacional de Prolog, pero

admitimos pereza anotada

Implementacion = traduccion de funciones a codigo Prolog(expansor Prolog).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 5: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Precedentes

Prolog + funciones definidas por el usuario ha sido propuestoantes (T. Asvanyi, 2003; A. Casas et al, 2006; etc).

A. Casas et al incluye lambda-abstracciones, orden superior yevaluacion perezosa (anotada)... basicamente lo que buscamos!

Nuestra propuesta se distingue fundamentalmente por:

tratamiento de HO (traduccion a 1er orden estilo Toy)

modelo de pereza (anotacion en constructoras en vez defunciones)

OCaml y otros admiten suspension de expresiones, pero:suspension/activacion explıcitas programas mas complicados

Nuestra propuesta

Automatiza la suspension/activacion (y ademas esta en uncontexto indeterminista).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 6: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Precedentes

Prolog + funciones definidas por el usuario ha sido propuestoantes (T. Asvanyi, 2003; A. Casas et al, 2006; etc).

A. Casas et al incluye lambda-abstracciones, orden superior yevaluacion perezosa (anotada)... basicamente lo que buscamos!

Nuestra propuesta se distingue fundamentalmente por:

tratamiento de HO (traduccion a 1er orden estilo Toy)

modelo de pereza (anotacion en constructoras en vez defunciones)

OCaml y otros admiten suspension de expresiones, pero:suspension/activacion explıcitas programas mas complicados

Nuestra propuesta

Automatiza la suspension/activacion (y ademas esta en uncontexto indeterminista).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 7: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Precedentes

Prolog + funciones definidas por el usuario ha sido propuestoantes (T. Asvanyi, 2003; A. Casas et al, 2006; etc).

A. Casas et al incluye lambda-abstracciones, orden superior yevaluacion perezosa (anotada)... basicamente lo que buscamos!

Nuestra propuesta se distingue fundamentalmente por:

tratamiento de HO (traduccion a 1er orden estilo Toy)

modelo de pereza (anotacion en constructoras en vez defunciones)

OCaml y otros admiten suspension de expresiones, pero:suspension/activacion explıcitas programas mas complicados

Nuestra propuesta

Automatiza la suspension/activacion (y ademas esta en uncontexto indeterminista).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 8: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Precedentes

Prolog + funciones definidas por el usuario ha sido propuestoantes (T. Asvanyi, 2003; A. Casas et al, 2006; etc).

A. Casas et al incluye lambda-abstracciones, orden superior yevaluacion perezosa (anotada)... basicamente lo que buscamos!

Nuestra propuesta se distingue fundamentalmente por:

tratamiento de HO (traduccion a 1er orden estilo Toy)

modelo de pereza (anotacion en constructoras en vez defunciones)

OCaml y otros admiten suspension de expresiones, pero:suspension/activacion explıcitas programas mas complicados

Nuestra propuesta

Automatiza la suspension/activacion (y ademas esta en uncontexto indeterminista).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 9: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Plan de la charla

Traduccion de funciones y predicados. Esquema basico.

Orden superior y λ-abstracciones.

Pereza anotada. Sharing.

Ejemplos. Rendimiento.

Conclusiones.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 10: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Traduccion de funciones elementales

Regla en sintaxis funcional:

f(A1, . . . , An)︸ ︷︷ ︸cabeza

= Exp︸︷︷︸cuerpo

:- C1, . . . , Cm︸ ︷︷ ︸condiciones

.

Traduccion (regla a regla):

f(A1, . . . , An, R) : − Ct1, . . . , C

tm, ExpR

anadir un argumento resultado Raplanar las llamadas a funcion de las condiciones Ci

traducir la expresion Exp dejando el resultado en R

fact(0) = 1.fact(N) = N*fact(N-1) :- N>0.

↓ traduccion (primitivas aritmeticas +,-. . . definidas en un preludio)

fact(0,R) :- R=1.fact(N,R) :- N>0, -(N,1,N1), fact(N1,R1), *(N,R1,R).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 11: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Interpretacion informal del significado de las funciones

Principio operacional 1: el orden de evaluacion de una funcion es:

paso de parametros (unificacion)︸ ︷︷ ︸(1)

- condiciones︸ ︷︷ ︸(2)

- cuerpo de la funcion︸ ︷︷ ︸(3)

Traduccion alternativa: intercambiar (2) y (3)cambia el comportamiento en presencia de cortes o noterminacion!ambas traducciones son aceptables, pero trabajamos con laprimera.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 12: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Interpretacion informal del significado de las funciones

Principio operacional 1: el orden de evaluacion de una funcion es:

paso de parametros (unificacion)︸ ︷︷ ︸(1)

- condiciones︸ ︷︷ ︸(2)

- cuerpo de la funcion︸ ︷︷ ︸(3)

Traduccion alternativa: intercambiar (2) y (3)cambia el comportamiento en presencia de cortes o noterminacion!ambas traducciones son aceptables, pero trabajamos con laprimera.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 13: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Traduccion de predicados

Para cada clausula:

aplanar las llamadas a funcion en las condiciones

doubleFact(N,M) :- fact(N)=F, M=2*F.

↓ traduccion

doubleFact(N,M) :- fact(N,F), *(2,F,M).

Los predicados Prolog se pueden “funcionalizar” con la primitiva:

proj(T,G) ::= evalua el objetivo G y devuelve el termino T

Por ejemplo, para extraer el functor ppal. y la aridad de un termino:

name and arity(Term) = proj((Name,Arity), functor(Term,Name,Arity)).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 14: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Orden superior

La aplicacion de una funcion parcial F a un argumento A sehace explıcita por medio de @ (“apply”): F@A.

Traduccion a primer orden (como en Toy): el sistema generalas clausulas para @.

map(F,[]) = [].

map(F,[X|Xs]) = [F@X|map(F,Xs)].

neg(L) = map(not,L).

not(true) = false.

not(false) = true.

↓ traduccion

map(F,[],[]).

map(F,[X|Xs],[Fx|Fxs]) :- @(F,X,Fx), map(F,Xs,Fxs).

neg(L,L1) :- map(not,L,L1). not(true,false). not(false,true).

@(map,F,map(F)).

@(map(F),L,L1) :- map(F,L,L1).

@(neg,L,L1) :- neg(L,L1).

@(not,X,Y) :- not(X,Y).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 15: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

λ-abstracciones

Sintaxis:

λx.e se escribe como fun(X,E)λx1 . . . xn.e se escribe fun(X1, . . . , Xn, E)

Traduccion (λ lifting):

Numerar (dar nombre) a cada ”fun”: fun1, fun2,. . .Introducir las llamadas y definiciones para fun1, fun2,. . .teniendo en cuenta las variables del contexto externo

f(L) = map(fun(X,X*2),L). g(X) = fun(Y,X+Y).

↓ λ-lifting

f(L) = map(fun1,L).fun1(X) = X*2.

g(X) = fun2(X).fun2(X,Y) = X+Y.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 16: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Evaluacion perezosa

Nuestras funciones son impacientes por defecto.

Pero no queremos renunciar a las posibilidades practicas queofrece la evaluacion perezosa, en particular a las estructurasde datos infinitas (o incompletas).

permitimos anotaciones explıcitas de pereza.

... pero, ¿donde localizamos la pereza? Dos alternativas:

46 en las funciones

X en las (constructoras de) estructuras de datos

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 17: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Anotaciones de pereza en las funciones

Traduccion directa con suspensiones Prolog (A. Casas et al, 2006):

freeze(Var,Goal) ::= suspende Goal hasta que V ar se ligue

:- lazy(from).from(N) = [N|from(N+1)].

take(0,L)=[]:-!.

take(N,[])=[]:-!.

take(N,[X|Xs])=[X|take(N-1,Xs)].

↓ se traduce como

from(N,L):- freeze(L,fromLazy(N,L)).fromLazy(N,[N|L]):- +(N,1,N1),from(N1,L).

take(0,L,R)...

...

take(3,from(1))trad from(1,L), take(3,L,K)

take(3,freeze(L, fromLazy(1 ,L))︸ ︷︷ ︸dem. por take

,K) from(2,M), take(3,[1|M],L)

∗ [1,2,3]

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 18: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en las funciones. Problemas

Criba de Eratostenes

primes = sieve(from(2)).

sieve([X|Xs])=[X|sieve(filter(fun(Y,mod(Y,X)=\=0), Xs))].

firstPrimes(N) = take(N,primes).

Funciones perezosas... cuales?

Sin ninguna declaracion de pereza loop!

from perezoso loop!! (filter demanda la la lista completa).

from y filter perezosos loop!!! (sieve demanda la evaluacionde la lista).

Todas las funciones perezosas funciona... muy ineficiente.

Conjunto mınimo de funciones perezosas en este caso:{from,filter , sieve}

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 19: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en las funciones. Problemas

Criba de Eratostenes

primes = sieve(from(2)).

sieve([X|Xs])=[X|sieve(filter(fun(Y,mod(Y,X)=\=0), Xs))].

firstPrimes(N) = take(N,primes).

Funciones perezosas... cuales?

Sin ninguna declaracion de pereza loop!

from perezoso loop!! (filter demanda la la lista completa).

from y filter perezosos loop!!! (sieve demanda la evaluacionde la lista).

Todas las funciones perezosas funciona... muy ineficiente.

Conjunto mınimo de funciones perezosas en este caso:{from,filter , sieve}

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 20: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en las funciones. Problemas

Criba de Eratostenes

primes = sieve(from(2)).

sieve([X|Xs])=[X|sieve(filter(fun(Y,mod(Y,X)=\=0), Xs))].

firstPrimes(N) = take(N,primes).

Funciones perezosas... cuales?

Sin ninguna declaracion de pereza loop!

from perezoso loop!! (filter demanda la la lista completa).

from y filter perezosos loop!!! (sieve demanda la evaluacionde la lista).

Todas las funciones perezosas funciona... muy ineficiente.

Conjunto mınimo de funciones perezosas en este caso:{from,filter , sieve}

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 21: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en las funciones. Problemas

Criba de Eratostenes

primes = sieve(from(2)).

sieve([X|Xs])=[X|sieve(filter(fun(Y,mod(Y,X)=\=0), Xs))].

firstPrimes(N) = take(N,primes).

Funciones perezosas... cuales?

Sin ninguna declaracion de pereza loop!

from perezoso loop!! (filter demanda la la lista completa).

from y filter perezosos loop!!! (sieve demanda la evaluacionde la lista).

Todas las funciones perezosas funciona... muy ineficiente.

Conjunto mınimo de funciones perezosas en este caso:{from,filter , sieve}

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 22: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en las funciones. Problemas

Criba de Eratostenes

primes = sieve(from(2)).

sieve([X|Xs])=[X|sieve(filter(fun(Y,mod(Y,X)=\=0), Xs))].

firstPrimes(N) = take(N,primes).

Funciones perezosas... cuales?

Sin ninguna declaracion de pereza loop!

from perezoso loop!! (filter demanda la la lista completa).

from y filter perezosos loop!!! (sieve demanda la evaluacionde la lista).

Todas las funciones perezosas funciona... muy ineficiente.

Conjunto mınimo de funciones perezosas en este caso:{from,filter , sieve}

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 23: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en las funciones. Problemas

Criba de Eratostenes

primes = sieve(from(2)).

sieve([X|Xs])=[X|sieve(filter(fun(Y,mod(Y,X)=\=0), Xs))].

firstPrimes(N) = take(N,primes).

Funciones perezosas... cuales?

Sin ninguna declaracion de pereza loop!

from perezoso loop!! (filter demanda la la lista completa).

from y filter perezosos loop!!! (sieve demanda la evaluacionde la lista).

Todas las funciones perezosas funciona... muy ineficiente.

Conjunto mınimo de funciones perezosas en este caso:{from,filter , sieve}

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 24: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en constructoras. Ideas previas

En muchos ejemplos practicos la pereza es util para podermanipular estructuras de datos infinitas

pereza asociada a las constructoras.

La forma habitual de manejar pereza en lenguajes impacientes(como OCaml) es mediante anotaciones explıcitas de perezaen las declaraciones de tipo:

type ’a listL = Nil | Cons of (’a * (’a listL Lazy.t));;

let rec from n = Cons (n,lazy (fromL (n+1)));;

let rec take n lst = match n,lst with

,Nil -> Nil

| 0, -> Nil

| ,Cons (x,xs) -> Cons (x, lazy (take (n-1) (Lazy.force xs)));;

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 25: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en constructoras. Primera aproximacion

λ-abstracciones como suspensiones:

E se suspende como λx.E ≡ fun( , E)se despierta aplicandola a un argumento dummyfun( , E)@dummy E

Ejemplo: listas perezosas en el segundo argumento

from(N)= [N|from(N+1)].

take(0,L)= []:-!.

take(N,[])=[]:-!.

take(N,[X|Xs])=

[X|take(N-1,Xs)].

from(N)=[N|fun( ,from(N+1))].

take(0,L)=[]:-!.

take(N,[])=[]:-!.

take(N,[X|Xs])=

[X|fun( ,take(N-1,Xs@dummy))].

Objetivo: automatizar esta transformacion en presencia de ladeclaracion :- lazy([ |on]).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 26: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en constructoras. Primera aproximacion

λ-abstracciones como suspensiones:

E se suspende como λx.E ≡ fun( , E)se despierta aplicandola a un argumento dummyfun( , E)@dummy E

Ejemplo: listas perezosas en el segundo argumento

from(N)= [N|from(N+1)].

take(0,L)= []:-!.

take(N,[])=[]:-!.

take(N,[X|Xs])=

[X|take(N-1,Xs)].

from(N)=[N|fun( ,from(N+1))].

take(0,L)=[]:-!.

take(N,[])=[]:-!.

take(N,[X|Xs])=

[X|fun( ,take(N-1,Xs@dummy))].

Objetivo: automatizar esta transformacion en presencia de ladeclaracion :- lazy([ |on]).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 27: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en constructoras + indeterminismo = problemas

Ordenacion por permutacion (generate and test)

% generate

permut([]) = [].

permut([X|Xs]) = insert(X,permut(Xs)).

insert(X,[]) = [X].

insert(X,[Y|Ys]) = [X,Y|Ys].

insert(X,[Y|Ys]) = [Y|insert(X,Ys)].

% test

sorted([]) = true.

sorted([X]) = true.

sorted([X,Y|Ys]) = sorted([Y|Ys]) :- X=<Y.

sorted([X,Y|Ys]) = false :- X>Y.

pemutSort(Xs) = ifThen(sorted(Ys),Ys) :- Ys=permut(Xs).

permutSort([4,3,2,1],L) [1,2,3,4] (muy ineficiente!)

+ declaracion :- lazy([ |on]).permutSort([4,3,2,1],L) [1,4,3,2]. . . [1,2,3,4] (incorrecto)

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 28: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Pereza en constructoras sin sharing

En el ejemplo anterior, con listas perezosas tenemos:

permutSort([4,3,2,1])

↓ * pemutSort(Xs) = ifThen(sorted(Ys),Ys) :- Ys=permut(Xs).

ifThen(sorted([1|λ . permut([4, 3, 2])︸ ︷︷ ︸↓

[2,3,4]ordenado

])

︸ ︷︷ ︸↓

true

, [1|λ . permut([4, 3, 2])︸ ︷︷ ︸↓

[4,3,2]desordenado!!

] )

↓ ∗[1,4,3,2] (tambien [1,3,4,2],. . . , [1,2,3,4] run-time choice)

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 29: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

λ-abstracciones con comparticion: δ-abstracciones

Principio operacional 2 En programas terminantes (con evaluacionestricta) la evaluacion de una funcion debe producir el mismoresultado con o sin declaraciones de pereza (si el programa es noterminante la pereza puede evitar divergencias).

Necesitamos comparticion en las λ-abstracciones generadaspara suspender δ-abstracciones:

δ Ev Res . Exptrad funN (Ev,Res, , Exp).

Ev (flag): on si la suspension ya ha sido evaluada, var e.o.c.Res: resultado de la evaluacion (si Ev == on).

: argumento dummy como antes

Regla de evaluacion:

funN(Ev,Res,ExpRes)=H :- (Ev==on,!;ExpRes,Ev=on),H=Res.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 30: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

δ-abstracciones. Ejemplo

:- lazy([ |on]).

app([],Xs) = Xs.app([X|Xs],Ys) = [X|app(Xs,Ys)].

↓ traduccion

app([],Ys,Ys).app([X|Xs],Ys,[X|fun1(Ev,Res,Xs,Ys)]).fun1(Ev,Res,Xs,Ys,Dummy,H):-(Ev==on, !

;@(Xs,dummy,Xs1), app(Xs1,Ys,R1), H=R1, Ev=on

), H=Res.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 31: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Eficiencia. Pereza: funciones & constructoras

Goal Lazy funs (all) Lazy funs (some) Lazy listsnPrime(300) 0.829399 0.534276 0.182028nPrime(600) 2.65868 1.70961 0.697245

nPrime(1000) overflow overflow 1.92277nPrime(6000) overflow overflow 80.5051

firstPrimes(300) 1.06425 0.543337 0.230733firstPrimes(600) 3.58354 1.76382 0.899285

firstPrimes(1000) overflow overflow 2.19576firstPrimes(1200) overflow overflow 3.39396firstPrimes(1500) overflow overflow overflow

permutSort(revLst(10)) 0.365988 0.160308 0.195278permutSort(revLst(12)) 3.18058 1.44293 1.70397permutSort(revLst(15)) 96.7763 42.2988 49.6788permutSort(revLst(16)) 248.329 110.585 128.547

Tiempos de ejecucion (en segundos)

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 32: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Eficiencia. Toy & Prolog + funciones (pereza en constructoras)

Goal Toy Lazy listspermutSort(revLst(10)) 0.76 0.28permutSort(revLst(12)) 6.90 2.35permutSort(revLst(12)) 6.90 2.35permutSort(revLst(12)) 62.43 22.97

Es posible optimizar la traduccion de Toy (eliminando gestionde 6=, etc) y aumentar su rendimiento

Pero el modelo de pereza es esencialmente distinto

Definimos: fib(0)=0. fib(1)=1. fib(N)=fib(N-1)+fib(N-2).

Goal Toy Lazy listspermutSort([fib(22),fib(21),fib(20)]) 1.16 1.13permutSort([fib(26),fib(25),fib(24)]) overflow 7.65

Toy reevalua el calculo los elementos de la lista.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 33: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Eficiencia. Toy & Prolog + funciones (pereza en constructoras)

Goal Toy Lazy listspermutSort(revLst(10)) 0.76 0.28permutSort(revLst(12)) 6.90 2.35permutSort(revLst(12)) 6.90 2.35permutSort(revLst(12)) 62.43 22.97

Es posible optimizar la traduccion de Toy (eliminando gestionde 6=, etc) y aumentar su rendimiento

Pero el modelo de pereza es esencialmente distinto

Definimos: fib(0)=0. fib(1)=1. fib(N)=fib(N-1)+fib(N-2).

Goal Toy Lazy listspermutSort([fib(22),fib(21),fib(20)]) 1.16 1.13permutSort([fib(26),fib(25),fib(24)]) overflow 7.65

Toy reevalua el calculo los elementos de la lista.

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 34: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Mezclando impaciencia y pereza (I)

Triangulo de Pascal con listas perezosas (Blas et al):

1 row 01 1 row 1

1 2 1 row 21 3 3 1 row 3

1 4 6 4 1 row 4. . .

Idea:

0 1 3 3 1 [0] ++ row 3+ 1 3 3 1 0 row 3 ++ [0]

1 4 6 4 1 row 4

:- include(prelude). :- lazy([ |on]).

iter(F) = [F|iter(zipWith((+),[0|F],append(F,[0])))].

pas=iter([1]). row(N)=nth(N,pas). comb(N,M)=nth(M,(nth(N,pas))).

row(6) [1, 6, 15, 20, 15, 6, 1]

take(5,pas) [ [1]︸︷︷︸, [1, 1]︸︷︷︸, [1, 2, 1]︸ ︷︷ ︸, [1, 3, 3, 1]︸ ︷︷ ︸, [1, 4, 6, 4, 1]︸ ︷︷ ︸]

↘↓↙¿y si evaluamos las listas internas de modo impaciente?

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 35: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Mezclando impaciencia y pereza (I)

Triangulo de Pascal con listas perezosas (Blas et al):

1 row 01 1 row 1

1 2 1 row 21 3 3 1 row 3

1 4 6 4 1 row 4. . .

Idea:

0 1 3 3 1 [0] ++ row 3+ 1 3 3 1 0 row 3 ++ [0]

1 4 6 4 1 row 4

:- include(prelude). :- lazy([ |on]).

iter(F) = [F|iter(zipWith((+),[0|F],append(F,[0])))].

pas=iter([1]). row(N)=nth(N,pas). comb(N,M)=nth(M,(nth(N,pas))).

row(6) [1, 6, 15, 20, 15, 6, 1]

take(5,pas) [ [1]︸︷︷︸, [1, 1]︸︷︷︸, [1, 2, 1]︸ ︷︷ ︸, [1, 3, 3, 1]︸ ︷︷ ︸, [1, 4, 6, 4, 1]︸ ︷︷ ︸]

↘↓↙¿y si evaluamos las listas internas de modo impaciente?

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 36: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Mezclando impaciencia y pereza (I)

Triangulo de Pascal con listas perezosas (Blas et al):

1 row 01 1 row 1

1 2 1 row 21 3 3 1 row 3

1 4 6 4 1 row 4. . .

Idea:

0 1 3 3 1 [0] ++ row 3+ 1 3 3 1 0 row 3 ++ [0]

1 4 6 4 1 row 4

:- include(prelude). :- lazy([ |on]).

iter(F) = [F|iter(zipWith((+),[0|F],append(F,[0])))].

pas=iter([1]). row(N)=nth(N,pas). comb(N,M)=nth(M,(nth(N,pas))).

row(6) [1, 6, 15, 20, 15, 6, 1]

take(5,pas) [ [1]︸︷︷︸, [1, 1]︸︷︷︸, [1, 2, 1]︸ ︷︷ ︸, [1, 3, 3, 1]︸ ︷︷ ︸, [1, 4, 6, 4, 1]︸ ︷︷ ︸]

↘↓↙¿y si evaluamos las listas internas de modo impaciente?

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 37: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Mezclando impaciencia y pereza (I)

Triangulo de Pascal con listas perezosas (Blas et al):

1 row 01 1 row 1

1 2 1 row 21 3 3 1 row 3

1 4 6 4 1 row 4. . .

Idea:

0 1 3 3 1 [0] ++ row 3+ 1 3 3 1 0 row 3 ++ [0]

1 4 6 4 1 row 4

:- include(prelude). :- lazy([ |on]).

iter(F) = [F|iter(zipWith((+),[0|F],append(F,[0])))].

pas=iter([1]). row(N)=nth(N,pas). comb(N,M)=nth(M,(nth(N,pas))).

row(6) [1, 6, 15, 20, 15, 6, 1]

take(5,pas) [ [1]︸︷︷︸, [1, 1]︸︷︷︸, [1, 2, 1]︸ ︷︷ ︸, [1, 3, 3, 1]︸ ︷︷ ︸, [1, 4, 6, 4, 1]︸ ︷︷ ︸]

↘↓↙¿y si evaluamos las listas internas de modo impaciente?

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 38: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Mezclando impaciencia y pereza (II)

Para las filas, listas impacientes: row ::= nil | cons (e,row)

Para la lista de filas, listas perezosas: :- lazy([ |on]).

iter2(F)=[F|iter2(zipWithRows((+),cons(0,F),appendRows(F,cons(0,nil))))].

pas2=iter2(cons(1,nil)). row2(N)=... comb2(N,M)=...

Goal Lazy lists Lazy/eager listsrow(400) 0.691386 0.248232

row(600) 1.77859 0.560645

row(800) overflow 1.01706

row(2000) overflow 6.71622

row(4000) overflow 30.0093

comb(500, 250) 0.87144 0.561656

comb(800, 400) 2.13438 2.18744

comb(1000, 500) 5.29124 4.3969

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 39: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Metaprogramacion (I)

Cifras y letras: dada una lista de operandos obtener un total conlas operaciones aritmeticas basicas

% expression ::= number | plus exp exp | minus ...

% non deterministic generation of expressions

genExp(Ns)=oneOf(Ns).

genExp(Ns)=E :- split(Ns)=(As,Bs),

E=..[oneOf([plus,minus,mult,div]),genExp(As),genExp(Bs)].

...

% evaluation of expressions

eval(plus(E1,E2)) = ... eval(minus(E1,E2)) = ...

% solution for the count-down problem

sol(V,L)=E :- E=genExp(L), V==eval(E).

Pero, y si queremos la mejor aproximacion?

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 40: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Metraprogramacion (II)

Supongamos que tenemos:

best(Gen,Data,Comp)::= devuelve la mejor alternativa dados:

Gen (generador): devuelve pares (Candidato,Valoracion) a partir dela lista de datos Data

Comp: criterio de comparacion para pares (Candidato,Valoracion)

Busqueda de la mejor aproximacion:

bestApprox(V,L) = best(genExpVal,[V,L],better).

genExpVal(V,L) = (E,abs(V-eval(E))) :- genExp(L)=E.

better((E1,V1),(E2,V2)) = (E1,V1) :- V1<V2, !.

better((E1,V1),(E2,V2)) = (E2,V2).

Ej: genExpVal(17,[3,4,1])indet (3 ∗ 4 + 1| {z }

13

, 4|{z}|13−17|

)

bestApprox(26,[4,5,3]) 3*(5+4) (=27)

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 41: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Metraprogramacion (II)

Supongamos que tenemos:

best(Gen,Data,Comp)::= devuelve la mejor alternativa dados:

Gen (generador): devuelve pares (Candidato,Valoracion) a partir dela lista de datos Data

Comp: criterio de comparacion para pares (Candidato,Valoracion)

Busqueda de la mejor aproximacion:

bestApprox(V,L) = best(genExpVal,[V,L],better).

genExpVal(V,L) = (E,abs(V-eval(E))) :- genExp(L)=E.

better((E1,V1),(E2,V2)) = (E1,V1) :- V1<V2, !.

better((E1,V1),(E2,V2)) = (E2,V2).

Ej: genExpVal(17,[3,4,1])indet (3 ∗ 4 + 1| {z }

13

, 4|{z}|13−17|

)

bestApprox(26,[4,5,3]) 3*(5+4) (=27)

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 42: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Ejemplos. Metaprogramacion (III)

La definicion de best:

best(F,Args,Better) = R :-applyLst(F,Args)=EV, retractall(currentBest( )),assert(currentBest(EV)), !, bestAux(F,Args,Better)=R.

bestAux(F,Args,Better) = R :-applyLst(F,Args)=E, currentBest(C), applyLst(Better,[E,C])=E,retractall(currentBest( )),assert(currentBest(E)), fail.

bestAux( , , )=R:-!,currentBest(R).

applyLst(F,[])=F.

applyLst(F,[X|Xs])=applyLst(F@X,Xs).

best es una funcion generica que encapsula la exploracion delespacio de busqueda

el orden superior facilita el aislamiento de lametaprogramacion del resto del codigo

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 43: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Conclusiones y trabajo futuro (I)

El uso de funciones en Prolog enriquece notablemente el lenguajesin perder las capacidades de metaprogramacion propias de Prolog.

La manipulacion explıcita de la pereza mediante anotaciones enconstructoras en vez de funciones resulta muy manejable y efectivaen la practica. Ademas es bastante transparente para elprogramador (el traductor automatiza la gestion de suspensiones).

Requiere un mecanismo automatico de comparticion δ-abstracciones (λ-abstracciones extendidas).

El traductor es relativamente sencillo (unas 500 lıneas de codigo) yde facil manejo.

La traduccion requiere formalizacion, en concreto la generacion yactivacion de suspensiones:

relacion con context sensitive rewriting (S. Lucas, 1998).

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 44: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Conclusiones y trabajo futuro (II)

Mejoras del sistema:

Prompt funcional.

X Disponible mediante :- fun. (admite anidamientos yλ-abstracciones, muestra tiempos de ejecucion).

Posibilidad de forzar la evaluacion de expresiones que contienensuspensiones.

X Funcion predefinida nf(Exp)::= evalua Exp a forma normal

Comprobaciones elementales de tipos (chequeo, no inferencia).

46 Actualmente solo comprobaciones simples de aridad.

Optimizaciones de codigo.

46 El sistema analiza el uso de cortes y optimiza el codigoeliminando variables de paso y unificaciones redundantes.

Posibilidad de encapsulado para suspender evaluacion (quotations)

X quot(Exp) λ . Exp

X unquot(Exp) Exp@dummy

J. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach

Page 45: Lazy Functional Prolog: a Practical Approachgpd.sip.ucm.es/jaime/pda/frolog.pdf · 2013. 5. 14. · -abstracciones, pereza Diferencia? inclusi on de Prolog en sentido propio: sintaxis

Conclusiones y trabajo futuro (II)

Mejoras del sistema:

Prompt funcional.

X Disponible mediante :- fun. (admite anidamientos yλ-abstracciones, muestra tiempos de ejecucion).

Posibilidad de forzar la evaluacion de expresiones que contienensuspensiones.

X Funcion predefinida nf(Exp)::= evalua Exp a forma normal

Comprobaciones elementales de tipos (chequeo, no inferencia).

46 Actualmente solo comprobaciones simples de aridad.

Optimizaciones de codigo.

46 El sistema analiza el uso de cortes y optimiza el codigoeliminando variables de paso y unificaciones redundantes.

Posibilidad de encapsulado para suspender evaluacion (quotations)

X quot(Exp) λ . Exp

X unquot(Exp) Exp@dummyJ. Rodrıguez-Hortala, J. Sanchez-Hernandez Lazy Functional Prolog: a Practical Approach