%%% shell.pro Dave Reed 3/25/02 %%% %%% Expert system shell %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- op(1100, xfx, '--->'). solve(Goal, CF) :- print_instructions, retractall(known(_, _)), solve(Goal, CF, [], 60). print_instructions :- nl, write('Responses must be either:'), nl, write(' (1) a number between 0 and 100 (a confidence factor).'), nl, write(' (2) why (to justify the relvance of the question).'), nl. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% CASE 1: truth of goal is already known solve(Goal, CF, _, Threshold) :- (known(Goal, CF) ; (true ---> Goal:CF)), !, above_threshold(CF, Threshold). %%% CASE 2: negated goal solve(not(Goal), CF, Rules, Threshold) :- !, negate_cf(Threshold, New_threshold), solve(Goal, CF_goal, Rules, New_threshold), negate_cf(CF_goal, CF). %%% CASE 3: conjunctive goals solve((Goal1, Goal2), CF, Rules, Threshold) :- !, solve(Goal1, CF1, Rules, Threshold), above_threshold(CF1, Threshold), solve(Goal2, CF2, Rules, Threshold), above_threshold(CF2, Threshold), and_cf(CF1, CF2, CF). %%% CASE 4: back chain on rule in KB solve(Goal, CF, Rules, Threshold) :- (Premise ---> Goal:CF_rule), solve(Premise, CF_premise, [(Premise ---> Goal:CF_rule)|Rules], Threshold), rule_cf(CF_rule, CF_premise, CF), above_threshold(CF, Threshold). %%% CASE 5: ask user solve(Goal, CF, Rules, Threshold) :- askable(Goal), ask_user(Goal, CF, Rules), !, assert(known(Goal, CF)), above_threshold(CF, Threshold). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% and_cf(A, B, Min) :- Min is min(A, B). rule_cf(CF_rule, CF_premise, CF) :- CF is (CF_rule * CF_premise / 100). negate_cf(CF, Negated_CF) :- Negated_CF is 100-CF. above_threshold(CF, T) :- T >= 50, CF >= T. above_threshold(CF, T) :- T < 50, CF =< T. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ask_user(Goal, CF, Rules) :- nl, write('User query: '), write(Goal), nl, write('? '), read(Answer), respond(Answer, Goal, CF, Rules). respond(CF, _, CF, _) :- number(CF), CF =< 100, CF >= 0. respond(why, Goal, CF, [Rule|Rules]) :- write(Rule), nl, ask_user(Goal, CF, Rules). respond(why, Goal, CF, []) :- write('At the top of the rule stack.'), nl, ask_user(Goal, CF, []). respond(_, Goal, CF, Rules) :- write('Illegal response.'), nl, ask_user(Goal, CF, Rules).