Ok, so you may need something like this:
1) You need a bean to store the parameter. You can declare it in DRL, or
use a normal java class and insert the instance from the main.
The DRL version would be this:
declare Parameters
threshold : double
end
rule "Initialize"
salience 9999 // fire first!
when
then
insert( new Parameters( 10.0 ) ); // your value here
end
Or, you can set a global:
// in java:
kSession.setGlobal( "threshold", 1.0 );
// in DRL, at the beginning:
global Double threshold;
2) You need rule "one" and something to hold your current average
temperature:
( ps. sorry, the $pers : person : Person() was a typo! :) )
Now: do you need to relate the temperature to the person? I mean, how
many Person
are there in your workingmemory? I guess one, also considering that the
SensorReading
are not related to the person... In any case, here Person is acting as
an "enabler fact"
or "guard" which effectively decides if the rule is applicable or not. So:
declare AverageTemperatureRecord // again, this or a java class
value : double
end
rule "one"
$pers : Person( gender == 'M' )
accumulate (
SensorReading( $temp : temperature ) over window:time( 10m ),
$avg : average( $temp );
then
insertLogical( new AverageTempRecord( $avg ) );
end
Notice the use of "insertLogical" : your average will change over time
(but see my remark about rule 2 below), so you may want to keep
only the latest value, or a "history" with all of them?
InsertLogical will make sure that a fact is retracted when its conditions
no longer hold, and in case of an accumulate this is done when the
aggregation set changes, i.e. whenever a SensorReading slides in or
out of the window... The net effect is that the latest will take
the place of the previous, which is different from keeping them all
in memory, or keeping one an modifying it every time - all behaviours
that can be obtained with slightly different rules.
3) Now you can write rule two: If you have the parameter object:
rule "two"
Parameters( $max : threshold )
$a : AverageTemperatureRecord( $avg : avg> $max )
then
// do something
end
or you can use the global :
rule "two with global "
$a : AverageTemperatureRecord( $avg : avg> threshol )
then
// do something
end
notice that your previous rule
rule "two - previous"
$p : Person( gender == 'M' )
Parameters( $max : threshold )
$a : AverageTemperatureRecord( $avg : avg> $max )
then
// do something
retract( $p );
end
This rule - which does not need an agenda group - will be EVALUATED for
every new AvgTempRecord (insertLogical will make
sure that only the last remains in the WM, but this will not affect the
evaluations: every ATR will be checked).
[ Notice that this is not a "call", but a producer-consumer relation
mediated by the working memory. Rule one generates some
data and drops them into a common environment. Rule two "picks it up"
and sees whether it matches its conditions or not.
You WOULD probably need the agenda-groups if other sources could
generate the ATRs for rule "two", but here rule "two"
can only be activated after rule "one" has fired, producing the
necessary fact]
If at some point the > constraint is satisfied, the rule will be
ACTIVATED and then FIRED. If the consequence retracts $p,
as you were doing, the guard patterns will no longer satisfied and rule
"one" (and two) will not be activated anymore.
On 09/28/2012 11:01 AM, thano wrote:
First of all many thanks for helping me here. I completely agree with
you
that I need to look into the basics. I will definitely start with drools
manual and examples.
coming back to the example which may not make a complete sense; I have a
deadline to meet and therefore, I dont have much time to look around. I
really appreciate your efforts for explaining my example. Basically, This is
what I am trying to achieve
rule 1 should check a condition and then perform the average. It also
retrieve a threshold from a class (just to show that). It then jump to rule
2 and thats why I used the agenda group.
rule 2 should only compare the average and the threshold. It should have
access to the average and the threshold. That is why i thought of inserting
them as facts in the first rule.
could you please look into the code below and give me further advise.
much appreciated
declare parameters
avg:double
end
rule "one"
$pers : person : Person( gender == 'M' ) // why $pers : person and not only
$pers
accumulate (
SensorReading( $temp : temperature ) over window:time( 10m ),
$avg : average( $temp );
then
insertLogical( /*$pers,*/ new AverageTempRecord( $avg ) ); // could you
please explain this. How exactly it should appear
drools.setFocus ("Two");
end
rule "two"
//should only compare avg>threshold
agenda-group "Two"
$p : Person() // I want threshold here
$a : AverageTemperatureRecord( /* pers == $p, */ $avg : avg )
then
end
--
View this message in context:
http://drools.46999.n3.nabble.com/function-in-drools-tp4020021p4020047.html
Sent from the Drools: User forum mailing list archive at
Nabble.com.
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users