clara

Joel 2023-10-26T18:29:17.006179Z

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

Joel 2023-10-26T18:46:04.369689Z

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

2023-10-26T19:16:04.202729Z

@joel380 how were you trying it?

Joel 2023-10-26T19:16:35.322799Z

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

Joel 2023-10-26T19:17:42.991569Z

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

2023-10-26T20:24:23.433629Z

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

Joel 2023-10-26T20:25:39.695399Z

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

2023-10-26T20:26:00.149749Z

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

2023-10-26T20:26:25.699769Z

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

Joel 2023-10-26T20:26:27.722309Z

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

2023-10-26T20:26:53.356969Z

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

Joel 2023-10-26T20:27:23.471709Z

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

2023-10-26T20:27:32.880149Z

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

Joel 2023-10-26T20:27:46.701829Z

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

2023-10-26T20:27:56.009609Z

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.

2023-10-26T20:28:47.104279Z

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.

Joel 2023-10-26T20:29:15.254869Z

Yeah, I could make something shorter.

2023-10-26T20:29:31.621019Z

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

Joel 2023-10-26T20:30:46.033209Z

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

2023-10-26T20:32:39.614739Z

I think you can just leave the LHS off?

2023-10-26T20:33:01.206799Z

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

2023-10-26T20:38:06.121399Z

(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

2023-10-26T20:38:49.202829Z

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

Joel 2023-10-26T20:44:44.096669Z

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

Joel 2023-10-26T20:45:13.006629Z

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

Joel 2023-10-26T20:49:59.496399Z

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

2023-10-27T00:17:50.929379Z

Ok good. No problem.