Fork me on GitHub

Do any changes proposed in affect short circuiting the evaluation of all LHS conditions? My understanding is that if the first condition doesn’t match the remaining ones are still processed


@alex-dixon right now the alpha network is “eagerly” evaluated


So constraints within conditions that are independent of a join with another condition


Clara has had this sort of “re-ordering” property since way back (maybe always) now. The discusses we have had before about trying to be “lazier” in evaluation by not evaluating any part of a condition if the prior conditions were satisfied, would be affected by this re-ordering logic


Thanks. Printed out ch 2 of the paper you recommended. It’s awesome. Working my way through. Will try to avoid asking you to explain rete to me in the interim:blush: That said: If Clara’s reordering doesn’t honor the order of conditions in the lhs as they are written (even if just for alphas) would any of the changes in @wparker ‘s proposal make it so the developer’s ordering is honored when evaluating a lhs? My understanding is that’s part of the proposal, but only for Boolean conditions. If that’s right and it’s developed, could the behavior be extended to apply to all conditions using much of the same code? Outside Boolean conditions, would this be a massive breaking change? I think so just want to confirm. I’m asking because I think there would be an appreciable performance difference between the two for CEP. I think Drools made changes along these lines for that reason


@alex-dixon I think the re-ordering (or not) is still being discussed in the 373 linked above. There already is re-ordering happening. It sounds like there may be some lean towards not needing to do that anymore. You should check out some of the comments in that issue now. I did mention the lazier evaluation thing there, but there are still concerns I’d have with that overall.


And yes, that paper is good. I first heard of it from Ryan putting a reference to it in the Clara GitHub repo @


If I were to call insert! from within an async callback for an effect triggered on the rhs of a rule, I assume that the context would be goofy and result in an exception or other undesirable behavior. Is there a best practice for capturing that context? The use case would be leveraging truth maintenance for facts inserted async, e.g. results from an http request.


@dave.dixon I’d expect the async response to be do an external insert when it is done


You’d “capture context” just via the variable bindings you passed to the async call


Oh, woops, missed part of your purpose


I think you’d have to model the fact that you caused the effect externally as a fact for TMS to help you. Example:


I don’t really like the maybe-undo-async-thing part of that. It doesn’t know which DownstreamResult may now be invalid and offloads it all to the external fn ext-maybe-undo-async-thing


I think there may be a better way around that


I made it so original-rule is always satisfied via the accumulator


So you can carry that information forward on which path you should take


Yes, that's how I'm doing it now. Like you say, it's fine when all the relationships are clean, but otherwise gets messy.


Referring to the first example.


So in my 2nd example, you can actually filter DownstreamResult if you track which bs they originally were associated with via that information being conveyed externally and back on the inserted new facts


It isn’t perfect, you still have to make an association on the facts, however, I think it could be practical


This is regarding one part of the overall problem


You also have the problem of when the async request is finished, ensuring it inserts to the session that it came from in its final state


so after the fire-rules that triggered the async request has completed


In a single-thread, I think that is not an issue


And you may be doing this single-threadedly


The async call though would need to have a way to access the session when it is finished


I have a way of handling session. But what I really want is to be able to do the final insert such that the fact is a logical consequence of the rule lhs. Not sure if that actually is meaningful given how rete works.


I’m not sure whether using Clara’s truth maintenance directly allows that, but you should be able to simulate it using unconditional inserts/retracts, other rules, and facts that represent the async event cycle. A poor attempt:

(defrule make-request-when
  [?task <- AsyncTask]
  (retract! ?task)
  (insert-unconditional (->AsyncRequest ?task))
 (async-side-effect! my-session ?task)

(defn async-side-effect! [session fact] (request! fact (fn [err res] 
(if err (insert session (->AsyncTaskError err fact)
(insert session (->AsyncTaskSuccess res fact))

(defrule on-async-task-success
  [?success <- AsyncTaskSuccess ?res ?fact]
  [?request <- AsyncTaskRequest ?fact]
(retract! ?success ?request)
(insert-unconditional! (->SomeFactRepresentingResponseFromThisKindOfRequest ?res)
  ;; similarly with error


I have something similar, and it works nicely. But it would be nice if I could avoid the manual truth maintenance.


I don’t think anything built-in would allow you to reliable have an actual “handle” on the mutable session state during fire rules for an insert! to go off later yet, still correctly be tracked with TMS


there’d be quite a bit of complications for the engine to try to support that even I think


Not to mention the fire-rules wouldn’t be able to be “done” until all async actions were done


and it’d have concurrency issues in a multi-threaded environment


Agreed. Maybe the right(ish) answer is to model facts as something like a promise. The semantics and behavior would have to be constrained, so it isn't just mutating facts behind your back without properly updating the session. But the basic concept seems like a way forward, because conditionally inserting a promise as a fact means it and whatever value it returns will get retracted when TMS requires it.


The thing I'm trying to avoid is having to manually perform truth management for facts inserted as the result of async effects. In the big picture, those facts are logical consequents of whatever condition triggered the async effect.


Yeah,I think the case is interesting