Concurso/Encontro Nacional de Programação Lógica
CeNPL'2003
Universidade de Évora
29--31 de Maio de 2003
Referências Trocadas
Dicionário Errado!
Um dicionário contem definições (ou entradas) para expressões de uma
língua, podendo essas definições conter referências a outras
expressões. Se uma referência numa das definições estiver errada é
necessário corrigir o dicionário de uma forma eficiente.
O autor do dicionário de que aqui se trata é muito propenso a erros do
tipo: dar como referência a expressão E se o que deveria referir é
uma expressão E' que aparece referida numa das definições de E.
Por exemplo, referir gato em vez de felino, que
aparece referido numa definição de gato --- é claro que na
definição de gato como marosca (aqui há gato!),
felino não consta.
Supõe-se que o autor do dicionário não é tão incompetente que crie
definições contendo referências para a própria expressão a definir.
Tarefa
Escreva um programa que resolva problemas do tipo
anterior, em que um dicionário é representado por uma lista de entradas
da forma e(X,Defs)
com X
um termo único que
descreve a expressão, e Defs
uma lista não vazia de
definições. Cada definição é representada por um termo
d(N,Descr)
com N
o número da definição e Descr
uma lista de termos de duas formas: p(P)
para palavras e
ref(R)
para referências.
Os Dados
O programa a escrever tem como dados o dicionário errado D
e uma
expressão E
, passados como argumentos ao predicado de topo.
Os Resultados
Para um dicionário errado D
e uma expressão E
pretende-se obter um dicionário corrigido C
substituíndo todas
as referências a E
por referências a Ec
, que é
(segundo o autor do dicionário!) a única expressão referida nas
definições de E
. Para evitar problemas futuros com o referido
autor, o programa deve falhar se houver mais que uma referência nas
definições de E
, bem como em situações de: mais
de uma entrada para a expressão dada, ou não existência de referência
que se possa usar.
Por questões de eficiência, o dicionário errado só pode ser visitado
(explicita ou implicitamente a nível do programa Prolog) uma única vez.
O predicado de topo do programa deve ser refsx(D,E,C).
Exemplos usando o seguinte dicionário:
[e(autor,[d(1,[p(criador)]),
d(2,[p(escritor)]),
d(3,[p(compositor)])]),
e(ave,[d(1,[p(comida),p(de),ref(gato)])]),
e(gato,[d(1,[ref(felino),p(pequeno)]),
d(2,[p(marosca)])]),
e(leao,[d(1,[p(especie),p(de),ref(gato)])]),
e(marosca,[d(1,[p(tramoia)])]),
e(rato,[d(1,[p(comida),p(de),ref(gato)]),
d(2,[p(esperto)]),
d(3,[p(alvo),p(para),ref(gato)])]),
e(terminal,[d(1,[p(fim)])])]
?- teste_dic(D), refsx(D,gato,C).
D = ...
C = [e(autor,[d(1,[p(criador)]),
d(2,[p(escritor)]),
d(3,[p(compositor)])]),
e(ave,[d(1,[p(comida),p(de),ref(felino)])]),
e(gato,[d(1,[ref(felino),p(pequeno)]),
d(2,[p(marosca)])]),
e(leao,[d(1,[p(especie),p(de),ref(felino)])]),
e(marosca,[d(1,[p(tramoia)])]),
e(rato,[d(1,[p(comida),p(de),ref(felino)]),
d(2,[p(esperto)]),
d(3,[p(alvo),p(para),ref(felino)])]),
e(terminal,[d(1,[p(fim)])])] ? ;
no
?- teste_dic(D),
refsx([e(leao,[d(1,[p(mau)])])|D],leao,C).
Mais de uma entrada para :leao
no
?- teste_dic(D), refsx(D,rato,C).
Mais de uma referencia na definicao de :rato
no
?- teste_dic(D), refsx(D,felino,C).
Nao existe referencia na definicao de :felino
no
?- teste_dic(D), refsx(D,lixo,C).
Nao existe referencia na definicao de :lixo
no
This document was translated from LATEX by
HEVEA.