Details
-
Feature Request
-
Resolution: Unresolved
-
Major
-
None
-
5.4.0.Beta2
-
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.