| 
									
										
										
										
											2001-06-06 19:40:57 +00: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 19:40:57 +00: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)), | 
					
						
							| 
									
										
										
										
											2005-05-23 23:33:41 +00:00
										 |  |  | 			(nl, write('Possible identification: '), write(Bird), nl)), | 
					
						
							| 
									
										
										
										
											2001-06-06 19:40:57 +00:00
										 |  |  | 		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 19:40:57 +00: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 19:40:57 +00: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. |