Agradeço comentários, sugestões ou correcções. O meu endereço de correio electrónico é < delfim@mat.ua.pt > . Desde já obrigado.

1  Sistemas Periciais

1.1  Introdução e generalidades sobre os Sistemas Periciais

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:

Um SP é formado por um conjunto de programas que manipulam conhecimento, com a finalidade de resolver problemas num domínio especializado que normalmente requer peritos humanos.

Os SP diferem dos programas de computador convencionais, em vários aspectos importantes. Alguns deles são:

Os SP surgiram em laboratórios de investigação, de umas poucas universidades, durante os anos 60 e 70. O primeiro SP a ser finalizado foi o DENDRAL, desenvolvido na Universidade de Stanford em finais dos anos 60. Este sistema era capaz de determinar a estrutura de componentes químicas, a partir de uma especificação dos elementos constituintes e da massa espectral do composto. Durante os testes, o DENDRAL descobriu um número de estruturas anteriormente desconhecidas dos peritos químicos! Este sistema conduziu depois ao Meta-DENDRAL, um módulo de aprendizagem para o DENDRAL, que era capaz de aprender novo conhecimento (novas regras) a partir de exemplos positivos: uma forma de aprendizagem indutiva. Depois do sistema DENDRAL estar completo, começou o desenvolvimento do MYCIN na Universidade de Stanford. O MYCIN diagnosticava doenças infeciosas do sangue e recomendava uma lista de terapias para o doente.

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 []

1.2  Implementação de um Sistema Pericial em Prolog

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.

1.2.1  Conhecimento

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).

1.2.2  Concha

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).

1.3   Incerteza

1.3.1  Motivação

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:

Muitos domínios são, por inerência, imprecisos e vagos. Em tais domínios, dados conflituosos podem surgir devido à presença de vários agentes com opiniões diferentes ou mesmo conflituosas. Nestas circunstâncias, o desempenho de um SP depende muito da maneira como a incerteza é gerida pelo sistema. Por esse motivo, um número de teorias alternativas foram desenvolvidas para gerir a incerteza. A maioria dessas teorias são quantitativas: é proposto um esquema de introdução de medidas que quantificam, numericamente, a incerteza e especificam como propagar e combinar essas medidas numéricas de incerteza durante o raciocínio. Como exemplo consideremos a seguinte regra que descreve uma heurística descrita por um perito em investimentos:

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.

1.3.2  Conjuntos vagos e Lógica Vaga

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

Tn = ì
í
î
0,  1
n-1
2
n-1
¼ n-2
n-1
, 1 ü
ý
þ
Por exemplo, numa lógica de 3-valores os valores de verdade permitidos são 0, 1/2 e 1, correspondendo ao falso, desconhecido e verdadeiro. A lógica difusa é uma lógica com infinitos valores, onde os valores de verdade estão no intervalo contínuo [0, 1].

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:

Teoria dos conjuntos vagos

Na teoria dos conjuntos tradicional, um conjunto A pode ser definido em termos de uma função

mA : U ® {0, 1},
do universo de discurso U no conjunto discreto {0, 1}, onde mA(x) = 1 se x pertence ao conjunto A e 0 caso contrário.

Um conjunto difuso A é definido por uma função

mA : U ® [0, 1].
O domínio desta função pode ser discreto ou contínuo. A imagem de um elemento x, mA(x), é um número real no intervalo fechado [0, 1] que indica a grau de pertença de x ao conjunto A. Note-se que este ``grau de pertença'' de um elemento no conjunto, não é a probabilidade do elemento pertencer ao conjunto: os graus de pertença de todos os elementos de U, não têm necessariamente de totalizar um.

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

A = n
å
i = 1 
xi / mi
onde sup(A) = { x1, x2¼, xn} e mi é o grau de pertença de xi.

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:

mmuito(A)(x) = mA2(x - d)
mmaisoumenos(A)(x) =   æ
Ö

m
 

A 
(x+d)
mnao(A)(x) = 1 - mA(x)
onde d é uma constante.

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:

mAÇB(x) = min{mA(x), mB(x)}
mAÈB(x) = max{mA(x), mB(x)}
mAÞ B(x) = mØA ÚB(x) = max{1-mA(x), mB(x)}

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).

1.4  Exercí cios

Geração de Explicações

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?''.

Tratamento de conhecimento incerto

Altere o perito.pl de modo a permitir lidar com conhecimento incerto, por meio da abordagem difusa atrás considerada.

References

[]
Peter Lucas and Linda Der Gaag, Principles of Expert Systems, Addison Wesley, 1991.

[]
Dennis Merritt, Building Expert Systems in Prolog, Springer Verlag, 1989.

[]
Chris Nikolopoulos, Expert Systems, Introduction to First and Second Generation and Hybrid Knowledge Based Systems, Marcel Dekker, 1997.

[]
Dan W. Patterson, Introduction to Artificial Intelligence & Expert Systems, Prentice Hall, 1990.

[]
Donald A. Waterman, Building expert systems, Addison Wesley, 1983.

[]
Donald A. Waterman, A guide to expert systems, Addison Wesley, 1986.