I must say I am always surprised by the creativity of the users on how to
model and solve some use cases. :) Very refreshing to hear!
Let me comment first on the way you are heading and after that how I
(Edson) would model the same problem.
What you are doing is, what I would call, a clever way of integrating the
rules engine with your application user interface by using the event
listeners frameworks. This is kind of the same thing Kris developed for
ruleflow groups transition control, if I'm not mistaken, but the difference
is that his code being internal, allows him to use some internal APIs to
overcome the walls you also hit. Using only the public APIs may not be
feasible and using internal APIs may cause undesiring coupling problems for
you when drools is upgraded.
My main worry recommending you to continue in the direction you are
heading is that you will face additional problems in the future. Just to
mention one example, in 5.0 I am implementing support for multi-thread rules
evaluation and network partitioning, and as part of this job, I'm removing
access to unsafe calls to the agenda that were kind-of available in 4.0
(they were not published as public APIs, but the methods were public).
So, how I would model your solution? Spliting "detection rules" from
"action rules" and using logical asserts to make the link between then. I
see other possible benefits of that approach, like multiple action options
for the same problem or a single action for multiple problems, etc. Let me
explain using an example. Pretend you have 2 rules for detecting overheat
and overpressure respectivelly:
rule "Detection rule: overheat"
Sensor( temperature > 50 )
insertLogical( new Alarm( Type.OVERHEAT, "some info here") );
rule "Detection rule: overpressure"
Sensor( pressure > 4 )
insertLogical( new Alarm( Type.OVERPRESSURE, "some info here") );
rule "Action rule: open valve"
exists( Alarm( type == Type.OVERHEAT || == Type.OVERPRESSURE ) )
// inform possible solution: open valve
rule "Action rule: increase refrigeration power"
exists( Alarm( type == Type.OVERHEAT ) )
// inform possible solution: increase refrigeration power
So, you see that the actions and detections being used as separate rules
allow you to sugest the same solution for multiple problems or just for
single problems. Also, you are free to fire your rules all the time, because
what informs you about the current status of the system are the Alarm facts
that are logically inserted into the working memory.
I don't know if you are familiar with the "logical insert" feature, but
if you have an overheat alarm and your temperature goes bellow the
threashold (50 in my example), it will detect the change and will
automatically retract the alarm fact as it is no longer true that you have
You may continue using listeners to update your user interface, by
monitoring the Alarm fact assertions instead of the agenda events, or you
can also use queries to get the alarms from working memory.
Let us know what you think and if you want to write a use case blog, like
we had the other day for a Naval Engineering use case, you are more than
2008/9/23 Fermion <henss(a)physik.uni-wuppertal.de>
I'm doing an expert system for a highly complex high energy physics
(CERN->ATLAS->Pixel Detector->Detector Control System).
In principle the detector is a complex machine with a rather hierarchical
The idea is to use a Drools based expert system to inform the operator of
the Detector about what to do in case of a problem. The system itself is
controlled by something that we call a "Finite State Machine" which is
reducing the complex operation of the detector to a number of simple
As the Finite State Machine does not suggest, what to do, if something goes
wrong, the expert system should do that.
In order to do so, the expert system shall display "solution advices" to
Detector operator. As there can be many unrelated problems at the same
we use a tree-structure to show, where in the Detector the problem
If a rule gets activated by a fact (in my case a process parameter of the
detector, e.g. a temperature), the corresponding node in the tree is being
highlighted by a dedicated icon. Once the facts change and the activation
cancelled, we remove the highlighting icon, so that the tree only shows the
current activations (we don't need logging here, as this is done
This works absolutely fine for us, BUT:
We can't FIRE the activations, as this would immediately remove them from
the agenda, which in turn would remove them from our tree => no operator
would see them.
At first I thought, that NOT-FIRING those activations wouldn't hurt, as we
just wrote the "solution" on the RHS of the rule and parsed this RHS by
ourselves. This way, we displayed the solution belonging to a given
activation as long as it was still on the agenda.
You can see, that the main problem of this is that one CANNOT do things
PrintSolution("Reason for problem is a over-temperature of: " + $temp +
on Module: " + $moduleName);
In our case we could still parse the code, but would be unable to access
local variables $temp and $moduleName (example) without actually firing the
Firing the rule on the other hand would cancel it's activation, rendering
our display tree useless.
I think the thing that would be most usefull for us would be a way to fire
rule "silently", without notifying the agenda about it (so that the
activation would NOT be removed).
I'm not sure whether I was able to explain the problem sufficiently, but
maybe someone has an idea how to handle the situation.
Thanks very much!
View this message in context:
Sent from the drools - user mailing list archive at Nabble.com
rules-users mailing list
JBoss Drools Core Development
JBoss, a division of Red Hat @ www.jboss.com