Re: [rules-users] looking for more information on drools expert
Thank you very much for the precision, I didn't see that. I used 'matches' instead of '==', because using '==' for comparing Strings in java is very unsafe since it compares the references and not the content of the strings. I thought it was the same in drools and I thought 'matches' was the equivalent of the java '.equals' method. But now you mention that in drools '==' is correct, I will use it rather. Aldian 2009/7/16, Edson Tirelli : >Very good! :) > >Just FYI, in the case of accumulate, you could also use the collectList() > function to simplify your rule. This: > > $alarmList : LinkedList() > from accumulate ( ($e : Element(parentindex!=0) and > $a : Alarm( origin matches > $e.name&& probablecause==45)), > init( LinkedList alarmList = new > LinkedList();), > action( alarmList.add($a);), > reverse( alarmList.remove($a);), > result( alarmList ) ); >Is the same as: > > $alarmList : List() > from accumulate ( ($e : Element(parentindex!=0) and > $a : Alarm( origin matches > $e.name&& probablecause==45)), > collectList( $a ) ); > >Also, you can always implement your own functions for accumulate: > > http://blog.athico.com/2009/06/how-to-implement-accumulate-functions.html > >Finally, I see you are using "matches" operator to compare equal strings. > Not sure if that is what you want, because "==" has different semantics and > better performance than "matches" if what you really want is compare > equality. Remember that in regexps, some characters have special meaning, > for instance, "." is a wildcard for any character. Meaning: > > "abc" matches "a.c" -> true > "abc" == "a.c" -> false > >Cheers, >Edson > > > > 2009/7/16 Gab Aldian > >> After some more investigation, I managed also to make it work with >> collect: http://drools.pastebin.com/m14f0e329 >> >> I would rather not multiplicate rules, because we probably will have >> dozens for our system which is very big and can supervise around a >> thousand equipements in some cases >> >> Thank you very much for the advices >> >> Aldian >> ___ >> rules-users mailing list >> rules-users@lists.jboss.org >> http://lists.jboss.org/mailman/listinfo/rules-users >> > > > > -- > Edson Tirelli > JBoss Drools Core Development > JBoss by Red Hat @ www.jboss.com > ___ rules-users mailing list rules-users@lists.jboss.org http://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
Very good! :) Just FYI, in the case of accumulate, you could also use the collectList() function to simplify your rule. This: $alarmList : LinkedList() from accumulate ( ($e : Element(parentindex!=0) and $a : Alarm( origin matches $e.name&& probablecause==45)), init( LinkedList alarmList = new LinkedList();), action( alarmList.add($a);), reverse( alarmList.remove($a);), result( alarmList ) ); Is the same as: $alarmList : List() from accumulate ( ($e : Element(parentindex!=0) and $a : Alarm( origin matches $e.name&& probablecause==45)), collectList( $a ) ); Also, you can always implement your own functions for accumulate: http://blog.athico.com/2009/06/how-to-implement-accumulate-functions.html Finally, I see you are using "matches" operator to compare equal strings. Not sure if that is what you want, because "==" has different semantics and better performance than "matches" if what you really want is compare equality. Remember that in regexps, some characters have special meaning, for instance, "." is a wildcard for any character. Meaning: "abc" matches "a.c" -> true "abc" == "a.c" -> false Cheers, Edson 2009/7/16 Gab Aldian > After some more investigation, I managed also to make it work with > collect: http://drools.pastebin.com/m14f0e329 > > I would rather not multiplicate rules, because we probably will have > dozens for our system which is very big and can supervise around a > thousand equipements in some cases > > Thank you very much for the advices > > Aldian > ___ > rules-users mailing list > rules-users@lists.jboss.org > http://lists.jboss.org/mailman/listinfo/rules-users > -- Edson Tirelli JBoss Drools Core Development JBoss by Red Hat @ www.jboss.com ___ rules-users mailing list rules-users@lists.jboss.org http://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
After some more investigation, I managed also to make it work with collect: http://drools.pastebin.com/m14f0e329 I would rather not multiplicate rules, because we probably will have dozens for our system which is very big and can supervise around a thousand equipements in some cases Thank you very much for the advices Aldian ___ rules-users mailing list rules-users@lists.jboss.org http://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
accumulate is indeed complex; the simpler collect might be applicable as well in this case. rule all45_A when forall ( Equipment( parent == 0, $id : id ) Alarm( cause == 45, source == $id ) ) $alarms : ArrayList() from collect( Alarm( cause == 45, $source : source ) ) then for( Object o: $alarms ){ retract( o );// or anything else with (Alarm)o } insert( new SummaryAlarm( 45 ) ); end Another solution would be by using 2 rules: rule all45_B1 when forall ( Equipment( parent == 0, $id : id ) Alarm( cause == 45, source == $id ) ) then insert( new SummaryAlarm( 45 ) ); end rule all45_B2 when SummaryAlarm( $cause : cause ) $a : Alarm( cause == $cause, $source : source ) Equipment( parent == 0, id == $source) then retract( $a ); // or anything else with $a end -W On Thu, Jul 16, 2009 at 10:55 AM, Gab Aldian wrote: > I finally suceeded to get what I wanted using the keyword accumulate > which is really very poweful as said in the doc. Here is the rule: > http://drools.pastebin.com/m4f938e40 > > It is a little bit complex, but it perfectly works. The only > observation I have is that it seems drools compatible jdk is < 1.5, > since I tryed to declare my linkedlist this way: LinkedList(), > but got warnings about the unexpected '<'. One other thing, the > "implicit and" does not work in the accumulate, you have to put it > clearly. > > Now I have something giving me the list I need, all should be easy I > think. Do you have any observation on the way I did it? > > Cheers > > Aldian > ___ > rules-users mailing list > rules-users@lists.jboss.org > http://lists.jboss.org/mailman/listinfo/rules-users > ___ rules-users mailing list rules-users@lists.jboss.org http://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
I finally suceeded to get what I wanted using the keyword accumulate which is really very poweful as said in the doc. Here is the rule: http://drools.pastebin.com/m4f938e40 It is a little bit complex, but it perfectly works. The only observation I have is that it seems drools compatible jdk is < 1.5, since I tryed to declare my linkedlist this way: LinkedList(), but got warnings about the unexpected '<'. One other thing, the "implicit and" does not work in the accumulate, you have to put it clearly. Now I have something giving me the list I need, all should be easy I think. Do you have any observation on the way I did it? Cheers Aldian ___ rules-users mailing list rules-users@lists.jboss.org http://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
2009/7/15, Wolfgang Laun : > 2009/7/15 Edson Tirelli : >> >>Aldian, >> >>Yes, this is the way to go: >> >> rule "detect and set routers different from root for alarm 45" >> When >>* All routers which index is different from 0 are raising the alarm 45 >>* There is an alarm $a of numero 45 raised by an equipement $e >> different from the root >> Then >>* execute some specific code on ($a,$e) >> end >> >>It would be like this: >> >> when >> forall( $e1 : Equipment( index != 0 ) >> Alarm( origin == $e1.name, probablecause == 45 ) ) >> $e2 : Equipment( index != 0 ) >> $a2 : Alarm( origin == $e2.name, probablecause == 45 ) >> then >> // do something with $e2 and $a2 >> end >> > > What happens if the RHS contains a retract( $a2 ), which (I think) is > one of the things Aldian intends to do? > > Also, there is the requirement of inserting a summary alarm > replacing all the 45ers on non-root equipments. You may not > want to do this on the RHS, unless you rely on the engine > discarding fact duplicates. > Thank you for your answers. I am currently examining how to use the accumulate keyword. As for the alarms that have been correlated in only one, I don't know how they are dealt with commonly, but here are the problems we have seen: 1) In the hypothesis where a same single alarm could be correlated with different pairs to create correlated alarms in different cases, it would be careless to retract it after having been correlated one time, because it would block all further correlation 2) In the hypothesis where a correlated alarm sum of a lot of single one has been created and where an event is raised to tell that one of these alarms has fallen: Two possibilities: Introducing the notion of "correlated alarm partially cleared" or removing the correlated alarm and reintroducing its remaining components. If the correlation has been well done, it doesn't make sense to use the first possibility, because once the condition are no longer validated, there is no reason to display the correlated alarm any further. Here is the way we will deal with this: Currently there are two list of alarms in main class: a) the list of alarms that has been inserted to drools (including single and correlated ones) but not cleared yet b) the list of alarms that should be displayed to the operator. So basically, when we decide that a group of alarms should be correlated in only one, we remove them from the list (b) and we add to (a) and (b) a correlated one that contains all the group. When an event rise to signal that one alarm is no longer raised, all correlated alarms it is part of are destroyed and removed from both lists and all their components except the fallen one are re-added to list b. The mechanisms allowing this are based on the alarm keys that are unique and on some mappings. So as you see there is a distinction between what is in drools, and what is visible by the operator. All non cleared alarms (single and correlated) are permanently in drools until it is destroyed because it has been cleared. The only inconvenient is then to avoid the rules to fire indefinitely, since they are permanently susceptible to be validated. To avoid this all rules are of type "If some alarms respect the folowing conditions and at least one of them is not part of a correlated alarm built for this rule, then...". There are probably smarter ways to do, but this is my point of view for the moment. Cheers Aldian ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
Well, I was going to suggest how to do it, but I guess it is a nice exercise for the avid users. :) Submit your suggestions to the list people. Lets see what you come up with. It can be implemented as a single rule or as multiple rules. I will send my own suggestion to the list for critics tomorrow. Rule spec: "When there is an alarm with probable cause 45 for each and every one of the monitored equipments in the network, except the equipment whose index is 0 (zero, i.e. non root equiment), discard all the corresponding alarms and replace them by a single, consolidated alarm." For simplicity, people can use pseudo code in the RHS if they prefer. The LHS of the rule (or rules) is what matters the most for us. The above spec has still some ambiguities, so feel free to interpret them as you like or suggest modifications. Any takers? ;) Cheers, Edson 2009/7/15 Wolfgang Laun > 2009/7/15 Edson Tirelli : > > > >Aldian, > > > >Yes, this is the way to go: > > > > rule "detect and set routers different from root for alarm 45" > > When > >* All routers which index is different from 0 are raising the alarm 45 > >* There is an alarm $a of numero 45 raised by an equipement $e > > different from the root > > Then > >* execute some specific code on ($a,$e) > > end > > > >It would be like this: > > > > when > > forall( $e1 : Equipment( index != 0 ) > > Alarm( origin == $e1.name, probablecause == 45 ) ) > > $e2 : Equipment( index != 0 ) > > $a2 : Alarm( origin == $e2.name, probablecause == 45 ) > > then > > // do something with $e2 and $a2 > > end > > > > What happens if the RHS contains a retract( $a2 ), which (I think) is > one of the things Aldian intends to do? > > Also, there is the requirement of inserting a summary alarm > replacing all the 45ers on non-root equipments. You may not > want to do this on the RHS, unless you rely on the engine > discarding fact duplicates. > > -W > > ___ > rules-users mailing list > rules-users@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/rules-users > -- Edson Tirelli JBoss Drools Core Development JBoss by Red Hat @ www.jboss.com ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
2009/7/15 Edson Tirelli : > > Aldian, > > Yes, this is the way to go: > > rule "detect and set routers different from root for alarm 45" > When > * All routers which index is different from 0 are raising the alarm 45 > * There is an alarm $a of numero 45 raised by an equipement $e > different from the root > Then > * execute some specific code on ($a,$e) > end > > It would be like this: > > when > forall( $e1 : Equipment( index != 0 ) > Alarm( origin == $e1.name, probablecause == 45 ) ) > $e2 : Equipment( index != 0 ) > $a2 : Alarm( origin == $e2.name, probablecause == 45 ) > then > // do something with $e2 and $a2 > end > What happens if the RHS contains a retract( $a2 ), which (I think) is one of the things Aldian intends to do? Also, there is the requirement of inserting a summary alarm replacing all the 45ers on non-root equipments. You may not want to do this on the RHS, unless you rely on the engine discarding fact duplicates. -W ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
Re: [rules-users] looking for more information on drools expert
Aldian, Yes, this is the way to go: rule "detect and set routers different from root for alarm 45" When * All routers which index is different from 0 are raising the alarm 45 * There is an alarm $a of numero 45 raised by an equipement $e different from the root Then * execute some specific code on ($a,$e) end It would be like this: when forall( $e1 : Equipment( index != 0 ) Alarm( origin == $e1.name, probablecause == 45 ) ) $e2 : Equipment( index != 0 ) $a2 : Alarm( origin == $e.name, probablecause == 45 ) then // do something with $e2 and $a2 end The beauty of Rete is that although you are writing constraints like "index != 0" and "probablecause == 45" twice in the rule, the engine will optimize and share them, effectively executing them only once for each fact. Performance will be very good. Just be careful with what you do in the consequence, because if for instance you remove $a2, the forall in the rule will immediately become false, and all subsequent activations will be canceled. The above is the preferred way of dealing with multiple facts of the same type, with the rule firing once for each pair ($e2, $a2), but If you want to gather a set of them all at once, you can use accumulate and collect CEs. Check the manual. Regarding the system clock, the problem is that the clock is not a fact inside the engine, but you are using it to do your reasoning. Meaning it is changing, but the engine does not know that. In Drools 5 we implement temporal reasoning and the concept of session clock. This makes your reasoning process safe, correct and also allows reproducibility and auditability. []s Edson 2009/7/15 Gab Aldian > 2009/7/10, Edson Tirelli : > >Hi Aldian, > > > >I think you misunderstood the semantics of forall(). Forall in Drools > is > > the same forall quantifier from the First Order Logic. > > > > http://en.wikipedia.org/wiki/First-order_logic > > > >So, if you want to write a rule that says: "When for all equipments of > > type 'router' there is an alarm, then raise a general failure alarm". > > > > when > > forall( $e : Equipment( type == "router" ) > > Alarm( source == $e ) ) > > then > > // raise a general failure alarm > > end > > > > So, if you have 10 routers in the working memory and only 9 of them > have > > associated alarms, this rule will NOT fire, because the condition is not > > matched. But, if an alarm is raised for the 10th router, then all of them > > have an associated alarm and the rule will fire. > > > > So, as you can see, "forall" is a quantifier CE, in the same way that > > "not" and "exists" are quantifiers. They operate on multiple facts at > once, > > and as so, you can not use the variables bound inside their scope outside > of > > it. In the above example, if you tried to use $e in the consequence, > which > > of the 10 routers would it be bound to? So, since it makes no sense, the > > engine disallow the usage of variables bound inside quantifiers outside > of > > them. > > Hello, and Thank you very much for the answer. But your explanation > shows that my understanding of this keyword was correct. And what if I > want to ewecute this condition/consequence: > > When > * All routers which index is different from 0 are raising the alarm 45 > then > * Execute some specific code on all these routers > end > > As you can see If I attribute a $e to the routers from the condition, > it makes sense hoping to retrieve a reference on these routers to > execute code on them. I think I will escape this problem doing it with > two rules: > > rule "all routers but the root raise 45" > When > * All routers which index is different from 0 are raising the alarm 45 > then > * write somewhere that rule "all routers but the root raise 45" > has been validated > end > > rule "set routers about the alarm 45" > When >* there is written somewhere that "all routers but the root raise > 45" has been validated >* $a : Alarm is raising 45 from an equipement $e different from root > then >* execute some specific code on $a and $e > end > > There is also the possibility to do it in only one rule, but I have > some doubts about time optimization: > > rule "detect and set routers different from root for alarm 45" > When >* All routers which index is different from 0 are raising the alarm 45 >* There is an alarm $a of numero 45 raised by an equipement $e > different from the root > Then >* execute some specific code on ($a,$e) > end > > this way, drools will proceed to two verifications: > * if forall routers which index is different from 0, they have raised > an alarm of numero 45 > * if any alarm $a originated from a routers $e different from the > root, is of numero 45 and then execute some code on it. > > > > > > Just to be easier to remember I call quantifier CEs "scope > delimiters". > > The general rule is: variables bound insid
Re: [rules-users] looking for more information on drools expert
2009/7/10, Edson Tirelli : >Hi Aldian, > >I think you misunderstood the semantics of forall(). Forall in Drools is > the same forall quantifier from the First Order Logic. > > http://en.wikipedia.org/wiki/First-order_logic > >So, if you want to write a rule that says: "When for all equipments of > type 'router' there is an alarm, then raise a general failure alarm". > > when > forall( $e : Equipment( type == "router" ) > Alarm( source == $e ) ) > then > // raise a general failure alarm > end > > So, if you have 10 routers in the working memory and only 9 of them have > associated alarms, this rule will NOT fire, because the condition is not > matched. But, if an alarm is raised for the 10th router, then all of them > have an associated alarm and the rule will fire. > > So, as you can see, "forall" is a quantifier CE, in the same way that > "not" and "exists" are quantifiers. They operate on multiple facts at once, > and as so, you can not use the variables bound inside their scope outside of > it. In the above example, if you tried to use $e in the consequence, which > of the 10 routers would it be bound to? So, since it makes no sense, the > engine disallow the usage of variables bound inside quantifiers outside of > them. Hello, and Thank you very much for the answer. But your explanation shows that my understanding of this keyword was correct. And what if I want to ewecute this condition/consequence: When * All routers which index is different from 0 are raising the alarm 45 then * Execute some specific code on all these routers end As you can see If I attribute a $e to the routers from the condition, it makes sense hoping to retrieve a reference on these routers to execute code on them. I think I will escape this problem doing it with two rules: rule "all routers but the root raise 45" When * All routers which index is different from 0 are raising the alarm 45 then * write somewhere that rule "all routers but the root raise 45" has been validated end rule "set routers about the alarm 45" When * there is written somewhere that "all routers but the root raise 45" has been validated * $a : Alarm is raising 45 from an equipement $e different from root then * execute some specific code on $a and $e end There is also the possibility to do it in only one rule, but I have some doubts about time optimization: rule "detect and set routers different from root for alarm 45" When * All routers which index is different from 0 are raising the alarm 45 * There is an alarm $a of numero 45 raised by an equipement $e different from the root Then * execute some specific code on ($a,$e) end this way, drools will proceed to two verifications: * if forall routers which index is different from 0, they have raised an alarm of numero 45 * if any alarm $a originated from a routers $e different from the root, is of numero 45 and then execute some code on it. > > Just to be easier to remember I call quantifier CEs "scope delimiters". > The general rule is: variables bound inside a scope delimiter are never > available outside of them. > > I don't understand what you are trying to do in your first rule in your > example. If you write your rule in plain English, the people from the list > can help you write it correctly.* I am sorry, English is not my mother language, but I hope you will understand a lot. I will know give further explanations on my example: I am supervising a network of equipements. They are not all routers, and actually, they are very different from each others, but you can consider them as routers, it doesn't matter. There is a central equipement, the root, which centralized all the alarms sent by the other equipements. And there is a software that supervise that root equipment and that folow me the alarms. I am trying to make correlation on some basic cases as this one: * for all equipements but the root I have the alarm "impossible to connect". It is a very common alarm, because we often work with virtual equipements, so we know that when we have that alarm on every equipement but the root, there is no worry to have. But we would like to suppress all that alarms that are all the same to only one that agregate all the others. So what we wish to do is the folowing: when * For all equipement different from the root an alarm of type 45 as been raised, then * Suppress all these alarms and create an alarm that agregate all these alarms in only one end As you can see the ideal would be that the forall allow to attribute to a $tabarray variable an Array of type Alarm [] containing all the alarms meeting the requirement. > > Finally, just for completeness, be careful with the semantics of time. > Your Alarm class is using the system clock to define timeout, and that will > give you all kinds of headaches, not to mention wrong/unexpected results. I suppose you say this because of the risk of unsy
Re: [rules-users] looking for more information on drools expert
Hi Aldian, I think you misunderstood the semantics of forall(). Forall in Drools is the same forall quantifier from the First Order Logic. http://en.wikipedia.org/wiki/First-order_logic So, if you want to write a rule that says: "When for all equipments of type 'router' there is an alarm, then raise a general failure alarm". when forall( $e : Equipment( type == "router" ) Alarm( source == $e ) ) then // raise a general failure alarm end So, if you have 10 routers in the working memory and only 9 of them have associated alarms, this rule will NOT fire, because the condition is not matched. But, if an alarm is raised for the 10th router, then all of them have an associated alarm and the rule will fire. So, as you can see, "forall" is a quantifier CE, in the same way that "not" and "exists" are quantifiers. They operate on multiple facts at once, and as so, you can not use the variables bound inside their scope outside of it. In the above example, if you tried to use $e in the consequence, which of the 10 routers would it be bound to? So, since it makes no sense, the engine disallow the usage of variables bound inside quantifiers outside of them. Just to be easier to remember I call quantifier CEs "scope delimiters". The general rule is: variables bound inside a scope delimiter are never available outside of them. I don't understand what you are trying to do in your first rule in your example. If you write your rule in plain English, the people from the list can help you write it correctly. Finally, just for completeness, be careful with the semantics of time. Your Alarm class is using the system clock to define timeout, and that will give you all kinds of headaches, not to mention wrong/unexpected results. But this e-mail is already too long. I suggest you take a look at the Drools Fusion docs on temporal reasoning. []s Edson 2009/7/10 Gab Aldian > Hi everybody > > I have read with attention the drools expert documentation, which was > very interesting, but a little 'too simple". For example, most > examples don't present rules with the keyword "forall". I also met big > difficulties mixing the references on the objects to my javacode. This > is why I would need some more documentation with examples that go > deeper into drools capacities. > > > To give you clues about my plan, here is an example (which works > perfectly in drools 5) that I have developed: > java code - http://drools.pastebin.com/m1a705614 > rule code - http://drools.pastebin.com/m3f30cbdc > > As you can see I am studying the case where drools is used for the > monitoring of a network of equipments that send alarms about their > problems. But I have big difficulties, because I would like to get > references on the objects of the "forall", and to execute javacode > such as $toto.method($titi, $tata), but such things seems impossible > (systematic failed of compilation) > > Could you please help me? > > Thank you very much! > > Aldian > ___ > rules-users mailing list > rules-users@lists.jboss.org > https://lists.jboss.org/mailman/listinfo/rules-users > -- Edson Tirelli JBoss Drools Core Development JBoss by Red Hat @ www.jboss.com ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users
[rules-users] looking for more information on drools expert
Hi everybody I have read with attention the drools expert documentation, which was very interesting, but a little 'too simple". For example, most examples don't present rules with the keyword "forall". I also met big difficulties mixing the references on the objects to my javacode. This is why I would need some more documentation with examples that go deeper into drools capacities. To give you clues about my plan, here is an example (which works perfectly in drools 5) that I have developed: java code - http://drools.pastebin.com/m1a705614 rule code - http://drools.pastebin.com/m3f30cbdc As you can see I am studying the case where drools is used for the monitoring of a network of equipments that send alarms about their problems. But I have big difficulties, because I would like to get references on the objects of the "forall", and to execute javacode such as $toto.method($titi, $tata), but such things seems impossible (systematic failed of compilation) Could you please help me? Thank you very much! Aldian ___ rules-users mailing list rules-users@lists.jboss.org https://lists.jboss.org/mailman/listinfo/rules-users