Comandos idiomáticos em linguagem natural e interfaces de perguntas

De Augusto Baffa Wiki
Revisão de 12h46min de 7 de novembro de 2020 por Abaffa (discussão | contribs) (Criou página com 'O significado cotidiano do termo "expressão idiomática" envolve uma frase em linguagem natural cuja forma gramatical segue os padrões típicos da linguagem, mas cujo signif...')
(dif) ← Edição anterior | Revisão atual (dif) | Versão posterior → (dif)
Ir para navegação Ir para pesquisar

O significado cotidiano do termo "expressão idiomática" envolve uma frase em linguagem natural cuja forma gramatical segue os padrões típicos da linguagem, mas cujo significado não é determinado o suficiente pelos significados usuais das palavras individuais na expressão. Principalmente, existem frases nominais idiomáticas ("an early hard winter"), e frases inteiras que são idiomáticas ("Leave no stone unturned.").

Aqui, usaremos uma definição mais ampla de expressão idiomática, para significar, aproximadamente, qualquer frase que um usuário típico do software em questão possa usar para se comunicar com o aplicativo em execução. Por idioma queremos dizer uma coleção de regras gramaticais com um significado comum. Pode haver muitas maneiras especiais (idiomáticas) de dizer a mesma coisa, ou seja, de transmitir o mesmo significado.

Por exemplo, considere o mundo dos blocos da Seção 2.19. Imagine uma interface de usuário que recebe a entrada do usuário na forma de comandos digitados e perguntas. Uma interface mais útil seria aquela que recebesse comandos falados, mas esta seção considera apenas as entradas que já foram quebradas em uma sequência de palavras, conforme considerado na seção anterior 7.2.


Vamos considerar dois idiomas, o primeiro dos quais é um comando, o segundo uma pergunta.

O primeiro idioma é o comando para criar um determinado arranjo de blocos. Uma maneira de especificar esse idioma é fornecer alguns scripts que a interface de comando deve traduzir para o significado pretendido. Por exemplo, ...

Command idiom c:
{Please} place < put>  {block} X on < onto > {block} Y, W on Z, ...
I want < would like>  X on Y, W on Z, ...
I want < would like>  you to put < place>  ...
Can < could>  < would>  you {please} put < place>  X on Y, ...

Os scripts são indicados informalmente aqui. Os colchetes {...} permitem palavras opcionais e os 'colchetes' <...> indicam palavras alternativas. Neste exemplo, o idioma do comando será a coleção de regras gramaticais que analisam todos esses comandos de script e o significado correspondente será o comando abstrato para realizar o arranjo de blocos descrito por tal comando. Claro, o arranjo pode ser fisicamente inválido, então o comando pode equivaler a uma ação implícita impossível.


Na Seção 8.3, animaremos graficamente a interface de comando e, assim, forneceremos um significado mais concreto para os comandos abstratos. Assim, o significado da entrada original na verdade é "interpretado" duas vezes: primeiro pelo idioma (as regras gramaticais) produzindo um significado formal e, em seguida, o significado formal é interpretado pelo simulador para determinar como realizar a ação abstrata. Comandos fisicamente válidos serão executados reorganizando os blocos conforme exigido pelo significado pretendido do comando; Os comandos fisicamente inválidos ou impossíveis obterão alguma resposta apropriada do sistema.


Segue uma gramática parcial para o idioma de comando

c(L) --> lead_in,arrange(L),end.

end --> ['.'] | ['?'].

lead_in --> please, place.
lead_in --> [i], [want] | [i], [would], [like], you_to_put.
lead_in --> ([can] | [could] | [would]), [you], please, place.

you_to_put --> [] | [you], [to], place.   %%% partially optional

please --> [] | [please].    %%% optional word

place --> [put] | [place].   %%% alternate words

arrange([ON]) --> on(ON).
arrange([ON|R]) --> on(ON), comma, arrange(R).

comma --> [','] | ['and'] | [','],[and].   %%% alternate words

on(on(X,Y)) --> block, [X], ([on] | [onto] | [on],[top],[of]), block, [Y].
on(on(X,table)) --> [X],([on] | [onto]), [the], [table].

block --> [] | [block].   %%% optional word

:- [read_line].

test_parser :- repeat,
               write('?? '), 
               read_line(X),
               ( c(F,X,[])   | q(F,X,[])  ),
               nl, write(X), nl, write(F), nl, fail.

Here is a sample parse for a command ...

?- test_parser.
?? Please put block a on top of block b, c on d, and f on the table.

[please,put,block,a,on,top,of,block,b,(,),c,on,d,9,0,and,f,on,the,table,.]
[on(a, b),on(c, d),on(f, table)]
?? ...

A primeira saída [please,put,...] é a entrada do usuário convertida em uma sequência de palavras, usando 'read_line', e a segunda saída [on(a b),...] é o significado abstrato correspondente à entrada do usuário. Nesse caso, é apenas uma lista de relacionamentos 'on' que podem ser o arranjo pretendido a ser criado como resultado do comando pretendido.

Antes de discutirmos um idioma de questão, deve ser explicado que vamos mudar a representação interna para o posicionamento dos blocos. Anteriormente, na Seção 2.19, isso era feito simplesmente com a propriedade on(-,-). Um animador para o movedor de blocos será fornecido na Seção 8.3. Nesse programa, os blocos receberão uma localização location(Block,[X,Y]) em relação a onde eles (atualmente) estão no plano de desenho gráfico (X e Y dando a localização do canto superior esquerdo de um bloco ) A propriedade on(-,-) é então definida em termos de location(-,[-,-]). Os blocos são desenhados com 5 unidades de altura.

   /*
   Cursor graphics for blocks animator
   
       positioning information
   
          [20,2 ]    [30,  ]   [40,  ]
          [20,7 ]    [30,  ]   [40,  ]
          [20,12]    [30,  ]   [40,  ]
          [20,17]    [30,  ]   [40,  ]
        -==============================-   < --- table
     
       The actions 'up', left', 'right', and 'down' will, in effect,
       move a block one position;  the animation of such a
       move will show movement for each screen cursor position.
   */
 
   free_spot_on_table([30,17]).
   free_spot_on_table([40,17]).
   
     %% initially
   location(a,[20,7]).
   location(b,[20,12]).
   location(c,[20,17]).
  
   on(A,table) :- location(A,[_,17]).
   on(A,B) :- B \== table,
              location(A,[X,YA]),
              location(B,[X,YB]),
              YB is YA + 5.

Agora, vamos adicionar um script simples para um idioma de pergunta.

Question idiom q:
Which block is on top of X?
What is on top of X?

e uma gramática parcial para o idioma da pergunta ...

:- op(500, xfx, 'is_on_top_of').

  %%% the question q
q(X is_on_top_of A) --> [which],[block],[is],[on],[top],[of],[A],end.
q(X is_on_top_of A) --> [what],[is],[on],[top],[of],[A],end.

   %%% How to answer q
B is_on_top_of A :- location(A,[X,Y]),
                    Y1 is Y-5,           %% What's above?
                    location(B,[X,Y1]), !.
'Nothing' is_on_top_of A .

answer(X is_on_top_of A) :- call(X is_on_top_of A),
                            say([X,is,on,top,of,A]).

say([X|R]) :- write(X), write(' '), say(R).
say([]).

Aqui está um exemplo de análise para uma pergunta ...

?- test_parser.
?? Which block is on top of b?
[which,block,is,on,top,of,b,?]
G1220 is_on_top_of b

?? What is on top of a?
[what,is,on,top,of,a,?]
G1136 is_on_top_of a

??..

Agora, o programa de exemplo também mostra como a pergunta será respondida -- consulte a Seção 8.3. O significado abstrato da pergunta "Qual bloco está no topo de b?" é Q = 'G1220 is_on_top_of b'. A maneira como esta pergunta será respondida é colocando a consulta 'Q' do Prolog, esperando ser possível vincular a variável 'G1220' a qualquer bloco que esteja no topo de 'b'; e então 'diz' a resposta correspondente. Se não houver bloco no topo de 'b', então o objetivo 'Q' falhará e, neste caso, a resposta será 'Nada' e dirá: "Nothing is on top of b".

Para cada exercício, formule um script razoável para o idioma e especifique um significado abstrato razoável para o idioma. Provavelmente será muito útil ler a Seção 8.3 e executar você mesmo o animador de blocos antes de fazer os exercícios.


Exercício 7.3.1 Formule um novo idioma de pergunta, um de cujos scripts é "Em que está o bloco X?".


Exercício 7.3.2 Formule um novo idioma de pergunta, um de cujos scripts é "Quais blocos estão na mesa?".


Exercício 7.3.3 Formule um novo idioma de comando, um dos scripts é "Coloque todos os blocos em uma única pilha.". Este é um idioma interessante, porque o significado abstrato é ambíguo - ou seja, pode haver mais de um significado abstrato para este idioma. Suponha que um significado abstrato não seja melhor ou pior do que outro; apenas gere um deles como "o" significado.


Exercício 7.3.4 Formule um novo idioma de comando, um dos scripts é "Coloque o bloco em cima de X no topo do bloco y." (ou na mesa). Isso envolverá a interpretação da descrição definida ("o ...") com precisão.


Exercício 7.3.5 Formule um novo idioma de comando, um de cujos scripts é "Coloque o bloco mais alto no topo do bloco y." (ou a mesa). Isso envolverá a interpretação da descrição definida ("o ...") com precisão.


Exercício 7.3.6 Projete um programa que possa converter comandos ou "scripts" baseados em texto de pergunta em um idioma (coleção de regras gramaticais com significado comum). Presumivelmente, o usuário poderia digitar os scripts e o significado de uma forma um tanto informal, e o programa geraria as regras gramaticais lógicas do Prolog automaticamente. Tente criar um formato parcialmente visual para o layout das entradas. Uma versão modificada deste exercício, se você tiver reconhecimento de voz, é construir uma interface de usuário vocal (VUI - vocal user interface) que recebe entradas vocais e gera a interface de comando e pergunta (presumindo que uma maneira apropriada seja encontrada para designar os significados).


Veja Também