Fork me on GitHub
#clara
<
2022-06-30
>
Ben Sless12:06:44

Building on my previous question, let's say I'm accumulating facts over time in my session, where these facts are will be grouped by an id I then want to write a rule that will operate on each group. Do I need to do something like:

(def gb (acc/grouping-by :id))

(defrecord Event [id timestamp ,,,])

(defrecord Group [id data])

(defrule update-aggregateion
  [Event (= ?id id)
   ?acc <- gb :from [Event]
   ?group <- Group (= ?id id)]
  =>
  (retract! ?group)
  (insert! (->Group ?id (get ?acc ?id))))

Ben Sless12:06:18

I need to keep track of each accumulated group separately and apply further rules per group

Ben Sless13:06:18

bit more details about what I'm trying to do because maybe I'm just way off - I want to track some status change events according to a bunch of rules, accumulate them by id for a period, and after that period has elapsed do some side effect with the all the accumulated events and remove them from the session

ethanc14:06:50

retractions always get tricky… you can very easily get into logical loops, so in general i recommend avoiding them. rather than retracting them, would it be possible to instead only collect the “latest” grouping. If we are talking time-based groupings/events, i would imagine that you could assume that there would be a linear progression in events and that the ids could be numerically incremented.

Ben Sless17:06:42

Already managed to trap myself in one 😆 Problem is the IDs are user ids coming from outside the system, I want a windowed aggregation per user

Ben Sless17:06:07

It's a bit wasteful but I figured I can have a rule which inserts a Group on the first time and another rule which matches on the group and the event, retracts the previous group and updates the current But it's ugly

ethanc20:06:13

i guess, looking at this again… i’m a little confused as to why this isn’t handled by the truth maintenance inherit to Clara. I would think that this would likely be as simple as something like:

(cr/defrule grouped-events
  [?acc <- gb :from [Event]]
  =>
  (doseq [[id events] ?acc]
    (r/insert! (->Group id events))))
any new events in the session would re-evaluate that accumulator. Doing an implicit retraction of the prior grouping.

Ben Sless04:07:55

Ah, that's just me not understanding how truth maintenance works, then. Cool, simpler than expected