/*---------------------------------------------------------- INFERENCE ENGINE ----------------------------------------------------------*/ %%% parse(-Value) %%% ============= %%% %%% Value is the value corresponding to a final item %%% generated by parsing a sentence typed in from the %%% standard input. parse(Value) :- read_input, % read a sentence init_chart, % init. to an empty chart init_agenda(Agenda), % init. agenda to include axioms exhaust(Agenda), % process agenda until exhausted final_item(Goal, Value), % get form of final goal item item_in_chart(Goal). % find all such items in chart %%% init_agenda(+Axioms, -Agenda) %%% ============================= %%% %%% Add indices corresponding to each of the Axioms to %%% an empty Agenda. init_agenda(Agenda) :- initial_items(Axioms), % get axioms empty_agenda(Empty), add_items_to_agenda(Axioms, Empty, Agenda). %%% exhaust(+Agenda) %%% ================ %%% %%% Generate all the consequences that follow from the %%% indices in the Agenda. exhaust(Empty) :- is_empty_agenda(Empty). exhaust(Agenda0) :- pop_agenda(Agenda0, Index, Agenda1), add_item_to_chart(Index), add_consequences_to_agenda(Index, Agenda1, Agenda), exhaust(Agenda). %%% add_consequences_to_agenda(+Index, +Agenda0, -Agenda) %%% ===================================================== %%% %%% Add to Agenda0 all the indices that follow %%% immediately from Index, yielding Agenda. add_consequences_to_agenda(Index, Agenda0, Agenda) :- all_solutions(Consequence, consequence(Index, Consequence), Consequences), add_items_to_agenda(Consequences, Agenda0, Agenda). %%% consequence(Index, Consequent) %%% ============================= %%% %%% Consequent is the consequent of an inference rule %%% whose antecedent is satisfied by the item given by %%% Index and other items in the chart. consequence(Index, Consequent) :- index_to_item(Index, Trigger), matching_rule(Trigger, RuleName, Others, Consequent, SideConds), items_in_chart(Others, Index), hold(SideConds), notify_consequence(RuleName, Trigger, Others, SideConds, Consequent). %%% items_in_chart(+Items, +Index) %%% ============================= %%% %%% All the elements of Items, generated when processing %%% Index from the agenda, are satisfied by stored items %%% in the chart. items_in_chart([], _Index). items_in_chart([Antecedent|Antecedents], Index) :- item_in_chart(Antecedent, Index), items_in_chart(Antecedents, Index). %%% hold(+Conditions) %%% ================= %%% %%% All the side Conditions hold. hold([]). hold([Cond|Conds]) :- call(Cond), hold(Conds). %%% matching_rule(+Trigger, %%% -RuleName, -Others, -Consequent, -SideConds) %%% ========================================================== %%% %%% Find an inference rule RuleName with antecedent of %%% the form U @ [Trigger] @ V, where Others is U @ V, %%% Consequent is the consequent of the rule and %%% SideConds are its side conditions. (@ denotes here %%% list concatenation). matching_rule(Trigger, RuleName, Others, Consequent, SideConds) :- inference(RuleName, Antecedent, Consequent, SideConds), split(Trigger, Antecedent, Others).