Agradeço comentários, sugestões ou correcções. O meu endereço de correio electrónico é < delfim@mat.ua.pt > . Desde já obrigado.
Os Sistemas Periciais (SP) são um dos primeiros sucessos comerciais da Inteligência Artificial. O seu uso na indústria, educação, ciência, medicina, ... tem aumentado durante os últimos anos.
Os SP são sistemas baseados em conhecimento, conhecimento esse a maior parte das vezes não procedimental, essencialmente declarativo. Isto faz com que o Prolog seja um candidato à construção de tais sistemas.
Várias áreas de trabalho, e investigação, encontram-se associadas ao desenvolvimento de SP. Algumas delas são:
Os SP diferem dos programas de computador convencionais, em vários aspectos importantes. Alguns deles são:
Outro SP pioneiro foi o PROSPECTOR, um sistema que assistia os geólogos na descoberta de depósitos minerais.
Desde a introdução destes SP pioneiros, a vastidão de aplicações aumentou dramaticamente. Os métodos e as teorias de suporte aos sistemas modernos são também mais complexas, integrando vários paradigmas. Assim, para além dos métodos lógicos tradicionais, encontramos abordagens conexionistas (e.g., redes neuronais) e paradigmas evolucionários (e.g., paradigmas genéticos).
Aplicações podem hoje ser encontradas em quase todas as áreas do conhecimento. Para uma lista e breve descrição de aproximadamente 200 SP veja-se []
Iremos aqui dar apenas ``um cheirinho'' das potencialidades e características de um SP.
Podemos dizer que a arquitectura mais comum usada na construção de SP, aliás como em outros tipos de sistemas baseados em conhecimento, são os sistemas baseados em regras. Estes sistemas usam o conhecimento codificado sobre a forma de regras de produção:
Se
Cond1 e Cond2 e ... e CondN
Entao
Conclusao.
Cada regra representa um pedacinho de conhecimento, relacionado com o domínio de peritagem escolhido. Em Prolog estas regras são escritas naturalmente como cláusulas.
A ``concha'' que iremos desenvolver irá usar este formalismo de representação de conhecimento, e o mecanismo de raciocínio (processo de inferência) lógico já disponibilizado pelo Prolog.
Tal como foi dito,
Sistema Pericial = Conhecimento + Inferência
e existe uma separação explícita entre as duas componentes.
Não entraremos aqui nas questões associadas à aquisição, verificação e validação de conhecimento, nem no estudo (e implementação) de mecanismos de aprendizagem.
Quanto ao tratamento de conhecimento incerto, iremos apenas dar (veja-se a secção ) uma pequena introdução a uma das muitas abordagens existentes: o uso de conjuntos difusos.
A Base de Conhecimento contém conhecimento específico de um determinado domínio (factos, regras, métodos, heurísticas, ...) e a indicação dos predicados questionáveis que fazem com que certos dados sobre o problema sejam solicitados ao utilizador quando necessário, de modo atingir o objectivo.
Segue-se um exemplo, em que o domínio de peritagem é a classificação de aves da América do Norte.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Base de Conhecimento (BC) 'aves.pl'
%% que conjuntamente com 'perito.pl'
%% forma o 'Sistema Pericial aves'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Para uma BC funcionar com o 'perito.pl'
% deve possuir:
%
% - conhecimento;
% - identificacao dos atributos questionaveis
% (recorrendo aos predicados 'questiona');
% - identificacao da especialidade da BC
% (recorrendo ao predicado 'objectivo/1').
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Conhecimento.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ave(albatrozLaysan) :-
familia(albatroz),
cor(branca).
ave(albatrozPePreto) :-
familia(albatroz),
cor(cinzenta).
ave(cisneSibilante) :-
familia(cisne),
voz(silvoMusicalAbafado).
ave(cisneCorneteiro) :-
familia(cisne),
voz(corneteiroEspalhafatoso).
ave(gansoCanadiano) :-
familia(ganso),
estacao(inverno),
pais(estadosUnidos),
cabeca(preta),
face(branca).
ave(gansoCanadiano) :-
familia(ganso),
estacao(verao),
pais(canada),
cabeca(preta),
face(branca).
ave(patoBravo) :-
familia(pato),
voz(grasno),
cabeca(verde).
ave(patoBravo) :-
familia(pato),
voz(grasno),
cabeca(manchasCastanhas).
ordem(bicoTubular) :-
narinas(tubularExterna),
vive(mar),
bico(curvo).
ordem(aquatico) :-
patas(membranaInterdigital),
bico(espalmado).
familia(albatroz) :-
ordem(bicoTubular),
dimensao(grande),
asas(longaEstreita).
familia(cisne) :-
ordem(bicoTubular),
pescoco(comprido),
cor(branca),
voo(lento).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% E' necessario, para funcionar com o
%% 'perito.pl', que especifiquemos quais
%% os atributos questionaveis, i.e., quais
%% os factos primitivos.
%%
%% Para cada caso, usar um dos predicados:
%% questiona/2
%% questiona/3
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
cor(X) :-
questiona(cor,X).
voz(X) :-
questiona(voz,X,[silvoMusicalAbafado,corneteiroEspalhafatoso,grasno]).
estacao(X) :-
questiona(estacao,X,[inverno,primavera,verao,outono]).
pais(X) :-
questiona(pais,X).
cabeca(X) :-
questiona(cabeca,X).
face(X) :-
questiona(face,X).
narinas(X) :-
questiona(narinas,X).
vive(X) :-
questiona(vive,X).
bico(X) :-
questiona(bico,X).
patas(X) :-
questiona(patas,X).
dimensao(X) :-
questiona(dimensao,X,[grande,pequena,media]).
asas(X) :-
questiona(asas,X).
pescoco(X) :-
questiona(pescoco,X).
voo(X) :-
questiona(voo,X).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Identifica a 'especialidade' desta Base
%% de Conhecimento: identificar aves.
%%
%% Para isso devemos usar o predicado
%% 'objectivo/1'
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
objectivo(X) :- ave(X).
A concha a desenvolver é formada por um interface (perito/0) que controla a comunicação entre o SP e o utilizador; por uma memória de trabalho que evita, por memorização das respostas (conhece/3), que haja perguntas repetidas; e por um motor de inferência (soluciona/0).
A concha permite recorrer a várias BCs (uma de cada vez que
consultamos o perito.pl, para evitar conflitos entre
cláusulas de BCs diferentes) permitindo assim termos vários
SPs para diferentes domínios de peritagem. A concha irá
resolver o problema definido pelo predicado objectivo/1
incluído na BC em questão.
Exemplo de uma sessão com o perito.pl:
?- consult(perito).
Yes
?- perito.
Concha simples de Sistema Pericial
Versao de 27/Maio/1999
Comandos disponiveis (introduza o numero `1.`, `2.` ou `3.`):
1 - Consultar uma Base de Conhecimento (BC)
2 - Solucionar
3 - Sair
> 1.
Nome da BC: aves.
BC consultada com sucesso.
Comandos disponiveis (introduza o numero 2 ou 3):
2 - Solucionar
3 - Sair
> 2.
narinas:tubularExterna? (sim/nao) sim.
vive:mar? (sim/nao) sim.
bico:curvo? (sim/nao) sim.
Qual o valor para dimensao?
[grande, pequena, media]
|: grande.
asas:longaEstreita? (sim/nao) sim.
cor:branca? (sim/nao) nao.
cor:cinzenta? (sim/nao) sim.
Resposta encontrada: albatrozPePreto
Comandos disponiveis (introduza o numero 2 ou 3):
2 - Solucionar
3 - Sair
> 3.
Volte Sempre!
Qualquer tecla para sair.
perito.pl:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% perito.pl
%%
%% Expert System Shell:
%% Permite carregar a base de conhecimento desejada.
%%
%% 27/Maio/1999
%% Delfim F. Marado Torres
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Predicado principal: perito/0
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
perito :-
write('Concha simples de Sistema Pericial'), nl,
write('Versao de 27/Maio/1999'), nl, nl,
esperaOrdens(123).
esperaOrdens(MC) :-
mostraComandos(MC),
write('> '),
read(Comando),
executa(MC,Comando).
mostraComandos(123) :-
write('Comandos disponiveis (introduza o numero `1.`, `2.` ou `3.`):'),
nl,
write('1 - Consultar uma Base de Conhecimento (BC)'), nl,
write('2 - Solucionar'), nl,
write('3 - Sair'), nl.
mostraComandos(23) :-
write('Comandos disponiveis (introduza o numero 2 ou 3):'), nl,
write('2 - Solucionar'), nl,
write('3 - Sair'), nl.
executa(_,1) :-
write('Nome da BC: '),
read(F),
consult(F),
write('BC consultada com sucesso.'), nl, nl,
continua.
executa(_,2) :-
soluciona,
esperaOrdens(23).
executa(_,3) :-
nl,
write('Volte Sempre!'), nl,
write('Qualquer tecla para sair.'),
get0(_),
halt.
executa(MC,X) :-
write(X),
write(' nao e um comando valido!'), nl,
esperaOrdens(MC).
continua :-
retract( executa(_,1) :- _ ), % Ja carrega'mos uma BC.
esperaOrdens(23). % De futuro ja nao temos essa opcao.
%%%%%%%%%%%%%%%
% soluciona/0
%%%%%%%%%%%%%%%
soluciona :-
abolish(conhece,3),
asserta(conhece(def,def,def)), % apenas para o predicado
objectivo(X), % conhece/3 estar definido...
nl, nl, write('Resposta encontrada: '),
write(X),
nl, nl.
soluciona :-
nl, nl, write('Nao foi encontrada resposta :-('), nl.
%%%%%%%%%%%%%%%
% questiona/2
%%%%%%%%%%%%%%%
questiona(Atributo,Valor) :-
conhece(sim,Atributo,Valor).
questiona(Atributo,Valor) :-
conhece(_,Atributo,Valor), !, fail.
questiona(Atributo,Valor) :-
write(Atributo:Valor),
write('? (sim/nao) '),
read(R),
processa(R,Atributo,Valor).
processa(sim,Atributo,Valor) :-
asserta(conhece(sim,Atributo,Valor)).
processa(R,Atributo,Valor) :-
asserta(conhece(R,Atributo,Valor)),!,
fail.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% questiona/3
%
% Recurso a Menus:
% sao apresentados ao utilizador os valores
% que cada atributo pode assumir.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
questiona(Atr,Val,_) :-
conhece(sim,Atr,Val).
questiona(Atr,_,_) :-
conhece(sim,Atr,_), !, fail.
questiona(Atr,Val,ListaOpcoes) :-
write('Qual o valor para '),
write(Atr),
write('? '), nl,
write(ListaOpcoes), nl,
read(X),
processa(X,Atr,Val,ListaOpcoes).
processa(Val,Atr,Val,_) :-
asserta(conhece(sim,Atr,Val)).
processa(X,Atr,_,ListaOpcoes) :-
member(X,ListaOpcoes),
asserta(conhece(sim,Atr,X)), !, fail.
processa(X,Atr,Val,ListaOpcoes) :-
write(X),
write(' nao e valor aceite!'), nl,
questiona(Atr,Val,ListaOpcoes).
O conhecimento dos peritos, e os seus processos de raciocínio, nem sempre podem ser modelados usando a lógica booleana e as suas técnicas de inferência: muitas vezes o conhecimento é incerto. A incerteza pode-se manifestar de diversas formas:
Se o investidor é de meia idade e tem um salário baixo Então o investidor encaixa no perfil de um investidor de baixo risco.
O perito pode não confiar em absoluto nesta regra (usualmente os investidores com estas características são investidores de baixo risco, mas nem sempre...). Um factor de confiança de 90% pode ser associada à regra que pode ser interpretada como significando que se o investidor satisfaz as condições da regra então ele é classificado como ``investidor de baixo risco'' com uma certeza de 90%. Mas também pode haver incerteza em saber quando as condições da regra são satisfeitas ou não. Podemos só estar 80% certos que o ordenado do investidor é baixo. Nesse caso, qual a certeza de o perfil do investidor ser um perfil de baixo risco? Deve ser menor do que 90%, mas como combinamos as incertezas? Outro factor que contribui para a incerteza é que os termos ``meia idade'' ou ``salário baixo'' são inerentemente difusos e vagos. Como tratar estes termos linguísticos imprecisos? Se fixarmos um intervalo para definir o termo ``meia idade'', por exemplo [45, 55], então o que dizer de uma pessoa que tem 44 anos, 11 meses e alguns dias? A regra não será aplicada a este investidor. O predicado idade tem um intervalo de difinição contínuo e discretizar este intervalo em subintervalos, correspondentes aos conceitos de novo, meia idade, etc., introduz o problema de lidar com os pontos fronteiros.
Introdução
A lógica difusa (Fuzzy logic) é uma tentativa de lidar com conhecimento vago. A teoria dos conjuntos vagos (ou conjuntos difusos) foi desenvolvida nos anos 60 e generaliza as lógicas de n-valores. Numa lógica de n-valores, o conjunto de valores verdade foi estendido do 0 ou 1 (verdadeiro ou falso) para valores no conjunto de verdade
|
Os peritos incorporam muitas vezes, nos seus processos de raciocínio, conceitos qualitativos tais como alto, baixo, calor, etc. e quantificadores como muito, pouco, normalmente, algumas vezes, etc. A imprecisão inerente nestes termos, é naturalmente implementada com a lógica difusa. O raciocínio é depois feito usando inferência difusa. Algumas das aplicações da lógica difusa são:
Na teoria dos conjuntos tradicional, um conjunto A pode ser definido em termos de uma função
|
Um conjunto difuso A é definido por uma função
|
Como exemplo, considere-se o conceito alto no universo
de todos os estudantes, docentes e funcionários, da Universidade de
Aveiro. Na lógica booleana, uma pessoa ou é alta ou
não. Assim sendo, teríamos de escolher um limiar. Todos os
elementos (pessoas) do universo (conjunto U) cuja altura fosse maior
que esse limiar seriam classificadas como altas e aquelas com altura
inferior ao limiar de não altas. Em contraste, na teoria
dos conjuntos vagos um valor de pertença é associado a cada
altura, indicando a quantidade de confiança em ser alto. A uma
altura de 1m e 90cm podemos associar o valor 1.0 (pessoa sem
dúvida alta no universo da Univ. de Aveiro); enquanto a uma
altura de 1m e 80cm podemos associar um valor de pertença
malto(1.80) = 0.90 e a 1m e 55cm malto(1.55) = 0.02.
A construção apropriada da função de pertença
m, é uma das principais dificuldades no uso da lógica
e inferência difusa. Os métodos, que até agora foram
propostos, são experimentais e ad hoc.
O suporte de um conjunto vago A, sup(A), é definido como o conjunto de elementos do universo cujo grau de pertença é estritamente positivo: sup(A) = { u Î U : mA(u) > 0}.
Um conjunto vago A de suporte finito, pode ser denotado por
|
Termos linguísticos
Os graus de certeza de uma frase são representados por termos linguísticos como possível, muito possível, etc. Por exemplo, podemos dizer que: ``É muito provável que o Sr. António seja rico''. Aqui rico é um conjunto vago (por exemplo definido pelo rendimento anual bruto da pessoa) e muito provável um termo linguístico que associa um valor de verdade à afirmação de que o Sr. António é rico.
Quando a pertença de um elemento num conjunto vago é expressa por tais termos linguísticos, temos de definir as funções de pertença para esses quantificadores, de modo a exprimir o seu significado. Por exemplo, se A é um conjunto vago podemos definir a função de pertença dos quantificadores muito, mais ou menos e não como se segue:
| |||||||||||
Operações com conjuntos vagos
Existem, na literatura especializada, muitas definições alternativas para as operações de união, intersecção, ... de conjuntos difusos. As mais usadas são as seguintes:
| ||||||
Lógica difusa em Prolog
De seguida segue-se uma possível implementação da lógica difusa em Prolog. Testamos o programa num problema de Tomada de Decisão. O objectivo é construir um ``sistema pericial'' para apoio a hotéis. Concretamente pretendemos ajudar na decisão: ``ligo ou não ligo o aquecedor?''
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Implementacao de Logica Difusa em Prolog.
% Delfim F. Marado Torres, 8/Junho/1999
%
% Exemplificacao:
%
% ?- ligaAquecedor(C).
%
% devolve em C um valor entre 0 e 1.
% Os conselhos peremptorios sao:
% C = 1 <=> aquecedor deve estar ligado;
% C = 0 <=> aquecedor deve estar desligado.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Um conjunto difuso e' representado pelo facto
%
% conjuntoDifuso(NomeConjunto,[ [X1,Y1], ..., [Xn,Yn] ]).
%
% O segundo argumento e' uma lista de listas [Xi,Yi]
% onde Xi e' um elemento do universo e Yi o respectivo
% grau de pertenca: mu(Xi) = Yi.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
conjuntoDifuso(temperaturasAltas,[[0,0.0],[5,0.2],[10,0.4],[20,0.8]]).
conjuntoDifuso(pertoDe(0), [[0,1.0],[5,0.8],[10,0.5],[20,0.0]]).
conjuntoDifuso(pertoDe(5), [[0,0.8],[5,1.0],[10,0.6],[20,0.2]]).
conjuntoDifuso(pertoDe(10),[[0,0.5],[5,0.6],[10,1.0],[20,0.9]]).
conjuntoDifuso(pertoDe(20),[[0,0.0],[5,0.2],[10,0.9],[20,1.0]]).
%%%%%%%%%%%%%%%%%%%%%%%%%
% 'Funcao de pertenca'
%%%%%%%%%%%%%%%%%%%%%%%%%
pertence(X,C,GP) :-
conjuntoDifuso(C,L),
pertence([X,GP],L).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Quantificadores vagos, tal como o 'muito', sao
% definidos por regras do seguinte tipo:
% Se [X,P] esta' na lista do conjunto A
% Entao [X,P^2] esta' na lista muito(A)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
conjuntoDifuso(muito(A),LMA) :-
conjuntoDifuso(A,LA),
mu_muito(LA,LMA).
mu_muito([],[]).
mu_muito([[X,Y]|R],[[X,Y2]|RM]) :-
Y2 is Y * Y,
mu_muito(R,RM).
conjuntoDifuso(mais_ou_menos(A),LMMA) :-
conjuntoDifuso(A,LA),
mu_mm(LA,LMMA).
mu_mm([],[]).
mu_mm([[X,Y]|R],[[X,RY]|RM]) :-
RY is sqrt(Y),
mu_mm(R,RM).
conjuntoDifuso(nao(A),LNA) :-
conjuntoDifuso(A,LA),
mu_nao(LA,LNA).
mu_nao([],[]).
mu_nao([[X,Y]|R],[[X,CY]|RM]) :-
CY is 1 - Y,
mu_nao(R,RM).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Operacoes sobre conjuntos vagos
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
conjuntoDifuso(e([A]),LA) :-
conjuntoDifuso(A,LA).
conjuntoDifuso(e([A,B]),LAB) :-
conjuntoDifuso(A,LA),
conjuntoDifuso(B,LB),
mu_e(LA,LB,LAB).
conjuntoDifuso(e([A|R]),L) :-
conjuntoDifuso(e([A,e(R)]),L).
mu_e([],_,[]).
mu_e([[X,Y1]|R],L2,[[X,Y]|RE]) :-
pertence([X,Y2],L2),
min(Y1,Y2,Y),
mu_e(R,L2,RE).
mu_e([_|R],L2,RE) :-
mu_e(R,L2,RE).
conjuntoDifuso(ou([A]),LA) :-
conjuntoDifuso(A,LA).
conjuntoDifuso(ou([A,B]),LAB) :-
conjuntoDifuso(A,LA),
conjuntoDifuso(B,LB),
mu_ou(LA,LB,LAB).
conjuntoDifuso(ou([A|R]),L) :-
conjuntoDifuso(ou([A,ou(R)]),L).
mu_ou([],L,L).
mu_ou([[X,Y1]|R],L2,[[X,Y]|RE]) :-
pertence([X,Y2],L2),
max(Y1,Y2,Y),
tira([X,Y2],L2,NL2),
mu_ou(R,NL2,RE).
mu_ou([[X,Y1]|R],L2,[[X,Y1]|RE]) :-
mu_ou(R,L2,RE).
conjuntoDifuso(implica(Ant,Cons),L) :-
conjuntoDifuso(ou([nao(Ant),Cons]),L).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Regra difusa (vaga):
%
% Se
% a Temperatura Exterior nao e' alta e
% a Temperatura Interior esta' proxima
% da Exterior
% Entao
% o Aquecedor deve estar ligado.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
aquecedorLigado(GP) :-
temperaturaExterior(TE),
temperaturaInterior(TI),
pertence(TE,e([nao(temperaturasAltas),pertoDe(TI)]),GP), !.
%%%%%%%%%%%%%%%%%
% Interface
%%%%%%%%%%%%%%%%%
temperaturaExterior(TE) :-
temperatura(exterior,TE).
temperaturaInterior(TI) :-
temperatura(interior,TI).
temperatura(M,T) :-
repeat,
nl,
write('Valor aproximado (0, 5, 10 ou 20) da temperatura '),
write(M), write(' = '),
read(T),
pertence(T,[0,5,10,20]), nl.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Predicados Auxiliares
%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pertence(X,[X|_]).
pertence(X,[_|R]) :-
pertence(X,R).
tira(X,[X|R],R).
tira(X,[Y|R],[Y|T]) :-
tira(X,R,T).
min(X,Y,X) :- X =< Y.
min(_,Y,Y).
max(X,Y,X) :- X >= Y.
max(_,Y,Y).
Pense numa maneira, e implemente-a, de alterar o perito.pl de modo a permitir dar resposta a perguntas do utilizador do tipo ``Porque é que quer saber isto?''; ``Como é que chegou a esta conclusão?''.
Altere o perito.pl de modo a permitir lidar com conhecimento incerto, por meio da abordagem difusa atrás considerada.