Forward Chaining

The Engine employs a forward-chaining strategy for resolving field values.

This means that:

Forward-chaining is useful for determining all the consequences of the pre-condition values.

Consider an agenda with the following discretely-reactive rules:

rule "Rule1" (READY)
decision "main"
    eval A > 10
    then
        case =TRUE: do D=1 end
    end
rule "Rule2" (READY)
decision "main"
    eval B > 0 or C < 10
    then
        case =TRUE: do X=2 end
    end
rule "Rule3" (READY)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end
rule "Rule4" (READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do C=12 end
    end
rule "Rule5" (READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do B=3 end
    end

Note: All decisions are non-iterative - so the Engine processes each rule in the context of a single rule thread.

Assume that field: A is currently resolved to the value: 5 - but that all other fields are unresolved.

The Engine first visits Rule1's thread. The Engine fails the thread and retires it from the agenda.

The Engine next visits Rule2's thread and pends it on premise references to fields B and C.

The resulting agenda is:

rule "Rule2" (thread PENDED on B & C)
decision "main"
    eval B > 0 or C < 10
    then
        case =TRUE: do X=2 end
    end
rule "Rule3" (thread READY)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end
rule "Rule4" (thread READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do C=12 end
    end
rule "Rule5" (thread READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do B=3 end
    end

The Engine next visits Rule3's thread and pends it on a premise reference to field: B.

The resulting agenda is as follows:

rule "Rule2" (thread PENDED on B & C)
decision "main"
    eval B > 0 or C < 10
    then
        case =TRUE: do X=2 end
    end
rule "Rule3" (thread PENDED on B)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end
rule "Rule4" (thread READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do C=12 end
    end
rule "Rule5" (thread READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do B=3 end
    end

The Engine next visits Rule4's thread and fires it. The action unpends Rule2's thread. The Engine removes Rule4 from the agenda.

The resulting agenda is as follows:

rule "Rule2" (thread READY)
decision "main"
    eval B > 0 or C < 10
    then
        case =TRUE: do X=2 end
    end
rule "Rule3" (thread PENDED on B)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end
rule "Rule5" (thread READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do B=3 end
    end

The Engine next visits Rule2's thread but pends it on a premise reference to field: B.

The resulting agenda is as follows:

rule "Rule2" (thread PENDED on B)
decision "main"
    eval B > 0 or C < 10
    then
        case =TRUE: do X=2 end
    end
rule "Rule3" (thread PENDED on B)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end
rule "Rule5" (thread READY)
decision "main"
    eval A < 10
    then
        case =TRUE: do B=3 end
    end

The Engine next visits Rule5's thread and fires it. The action unpends threads for both Rule2 and Rule3. The Engine removes Rule5 from the agenda.

The resulting agenda is as follows:

rule "Rule2" (thread READY)
decision "main"
    eval B > 0 or C < 10
    then
        case =TRUE: do X=2 end
    end
rule "Rule3" (thread READY)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end

The Engine next visits the Rule2 thread, fires it and removes it from the agenda.

The resulting agenda is as follows:

rule "Rule3" (thread READY)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end

The Engine next visits Rule3's thread - but pends it on its action reference to field: D.

Since there are no more rule threads to visit, the Engine terminates inferencing with the final agenda:

rule "Rule3" (thread PENDED on D)
decision "main"
    eval B < 10
    then
        case =TRUE: do Y=D end
    end

Rule3's thread may remain pended indefinitely - unless D is a pre-condition field and the client application resolves it.

The final field status is:

A=5, B=3, C=12, D unresolved, X=2, Y unresolved