Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas


aula2 - Programação Funcional, Notas de aula de Análise de Sistemas de Engenharia

INE 5363 - Programação Funcional - INE/CTC/UFSC - Curso de Bacharelado em Ciências da Computação. Prof. Dr. rer.nat. Aldo von Wangenheim - http://www.inf.ufsc.br/~awangenh/Funcional

Tipologia: Notas de aula

Antes de 2010

Compartilhado em 25/01/2010

ednaldo-miranda-6
ednaldo-miranda-6 🇧🇷

4

(1)

38 documentos

1 / 14

Toggle sidebar

Esta página não é visível na pré-visualização

Não perca as partes importantes!

bg1
INE 5363 - Programação Funcional - INE/CTC/UFSC - Curso de Bacharelado em Ciências da Computação
Prof. Dr. rer.nat. Aldo von Wangenheim - http://www.inf.ufsc.br/~awangenh/Funcional
2.2. A Semântica Operacional do Cálculo Lambda
Até agora foi descrita a sintaxe do cálculo- . Para chamá-lo de “cálculo”, devemos porém dizer
como “calcular” com ele.
Basicamente isto é realizado através de três regras de conversão, que descrevem como conver-
ter uma expressão- em outra.
2.2.1. Introdução à conversão: Variáveis atadas e livres (bound/free)
Consideremos a expressão- : ( x. + x y) 4
Para avaliar esta expressão necessitamos:
saber o valor “global” de y.
não necessitamos saber o valor global de x, pois é o parâmetro formal da função.
Assim vemos que: x e y possuem um status bastante diferente.
A razão é que x ocorre atado pelo x, é somente um encaixe dentro do qual o argumento 4 é
colocado quando a abstração- for aplicada ao argumento.
Por outr lado, y não é atado por nenhum e assim ocorre livre na expressão.
A ocorrência de uma variável é atada se há uma expressão- envolvente que a amarra, senão
é livre. No exemplo a seguir, x e y ocorrem atados, z porém, ocorre livre:
x. + (( y. + y z) 7) x
Observe que os termos atado e livre se referem a ocorrências específicas da variável em uma
expressão.
Uma variável pode possuir tanto uma ocorrência atada como uma livre em uma expressão.
Considere o exemplo:
+ x (( x. + x 1) 4)
Aqui x ocorre livre (a primeira vez) e atada (a segunda). Cada ocorrência individual de uma
variável deve ser ou atada ou livre.
λ
λ
λλ
λ
λ
λ
λ
λλ
λ
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe

Pré-visualização parcial do texto

Baixe aula2 - Programação Funcional e outras Notas de aula em PDF para Análise de Sistemas de Engenharia, somente na Docsity!

2.2. A Semântica Operacional do Cálculo Lambda

Até agora foi descrita a sintaxe do cálculo-. Para chamá-lo de “cálculo”, devemos porém dizer

como “calcular” com ele.

Basicamente isto é realizado através de três regras de conversão, que descrevem como conver-

ter uma expressão- em outra.

2.2.1. Introdução à conversão: Variáveis atadas e livres (bound/free)

Consideremos a expressão- : ( x. + x y) 4

Para avaliar esta expressão necessitamos:

• saber o valor “global” de y.

  • não necessitamos saber o valor global de x, pois é o parâmetro formal da função.

• Assim vemos que: x e y possuem um status bastante diferente.

A razão é que x ocorre atado pelo x , é somente um encaixe dentro do qual o argumento 4 é

colocado quando a abstração- for aplicada ao argumento.

Por outr lado, y não é atado por nenhum e assim ocorre livre na expressão.

A ocorrência de uma variável é atada se há uma expressão- envolvente que a amarra, senão

é livre. No exemplo a seguir, x e y ocorrem atados, z porém, ocorre livre:

x. + (( y. + y z) 7) x

Observe que os termos atado e livre se referem a ocorrências específicas da variável em uma expressão.

Uma variável pode possuir tanto uma ocorrência atada como uma livre em uma expressão. Considere o exemplo:

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

Aqui x ocorre livre (a primeira vez) e atada (a segunda). Cada ocorrência individual de uma

variável deve ser ou atada ou livre.

As definições formais de livre a atado são dadas abaixo:

2.2.2. Conversão-Beta

Uma abstração - denota uma função. Assim necessitamos descrever como aplicá-la a um

argumento.

A função ( x. + x 1) 4 é a justaposição do função ( x. + x y) e do argumento 4 e, por conse-

guinte, denota a aplicação de uma certa função, denotada pela abstração- , ao argumento 4.

A regra para a aplicação de uma função é muito simples:

  • O resultado da aplicação de uma abstração- um argumento é uma instância do corpo da

abstração- no qual ocorrências (livres) do parâmetro formal no corpo são repostos pelo argumento.

O resultado de se aplicar a abstração ao argumento é: + 4 1 onde o (+ 4 1) é um instância do corpo (+ x 1) no qual ocorrências do parâmetro formal x foram repostas pelo argumento 4.

Nós escrevemos as conversões utilizando o símbolo como antes:

Definição de ocorre livre:

x ocorre livre em x (mas não em outra variável ou constante qualquer)

x ocorre livre em ( E F ) x ocorre livre em E ou x ocorre livre em F

x ocorre livre em y.E x e y são variáveis diferentes e x ocorre livre em E

Nota: nenhuma variável oorre atada em uma expressão consistindo e uma única constante.

Definição de ocorre atada:

x ocorre atada em ( E F ) x ocorre atada em E ou x ocorre atada em F

x ocorre atada em y. E ( x e y são a mesma variável e x ocorre livre em E ) ou x ocorre atada em E

λ ⇔

λ ⇔

λ

λ λ

λ

λ

λ

Uma instância da abstração x é substituída por f onde quer que f apareça no corpo da

abstração de f.

Nomenclatura:

Nomes de parâmetros formais podem não ser únicos:

( x.( x. + ( - x 1)) x 3) 9 ( x. + (- x 1)) 9 3

+ (- 9 1) 3

11

Observe-se que o x interno não foi substituído na primeira redução, pois estava protegido pelo

x envolvente, ou seja, a ocorrência interna de x não é livre no corpo da abstração

x externa.

Dada uma asbtração- , ( x.E) , é possível identificar-se exatamente as ocorrências de x que

deveriam ser substitídas atraves da identificação de todas as ocorrências de x que estão livres.

Dessa forma, para o exemplo acima, examinamos o corpo da abstração:

( x. + (- x 1)) x 3

e vemos que a segunda ocorrência de x é livre, podendo ser substituída.

A idéia do aninhamento do escopo de variáveis em uma linguagem de programação estruturada é análoga a esta regra.

Outro exemplo:

( x. y.+ x (( x.- x 3) y)) 5 6

( y.+ 5 (( x.- x 3) y)) 6

+ 5 (( x.- x 3) 6)

+ 5 (- 6 3)

8

Novamente, o x mais interno não é substituído, uma vez que não é livre no corpo da abstração mais externa.

λ

λ

λ λ → λ

λ

λ

λ λ

λ

λ λ λ

→ λ λ

→ λ

Exemplo maior: Modelagem de Construtores de Dados

Definimos CONS, HEAD e TAIL da seguinte forma:

CONS = ( a. b. f.f a b)

HEAD = ( c.c ( a. b.a))

TAIL = ( c.c ( a. b.b))

as fórmulas acima obedecem às regras para CONS, HEAD e TAIL definidas anteriormente (Seção 2.1.3). Exemplo:

HEAD (CONS p q) = ( c.c ( a. b.a))(CONS p q)

CONS p q ( a. b.a)

= ( a. b. f.f a b) p q ( a. b.a)

( b. f.f p b)q ( a. b.a)

( f.f p q)( a. b.a)

( a. b.a)p q

( b p) q

p

Isto significa:

  • Não existe necessidade real para as funções embutidas HEAD e CONS ou TAIL.
  • Todas as funções embutidas podem ser modeladas como abstrações-lambda.
  • De um ponto de vista teórico, isto é satisfatório, para efeitos práticos porém, não é utilizado (eficiência).

2.2.3. Conversão-Alfa

Considere:

( x. + x 1) e ( y. + y 1)

Evidentemente elas devem ser equivalentes. A conversão- é o nome dado à operação de

mudança de nome (consistente) de um parâmetro formal.

Notação:

( x. + x 1) ( y. + y 1)

λ λ λ

λ λ λ

λ λ λ

λ λ λ

→ λ λ

λ λ λ λ λ

→ λ λ λ λ

→ λ λ λ

→ λ λ

→ λ

λ λ

α

λ ↔

λ

  • Quando as duas expressões denotam funções, esta prova pode se tornar extremamente longa.

Há porém, métodos para abreviar provas, que não sacrificam o seu rigor. Exemplo :

IF TRUE (( p.p) 3) e ( x. 3)

Ambas as expressões denotam a mesma função, que invariavelmente retorna o valor 3 , não importa o valor de seu argumento e seria de se esperar que ambas sejam interconvertíveis.

Isto realmente ocorre:

IF TRUE (( p.p) 3) IF TRUE 3

( x. IF TRUE 3 x)

( x. 3)

onde o passo final é a regra de redução para IF.

Um método alternativo de se provar a interconvertibilidade de duas expressões, muito mais con- veniente, é o de se aplicar as duas expressões a um argumento w , como:

IF TRUE (( p.p) 3) w ( x. 3) w

( p.p) 3 3

3

Portanto: IF TRUE (( p.p) 3) ( x. 3)

Esta prova tem a vantagem de somente utilizar a redução e de evitar o uso explícito da conver-

são-.

O raciocínio por detrás da generalização da interconvertibilidade acima segue abaixo. Suponha que possamos demonstrar que:

F 1 w E

e

F 2 w E

λ λ

λ (^) ↔

λ

→ λ

λ λ

→ λ →

λ ↔ λ

η

onde w é uma variável que não ocorre livre tampouco em F 1 como em F 2 , e E é alguma expres-

são, então podemos raciocinar da seguinte forma:

F 1 ( w. F 1 w)

( w. E)

( w. F 2 w)

F 2

e por conseguinte F 1 F 2.

Não é sempre que expressões- que “deveriam” dizer a mesma coisa são interconvertíveis.

Isto será tratado mais tarde.

2.2.6. Sumário: Regras de Conversão

Há três regras de conversão que possibilitam a interconversão de expressões envolvendo

abstrações- :

  1. Mudança de nome : a conversão- permite que se troque o nome de parâmetros formais

de uma abstração- , penquanto isto for feito de forma consistente.

  1. Aplicação de funções : A redução- permite a aplicação de abstrações- a um argumen-

toatravés de geração de uma nova instância do corpo da abstração, substituindo o argu- mento por ocorrências livres do parâmetro formal. Cuidado especial deve ser tomado quando o argumento contém variáveis livres.

  1. Eliminação de abstrações- redundantes : A redução- pode as vezes eliminar uma

abstração-.

Dentro deste contexto, podemos considerar as funções embutidas (predefinidas) como mais

uma forma de conversão. Esta forma de conversão recebe o nome de conversão-.

λ

↔ λ

↔ λ

↔ η ↔ λ λ α λ

β λ

λ η

λ

δ

2.3.1. Ordem Normal de Redução

² Uma questão que se coloca, além da questão "poderei encontrar uma forma normal ?", é a questão de se existe mais de uma forma normal para para uma expressão, ou:

Poderá uma seqüência de redução diferente levar a uma forma normal diferente?

Ambas as questões estão interligadas. ² A resposta para a última pergunta é: não. Isto é uma conseqüência dos teoremas de Church-Rosser CRT1 e CRT2.

Teorema de Church-Rosser 1 (CRT1): Se E 1 <-> E 2 , então existe uma expressão E , tal que E 1 -> E e E 2 -> E Corolário: Nenhuma expressão pode ser convertida em duas formas normais distintas. Isto significa que não existem duas formas normais para uma expressão que não sejam a- convertíveis entre si. Prova: Suponha que E 1 <-> E e E 2 <-> E , onde E 1 e E 2 estão na forma normal.

Então E 1 <-> E 2 e, pelo CRT1, deve haver uma expressão F tal que E 1 -> F e E 2 -> F.

Como tanto E 1 como E 2 não possuem redexes, logo E 1 = F = E (^2)

² Informalmente, o teorema CRT1 diz que todas as seqüências de redução que terminam, haverão de atingir o mesmo resultao.

O segundo teorema de Church-Rosser, CRT2, diz respeito a uma ordem particular de redução, chamada ordem normal de redução.

Teorema de Church-Rosser 2 (CRT2): Se E 1 -> E 2 , e E 2 está na forma normal, então existe uma ordem normal de seqüência de redução de E 1 para E 2.

Conseqüências: ² Existe no mínimo um resultado possível e ² a ordem normal de redução encontrará este resultado, caso ele exista. ² Observe que nenhuma seqüência de redução poderá levar a um resultado incorreto, o máximo que poderá acontecer é a não-terminação. A Ordem Normal de Redução especifica que o redex mais à esquerda mais externo deverá ser reduzido primeiro. ²No exemplo anterior ( λ x.3) (D D) , escolheríamos o redex-λx primeiro, não o (D D). ² Esta regra encorpa a intuição de que argumentos para funções podem ser descartados, de forma que deveríamos aplicar a função ( l x.3) primeiro, ao invés de primeiro avaliarmos o argumento (D D).

2.3.2. Ordens de redução ótimas

² Enquanto a ordem normal de redução garante que ou uma solução seja encontrada ou o não-término ocorra, ela não garante que isto ocorra no número mínimo de passos de redução, o que é um fato relevante na utilização do cálculo-l para a implementação de linguagens de programação interpretadas.

² No caso da implementação da resolução através de redução de grafos - que estudaremos mais tarde - porém, aparentemente a ordem normal de redução é "geralmente ótima" em questão de tempo de execução.

Analisar uma expressão para encontrar o redex ótimo para ser reduzido é aparentemente muito mais trabalhoso e gasta mais tempo do que arriscar uma redução com mais passos seguindo "cegamente" a ordem normal.

² Alguns autores como ( Levy, J.J.; Optimal Reductions in the Lambda Calculus in Essays on Combinatory Logic, Academic Press, 1980 ) se ocuparam de algoritmos para encontrar ordens ótimas ou quase-ótimas de redução que preservassem as qualidades da ordem normal de redução. Isto é assunto de um tópico avançado que não cabe nesta disciplina.

2.4. Funções Recursivas

² Se o propósito da utilização de cálculo lambda é a conversão de programas funcionais neste para que possamos resolvê-los, devemos ser capazes de representar uma das características mais marcantes das linguagens funcionais, a recursão.

² O cálculo lambda suporta a representação de recursividade sem maiores extensões através da utilização de alguns pequenos truques.

2.4.1. Funções Recursivas e o Y

² Considere a definição da função fatorial abaixo:

FAC = ( λn.IF (= n 0) 1 (* n (FAC (- n 1 ))))

² Esta definição baseia-se na capacididade de se dar um nome a uma abstração lambda e de fazer referência a esta dentro dela mesma.

² Nenhuma construção deste tipo é provida pelo cálculo lambda.

² O maior problema aqui é que funções lambda são anônimas.

² Dessa forma elas não podem nomear-se e assim não podem se referenciar a si mesmas.

Para resolver este problema iniciamos com um caso onde encontramos a recursão na sua forma mais pura:

FAC = ( λn. ... FAC ... )

² Aplicando uma abstração-b sobre FAC, podemos transformar esta definição em:

FAC = ( λfac.(λn. (...fac...)))FAC

² Esta definição podemos escrever da forma:

FAC = H FAC (2.1)

² onde:

-> * 1 (IF (= 0 0) 1 (* n (Y H(- 0 1)))) -> * 1 1 -> 1

2.4.2. Y pode ser definido como uma Abstração Lambda

² Para a transformação de uma expressão recursiva em uma não-recursiva, utilizamos o combinador de ponto fixo, uma função que chamamos de Y.

² A propriedade que Y necessita ter é: Y H = H (Y H)

² e isto representa evidentemente a recursão da forma mais pura, uma vez que esta fórmula pode ser utilizada para representar, de forma abstrata, qualquer fórmul arecursiva que queiramos.

² O truque é que podemos representar Y como uma abstração lambda sem utilizar a recursão: Y = ( λ h. ( λ x.h (x x)) ( λ x. h (x x)))

Para demonstrar que Y possui a qualidade desejada, evaluemos:

Y H = ( λ h. ( λ x.h (x x)) ( λ x. h (x x))) H <-> ( λ x.H (x x)) ( λ x. H (x x)) <-> H (( λ x.H (x x)) ( λ x. H (x x))) <-> H (Y H)

² O fato de Y poder ser definido como uma abstração lambda é, do ponto de vista matemático, realmente digno de nota.

² Do ponto de vista da implementação, é relativamente ineficiente implementar Y como uma abstração lambda. Para a construção de linguagens funcionais, utiliza-se geralmente uma função embutida com a regra de redução: Y H -> H (Y H)

2.4.3. Exercícios (entregar próxima aula)

I. Redução :

Reduza as seguintes expressões-lambda às suas respectivas formas normais:

((( λf.λx.λy.(x)(f)y)p)q)r

((( λx.λy.λz.(y)x)(x)y)(u)z)y

( λx.(λy.(x)(y)y) λz.(x)(z)(λu.λv.u)w

((( λx.λy.λz.((x)z)(y)z)(λu.λv.u)w)λs.s)t

((( λx.(λz.(x)(y)y)ly.(x)(y)y)λz.λu.λv.(u)(z)v)(λr.λs.r)t)w

( λx.x(xy))N

( λx.y)N

( λx.(λy.xy)N)M

( λx.xx)(λx.xx)

( λx.xxy)(λx.xxy)

( λx.z)((λx.xxy)((λx.xxy))

II. Recursividade :

  1. Dê uma definição recursiva para o maior divisor comum de dois inteiros e calcule o valor de ((mdc) 10) 14) utilizando o combinador Y.
  2. Tente o mesmo para os números de Fibonacci e use Y para computar (Fibo) 5.