clara

http://www.clara-rules.org/
2020-06-22T13:05:53.154700Z

Have you seen http://www.clara-rules.org/docs/fact_type_customization/? This would allow you to match on the ancestor type and just have the single accumulator.

ethanc 2020-06-22T13:21:18.156400Z

Another option would be to leverage interfaces and allow the default ancestors function to handle it. Something like:

(ns test.interfaces
  (:require [clara.rules :as r]
            [clara.rules.accumulators :as acc]))

(definterface Summable
  (^long amount []))


(defrecord RecordOne [x]
  Summable
  (amount [_] x))

(defrecord RecordTwo [y]
  Summable
  (amount [_] y))


(defrecord Sum [z])


(r/defrule sum-rule
  [?s <- (acc/sum #(.amount ^Summable %)) :from [Summable]]
  =>
  (r/insert! (->Sum ?s)))

(r/defquery sum-query
  []
  [?s <- Sum])

(defn run-test
  []
  (-> (r/mk-session)
      (r/insert (->RecordOne 1)
                (->RecordOne 2)
                (->RecordTwo 3)
                (->RecordTwo 4))
      (r/fire-rules)
      (r/query sum-query)))

;; (run-test)
;; => ({:?s #test.interfaces.Sum{:z 10}})

ethanc 2020-06-22T13:22:37.157600Z

this assumes you own the definition of the records in the session. Otherwise, @mbragg solution would likely be easier

ethanc 2020-06-22T13:53:54.158Z

cc. @nfedyashev

nick 2020-06-22T13:56:55.158500Z

@mbragg @ethanc Perfect! Thank you so much