How to check for a variable number of "conditions" in a rule?

View: New views
4 Messages — Rating Filter:   Alert me  

How to check for a variable number of "conditions" in a rule?

by Ron Kneusel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Greetings!

I want to create a rule that checks a fact which contains an array to see if n or more of the elements of that array have a specific value.  The number of elements to check will vary from invocation to invocation of the rules engine and will likely be added as a global.

I can do this by using a helper function.  Say, for example, I have:

rule "fire_when_testFlags_true"
    when
        eval(testFlags(flags, limit.intValue()));
    then
        System.out.println("Yup, " + limit + " or more flags are true!");
end

Where flags and limit are both globals.  Then I can define testFlags as:

function boolean testFlags(Flags flags, int threshold) {
    int count = 0;

    for(int i=0; i < flags.getSize(); i++) {
        if (flags.getValue(i)) {
            count++;
            if (count>= threshold) {
                return true;
            }
        }
    }  
    return false;
}

This works but violates the warning not to use a global that isn't immutable in the LHS of a rule.  Does anyone have an idea about how to implement a rule that in effect has an arbitrary number of conditions to be tested?

Ron

_________________________________________________________________
Keep your kids safer online with Windows Live Family Safety.
http://www.windowslive.com/family_safety/overview.html?ocid=TXT_TAGLM_WL_family_safety_072008
_______________________________________________
rules-users mailing list
rules-users@...
https://lists.jboss.org/mailman/listinfo/rules-users

RE: How to check for a variable number of "conditions" ina rule?

by Anstis, Michael (M.) :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Ron,

Have a look at the "Alarms" example for "Collect" in the (4.0.5) manual.

This should give you a good starting point.

Cheers,

Mike

-----Original Message-----
From: rules-users-bounces@...
[mailto:rules-users-bounces@...] On Behalf Of Ron Kneusel
Sent: 22 July 2008 23:01
To: rules-users@...
Subject: [rules-users] How to check for a variable number of
"conditions" ina rule?


Greetings!

I want to create a rule that checks a fact which contains an array to
see if n or more of the elements of that array have a specific value.
The number of elements to check will vary from invocation to invocation
of the rules engine and will likely be added as a global.

I can do this by using a helper function.  Say, for example, I have:

rule "fire_when_testFlags_true"
    when
        eval(testFlags(flags, limit.intValue()));
    then
        System.out.println("Yup, " + limit + " or more flags are
true!");
end

Where flags and limit are both globals.  Then I can define testFlags as:

function boolean testFlags(Flags flags, int threshold) {
    int count = 0;

    for(int i=0; i < flags.getSize(); i++) {
        if (flags.getValue(i)) {
            count++;
            if (count>= threshold) {
                return true;
            }
        }
    }  
    return false;
}

This works but violates the warning not to use a global that isn't
immutable in the LHS of a rule.  Does anyone have an idea about how to
implement a rule that in effect has an arbitrary number of conditions to
be tested?

Ron

_________________________________________________________________
Keep your kids safer online with Windows Live Family Safety.
http://www.windowslive.com/family_safety/overview.html?ocid=TXT_TAGLM_WL
_family_safety_072008
_______________________________________________
rules-users mailing list
rules-users@...
https://lists.jboss.org/mailman/listinfo/rules-users

_______________________________________________
rules-users mailing list
rules-users@...
https://lists.jboss.org/mailman/listinfo/rules-users

Parent Message unknown RE: How to check for a variable number of "conditions" ina rule?

by Ron Kneusel :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


Mike,

I think the collect will work, I'll have to look at it more closely because the ordering of elements in the array is significant so I'm not sure I can just break the elements up into facts and let collect group them however it will.

As a follow up, while my solution of using a global in the LHS works, is the problem with changing the global simply that the engine will not see the changes?  For my case, the global is set before the rules engine is called and it will not change while the engine runs.

Ron

Mike wrote:
 
>Have a look at the "Alarms" example for "Collect" in the (4.0.5) manual.
>  
>This should give you a good starting point.
>  
>Cheers,
>      
>Mike

_________________________________________________________________
With Windows Live for mobile, your contacts travel with you.
http://www.windowslive.com/mobile/overview.html?ocid=TXT_TAGLM_WL_mobile_072008
_______________________________________________
rules-users mailing list
rules-users@...
https://lists.jboss.org/mailman/listinfo/rules-users

Re: How to check for a variable number of "conditions" ina rule?

by Edson Tirelli-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


   Ron, if your global is set before ***asserting facts**** to the working memory and not changed anymore, you can use it.
   Also, make sure your array or whatever is an attribute of a class, and so has some semantic to it.

   You can do things like this:

when
    MyArrayContainer( $flags : flags )
    Number( intValue >= SOME_GLOBAL_THRESHOLD ) from
          accumulate( $f : Flag( value == SOME_GLOBAL_VALUE ) from $flags,
                             count( $f ) )
then
   // threshold met
end

    Another options is just create a holder class for your globals and assert it as a fact instead of using globals:

when
    MyParameters( $threshold : threshold, $value : value )
    MyArrayContainer( $flags : flags )
    Number( intValue >= $threshold ) from
          accumulate( $f : Flag( value == $flags ) from $flags,
                             count( $f ) )
then
   // threshold met
end
 

    Hope it helps,
       Edson


2008/7/23 Ron Kneusel <oneelkruns@...>:

Mike,

I think the collect will work, I'll have to look at it more closely because the ordering of elements in the array is significant so I'm not sure I can just break the elements up into facts and let collect group them however it will.

As a follow up, while my solution of using a global in the LHS works, is the problem with changing the global simply that the engine will not see the changes?  For my case, the global is set before the rules engine is called and it will not change while the engine runs.

Ron

Mike wrote:

>Have a look at the "Alarms" example for "Collect" in the (4.0.5) manual.
>
>This should give you a good starting point.
>
>Cheers,
>
>Mike

_________________________________________________________________
With Windows Live for mobile, your contacts travel with you.
http://www.windowslive.com/mobile/overview.html?ocid=TXT_TAGLM_WL_mobile_072008
_______________________________________________
rules-users mailing list
rules-users@...
https://lists.jboss.org/mailman/listinfo/rules-users



--
Edson Tirelli
JBoss Drools Core Development
JBoss, a division of Red Hat @ www.jboss.com

_______________________________________________
rules-users mailing list
rules-users@...
https://lists.jboss.org/mailman/listinfo/rules-users
LightInTheBox - Buy quality products at wholesale price