Matching 2 Arrays
by Ken Archer
To create a condition to check if any value within an array of a fact matches any value within an array of values in a rule, the only only approach that seems to work is: WHEN (<Collection> CONTAINS <Value> || <Collection> CONTAINS <Value> || ...)
Is there a more straightforward and elegant approach this type of matching?
Ken Archer
Telogical Systems
15 years, 3 months
Temporal constraints
by Chris Richmond
Hello,
I am trying to make a rule to delay firing until a certain amount of time
has passed without another event being received. I have set up a loop that
goes every 10 seconds in my main application that takes readings and injects
them into the ReadingStream. These are like sensor readings.
I have a thread started at initialization that is basically calling
fireUntilHalt() and I never call halt until shutdown, and that seams to be
working fine.
So basically any time an out of spec reading in my Reading object (<15) is
received, I want to wait to see if a FollowUpReading is not received in the
next 5 seconds, before I fire the results(The second rule below). The first
rule is there just to verify I am indeed detecting NumReadings with values <
15 being injected and that works fine. Now at this point in my appication
I am *never* inserting a FollowUpReading object/event, so I would expect the
2nd rule to fire all the time, however the strange thing is that it only
fires the first time I receive a reading out of spec. I see rule one fire,
then the seond time, but after that any subsequent out of spec readings
received(I know they are out of spec, because rule 1 still fires when
received) but rule 2 never fires again. It only ever fires one time! This
is very confusing. These ar the only 2 rules and the only two object types
being inserted to the stream. Know that rule 2 *can* fire because it does
once and only once. Why won't it fire beyond the first time, even though I
never insert the FollowUpReading() ?
Thanks,
Chris
declare NumReading
@role( event )
end
declare FollowUpReading
@role(event)
end
rule "Determine out of spec reading"
when
$n : NumReading($r:reading < 15) from entry-point "ReadingStream";
then
System.err.println("Fire off a follow up reading for device: " + $n);
end
rule "Missed degrading confirmation reading"
when
$n : NumReading($r:reading < 15) from entry-point "ReadingStream";
not (FollowUpReading(this after[0s, 5s] $n))
then
System.err.println("No good reading received for: " + $n);
end
15 years, 3 months
Struggling to improve my rules performance !
by Costigliola Joel (EXT)
Hello,
I would like to improve the performance of my Drools process, I have already done some enhancements like removing the use of "collect" and "eval".
I must say I'm a Drools newbie struggling to determine what causes my performance problems.
Before asking, I need to explain in few words the problem I want to solve with Drools :
My company is a bank where traders are making deals on markets, these deals must be classified in book, this is what we call "booking process".
Booking is done according to booking criteria : which trader has made the deal ? on which product ? etc ...
A booking rule defines a set of criteria and the target book where the deal will classified.
I'm using Drools to :
1. find all booking rules matching deals made by traders
2. apply the right booking rule on the deal among the ones matching the deal (i.e. that is book the deal)
I'm testing the booking process with 1000 deals and 229 booking rule.
It takes 60 seconds for Drools to book the 1000 deals, which is too slow to be put in production.
On the 60 seconds, I have 7 seconds for facts insertion and the remaining for process (after session.fireAllRules)
Do you think such numbers are normal/expected ?
Like I said I don't really know where the performance bottlenecks are ... I'm thinking of exploring the following possibilities :
* splitting my rules into very simple rules
* starting the booking process with fewer data and running it several times (instead of one booking process on 1000, run 10 booking processes on 100 deals each)
I have put my rules code below (for courageous people), if you see some obvious performance problems or if you can give some hint to explore, you would be very welcome.
Thanks in advance for your lights,
Regards,
Joël Costigliola
Ps : rules details
I have defined a flow composed of 3 steps/rules group, each group has one rule, here's the flow and the rules.
Flow :
------
"Find matching booking rules" -> "Refresh" -> "Apply booking rule group"
Rules :
------
The job of this rule is to store in DealMatchingBookingRules all the booking rule matching a specific deal (each DealMatchingBookingRules instance has a unique Deal).
rule "Find matching level 1 booking rules by deal"
salience 10
no-loop
ruleflow-group "Find level 1 matching booking rules by deal group"
when
$dealMatchingBookingRules : DealMatchingBookingRules($dealModel : deal, $dealProductRelatedIndexes : dealProductRelatedIndexes)
$bookingRule : BTExecutionBookingRuleModel (
priority == 1
// when a criterion is not set, it is considered as satisfied.
&& (traderCriterion == null || $dealModel.trader == traderCriterion)
&& (portfolioCriterion == null || $dealModel.portfolio == portfolioCriterion)
// when a product type criterion is set to unknown, it is considered as satisfied whatever deal product type is.
&& (productTypeStringCriterion == null || productTypeCriterion == ProductType.Unknown
|| $dealModel.product.productType == productTypeCriterion)
&& (listedIndexCriterion == null || $dealProductRelatedIndexes.relatedIndexes contains listedIndexCriterion)
)
then
Logger log = LoggerFactory.getLogger("Matching booking rules LOGGER");
log.info("Found a level 1 matching rule for deal : " + $dealModel + ", rule is " + $bookingRule);
$dealMatchingBookingRules.addMatchingBookingRule($bookingRule);
end
// used to tell Drools that our $dealMatchingBookingRules are ready for next step in flow
rule "Refresh facts in level 1 booking rule process"
salience 5
no-loop
ruleflow-group "Refresh facts in level 1 booking rule process group"
when
$dealMatchingBookingRules : DealMatchingBookingRules()
then
update($dealMatchingBookingRules);
end
rule "Apply level 1 booking rule"
no-loop
ruleflow-group "Apply level 1 booking rule group"
when
$dealMatchingBookingRules : DealMatchingBookingRules(hasSingleMatchingLevel1BookingRule == true)
then
BTExecutionBookingRuleModel effectiveBookingRuleModel = $dealMatchingBookingRules.getSingleMatchingLevel1BookingRule();
effectiveBookingRuleModel.applyRuleOnDeal($dealMatchingBookingRules.getDeal());
retract($dealMatchingBookingRules);
end
--------------------------------------------------------
Ce courriel et toutes les pièces jointes sont confidentiels et peuvent être couverts par un privilège ou une protection légale. Il est établi à l'attention exclusive de ses destinataires. Toute utilisation de ce courriel non conforme à sa destination, toute diffusion ou toute publication, totale ou partielle, est interdite, sauf autorisation expresse préalable. Toutes opinions exprimées dans ce courriel ne sauraient nécessairement refléter celle de Natixis, de ses filiales. Elles sont aussi susceptibles de modification sans notification préalable. Si vous recevez ce courriel par erreur, merci de le détruire et d'en avertir immédiatement l'expéditeur. L'Internet ne permettant pas d'assurer l'intégrité de ce courriel, Natixis décline toute responsabilité s'il a été altéré, déformé ou falsifié et chaque destinataire qui utilise ce mode de communication est supposé en accepter les risques.
This email and any attachment are confidential and may be legally privileged or otherwise protected from disclosure. It is intended only for the stated addressee(s) and access to it by any other person(s) is unauthorised. Any use, dissemination or disclosure not in accordance with its purpose, either in whole or in part, is prohibited without our prior formal approval. Any opinion expressed in this email may not necessarily reflect the opinion of Natixis, its affiliates. It may also be subject to change without prior notice. If you are not an addressee, you must not disclose, copy, circulate or in any other way use or rely on the information contained in this email. If you have received it in error, please inform us immediately and delete all copies. The Internet can not guarantee the integrity of this email therefore Natixis shall not be liable for the email if altered, changed or falsified and anyone who communicates with us by e-mail is taken to accept these risks.
--------------------------------------------------------
15 years, 3 months
Error accumulate function
by nestabur
Hi All,
I'm getting an error when firing the rule using the accumulate function:
Number(intValue >= 1) from accumulate( fact() over window:time(1d) from
entry-point "MyEntryPoint", init( int mytotal = 0; ),action( mytotal++;
),reverse( mytotal--; ),result( new Integer(mytotal) ))
The error is:
org.drools.RuntimeDroolsException: [Error: variable already defined within
scope: class java.lang.Integer mytotal]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]
at org.drools.rule.Accumulate.init(Accumulate.java:144)
at
org.drools.reteoo.AccumulateNode.assertLeftTuple(AccumulateNode.java:142)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.doPropagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:117)
at
org.drools.reteoo.SingleLeftTupleSinkAdapter.propagateAssertLeftTuple(SingleLeftTupleSinkAdapter.java:28)
at org.drools.reteoo.JoinNode.assertObject(JoinNode.java:175)
at
org.drools.reteoo.SingleObjectSinkAdapter.propagateAssertObject(SingleObjectSinkAdapter.java:42)
at
org.drools.reteoo.PropagationQueuingNode$AssertAction.execute(PropagationQueuingNode.java:326)
at
org.drools.reteoo.PropagationQueuingNode.propagateActions(PropagationQueuingNode.java:221)
at
org.drools.reteoo.PropagationQueuingNode$PropagateAction.execute(PropagationQueuingNode.java:394)
at
org.drools.common.AbstractWorkingMemory.executeQueuedActions(AbstractWorkingMemory.java:1486)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:158)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:122)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:80)
at org.drools.common.NamedEntryPoint.insert(NamedEntryPoint.java:28)
at
com.s2grupo.triton.service.impl.TemporalCorrelatorServiceImpl.insertFact(TemporalCorrelatorServiceImpl.java:95)
at
com.s2grupo.triton.jms.impl.JmsMessageListenerImpl.onMessage(JmsMessageListenerImpl.java:98)
at
org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1021)
at
org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:122)
at
org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:192)
at
org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:122)
at
org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:43)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: [Error: variable already defined within scope: class
java.lang.Integer mytotal]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]
at
org.drools.base.mvel.DroolsMVELFactory.createVariable(DroolsMVELFactory.java:252)
at
org.mvel2.ast.TypedVarNode.getReducedValueAccelerated(TypedVarNode.java:68)
at org.mvel2.MVELRuntime.execute(MVELRuntime.java:85)
at
org.mvel2.compiler.CompiledExpression.getValue(CompiledExpression.java:107)
at org.mvel2.MVEL.executeExpression(MVEL.java:978)
at org.drools.base.mvel.MVELAccumulator.init(MVELAccumulator.java:134)
at org.drools.rule.Accumulate.init(Accumulate.java:138)
... 23 more
Could anyone help me?
Thanks,
Nestor
--
View this message in context: http://www.nabble.com/Error-accumulate-function-tp25611774p25611774.html
Sent from the drools - user mailing list archive at Nabble.com.
15 years, 3 months
Events Temporal reasoning problem
by Chris Richmond
Hello,
I am trying to make a rule to delay firing until a certain amount of time
has passed without another event being received. I have set up a loop that
goes every 10 seconds in my main application that takes readings and injects
them into the ReadingStream. These are like sensor readings.
I have a thread started at initialization that is basically calling
fireUntilHalt() and I never call halt until shutdown, and that seams to be
working fine.
So basically any time an out of spec reading in my Reading object (<15) is
received, I want to wait to see if a FollowUpReading is not received in the
next 5 seconds, before I fire the results(The second rule below). The first
rule is there just to verify I am indeed detecting NumReadings with values <
15 being injected and that works fine. Now at this point in my appication
I am *never* inserting a FollowUpReading object/event, so I would expect the
2nd rule to fire all the time, however the strange thing is that it only
fires the first time I receive a reading out of spec. I see rule one fire,
then the seond time, but after that any subsequent out of spec readings
received(I know they are out of spec, because rule 1 still fires when
received) but rule 2 never fires again. It only ever fires one time! This
is very confusing. These ar the only 2 rules and the only two object types
being inserted to the stream. Know that rule 2 *can* fire because it does
once and only once. Why won't it fire beyond the first time, even though I
never insert the FollowUpReading() ?
Thanks,
Chris
declare NumReading
@role( event )
end
declare FollowUpReading
@role(event)
end
rule "Determine out of spec reading"
when
$n : NumReading($r:reading < 15) from entry-point "ReadingStream";
then
System.err.println("Fire off a follow up reading for device: " + $n);
end
rule "Missed degrading confirmation reading"
when
$n : NumReading($r:reading < 15) from entry-point "ReadingStream";
not (FollowUpReading(this after[0s, 5s] $n))
then
System.err.println("No good reading received for: " + $n);
end
15 years, 3 months
Event streams
by Chris Richmond
It is my understanding that an event will be detected as soon as it is
inserted into a stream.meaning that I don't have to explicitly call
fireRules in order to evaluate events, but them will be evaluated as soon as
I insert them into a stream, so a rule like the one below would fire as soon
as I perform datastream.insert(myDataStreamObject) without having to
explicitly fire rules? Is that behavior correct/intended?
Declare MyDataStreamObject
@role(event)
End
//rule "detect a stream data object"
When
MyDataStreamObject() from entry point "DATA"
Then
System.err.println("data object inserted");
end
Also, could I generate another event(long lived.say it lives 1 minute) so
that if the above event detector fired and some condition was met, I could
have it fire some event within the rule engine? Something like the
following:
//rule "detect a stream data object"
When
MyDataStreamObject($val: fieldValue < 20) from entry point
"DATA"
Then
//I want to raise an event purely from this rule that will live
for one minute or so, that I can use to further refine this rule, to make
sure this rule makes
//sure that the MyDataStreamObject event "NOT INCLUDED" within
the generated longer lived event lifetime. Efffectively preventing me from
firing this if one of my
//generated events is still living
end
Thanks,
Chris
15 years, 3 months
Error running Drools 5.0 HelloWorldExample on WebSphere 6.1
by Blythe, Marshall
Hi,
I'm evaluating Drools 5.0 for use in a WebSphere 6.1.0.13 (Java 1.5 JRE) environment, and I've encountered an exception that I can't seem to fix. I downloaded the Drools examples and started looking at the HelloWorldExample class. First I executed it on standalone IBM JVM (not in a servlet container), and it worked just fine.
Then I created a simple web app and modified the HelloWorldExample to allow it to be called from a servlet. I copied the Drools JARs to my WEB-INF/lib folder, and I set the classloader mode to PARENT_LAST to ensure my JARs would be picked up before those on the app server. When executed in this environment the HelloWorldExample fails with this exception:
[9/25/09 16:16:23:351 EDT] 00000021 SystemErr R org.drools.runtime.rule.ConsequenceException: [Error: System.out.println( message ): Class org.mvel2.optimizers.impl.refl.ReflectiveAccessorOptimizer can not access a member of class com.ibm.ejs.ras.SystemStream with modifiers "public"]
[Near : {... Unknown ....}]
^
[Line: 1, Column: 0]
The line of code that triggers this exception is "ksession.fireAllRules()" where "ksession" is an instance of StatefulKnowledgeSession. Does anyone know how to solve this problem?
----------------------------------------- This e-mail and any attachments may contain CONFIDENTIAL information, including PROTECTED HEALTH INFORMATION. If you are not the intended recipient, any use or disclosure of this information is STRICTLY PROHIBITED; you are requested to delete this e-mail and any attachments, notify the sender immediately, and notify the LabCorp Privacy Officer at privacyofficer(a)labcorp.com or call (877) 23-HIPAA.
15 years, 3 months
Agenda Filters usage
by Chris Richmond
Would agenda filters be a good usage in this scenario.
I have a set of objects I want to evaluate in stages, and so I only want
certain rules to fire at certain stages. So the idea would be to have the
main application do some work on those objects then updte and fire rules on
them for stage 1(Agenda Filter 1) where the rule enine would set some bits
based on the objects based on other fields.then the outside appliction would
process some more and then update the objects and fire ther rules for stage
2(Agenda Filter 2) and so on for many stages. This would make it easier to
write rules that only evaluate on the obects at certain stages and would
make it easier to write rules that don't' conflict with each other(i.e. a
rule I only want to evaluate stage 2 objects evaluating stage 1 objects).
IF this *is* a reasonable usage scenario, is there a sample in the
documentation of Firing rules on an agenda filter. I found reference to
writing a rule file that puts rules in certain agendas, but not actually
firing those rules from the client.
Thanks,
Chris
15 years, 3 months
java.lang.NoSuchMethodError (org.eclipse.jdt.internal.compiler.CompilationResult.getProblems())
by Vadivelkumar
Hi,
My Application service(Hilo) is using Jboss Server.
I have used drools rule engine as part of my Application Process.
I have compiled it using simple java void main class, it works fine.
Then i have converted as a simple java process & Deploy as part of
my application service, i'm getting below error in my stack trace.
Note:
1. Drools Version 5.0
2. Eclipse Version 3.5.0 (IDE which i have used to compile)
3. I have already tried the solutions suggested in http://www.jboss.org/community/wiki/RulesTomcat
. Still we are not able to resolve it?
java.lang.NoSuchMethodError:
org.eclipse.jdt.internal.compiler.CompilationResult.getProblems()[Lorg/
eclipse/jdt/core/compiler/CategorizedProblem;
org.drools.commons.jci.compilers.EclipseJavaCompiler
$3.acceptResult(EclipseJavaCompiler.java:321)
org
.eclipse
.jdt.internal.compiler.Compiler.handleInternalException(Compiler.java:
415)
org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:352)
org
.drools
.commons
.jci.compilers.EclipseJavaCompiler.compile(EclipseJavaCompiler.java:351)
org
.drools
.commons
.jci.compilers.AbstractJavaCompiler.compile(AbstractJavaCompiler.java:
51)
org
.drools
.rule.builder.dialect.java.JavaDialect.compileAll(JavaDialect.java:389)
org
.drools
.compiler
.DialectCompiletimeRegistry.compileAll(DialectCompiletimeRegistry.java:
56)
org.drools.compiler.PackageRegistry.compileAll(PackageRegistry.java:74)
org.drools.compiler.PackageBuilder.compileAll(PackageBuilder.java:690)
org.drools.compiler.PackageBuilder.addPackage(PackageBuilder.java:653)
org
.drools.compiler.PackageBuilder.addPackageFromDrl(PackageBuilder.java:
290)
org
.drools
.compiler.PackageBuilder.addKnowledgeResource(PackageBuilder.java:488)
org
.drools
.builder.impl.KnowledgeBuilderImpl.add(KnowledgeBuilderImpl.java:25)
It will be great, if anybody can help it.
Thanks,
Vadi
15 years, 3 months
java.lang.NoSuchMethodError while using Split node
by yuvraj.vohra@rbs.com
Hi,
I am new to the drools engine. I am using drools 5.0.
Issue is, If I add Split node to process flow, I am getting java.lang.NoSuchMethodError exception .
java.lang.NoSuchMethodError: .......returnValueEvaluator0(Lorg/drools/spi/ProcessContext;)Ljava/lang/Object;
..................ReturnValueEvaluator0Invoker.evaluate(Process................0ReturnValueEvaluator0Invoker.java:14)
at org.drools.workflow.instance.impl.ReturnValueConstraintEvaluator.evaluate(ReturnValueConstraintEvaluator.java:121)
at org.drools.workflow.instance.node.SplitInstance.internalTrigger(SplitInstance.java:62)
at org.drools.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:111)
at org.drools.workflow.instance.impl.NodeInstanceImpl.triggerConnection(NodeInstanceImpl.java:141)
at org.drools.workflow.instance.impl.NodeInstanceImpl.triggerCompleted(NodeInstanceImpl.java:128)
at org.drools.workflow.instance.node.StartNodeInstance.triggerCompleted(StartNodeInstance.java:49)
at org.drools.workflow.instance.node.StartNodeInstance.internalTrigger(StartNodeInstance.java:41)
at org.drools.workflow.instance.impl.NodeInstanceImpl.trigger(NodeInstanceImpl.java:111)
at org.drools.ruleflow.instance.RuleFlowProcessInstance.internalStart(RuleFlowProcessInstance.java:16)
at org.drools.process.instance.impl.ProcessInstanceImpl.start(ProcessInstanceImpl.java:185)
at org.drools.workflow.instance.impl.WorkflowProcessInstanceImpl.start(WorkflowProcessInstanceImpl.java:230)
at org.drools.common.AbstractWorkingMemory.startProcess(AbstractWorkingMemory.java:1639)
Could any one please let me know is this because of some problem with jars in classpath or I am missing something?
Thanks,
Yuvraj Vohra
***********************************************************************************
The Royal Bank of Scotland plc. Registered in Scotland No 90312. Registered Office: 36 St Andrew Square, Edinburgh EH2 2YB.
Authorised and regulated by the Financial Services Authority.
This e-mail message is confidential and for use by the
addressee only. If the message is received by anyone other
than the addressee, please return the message to the sender
by replying to it and then delete the message from your
computer. Internet e-mails are not necessarily secure. The
Royal Bank of Scotland plc does not accept responsibility for
changes made to this message after it was sent.
Whilst all reasonable care has been taken to avoid the
transmission of viruses, it is the responsibility of the recipient to
ensure that the onward transmission, opening or use of this
message and any attachments will not adversely affect its
systems or data. No responsibility is accepted by The
Royal Bank of Scotland plc in this regard and the recipient should carry
out such virus and other checks as it considers appropriate.
Visit our website at www.rbs.com
***********************************************************************************
15 years, 3 months