Best way to have a rule only fire once despite a number of facts that would cause it to fire

4,364 views
Skip to first unread message

David W

unread,
Dec 29, 2014, 6:48:32 PM12/29/14
to drools...@googlegroups.com

If i have a rule which says "if attribute > X then do something" and I'm getting a stream of values for that attribute, what is the best way to have this rule only fire the first time the condition is met?
If I have a second rule which says "if attribute < Y then do something else", how do I get it to fire once and allow the previous rule to fire.
Is activation groups the right way? Is there a better way?

I'm using a stateful cloud session. Is it better to use a stream session?

This email is intended solely for the recipients named above and may contain information that is confidential, privileged or legally protected.  If you receive this communication in error, please immediately notify the sender by return e-mail and delete all copies of the original email and attachments.

Mark Proctor

unread,
Dec 29, 2014, 7:03:52 PM12/29/14
to drools...@googlegroups.com
does “exists” conditional element work for you?

Mark
--
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/drools-usage/a60fa980-6a86-42ef-9fde-1958dc5922d6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

David W

unread,
Dec 29, 2014, 7:54:46 PM12/29/14
to drools...@googlegroups.com
Possibly. I hacked a fire-once rule using String (If not String(this=="X")) then insert ("X")) which works fine for case 1 below, but not for the second case (where the two separate rules kind of work together). 
I'm examining the stock-broker example from the jpbm integration to see how that works. 
I think I'm going to use the CPE part of Drools to make my stuff work.

David W

unread,
Dec 29, 2014, 8:15:50 PM12/29/14
to drools...@googlegroups.com
Just for clarification's sake, how does the lock-on-active and rules-group work together? I thought that if I have lock-on-active for the "value > X" case, then when the value goes greater than X, the rule will be locked and a subsequent setting of the value greater than X will not trigger the rule? If so, does the lock clear when the value is set to less than X? Or am I misunderstanding lock-on-active?

Davide Sottara

unread,
Jan 3, 2015, 9:07:44 AM1/3/15
to drools...@googlegroups.com
A few of clarifications on the use case:
You have two rules, att > X and att < Y: Should each rule fire up to one time, independently?
If you have multiple facts that possibly get updated, do you want the rule to fire just once, or once for each fact?
Also, do you ever retract facts? If so, do you ever want the rule(s) to refire when you re-insert them?

Lock-on-active is scoped by a rule-group and will prevent rules from re-firing as long as the
group is focused. It does not depend on new facts, or updates to the existing ones, but
only on the agenda focus. If you do not manipulate groups, this may be an option.

Exists works for all facts, but can be cleared if you retract/modify objects, so it may refire later.

Control facts are not my first choice, but work, especially if they have some concrete meaning in the domain.
With a control fact, you effectively block the rule forever after the first activation.

Also see this ever-green blog post from Esteban which shows other options
http://ilesteban.wordpress.com/2012/11/16/about-drools-and-infinite-execution-loops/

Hope this hepls
Davide



David W

unread,
Jan 5, 2015, 2:14:33 PM1/5/15
to drools...@googlegroups.com
In a streaming context (timestamped data coming in)


On Saturday, January 3, 2015 6:07:44 AM UTC-8, Davide Sottara wrote:
A few of clarifications on the use case:
You have two rules, att > X and att < Y: Should each rule fire up to one time, independently?

 Not quite. Let's say I'm looking at temperature and reporting the temperature every hour. As temperature rises during the day, the (att > Y) should be fired, once, when the temperature rises above the Y value. As long as temperature is above Y, no more rules should fire. As the temperature falls during the night, the rule (att < X) should fire, once, when the temperature drops below X. However, the next day, the temperature will rise again and cause rule (att > Y) to fire, once, again, similarly as the temperature cycles, day after day.


If you have multiple facts that possibly get updated, do you want the rule to fire just once, or once for each fact?
Once for each fact.
 
Also, do you ever retract facts? If so, do you ever want the rule(s) to refire when you re-insert them?
No facts are retracted - but I am updating them with the new data as it comes in. 

Lock-on-active is scoped by a rule-group and will prevent rules from re-firing as long as the
group is focused. It does not depend on new facts, or updates to the existing ones, but
only on the agenda focus. If you do not manipulate groups, this may be an option.

I'm just assuming that all the rules are in the "MAIN" agenda group
 
Exists works for all facts, but can be cleared if you retract/modify objects, so it may refire later.

I don't want to use the control facts approach as keeping track of them will become increasingly difficult as the number of rules increase.
 
Control facts are not my first choice, but work, especially if they have some concrete meaning in the domain.
With a control fact, you effectively block the rule forever after the first activation.

Also see this ever-green blog post from Esteban which shows other options
http://ilesteban.wordpress.com/2012/11/16/about-drools-and-infinite-execution-loops/


This blog is pretty useful - I wasnt aware of propertychange and its fine-grained approach. I'm mimicking its behavior by overriding equals and hashcode in my main fact object class (one object class, many instances).

Hope this hepls
Davide

Somewhat... still not quite getting the behavior I'm looking for.

David W

unread,
Jan 5, 2015, 6:28:08 PM1/5/15
to drools...@googlegroups.com
KieSession.insert() vs KieSession.update()

Looks like if I use insert, then the rule fires once. If I use update, the rule fires every time.
This is with the KieBase using the "Equality" behavior and my object defining "equals" and "hashcode".

So insert() will overwrite any object found to be 'equals', but not trigger an Activation() Event?

My object is a JSON-style object which has some primary attributes (which I'm testing for equality) and some secondary attributes (which are not part of the equality test). I'm update() ing an object if the attributes are different from those already in the session, otherwise I'll insert() it.
This is giving me the behavior I want.

David.

Wolfgang Laun

unread,
Jan 7, 2015, 1:14:17 PM1/7/15
to drools...@googlegroups.com
David, I suspect that you are looking for events that represent the transgression of a threshold in a sequence of, say, sensor values.

If that is so, there's two kinds of facts to keep apart: those that represents an update of the sensor reading, and the fact that represents the state of the monitored thing(s). This means that you rule should not fire on some value being greate than X - instead it should fire when the object changes its state.

Thus:

rule monitorHigh
when
    Reading( $value: value )
    $t: Thing( state != State.HIGH, $value < upperLimit )
then
    modify( $t ){ setState( State.HIGH ) }
end

-W

David Weir

unread,
Jan 8, 2015, 11:55:14 AM1/8/15
to drools...@googlegroups.com
Hi Wolfgang, (and Mark and Davide),
Thanks for the tip.
My basic use case is that the first occurrence of any event should trigger any rules pertinent to that event and subsequent ones will not, unless they happen to change the state that those rules are monitoring.
I'm a little troubled by the 'state variable' approach as it requires a rule to explicitly set the state *and a second rule to unset it*
This means that every rule/criterion that I want to monitor has to have a second rule. This is less than optimal.

Can you explain to me how lock-on-active is supposed to work? Can you show me a simple rule file which will do the following, in response to a set of temperature values received as a stream?
When the temp falls below 0, print "Temp Fell below freezing"
When the temp rises above 25, print "Its nice outside"

The temperature stream contains the followiing temps: {7, 6, 2, -1, -3, 0, 8, 15, 20, 28, 29, 27}
the printout should be:
Temp Fell below freezing
Its nice outside

And that's it.

David.

#JeSuisCharlie

--
You received this message because you are subscribed to a topic in the Google Groups "Drools Usage" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/drools-usage/BGCJ-NgaALM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to drools-usage...@googlegroups.com.

To post to this group, send email to drools...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Wolfgang Laun

unread,
Jan 8, 2015, 2:21:48 PM1/8/15
to drools...@googlegroups.com
Hi David

if you're using events you might use time-based reasoning:

when
    $t1: Reading( $value: value <= threshold )
    $t2: Reading( this after $t1, $value: value > threshold )
    not Reading( this after $t1 && before $t2 )
then
   // getting hot

-W


David Weir

unread,
Jan 9, 2015, 1:47:25 PM1/9/15
to drools...@googlegroups.com
This might work, but I don’t know the threshold duration.
Can you explain why “lock-on-active” isn’t the right approach for this problem?

I thought that this would work:

rule “too hot”
lock-on-active true
agenda-group “HOT"
when $m: Message(value > HIGH)
then System.out.println(“too hot”);
end

rule “too cold”
lock-on-active true
agenda-group “COLD"
when $m: Message(value > LOW)
then System.out.println(“too hot”);
end

and I use “kieSession.insert(Message);” from my program.

Is there a good way to fully debug what’s going on inside KieSession using Eclipse? I’ve set up the DebugAgendaEventListener and DebugRuleRuntimeEventListener. What else can I use?

Thanks for your help.

-- 
David Weir



For more options, visit https://groups.google.com/d/optout.

Mark Proctor

unread,
Jan 9, 2015, 1:50:42 PM1/9/15
to drools...@googlegroups.com
have you tried the audit log? There is a visualiser for that too.

If you want to go really deep, there is now a trace output.


Mark
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.

To post to this group, send email to drools...@googlegroups.com.

David Weir

unread,
Jan 9, 2015, 2:11:07 PM1/9/15
to drools...@googlegroups.com
Tried the audit log - seems to be a visualization of the output of the debuggers. (unless I missed a configuration).
I’ll try the trace output.

Thanks.

But what about this lock-on-active flag? 

-- 
David Weir



For more options, visit https://groups.google.com/d/optout.

Wolfgang Laun

unread,
Jan 9, 2015, 2:26:18 PM1/9/15
to drools...@googlegroups.com
Regarding lock-on-active in an agenda-group "HOT", you'll first have to decide what to do to give focus to this agenda-group. auto-focus is one way, probably the only way. Second, you'll need a way to remove this agenda-group from the stack. When will you do that? Using another group for "NORMAL", with auto-focus and lock-on-active is not a good answer, as it will let the stack grow. Then, same thing for "COLD"...

I'm not saying it can't be done, but I dislike the emerging tangle of rule attributes. I'm simple minded, and logic I can understand, mostly :-)

Cheers
Wolfgang

David Weir

unread,
Jan 9, 2015, 2:36:59 PM1/9/15
to drools...@googlegroups.com
You mention “remove this agenda-group from the stack”.
Is there a way do do this using the Kie API or does it have to be done in the drl? If so, how does one do this? (is it a side effect of using the setFocus() command when you set the focus to something else?)

It looks like there isn’t a simple way to avoid the ‘tangle of attributes” - either they’re state attributes or rule attributes… :-)

-- 
David Weir


For more options, visit https://groups.google.com/d/optout.

Mark Proctor

unread,
Jan 9, 2015, 2:46:15 PM1/9/15
to drools...@googlegroups.com
As this is all fairly meta, it may be easier to use an AgendaFilter and collect the meta data via Agenda listeners.

You can use the AgendaFilter to block a rule firing, and you can use the listeners to collect what facts and rules have fired together. you can also use the agenda filter to know when a rule instance has changed, to reset the agenda filter for that combination.

It’s not very declarative, but should work.

One small note do not insert/update/delete inside of the listeners themselves.

Mark



You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.

To post to this group, send email to drools...@googlegroups.com.

Wolfgang Laun

unread,
Jan 9, 2015, 3:09:24 PM1/9/15
to drools...@googlegroups.com
An agenda-group is popped from the stack as soon as all activations have been fired.

If you have only one "HOT" rule in its group, it'll pop immediately, and then you are presumably back in the group where an event with high temperature will fire "HOT" again.

-W


David Weir

unread,
Jan 9, 2015, 3:25:32 PM1/9/15
to drools...@googlegroups.com
Given that it is a “Meta” problem then I think Mark’s suggestion is a good one to follow.
Thanks for the clarification about the “lock-on-active” & Agenda Groups, but I’m still a little confused:
  Given that the fact is in the working memory (and is not retracted), why does the “Hot” rule pop immediately? Is it a consequence of it being an Event? (using @role(event) )? Or just the normal behavior?

If I use “insertLogical” instead of “insert” will that make a difference?

Thanks for your help and apologies for my continued confusion!

-- 
David Weir


For more options, visit https://groups.google.com/d/optout.

Wolfgang Laun

unread,
Jan 10, 2015, 2:30:29 AM1/10/15
to drools...@googlegroups.com
Insert logical of what? It makes only sense with facts resulting as the consequence of a certain fact combination.

The "HOT" rule would fire, and if it is the only one in its group it will remove the agenda-group from the focus stack immediately. If it is not the only one: which other rules are in there? I can't discuss this without knowing the full picture.

Cheers
Wolfgang


David Weir

unread,
Jan 12, 2015, 7:32:07 PM1/12/15
to drools...@googlegroups.com
Thanks Wolfgang,
I was thinking of the insertLogical being used for the state or guard object - it only exists as long as the given state is true (e.g. temp > 25).
Didn’t realize that if you only have one rule in a rule group, it is removed from the focus stack immediately. (does that mean *after* the rule has fired, or as soon as the event is received?)

This is the drl file I’m using:

rule “Hot”
lock-on-active true
agenda-group “TempHigh”
when
$m: Message(temperature>25)
then
        System.out.println(“Its nice outside”);
        drools.setFocus(“TempHigh”);
end

rule “Cold”
lock-on-active true
agenda-group “TempLow”
when
$m: Message(temperature<5)
then
        System.out.println(“Its cold outside”);
        drools.setFocus(“TempLow”);
end

But when I run it, with the temperature set  {7, 6, 23, -1, -3, 0, 8, 15, 20, 4 29, 27} I want   the following printout:
Its cold outside
Its cold outside
Its nice outside

I’m using a loop like:
  for (Int temp: temps) {
      kieSession.insert(new Message(temp));
     kieSession.fireAllRules();
}

I was thinking that the when message would have a not exists(High) (or Low, respectively) and the “then” part would have an insertLogical(High), so that the logical part would control the existence of the High or Low object.

My alternative view is to look at the StockBroker model and use the incoming events to change the status of some meta object, which is what the high or low rules actually check against…

If you have a pointer to which would be more efficient, that’d be great.

Mark,
I’d rather not put the logic outside the drl file as I’m hoping to do some high-speed event streaming and I want the drl engine to handle all the logic.

Thanks for your continued help,
David

-- 
David Weir

On Friday, January 9, 2015 at 11:30 PM, Wolfgang Laun wrote:

acts resulting as the consequence o

Wolfgang Laun

unread,
Jan 13, 2015, 4:28:32 AM1/13/15
to drools...@googlegroups.com
Hi David,

it' difficult to compare the efficiency of this way or that way without a benchmark. But I think that

when
      $m: Message(temperature<5)
      not Low()
then
      insertLogical( Temp.LOW );
end

and a similar one for high temperature would be just as efficient as modifying a property of a single state fact. Note two things: (a) "not X()" is the negative existence and (b) I propose the insertion of static facts so the objects don't have to recreated and GC-ed.

Running a test with fireUntilHalt in one thread and inserting (with appropriate delays) from another thread should give you an idea how much your system can handle.

-W



--
You received this message because you are subscribed to a topic in the Google Groups "Drools Usage" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/drools-usage/BGCJ-NgaALM/unsubscribe.
To unsubscribe from this group and all its topics, send an email to drools-usage...@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.

David Weir

unread,
Jan 13, 2015, 2:12:43 PM1/13/15
to drools...@googlegroups.com
Hi Wolfgang,
In your example, is not Low() a different fact to “Temp,LOW” ? If so, does Low() ever get instantiated?

-- 
David Weir

For more options, visit https://groups.google.com/d/optout.

Wolfgang Laun

unread,
Jan 13, 2015, 4:54:10 PM1/13/15
to drools...@googlegroups.com
Sorry for being so terse and/or sloppy.

Any pair of objects that represent "cold" or "warm"  will do; I was thinking of subclasses to Temp: Low extends Temp, High extends Temp. It's not necessary to create them for each insertLogical, just keep them reachable, e.g. as public static finals in some class.

-W


   

David Weir

unread,
Jan 13, 2015, 5:32:22 PM1/13/15
to drools...@googlegroups.com
Thanks for response. In my version, this isn’t working.
Immediately after the rule fires (AfterActivationFiredEvent) I see an “ObjectDeletedEvent” which is deleting the logical fact i just inserted (logical). Since I’m not deleting any facts I’m very puzzled by this…

Can we take this offline for deeper discussion?

-- 
David Weir

For more options, visit https://groups.google.com/d/optout.

David Weir

unread,
Jan 13, 2015, 7:05:14 PM1/13/15
to drools...@googlegroups.com
Just upgraded to 6.2.0.CR4 and getting the same behavior.
Puzzlement

-- 
David Weir

Mark Proctor

unread,
Jan 13, 2015, 7:16:59 PM1/13/15
to drools...@googlegroups.com
Take a look at the logic of what you wrote:
when
      $m: Message(temperature<5)
      not Low()
then
      insertLogical( Temp.LOW );
end

Now think about the definition of a logical object. It will exist while the support (the LHS when) remains true. When that is no longer true, it will delete the object.

Now look at the definition of ‘not’. It is true when an object does NOT exist. But what is the consequence doing, it’s making the object exist. So it breaks it’s own support.

What’s needed is to separate the LHS into a logical support bit and non-logical support bit - but we don’t have that capability yet. We hope to add this on the next release, this is something that Jess and Clips already do - via the logical conditional element.

Mark


You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.

To post to this group, send email to drools...@googlegroups.com.

Mark Proctor

unread,
Jan 13, 2015, 7:24:52 PM1/13/15
to drools...@googlegroups.com
Btw logical objects, if equals/hashcode are implemented correctly, can only ever have one instance existing for a given equality. So the ‘not’ is redundant - as long as you implemented hashcode/equals correctly.

Mark

David Weir

unread,
Jan 13, 2015, 7:26:50 PM1/13/15
to drools...@googlegroups.com
So obviously right, I’m embarrassed.

Thought I might try "exists (Message(temperature>25))” to do the fire once. Would that work?

-- 
David Weir

For more options, visit https://groups.google.com/d/optout.

Mark Proctor

unread,
Jan 13, 2015, 7:27:54 PM1/13/15
to drools...@googlegroups.com
On 14 Jan 2015, at 00:26, David Weir <d...@millanetworks.com> wrote:

So obviously right, I’m embarrassed.

Thought I might try "exists (Message(temperature>25))” to do the fire once. Would that work?
See my other email, if you implemented hashcode/equals correctly there will only ever be once instance in the WM - all other equal objects will not filtered out.

Mark Proctor

unread,
Jan 13, 2015, 7:29:38 PM1/13/15
to drools...@googlegroups.com
On 14 Jan 2015, at 00:27, Mark Proctor <mdpr...@gmail.com> wrote:


On 14 Jan 2015, at 00:26, David Weir <d...@millanetworks.com> wrote:

So obviously right, I’m embarrassed.

Thought I might try "exists (Message(temperature>25))” to do the fire once. Would that work?
See my other email, if you implemented hashcode/equals correctly there will only ever be once instance in the WM - all other equal objects will not filtered out.
Although your idea should work too (i think) - it’s slightly more optimized, but less readable.

My recommendation is to try these things, write a unit test to check you are getting the behaviour you want. It’s a lot simpler and less abstract.

Mark

David Weir

unread,
Jan 13, 2015, 7:32:59 PM1/13/15
to drools...@googlegroups.com
Yes, unit test is good idea. I have a very small rules file (2 rules) and a simple kiesession with the debug listeners. All I have in my rule is the parameter check in the “when" clause and a System.out.println() in the “then” clause.
I’m also looking at the contents of the working memory using KieSession.getObjects().

-- 
David Weir

For more options, visit https://groups.google.com/d/optout.

David Weir

unread,
Jan 13, 2015, 7:56:43 PM1/13/15
to drools...@googlegroups.com
nope, doesn’t work… because the ‘exists’ clause is already true in order for the the rule to become true…
I’m back to the when not Object() && condition then insert Object() version, but I also have to have the contra case (when !condition) to retract the Object().
However, we have decided that the “fire once” case is a rare occurrence, so I might be able to live with this extra complexity.

-- 
David Weir

For more options, visit https://groups.google.com/d/optout.

David Weir

unread,
Jan 13, 2015, 8:15:05 PM1/13/15
to drools...@googlegroups.com
Solved: Have to use a “guard” object and second rule to retract the guard when condition is false.

Eg:

rule “Hot”
when
$m: Message(temp>20)
        not Status(temp>20)
then
        System.out.println(“its hot”);
        insert (new Status(temp=$m.temp));
end

rule “Not Hot”
when
$m: Message(temp<=20)
        $s: Status(temp>20)
then
retract($s);
System.out.println(“It’s not hot”);
end


-- 
David Weir

David Weir

unread,
Mar 4, 2015, 5:57:53 PM3/4/15
to drools...@googlegroups.com, d...@millanetworks.com
Revisiting this topic. I recently came across an item (from thread https://groups.google.com/forum/#!searchin/drools-usage/facts$20for$20rules/drools-usage/SuCUjefgu-A/PzRJ7ethUz8J)  about kcontext.blockMatch in one of the Unit tests.
Is there more information about blockMatch? Is this an alternative to guard objects? I'm hoping that I can use it to set a state and automatically unset the state when the triggering conditions expire.

I tried to understand the example in 6.2.3 Declarative Agenda, but I'm missing something - maybe the sequence of inserts that demonstrate the behavior?


On Monday, December 29, 2014 at 3:48:32 PM UTC-8, David W wrote:

If i have a rule which says "if attribute > X then do something" and I'm getting a stream of values for that attribute, what is the best way to have this rule only fire the first time the condition is met?
If I have a second rule which says "if attribute < Y then do something else", how do I get it to fire once and allow the previous rule to fire.
Is activation groups the right way? Is there a better way?

I'm using a stateful cloud session. Is it better to use a stream session?

Mark Proctor

unread,
Mar 4, 2015, 6:05:04 PM3/4/15
to drools...@googlegroups.com, d...@millanetworks.com
There is only what we wrote in the documentation on Declarative Agenda - it’s still an experimental item. I’m not entirely happy with it, but it has potential. The core of the issue is loss of type safety - we need to code generate Rule literals, which provide typed access to variables.

Here are a set of unit tests:

And there is some stuff in the manual too. Some of the things in those examples are deprecated - as we’ve evolved better solutions, for example "@activationListener('direct’). is gone.

My recommendation is to use 6.2 and where you nee to @Propagation(Eager). The reason for this is you can’t block something that hasn’t yet bee produced - so the lazy propagation can potential be confusing.

The mechanism is pretty simple. When a rule Matches it first is inserted into the working memory, where it can potential be blocked, before it fires. If nothing block it, it fires. The blocking is “undone” automatically, when the blocking rule is unmatched.

Mark

-- 
You received this message because you are subscribed to the Google Groups "Drools Usage" group.
To unsubscribe from this group and stop receiving emails from it, send an email to drools-usage...@googlegroups.com.
To post to this group, send email to drools...@googlegroups.com.

David Weir

unread,
Mar 4, 2015, 6:14:12 PM3/4/15
to Mark Proctor, drools...@googlegroups.com
Thanks Mark,
Looks like i have to a) install drools 6.2 (using 6.1 presently) b) Run through that integration test to see exactly what it’s doing.

We’re using Drools as a complex state machine - I don’t think it’s the most ideal usage. When I look at the way the examples work, most of it is about having 1 triggering condition and then deriving, through rule chaining, a result. What we’re doing is manually creating the conditions to go from one state to the next, using drools to figure out which one of the optional states to go to next. I’m wondering if we should be using the rule-flow setup with drl & rf with ‘manual’ tasks (which are our inputs) instead. 
Can you comment?

David.

Michael Anstis

unread,
Mar 4, 2015, 6:35:19 PM3/4/15
to drools...@googlegroups.com

Perhaps it's my numpty thinking, but are you keeping state in working memory which causes the rule propogation or just using the rules to determine a change in state? If you held state externally is it just a matter of using a new session and inserting current state to determine the transition?

Sent on the move

Mark Proctor

unread,
Mar 4, 2015, 6:36:46 PM3/4/15
to David Weir, drools...@googlegroups.com
Tbh I’m forgetting the historical content of this thread.

But did I mention to look at defeasible logic? This is a better way of doing blocking.

You need your rules to do logical insertions, and then one rule can block the data propagation of another rule.

Look the bird’s fly example.


Mark

Davide Sottara

unread,
Mar 4, 2015, 6:45:20 PM3/4/15
to drools...@googlegroups.com, David Weir
If it is a state machine I would argue to use an explicit representation of the state.
That is, if your "do something" implies a change in state and then take some action before|during|after entering the state,
I would keep a state object, modify it and write the logic conditionally.

Rules are by definition stateless, so assuming an implicit state and relying on the engine to figure it out does not seem
the most robust way to tackle it

e.g. declare State @propertyReactive state: String end

rule TransitionAB
when
Event( ... )
State( state == "A" )
then
  modify ( $s ) { setState( "B" ); }
end

rule OnEntryInB
when 
State( state == "B" )
then
...
end

Not sure this is applicable to your use case, but you are generally asking for "constraint refraction", that is,
a constraint requiring to be violated before it can be satisfied again after the last time it was satisfied.

This is a nice feature we have not implemented yet. We have @propertyReactivity, which is a weaker form.


Reply all
Reply to author
Forward
0 new messages