Drools always return null - drools

I have a .drl file generated from a rule xls:
#From row number: 19
rule "check_19"
salience 65517
activation-group "testCheck"
when
application : Application(eval( isApplicantType(applicantType, "SINGLE")))
applicant : Applicant(eval(isValid("18")))
then
result.add("false");
end
The drools fires without any errors but the result is always null. The activation group testCheck is set to XOR so I'm assuming either one of application or applicant must be true. Can someone explain to me the issue here? Thanks

Related

how to know the rules which are using a particular attribute

Say I have a rule file like below. Below rules are built on 2 properties Instrument and maverickModelMappingId. Can Drools tell me how many rules use the field "Instrument"? My use case is that I want to know if I am deleting an attribute or a field, how many rules and which rules are going to be affected.
package abc.modelMapping.ruleEngine;
dialect "java"
declare FRONTOFFICESYSTEM
Instrument : String
maverickModelMappingId : String
end
rule "rule_MurexCredit_Rule_3"
salience 3
no-loop true
when
$frontOfficeSystem : FRONTOFFICESYSTEM("Default swap".equalsIgnoreCase(Instrument))
then
$frontOfficeSystem.setMaverickModelMappingId("001282");
System.out.println("001282 "+"MurexCredit_Rule_3+");
end
rule "rule_MurexCredit_Rule_2"
salience 2
no-loop true
when
$frontOfficeSystem : FRONTOFFICESYSTEM("Euro credit index option".equalsIgnoreCase(Instrument))
then
$frontOfficeSystem.setMaverickModelMappingId("001283");
System.out.println("001283 "+"MurexCredit_Rule_2+");
end
rule "rule_MurexCredit_Rule_1"
salience 1
no-loop true
when
$frontOfficeSystem : FRONTOFFICESYSTEM("Credit index".equalsIgnoreCase(Instrument))
then
$frontOfficeSystem.setMaverickModelMappingId("001282");
System.out.println("001282 "+"MurexCredit_Rule_1+");
end
This is not possible with Drools, as of the current version (7.33.0.Final). As mentioned in the comments, the better solution will be to use your IDE's search tools -- or other find/grep solution -- to search the text of the rule file(s) for references to the given attribute or method.

Where can I see if a pattern failed in rule?

I run a rule that contains a few patterns, I want to know which pattern failed:
I've tried to debug the code (drools 7.18.0), and didn't found the relevant place.
rule example:
rule "Trigger"
agenda-group "Trigger"
salience 100
when
$pcase : PCaseMgr()
D1($id: id, type != null, type == "AAA")
D2(aId == $id)
then
$pcase.printAnalyticsRuleLog(">>>>>>>>>>>>>>>>>>> In Trigger");
end
in the example above, if D1 pattern is passed, and D2 pattern is failed, where in the code (of drools 7.18.0) can i see if the pattern was failed?
You can't. Because of the algorithm Drools uses internally, patterns are decomposed into nodes and nodes can be shared among multiple rules in your knowledge base. If you really need to know why a rule was not fire, then you can create other rules that will tell you that. In your example, you could create something like this:
rule "No Trigger because of No D2"
agenda-group "Trigger"
salience 100
when
$pcase : PCaseMgr()
D1($id: id, type != null, type == "AAA")
not D2(aId == $id)
then
$pcase.printAnalyticsRuleLog(">>>>>>>>>>>>>>>>>>> No Trigger because no D2");
end
Hope it helps,

Drools trigger one rule per item in list input for StatelessKieSession

I am using decision tables and would like to trigger one rule per input item.
I am using decision have set the Sequential = true and defined all rules as part of the same ACTIVATION-GROUP.
When I trigger the drools rules engine using below it just evaluates for the first input item and others are ignored. The behavior I want is to evaluate at most 1 rule per input item (rule order defined by the Salience).
kieStatelessSession.execute(inputList)
I can get this working by sending one item at a time to the kieStatelessSession, but would prefer to execute all at once.
I am using Drools verison 6.5.0.FINAL and Java 7.
There is no out of the box support in Drools for what you are trying to achieve. If you want your rules to be evaluated once for each fact, you will need to code it yourself.
One approach could be to have another type of facts to mark when one of the inputs is processed:
declare Marker
fact : Object
end
//Bellow are the rules that should be coming from your decision table.
//Each rule will do whatever it needs to do, and then it will create a
//Marker fact for the fact that was processed.
//These rules now include a "not" Conditional Element to avoid a fact to be
//evaluated more than once.
rule "Rule 1"
salience 100
when
$fact: Object(...) //your conditions
not Marker(fact == $fact)
then
//... Your logic
insert(new Marker($fact));
end
...
rule "Rule 50"
salience 50
when
$fact: Object(...) //your conditions
not Marker(fact == $fact)
then
//... Your logic
insert(new Marker($fact));
end
Hope it helps,

Drools Check for Non-Existence isnt behaving like id expect

relative new comer to drools and rules engines.
I have three rules that essentially check if different instances of the same object exist, if they don't, they create one and insert it into the working memory. After performing a series of other related rules, theres a rule that checks for validity of the models.
The goal here is to have three different instances of the same object that represent three different entities and proceed as long as 2 of them are in a valid state.
They're defined as follows:
rule "SetupA"
salience 80
lock-on-active
when
not InvalidModel(name == "A-Name")
then
InvalidModel invalidA = new InvalidModel();
invalidA.setName("A-Name");
insert(invalidA);
end
rule "SetupB"
salience 80
lock-on-active
when
not InvalidModel(name == "B-Name")
then
InvalidModel invalidB = new InvalidModel();
invalidB.setName("B-Name");
insert(invalidB);
end
rule "SetupC"
salience 80
lock-on-active
when
not InvalidModel(name == "C-Name")
then
InvalidModel invalidC = new InvalidModel();
invalidC.setName("C-Name");
insert(invalidC);
end
rule "VALIDATE_MODEL_FOR_ANY_INVALID_FLAGS"
salience -10
when
$invalidList: List(size > 1) from collect(InvalidModel(isNotFound || isFlagged || isNotActive))
then
setDecision(result, "Denied");
end
However, what's happening is that it seems like these rules are matched on every request to this ruleset which I interpret as the facts not existing in the Working Memory. I'd expect the rules to be fired once, when each of the facts for the respective names dont exist, and then to not fire again as there is nothing that would remove them from the working memory. However, my audit log of the rules that fire show that for every request those rules get fired.
Furthermore, the fourth rule's condition seems to not be performing as expected as it returns a response like such
=============== DEBUG MESSAGE: illegal bytecode sequence - method not verified ================
My ask is for some guidance on where my logic/drools language structure may have gone astray. Thanks for your time.

Why doesn't rule 1 consequence effect behavior of rule 2?

As an exercise in teaching myself drools I'm working on rules for bidding in the bridge card game. The rules work independently of each other (enforced by use of drools.halt() in the rules) but when I try to extend the example by removing the halt() calls, I get behavior I didn't expect. In the example below I am commenting out the halt() in the first rule, and adding the size() condition to the 2nd rule to replace it, trying to prevent the 2nd rule from firing. I would not expect the 2nd rule to fire because the consequence of the first rule added a bid to the Auction's collection, and so subsequently in rule 2 the count should not be zero. I've tried explicitly adding the 'update' or 'modify' directives in the first rule, but that didn't make any difference.
rule "rule1"
salience 100
when
$auction : Auction( $currentBidder : currentBidder != null )
$hand : Hand( owner.equals($currentBidder), getTotalPoints(getLongestSuit()) >= 13 )
then
$auction.bid($currentBidder, new Bid(1, $hand.getLongestSuit()));
//drools.halt();
end
rule "rule2"
salience 1
when
$auction : Auction( $currentBidder : currentBidder != null, getPlayerBids().size() == 0 )
Hand(owner.equals($currentBidder))
then
$auction.bid($currentBidder, new Pass());
drools.halt();
end
When you change an object, you need to tell the engine you updated it. So try adding update($action); at the end of the first rule.