Type-Casting in when-part of rule
by Fermion
Hi!
I'm using pattern matching on Java objects in the when part of my rules. One
example might be:
CommonDataObject($name : name matches ".*STATUS_D.._B..\.fsm.*", type ==
Type.STRING, $stringValue : stringValue != "OK" && stringValue != "UNKNOWN")
So you can see, that my Java object "CommonDataObject" has at least 3
members: name, type and stringValue.
This works all fine.
Unfortunately my object could also hold a Float or an Integer value.
The current implementation uses additional "floatValue" and "integerValue"
members in order to access them from the rules.
I would prefer very much to remove my "stringValue", "floatValue" and
"integerValue" members at all. As I already have a "type" member (which can
be Type.STRING, Type.FLOAT or Type.INTEGER), I would like to just store one
member called "value" which would then just be an Object.
As the rules have access to the type-member, they should then be able to
cast the value-member to the correct type:
CommonDataObject($name : name matches ".*STATUS_D.._B..\.fsm.*", type ==
Type.STRING, $value : (String)value != "OK" && (String)value != "UNKNOWN")
Unfortunately it seems, that a direct type-cast is not possible in the when
part of a rule.
Maybe someone knows a way to realize this functionality...
Thanks in advance!
--
View this message in context: http://www.nabble.com/Type-Casting-in-when-part-of-rule-tp16628142p166281...
Sent from the drools - user mailing list archive at Nabble.com.
16 years, 7 months
RE: [rules-users] Synch Business Object / Working Memory
by Jonathan Guéhenneux
Ok.
I have to compute the gravity for a large number of debts. (It must be done as fast as possible). The customer give me the rules 'in natural language' and a ruleflow.
The ruleflow : attached to this mail, I hope
Problems :
1) no more than 1 rule can be activated in each ruleflowgroup (thats why I used the "computed")
2) using "computed", I realize that the value of "computed" in the real object was true after the first rule activated, but still false in his shadow.
3) so I used update. It worked fine for the first ruleflow group, but in the second ruleflow group (compute C), the first rule was activated again and again (I absolutely need to know the new value of C in order to compute D, so I also used update in this group).
4) Solution : use booleans to control the ruleflow ... without ruleflow.
That's where I am.
Subject: RE: [rules-users] Synch Business Object / Working Memory
Date: Fri, 11 Apr 2008 15:57:03 +0100
From: manstis1(a)ford.com
To: rules-users(a)lists.jboss.org
I am confident Drools supports what you are looking for; did you try update() - or modify() - in the 'then' part of the rule (and not in Java as you code snippet)? Can you explain more the need for the 'computed' flag on the fact? Is the value of a property set sometimes whilst calculated at other times? Stick with both Drools and the group - we'll get you to where you want to be.
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@lists.jboss.org] On Behalf Of Jonathan Guéhenneux
Sent: 11 April 2008 15:41
To: Rules Users List
Subject: RE: [rules-users] Synch Business Object / Working Memory
First, thank you for yours answers which are very clear. Your solution will probably work. I'm just desapointed that there is no way to synchronized the shadow with the object. That would be great for my work.
Subject: RE: [rules-users] Synch Business Object / Working Memory
Date: Fri, 11 Apr 2008 14:57:52 +0100
From: manstis1(a)ford.com
To: rules-users(a)lists.jboss.org
Do you need ruleflow? Perhaps this is too simple and I misunderstood. package com.sample; public class Test { private Integer a;
private Integer b;
private Integer c; public Integer getA() {
return a;
} public Integer getB() {
return b;
} public Integer getC() {
return c;
} public void setA(Integer a) {
this.a = a;
} public void setB(Integer b) {
this.b = b;
} public void setC(Integer c) {
this.c = c;
} } package com.sample import com.sample.Test
rule 'rule 1'
salience 90
when
a : Test( a != null, b == null )
then
System.out.println('setting b to 10');
a.setB(10);
update(a);
end rule 'rule 2'
salience 80
when
a : Test( b : b != null, c == null )
then
System.out.println('setting c to b x 5');
a.setC(b * 5);
update(a);
end rule 'rule 3'
salience 70
when
a : Test( c != null )
then
System.out.println('c = ' + a.getC());
end
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@lists.jboss.org] On Behalf Of Jonathan Guéhenneux
Sent: 11 April 2008 13:23
To: Rules Users List
Subject: RE: [rules-users] Synch Business Object / Working Memory
Indeed, it works but I will have to use such booleans for a lot of rules.
Cause my rule flow is schematically :
compute A
compute B(A)
compute C(B)
...
Perhaps I may create several ruleflows, one per independant computing?
Subject: RE: [rules-users] Synch Business Object / Working Memory
Date: Fri, 11 Apr 2008 12:11:32 +0100
From: manstis1(a)ford.com
To: rules-users(a)lists.jboss.org
I was thinking something more like this:- package com.sample import com.sample.Test
rule 'rule 1 - 1'
salience 90
when
a : Test(
computed == 'false',
c < 15,
d >= 75)
then
System.out.println('setting e to 0');
a.setE(0);
update(a);
end rule 'rule 1 - 2'
salience 10
when
a : Test(
computed == 'false',
c < 15,
d >= 75)
then
System.out.println('setting e to 1');
a.setE(1);
end
Note rule 'rule 1 - 2' deliberately uses the same patterns as rule 'rule 1 - 1'. package com.sample; public class Test {
private boolean computed =false;
private int c=0;
private int d=80;
private int e; public String getComputed(){
if(computed)
return 'true';
else
return 'false';
} public int getC() {
return c;
} public int getD() {
return d;
} public void setE(int e){
this.e = e;
computed = true;
} }
Rule 'rule 1 - 1' is the only rule to run (and runs once); the second activatino being cancelled due to the update to 'computed'. Here's the audit view:- <object-stream>
<list>
<org.drools.audit.event.ActivationLogEvent>
<activationId>rule 1 - 1 [1]</activationId>
<rule>rule 1 - 1</rule>
<declarations>a=com.sample.Test@67126712(1)</declarations>
<type>4</type>
</org.drools.audit.event.ActivationLogEvent>
<org.drools.audit.event.ActivationLogEvent>
<activationId>rule 1 - 2 [1]</activationId>
<rule>rule 1 - 2</rule>
<declarations>a=com.sample.Test@67126712(1)</declarations>
<type>4</type>
</org.drools.audit.event.ActivationLogEvent>
<org.drools.audit.event.ObjectLogEvent>
<factId>1</factId>
<objectToString>com.sample.Test@67126712</objectToString>
<type>1</type>
</org.drools.audit.event.ObjectLogEvent>
<org.drools.audit.event.ActivationLogEvent>
<activationId>rule 1 - 1 [1]</activationId>
<rule>rule 1 - 1</rule>
<declarations>a=com.sample.Test@67126712(1)</declarations>
<type>6</type>
</org.drools.audit.event.ActivationLogEvent>
<org.drools.audit.event.ActivationLogEvent>
<activationId>rule 1 - 2 [1]</activationId>
<rule>rule 1 - 2</rule>
<declarations>a=com.sample.Test@67126712(1)</declarations>
<type>5</type>
</org.drools.audit.event.ActivationLogEvent>
<org.drools.audit.event.ObjectLogEvent>
<factId>1</factId>
<objectToString>com.sample.Test@67126712</objectToString>
<type>2</type>
</org.drools.audit.event.ObjectLogEvent>
<org.drools.audit.event.ActivationLogEvent>
<activationId>rule 1 - 1 [1]</activationId>
<rule>rule 1 - 1</rule>
<declarations>a=com.sample.Test@67126712(1)</declarations>
<type>7</type>
</org.drools.audit.event.ActivationLogEvent>
</list>
</object-stream>
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@lists.jboss.org] On Behalf Of Jonathan Guéhenneux
Sent: 11 April 2008 11:33
To: Rules Users List
Subject: RE: [rules-users] Synch Business Object / Working Memory
Ok, I think I understood well. I modified my business code, now I call if
(wm != null)
wm.update(wm.getFactHandle(this), this);
each time a properties is modified.
But it is worse. Rules that sould be activated only once actually loop, even if I add the no-loop clause.
I understand why they loop, assuming update = (rectact + insert), but I dont get a solution to my problem. I just want to notify an object changement in order to read again the properties, but I dont want to restart the ruleflow.
Sorry, but I find hard to say it in english because even in french, it's not very clear ;)
Subject: RE: [rules-users] Synch Business Object / Working Memory
Date: Fri, 11 Apr 2008 10:39:41 +0100
From: manstis1(a)ford.com
To: rules-users(a)lists.jboss.org
In essence, yes. Have a look at 'update' in the manual (and a read on Shadow Facts will probably be useful too).
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@lists.jboss.org] On Behalf Of Jonathan Guéhenneux
Sent: 11 April 2008 10:24
To: Rules Users List
Subject: RE: [rules-users] Synch Business Object / Working Memory
yes, i made a mistake. its a.setE(...) and not c.setE(...).
I don't call update. If I dont call update, properties of an object are just read one time for all rules?
Subject: RE: [rules-users] Synch Business Object / Working Memory
Date: Fri, 11 Apr 2008 09:47:43 +0100
From: manstis1(a)ford.com
To: rules-users(a)lists.jboss.org
I guess the example is a simplification as 'c' (in RHS) has not been bound to a fact. Anyway, that aside, do you call 'update' to ensure WM knows of changes to facts otherwise properties need to be 'time-constant' which in your example they are not.
From: rules-users-bounces(a)lists.jboss.org [mailto:rules-users-bounces@lists.jboss.org] On Behalf Of Jonathan Guéhenneux
Sent: 11 April 2008 09:34
To: Rules Users List
Subject: [rules-users] Synch Business Object / Working Memory
Hi,
I have two rules :
rule 'rule 1 - 1'
salience 90
ruleflow-group 'rfg1'
when
a : A(
eComputed == 'false',
c < 15,
d >= 75)
then
c.setE(0);
end
rule 'rule 1 - 2'
salience 10
ruleflow-group 'rfg1'
when
a : A(
eComputed == 'false',
c >= 15,
d >= 75)
then
c.setE(1);
end
and part of the corresponding business code :
public class A {
...
public String getEComputed(){
if(eComputed)
return 'true';
else
return 'false';
}
...
public void setE(int e){
this.e = e;
eComputed = true;
}
...
}
so, I expected that if the first rule is activated, the second won't be. But according to my tests, the two rule can be fired on the same object A.
While debugging, I noticed the getEComputed method was only called once. I suppose that I should write this :
rule 'rule 1 - 1'
salience 90
ruleflow-group 'rfg1'
when
a : A(
eComputed == 'false',
c < 15,
d >= 75)
then
c.setE(0);
c.setEComputed('true);
end
rule 'rule 1 - 2'
salience 10
ruleflow-group 'rfg1'
when
a : A(
eComputed == 'false',
c >= 15,
d >= 75)
then
c.setE(1);
c.setEComputed('true);
end
But I would prefer another solution. Thanks for help.
Plus de 15 millions de français utilisent Windows Live Messenger ! Téléchargez Messenger, c'est gratuit !
Plus de 15 millions de français utilisent Windows Live Messenger ! Téléchargez Messenger, c'est gratuit !
Tous vos amis discutent sur Messenger, et vous ? Téléchargez Messenger, c'est gratuit !
Tous vos amis discutent sur Messenger, et vous ? Téléchargez Messenger, c'est gratuit !
Discutez gratuitement avec vos amis en vidéo ! Téléchargez Messenger, c'est gratuit !
_________________________________________________________________
Recevez tous vos e-mails sur un seul compte ! Créez une adresse Hotmail !
http://www.windowslive.fr/hotmail/default.asp
16 years, 7 months
Error on access variable in workingmemorylogger
by vdelbart
Hello,
I have an error on WorkingMemoryLogger with this rule :
package example
import mcmipih.rules.demo.model.*;
global Param param;
rule "Your Third Rule"
dialect "mvel"
when
Param( iep : IEP ) from param
then
System.out.println("Iep de param " + iep);
end
The error :
java.lang.NullPointerException
at
org.drools.base.mcmipih.rules.demo.model.Param22676229$getIEP.getValue(Unknown
Source)
at
org.drools.base.ClassFieldExtractor.getValue(ClassFieldExtractor.java:127)
at org.drools.rule.Declaration.getValue(Declaration.java:198)
at
org.drools.audit.WorkingMemoryLogger.extractDeclarations(WorkingMemoryLogger.java:265)
at
org.drools.audit.WorkingMemoryLogger.activationCreated(WorkingMemoryLogger.java:199)
at
org.drools.event.AgendaEventSupport.fireActivationCreated(AgendaEventSupport.java:75)
at
org.drools.reteoo.RuleTerminalNode.assertTuple(RuleTerminalNode.java:331)
at
org.drools.reteoo.RuleTerminalNode.assertTuple(RuleTerminalNode.java:137)
at
org.drools.reteoo.SingleTupleSinkAdapter.propagateAssertTuple(SingleTupleSinkAdapter.java:20)
at org.drools.reteoo.FromNode.assertTuple(FromNode.java:90)
at
org.drools.reteoo.SingleTupleSinkAdapter.createAndPropagateAssertTuple(SingleTupleSinkAdapter.java:55)
at
org.drools.reteoo.LeftInputAdapterNode.assertObject(LeftInputAdapterNode.java:116)
at
org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:22)
at org.drools.reteoo.ObjectTypeNode.assertObject(ObjectTypeNode.java:153)
at org.drools.reteoo.Rete.assertObject(Rete.java:175)
at org.drools.reteoo.ReteooRuleBase.assertObject(ReteooRuleBase.java:192)
at
org.drools.reteoo.ReteooWorkingMemory$WorkingMemoryReteAssertAction.execute(ReteooWorkingMemory.java:179)
at
org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:1315)
at
org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:462)
at
org.drools.common.AbstractWorkingMemory.fireAllRules(AbstractWorkingMemory.java:433)
at
execute.ExecReglesWorkingMemory.testExecReglesWorkingMemory(ExecReglesWorkingMemory.java:107)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at
org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
The workingmemorylogger wants to show the value of the variable iep even if
my 'param' is not present in the working memory !
Is it a bug ?
thanks for your help,
regards,
V.
--
View this message in context: http://www.nabble.com/Error-on-access-variable-in-workingmemorylogger-tp1...
Sent from the drools - user mailing list archive at Nabble.com.
16 years, 7 months
Access to currently executing rule in consequence?
by rrogers@us.imshealth.com
Is there an easy way to access information about the currently executing
rule (e.g. Name, salience, group) within a rule consequence? E.g.
rule "Sample Rule"
salience = 100
when
$v : Fact(name == "Test")
then
System.out.println("The currently executing rule is " +
<???>.getName());
end
I could copy the name into the print but of course then I have it in two
places I need to keep in sync. I know I can get the full log but that's
not what I'm interested in.
-Russ
16 years, 7 months
Synch Business Object / Working Memory
by Jonathan Guéhenneux
Hi,
I have two rules :
rule "rule 1 - 1"
salience 90
ruleflow-group "rfg1"
when
a : A(
eComputed == "false",
c < 15,
d >= 75)
then
c.setE(0);
end
rule "rule 1 - 2"
salience 10
ruleflow-group "rfg1"
when
a : A(
eComputed == "false",
c >= 15,
d >= 75)
then
c.setE(1);
end
and part of the corresponding business code :
public class A {
...
public String getEComputed(){
if(eComputed)
return "true";
else
return "false";
}
...
public void setE(int e){
this.e = e;
eComputed = true;
}
...
}
so, I expected that if the first rule is activated, the second won't be. But according to my tests, the two rule can be fired on the same object A.
While debugging, I noticed the getEComputed method was only called once. I suppose that I should write this :
rule "rule 1 - 1"
salience 90
ruleflow-group "rfg1"
when
a : A(
eComputed == "false",
c < 15,
d >= 75)
then
c.setE(0);
c.setEComputed("true);
end
rule "rule 1 - 2"
salience 10
ruleflow-group "rfg1"
when
a : A(
eComputed == "false",
c >= 15,
d >= 75)
then
c.setE(1);
c.setEComputed("true);
end
But I would prefer another solution. Thanks for help.
_________________________________________________________________
Créez votre disque dur virtuel Windows Live SkyDrive, 5Go de stockage gratuit !
http://www.windowslive.fr/skydrive/
16 years, 7 months
Nested Rules
by Swathi B
Hi All,
This is Swathi..this is my first post to the group.
Can any one tell me whether nested rules is possible in drools rules engine?
Example : Based on successful execution of one rule is there any way/means
to
execute another rule at a time.
Thanks in Advance,
Swathi.
--
View this message in context: http://www.nabble.com/Nested-Rules-tp16627823p16627823.html
Sent from the drools - user mailing list archive at Nabble.com.
16 years, 7 months
Shouldn't inserted objects be finalized after session.dispose()?
by Sylvain Gaudan
Hi,
I thought that inserted objects should be finalized by the GC once
a statefulsession is dropped by session.dispose(). However, this is
done only if I retract handles one by one (session.retract(it.next()))
using the method session.iterateFactHandles() and then
session.dispose().
Is it wrong to expect that the object should be dropped by the GC
once the session is disposed?
Thank you for your help.
Kind regards,
Sylvain.
16 years, 7 months
the "not in" expression does not work...have u ever had this issue before?
by mmquelo massi
Hi there!
I am using a svn-built version of drools-core.jar and
drools-decisiontable.jar runtime lib (3rd March 2008).
I have got the following "Decision table" generated row:
*#From row number: 25*
*rule "Otherwise_25"*
**
*no-loop true*
*ruleflow-group "Convert"*
*when*
* cw:ContractWrapper(mycontract.serviceDetail.name not in ("STRING 1",
"STRING 2", "STRING 3", "STRING 4", "STRING 5", null))*
*then*
* ...*
*end*
The point is... despite of a ContractWrapper fact that DOES NOT encapsulate
a
nested 'name' whose value is in the above set, the rule does not fire
anyway.
For instance, if i have got a fact (in working memory) cw1 of class
ContractWrapper with cw1.mycontract.serviceDetail.name = "*STRING *6",
i expect the rule "Otherwise_25" to fire BUT IT ACTUALLY DOES NOT!
Furthermore if i omit the 'not' operator and i insert a fact cw2 with
cw2.mycontract.serviceDetail.name = "*STRING *2",
the RULE DOES fire!
For this reason there should be something wrong with the "not" operator.
but I do not know what exactly!
By the time the rule is generated from an .xls decision table
i really would not express the "otherwise" rule simply using
a sequence of "!=" and "and" operators (which would be a workaround)
.... If I did so the decisiontable would appear "too technical" and
not suitable for a business user.
Have u ever had this issue before?
I have also tried to omit the "null" value from the set but thait is not
the problem.
Please let me know.
Massi
16 years, 7 months