This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-30
Channels
- # arachne (23)
- # bangalore-clj (2)
- # beginners (64)
- # boot (20)
- # cider (3)
- # clara (11)
- # cljs-dev (29)
- # cljsrn (10)
- # clojure (143)
- # clojure-brasil (4)
- # clojure-dev (22)
- # clojure-dusseldorf (3)
- # clojure-italy (26)
- # clojure-sanfrancisco (13)
- # clojure-seattle-old (2)
- # clojure-spec (15)
- # clojure-uk (27)
- # clojured (1)
- # clojurescript (52)
- # core-async (13)
- # cursive (2)
- # datomic (106)
- # fulcro (45)
- # garden (1)
- # graphql (11)
- # hoplon (98)
- # jobs (11)
- # juxt (7)
- # keechma (2)
- # leiningen (36)
- # off-topic (39)
- # parinfer (13)
- # re-frame (34)
- # reagent (5)
- # ring (1)
- # rum (4)
- # shadow-cljs (83)
- # sql (1)
- # timbre (1)
- # unrepl (49)
- # vim (1)
- # yada (42)
Hello, I have question about acc/all
behavior, the following snippet of code:
(ns rules-acc-all
(require [clara.rules :as rules]
[clara.rules.accumulators :as acc]
[clojure.pprint :refer [pprint]]))
(defrecord Customer [id])
(defrecord Reward [id])
(defrecord CustomerReward [id customer-id reward-id])
(rules/defrule quals
[Customer (= ?C id)]
[Reward (= ?R id) (= id "bonus-1")]
;;[?items <- (acc/all) :from [CustomerReward (= id ?I) (= ?C customer-id)]]
[?items <- (acc/all) :from [CustomerReward (= ?C customer-id)]]
=>
(pprint {"?items" ?items}))
(let [session (-> (rules/mk-session 'rules-acc-all)
(rules/insert (->Customer "customer-1")
(->Reward "bonus-1")
(->Reward "offer-1")
(->Reward "offer-2")
(->CustomerReward "cr-1" "customer-1" "offer-1")
(->CustomerReward "cr-2" "customer-1" "offer-2")))
fired (rules/fire-rules session)]
)
Prints
{"?items"
[{:id "cr-1", :customer-id "customer-1", :reward-id "offer-1"}
{:id "cr-2", :customer-id "customer-1", :reward-id "offer-2"}]}
However if condition [?items <- (acc/all) :from [CustomerReward (= ?C customer-id)]]
is replaced with [?items <- (acc/all) :from [CustomerReward (= id ?I) (= ?C customer-id)]]
(pretty much same with unification added for CustomerReward (= id ?I)
the the output would be:
{"?items"
[{:id "cr-1", :customer-id "customer-1", :reward-id "offer-1"}]}
{"?items"
[{:id "cr-2", :customer-id "customer-1", :reward-id "offer-2"}]}
I am trying to wrap my mind around this, but cannot - those two rules set look pretty much same to me
I believe it's because when you specify (= id ?I)
in the accumulator, clara will now make a unique binding for each unique value of id
, so the rule fires once for each id
of CustomerReward
rather than accumulating over all CustomerReward
's with different id
's.
Thanks @dave.dixon - that kind of explains it. I guess my confusion was due thinking that binding (= id ?I)
is kind of "local" to accumulator, in other words it works as sub-select in SQL, however it appears such binding makes ?I
"available" to "outer scope", i.e. I could refer it for unification in clauses which are siblings of accumulator.
Correct. Or you could refer to ?I
in the RHS of the rule, where it would have to be unique.