Fork me on GitHub
#clara
<
2020-06-22
>
mbragg13:06:53

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.

ethanc13:06:18

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}})

ethanc13:06:37

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

ethanc13:06:54

cc. @nfedyashev

nfedyashev13:06:55

@mbragg @ethanc Perfect! Thank you so much