Uploaded image for project: 'JBRULES'
  1. JBRULES
  2. JBRULES-3428

accumulate/collect CEs should trigger against largest fact set possible

This issue belongs to an archived project. You can view it, but you can't modify it. Learn more

    XMLWordPrintable

Details

    • Feature Request
    • Resolution: Unresolved
    • Major
    • None
    • 5.4.0.Beta2
    • drools-compiler
    • None

    Description

      I'm interested in a way to ensure that a rule containing a collect or accumulate CE doesn't fire until no other rule inserting an accumulated/collected fact can fire. I've had a few conversations on IRC about this, where I was told that the only ways to accomplish this were through explicit ordering (i.e. salience, agenda groups, or ruleflow-groups), or through meta-objects. Obviously explicit ordering works, but it makes ongoing rule maintenance and reasoning more difficult. And meta-objects don't always work: you don't always know ahead of time how many of these accumulated/collected facts to expect, and you can't always use retraction + not exists() as a condition (suppose the retracted facts need to be used by multiple rules).

      My rules makes extensive use of collect and accumulate to aggregate sets of facts, and to work around this I've partitioned my rules into agenda-groups, and, within a rule file, used salience to guarantee ordering. Frankly, this explicit ordering is pretty tiresome.

      Here's a concrete example:

      rule "insert accumulated fact"
        when
          Foo()
        then
          insert(new Bar())
      end
      
      rule "do the accumulation"
        when
          accumulate(Bar(), $count : count())
        then
          insert(new Cow($count));
      end
      
      

      I shouldn't have to insert "salience -1" into the second rule to guarantee that I get a Cow() with the largest count possible. Now, you might say "well, retract the Foo() when you insert the Bar(), and then add not exists(Bar()) to the second rule". Suppose there's a third rule that also depends on Foo(); retracting Foo() would mean the second rule doesn't get to use it. Or you might say "if you insert all your Foo() objects a priori, insert a FooCount() along with them that the second rule can use to know how many Bar() objects should exist before firing". That does work when Foo() is inserted a priori, but it gets messy if it's inserted by another rule; how do you know how many to expect then?

      Ideally the second rule would know that it depends on facts from the first rule, and wouldn't fire until the first rule (and other rules that may trigger the first rule) can no longer fire. Less ideal would be an explicit dependency mechanism that I can insert into the second rule to control this myself.

      Attachments

        Activity

          People

            mproctor@redhat.com Mark Proctor
            hltbdivl_jira Adar Dembo (Inactive)
            Archiver:
            rhn-support-ceverson Clark Everson

            Dates

              Created:
              Updated:
              Archived:

              PagerDuty