How to check for a variable number of "conditions" in a rule?
by Ron Kneusel
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_...
17 years, 11 months
RuleFlow Spanning Multiple Packages
by Carlsen, Len
Hi All,
Is it possible to define a rule flow that spans multiple packages
(rulesets).
Currently we have the 3 packages (and we are planning on dividing them
into more sub-packages):
Package1: 10,000 rules
Package2: 5000 rules
Package3: 1000 rules
And we would like to create one rule flow for all 3 packages.
I have looked through the documentation and it seems that you can only
create one rule flow per package.
Am I right or have I missed something somewhere?
We are using Drools 4.0.7
Thanks,
Len
17 years, 11 months
Clarification of using collections as facts
by Bagwell, Allen F
I'm going through the Drools documentation regarding the use of lists and other collections. I want to make sure my understanding is correct.
So if I have a class:
public class Foo {
private int x;
private int y;
private List<String> names = ArrayList<String>();
public List<String> getNames() {return names;}
// appropriate getters/setters for the int fields ...
}
With this I can insert a Foo object into working memory. I can even make the int fields dynamic facts with the appropriate addition of "bean-ifying" code.
For the List, however, I need to insert it separately into working memory in order to make use of Drools' rule language ('contains' ,etc.)? I'm assuming that doesn't come free because I have to insert my own custom class objects if they are included via composition in a larger fact!
Also, I'm guessing the Collection type classes cannot be dynamic facts? Meaning if I modify my List with add, remove, clear, etc., I must explicitly call update in my code on the List fact in order to alert Drools to a change in the List, correct?
So then the question also comes up as to how I would write a rule that looks for all instances of Strings in the List that match against a given regex expression. I've not been successful at figuring this out...
Rule "when a Foo List is modified, get all Strings in it that start with 'error'"
when
$foo : Foo($names : names)
$foundThese : ArrayList() from collect(??? matches "error.*" from $names)
then
// act on $foo and $foundThese
I know that rule is NOT correct, but I'm not sure how I'm supposed to access an immutable object inside a collection. The examples in the documentation show how to get at mutable class objects.
Thanks!
-Allen
17 years, 11 months
[Drools 4.0.7] JBRMS package dependencies and RuleAgent
by Jones, Alan R
Hi,
When compiling and deploying a package in JBRMS, it uses a bunch of jar
files in the JBRMS model. I have an axis2 web service that calls
RuleAgent in order to create a rulebase->working memory from this jbrms
package. However, though I do have all the classes that were in the
JBRMS model loaded in the lib of my web service, exceptions are thrown
during creation of the rulebase about those classes not being found.
Why is it not enough for the RuleAgent to have these classes loaded by
the web service? The only way to get this to work is to put the jars
used by jbrms model into the Axis2/lib, which is not right. I would like
RuleAgent to be able to use the jars loaded when the web service is
loaded from the service's (archive) /lib directory.
Suggestions?
Thanks,
aj
17 years, 11 months
Re: [rules-users] Using from
by Aziz Boxwala
Marcus,
Thank you very much. I am trying that out.
--Aziz
----- Original Message ----
From: Marcus Ilgner <marcus.ilgner(a)gmail.com>
To: Rules Users List <rules-users(a)lists.jboss.org>
Sent: Thursday, July 17, 2008 2:35:55 PM
Subject: Re: [rules-users] Using from
Hi Aziz,
On Thu, Jul 17, 2008 at 8:26 PM, Aziz Boxwala <boxwala(a)yahoo.com> wrote:
> I have the following class structure.
>
> Class GrandFather {
> List<Father> fathers;
> public List<Father> getFathers() {return fathers;}
> }
>
> Class Father {
> int age;
> List<Son> sons;
> public int getAge() {return age;}
> public List<Son> getSons() {return sons;}
> }
>
> Class Son {
> int age;
> public int getAge() {return age;}
> }
>
> I'd like to write a rule that finds all the Fathers who have age > 45 and
> have Sons where the son's age is greater than 5. But I can't figure out how
> to use "from" to iterate over father first and then over son.
>
> Any help will be greatly appreciated.
>
> Thanks,
> --Aziz
Something like this?
rule "FatherAndSon
when
$father : Father(age > 45)
$son : Son(age > 5) from $father.sons
then
// do something
end
Best regards
Marcus
_______________________________________________
rules-users mailing list
rules-users(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/rules-users
17 years, 11 months
Mvel compilation error
by John Squire
Hi All,
We are intermittently getting mvel compilation errors with the following:
Caused by: java.lang.IllegalArgumentException: object is not an instance of
declaring class
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
org.mvel.optimizers.impl.refl.MethodAccessor.getValue(MethodAccessor.java:61
)
... 148 more
The rules compile ok and the application will run normally (rules processing
successfully) for a few days then this error will occur. Tried to replicate
but once the application is restarted the last action before the failure is
repeated and always processes successfully.
Any help would be appreciated.
Regards
JS
17 years, 11 months
Using from
by Aziz Boxwala
I have the following class structure.
Class GrandFather {
List<Father> fathers;
public List<Father> getFathers() {return fathers;}
}
Class Father {
int age;
List<Son> sons;
public int getAge() {return age;}
public List<Son> getSons() {return sons;}
}
Class Son {
int age;
public int getAge() {return age;}
}
I'd like to write a rule that finds all the Fathers who have age > 45 and have Sons where the son's age is greater than 5. But I can't figure out how to use "from" to iterate over father first and then over son.
Any help will be greatly appreciated.
Thanks,
--Aziz
17 years, 11 months
Alternate approaches of using OR operator (to avoid sub-rule generation)
by Jaikiran Pai
We are using Drools-3.0.6. In one of our scenarios, we are trying to use the OR operator as follows:
rule Testing
when
person : (Person (interests contains "Golf") or Person (interests contains "Soccer") )
then
System.out.println("I am interested");
end
Based on one of my earlier posts in this forum (long time back), this rule will result in
"The OR CE will cause subrule generation, meaning the rule will fire twice if both conditions are true".
One of the ways, i was planning to change this is as follows:
rule Testing
when
person : Person()
then
if (person.getInterests().contains("Golf") || person.getInterests().contains("Soccer")) {
System.out.println("I am interested");
}
end
I don't think this is the best solution, though. Anyone has any better ways of implementing this? I know that Drools - 4 has a better support for this, but right now we don't have plans of migrating.
Thank you.
regards,
-Jaikiran
---------------------------------
Did you know? You can CHAT without downloading messenger. Click here
17 years, 11 months
Re: variable 'or' constraints with a DSL
by Matt Geis
Hi Reid,
>>The user has to be able to specify any of the attributes or any combination thereof and not necessarily in any order or all of them.
[snip]
>>I think answer is adding constraints with the dash syntax
No, dash syntax is not the answer. Clever construction of the DSL mapping will get you what you need.
Allow me to take your example and modify it.
[condition][File]file_name = fileName
[condition][File]dir_name = dirName
[condition][File]group_name = gName
[condition][File]user_name = uName
[condition][]file where {constraints}=$f: File(where {constraints})
[condition][]where {attr} matches {value}={attr} matches {value}
[condition][]and {attr} matches {value}=,{attr} matches {value}
[condition][]or {attr} matches {value}= || {attr} matches {value}
So if the user requests specifies jpg's owned by Bob, you can generate:
file where file_name matches "*.jpg" and user_name matches "Bob"
Which generates appropriate 'when' syntax in DRL:
$f : File(fileName matches "*.jpg", uName matches "bob")
A good way to get ORs with the dash syntax to get something like this:
file where file_name matches "*.jpg" or user_name matches "Bob"
which expands to
$f : File(fileName matches "*.jpg" || uName matches "bob")
Now, I mentioned that you *might* have to use the variable typing feature new to Drools 5.0, but you may not.
If you do, the attribute lines might look a bit like this...
[condition][File](?i:where)\s+{attr:[A-Za-z0-9]+}\s+matches\s+{value:".*?"}={attr} matches {value}
[condition][File](?i:and)\s+{attr:[A-Za-z0-9]+}\s+matches\s+{value:".*?"}=,{attr} matches {value}
[condition][File](?i:or)\s+{attr:[A-Za-z0-9]+}\s+matches\s+{value:".*?"}= || {attr} matches {value}
What you're seeing here is a few things.
The "?i" at the start of any literals makes it case-insensitive. This, of course, is up to you.
The \s+ instead of a space matches on one or more whitespace characters.
The pattern after the variable name contstrains the match rather tightly. I have found that you need this if you're trying to allow a user to enter an arbitrary number of constraints in whatever order they please.
Good luck!
Matt
17 years, 11 months