Fork me on GitHub
#clara
<
2023-10-26
>
Joel18:10:17

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

Joel18:10:04

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

mikerod19:10:04

@UH13Y2FSA how were you trying it?

Joel19:10:35

[?rules <- (acc/all) :from [RuleFired]] Did NOT work.

Joel19:10:42

It’s like it requires the test: (some? rule), but I want them all.

mikerod20:10:23

I mean how are you evaluating the rules - the whole flow

Joel20:10:39

(-> (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)]

mikerod20:10:00

session is the result after the r/fire-rules?

mikerod20:10:25

I guess the main thing here is, I want to make sure you are doing r/fire-rules before doing any r/query

Joel20:10:27

Yes, the only change I’m making is adding/removing (some? rule) and it works/doesn’t work.

mikerod20:10:53

Remember the session is immutable too, so you have to bind to the results of r/fire-rules.

Joel20:10:23

Right. Like I say it works if (some? rule) is there, which is meaningless.

mikerod20:10:32

(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)]
  ...)

Joel20:10:46

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

mikerod20:10:56

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.

mikerod20:10:47

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.

Joel20:10:15

Yeah, I could make something shorter.

mikerod20:10:31

It’s seems like quite a basic case for it to not work

Joel20:10:46

what is a rule that is always true (LHS)?

mikerod20:10:39

I think you can just leave the LHS off?

mikerod20:10:01

If not, you could do something with (acc/all) since it always causes the RHS to fire - just with empty coll.

mikerod20:10:06

(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 blame

mikerod20:10:49

Still 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{}]})

Joel20:10:44

hmm, wonder if i have some repl issue going on. i did see it just work without the condition.

Joel20:10:13

(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 "<---"))

Joel20:10:59

Yeah, looks like repl artifact, odd, thanks for looking!

mikerod00:10:50

Ok good. No problem.