PROBLEM :
I have three rule tables in Decision Table (Spreadsheet) the rules of first two rule table defines which rule is to be fired from the third rule table. In First rule table according to some conditions, I have updated the fact and this fact is used to fire a rule from second rule table. And in ACTION column of second rule table I have updated the fact and I want to fire rules in 3rd Rule table based on this updated fact, but because of updated fact the rule from the first table fires again and then second and the loop goes on.
I can't find the way to add RuleFlow-Group in rule table whenever I add RuleFlow-Group the rules stops firing for any fact.
WHAT I TRIED :
I have added No-Loop to true so that no rules are firing of the same rule table for the updated fact.
I tried adding LOCK-ON-ACTIVE attribute, rules from the Rule Table 1 are working fine but no other rules are getting firing.
I think after firing the rule from Rule Table 1 it locks all the rule of the Rule Package instead, I am adding "lock-on-active" in Rule Table, not in Rule Set.
Spread Sheet illustrating problem statement.
This is a very abstract set of rules, and I don't feel that it's worth discussing in depth. Updating a fact means it is re-evaluated wherever it occurs, which is in all rules. To avoid re-evaluation, use constraints that keep the rule from firing if the result of the RHS is already set in the fact.
rule "table_1_1"
when
$input: Input(a==1, b!=1)
then
modify( $input ){ setB( 1 ); }
end
rule "table_2_1"
when
$input: Input(b==1, c!=1)
then
modify( $input ){ setC( 1 ); }
end
The third table isn't using modify so it doesn't cause a loop.
Related
I've few drools rules that I want to use in different rule flows. Since, Drools rule supports only one ruleflow-group name at a time and rule flow business rule task also can be mapped with single ruleflow-group, I'm not able to use same rule in different rule flows. Is there any other way that I can use to filter the rules? like using tags or and metadata?
You could create your own rule groups. You create a class OwnRuleGroup with String group in it as a field. Then when you fire rules you create an instance of your own rule grup:
OwnRuleGroup myGroup = new OwnRuleGroup();
myGroup.group = "foo";
and insert it into session with other facts. In every rule you could specify which of the groups you want to fire.
rule "This will fire for groups foo,bar"
when
OwnRuleGroup(group in ["foo", "bar"])
rule "one"
activation-group "Harris"
salience 10
when
$p : Person(age < 10);
then
$p.setDiscount(0.1);
end
rule "two"
activation-group "Harris"
salience 10
when
$p : Person(age > 10);
then
$p.setDiscount(0.2);
end
When I insert some Persons to working memory through KSession.insert(Object), only the first Person is evaluated, the other persons just ignored. My understanding about Drools activation-group is that if I have X number of rules that belong to the same activation-group with various salience values that each
Person will be processed by the rules and the one with the highest
salience will be fired and the rest will be ignored. Once that's
complete the next Person will come through and repeat the process. What
I'm experiencing is that the first Person to trigger any rule in that
activation-group will disable the entire activation group and no further
Persons will be processed.
Any suggestion?
"Only one rule within an activation group will fire, i.e., the first one to fire cancels any existing activations of other rules within the same group." This is pretty explicit.
Don't use an activation group if you want to do the same thing for many Person facts.
(a) Insert just one, fire all rules - repeat.
(b) Insert many persons, fire all rules but retract a Person fact in each consequence.
Salience is almost always bad. Use logic (constraints) for fine-grained control of the rule firing order.
activation-group will not work in your case. Insert and fireAlleules one by one shockingly that will work because it will fire up the rules considering the new updates in KnowledgeBase.(Not Recommended).
But i would suggest you to write up the unique rules to avoid activation-group. You can also try extending rules for more constructive.
I have a small project created on drools workbench deployed on a KIE server. Using the rest API I am able to insert facts, with rules appropriately fired. However the rules included in guided decision tables do not fire. Here is an example of a request I would send to the KIE server:
<batch-execution lookup="defaultKieSession">
<insert out-identifier="applicant" return-object="true" entry-point="DEFAULT">
<models.Applicant>
<timeEmployed>35</timeEmployed>
<employmentStatus>Contract</employmentStatus>
<violations>[]</violations>
</models.Applicant>
</insert>
<fire-all-rules/>
</batch-execution>
All rules that this data should trigger are fired, except for those included in the Decision table.
When I run a test scenario with the same data, all rules, including the decision table's rules, are fired correctly:
The problem seems to be related to the use of the REST API. Any ideas as to what I am doing wrong?
Here is the Table in question:
Violation simply calls a method that appends an error to the violations array.
Inside kmodule.xml I have.
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
Clarification
Just to be clear my requests fire rules from Guided DRLs, my issue is only with the rules in guided rules table. For example:
Given the rule:
If I send this request:
1994-04-15 11:03:44-0000
1970-01-13 16:19:41-0024
Contract
35
[]
This is a fragment of the response:
This data should also match the rule in the gdst however it is not fired.
While we can't see the condition operators in the table, my guess is the criteria doesn't meet any of the decision table rows/rules.
Mapping the input data to the decision table, we can see that:
Employment Status is Contract, so that matches row 1. In rows 3-11 it is ignored, so depends on the matching of the remaining columns.
Employment Duration is probably timeEmployed, and it does not match equality of any row. If the column operator is >, it matches rows 2-11. If it is <, then it matches row 1.
Job Category is ignored for rows 1 and 2, and has no apparent matching value in the input so rows 3-11 do not match.
Based on those:
3 says only rows 1 and 2 could match
1 says only row 1 could match of rows 1 and 2
2 is indeterminate based on what we see
My guess is row 1 is close but #2 doesn't match.
I am using the native rule engine of webMethods (wm Business rule) to create complex rule. I need to create a decision table that depends on the result of another decision table. As shown in the graphic below,
I finally find out how to do it.
The idea is to put both decision tables into the same rule set. Then running the rule set by providing var1, var2, param1 and param2
The rule engine is going to infer the result for the first decision table into the second one.
NB. the name of the result of the first table has to be the same in the second table.
I read the rule file and add them into my knowledgeBase then I want to fire a particular rule in that knowledgeBase. Is this task possible in current drools version?
If you have a rule base where rules should be made active dynamically according to some criterion you have several choices.
Agenda filter. You say you don't want this, but why?
Put the alternative rules into agenda groups. Select the agenda group "group_3" prior to inserting the fact by a call to
kieSession.getAgenda().getAgendaGroup( "group_3" ).setFocus();
Write your rules to include a "selection" fact, e.g.
rule rule_3
when
Select( rule == "rule_3" )
Person( ... )
then ... end
The Select fact can be inserted along with the data fact but must be retracted after firing the rule.