Assuntos para 2o exercício
Métodos de Computação Inteligente
1o semestre de 2002
Jacques Robin
CIn-UFPE
Assuntos para o 2o exercício



Tema do 2o exercício: sistemas especialistas
Leitura: capítulos 15 e 16 de Prolog Programming for Artificial
Intelligence, 3rd Ed. de Ivan Bratko
Tarefas:
 Implementar um shell de sistema especialista com funcionalidades de:




Máquina de inferência
Aquisição interativa de conhecimento
Justificação das perguntas de aquisição
Explicação de raciocínio
 Implementar uma base de conhecimento brinquedo na linguagem de
representação do conhecimento aceita pelo shell
 Testar o shell com essa base de conhecimento

Equipes de 4 alunos
Assuntos para o 2o exercício





Sistema especialista baseado em redes bayesianas em
Prolog, Flora, JEOPS ou Java
Sistema especialista combinando encadeamento de
regras para frente e para trás em Prolog, Flora,
JEOPS ou Java
Sistema especialista combinado frames com regras
encadeadas para frente em Prolog ou Java
Sistema especialista combinado frames com regras
encadeadas para trás em Prolog ou Java
2 equipes podem escolher o mesmo assunto, do momento
que escolhem duas linguagens de programação diferentes
Implementação Prolog de máquina de
inferência encadeando regras
Codificação da base de fatos
•
fact(TermoProlog).
Codificação da base de regras
•
•
•
if P1 conj ... conj Pn then C onde
P1 ... Pn e C são termos Prolog
conj é and ou or
Codificação das consultas
•
forward deriva todos os fatos
Exemplo de base de conhecimento
if hallWet and kitchenDry then leakInBathroom
if hallWet and bathroonDry then problemInKitchen
if windowClosed or noRain then noWaterFromOutside
if problemInKitchen and noWaterFromOutside
then leakInKitchen
Exemplos de consulta
?- forward
Derive: problemInKitchen
Derive: noWaterFromOutside
Derive: leakInKitchen
No more facts
?- is_true(leak_in_kitchen).
yes
Implementação Prolog de máquina de
inferência encadeando regras
Para frente:
::::-
op( 800, fx, if).
op( 700, xfx, then).
op( 300, xfy, or).
op( 200, xfy, and).
forward :- new_derived_fact(P), !,
write('Derived: '), write(P), nl, assert(fact(P)),
forward ; write('No more facts').
new_derived_fact(Concl) :- if Cond then Concl,
not fact(Concl), composed_fact(Cond).
composed_fact(Cond) :- fact(Cond).
composed_fact(Cond1 and Cond2) :composed_fact(Cond1), composed_fact(Cond2).
composed_fact(Cond1 or Cond2) :composed_fact(Cond1) ; composed_fact(Cond2).
Pata trás:
::::-
op( 800, fx, if).
op( 700, xfx, then).
op( 300, xfy, or).
op( 200, xfy, and).
is_true( P) :- fact( P).
is_true( P) :- if Condition then P,
is_true( Condition).
is_true( P1 and P2) :- is_true( P1), is_true( P2).
is_true( P1 or P2) :- is_true( P1) ; is_true( P2).
Implementação Prolog de máquina de
inferência encadeando regras para trás
Implementação Prolog de máquina de
inferência baseada em frames
Codificação dos triplos <frame slot value>
•
•
fatos frame(Slot,Value).
com um predicado por cada frame do domínio
Codificação dos gatilhos
•
•
regras da forma: trigger(Frame,Value) :- ....
com um predicado trigger por cada gatilho do domínio
Associação dos triplos <frame slot trigger>
•
•
fatos frame(Slot, execute(gatilho(Frame,Value), Frame,Value)).
um por par <frame trigger> do domínio
Codificação das consultas
•
calcular valor de um slot de um frame
value(Frame, Slot,Value)
Implementação Prolog de máquina de
inferência baseada em frames
Hierarquia de conceitos:
Sobrescrita de propriedades default:
bird(a_kind_of, animal).
albatross(a_kind_of, bird).
kiwi(a_kind_of, bird).
kiwi(moving_method, walk).
kiwi(active_at, night).
albert(size, 120).
ross(size, 40).
Propriedades dos conceitos e default das
suas especializações e instâncias:
Gatilho:
bird(moving_method, fly).
bird(active_at, daylight).
albatross(colour, black_and_white).
albatross(size, 115).
kiwi(size, 40).
kiwi(colour, brown).
animal(relative_size,
execute(relative_size(Object, Value),
Object, Value) ).
relative_size(Object,RelativeSize) :value(Object,size,Objsize),
value(Object,instance_of,ObjClass),
value(ObjClass,size,ClassSize),
RelativeSize is ObjSize/ClassSize * 100.
Instâncias de conceitos:
Exemplo de consultas
albert(instance_of, albatross).
ross(instance_of, albatross).
?- value(ross,moving_method,M).
M = fly.
?- value(ross,relative_size,R)
R = 34.78.
Implementação Prolog de máquina de
inferência baseada em frames
% Valor declarada no próprio frame:
value(Frame,Slot,Value) :value(Frame,Frame,Slot,Value).
% Valor herdada do super conceito imediato:
value(Frame,SuperFrame,Slot,Value) :Query =.. [SuperFrame,Slot,Information],
call(Query),
process(Information,Frame,Value), !.
% Valor herdada de conceitos mais altos na
hierarquia:
value(Frame,SuperFrame,Slot,Value) :parent(SuperFrame,ParentSuperFrame),
value(Frame,ParentSuperFrame,Slot,Value).
% Acessar super-conceito na hierarquia:
parent(Frame,ParentFrame) :(Query =.. [Frame,a_kind_of,ParentFrame]
; Query =.. [Frame,instance_of,ParentFrame]),
call(Query).
% Information é derivada por um gatilho
process(execute(Goal,Frame,Value),Frame,Value)
:- !, call(Goal).
% Information é um valor declarado
process(Value,_,Value).
Implementação Prolog de máquina de
inferência baseada redes bayesianas
Codificação da estrutura da rede
•
predicado parent(ParentNode, Node)
Codificação das probabilidades da rede
•
•
predicado p(Node, PriorProbability)
predicado p(Node, ListOfParentNodeValues,
ConditionalProbability)
i.e., p(N0 | N1  ...  Nn)
Codificação das consultas a rede
•
predicado probs(Node, ListOfNodeValues
ConditionalProbability)
i.e., p(N0 | N1  ...  Nn)
Exemplo de rede:
parent(burglary, sensor).
parent(lightning, sensor).
parent(sensor, alarm).
parent(sensor, call).
p(burglary, 0.001).
p(lightning, 0.02).
p(sensor, [ burglary, lightning], 0.9).
p(sensor, [ burglary, not lightning], 0.9).
p(sensor, [ not burglary, lightning], 0.1).
p(sensor, [ not burglary, not lightning], 0.001).
p(alarm, [ sensor], 0.95).
p(alarm, [ not sensor], 0.001).
p(call, [ sensor], 0.9).
p(call, [ not sensor], 0.0).
Exemplo de consulta:
?- prob(burglary, [call, not lightning], P).
P = 0.473934
Implementação Prolog de máquina de
inferência baseada redes bayesianas
prob([X | Xs], Cond, P) :- !, prob(X, Cond, Px),
prob(Xs, [X | Cond], PRest), P is Px * PRest.
prob([], _, 1) :- !.
prob(X, Cond, 1) :- member(X, Cond), !.
prob(X, Cond, 0) :- member(not X, Cond), !.
prob(not X, Cond, P) :- !,
prob(X, Cond, P0), P is 1 - P0.
prob(X, Cond0, P) :- delete(Y, Cond0, Cond),
predecessor(X, Y), !, prob(X, Cond, Px),
prob(Y, [X | Cond], PyGivenX),
prob(Y, Cond, Py), P is Px * PyGivenX / Py.
prob(X, Cond, P) :- p(X, P), !.
% Coloca
prob(X, Cond, P) :- !,
findall((CONDi,Pi), p(X,CONDi,Pi), CPlist),
sum_probs(CPlist, Cond, P).
% Calcula p(X|Cond) como somatórios nos
% predecessores Si de X na rede de
% p(X|Si)*p(Si|Cond)
sum_probs([], _, 0).
sum_probs([(COND1,P1)|CondsProbs], COND, P)
:- prob(COND1, COND, PC1),
sum_probs(CondsProbs, COND, PRest),
P is P1 * PC1 + PRest.
% Busca por predecessores subindo na rede
predecessor(X, not Y) :- !, predecessor(X, Y).
predecessor(X, Y) :- parent(X, Y).
predecessor(X, Z) :- parent(X, Y),
predecessor(Y, Z).
% Predicados utilitários
member(X, [X | _]).
member(X, [_ | L]) :- member(X, L).
delete(X, [X | L], L).
delete(X, [Y | L], [Y | L2]) :- delete(X, L, L2).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
Codificação das regras para o shell:


RuleName :: if Condition then Conclusion,
onde:
 Condition é um termo Prolog
 Conclusion são termos Prolog conectados por and, or ou not
Codificação dos fatos para o shell:


fact :: ShellFact
onde: ShellFact é um fato Prolog ou uma regras Prolog
Sintaxe natural:

Operadores Prolog podem ser usados para definir propriedades podem ser definidos e aparecer nas
regras e fatos do shell para tornar a aparência da base de conhecimento “mais natural”
Aquisição interativa dos fatos via o shell:

askable(Term) indica que o termo Prolog Term é um dos fatos do shell cujo valor (os valores das
suas variáveis não instanciadas) pode ser pedido para o usuário durante o raciocínio
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
% Operadores de ‘sintaxe natural’
:- op( 100, xfx, [ has, gives, 'does not', eats, lays, isa]).
:- op( 100, xf, [ swims, flies]).
% Base de regras
rule1 :: if Animal has hair or Animal gives milk then Animal isa mammal.
rule2 :: if Animal has feathers or (Animal flies and Animal lays eggs) then Animal isa bird.
rule3 :: if Animal isa mammal and (Animal eats meat or (Animal has 'pointed teeth' and
Animal has claws and
Animal has 'forward pointing eyes' )
then Animal isa carnivore.
rule4 :: if Animal isa carnivore and Animal has 'tawny color' and Animal has 'dark spots'
then Animal isa cheetah.
rule5 :: if Animal isa carnivore and Animal has 'tawny color' and Animal has 'black stripes'
then Animal isa tiger.
rule6 :: if Animal isa bird and Animal 'does not' fly and Animal swims then Animal isa penguin.
rule7 :: if Animal isa bird and Animal isa 'good flyer' then Animal isa albatross.
% Base de fatos
fact :: X isa animal :- member( X, [cheetah, tiger, penguin, albatross]).
askable( _ gives _, 'Animal' gives 'What'). askable( _ flies, 'Animal' flies).
askable( _ lays eggs, 'Animal' lays eggs). askable( _ eats _, 'Animal' eats 'What').
askable( _ has _, 'Animal' has 'Something'). askable( _ 'does not' _, 'Animal' 'does not' fly).
askable( _ swims, 'Animal' swims). askable( _ isa 'good flyer', 'Animal' isa 'good flyer').
member(X,[X | _]).
member( X, [_ | Rest]) :- member( X, Rest).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
% Base de regras
broken_rule :: if on(Device) and device( Device) and (not working(Device))
and connected( Device, Fuse) and proved( intact( Fuse))
then proved( broken( Device)).
fuse_ok_rule :: if connected( Device, Fuse) and working( Device) then proved( intact( Fuse)).
fused_rule :: if connected( Device1, Fuse) and on( Device1) and (not working( Device1))
and samefuse( Device2, Device1) and on( Device2) and (not working( Device2))
then proved( failed( Fuse)).
same_fuse_rule :: if connected( Device1, Fuse) and connected( Device2, Fuse)
and different( Device1, Device2)
then samefuse( Device1, Device2).
device_on_rule :: if working( Device) then on( Device).
% Base de fatos
fact :: different( X, Y) :- not (X = Y).
fact :: device( heater). fact :: device( light1). fact :: device( light2). fact :: device( light3).
fact :: device( light4).
fact :: connected( light1, fuse1). fact :: connected( light2, fuse1). fact :: connected( heater, fuse1).
fact :: connected( light3, fuse2). fact :: connected( light4, fuse2).
askable( on(D), on('Device')). askable( working(D), working('Device')).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
Question, please:
peter isa tiger.
Is it true: peter has hair?
yes.
Is it true: peter eats meat?
no.
Is it true: peter has pointed teeth?
yes.
Is it true: peter has claws?
why.
To investigate, by rule3, peter is a carnivore
To investigate, by rule 5, peter is a tiger
This was your question.
Is it true: peter has claws?
yes.
Is it true: peter has forward pointing eyes?
yes.
Is it true: peter has tawny colour?
yes.
Is it true: peter has black stripes?
yes.
(peter is a tiger) is true
Would you like to see how?
yes.
peter is a tiger was derived by rule5 from
peter isa carnivore was derived by rule3 from
peter is mamamal was derived by rule1 from
peter has hair was told
and peter has pointed teeth was told
and peter has claws was told
and peter has forward pointing eyes was told
and peter has tawny color was told
and peter has black stripes was told
Question, please:
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
Predicados principais:
expert: dispara o sistemas especialista
 explore(Goal,Trace,Answer):
 dispara encadeamento de regras para trás
para tentar provar objetivo Goal
 guarda em Trace a lista dos objetivos
intermediários que foram provados, junto
a regra utilizada para prova cada um
 guarda em Answer a árvore da prova de
Goal
 useranswer(Goal,Trace,Answer):

 caso Goal for askable, pergunta Goal para o
usuário
 caso a resposta a essa pergunta for yes or no,
instância Answer com essa resposta
 caso a resposta a essa pergunta for why,
apresenta Trace como respota
 usa getreply(Reply) para recuperar de maneira
robusta a resposta do usuário

present(Answer): apresenta Answer para o
usuário como resposta a perguntas de tipo
how?
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
% Operadores do shell
:- op( 900, xfx, ::).
:- op( 800, xfx, was).
:- op( 870, fx, if).
:- op( 880, xfx, then).
:- op( 550, xfy, or).
:- op( 540, xfy, and).
:- op( 300, fx, 'derived by').
:- op( 600, xfx, from).
:- op( 600, xfx, by).
:- op( 900, fy, not).
% Predicado driver do shell
expert :- getquestion(Question),
(answeryes(Question) ; answerno( Question)).
getquestion(Question) :- nl,
write( 'Question, please '), nl, read( Question).
answeryes(Question) :- markstatus( negative),
explore( Question, [], Answer), positive( Answer),
markstatus( positive), present( Answer), nl,
write('More solutions? '), getreply( Reply),
Reply = no.
answerno( Question) :retract(no_positive_answer_yet), !,
explore( Question, [], Answer), negative( Answer),
present( Answer), nl,
write('More negative solutions? '),
getreply( Reply), Reply = no.
markstatus( negative) :assert(no_positive_answer_yet).
markstatus( positive) :retract(no_positive_answer_yet), ! ; true.
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
explore(Goal,Trace, _) :- copy_term( Goal, Copy), member( Copy by Rule, Trace),
instance_of( Copy, Goal), !, fail.
explore(Goal,Trace, Goal is true was 'found as a fact') :- fact :: Goal.
explore(Goal,Trace, Goal is TruthValue was 'derived by' Rule from Answer) :Rule :: if Condition then Goal, explore( Condition, [Goal by Rule | Trace], Answer),
truth( Answer, TruthValue).
explore( Goal1 and Goal2, Trace, Answer) :- !, explore( Goal1, Trace, Answer1),
continue( Answer1, Goal1 and Goal2, Trace, Answer).
explore( Goal1 or Goal2, Trace, Answer) :- exploreyes( Goal1, Trace, Answer) ;
exploreyes( Goal2, Trace, Answer).
explore( Goal1 or Goal2, Trace, Answer1 and Answer2) :- !, not exploreyes( Goal1, Trace, _),
not exploreyes( Goal2, Trace, _), explore( Goal1, Trace, Answer1), explore( Goal2, Trace, Answer2).
explore( not Goal, Trace, Answer) :- !, explore( Goal, Trace, Answer1), invert( Answer1, Answer).
explore( Goal, Trace, Goal is Answer was told) :- useranswer( Goal, Trace, Answer).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
exploreyes( Goal, Trace, Answer) :- explore( Goal, Trace, Answer), positive( Answer).
continue( Answer1, Goal1 and Goal2, Trace, Answer) :positive( Answer1), explore( Goal2, Trace, Answer2),
(positive( Answer2), Answer = Answer1 and Answer2 ; negative( Answer2), Answer = Answer2 ).
continue( Answer1, Goal1 and Goal2, _, Answer1) :- negative( Answer1).
truth( Question is TruthValue was Found, TruthValue) :- !.
truth( Answer1 and Answer2, TruthValue) :- truth( Answer1, true), truth( Answer2, true), !,
TruthValue = true ; TruthValue = false.
positive( Answer) :- truth( Answer, true).
negative( Answer) :- truth( Answer, false).
invert( Quest is true was Found, (not Quest) is false was Found).
invert( Quest is false was Found, (not Quest) is true was Found).
instantiated( Term) :- numbervars(Term, 0, 0).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
useranswer( Goal, Trace, Answer) :- askable( Goal, _), freshcopy( Goal, Copy),
useranswer( Goal, Copy, Trace, Answer, 1).
useranswer( Goal, _, _, _, N) :- N > 1, instantiated( Goal), !, fail.
useranswer( Goal, Copy, _, Answer, _) :- wastold( Copy, Answer, _), instance_of( Copy, Goal), !.
useranswer( Goal, _, _, true, N) :- wastold( Goal, true, M), M >= N.
useranswer( Goal, Copy, _, Answer, N) :- end_answers( Copy), instance_of( Copy, Goal), !,
not wastold( Goal, _, _), Answer = false.
useranswer( Goal, _, Trace, Answer, N) :- askuser( Goal, Trace, Answer, N).
askuser( Goal, Trace, Answer, N) :- askable( Goal, ExternFormat),
format( Goal, ExternFormat, Question, [], Variables),
ask( Goal, Question, Variables, Trace, Answer, N).
ask( Goal, Question, Variables, Trace, Answer, N) :- nl,
( Variables = [], !, write( 'Is it true: ') ; write( 'Any (more) solution to: ')),
write( Question), write('? '), getreply( Reply), !,
process( Reply, Goal, Question, Variables, Trace, Answer, N).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
process( no, Goal, _, _, _, false, N) :- freshcopy( Goal, Copy), wastold( Copy, true, _), !,
assertz( end_answers( Goal)), fail ; nextindex( Next), assertz( wastold( Goal, false, Next)).
format( Var, Name, Name, Vars, [Var/Name|Vars]) :- var( Var), !.
format( Atom, Name, Atom, Vars, Vars) :- atomic( Atom), !, atomic( Name).
format( Goal, Form, Question, Vars0, Vars) :- Goal =.. [Functor|Args1], Form =.. [Functor|Forms],
formatall( Args1, Forms, Args2, Vars0, Vars), Question =.. [Functor|Args2], !.
format( Goal, _, Question, Vars0, Vars) :- format( Goal, Goal, Question, Vars0, Vars).
formatall( [], [], [], Vars, Vars).
formatall( [X|XL], [F|FL], [Q|QL], Vars0, Vars) :- formatall( XL, FL, QL, Vars0, Vars1),
format( X, F, Q, Vars1, Vars).
askvars( []).
askvars( [Variable/Name|Variables]) :- nl, write( Name), write( ' = '), read( Variable), askvars( Variables).
showtrace([]) :- nl, write('This was your question'), nl.
showtrace( [Goal by Rule | Trace]) :- nl, write( 'To investigate, by '), write( Rule), write( ', '),
write( Goal), showtrace( Trace).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
instance_of( Term, Term1) :- copy_term( Term1, Term2), numbervars( Term2, 0, _), !, Term = Term2.
freshcopy( Term, FreshTerm) :- asserta( copy( Term)), retract( copy( FreshTerm)), !.
nextindex( Next) :- retract( lastindex( Last)), !, Next is Last + 1, assert( lastindex( Next)).
:- assert( lastindex( 0)), assert( wastold( dummy, false, 0)), assert( end_answers( dummy)).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
present( Answer) :- nl, showconclusion( Answer), nl, write( 'Would you like to see how?'),
nl, getreply( Reply), ( Reply = yes, !, show( Answer) ; true ).
showconclusion( Answer1 and Answer2) :- !, showconclusion( Answer1), write( ' and '),
showconclusion( Answer2).
showconclusion( Conclusion was Found) :- write( Conclusion).
show( Solution) :- nl, show( Solution, 0), !.
show( Answer1 and Answer2, H) :- !, show( Answer1, H), tab( H), write(and), nl, show( Answer2, H).
show( Answer was Found, H) :- tab( H), writeans( Answer), nl, tab( H), write( ' was '), show1( Found, H).
show1( Derived from Answer, H) :- !, write( Derived), write(' from'), nl, H1 is H + 4, show( Answer, H1).
show1( Found, _) :- write( Found), nl.
writeans( Goal is true) :- !, write( Goal).
writeans( Answer) :- write( Answer).
getreply(Meaning) :- read( Reply), means( Reply, Meaning), ! ;
nl, write('Answer unknown, try again please!'), nl, getreply( Meaning).
Implementação Prolog de shell de sistema
especialista encadeando regras para trás
means( why, why) :- !.
means( w, why) :- !.
means( yes, yes) :- !.
means( y, yes) :- !.
means( no, no) :- !.
means( n, no) :- !.
member( X, [X|_]).
member( X, [_|L]) :- member( X, L).
numbervars( Term, N, Nplus1) :- var( Term), !, Term = var/N, Nplus1 is N + 1.
numbervars( Term, N, M) :- Term =.. [Functor | Args], numberargs( Args, N, M).
numberargs( [], N, N) :- !.
numberargs( [X | L], N, M) :- numbervars( X, N, N1), numberargs( L, N1, M).
Download

yes.