Interface Português-Prolog 

Mapeamento de sintagmas nominais para lógica e para Prolog

Sintagma Nominal Lógica Prolog
Brutos Brutos brutos
mortal Mortal mortal
um homem $x Homem(x)

Criar um novo identificador para representar um homem: homem(1), por exemplo.

Registar o facto desse identificador ser um homem: homem(homem(1)), por exemplo.

o homem $1x Î Contexto Homem(x) Verificar se existe um homem num contexto adequado. Se existir, usar esse. Se não existir, assumir que se trata da classe dos homens como na frase "o homem é um ser vivo".
Todos os homens "x Homem(x) X:homem(X)

Esta abordagem tem muitas limitacoes. Por exemplo:

A frase "A senhora da recepção morreu" introduz uma senhora na conversa e, no entanto, tem um artigo definido antes do nome. Além disso, depois de ter morrido talvez não queiramos que o programa continue a achar que ainda existe essa senhora.

 A frase "Todos os homens têm uma mãe" não quer dizer que existe uma mulher que é mãe de todos os homens. Cada homem tem a sua mãe. 

Na frase "O homem é um animal racional", "animal racional é uma classe não é nenhum indivíduo mas seria criado um novo indivíduo.

O contexto está tratado com muita simplicidade. Obviamente é necessário muito mais.

Suspeito que as interrogações terão problemas.

Representação semântica das palavras

nome(brutos)--> ['Brutos'].

nome(mortal)--> [mortal];[mortais].

nome(homem)-->[homem];[homens].

nome(rua)-->[rua];[ruas].

pronome(utilizador)-->[eu].

pronome(programa)-->[tu].

pronome(X)-->[quem];[quais];[que].  % Pronomes interrogativos

verbo(ser)-->[sou];[és];[é];[somos];[sois];[são].

verbo(atravessar)-->[atravessou].

verbo(morrer)-->[morreu].

det(o)-->[o];[a].

det(um)-->[um];[uma].

det(todo)-->[todos, os];[todas, as].

Regras de gramática aumentadas para gerar a representação semântica

sn(Obj) --> nome(Obj).

sn(Obj)--> pronome(Obj).

sn(Obj)--> det(D), nome(N), { composicao_det_nome(D, N, Obj) }.

sv(Pred)--> verbo(V), { Pred =.. [V, X] }.

sv(Pred) --> verbo(V), sn(Obj), { Pred =.. [V, X, Obj] }.

s(Prop)--> sn(Obj), sv(Pred), { composicao_sn_sv(Obj, Pred, Prop) }.

composicao_det_nome(um, N, Obj):-

    criar_identificador_novo(N, Obj),

    registar_classe_do_identificador(N, Obj).

composicao_det_nome(um, N, Obj):-    % existe um individuo particular

    F =.. [N, Obj],

    call(F).

composicao_det_nome(um, N, N).    % classe

composicao_det_nome(todo, N, X:Obj):-

    Obj =.. [N, X].

composicao_sn_sv(Obj, Pred, Prop):-

    Pred =.. [V, X|Resto],

    Prop =.. [V, Obj|Resto].

criar_identificador_novo(N, Obj):-

    novo_id(Id),

    Obj =.. [N, Id].

registar_classe_do_identificador(N, Obj):-

    F =.. [N, Obj],

    asserta(F).

novo_id(Id):-

    retract(id(Id)), !,

    Id1 is Id + 1,

    assert(id(Id1)).

novo_id(1):-

    assert(id(2)).

 

Programa de interface com Prolog

talk_talk:-

    repeat,

        getsentence(S, Tipo),

        processa_frase(S, Tipo), !.

processa_frase([fim], _):- !.

processa_frase(S, afirmacao):-

    s(Repr, S, []),

    converte_para_prolog(Repr, Afirmacao),

    write(Afirmacao), nl,

    assert(Afirmacao), !, fail.

processa_frase(S, interrogacao):-

    s(Repr, S, []),

    converte_para_prolog(Repr, Interrogacao),

    write(Interrogacao), nl,

    findall(Interrogacao, Interrogacao, Respostas),

    write(Respostas), nl, !, fail.

/*

Conversao para Prolog

Após a conversão, os argumentos constantes permanecem inalterados, os

argumentos X:T sofrem processamento

 

Exemplo:

ser(X:homem(X), mortal) é convertido para ser(X, mortal):- homem(x).

*/
converte_para_prolog(Prop, (Consequente:- Antecedente)):-
    Prop =.. [V | Rest],
    converte_args(Rest, Args, TermosU),
    Consequente =.. [V | Args],
    antecedente(TermosU, Antecedente).

converte_args([], [], []).
converte_args([X:T|Rest], [X|Args], [X:T|TermosU]):-
    termo_universal(X:T),
    !,
    converte_args(Rest, Args, TermosU).
converte_args([X|Rest], [X|Args], TermosU):-
    converte_args(Rest, Args, TermosU).

antecedente([], true).
antecedente([X:T], T).
antecedente([X1:T1, X2:T2|TermosU], (T1, Ant)):-
    antecedente([X2:T2|TermosU], Ant).

termo_universal(T):- nonvar(T), T = X:Termo.