Use of a control fact - drools

UPDATE
Introduced a control fact to control rules from firing. Facts are
Product (sku="zzz")
TextChoiceOption (sku="control", optionValueValue = "xxx")
DimensionOption (sku="dim", widthValue = 29, heightValue = 71)
TextOption (sku="default_tube_size", value="")
TextOption (sku="motorTubeRule", value="N")
Only one rule is firing by rule 12 is firing instead of rule 10 or 11. Based on Salience level rule 10 or 11 should fire with LIFO firing rule 11 but that is not the case. What is the problem?
rule "rule_10"
salience 390
no-loop true
when
p: Product(sku != 1)
TextOption(sku="motorTubeRule", value == "N")
$opt : TextChoiceOption(sku == "motorControl")
exists (OptionValue(optionValueValue in ("xxx")) from $opt.value)
DimensionOption(sku == "dim", widthValue <= "72", heightValue <= "120")
$edi : TextOption(sku == "default_tube_size")
$ruleFire : TextOption(sku == "motorTubeRule")
then
$edi.setValue("1.5"); update($edi);
$ruleFire.setValue("Y"); update($ruleFire);
end
rule "rule_11"
salience 390
no-loop true
when
p: Product(sku != 1)
TextOption(sku="motorTubeRule", value == "N")
$opt : TextChoiceOption(sku == "motorControl")
exists (OptionValue(optionValueValue in ("xxx")) from $opt.value)
DimensionOption(sku == "dim", widthValue <= "96", heightValue <= "96")
$edi : TextOption(sku == "default_tube_size")
$ruleFire : TextOption(sku == "motorTubeRule")
then
$edi.setValue("1.5"); update($edi);
$ruleFire.setValue("Y"); update($ruleFire);
end
rule "rule_12"
salience 380
no-loop true
when
p: Product(sku != 1)
TextOption(sku="motorTubeRule", value == "N")
$opt : TextChoiceOption(sku == "motorControl")
exists (OptionValue(optionValueValue in ("xxx")) from $opt.value)
DimensionOption(sku == "dim", widthValue <= "102", heightValue <= "120")
$edi : TextOption(sku == "default_tube_size")
$ruleFire : TextOption(sku == "motorTubeRule")
then
$edi.setValue("2"); update($edi);
$ruleFire.setValue("Y"); update($ruleFire);
end

Related

Activation Group and Salience - wrong rule being fired

I have the following 3 rules in my system. The facts match all 3 rules. Based on the salience and activation group I would expect either rule 10 or 11 to fire. However rule 12 is always firing.
To complicate matters I have 3 systems this runs on. It runs with the expected rule 10 or 11 firing on one system and the other two systems rule 12 is firing.
Any ideas?
rule "dimensionConfigMotorTubeDefault_10"
salience 390
activation-group "ag_R238_r28-wirefree"
no-loop true
lock-on-active true
when
p: Product(sku != 1)
$mm : InventoryChoiceOption(sku == "mm")
exists (NII(internalPattern in ("R238")) from $mm.value)
$opt : TextChoiceOption(sku == "motorControl")
exists (OptionValue(optionValueValue in ("r28-wirefree")) from $opt.value)
DimensionOption(sku == "dim", widthValue <= "72", heightValue <= "120")
$edi : TextOption(sku == "default_tube_size")
then
$edi.setValue("1.5"); update($edi);
end
rule "dimensionConfigMotorTubeDefault_11"
salience 390
activation-group "ag_R238_r28-wirefree"
no-loop true
lock-on-active true
when
p: Product(sku != 1)
$mm : InventoryChoiceOption(sku == "mm")
exists (NII(internalPattern in ("R238")) from $mm.value)
$opt : TextChoiceOption(sku == "motorControl")
exists (OptionValue(optionValueValue in ("r28-wirefree")) from $opt.value)
DimensionOption(sku == "dim", widthValue <= "96", heightValue <= "96")
$edi : TextOption(sku == "default_tube_size")
then
$edi.setValue("1.5"); update($edi);
end
rule "dimensionConfigMotorTubeDefault_12"
salience 380
activation-group "ag_R238_r28-wirefree"
no-loop true
lock-on-active true
when
p: Product(sku != 1)
$mm : InventoryChoiceOption(sku == "mm")
exists (NII(internalPattern in ("R238")) from $mm.value)
$opt : TextChoiceOption(sku == "motorControl")
exists (OptionValue(optionValueValue in ("r28-wirefree")) from $opt.value)
DimensionOption(sku == "dim", widthValue <= "102", heightValue <= "120")
$edi : TextOption(sku == "default_tube_size")
then
$edi.setValue("2"); update($edi);
end

Give the results of the following Boolean operations

Assuming that A = True, B = False and C = True.
Give the results of the following Boolean operations
AB + BC’ (A + B’C) + B
(b) ABC’ + (B + AC’)B + A’
in boolean multiply operation is AND (&&) operation
and plus + operation is OR(||) operation
and ' operator measn NOT(!)
so,
AB + BC’ (A + B’C) + B
can be written as
(A && B) || [(B && (!C)) && (A || ((!B) && C))] || B
PUTTING THE VALUE IN THE ABOVE EQUATION
= (1 && 0) || [(0 && (!0)) && (1 || ((!1) && 1))] || 1
= 0 || [(0 && 1 )&& (1 || (0 && 1)] ||1
= 0 || [(0 && 1) && (1 || 0)] ||1
= 0 || [0 && 1] ||1
= 0 || 0 || 1
= 1
I KNOW IT IS HARD TO FOLLOW BUT THE ANSWER WILL BE 1
AND FOLLOWING THE SAME LOGIC THE ANSWER TO THE 2ND STATEMENT WILL ALSO BE 1
IF YOU WANT TO UNDERSTAND HOW THIS WORKS PLEASE READ THE DOCS

drools how to fire specified group dynamically

i am using drools 7.x.
my logic looks like following:
if(variableA == 1) {
if(variableA1 == 2) {
....
} else if(variableA1 == 3) {
....
}
}else {
if(variableB1 == 1) {
....
}else if(variableB1 == 2) {
if(variableN == 1) {
}else if(variableN == 2) {
}
}
}
by the way, these variables not in the same class, i intend to insert them as fact in drl.
how can i define the rules? or how can i define rules like :
rule 1
when
then
end
rule 2
when
then
end
rule 1-1
when
then
end
rule 1-2
when
then
end
rule 2-1
when
then
end
rule 2-2
when
then
end
wherein, only one of rules will be fired in rule 1 and rule 2, rule 1-1 and rule 1-2 is group1, rule 2-1 and rule 2-2 is group2.
if rule 1 is fired, then only one of rules is fired in group1, there is no need to test group2. While if rule 2 is fired, then only one of rules is fired in group2, there is no need to test group1.
salience for rules priority
logical insertions to depend on other rule
activation-group for xor logic
rule "1"
salience 1
activation-group "group 0"
when
$model : Model(a == 1)
then
insertLogical(new GroupActivation("group 1", $model));
System.out.println("rule 1");
end
rule "2"
salience 1
activation-group "group 0"
when
$model : Model(b == 1)
then
insertLogical(new GroupActivation("group 2", $model));
System.out.println("rule 2");
end
rule "1-1"
activation-group "group 1"
when
GroupActivation(name == "group 1", $model : model)
Model(this == $model, a1 == 1)
then
System.out.println("rule 1-1");
end
rule "1-2"
activation-group "group 1"
when
GroupActivation(name == "group 1", $model : model)
Model(this == $model, a2 == 1)
then
System.out.println("rule 1-2");
end
rule "2-1"
activation-group "group 2"
when
GroupActivation(name == "group 2", $model : model)
Model(this == $model, b1 == 1)
then
System.out.println("rule 2-1");
end
rule "2-2"
activation-group "group 2"
when
GroupActivation(name == "group 2", $model : model)
Model(this == $model, b2 == 1)
then
System.out.println("rule 2-2");
end
Model.java
public class Model {
private int a;
private int a1;
private int a2;
private int b;
private int b1;
private int b2;
...
GroupActivation.java
public class GroupActivation {
private String name;
private Model model;
...
I'm going to assume all of these variables exist inside of an class which I'm going to call Inputs. You'd call these rules by passing an instance of Inputs into the rules.
I'm also going to assume that the last 'else if' in your example was a type and you're actually checking that variableN == 2.
rule "A1-2"
when
Inputs( variableA == 1,
variableA1 == 2 )
then
// ...
end
rule "A1-3"
when
Inputs( variableA == 1,
variableA1 == 3 )
then
// ...
end
rule "B1"
when
Inputs( variableA != 1,
variableB1 == 1 )
then
// ...
end
rule "B2-N1"
when
Inputs( variableA != 1,
variableB1 == 2,
variableN == 1 )
then
// ...
end
rule "B2-N2"
when
Inputs( variableA != 1,
variableB1 == 2,
variableN == 2 )
then
// ...
end
Rather straight forward. The key is that you need to check that the condition for variableA ==1 is not true for the rules that deal with B. Basically when you're converting an if/elsif/else into rules, you need to negate the conditions from the previous if-clauses on your left-hand-side.
There's no "specified groups" involved. Mostly because there's no explanation about what you mean by these words.
Drools also has inheritance. There's no real reason to use it here, but you could if you wanted to:
rule "A1"
when
$i: Inputs(variableA == 1)
then // notice empty "then"
end
rule "A1 = 2" extends "A1"
when
Inputs( variableA1 == 2 ) from $i
then
//
end

Last elseif statement does not execute

My last elseif statement does not execute even if the conditions are met:
Currency_Exchanage != 'Select...' and all other variables (ETF_Exchanage, Index_Exchanage and Stock_Exchanage) = 'Select...'
Here is the section of code that I am concerned about:
if (strcmp(ETF_Exchanage,'Select...') == 1) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1)
if db == 1 && uni == 1
tickers = gnr_bloomberg; % Analsise Bloomberg natural resources
nrm=1;
elseif db == 1 && uni == 2
tickers = all_bloomberg; % Analsise Bloomberg all
nrm=1;
elseif db == 2 && uni == 1
tickers = gnr_yahoo; % Analsise Yahoo natural resources
nrm=1;
elseif db == 2 && uni == 2
tickers = all_yahoo; % Analsise Yahoo all
nrm=1;
end
else
%Yahoo inputs
if (strcmp(ETF_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from ETF
tickers = ETF_Yahoo(:,1);
Exchanges = ETF_Yahoo(:,2);
Exchange = ETF_Exchanage;
db=2; %Yahoo Selection
elseif (strcmp(Index_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(ETF_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from Index
tickers = Index_Yahoo(:,1);
Exchanges = Index_Yahoo(:,2);
Exchange = Index_Exchanage;
db=2;
elseif (strcmp(Stock_Exchanage,'Select...') == 0) && (strcmp(ETF_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(Currency_Exchanage,'Select...') == 1); %Choose exhanges from Stock
tickers = Stock_Yahoo(:,1);
Exchanges = Stock_Yahoo(:,2);
Exchange = Stock_Exchanage;
db=2;
elseif (strcmp(Currency_Exchanage,'Select...') == 0) && (strcmp(Stock_Exchanage,'Select...') == 1) && (strcmp(Index_Exchanage,'Select...') == 1)...
(strcmp(ETF_Exchanage,'Select...') == 1); %Choose exhanges from Currency
tickers = Currency_Yahoo(:,1);
Exchanges = Currency_Yahoo(:,2);
Exchange = Currency_Exchanage;
db=2;
else
msg = 'Error occurred.\Only one Yahoo input menue must be used!';
error(msg)
end
end
Any Help would be much appropriated, I can't see where I'm going wrong here. I am using Matlab 2013a.
Put a breakpoint at the elseif statement in question and then check in the command window what your condition evaluates to.
If it does not evaluate like expected, check what the individual terms evaluate to.
It is important to actually test what the conditions evaluate to in matlab, rather than only visually comparing the string values.
Usually by that point you should get a rough idea what is wrong.
However in your case we can't do these steps for you because something is off. Your code condensed to the more reasonable minimal example
if 1 && 1 && 1...
1;
disp('I was here')
end
does not even execute in R2014a since the interpreter complains about '...' being an unexpected matlab expression.

Locating syntax error in Drools

I have a drool file where rule 2 is always coming out to true.
rule "R2"
salience 1000
when
((residence status = "US Citizen") || ((residence status = "Lawfully-entered Alien") and (residence duration >= 5))) and (fpl <= 133)
then
Add to Programs List "3"
end
the value of
residence status is US Citizen
residence status is null
residence duration is 0
fpl is 278.77
Why it is going into it always though for specified value the condition is false .
Kindly find the all files.
package com.eligibility.service;
import com.platform.enrollment.domain.BasicInfo;
import com.platform.enrollment.domain.FamilyMember;
global java.util.List prog_id_list;
global java.lang.Double fpl;
[condition][] and=and
[condition][] or=or
[condition][]residence status \= "{value}"=FamilyMember(basicInfo.citizenshipStatus == "{value}")
[condition][]residence duration >\= {value}=FamilyMember(basicInfo.permanentResidenceDuration >= {value})
[condition][]job status \= "{value}"=FamilyMember(basicInfo.jobStatus == "{value}")
[condition][]large business status \= "{value}"=FamilyMember(basicInfo.largeBusinessStatus == "{value}")
[condition][]false=eval(false)
[condition][]true=eval(true)
[condition][]age \= {value}=FamilyMember(basicInfo.getAge=={value})
[condition][]age < {value}=FamilyMember(basicInfo.getAge<{value})
[condition][]age > {value}=FamilyMember(basicInfo.getAge>{value})
[condition][]age <\= {value}=FamilyMember(basicInfo.getAge<={value})
[condition][]age >\= {value}=FamilyMember(basicInfo.getAge>={value})
[condition][]fpl \= {value}=eval(fpl=={value})
[condition][]fpl < {value}=eval(fpl<{value})
[condition][]fpl > {value}=eval(fpl>{value})
[condition][]fpl <\= {value}=eval(fpl<={value})
[condition][]fpl >\= {value}=eval(fpl>={value})
[condition][]gender \= "{value}"=FamilyMember(basicInfo.gender == "{value}")
[condition][]pregnant \= true=Applicant(eval(pregnant))
[condition][]pregnant \= false=Applicant(eval(!pregnant))
[condition][]Family member age greater than or equal to 60 \= true=eval(any_member_greater_than_equal_to_60)
[condition][]Family member age greater than or equal to 60 \= false=eval(!any_member_greater_than_equal_to_60)
[condition][]job status \= "{value}"=Applicant(eval(job_status.contains("{value}")))
[condition][]large business status \= "{value}"=Applicant(eval(large_business_status.contains("{value}")))
[condition][]employer benefits \= "{value}"=Applicant(eval(large_business_status.contains("{value}")))
[condition][]spouse \= true=eval(spouse)
[condition][]spouse \= false=eval(!spouse)
[condition][]total assets \= {value}=eval(total_assets=={value})
[condition][]total assets < {value}=eval(total_assets<{value})
[condition][]total assets > {value}=eval(total_assets>{value})
[condition][]total assets <\= {value}=eval(total_assets<={value})
[condition][]total assets >\= {value}=eval(total_assets>={value})
[condition][] Question with code "{code}" has answer "{answer}"=Question(code=="{code}"&& eval(answer.contains("{answer}")))
[consequence][]Add to Programs List {id}=prog_id_list.add({id});
rule "R0"
salience 1000
when
(age <= 0) and ((residence status = "US Citizen") || (residence status = "Lawfully-entered Alien")) and (fpl <= 200)
then
Add to Programs List "1"
end
rule "R1"
salience 1000
when
((residence status = "US Citizen") || (residence status = "Lawfully-entered Alien")) and (fpl >= 400)
then
Add to Programs List "2"
end
rule "R2"
salience 1000
when
((residence status = "US Citizen") || ((residence status = "Lawfully-entered Alien") and (residence duration >= 5))) and (fpl <= 133)
then
Add to Programs List "3"
end
rule "R3"
salience 1000
when
((residence status = "US Citizen") || (residence status = "Lawfully-entered Alien")) and (fpl > 133) and (fpl < 400)
then
Add to Programs List "4"
end
Can anybody help me why it is enetring is list3 though data as provided above is not making it valid
It could also be helpful to look at the generated java class for your rule and see what the issue might be.
Use:
-Ddrools.dump.dir=
to set path for the generated code.
It could also be helpful to set a rules listener and look at the fact insertions updates and rules firing sequence.
Also you could try to break the problematic rule into two rules without DSL as follows for debug purpose:
when
FamilyMember(basicInfo.citizenshipStatus == "US Citizen")
Fact(eval(fpl <= 133))
when
FamilyMember(basicInfo.citizenshipStatus == "Lawfully-entered Alien")
FamilyMember(basicInfo.permanentResidenceDuration >= 5)
Fact(eval(fpl <= 133))
Hope this helps.