The rule works, but the query does not, how do I get the same thing to work from the defquery?
(r/defrule rules-fired
"Rule that gets the rules fired."
[?rules <- (acc/all) :from [RuleFired]]
=>
(prn "RULES" (->> ?rules (mapv :rule) (mapv :name))))
(r/defquery get-rules-fired
"Query to retrieve the fired rules."
[]
[?rules <- (acc/all) :from [RuleFired]])
This makes it work, but it seems wrong to me. I don’t think I should need to specify a condition. (some? rule)
[?rules <- (acc/all) :from [RuleFired (some? rule)]]
@joel380 how were you trying it?
[?rules <- (acc/all) :from [RuleFired]] Did NOT work.
It’s like it requires the test: (some? rule), but I want them all.
I mean how are you evaluating the rules - the whole flow
(-> (r/mk-session :fact-type-fn #(or (:type %) (type %)))
(r/insert (assoc example-context-map :type :context))
(r/fire-rules))
rules-fired (-> session (r/query get-rules-fired) first)]
session is the result after the r/fire-rules?
I guess the main thing here is, I want to make sure you are doing r/fire-rules before doing any r/query
Yes, the only change I’m making is adding/removing (some? rule) and it works/doesn’t work.
Remember the session is immutable too, so you have to bind to the results of r/fire-rules.
Right. Like I say it works if (some? rule) is there, which is meaningless.
(let [session (-> (r/mk-session :fact-type-fn #(or (:type %) (type %)))
(r/insert (assoc example-context-map :type :context))
(r/fire-rules))
rules-fired (-> session (r/query get-rules-fired) first)]
...)(let [session
(-> (r/mk-session :fact-type-fn #(or (:type %) (type %)))
(r/insert (assoc example-context-map :type :context))
(r/fire-rules))
rules-fired (-> session (r/query get-rules-fired) first)]
(clojure.pprint/pprint (ir/inspect session))
(prn "Fired Rules: " (mapv #(get-in % [:rule :name]) (:?rules rules-fired))))
Yes, but when you do not do r/fire-rules there could be some amount of unevaluated query behavior - so I’m just ruling out that that is the difference when you add a constraint.
I don’t see the problem otherwise. I’m curious if this can be trivially recreated with a mini example rules or if it only works this way for you.
Yeah, I could make something shorter.
It’s seems like quite a basic case for it to not work
what is a rule that is always true (LHS)?
I think you can just leave the LHS off?
If not, you could do something with (acc/all) since it always causes the RHS to fire - just with empty coll.
(require '[clara.rules :as r])
(require '[clara.rules.accumulators :as acc])
(defrecord RuleFired [])
(defrecord RuleFiredRes [])
(r/defrule rules-fired
"Rule that gets the rules fired."
[?rules <- (acc/all) :from [RuleFired]]
=>
(prn "Fired!")
(r/insert! (->RuleFiredRes)))
(r/defquery get-rules-fired
"Query to retrieve the fired rules."
[]
[?rules <- (acc/all) :from [RuleFired]])
(let [session (-> (r/mk-session)
(r/insert (->RuleFired))
(r/fire-rules))]
(r/query session get-rules-fired))
;; "Fired!"
;;= ({:?rules [#user.RuleFired{}]})
This works for me. So if there are issues, perhaps the :fact-type-fn is to blameStill works if I add that:
(let [session (-> (r/mk-session :fact-type-fn #(or (:type %) (type %)))
(r/insert (->RuleFired))
(r/fire-rules))]
(r/query session get-rules-fired))
;; "Fired!"
;;= ({:?rules [#user.RuleFired{}]})hmm, wonder if i have some repl issue going on. i did see it just work without the condition.
(defrecord RuleFired [rule])
(r/defquery get-rules-fired
"Query to retrieve the fired rules."
[]
[?rules <- (acc/all) :from [RuleFired (some? rule)]])
(r/defrule this-rule-is-on-fire
=> (r/insert! (->RuleFired (meta (resolve 'this-rule-is-on-fire)))))
(-> (r/mk-session [this-rule-is-on-fire get-rules-fired])
(r/fire-rules)
(r/query get-rules-fired)
(prn "<---"))
Yeah, looks like repl artifact, odd, thanks for looking!
Ok good. No problem.