Cálculo Lambda Sem Tipos - Inf

Propaganda
Cálculo Lambda Sem Tipos
Cálculo lambda sem tipos
• Peter Landin (60’s) observou que uma linguagem de
programação pode ser compreendida formulando-a em um
pequeno núcleo capturando suas características essenciais
• outras formas, chamadas de formas derivadas, podem ser
compreeendidas traduzindo-as para o núcleo
• linguagem núcleo usada por Peter Landin foi o cálculo
lambda
Cálculo Lambda Sem Tipos
UFRGS-2007
p.2/33
Cálculo lambda sem tipos
• Cálculo λ inventado por Alonzo Church na década de 20
• toda computação pode ser reduzida a operações básicas de
definição de função e aplicação de função
• computacionalmente completo
Cálculo Lambda Sem Tipos
UFRGS-2007
p.3/33
Cálculo lambda sem tipos
• LISP (John McCarthy, 50’s) foi implementada baseada no
cálculo lambda
• cálculo λ largamente utilizado na especificação, projeto e
implementação de linguagens de programação
• pode ser visto como uma linguagem de programação
simples
• e, ao mesmo tempo, é um objeto matemático sobre o qual
podemos fazer afirmações precisas que podem ser provadas
Cálculo Lambda Sem Tipos
UFRGS-2007
p.4/33
Outros cálculos
• CCS (Milner) - concorrência
• Cálculo π (Milner, Parrow e Walker) - concorrência e
mobilidade
• Cálculo de objetos (Abadi e Cardeli) - para orientação a
objetos
• vários outros cálculos ...
• técnicas utilizadas com cálculo λ podem ser utilizadas
também com esses outros cálculos
Cálculo Lambda Sem Tipos
UFRGS-2007
p.5/33
Conceitos básicos
Abstração funcional (ou procedural) é freqüente em praticamente
todas as linguagens de programação. A seqüência de
computação repetitiva abaixo
(succ succ 5) + (succ succ 3) − (succ succ 2)
pode ser reescrita na forma
add2(5) + add2(3) − add2(2)
onde
add2(x) = succ succ x
Cálculo Lambda Sem Tipos
UFRGS-2007
p.6/33
Cálculo λ
add2 é simplesmente um nome dado para
"função que dado argumento x, retorna x mais dois
λx. succ succ x".
Esta função existe independente do seu nome e pode ser escrita
como:
λx. succ succ x
Cálculo Lambda Sem Tipos
UFRGS-2007
p.7/33
Cálculo λ
Na sua forma pura, tudo é função
• argumentos aceitos por funções são funções
• resultado retornado por uma função também é uma função
Sintaxe Abstrata do cálculo λ:
t ::=
termos:
x
variável
λx.t abstração
tt
Cálculo Lambda Sem Tipos
aplicação
UFRGS-2007
p.8/33
Sintaxe abstrata e concreta
Gramática anterior descreve a sintaxe abstrata, ou seja descreve
termos lambda como árvores.
Quando representadas linearmente podem surgir ambigüidades.
Que termo (que árvore de sintaxe abstrata), por exemplo,
corresponde a
xyz ?
Ambiguidade na representação linear de árvore é resolvida:
• usando parênteses, e adotando convenções que permitam
reduzir o seu uso, ou
• adotando uma representação linear que evite tais
ambiguidades (expressões S)
Cálculo Lambda Sem Tipos
UFRGS-2007
p.9/33
Sintaxe Abstrata
Como resolver a ambigüidade que surge na interpretação de
xyz ?
• há uma convenção pela qual aplicação é associativa a
esquerda.
• logo o termo acima tem a mesma interpretação de (x y) z
• usando notação S ele seria escrito na forma
app(app(x , y), z ) por exemplo
Cálculo Lambda Sem Tipos
UFRGS-2007
p.10/33
Sintaxe Abstrata
Como resolver a ambigüidade que surge na interpretação de
λx.λy.x y z
• convenção diz que abstrações lambda se extendem o mais a
direita possível, ou seja,
• o termo acima corresponde a λx.(λy.((x y) z))
• que, usando notação S, ficaria, por exemplo, na forma
abs(x , abs(y, app(app(x , y), z )))
Cálculo Lambda Sem Tipos
UFRGS-2007
p.11/33
Escopo de variáveis
Ocorrência de x é dita ligada quando ocorre no corpo de uma
abstração λx.t. Uma ocorrência de x é livre se não é ligada.
Exemplos:
• ocorrências de x nos termos x y e λy.x y são livres
• ocorrência de x nos termos λx.x e λx.λy.x (y z) são
ligadas
• em (λx.x) x a primeira ocorrência de x é ligada e a
segunda é livre
Termo é fechado se não possui variáveis livres. Também é
chamado de combinador
Cálculo Lambda Sem Tipos
UFRGS-2007
p.12/33
Semântica operacional
Computação consiste basicamente em aplicar função a
argumento: (λx.t1 ) t2 −→ [x 7→ t2 ] t1
A notação
[x 7→ t2 ]t1
representa o termo que resulta da substituição das ocorrências
livres de x em t1 pelo termo t2 .
Por exemplo:
• o termo (λx. x) y é avaliado para y
• o termo (λx. x (λx.x)) (u r) é avaliado para (u r) (λx.x)
Termo na forma (λx.t1 ) t2 é chamado redex
Cálculo Lambda Sem Tipos
UFRGS-2007
p.13/33
Semântica Operacional
Existem diversas estratégias para avaliar um termo lambda. Cada
uma diz a ordem na qual redexes devem ser avaliados.
Considere o termo (λx.x) ((λx.x) (λz.(λx.x) z)). Chamando
λx.x de id, por clareza, podemos escrevê-lo na forma
id (id (λz.id z))
Esse termo tem 3 redexes (aparecem sublinhados abaixo):
id (id (λz.id z))
id (id (λz.id z))
id (id (λz.id z))
Cálculo Lambda Sem Tipos
UFRGS-2007
p.14/33
Redução β completa
Redução β completa: qualquer redex pode ser escolhido. Uma
seqüência possível de redução é a seguinte:
id (id (λz.id z))
−→ id (id (λz.z))
−→ id (λz.z)
−→ λz.z
6−→
Cálculo Lambda Sem Tipos
UFRGS-2007
p.15/33
Ordem normal
Ordem normal: preferência pelo redex mais externo, mais a
esquerda. Única seqüência de redução possível:
id (id (λz.id z))
−→ id (λz.id z)
−→ λz.id z
−→ λz.z
6−→
Cálculo Lambda Sem Tipos
UFRGS-2007
p.16/33
Call by name
Chamada por nome ou call by name: como ordem normal, mas
não avalia o corpo de uma abstração lambda. Única seqüência
possível:
id (id (λz.id z))
−→ id (λz.id z)
−→ λz.id z
6−→
Cálculo Lambda Sem Tipos
UFRGS-2007
p.17/33
Call by value
Chamada por valor call by value. Só avalia redexes mais
externos e redex só é reduzido se seu lado direito já estiver
totalmente reduzido. Usado pela maioria das linguagens
id (id (λz.id z))
−→ id (λz.id z)
−→ λz.id z
6−→
Cálculo Lambda Sem Tipos
UFRGS-2007
p.18/33
Estratégias estritas X estratégias não estritas
• Estritas: argumentos de funções são sempre avaliados
(mesmo que não sejam utilizados). Call by value é estrita
• Não estritas, também chamadas de lazy: somente avalia
argumentos que são realmente utilizados. Call by name é
não estrita
Cálculo Lambda Sem Tipos
UFRGS-2007
p.19/33
Semântica Operacional - call by value
v ::= λx. t
(λx.t) v −→ [x 7→ v] t
t1 −→ t′1
(β)
(A PP 1)
t1 t2 −→ t′1 t2
t2 −→ t′2
(A PP 2)
v t2 −→ v t′2
Cálculo Lambda Sem Tipos
UFRGS-2007
p.20/33
Múltiplos argumentos
Até agora todas as funções são de um único argumento. Como
representar funções de dois, ou mais argumentos?
Usando funções de alta ordem, ou seja funções que podem
retornar funções como resultado
• no lugar de λ(x, y).t usamos λx.λy.t
• se f = λx.λy.t, ao invés de f (a, b) escrevemos (f a) b
Transformação de função de vários argumentos em função de
alta ordem é chamada de currificação em homenagem a Haskell
Curry (contemporâneo de Church)
Cálculo Lambda Sem Tipos
UFRGS-2007
p.21/33
Booleanos de Church
Codificação de booleanos
• tru = λt.λf. t
• fls = λt.λf. f
Definindo condicional na forma: test = λl. λm. λn. (l m) n
temos que:
• test tru v w
retorna v
• test fls v w
retorna w
Cálculo Lambda Sem Tipos
UFRGS-2007
p.22/33
Pares
Usando booleanos:
• pair
= λf. λs. λb. b f s
• fst
= λp.p tru
• snd
= λp.p fls
Reduzir o termo
fst (pair v w)
Cálculo Lambda Sem Tipos
UFRGS-2007
p.23/33
Numerais de Church
• c0 = λs.λz. z
• c1 = λs.λz. s z
• c2 = λs.λz. s s z
• c3 = λs.λz. s s z
• ...
Cálculo Lambda Sem Tipos
UFRGS-2007
p.24/33
Operações aritméticas
• scc
= λn.λs.λz. s (n s z)
• plus
= λm.λn.λs.λz.m s (n s z)
• times
= λm.λn.m (plus n) c0
• iszro
= λm.λn (λx fls ) tru
• ...
Cálculo Lambda Sem Tipos
UFRGS-2007
p.25/33
Recursão
• a prova de que o cálculo lambda é computacionalmente
completo consiste em provar que o poder de expressão da
linguagem é igual ao de máquinas de Turing (ou ao da
linguagem das funções recursivas, ou outro formalismo
equivalente)
• o que fizemos foi mostrar como programar algumas
funções e valores tais como valores verdade, números
inteiros, condicionals, sucessor, predecessor, soma, etc
• para ser computacionalmente completo deve ser possível
programar comportamento repetitivo!
• no cálculo lambda puro se obtém repetição com recursão!
Cálculo Lambda Sem Tipos
UFRGS-2007
p.26/33
Recursão no cálculo lambda puro
• alguns termos no cálculo lambda puro não podem ser
avaliados para formas normais:
omega = (λx. x x) (λx. x x)
• reduzindo esse redex obtemos ômega novamente !
• avaliação de omega exibe um comportamento repetitivo
• dizemos que termos sem forma normal divergem
Cálculo Lambda Sem Tipos
UFRGS-2007
p.27/33
Recursão no cálculo lambda puro
• o termo abaixo, chamado combinador de ponto fixo (ou
combinador Y call-by-value), pode ser usado para definir
funções recursivas
fix = λf. (λx. f (λy. x x y)) (λx. f (λy. x x y))
• podemos dizer que é uma versão "melhorada” de omega
• difícil de entender por si só, o melhor é entender a forma
como ele é usado
Cálculo Lambda Sem Tipos
UFRGS-2007
p.28/33
Recursão no cálculo lambda puro
A função fatorial pode ser definida da seguinte forma:
g = λfct. λn. if realeq n c0 then c1 else (times n (fct (prd n)))
fatorial = fix g
fatorial pode ser usado da seguinte forma
fatorial c3
Cálculo Lambda Sem Tipos
UFRGS-2007
p.29/33
Extendendo o cálculo λ
• toda programação pode ser feita a partir do cálculo λ puro
• mais conveniente trabalhar com cálculo λ extendido com
outros termos
Cálculo Lambda Sem Tipos
UFRGS-2007
p.30/33
Formalidades
D EFINIÇÃO 1 O conjunto de variáveis livres de um termo t,
denotado por FV (t), é definido como segue
FV (x)
= {x}
FV (lambdax.t) = FV (t) {x}
FV (t1 t2 )
Cálculo Lambda Sem Tipos
= FV (t1 ) ∪ FV (t2 )
UFRGS-2007
p.31/33
Formalidades
Substituição de variável livre no corpo de função é o mecanismo
usado para passagem de argumento. Ela deve ser definida com
cuidado, caso contrário ela pode ter como efeito indesejável a
mudança do comportamento da função.
Temors que diferem somente no nome de variáveis ligadas
são equivalentes
[x 7→ s]x
= s
[x 7→ s]x
= y
y 6= x
[x 7→ s](λy.t1 ) = λy. [x 7→ s]t1
x 6= y e y 6∈ FV (s)
[x 7→ s](t1 t2 ) = [x 7→ s]t1 [x 7→ s]t2
Cálculo Lambda Sem Tipos
UFRGS-2007
p.32/33
Referências
O capítulo 5 de TPL - Bejnamim Pierce tem o necessário para a
disciplina. Mais sobre cálculo lambda sem tipo em
• The Lambda Calculus - Henk Barendregt, 1984.
Compêndio sobre cálculo lambda.
• A seção 2 de Lambda calculi with types - Henk Barendregt
(no capítulo II do Handbook of Logic in Computer Science
disponível também no site da disciplina) é sobre cálculo
lambda sem tipos
Cálculo Lambda Sem Tipos
UFRGS-2007
p.33/33
Download