prolog rules as arguments

439 views Asked by At

I'm building an expert system shell based on Luger & Stubblefield's ExShell. In their system, they define rules in the following way:

rule((Goal :- (Premise)), CF_Rule).

Ignore the CF_Rule. An example of this syntax is:

rule((fix(Advice) :-
    (bad_component(X),fix(X, Advice))), 100).

I want to add an OR in certain rules, but SWI-Prolog doesnt recognize the ";" and just skips the rule like it had a typo. For example, if i wanted to do:

rule((fix(Advice) :-
    (bad_component(X); fix(X, Advice))), 100).

Then the rule is no longer recognized. Defining two rules is not an option due to how the shell is built (it wont trigger two goals with the same head). How can I add an OR to these rules?

EDIT: The system starts by writing

solve(fix(X), CF).

Solve looks for rules to trigger and then tries to solve their premises, like this:

%backchain on a rule in knowledge base  
solve(Goal, CF, Rules, Threshold) :-
    rule((Goal :- (Premise)), CF_rule), 
    solve(Premise, CF_premise, 
        [rule((Goal :- Premise), CF_rule)|Rules], Threshold),
    rule_cf(CF_rule, CF_premise, CF),
    above_threshold(CF, Threshold).

The top level goal that starts the search is:

rule((fix(Advice) :-
    (bad_component(X),fix(X, Advice))), 100).
1

There are 1 answers

2
dlask On BEST ANSWER

It works, at least in SWI-Prolog version 6.6.6.

Let's have both rules defined:

rule((fix(Advice) :- (bad_component(X), fix(X, Advice))), 100).
rule((fix(Advice) :- (bad_component(X); fix(X, Advice))), 100).

If we ask for available rules we obtain both of them:

?- rule((A :- B), C).
A = fix(_G2329),
B = (bad_component(_G2334), fix(_G2334, _G2329)),
C = 100 ;
A = fix(_G2329),
B = (bad_component(_G2334);fix(_G2334, _G2329)),
C = 100.