Reputation: 772
I'm trying to use Drools backward chaining to find out which facts are needed to get an object inserted in the working memory. In the following example, I expect to get the fact "go2".
rule "ins a"
when
String( this == "go2" )
then
insert(new A());
end
rule "Run"
when
then
insert(new String("go1"));
end
rule "Test isThereAnyA"
when
String( this == "go1" )
isThereAnyA(a;)
then
System.out.println( "you can get " + a );
end
query isThereAnyA (A a)
a := A()
end
I've been looking at examples in the official documentation http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21289 but they show a different situation (the rules in those examples doesn't creates new fact)
From the chart http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_single/index.html#d0e21240 I think it should work but I haven't found a way to specify a query that gives me the expected results.
Thank you in advance.
Upvotes: 4
Views: 2971
Reputation: 221
Short answer:
Unfortunately backward chaining can not be used for this purpose. It will not give you "go2" in this case.
Long answer:
In Drools, Backward chaining (BC) is a way to query the WM in a goal-driven fashion, not a way to trace back the derivation graph of a normal forward chaining inference process.
BC allows rule "Test" to retrieve As through the query "isThereAnyA", and possibly invoke other queries, but will not allow to find the "production" link between "A" and "go2". The reason is that "when..then..insert.." does not create any link between the triggering facts and the asserted conclusion, and backward chaining will not change it.
What you could do with BC is this:
query isThereAnyA_InPresenceOfA_String( A a )
isThereAnyString( $s ; )
a := A()
end
query isThereAnyString( String $s )
$s := String( this == "go2" )
end
This will pick up As only if a String "go2" is (still) present. However you'll notice that the connection between a particular instance of A and a the particular String which led to its assertion is still missing.
To know exactly which objects led to the assertion of another object you may need a different approach. Options include:
The TMS-based one would be my tentative choice, but it also depends on your exact requirements.
This use case is common, there may be other options, including a few which are experimental as they are being developed in 6.3, but I'd rather ask a few questions first. That is: when do you need exactly to discover the facts - during the execution of the rules, or "offline"? Is it purely for auditing purposes, or does it impact your business logic? Can you have multiple rules asserting the "same" object?
Hope this helps Davide
Upvotes: 3