CÁLCULO LAMBDA Base da programação funcional e um modelo alternativo de computabilidade. Inventor: Alonzo Church J.M.Barreto INE-CTC-UFSC Modelos de Computabilidade • Máquina de Turing (Alain Turing- 1936) • Lambda cálculo (Alonzo Church - 1936) • Linguagens While (Michael Arbib-1982) Alan Turing provou em 1937 a equivalência entre uma Máquina de Turing e o Cálculo Lambda em termos de computabilidade J. M. Barreto UFSC_INE A. Church, Washington1903 Doutor pela Universidade de Princepton. Após seu doutoramento foi para Harvard trabalhar com Birkhoff e Huntington. E foi nesta época em que Birkhoff e ele tiveram discussões que resultaram na Teoria das Categorias como a conhecemos hoje. Trabalhou até 1990 quando com oitenta e sete anos parou de dar aulas mas continuou a orientar alguns pesquisadores selecionados, Turing tendo sido um de seus doutorandos. J. M. Barreto UFSC_INE Programaçãp Funcional (1/2) • A maioria das Linguagens de Programação Funcional são semelhantes e diferem somente em aspectos sintáticos. O Cálculo lambda pode ser considerado como a ferramenta mais adequada a escrever programas usando o paradigma funcional. Neste paradigma, em que a solução de um problema é considerada como sendo implementar uma função, usa nesta implementação um conjunto de primitivas e regras de construir novas funções a partir destas primitivas. J. M. Barreto UFSC_INE Programação Funcional (2/2) • Interessantes pela sua simplicidade sintática • Facilidade de escrever problemas recursivos. • Maioria das implementações são poucos aceitas devido à ineficiência em comparação com linguagens de programação comuns. • Novas implementações de interpretadores e/ou compiladores e novas linguagens mais modernas tem surgido. J. M. Barreto UFSC_INE Exemplos de Linguagens Funcionais - LISP (LISt Processing - década de 60). Muito simples em muitos aspectos. É a mais utilizada devendo continuar por muito tempo. - Miranda (Turner 1985) - Haskell (1990) - Orwell (Wadler 1985) - Outras: ML, KRC, LML, SASL. J. M. Barreto UFSC_INE Sintaxe do Cálculo Lambda O cálculo lambda pode ter sua sintaxe definida como um sistema formal. J.M.Barreto INE-CTC-UFSC Termos do Cálculo Lambda • A linguagem do cálculo lambda usa um alfabeto S constituído de: • - um conjunto de variáveis: vo, v1, v2,....vn.... • - abstrator l (lambda) • - agrupadores (,) • Ao conjunto de cadeias finitas sobre S denota-se por S* e a cadeia que não contem elementos por e. Usam-se as variáveis x, y, z, ... para denotar cadeias de S* J. M. Barreto UFSC_INE Cadeias de Símbolos: definições • Definição (Equivalência de duas cadeias) • Duas cadeias x e y são equivalentes e se escreve (x,y) Eq x = y • Definição (Comprimento de uma cadeia) • É uma função: • : S* Z+ • em que o número inteiro exprime o número de elementos da cadeia. J. M. Barreto UFSC_INE Termo Lambda: definição • Um termo lambda, denotado pelas letras M, N, O, P,.. é um elemento da linguagem L, onde S* L definido da seguinte forma: • - vi é termo lambda; • - dado M, (lvi M) é termo lambda; • - dados dois termos lambda M, N então (MN) é termo lambda; • - e nada mais é termo lambda. J. M. Barreto UFSC_INE Exemplos de Termos lambda • Verificar quais das expressões abaixo são termos lambda, justificando sua resposta: • vo • (vov1) • (vo) • (lvo(vov1)) • (lv1(vo(lv1(vov1)))) • (lvo(vov1) J. M. Barreto UFSC_INE Notacão Lambda Simplificada • 1-Precedência a esquerda. ((MN)L) MNL • 2-Sucessão de abstratores: • Assim (lx(ly(lz........))) lxyz... • 3-Separador: usa-se um ponto para designar o final de uma lista de argumentos lambda • Assim lx.xly.y (lx(x(ly.y))) • 4-Supõe-se que letras diferentes designam entidades diferentes. • Assim x y em lx.y J. M. Barreto UFSC_INE Semântica Operacional do Cálculo l Até agora foi descrita a sintaxe do cálculol. Sua semântica operacional diz como um programa Lambda opera, isto é, calcula. J.M.Barreto INE-CTC-UFSC O Porque da Semântica: • Para chamá-lo de "cálculo'', deve-se porém dizer como "calcular'' com ele. Basicamente isto é realizado através de três regras de conversão, que descrevem como converter uma expressão-l em outra que lhe seja equivalente. • Mostra também como se introduzem os argumentos a serem usados como dados do programa. J. M. Barreto UFSC_INE Programa Lambda • Um programa Lambda se escreve como um conjunto de expressões lambda. Normalmente, usando notação simplificada encontra-se o símbolo lambda seguido de lista de variáveis. limitando estas variáveis vem um ponto ".'' seguido pelo corpo da função. As variáveis são chamadas de parâmetros formais e diz-se que o lambda os liga. Exemplo: lxy.(+ x y) J. M. Barreto UFSC_INE Programa Lambda • Os dados são escritos logo depois da função lambda, como uma lista e são consumidos durante a operação do programa. • Exemplos: – > (lxy. (y x)) dia bom – > (lxy. (+ x y)) 3 6 – > (lxy. (x y z)) 3 1 4 5 J. M. Barreto UFSC_INE Executar Programa Lambda • Para executar um programa lambda é suficiente dar valores às variáveis lambda. Assim tem-se: • lxy.(+ x y) 3 4 • ly.(+ 3 y) 4 • (+ 3 4) • 7 • Nota: geralmente operadores são pré-fxados. Isto na realidade é uma conversão de uma expressão em uma mais simples. Há 3 tipos de conversão. J. M. Barreto UFSC_INE Funções embutidas • Funções embutidas como + não existem no cálculo lambda na sua forma mais pura. Para fins práticos, uma extensão que as suporte é útil. Estas incluem funções aritméticas (como +, -, *, /), constantes (como 0, 1,...), funções lógicas (como E, OU, NÃO,...), constantes lógicas (VERDADE, FALSO), manipulação de listas (PRIMEIRO, CAUDA, CONSTRUA, IGUAL) e reconhecedoras de listas (ATOM). J. M. Barreto UFSC_INE Avaliação de programa lambda • A avaliação ocorre através da seleção repetida de uma expressão redutível (redex) e de sua redução. Expressão redutível é aquela que pode ser avaliada imediatamente. No exemplo : • (+ (* 5 6) (* 8 3)) • Que são: (* 5 6) e (* 8 3) • A escolha do primeiro redex para redução fornece: • (+ (* 5 6) (* 8 3)) -> (+ 30 (* 8 3)) • Do qual resulta: J. M. Barreto UFSC_INE (+ 30 24) -> 54 Regras de Conversão • Introdução à l-conversão: Variáveis atadas e livres • Conversão-Alfa () • Conversão-Beta (ß) • Conversão-Eta () • Provas de Interconvertibilidade J. M. Barreto UFSC_INE Variáveis atadas e livres(1/2) • Seja a expressão-l: (lx. + x y) 4 • Para avaliar esta expressão é necessário: • saber o valor "global'' de y. • não é necessário saber o valor global de x, pois é o parâmetro formal da função. • x ocorre atado pelo lx, y não é atado por nenhum e assim ocorre livre na expressão. J. M. Barreto UFSC_INE Variáveis atadas e livres (2/2) • .A ocorrência de uma variável é atada se há uma expressão-l envolvente que a amarra, senão é livre. • No exemplo a seguir, x e y ocorrem atados, z porém, ocorre livre: • lx. + ((ly. + 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. Note ainda que x é atado mas não sabe-se seu valor para calcular a expressão-l. J. M. Barreto UFSC_INE Conversão Alfa • Usa a -congruência: duas expressões-l M e N são -congruentes (ou -equivalentes), denotado por M N se ou • M = N ou • MN, ou • N é obtido de M através da reposição de uma subexpressão S de M por uma expressão-l T tal que S T, ou existe alguma expressão-l, R tal que M R e R N. J. M. Barreto UFSC_INE Conversão Alfa: exemplos Exemplo 1: Nomes de parâmetros formais podem não ser únicos: (lx.( lx. + (- x 1)) x 3) 9 (lx. + (- x 1)) 9 3 + (- 9 1) 3 11 J. M. Barreto UFSC_INE Exemplo 2: (lxy.+ x ((lx.- x 3) y)) 5 6 (ly.+ 5 ((lx.- x 3) y)) 6 + 5 ((lx.- x 3) 6) + 5 (- 6 3) 8 Conversão Alfa: exemplos Exemplo 3: (lx. (ly. - y x)) 4 5 (ly. - y 4) 5 -54 1 J. M. Barreto UFSC_INE Exemplo 4: Crie um exemplo semelhante aos 3 anteriores. Conversão beta • Conversão beta consiste na substituição de uma variável ligada pelo valor que foi justaposto `a definição da função. • Exemplo: (lx. + x 1) 4 +41 5 J. M. Barreto UFSC_INE Conversão Beta • O parâmetro formal pode ocorrer várias vezes no corpo: • (lx. + x x) 5 • +55 • 10 • Pode não haver ocorrências do parâmetro formal no corpo. Ex: • (lx. 3) 5 3 • Nada a converter! Uma variável pode possuir tanto uma ocorrência atada como uma livre em uma expressão. Considere o exemplo: + x ((lx. + x 1) 4) Aqui x ocorre livre (a primeira vez) e atada (a segunda). J. M. Barreto UFSC_INE Conversão eta • Sejam: (lx. + 1 x) e (+ 1). Estas expressões se comportam exatamente da mesma maneira, quando aplicadas a um argumento: ambas adicionam 1 ao argumento. Conversão-z é o nome dado à regra que expressa essa equivalência. Assim: (lx. + 1 x) -> (+ 1) Formalmente: (lx. F x) -> F desde que x não ocorra livre em F e F denote uma função. J. M. Barreto UFSC_INE Conversão eta A condição de que x não deve ocorrer livre em em F previne conversões errôneas. Exemplo: (lx. + x x) não é e-conversível para (+ x) pois x ocorre livre em (+ x). Os dois x são ligados. Assim: • (lx. + x x) 5 ( + 5 5) 10 J. M. Barreto UFSC_INE Teorremas de Church-Rosser J. M. Barreto UFSC_INE Teoremas de Church-Rosser 90 80 70 60 50 East West North 40 30 20 10 0 1st Qtr J. M. Barreto UFSC_INE 2nd Qtr 3rd Qtr 4th Qtr Teoremas de Church-Rosser J. M. Barreto UFSC_INE Funções Recursivas • No Cálculo lambda as funções não tem nomes. • Cálculo lambda é a base da programação funcional. • Um dos mecanismos mais importantes usados em programação funcional é a recursividade. • Recursividade exige que se nomeie funções para que possam ser referenciadas. • E agora? (Fico vermelho de vergonha!) J. M. Barreto UFSC_INE Recursividade: exemplo introdutório • Suponha existir a primitiva SE com duas direções e seja a abstração: • (lxn. SE (= n 0) (1) (* n x (-n 1))) • Vamos dar o nome de FAC à aplicação desta abstração à FAC; tem-se: • FAC = (lxn. SE (= n 0) (1) (* n x (-n 1))) FAC = (ln. SE (= n 0) (1) (* n FAC (-n 1))) • Que é a definição recursiva desejada. J. M. Barreto UFSC_INE Transformação ao inverso Se já fosse disponível a definição recursiva: • Seja F = (lx …. F….) • Usando Transformação ao contrário: • F = (lf … (lx . f….))F • Ou: F = H F onde H = (lf … (lx . f….)) F é dito ponto fixo de H J. M. Barreto UFSC_INE Combinador de Ponto Fixo Para isto, invente-se, a título provisório, uma função Y, a qual toma uma função como argumento e devolve o seu ponto fixo como resultado. Logo será: YH = F Substituindo F por YH em F = H F tem-se: YH = H (YH) Esta é uma definição não recursiva de F! J. M. Barreto UFSC_INE Exercício: Fac 1 • • • • • • • • • • • • • FAT = Y H onde: H = (lfat. l n. SE (= n 0) 1 (* n (fat (- n 1)))) Assim: FAT 1 Y H 1 H (Y H) 1 (lfat. ln.SE (= n 0) 1 (* n (fat (- n 1))))(Y H) 1 (l n.SE (= n 0) 1 (* n (Y H (- n 1)))) 1 SE (= 1 0) 1 (* 1 (Y H (- 1 1))) * 1 (Y H 0) = * 1 (H (Y H) 0) = * 1 ((lfat.ln.SE (= n 0)1(* n(fat(- n 1))))(Y H) 0) * 1 ((ln.SE (= n 0) 1 (* n (Y H (- n 1)))) 0) * 1 (SE (= 0 0) 1 (* n (Y H(- 0 1)))) 1 J. M. Barreto UFSC_INE Exercícios (Redução) J. M. Barreto UFSC_INE Exercícios (Recursividade) J. M. Barreto UFSC_INE E se estas coisas fossem usadas em uma linguagem real? Esta linguagem existe e é LISP! LISP é linguagem velha: tem 40 anos... Mas LISP se mantem jóvem pois LISP é estensível, suporta programação objeto e icônica! J. M. Barreto UFSC_INE Noções de lisp Lisp: LISp Processing J.M.Barreto INE-CTC-UFSC Qual a razão de conhecer LISP? • Segundo McDermot e Charniac a razão ér a mesma de aprender francês se vai estudar na França: é a lingua natural falada pelos franceses! • Será isto ainda verdade? –Nem tanto, mas... Será a Programação Funcional? J. M. Barreto UFSC_INE Razões para usar LISP (1/4) • LISP é uma linguagem funcional pobre, mas raros são os profissionais de IA que escolhem LISP por suas características funcionais. Exatamente por esta razão ela é pobre em termos funcionais: juntam-se outras facilidades que mascaram o estilo funcional puro! J. M. Barreto UFSC_INE Razões para usar LISP (2/4) • LISP é estensível e se não se gosta de um interface oferecido é fácil criar outro. • LISP tem programa e dados com a mesma estrutura de dados: listas. Logo, um programa pode facilmente ler a ele mesmo, modificar-se durante a execução e continuar funcionando modificado sem interrupção: isto é, torna-se fácil implementar algoritmos de aprendizado. J. M. Barreto UFSC_INE Razões para usar LISP (3/4) • Estruturas de dados são facilmente manipuladas em LISP. • Por exemplo: – A pilha é a própria lista; – Existem primitivas para ler, juntar novo elemento na pilha, etc. – Árvores são implementadas como listas de listas., s3endo fácil percorrê-las e modificá-las. J. M. Barreto UFSC_INE Razões para usar LISP (4/4) • É fácil aprender LISP e seu aprendizado ajuda a desenvolver capacidades mentais. Foi exatamente acreditando nisto que Papert, criou no MIT a linguagem LOGO, subconjunto de LISP, com ênfase gráfica, para uso do aprendizado de crianças. As experiências tem sido animadoras. E como nasceu esta linguagem? J. M. Barreto UFSC_INE Lisp: Nota histórica (1/3) • John McCarthy vinha trabalhando há anos em uma linguagem que fosse, como provado por Turing, equivalente à sua máquina. Em 1960, dando aula no MIT demonstrou que a função “eval” era capaz de simular a máquina de Turing, resultado teórico de grande valor. J. M. Barreto UFSC_INE Lisp: Nota histórica (2/3) • Um dos alunos de John McCarthy, Steve Russel comentou: “sendo verdade este teorema, basta implementar “eval” e teremos a Máquina de Turing”, ao que McCarthy contestou “Não confunda teoria com prática, este é um resultado teórico, para ter valor prático tem de percorrer um longo caminho”. J. M. Barreto UFSC_INE Lisp: Nota histórica (3/3) • Russel não se satisfez. Implementou “eval” e algumas outras funções em Máquina IBM704, apresentou seu trabalho e assim nasceu Lisp, linguagem fruto do espírito prático de aluno com grande conhecimento teórico. Guarda ainda hoje lembranças do passado: car: “contents of address register; cdr: “contents of decrement register; • Símbolos do assembler do IBM704. J. M. Barreto UFSC_INE Sintaxe de Lisp • Vocabulário de Lisp: • Atomos: elementos indivisíveis, podendo ser: – Números; ex: 1, 13, 15, -.35, etc. – Identificadores: sequencias de letras e números; ex: Lisa, Jane1, fibo, etc. – Identificadores reservados: +, -, /, *, car, cdr, etc. • Delimitadores: (,) J. M. Barreto UFSC_INE Sintaxe de Lisp • Linguagem Lisp: – Lisp* = atom | lista – Atom = identificador | identificador reservado | número – Lista = (atom) | (atom lista) J. M. Barreto UFSC_INE Lisp Puro • Lisp Puro contem as seguintes funções primitivas: – – – – Car primeiro elemento de uma lista; Cdr: o que sobra de uma lista tirando o 1º elemento Cons: constroi lista dado um elemento e uma lista; Eql: retorna T se os dois elementos que se seguem são iguais, NIL no caso contrario; – Atom: retorna T se elemento que o segue é atomico, NIL em caso contrário. J. M. Barreto UFSC_INE Semantica operacional de Lisp Puro Seletores: car, cdr – – – – > (car ´(a d f)) >A > (cdr ´(a s d f g)) > (s d f g) Construtor: – > (cons ‘a ‘(s d f g)) – > (a s d f g) J. M. Barreto UFSC_INE Predicado atômico: – – – – > (atom ‘jane) >T > (atom ‘(a s d f g)) > NIL Predicado egalitário – – – – > (eql ‘casa ‘casa) >T > (eql 10 20) > NIL Assignação e valor de atomo • (set ‘a 10) A • (setq b 20) B • B 20 • ‘B B • (atom ‘b) T • (atom b) T J. M. Barreto UFSC_INE • (setq c ‘(a s d)) C • C (a s d) • (car c) A • (cdr c) (s d) • (atom c) NIL • (atom ‘c) T Manipulação de listas; exemplos • (setq ‘v ‘(e i o u)) V • (cons ‘a v) (a e i o u) • (car ‘(q w e r t)) Q • (cdr ‘(q w e r t)) (w e r t) • (cdr (car v)) nil J. M. Barreto UFSC_INE • (car (cdr (cdr ‘(a s d f g)))) D • (caddr ‘(a s d f g)) D • (atom v) Nil • (eql ‘v ‘v) T • (eql ‘v v) nil Operações aritméticas • (+ 2 3 4 5) 14 • (+1 2) 3 • (*2 3) 6 • (* 2 3 4 ) 24 J. M. Barreto UFSC_INE • (* (+ 2 3) (+ 1 2 3)) 30 • (* 2 (* 5 6 3) 2) 360 • e assim não é preciso chamar a calculadora do computador... Novas Funções • (defun nome-da-função (variáveis ligadas) (corpo da definição)) • Corpos: – Cond – Program – if J. M. Barreto UFSC_INE Exemplos de novas funções • Encontra o segundo elemento de uma lista: (defun segundo (lista) (cadr lista)) • Calcula o fatorial de um número: (defun fat (n) (cond (( > n 0) (‘Numero negativo não tem fatorial’)) (( = n 0) 1) (( = n 1) 1) (T (fat (- n 1))))) J. M. Barreto UFSC_INE • Lê uma lista até um elemento dado retornando o que sobra: (defun resto (lista elemento) (cond ((eql (car lista) elemento) cdr lista) (T (resto ((cdr lista) elemento ))))) J. M. Barreto UFSC_INE Exercícios • Escreva 2 funções Lisp para juntar novos telefones e consultar uma lista de nomes e de telefones. Sugestão: use como estrutura de dados uma lista de pares, (nome telefone) J. M. Barreto UFSC_INE • Sabendo que sua verão de Lisp usa > e < para ordem alfabética, escreva função Lisp para colocar em ordem um lista de nomes. • E se fosse a lista de endereços do exercício anterior? Que faço com isso tudo? Jogou! J. M. Barreto UFSC_INE • Não! • Não jogue o pobre cálculo l no lixo! • Ele é a base das linguagens funcionais e de Lisp, que apesar de todas as suas impurezas vale o estudo!