Lambda Calculo e Programacao Funcional

download Lambda Calculo e Programacao Funcional

of 29

Transcript of Lambda Calculo e Programacao Funcional

Lambda Clculo e Programao FuncionalProgramao Funcional Bacharelado em Sistemas de Informao Maio - 2009

Alonzo Church (19031995)Professor em Princeton, EUA (19291967) e UCLA (19671990) Inventou um sistema formal, chamado -calculus (Lambda Clculo) , e definiu a noo de funo computvel utilizando este sistema. O Lambda Clculo pode ser chamado a menor linguagem de programao universal do mundo. As linguagens de programao funcionais, como Lisp, Miranda, ML, Haskell so baseadas no Lambda Clculo.

Lambda ClculoO lambda clculo pode ser visto como uma linguagem de programao abstrata em que funes podem ser combinadas para formar outras funes, de uma forma pura. O lambda clculo trata funes como cidados de primeira classe, isto , entidades que podem, como um dado qualquer, ser utilizadas como argumentos e retornadas como valores de outras funes.

SintaxeUma expresso simples do lambda clculo: (+ 4 5) Todas as aplicaes de funes no lambda clculo so escritas no formato prefixo. Avaliando a expresso: (+ 4 5) = 9 A avaliao da expresso procede por reduo: (+ (* 5 6)(* 4 3)) (+ 30 (* 4 3)) (+ 30 12) 42

SintaxeUma abstrao lambda um tipo de expresso que denota uma funo: (x. + x 1) O determina que existe uma funo, e imediatamente seguido por uma varivel, denominada parmetro formal da funo. ( x . + x 1)A funo de x que incrementa x de 1

SintaxeUma expresso lambda deve ter a forma: ::= | | | .

Os parnteses podem ser utilizados nas expresses para prevenir ambiguidades.

Exemplos(x. x) y (x. f x) xy (x. x) (x. x) (x. x y) z (x y. x) t f (x y z. z x y) a b (x y. x) (f g. f g) (x. x) (x. x) z (x y. x y) y (x y. x y) (x. x) (x. x) (x y. x y) ((x. x) (x. x))

Anlise de Expresses LambdaA expresso Lambda se estende para a direita

f. x y xyz f g. x

f.(x y) (x y) z f . g. x

A aplicao associativa esquerda

Mltiplos lambdas podem ser omitidos

Variveis Livres e LigadasA varivel x ligada por na expresso: x.e Caso a varivel no seja ligada, ento considerada livre. As variveis livres de um termo so definidas como:FV(x) FV(e1 e2) FV( x . e) = = = {x} FV(e1) FV(e2) FV(e) - { x }

Para a expresso abaixo, y ligada e x uma varivel livre.y.xy

Variveis Livres e Ligadas( x. + x y) 4

Para avaliar completamente a expresso, necessrio conhecer o valor global de y. Para x, a varivel local e pertence funo. Exemplos: x. + (( y. + y z) 7) x + x (( x. + x 1) 4)// z livre // o primeiro x livre

ReduoA aplicao de um argumento uma abstrao lambda implica na substituio das ocorrncias das variveis correspondentes ao argumento:( x. + x 1) 4

+ 4 1

Esta operao denominada -reduo. Funes tambm podem ser passadas como argumento:( f. f 3) ( x. + x 1)

( x. + x 1) 3 + 3 1 4

-reduo( x. y. + (- x 1)) x 3) 9 ( x. + (- x 1)) 9 3 + (- 9 1) 3 + 8 3 11 ( x. y. + x (( x.- x 3) y)) 5 6

??

ConversoConsidere as duas abstraes lambda:( x. + x 1) ( y. + y 1) Claramente as duas abstraes acima so equivalentes e uma -converso nos permite mudar o nome do parmetro formal de uma abstrao lambda. Ento: ( x. + x 1)

( y. + y 1)

ConversoConsidere as duas expresses:( x. + 1 x) (+ 1) Ambas tem o mesmo comportamento quando aplicadas argumento: adicionam 1 ao argumento. Uma reduo uma regra expressando tal equivalncia: ( x. + 1 x )

(+ 1)

reduo (Equivalncia)( x. + 1 x) (+ 1)

Em Haskell:Main> (\x (+) 1 x) 4 5 Main> ( (+) 1) 4 5

Resumoconverso (renomeao) reduo (aplicao) conversox.e y. e Quando y no uma varivel livre em e. Operaes de renomeao e substituio. Elimina uma abstrao mais complexa.

( x . e1) e2

[ e2/x ] e1

x.ex e

Exemplos de funesExemplo: rea de um crculo F * r2, r N Q x * x, x N H=FQ H(r) = 3,14 * Q(r) Abstrao Lambda:Em Haskell:

(funo composta) (Fortran)

y. * y * yMain> (\y -> pi * y * y) 3 28.2743338823081

Exemplos de funesint f(x) { return x+2; } f(5);(f. f(5)) (x. x+2) Bloco principal Funo declarada

Exemplos de funesDada uma funo f, defina uma expresso f f:

f. x. f (f x)Aplicao para f(x) = x+1:

(f. x. f (f x)) (y. y+1) = x. (y. y+1) ((y. y+1) x) = x. (y. y+1) (x+1) = x. (x+1)+1

Tuplas como funesEm Haskell:t f pair first second = = = = = \x \x \x \p \p -> -> -> -> -> \y -> x \y -> y \y -> \z -> z x y p t p f

Main> first (pair 1 2) 1 Main> first (second (pair 1 (pair 2 3))) 2

Exerccios1. Calcular a mdia das notas dos alunos de um curso:type Aluno = (Int, String, Float) -- N Aluno, Nome, Nota type Curso = [Aluno] listaAlunos :: Curso listaAlunos = [(1234, "Jose Azevedo", 13.2), (2345, "Carlos Silva", 9.7), (3456, "Rosa Mota", 17.9)] media :: Curso->Float media l = (/) (sum (map (\(_,_,n)->n) l)) (fromIntegral (length l))

ExercciosMain> media listaAlunos 13.6 Funes utilizadas: fromIntegral : funo que transforma o argumento em um nmero da classe Fractional Exemplo: divisao a b = (fromIntegral a) / (fromIntegral b) map : funo que aplica uma funo a todos os elementos de uma lista. Exemplo: Main> dobro 3 9

ExercciosMain> map dobro [1,2,3] [1,4,9] Main> map (\(_,n) -> n) [(1,2),(3,4)] [2,4] sum : funo que soma os elementos de uma lista. Main> sum [1,2,3] 6 Main> sum ['a','b','c'] ERROR - Cannot infer instance *** Instance : Num Char *** Expression : sum ['a','b','c'] Main> sum [1.2,3.3] 4.5

Exerccios2. Implementar uma funo que calcula o sucessor de um nmero inteiro usando expresso lambda (x. x+1). Em seguida, definir uma funo duasVezes para aplicar uma funo nela mesma. Finalmente, construir uma funo para mapear a aplicao de duasVezes sobre uma lista de inteiros.sucessor::(Int -> Int) sucessor = \x -> x + 1 Main> 2 Main> 6 Main> ERROR sucessor 1 sucessor 5 sucessor 'a' - Type error in application

ExercciosFuno duasVezes para aplicar uma funo nela mesma:sucessor::(Int -> Int) sucessor = \x -> x + 1 duasVezes :: (a->a) ->a ->a duasVezes f x = f (f x)Main> 7 Main> 102 Main> ERROR

duasVezes sucessor 5 duasVezes sucessor 100 duasVezes sucessor 5.6- Cannot infer instance

ExercciosFuno mapear para aplicar uma funo uma lista de Valores (sem usar a funo map)sucessor::(Int -> Int) sucessor = \x -> x + 1 duasVezes :: (a->a) ->a ->a duasVezes f x = f (f x) mapear::(a->b)->[a]->[b] mapear f [] = [] mapear f (x:xs) = (f x): mapear f xs

ExercciosMain> mapear sucessor [1,3,5] [2,4,6] Main> mapear (duasVezes sucessor) [1,3,5] [3,5,7] Main> mapear (duasVezes (+ 1)) [1,3,5] [3,5,7] Main> mapear (duasVezes (\x -> x * x)) [3,4,5] [81,256,625] Main> mapear (\y -> y ++ y) ["na","ta","la"] ["nana","tata","lala"] Main> mapear (duasVezes (\y -> y ++ y)) ["na","ta","la"] ["nananana","tatatata","lalalala"]

Exerccios3. Dados um elemento e uma lista, intercale o elemento na lista, em todas as posies.intercala :: a -> [a] -> [[a]] intercala x [] = [[x]] intercala x (l:ls) = [x:l:ls] ++ map (l:) (intercala x ls) Main> intercala 1 [2,3] [[1,2,3],[2,1,3],[2,3,1]]

Exerccios4. Reduza as expresses avaliando-as e escreva o cdigo correspondente em Haskell, testando no ambiente Hugs.1) ( x.2*x + 1) 3 2) ( xy.x+y) 5 7 3) ( yx.x+y) 5 7 4) ( xy.x-y) (z.z/2) 5) ( x.xx) ( y.y) 6) ( x. y. x + (( x.8) - y)) 5 6 7) ( x. y. x y) 9 4