Declarative Agenda

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Declarative Agenda

Mark Proctor
I just got a first cut working for "declarative agenda". The idea here
is rules can control which rule can or cannot fire. Because this is
highly experimental it is off by default and users must explicitely
enable it, it will stay this way until we are happy with the solution.
My hope is that it will provide a more declarative approach to execution
control; which will enable more readable and maintainable rules compared
to using magic salience values and in some circumstances control objects..

         KnowledgeBaseConfiguration kconf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
         kconf.setOption( DeclarativeAgendaOption.ENABLED );
         KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(
kconf );

The basic idea is:
-All matched rule's Activations are inserted into WorkingMemory as
facts. So you can now match against an Activation the rules metadata and
declarations are available as -fields on the Activation object.
-You can use the kcontext.block( $a ) for the current rule to block the
selected activation. Only when that rule becomes false will the
activation be elegible for firing. If it is already elebible for firing
and is later blocked, it will be removed from the agenda until it is
unblocked.
-An activation may have multiple blockers, all blockers must became
false, so they are removed to enable the activation to fire
-kcontext.unblockAll( $a ) is an over-ride rule that will remove all
blockers regardless
-@activationListener('direct') allows a rule to fire as soon as it's
matched, this is to be used for rules that block/unblock activations, it
is not desirable for these rules to have side effects that impact else
where. The name may change later, this is actually part of the pluggable
terminal node handlers I made, which is an "internal" feature for the
moment.

I should be committing this later today, and will send a follow up email
once it hits HEAD, but here is a unit test. It uses a control role to
stop all rules with metadata declaring the rules to be in the "sales"
department. Only when that control rule becomes false can they fire.

package org.domain.test
import org.drools.runtime.rule.Activation
global java.util.List list
dialect 'mvel'

rule rule1 @department('sales')
when
      $s : String( this == 'go1' )
then
     list.add( kcontext.rule.name + ':' + $s );
end
rule rule2 @department('sales')
when
      $s : String( this == 'go1' )
then
     list.add( kcontext.rule.name + ':' + $s );
end
rule rule3 @department('sales')
when
      $s : String( this == 'go1' )
then
     list.add( kcontext.rule.name + ':' + $s );
end
rule blockerAllSalesRules @activationListener('direct')
when
      $s : String( this == 'go2' )
      $i : Activation( department == 'sales' )
then
     list.add( $i.rule.name + ':' + $s  );
     kcontext.block( $i );
end

KnowledgeBaseConfiguration kconf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kconf.setOption( DeclarativeAgendaOption.ENABLED );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kconf );
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
List list = new ArrayList();
ksession.setGlobal( "list", list);
ksession.insert(  "go1" );
FactHandle go2 = ksession.insert(  "go2" );
ksession.fireAllRules();
assertEquals( 3, list.size() ); // none of the rules 1-3 fire, as they
are blocked.
assertTrue( list.contains( "rule1:go2" ));
assertTrue( list.contains( "rule2:go2" ));
assertTrue( list.contains( "rule3:go2" ));

list.clear();

ksession.retract( go2 ); // the blocker rule is nolonger true, so rules
1-3 can now fire.
ksession.fireAllRules();

assertEquals( 3, list.size() );
assertTrue( list.contains( "rule1:go1" ));
assertTrue( list.contains( "rule2:go1" ));
assertTrue( list.contains( "rule3:go1" ));

ksession.dispose();








_______________________________________________
rules-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/rules-dev
Reply | Threaded
Open this post in threaded view
|

Re: Declarative Agenda

salaboy
Hi man, I didn't have the time to review the code of this feature but I'm really interested to understand how you are achieving this:
"
-All matched rule's Activations are inserted into WorkingMemory as
facts. 
"
How are you getting the newly created activation and inserting it inside the working memory? Are you wrapping the real Activation Object or creating a new representation of it?  I want to understand how you are managing the information and if you create a hook to do that to be able to copy the same mechanism and apply it for processes.

Cheers.



On Sun, Aug 7, 2011 at 6:29 AM, Mark Proctor <[hidden email]> wrote:
I just got a first cut working for "declarative agenda". The idea here
is rules can control which rule can or cannot fire. Because this is
highly experimental it is off by default and users must explicitely
enable it, it will stay this way until we are happy with the solution.
My hope is that it will provide a more declarative approach to execution
control; which will enable more readable and maintainable rules compared
to using magic salience values and in some circumstances control objects..

        KnowledgeBaseConfiguration kconf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
        kconf.setOption( DeclarativeAgendaOption.ENABLED );
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(
kconf );

The basic idea is:
-All matched rule's Activations are inserted into WorkingMemory as
facts. So you can now match against an Activation the rules metadata and
declarations are available as -fields on the Activation object.
-You can use the kcontext.block( $a ) for the current rule to block the
selected activation. Only when that rule becomes false will the
activation be elegible for firing. If it is already elebible for firing
and is later blocked, it will be removed from the agenda until it is
unblocked.
-An activation may have multiple blockers, all blockers must became
false, so they are removed to enable the activation to fire
-kcontext.unblockAll( $a ) is an over-ride rule that will remove all
blockers regardless
-@activationListener('direct') allows a rule to fire as soon as it's
matched, this is to be used for rules that block/unblock activations, it
is not desirable for these rules to have side effects that impact else
where. The name may change later, this is actually part of the pluggable
terminal node handlers I made, which is an "internal" feature for the
moment.

I should be committing this later today, and will send a follow up email
once it hits HEAD, but here is a unit test. It uses a control role to
stop all rules with metadata declaring the rules to be in the "sales"
department. Only when that control rule becomes false can they fire.

package org.domain.test
import org.drools.runtime.rule.Activation
global java.util.List list
dialect 'mvel'

rule rule1 @department('sales')
when
     $s : String( this == 'go1' )
then
    list.add( kcontext.rule.name + ':' + $s );
end
rule rule2 @department('sales')
when
     $s : String( this == 'go1' )
then
    list.add( kcontext.rule.name + ':' + $s );
end
rule rule3 @department('sales')
when
     $s : String( this == 'go1' )
then
    list.add( kcontext.rule.name + ':' + $s );
end
rule blockerAllSalesRules @activationListener('direct')
when
     $s : String( this == 'go2' )
     $i : Activation( department == 'sales' )
then
    list.add( $i.rule.name + ':' + $s  );
    kcontext.block( $i );
end

KnowledgeBaseConfiguration kconf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kconf.setOption( DeclarativeAgendaOption.ENABLED );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kconf );
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
List list = new ArrayList();
ksession.setGlobal( "list", list);
ksession.insert(  "go1" );
FactHandle go2 = ksession.insert(  "go2" );
ksession.fireAllRules();
assertEquals( 3, list.size() ); // none of the rules 1-3 fire, as they
are blocked.
assertTrue( list.contains( "rule1:go2" ));
assertTrue( list.contains( "rule2:go2" ));
assertTrue( list.contains( "rule3:go2" ));

list.clear();

ksession.retract( go2 ); // the blocker rule is nolonger true, so rules
1-3 can now fire.
ksession.fireAllRules();

assertEquals( 3, list.size() );
assertTrue( list.contains( "rule1:go1" ));
assertTrue( list.contains( "rule2:go1" ));
assertTrue( list.contains( "rule3:go1" ));

ksession.dispose();








_______________________________________________
rules-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/rules-dev



--
 - CTO @ http://www.plugtree.com 
 - MyJourney @ http://salaboy.wordpress.com
 - Co-Founder @ http://www.jbug.com.ar
 
 - Salatino "Salaboy" Mauricio -

_______________________________________________
rules-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/rules-dev
Reply | Threaded
Open this post in threaded view
|

Re: Declarative Agenda

Mark Proctor
The work is now committed and extensively unit tested here, which should how to use it. Notice the test at the end, so you can reason on the number of active and inactive activations:
https://github.com/droolsjbpm/drools/blob/master/drools-compiler/src/test/java/org/drools/integrationtests/DeclarativeAgendaTest.java

I'm just doing the N&N update and then we should be good to beta1

Mark
On 07/08/2011 23:15, Mauricio Salatino wrote:
Hi man, I didn't have the time to review the code of this feature but I'm really interested to understand how you are achieving this:
"
-All matched rule's Activations are inserted into WorkingMemory as
facts. 
"
How are you getting the newly created activation and inserting it inside the working memory? Are you wrapping the real Activation Object or creating a new representation of it?  I want to understand how you are managing the information and if you create a hook to do that to be able to copy the same mechanism and apply it for processes.

Cheers.



On Sun, Aug 7, 2011 at 6:29 AM, Mark Proctor <[hidden email]> wrote:
I just got a first cut working for "declarative agenda". The idea here
is rules can control which rule can or cannot fire. Because this is
highly experimental it is off by default and users must explicitely
enable it, it will stay this way until we are happy with the solution.
My hope is that it will provide a more declarative approach to execution
control; which will enable more readable and maintainable rules compared
to using magic salience values and in some circumstances control objects..

        KnowledgeBaseConfiguration kconf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
        kconf.setOption( DeclarativeAgendaOption.ENABLED );
        KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(
kconf );

The basic idea is:
-All matched rule's Activations are inserted into WorkingMemory as
facts. So you can now match against an Activation the rules metadata and
declarations are available as -fields on the Activation object.
-You can use the kcontext.block( $a ) for the current rule to block the
selected activation. Only when that rule becomes false will the
activation be elegible for firing. If it is already elebible for firing
and is later blocked, it will be removed from the agenda until it is
unblocked.
-An activation may have multiple blockers, all blockers must became
false, so they are removed to enable the activation to fire
-kcontext.unblockAll( $a ) is an over-ride rule that will remove all
blockers regardless
-@activationListener('direct') allows a rule to fire as soon as it's
matched, this is to be used for rules that block/unblock activations, it
is not desirable for these rules to have side effects that impact else
where. The name may change later, this is actually part of the pluggable
terminal node handlers I made, which is an "internal" feature for the
moment.

I should be committing this later today, and will send a follow up email
once it hits HEAD, but here is a unit test. It uses a control role to
stop all rules with metadata declaring the rules to be in the "sales"
department. Only when that control rule becomes false can they fire.

package org.domain.test
import org.drools.runtime.rule.Activation
global java.util.List list
dialect 'mvel'

rule rule1 @department('sales')
when
     $s : String( this == 'go1' )
then
    list.add( kcontext.rule.name + ':' + $s );
end
rule rule2 @department('sales')
when
     $s : String( this == 'go1' )
then
    list.add( kcontext.rule.name + ':' + $s );
end
rule rule3 @department('sales')
when
     $s : String( this == 'go1' )
then
    list.add( kcontext.rule.name + ':' + $s );
end
rule blockerAllSalesRules @activationListener('direct')
when
     $s : String( this == 'go2' )
     $i : Activation( department == 'sales' )
then
    list.add( $i.rule.name + ':' + $s  );
    kcontext.block( $i );
end

KnowledgeBaseConfiguration kconf =
KnowledgeBaseFactory.newKnowledgeBaseConfiguration();
kconf.setOption( DeclarativeAgendaOption.ENABLED );
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase( kconf );
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
List list = new ArrayList();
ksession.setGlobal( "list", list);
ksession.insert(  "go1" );
FactHandle go2 = ksession.insert(  "go2" );
ksession.fireAllRules();
assertEquals( 3, list.size() ); // none of the rules 1-3 fire, as they
are blocked.
assertTrue( list.contains( "rule1:go2" ));
assertTrue( list.contains( "rule2:go2" ));
assertTrue( list.contains( "rule3:go2" ));

list.clear();

ksession.retract( go2 ); // the blocker rule is nolonger true, so rules
1-3 can now fire.
ksession.fireAllRules();

assertEquals( 3, list.size() );
assertTrue( list.contains( "rule1:go1" ));
assertTrue( list.contains( "rule2:go1" ));
assertTrue( list.contains( "rule3:go1" ));

ksession.dispose();








_______________________________________________
rules-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/rules-dev



--
 - CTO @ http://www.plugtree.com 
 - MyJourney @ http://salaboy.wordpress.com
 - Co-Founder @ http://www.jbug.com.ar
 
 - Salatino "Salaboy" Mauricio -


_______________________________________________
rules-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/rules-dev


_______________________________________________
rules-dev mailing list
[hidden email]
https://lists.jboss.org/mailman/listinfo/rules-dev