[rules-users] Fire rule only upon change of particular event (or fact)

Davide Sottara dsotty at gmail.com
Sat May 25 15:18:41 EDT 2013


Drools is reactive by default, what you propose would require to change
the engine's semantics completely - at least for those rules which use
"upon".

In fact, the dual approach - DISABLING reactivity - has been discussed and
has been on the TODO list for a while:

when
SomeEvent()
?SomeFact()
then
...

Notice the ? in front of SomeFact: this would achieve your desired result.

To this date, the closest supported workaround involves the use of queries:

query someFact()    
    SomeFact()
end

when
    SomeEvent()
    ?someFact()
then ... end
 
In this case, only SomeEvent can trigger activations with preexisting
SomeFact instances.


But you are right, there are other languages which use the syntax
on ... when/if ... then ... end
and do not exhibit a reactive behaviour unless the optional "on" part is
specified.
I'd wait for others to add their 2 cents to the discussion.

Davide


On 05/26/2013 04:27 AM, Jörg Henne wrote:
> Hi all,
>
> after using drools for some time now, I have repeatedly stumbled upon
> situations where it would have been useful to be able to tell Drools to fire
> a rule only upon the insertion of a particular event, but not other
> events/facts on which the rule depends. It might be that I am hopelessly
> mis-guided, but I would like to float an idea and see what you think.
>
> To illustrate what I am talking about, please consider the following rules:
> ------------------------------------------------------------------------------------------------------------
> package test
>
> declare SomeEvent
>     @role(event)
>     name: String
> end
> declare SomeFact
>     @role(fact)
>     name: String
> end
>
> rule "Trigger on some event when there is some fact"
>     when
>         e: SomeEvent()
>         f: SomeFact()
>     then
>         System.out.println("=> Got Event '" + e.getName() + "' and Fact '" +
> f.getName() + "'");
> end
> rule "Discard 'used' events"
>     salience -99999
>     when
>         e: SomeEvent()
>     then
>         retract(e);
> end
> ------------------------------------------------------------------------------------------------------------
>
> Now we insert facts and events, for example like this
>
> ------------------------------------------------------------------------------------------------------------
> rule "Insert fact"
>     when
>     then
>         System.out.println("Inserting initial Fact");
>         insert(new SomeFact("initial fact"));
> end
>
> rule "Insert an event"
>         timer(int: 5s)
>     when
>     then
>         System.out.println("Inserting initial Event");
>         insert(new SomeEvent("initial event"));
> end
>
> rule "Insert yet another fact"
>         timer(int: 10s)
>     when
>     then
>         System.out.println("Inserting yet another fact");
>         insert(new SomeFact("yet another"));
> end
>
> rule "Insert yet another event"
>         timer(int: 10s)
>     when
>     then
>         System.out.println("Inserting yet another event");
>         insert(new SomeEvent("yet another"));
> end
> ------------------------------------------------------------------------------------------------------------
>
> The result of running those rules is, of course:
>
> ------------------------------------------------------------------------------------------------------------
> Inserting initial Fact
> Inserting initial Event
> => Got Event 'initial event' and Fact 'initial fact'
> Inserting yet another fact
> => Got Event 'initial event' and Fact 'yet another'
> Inserting yet another event
> => Got Event 'yet another' and Fact 'yet another'
> => Got Event 'yet another' and Fact 'initial fact'
> ------------------------------------------------------------------------------------------------------------
>
> Please note the output does not match the name of the rule "Trigger on some
> event when there is some fact". In fact, this rule fires irrespective of
> whether an event is inserted or a fact. But what I really want is, that it
> just fires upon the 'arrival' of events. A possible syntax extension whould
> be something along the lines of:
>
> ------------------------------------------------------------------------------------------------------------
> rule "Trigger on some event when there is some fact"
>     when
>         upon(e: SomeEvent())
>         f: SomeFact()
>     then
>         System.out.println("=> Got Event '" + e.getName() + "' and Fact '" +
> f.getName() + "'");
> end
> ------------------------------------------------------------------------------------------------------------
>
> The expected output of that would be:
>
> ------------------------------------------------------------------------------------------------------------
> Inserting initial Fact
> Inserting initial Event
> => Got Event 'initial event' and Fact 'initial fact'
> Inserting yet another fact
> Inserting yet another event
> => Got Event 'yet another' and Fact 'yet another'
> => Got Event 'yet another' and Fact 'initial fact'
> ------------------------------------------------------------------------------------------------------------
>
> There are work-arounds that let me achieve the desired behaviour, for
> example this one:
>
> ------------------------------------------------------------------------------------------------------------
> rule "Focus on 'process SomeEvent'"
>     agenda-group "process SomeEvent"
>     auto-focus
>     when
>         e: SomeEvent()
>     then
>         // nothing to do but focus the agenda-group
> end
> rule "Trigger on some event when there is some fact"
>     agenda-group "process SomeEvent"
>     when
>         e: SomeEvent()
>         f: SomeFact()
>     then
>         System.out.println("=> Got Event '" + e.getName() + "' and Fact '" +
> f.getName() + "'");
> end
> ------------------------------------------------------------------------------------------------------------
>
> However, I think the hypothetical 'upon'-keyword would be a lot clearer. Is
> there any fundamental reason (e.g. rooted in the rete-algorithm or the way
> Drools implements it) that would preclude the implementation of 'upon'? And,
> more importantly, do you even agree with me that it would be a useful
> extension?
>
> Please note that while I always spoke of events in conjunction with 'upon' I
> don't see a reason why it should not behave this way with plain facts as
> well. Please not as well that the inverse of upon would also be conceivable:
> "don't fire this rule just because <some pattern> triggered", e.g. maybe
> simply "not(upon(Pattern()))".
>
> Thanks
> Joerg Henne
>
>
>
> --
> View this message in context: http://drools.46999.n3.nabble.com/Fire-rule-only-upon-change-of-particular-event-or-fact-tp4023972.html
> Sent from the Drools: User forum mailing list archive at Nabble.com.
> _______________________________________________
> rules-users mailing list
> rules-users at lists.jboss.org
> https://lists.jboss.org/mailman/listinfo/rules-users
>



More information about the rules-users mailing list