Re: [rules-users] looking for more information on drools expert

2009-07-16 Thread Gab Aldian
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: LinkedListAlarm(),
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-07-16 Thread Wolfgang Laun
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 Aldianaldian...@gmail.com 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: LinkedListAlarm(),
 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

2009-07-16 Thread 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


Re: [rules-users] looking for more information on drools expert

2009-07-16 Thread 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 aldian...@gmail.com

 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

2009-07-15 Thread Gab Aldian
2009/7/10, Edson Tirelli tire...@post.com:
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 unsynchronized clocks on
the network? But for now I 

Re: [rules-users] looking for more information on drools expert

2009-07-15 Thread 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 == $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 aldian...@gmail.com

 2009/7/10, Edson Tirelli tire...@post.com:
 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 

Re: [rules-users] looking for more information on drools expert

2009-07-15 Thread Wolfgang Laun
2009/7/15 Edson Tirelli tire...@post.com:

    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

2009-07-15 Thread Edson Tirelli
 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 wolfgang.l...@gmail.com

 2009/7/15 Edson Tirelli tire...@post.com:
 
 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-07-15 Thread Gab Aldian
2009/7/15, Wolfgang Laun wolfgang.l...@gmail.com:
 2009/7/15 Edson Tirelli tire...@post.com:

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

2009-07-10 Thread 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.

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 aldian...@gmail.com

 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