oracle-samples/clara-rules

Oddities of ordering of RHS retractions, unconditional insertions, and rule activations

Opened this issue · 0 comments

When facts are retracted in the RHS of a rule, they are immediately retracted from the rules network [1], skipping any batching behavior except for the batching behavior in a single rule activation discussed in #171. However, both logical insertions and unconditional insertions are added to the pending-updates [2]. This can introduce oddities of behavior where, for rules R1 and R2 in the same activation group, RHS retractions from an activation R1 can be visible to an activation of R2 without insertions from the same activation of R1 being visible to the activation of R2. [3] is a an example of such a test.

Because of batching behavior, it is also possible that for rules R1 and R2 in the same activation group, for both unconditional insertions and RHS retractions, each can activate without any visibility of the consequences of activating the other. I think we've already established that there is no guarantee of rule execution order when salience is not supplied, but a user might expect that if R1 activates first that when R2 activates it will have visibility to the changes from R1's activation, or vice versa if R2 activates first. This is not in fact the case, as can be seen in [4].

In general, I'd personally consider it best practice to avoid these sorts of scenarios by using truth maintenance except when performance requirements don't allow its overhead. I'd prefer to impose requirements to manage rule order via activation groups when these primitive operations are used rather than making changes that would slow down the preferred truth maintenance path. The issue of neither R1 and R2 seeing the activation of the other before activating seems like a fundamental property of interactions between batching behavior in the pending-updates and the existence of unconditional insertions. We have seen that batching behavior in the pending-updates dramatically improves performance, and I don't think making changes around an edge case of primitive operations would be worth the perf hit to our preferred path (using truth maintenance). I think the problem of making both the retractions and insertions from R1 visible to R2 at the same time could be solved by making [1] add the retractions done in the RHS to the pending-updates rather than immediately executing them. The insertions and retractions within a single activation are still reordered by the engine but I think the reasoning in [5] still applies. Also, subjectively, having part but not all of a rule activation be visible seems more surprising to me than either having it be totally visible or totally invisible.

I'd like to think about this a bit more, and am curious what thoughts others have on this. With that said, I tentatively propose the following principles/axioms regarding primitive operations (RHS retractions and unconditional insertions) and rule ordering:

  • A rule will either have visibility to all of the insertions and retractions from another rule activation or it will have visibility to none of them.
  • Clara makes no guarantees that any rule within an activation group will have access to the consequences of any other rule in an activation group before firing if the rule in question can fire without access to those consequences.
  1. https://github.com/rbrush/clara-rules/blob/0.13.0-RC2/src/main/clojure/clara/rules/engine.cljc#L200
  2. https://github.com/rbrush/clara-rules/blob/0.13.0-RC2/src/main/clojure/clara/rules/engine.cljc#L217
  3. https://gist.github.com/WilliamParker/d3dbe9059ebe6ba094afe97c74391f9f
  4. https://gist.github.com/WilliamParker/fae4b2f10034d504c95a7f4e3b11ef0f
  5. #171 (comment)