% From the book % PROLOG PROGRAMMING IN DEPTH % by Michael A. Covington, Donald Nute, and Andre Vellino % (Prentice Hall, 1997). % Copyright 1997 Prentice-Hall, Inc. % For educational use only % FCHAIN.PL % This file contains a simple forward chaining % inference engine that accepts Prolog translations % of production rules, plus a supervisory program % for use with the inference engine. % forward-chainer % finds a production rule that can be fired, % fires it, and informs the user, then calls % itself to repeat the process. :- dynamic f/1, g/1, rule/1. :- multifile f/1, g/1, rule/1. forward_chainer :- findall(X,satisfied(X),ConflictSet), resolve_set(ConflictSet,ID), rule(ID), write('Fired rule: '), write(ID), write('.'), nl, !, forward_chainer. % satisfied(?Rule) % succeeds if every condition for rule(Rule) tha comes % before the predicate then/0 succeeds. satisfied(X) :- clause(rule(X),Body), satisfied_conditions(Body). satisfied_conditions((then,_)) :- !. satisfied_conditions((First,Rest)) :- First, satisfied_conditions(Rest). % resolve(+ConflictSet,+RuleNumber) % Returns the RuleNumber of the first member of the % ConflictSet (which is the first rule in the database % whose condition is satisfied). resolve_set([ID|_],ID) :- !. % The remaining predicates are provided to make % writing and reading production rules easier. af(X) :- asserta(f(X)). rf(X) :- retract(f(X)). ag(X) :- assert(g(X)). rg(X) :- retract(g(X)). then. % Supervisory program fc :- display_help_message, repeat, write('>'), read(X), ( X = stop,abolish(f/1),abolish(g/1) ; process(X), nl, fail ). % display_help_message % provides a list of commands to use with the forward % chaining supervisor. display_help_message :- nl, nl, write('FCHAIN - A Forward Chaining Inference Engine'), nl, nl, write('This is an interpreter for files containing production'), nl, write('rules written in the FCHAIN format.'), nl, nl, write('The > prompt accepts four commands:'), nl, nl, write('load. - prompts for names of rules files'), nl, write(' (enclose names in single quotes)'), nl, write('list. - lists facts and goals in working'), nl, write(' memory'), nl, write('go. - starts the forward chainer'), nl, nl, write('stop. - exits FCHAIN'), nl, nl, write('help. - display this message'), nl, nl. % process(+Command) % provides procedures for processing each of the % four kinds of commands the user may give to the % supervisor. process(go) :- nl, forward_chainer. process(go) :- !. /* if forward_chainer failed */ process(load) :- nl, write('File name? '), read(Filename), reconsult(Filename), !. process(list) :- nl, write('Facts:'), nl, f(X), write(' '), write(X), nl, fail. process(list) :- nl, write('Goals:'), nl, g(X), write(' '), write(X), nl, fail. process(list) :- !. process(list(X)) :- nl, f(X), write(' '), write(X), nl, fail. process(list(_)) :- !. % Starting query :- fc.