Jogo dos Animais
Está é uma versão Prolog do jogo de identificação de animais (sistema especialista simples) apresentado em um programa 'Lisp' no Capítulo 6 de Winston e Horn (1985)[1]. Carregue o arquivo e faça a consulta ?- go
. O programa usa suas regras de identificação para determinar o animal que você escolheu.
/* animal.pro
animal identification game.
start with ?- go. */
go :- hypothesize(Animal),
write('I guess that the animal is: '),
write(Animal),
nl,
undo.
/* hypotheses to be tested */
hypothesize(cheetah) :- cheetah, !.
hypothesize(tiger) :- tiger, !.
hypothesize(giraffe) :- giraffe, !.
hypothesize(zebra) :- zebra, !.
hypothesize(ostrich) :- ostrich, !.
hypothesize(penguin) :- penguin, !.
hypothesize(albatross) :- albatross, !.
hypothesize(unknown). /* no diagnosis */
/* animal identification rules */
cheetah :- mammal,
carnivore,
verify(has_tawny_color),
verify(has_dark_spots).
tiger :- mammal,
carnivore,
verify(has_tawny_color),
verify(has_black_stripes).
giraffe :- ungulate,
verify(has_long_neck),
verify(has_long_legs).
zebra :- ungulate,
verify(has_black_stripes).
ostrich :- bird,
verify(does_not_fly),
verify(has_long_neck).
penguin :- bird,
verify(does_not_fly),
verify(swims),
verify(is_black_and_white).
albatross :- bird,
verify(appears_in_story_Ancient_Mariner),
verify(flys_well).
/* classification rules */
mammal :- verify(has_hair), !.
mammal :- verify(gives_milk).
bird :- verify(has_feathers), !.
bird :- verify(flys),
verify(lays_eggs).
carnivore :- verify(eats_meat), !.
carnivore :- verify(has_pointed_teeth),
verify(has_claws),
verify(has_forward_eyes).
ungulate :- mammal,
verify(has_hooves), !.
ungulate :- mammal,
verify(chews_cud).
/* how to ask questions */
ask(Question) :-
write('Does the animal have the following attribute: '),
write(Question),
write('? '),
read(Response),
nl,
( (Response == yes ; Response == y)
->
assert(yes(Question)) ;
assert(no(Question)), fail).
:- dynamic yes/1,no/1.
/* How to verify something */
verify(S) :-
(yes(S)
->
true ;
(no(S)
->
fail ;
ask(S))).
/* undo all yes/no assertions */
undo :- retract(yes(_)),fail.
undo :- retract(no(_)),fail.
undo.
O programa é interessante principalmente no que diz respeito a como tenta verificar certas propriedades que usa para tirar conclusões e como faz perguntas e registra as respostas para referência futura. Se uma pergunta 'q' for feita e a resposta for 'yes', essa resposta será registrada afirmando (com o comando assert) yes(q)
e bem-sucedida; caso contrário, a resposta será registrada afirmando(com o comando assert) no(q)
e falhando.
Mesmo as respostas "yes" precisam ser registradas, uma vez que uma resposta "no" subsequente a uma pergunta diferente ao tentar verificar a mesma hipótese pode fazer com que toda a hipótese falhe, mas a mesma resposta "yes" pode levar a uma verificação bem-sucedida de um hipótese diferente mais tarde. É assim que o programa evita fazer a mesma pergunta duas vezes. O método geral de verificação de uma condição 'q' é então verificar se yes(q)
foi armazenado na memória e se foi bem-sucedido ou se no(q)
foi armazenado e falhar, caso contrário, pergunte: ask(q)
.
O Capítulo 6 constrói uma estrutura geral para sistemas especialistas em Prolog.
Veja Também
- Código do Prolog para esta seção.
- 2.18 Cláusulas como dados
- Prolog Tutorial Sumário
Referências
- ↑ Winston, P.H., and Horn, P., Lisp, Addison-Wesley, 1985.