2001-06-06 20:40:57 +01:00
|
|
|
|
|
|
|
:- object(expert,
|
|
|
|
imports(protected::descriptors)).
|
|
|
|
|
|
|
|
|
|
|
|
:- info([
|
2003-02-05 00:15:28 +00:00
|
|
|
author is 'Paulo Moura',
|
2005-03-06 21:19:09 +00:00
|
|
|
version is 1.1,
|
|
|
|
date is 2005/3/6,
|
2001-06-06 20:40:57 +01:00
|
|
|
comment is 'Expert system for bird identification.',
|
|
|
|
source is 'Example adopted from an Amzi! Inc Prolog book.']).
|
|
|
|
|
|
|
|
|
|
|
|
:- public(identify/0).
|
|
|
|
|
|
|
|
:- mode(identify, one).
|
|
|
|
|
|
|
|
:- info(identify/0,
|
|
|
|
[comment is 'Starts a bird identification session.']).
|
|
|
|
|
|
|
|
|
|
|
|
:- private(known_/3).
|
|
|
|
:- dynamic(known_/3).
|
|
|
|
|
|
|
|
:- mode(known_(?nonvar, ?nonvar, ?nonvar), zero_or_more).
|
|
|
|
|
|
|
|
:- info(known_/3, [
|
|
|
|
comment is 'Table of already known facts.',
|
|
|
|
argnames is ['Answer', 'Attribute', 'Value']]).
|
|
|
|
|
|
|
|
|
|
|
|
identify :-
|
|
|
|
::retractall(known_(_, _, _)),
|
|
|
|
write('Bird identification expert system'), nl, nl,
|
|
|
|
forall(
|
|
|
|
(order::leaf(Bird), check(Bird)),
|
|
|
|
(nl, write('Possible identification : '), write(Bird), nl)),
|
|
|
|
nl, write('No (more) candidates found.').
|
|
|
|
|
|
|
|
|
|
|
|
check(Bird) :-
|
|
|
|
forall(
|
|
|
|
(::descriptor(Functor/Arity),
|
|
|
|
functor(Predicate, Functor, Arity),
|
|
|
|
Bird::Predicate),
|
|
|
|
call(Predicate)).
|
|
|
|
|
|
|
|
|
|
|
|
bill(X):-
|
|
|
|
ask(bill, X).
|
|
|
|
|
|
|
|
cheek(X):-
|
|
|
|
ask(cheek, X).
|
|
|
|
|
|
|
|
color(X):-
|
|
|
|
ask(color, X).
|
|
|
|
|
|
|
|
eats(X):-
|
|
|
|
ask(eats, X).
|
|
|
|
|
|
|
|
feed(X):-
|
|
|
|
ask(feed,X).
|
|
|
|
|
|
|
|
feet(X):-
|
|
|
|
ask(feet, X).
|
|
|
|
|
|
|
|
flight(X):-
|
|
|
|
menuask(flight, X, [ponderous, powerful, agile, flap_glide, other]).
|
|
|
|
|
|
|
|
flight_profile(X):-
|
|
|
|
menuask(flight_profile, X, [flat, v_shaped, other]).
|
|
|
|
|
|
|
|
head(X):-
|
|
|
|
ask(head,X).
|
|
|
|
|
|
|
|
live(X) :-
|
|
|
|
ask(live, X).
|
|
|
|
|
|
|
|
neck(X):-
|
|
|
|
ask(neck, X).
|
|
|
|
|
|
|
|
nostrils(X):-
|
|
|
|
ask(nostrils, X).
|
|
|
|
|
|
|
|
size(X):-
|
|
|
|
menuask(size, X, [large, plump, medium, small]).
|
|
|
|
|
|
|
|
tail(X):-
|
|
|
|
menuask(tail, X, [narrow_at_tip, forked, long_rusty, square, other]).
|
|
|
|
|
|
|
|
throat(X):-
|
|
|
|
ask(throat, X).
|
|
|
|
|
|
|
|
voice(X):-
|
|
|
|
ask(voice,X).
|
|
|
|
|
|
|
|
wings(X):-
|
|
|
|
ask(wings, X).
|
|
|
|
|
|
|
|
|
|
|
|
ask(Attribute,Value):-
|
|
|
|
::known_(yes, Attribute, Value),
|
|
|
|
!.
|
|
|
|
|
|
|
|
ask(Attribute,Value):-
|
|
|
|
::known_(_, Attribute, Value),
|
|
|
|
!, fail.
|
|
|
|
|
|
|
|
ask(Attribute,_):-
|
|
|
|
::known_(yes, Attribute, _),
|
|
|
|
!, fail.
|
|
|
|
|
|
|
|
ask(Attribute, Value):-
|
2005-03-06 21:19:09 +00:00
|
|
|
write(Attribute), write(': '), write(Value),
|
2001-06-06 20:40:57 +01:00
|
|
|
write('? (yes or no): '),
|
|
|
|
read(Answer),
|
|
|
|
::asserta(known_(Answer, Attribute, Value)),
|
|
|
|
Answer = yes.
|
|
|
|
|
|
|
|
|
|
|
|
menuask(Attribute,Value, _):-
|
|
|
|
::known_(yes, Attribute, Value),
|
|
|
|
!.
|
|
|
|
|
|
|
|
menuask(Attribute, _, _):-
|
|
|
|
::known_(yes, Attribute, _),
|
|
|
|
!, fail.
|
|
|
|
|
|
|
|
menuask(Attribute, AskValue, Menu):-
|
|
|
|
nl, write('What is the value for '), write(Attribute), write('?'), nl,
|
|
|
|
display_menu(Menu),
|
|
|
|
write('Enter the number of choice> '),
|
|
|
|
read(Num),nl,
|
|
|
|
pick_menu(Num, AnswerValue, Menu),
|
|
|
|
::asserta(known_(yes,Attribute,AnswerValue)),
|
|
|
|
AskValue = AnswerValue.
|
|
|
|
|
|
|
|
|
|
|
|
display_menu(Menu):-
|
|
|
|
display_menu(Menu, 1).
|
|
|
|
|
|
|
|
|
|
|
|
display_menu([], _).
|
|
|
|
|
|
|
|
display_menu([Item| Rest], N):-
|
|
|
|
write(N), write(' : '), write(Item), nl,
|
|
|
|
NN is N + 1,
|
|
|
|
display_menu(Rest, NN).
|
|
|
|
|
|
|
|
|
|
|
|
pick_menu(N, Val, Menu):-
|
|
|
|
integer(N),
|
|
|
|
pic_menu(1, N, Val, Menu), !.
|
2005-03-06 21:19:09 +00:00
|
|
|
|
|
|
|
pick_menu(Val, Val, _).
|
2001-06-06 20:40:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
pic_menu(_, _, none_of_the_above, []).
|
|
|
|
|
|
|
|
pic_menu(N, N, Item, [Item| _]).
|
|
|
|
|
|
|
|
pic_menu(Ctr, N, Val, [_| Rest]):-
|
|
|
|
NextCtr is Ctr + 1,
|
|
|
|
pic_menu(NextCtr, N, Val, Rest).
|
|
|
|
|
|
|
|
|
|
|
|
:- end_object.
|