• Nenhum resultado encontrado

Redução-β em Prolog SN :? N : M. Det :?

N/A
N/A
Protected

Academic year: 2021

Share "Redução-β em Prolog SN :? N : M. Det :?"

Copied!
10
0
0

Texto

(1)

Redução-β em Prolog

Luiz Arthur Pagani (UFPR)

Resumo

Apresenta-se aqui uma nova implementação em Prolog para a operação de redução-β, parte do cálculo-λ importante para a semântica composicional, e que não apresenta o mesmo defeito das implementações de Pereira & Shieber e de Blackburn & Bos (em ambas, as variáveis ligadas pelo operador-λ acabam instanciadas com constantes, o que inviabiliza a manutenção do histórico derivacional das reduções).

1 Introdução

O cálculo-λ é uma ferramenta indispensável para a construção da representação compo-sicional da interpretação semântica de uma expressão linguística desde, pelo menos, o advento da Semântica de Montague (como podemos perceber facilmente em manuais de semântica formal, como [7, ps. 98110], [3, p. 112149], [8, p. 3439], [5, ps. 391429]; e também em manuais de linguística computacional, como [6, ps. 6465] e [1, ps. 265267]). Neste contexto, o cálculo-λ é usado, por exemplo, para identicar uma fórmula (um termo-λ) que represente o signicado do item lexical todo, em todo menino corre, de forma que ela colabore composicionalmente na representação do signicado daquela sentença; além disso, é possível unicar a representação do signicado dos quanticadores com a dos nomes próprios (chamada de quanticação generalizada, onde a denotação de ambas as fórmulas correspondem a conjuntos de conjuntos).

Considerando que o signicado de todo menino corre seja representado pela clássica fórmula do cálculo de predicados ∀x.[(M x) → (C x)], e que os signicados de menino e corre também correspondam, respectivamente, aos clássicos predicados M e C,1 podemos

nos perguntar, primeiro, pela representação do signicado do SN e, depois, pela do Det todo, como esquematizado na árvore abaixo.

S : ∀x.[(M x) → (C x)] SN :? Det :? todo N : M menino SV : C V : C corre

Começando pelo SN, sabemos que o signicado da sentença é ∀x.[(M x) → (C x)] e que o do SV é C, podemos abstrair o segundo do primeiro, através do cálculo-λ (de

Email: [email protected], página de internet: http://www.ufpr.br/arthur.

1Esses predicados podem ser compreendidos como conjuntos de indivíduos (o de meninos, no primeiro

caso; e o dos que correm, no segundo), mas também podem ser pensados como funções que levam de indivíduos a valores de verdade (as chamadas funções características); como estas opções são equivalentes,

(2)

acordo com sua apresentação, como veremos a seguir), e chegamos à conclusão de que o signicado do SN pode ser representado por λP.∀x.[(M x) → (P x)]. A seguir abstraímos deste signicado a parte correspondente ao N, e obtemos a fórmula λQ.λP.∀x.[(Q x) → (P x)], que representa nalmente o signicado do Det todo. Assim, podemos reconstruir composicionalmente a árvore acima da seguinte maneira:2

todo menino corre

Det : λQ.λP.∀x.[(Q x) → (P x)] N : M V : C

SN : (λQ.λP.∀x.[(Q x) → (P x)] M ) =red.β λP.∀x.[(M x) → (P x)]

S : (λP.∀x.[(M x) → (P x)] C) =red.β ∀x.[(M x) → (C x)]

O leitor perspicaz terá observado que, na derivação acima, o signicado do SN passa a ser uma função, que toma o signicado do SV como argumento (que também é uma função, o que faz da representação do signicado do SN uma função de segunda ordem) para resultar no signicado da sentença; mas isso é o oposto do que acontece tradicional-mente na explicação de uma sentença como Pedro corre, em que o SV é que corresponde à função que toma o signicado do SN como argumento. No entanto, com o cálculo-λ isso deixa de ser um problema: supondo que o signicado de Pedro seja representado por p (o indivíduo que é o próprio Pedro), basta promovê-lo para λP.(P p), para podermos usar o mesmo procedimento anterior, em que o signicado do SN é a função e o do SV é o argumento, como na árvore a seguir.

Pedro corre

N : p V : C

SN : λP.(P p) SV : C

S : (λP.(P p) C) =red.β (C p)

Como recurso formal, uma representação através do cálculo de predicados acrescido do cálculo-λ é especialmente adequada para a construção composicional da interpreta-ção semântica das expressões executada computacionalmente. Portanto, o objetivo do presente texto é o de apresentar uma implementação em Prolog deste recurso; para isso, iremos primeiro apresentar a denição do cálculo-λ e duas versões anteriores de imple-mentação (uma bastante supercial e outra mais robusta), para que possamos identicar as limitações que vamos querer superar na implementação proposta aqui.

2Mas a partir daqui vamos passar a empregar o chamado diagrama de Prawitz, bastante usado na

Gramática Categorial, que simplica um pouco a apresentação da árvore, ainda que faça isso às custas de inverter o sentido com o qual os linguistas estão mais acostumados.

(3)

2 Cálculo-λ

O cálculo-λ foi inventado pelo matemático americano Alonzo Church, a partir de meados dos anos 30, para tentar formalizar a Matemática através da noção de função, ao invés da teoria de conjuntos. Apesar de não ter servido aos seus propósitos originais, o cálculo-λ acabou exercendo uma função importante no estudo da computabilidade, de forma a ser considerado a menor língua universal de programação do mundo [11, p 1].

Seguindo a apresentação de Carpenter [4, p. 50], podemos denir o cálculo-λ a partir de três axiomas:3

a. ` λη.α ⇒ λδ.α[η 7→ δ] (redução-α)

[δ /∈ Livre(α) ∧ LivreP ara(δ, η, α)]

b. ` (λη.α β) ⇒ α[η 7→ β] (redução-β)

[LivreP ara(β, η, α)]

c. ` λη.(α η) ⇒ α (redução-η)

[η /∈ Livre(α)]

Como vamos nos concentrar na redução-β, não vamos comentar as outras duas redu-ções; além disso, por falta de espaço, também não apresentaremos as denições formais de Livre e LivreP ara (que podem ser encontradas em [4, ps. 4344]).

O axioma da redução-β nos diz que um termo-λ com o formato λη.α (que corresponde a uma função), quando toma como argumento um termo com o formato β, resulta num termo constituído pela substituição, no termo α, de todas as ocorrências livres de η por β, contanto que β seja livre para substituir η em α (ou seja, ao substituir δ em α, nenhuma variável livre de β pode acabar sendo acidentalmente ligada).

Já apresentamos três reduções-β na seção anterior, e agora vamos observais mais detidamente como elas foram executadas. Para aplicar a regra de redução à fórmula que representa a composição do signicado do SN todo menino, podemos colocá-la num esquema que esclarece a operação:4

(λ Q |{z} . λP.∀x.[(Q x) → (P x)] | {z } M |{z} ) (λ η . α β ) ⇒ α[η 7→ β] z }| { λP.∀x.[(M x) → (P x)]

Na linha central do esquema, temos a regra de redução-β; na linha de cima, a fórmula a ser reduzida; e na linha de baixo, o resultado da redução. As unicações estão identi-cadas com as chaves: se zermos o η da regra valer Q (η = Q), α = λP.∀x.[(Q x) → (P x)] e β = M, então o resultado será α[η 7→ β] = λP.∀x.[(M x) → (P x)] (o M substitui o Q na fórmula instanciada em α).

O mesmo vale para (λP.∀x.[(M x) → (P x)] C), que é o signicado de todo menino corre: (λ P |{z} . ∀x.[(M x) → (P x)] | {z } C |{z} ) (λ η . α β ) ⇒ α[η 7→ β] z }| { ∀x.[(M x) → (C x)]

3A apresentação de Carpenter privilegia unicamente o sentido da redução, mas os axiomas também

podem ser usados na expansão (foi o que zemos, na seção anterior, para deduzir o signicado de todo); quando apresentados nos dois sentidos, eles são chamados de convenção ou igualdade [9, ps. 5051].

4Minha notação é um pouco diferente da de Carpenter: coloco a função seguida do argumento

(4)

E também para (λP.(P p) C), que representa o signicado de Pedro corre: (λ P |{z} . (P p) | {z } C |{z} ) (λ η . α β ) ⇒ α[η 7→ β] z }| { (C p)

Como último exemplo, vamos apresentar a redução-β de (λP.(P p) (λQ.λx.(Q x) C)), que é uma fórmula mais complexa e apresena mais de uma alternativa de redução. Temos, na verdade, duas opções para iniciar a série de reduções;5 podemos começar reduzindo o

operador-λ que liga a variável P , como a seguir:

(λ P |{z} . (P p) | {z } (λQ.λx.(Q x) C) | {z } ) (λ η . α β ) ⇒ α[η 7→ β] z }| { ((λQ.(λx.(Q x) C) p) E, depois fazer a redução da subfórmula para o operador-λ que liga a variável Q:

(λ Q |{z} . λx.(Q x) | {z } C |{z} ) (λ η . α β ) ⇒ α[η 7→ β] z }| { λx.(C x)

Ou, alternativamente, podemos começar reduzindo a subfórmula na qual ocorre a ligação da variável Q: (λ Q |{z} . λx.(Q x) | {z } C |{z} ) (λ η . α β ) ⇒ α[η 7→ β] z }| { λx.(C x)

Substituindo, depois a fórmula reduzida na fórmula inicial, e procedendo uma nova re-dução: (λ P |{z} . (P p) | {z } λx.(C x) | {z } ) (λ η . α β ) ⇒ α[η 7→ β] z }| { (λx.(C x) p)

De qualquer maneira, no nal, obtemos a mesma fórmula, que precisa ainda passar pela última redução-β para chegarmos à forma equivalente mais simples para a fórmula inicial (λP.(P p) (λQ.λx.(Q x) C)): (λ x |{z} . (C x) | {z } p |{z} ) (λ η . α β ) ⇒ α[η 7→ β] z }| { (C p)

5Efetivemente, usando o cálculo-λ integralmente, teríamos mais alternativas, já que a subfórmula

λQ.(Q x) pode sofrer uma redução-η; como aqui estamos nos concentrando na redução-β, não explora-remos esta possibilidade.

(5)

O que é importante observar, antes de passarmos às implementações, é que a redução-β só se aplica a um termo-λ com a forma (λη.α β)  onde η é uma variável, e α e β são outros termos-λ.6 Mas, principalmente, aquilo que o operador-λ liga precisa ser

necessariamente uma variável.7

3 Implementações anteriores

Passemos, então, às duas implementações encontradas.

3.1 Pereira & Shieber

No livro de Pereira e Shieber [10, p. 96], podemos encontrar o que provavelmente seja a primeira tentativa de implementar a redução-β em Prolog, denida numa única linha: reduce(Arg^Expr, Arg, Expr).

Todo o trabalho de redução é executado pela unicação do argumento (Arg) com a variável ligada pelo operador-λ (que aqui é representado pelo acento circunexo (^) em posição inxa); o resultado decorre da unicação com o escopo do operador (Expr).

Assim, para executar, por exemplo, a redução de (λP.(P p) C) é preciso converter a fórmula para o formato escolhido pelos autores. Além do operador-λ inxo (^), a aplicação funcional é representada pelo sinal @; assim, a parte funcional da fórmula é escrita em Prolog como P^[email protected] E a redução pode ser invocada da seguinte maneira:

?- reduce(P^P@p, c, Result). P = c,

Result = c@p.

Há fundamentalmente dois problemas nesta implementação. O primeiro é que ela não dá conta da complexidade estrutural de todas as fórmulas que poderíamos precisar reduzir; como a redução não é difundida para as subfórmulas da fórmula a ser reduzida, reduções em algumas dessas subfórmulas não seriam processadas. O segundo problema é que a unicação do argumento com a variável ligada pelo operador-λ acaba instanciando esta variável com uma constante (P = c); assim, caso precisássemos continuar usando a fórmula λP.(P p) (P^P@c)  para manter um histórico derivacional  ela já estaria correspondendo a λc.(c p) (c^c@p); ou seja, teríamos uma constante onde deveríamos ter obrigatoriamente uma variável.

6Na notação que estamos usando, a dica para identicar uma redução-β é achar um parêntesis abrindo

seguido do operador-λ: . . . (λ. . . .

7Não estamos dando atenção às restrições sobre ligação das variáveis porque no uso que fazemos da

redução-β todas as variáveis introduzidas em qualquer derivação precisam ser novas; isso garante que não haja ligações indevidas (as únicas ligações são as que ocorrem com operadores de ligação inseridos lexicalmente).

8Sem os parêntesis, a representação presupõe uma precedência maior do operador funcional em relação

(6)

3.2 Blackburn & Bos

A outra implementação está no livro de Blackburn e Bos [2, ps. 7778], e pode ser obtida diretamente da internet.9 Como podemos observar na listagem abaixo, ao lidar com a

estrutura das fórmulas a serem reduzidas, esta implementação é capaz de fazer as reduções internas. betaConvert(X,Y,[]):-var(X), !, Y=X. betaConvert(Expression,Result,Stack):-nonvar(Expression), Expression = app(Functor,Argument), betaConvert(Functor,Result,[Argument|Stack]), !. betaConvert(Expression,Result,[X|Stack]):-nonvar(Expression), Expression = lam(X,Formula), betaConvert(Formula,Result,Stack), !. betaConvert(Formula,Result,[]):-nonvar(Formula), !, Formula =.. [Functor|Formulas], betaConvertList(Formulas,ResultFormulas), Result =.. [Functor|ResultFormulas].

No entanto, a seguir mostramos uma seção de redução de (λP.(P mia) λx.(snort x)) (que, na notação em Prolog dos autores, em que a aplicação funcional é representada pelo predicado app/2 e o operador-λ pelo predicado lam/2) é escrita como app(lam(A, app(A, mia)), lam(B, snort(B))).

?- betaConvert(app(lam(A, app(A, mia)), lam(B, snort(B))), Result, []). A = lam(mia, snort(mia)),

B = mia,

Result = snort(mia).

Como se nota, apesar de estruturalmente mais completo, este programa sofre do outro problema que o anterior também sofria: a unicação B = mia causa a unicação A = lam(mia, snort(mia)), tornando a fórmula reduzida inadequada para o registro do histórico derivacional, colocando uma constante onde só poderia haver uma variável.

4 Nova implementação

Avaliando os resultados equivalentes em ambas as implementações anteriores, observa-se que as variáveis do Prolog são usadas para repreobserva-sentar diretamente as variáveis da língua de representação da interpretação semântica. Desse modo, a nova proposta que será apresentada a seguir trata as variáveis da língua representacional como constantes do Prolog; apesar de poder soar inicialmente como uma contradição, na verdade, esta 9O endereço é http://homepages.inf.ed.ac.uk/jbos/comsem/download/bb1.tar.gz. A versão

apresentada aqui foi simplicada em relação ao arquivo disponibilizado na internet pelos autores, assemelhando-se mais à primeira versão comentada no livro.

(7)

opção segue a distinção entre variável e metavariável, tratando as variáveis como coisas a serem descritas, e portanto como coisas a serem referidas através de constantes, cando as variáveis do Prolog com a função de representar as metavariáveis.

% Definição dos operadores

:- op(500, yfx, @). % aplicação funcional

:- op(550, xfx, /\). % conjunção :- op(550, xfx, =>). % implicação

:- op(600, xfy, ^). % operador-lambda

% Lista de conectivos proposicionais con_prop(/\). con_prop(=>). % Lista de quantificadores quant(algum). quant(todo). % reduz_lista(Lista, Reduzido) % ****************************************** % * Reduzido é o resultado da redução-beta * % * recorrente do primeiro Termo da Lista * % ****************************************** reduz_lista(Lista, Reduzido) :-Lista = [Termo|_], reduz_termo(Termo, Resultado), reduz_lista([Resultado|Lista], Reduzido), !. reduz_lista(Resultado, Resultado). % reduz_termo(Termo1, Termo2) % ************************************************** % * Termo2 é o resultado da redução-beta do Termo1 * % ************************************************** % Aplicação

reduz_termo((Var^Termo)@Arg, Resultado) :-substitui(Termo, Var, Arg, Resultado). reduz_termo(Termo1@Termo2, Termo1@Resultado) :-reduz_termo(Termo2, Resultado). reduz_termo(Termo1@Termo2, Resultado@Termo2) :-reduz_termo(Termo1, Resultado). % Abstração reduz_termo(Var^Termo, Var^Resultado) :-reduz_termo(Termo, Resultado). % Conectivos proposicionais reduz_termo(Termo, Resultado) :-Termo =.. [Con, :-Termo1, :-Termo2], con_prop(Con),

(8)

Resultado =.. [Con, Termo1, Parcial]. reduz_termo(Termo, Resultado)

:-Termo =.. [Con, :-Termo1, :-Termo2], con_prop(Con),

reduz_termo(Termo1, Parcial),

Resultado =.. [Con, Parcial, Termo2]. % Quantificadores

reduz_termo(Termo, Resultado)

:-Termo =.. [Quant, Var, Sub:-Termo], quant(Quant),

reduz_termo(SubTermo, Parcial), Resultado =.. [Quant, Var, Parcial]. % substitui(Termo1, Var, Termo2, Termo3)

% *************************************************************** % * Termo3 é o resultado de substituir Var por Termo2 no Termo1 * % *************************************************************** % Variável

substitui(x(M), x(N), Termo2, Termo3)

:-( x(M) \= x(N) -> Termo3 = x(M) ; Termo3 = Termo2 ). % Constante substitui(Termo3, _, _, Termo3) :-atom(Termo3). % Aplicação

substitui(Termo1a@Termo1b, Var, Termo2, Termo3a@Termo3b) :-substitui(Termo1a, Var, Termo2, Termo3a),

substitui(Termo1b, Var, Termo2, Termo3b). % Abstração

substitui(Var1^Termo1, Var, Termo2, Termo3) :-( Var1 = Var

-> Termo3 = Var1^Termo1

; substitui(Termo1, Var, Termo2, Resultado), Termo3 = Var1^Resultado

).

% Conectivos proposicionais

substitui(Termo1, Var, Termo2, Termo3) :-Termo1 =.. [Con, :-Termo1a, :-Termo1b], con_prop(Con),

substitui(Termo1a, Var, Termo2, Termo3a), substitui(Termo1b, Var, Termo2, Termo3b), Termo3 =.. [Con, Termo3a, Termo3b].

% Quantificadores

substitui(Termo1, Var, Termo2, Termo3) :-Termo1 =.. [Quant, Var1, Sub:-Termo1], quant(Quant),

(9)

( Var1 = Var

-> Termo3 =.. [Quant, Var1, SubTermo1]

; substitui(SubTermo1, Var, Termo2, Resultado), Termo3 =.. [Quant, Var1, Resultado]

).

Abaixo podemos observar um exemplo de uso da nova implementação. Para facilitar a apresentação, incluí no programa o predicado reduz_lista/2, que toma uma lista como entrada (que deve ser instanciada com uma lista que contenha apenas a fórmula a ser reduzida) e devolve como saída uma lista com a sequência de reduções-β executadas (em ordem inversa, devido ao empilhamento da lista no Prolog).

?- reduz_lista([(x(0)^x(0)@p)@(x(1)^c@x(1))], Resultado).

Resultado = [c@p, (x(1)^c@x(1))@p, (x(0)^x(0)@p)@ (x(1)^c@x(1))].

Neste exemplo, foi pedido que o programa reduzisse a fórmula (λP.(P p) λx.(C x)) (representada por (x(0)^x(0)@p)@(x(1)^c@x(1)), onde x(0) está para P e x(1) para x). Como se pode constatar, o programa produz uma lista com c@p na primeira posi-ção (que corresponde a (C p), que é a forma normal da fórmula inicial de entrada), (x(1)^c@x(1))@p na posição intermediária (que corresponde à fórmula (λx.(C x) p)), e a própria fórmula de entrada na última posição. Assim, pudemos manter o histórico das reduções, sem instanciar variáveis com constantes nas expressões com o operador-λ.

5 Conclusões

Evidentemente, é possível que haja uma possibilidade de remendar as implementações anteriores, de forma a evitar a propagação das instanciações indevidas. No entanto, a solução proposta aqui parece mais el à sintaxe do cálculo-λ e a uma certa losoa da programação em Prolog (e mesmo do cálculo de predicados), que determina que tratemos as entidades manipuladas como constantes e reservemos as variáveis para as asserções quanticadas.

A presente proposta também inclui um exemplo da manipulação da estrutura do cálculo de predicados, dendo-se operadores para representar os conectivos proposicionais e usando predicados para representar os quanticadores. Aqui exemplicamos apenas a denição da conjunção e da implicação, mas os outros conectivos proposicionais poderiam ser facilmente introduzidos na implementação pelos mesmos moldes.10

Finalmente, convém observar que o que foi apresentado aqui é apenas uma pequena parte da implementação do cálculo-λ. Não apenas não implementamos os outros dois axiomas (diferentemente de [2, ps. 7882], no qual se apresenta uma denição para a redução-α), como a implementação só foi concebida para o sentido da redução, e não para o da expansão (assim como a de Blackburn & Bos). No entanto, nas aplicações em que temos empregado a presente implementação (basicamente em assistentes de análise 10A negação, por ser um conectivo unário (ao contrário dos outros, que são binários), exigiria um

tratamento especial. De qualquer forma, bastaria incluir uma cláusula especíca na denição dos predi-cados reduz_termo/2 e substitui/2, nos mesmos termos da cláusula dos binários, mas apenas para um subtermo; ou, alternativamente, designar um predicado que percorresse a lista de subtermos reunidos pelo conectivo proposicional (a implementação de Blackburn & Bos faz exatamente isso na sua última cláusula, ainda que de forma precária: a sintaxe dos conectivos e dos quanticadores não é explicitada).

(10)

e analisadores gramaticais para Gramáticas Categoriais), não sentimos a necessidade de empregar nenhum dos outros dois axiomas (a ligação indevida de variáveis é evitada, como comentamos na nota 7, através da inserção de variáveis sempre novas; e ainda não encontramos motivação linguística para o emprego da conversão-η).

Referências

[1] James Allen. Natural Language Understanding. Benjamin/Cummings, California, second edition, 1995.

[2] Patrick Blackburn and Johan Bos. Representation and Inference for Natural Lan-guage  A First Course in Computational Semantics. CSLI, Stanford, CA, 2005. [3] Ronnie Cann. Formal Semantics  An Introduction. Cambridge University Press,

Cambridge, 1993.

[4] Bob Carpenter. Type-Logical Semantics. The MIT Press, Cambridge, MA, 1997. [5] Gennaro Chierchia and Sally McConnell-Ginet. Meaning and Grammar  An

Intro-duction to Semantics. The MIT Press, Cambridge, MA, second edition, 2000. [6] Michael A. Covington. Natural Language Processing for Prolog Programmers.

Pren-tice Hall, Englewood Clis, 1994.

[7] David R. Dowty, Robert E. Wall, and Stanley Peters. Introduction to Montague Semantics. Reidel, Dordrecht, 1981.

[8] Irene Heim and Angelika Kratzer. Semantics in Generative Grammar. Wiley-Blackwell, Oxford, 1998.

[9] Glyn V. Morrill. Type Logical Grammar. Kluwer, Dordrecht, 1994.

[10] Fernando C. N. Pereira and Stuart M. Shieber. Prolog and Natural Language Analy-sis. CSLI, Stanford, 1987.

[11] Raúl Rojas. A tutorial introduction to the lambda calculus. [A partir de http://www.utdallas.edu/gupta/courses/apl/lambda.pdf, acessado em 04.09.2012], 1998.

Referências

Documentos relacionados

In the present investigation, we evaluated the diurnal variation in brachial artery diameter (BAD), flow-mediated dilation (FMD) and endothelium-independent dilation (NFMD) in

Para faturas com o número de contribuinte, basta solicitar no momento da compra na bilheteira local para que a mesma seja impressa ou enviada para a morada correspondente. - No ano

Na minha opinião, são destaques inquestionáveis de 2012 os progressos no sentido do reforço da cooperação entre laboratórios de saúde pública dos diferentes Estados-Membros e

Antes de executar a manutenção no regulador, desligue a pressão de entrada e saída e remova a compressão de mola girando o botão de configuração completamente no sentido

O presente trabalho relata um caso de periodontite apical assintomática, abscesso periapical crônico, cuja história clínica é de uma paciente que se apre- sentou para

No código abaixo, foi atribuída a string “power” à variável do tipo string my_probe, que será usada como sonda para busca na string atribuída à variável my_string.. O

COMT polymorphisms have been associated with several different cognitive abilities such as reading (Landi et al., 2013), numerical processing (Júlio-Costa et al., 2013; Tan et

No formato Dublin Core Simples, somente os 15 elementos n˜ao conseguem abranger todos os dados necess´arios para identificar os tipos de trabalho armazenados no reposit´orio da