| 1 | |
|---|
| 2 | :- object(expert, |
|---|
| 3 | imports(protected::descriptors)). |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | :- info([ |
|---|
| 7 | author is 'Paulo Moura', |
|---|
| 8 | version is 1.1, |
|---|
| 9 | date is 2005/3/6, |
|---|
| 10 | comment is 'Expert system for bird identification.', |
|---|
| 11 | source is 'Example adapted from an Amzi! Inc Prolog book.']). |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | :- public(identify/0). |
|---|
| 15 | |
|---|
| 16 | :- mode(identify, one). |
|---|
| 17 | |
|---|
| 18 | :- info(identify/0, |
|---|
| 19 | [comment is 'Starts a bird identification session.']). |
|---|
| 20 | |
|---|
| 21 | |
|---|
| 22 | :- private(known_/3). |
|---|
| 23 | :- dynamic(known_/3). |
|---|
| 24 | |
|---|
| 25 | :- mode(known_(?nonvar, ?nonvar, ?nonvar), zero_or_more). |
|---|
| 26 | |
|---|
| 27 | :- info(known_/3, [ |
|---|
| 28 | comment is 'Table of already known facts.', |
|---|
| 29 | argnames is ['Answer', 'Attribute', 'Value']]). |
|---|
| 30 | |
|---|
| 31 | |
|---|
| 32 | identify :- |
|---|
| 33 | ::retractall(known_(_, _, _)), |
|---|
| 34 | write('Bird identification expert system'), nl, nl, |
|---|
| 35 | forall( |
|---|
| 36 | (order::leaf(Bird), check(Bird)), |
|---|
| 37 | (nl, write('Possible identification: '), write(Bird), nl)), |
|---|
| 38 | nl, write('No (more) candidates found.'). |
|---|
| 39 | |
|---|
| 40 | |
|---|
| 41 | check(Bird) :- |
|---|
| 42 | forall( |
|---|
| 43 | (::descriptor(Functor/Arity), |
|---|
| 44 | functor(Predicate, Functor, Arity), |
|---|
| 45 | Bird::Predicate), |
|---|
| 46 | call(Predicate)). |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | bill(X):- |
|---|
| 50 | ask(bill, X). |
|---|
| 51 | |
|---|
| 52 | cheek(X):- |
|---|
| 53 | ask(cheek, X). |
|---|
| 54 | |
|---|
| 55 | color(X):- |
|---|
| 56 | ask(color, X). |
|---|
| 57 | |
|---|
| 58 | eats(X):- |
|---|
| 59 | ask(eats, X). |
|---|
| 60 | |
|---|
| 61 | feed(X):- |
|---|
| 62 | ask(feed,X). |
|---|
| 63 | |
|---|
| 64 | feet(X):- |
|---|
| 65 | ask(feet, X). |
|---|
| 66 | |
|---|
| 67 | flight(X):- |
|---|
| 68 | menuask(flight, X, [ponderous, powerful, agile, flap_glide, other]). |
|---|
| 69 | |
|---|
| 70 | flight_profile(X):- |
|---|
| 71 | menuask(flight_profile, X, [flat, v_shaped, other]). |
|---|
| 72 | |
|---|
| 73 | head(X):- |
|---|
| 74 | ask(head,X). |
|---|
| 75 | |
|---|
| 76 | live(X) :- |
|---|
| 77 | ask(live, X). |
|---|
| 78 | |
|---|
| 79 | neck(X):- |
|---|
| 80 | ask(neck, X). |
|---|
| 81 | |
|---|
| 82 | nostrils(X):- |
|---|
| 83 | ask(nostrils, X). |
|---|
| 84 | |
|---|
| 85 | size(X):- |
|---|
| 86 | menuask(size, X, [large, plump, medium, small]). |
|---|
| 87 | |
|---|
| 88 | tail(X):- |
|---|
| 89 | menuask(tail, X, [narrow_at_tip, forked, long_rusty, square, other]). |
|---|
| 90 | |
|---|
| 91 | throat(X):- |
|---|
| 92 | ask(throat, X). |
|---|
| 93 | |
|---|
| 94 | voice(X):- |
|---|
| 95 | ask(voice,X). |
|---|
| 96 | |
|---|
| 97 | wings(X):- |
|---|
| 98 | ask(wings, X). |
|---|
| 99 | |
|---|
| 100 | |
|---|
| 101 | ask(Attribute,Value):- |
|---|
| 102 | ::known_(yes, Attribute, Value), |
|---|
| 103 | !. |
|---|
| 104 | |
|---|
| 105 | ask(Attribute,Value):- |
|---|
| 106 | ::known_(_, Attribute, Value), |
|---|
| 107 | !, fail. |
|---|
| 108 | |
|---|
| 109 | ask(Attribute,_):- |
|---|
| 110 | ::known_(yes, Attribute, _), |
|---|
| 111 | !, fail. |
|---|
| 112 | |
|---|
| 113 | ask(Attribute, Value):- |
|---|
| 114 | write(Attribute), write(': '), write(Value), |
|---|
| 115 | write('? (yes or no): '), |
|---|
| 116 | read(Answer), |
|---|
| 117 | ::asserta(known_(Answer, Attribute, Value)), |
|---|
| 118 | Answer = yes. |
|---|
| 119 | |
|---|
| 120 | |
|---|
| 121 | menuask(Attribute,Value, _):- |
|---|
| 122 | ::known_(yes, Attribute, Value), |
|---|
| 123 | !. |
|---|
| 124 | |
|---|
| 125 | menuask(Attribute, _, _):- |
|---|
| 126 | ::known_(yes, Attribute, _), |
|---|
| 127 | !, fail. |
|---|
| 128 | |
|---|
| 129 | menuask(Attribute, AskValue, Menu):- |
|---|
| 130 | nl, write('What is the value for '), write(Attribute), write('?'), nl, |
|---|
| 131 | display_menu(Menu), |
|---|
| 132 | write('Enter the number of choice> '), |
|---|
| 133 | read(Num),nl, |
|---|
| 134 | pick_menu(Num, AnswerValue, Menu), |
|---|
| 135 | ::asserta(known_(yes,Attribute,AnswerValue)), |
|---|
| 136 | AskValue = AnswerValue. |
|---|
| 137 | |
|---|
| 138 | |
|---|
| 139 | display_menu(Menu):- |
|---|
| 140 | display_menu(Menu, 1). |
|---|
| 141 | |
|---|
| 142 | |
|---|
| 143 | display_menu([], _). |
|---|
| 144 | |
|---|
| 145 | display_menu([Item| Rest], N):- |
|---|
| 146 | write(N), write(' : '), write(Item), nl, |
|---|
| 147 | NN is N + 1, |
|---|
| 148 | display_menu(Rest, NN). |
|---|
| 149 | |
|---|
| 150 | |
|---|
| 151 | pick_menu(N, Val, Menu):- |
|---|
| 152 | integer(N), |
|---|
| 153 | pic_menu(1, N, Val, Menu), !. |
|---|
| 154 | |
|---|
| 155 | pick_menu(Val, Val, _). |
|---|
| 156 | |
|---|
| 157 | |
|---|
| 158 | pic_menu(_, _, none_of_the_above, []). |
|---|
| 159 | |
|---|
| 160 | pic_menu(N, N, Item, [Item| _]). |
|---|
| 161 | |
|---|
| 162 | pic_menu(Ctr, N, Val, [_| Rest]):- |
|---|
| 163 | NextCtr is Ctr + 1, |
|---|
| 164 | pic_menu(NextCtr, N, Val, Rest). |
|---|
| 165 | |
|---|
| 166 | |
|---|
| 167 | :- end_object. |
|---|