solve(Goal) :- solve(Goal, []). solve([], Rules). solve([X|Xs], Rules) :- solve(X, Rules), solve(Xs, Rules). solve(X, Rules) :- rule(X, Xs), solve(Xs, [rule(X, Xs)|Rules]). solve(X, Rules) :- askable(X), \+ known(X), ask(X, Answer), process_reply(Answer, X, Rules). ask(X, Answer) :- display_query(X), read(Answer). process_reply(yes, X, Rules) :- assert(true(X)). process_reply(no, X, Rules) :- assert(untrue(X)), fail. process_reply(why, X, [Rule|Rules]) :- /* If user asks `why', then */ display_rule(Rule), /* display the parent rule, */ ask(X, Answer), /* repeat the question, */ process_reply(Answer, X, Rules). /* and process the new reply. */ process_reply(why, X, []) :- /* What to do if `why' is */ write('No more explanation'), nl, /* asked but there is no */ ask(X, Answer), /* parent. */ process_reply(Answer, X, []). display_rule(rule(X, Xs)) :- write('IF '), write_conjunction(Xs), write(' THEN '), write(X), nl. write_conjunction([X1, X2 | Xs]) :- !, write(X1), write(' AND '), write_conjunction([X2 | Xs]). write_conjunction([X]) :- write(X), nl. write_conjunction([]) :- nl. known(X) :- true(X). known(X) :- untrue(X). display_query(X) :- write(X), write('? ').