clara

http://www.clara-rules.org/
Joel 2019-04-30T00:22:14.021300Z

How can I apply the working memory from one session to another? Or fire one group of rules, and then apply it's WM to another set of rules?

2019-04-30T01:33:52.022900Z

@joel380 if needing to go from one group or rules to another, you could just make query for the facts you want out of the first group, then insert those query results into the next group.

Joel 2019-04-30T01:43:51.024300Z

i'd want all of them, would rather avoid queries for each type.

Joel 2019-04-30T01:44:57.024600Z

I didn't see them listed as part of the session.

2019-04-30T13:27:33.026800Z

Yeah a query for all types is typically rough on performance.

2019-04-30T13:28:43.028600Z

For all facts in working memory I don’t think there is a direct hook. I think maybe @ethanc would remember how we did “all facts” before.

2019-04-30T13:29:44.030500Z

Also, keep in mind that the engine won’t hold onto facts that it knows will never match. So for example, if you insert a fact A but no rule will ever be able to match it, it doesn’t stay in working memory. So you wouldn’t get it back with some “all facts” request.

ethanc 2019-04-30T14:00:19.033900Z

@joel380, Perhaps creating a marker protocol for the types of facts that you are interested in, and then leveraging a single query on that protocol. Something like:

(require '[clara.rules :refer :all])
(require '[clara.rules.accumulators :as acc])

(defprotocol ImportantFacts)

(defrecord A [x])
(defrecord B [y])

(defrecord C [z]
  ImportantFacts)

(defrecord D [a]
  ImportantFacts)

(defrecord E [b]
  ImportantFacts)


(defrule a-rule 
  [A (= ?x x)]
  =>
  (insert! (->C (+ ?x 10))))


(defrule b-rule
  [B (= ?y y)]
  =>
  (insert! (->D (+ ?y 50))))

(defrule ab-rule
  [A (= ?x x)]
  [B (= ?y y)]
  =>
  (insert! (->E (+ ?y ?x))))

(defquery important-query
  []
  [?all-important <- (acc/all) :from [user.ImportantFacts]])


(-> (mk-session)
    (insert (->A 12))
    (insert (->B 1))
    fire-rules
    (query important-query))
There is something goofy about the clara.rules.dsl namespace, with respect to how it resolves “types”, specifically protocols so i had to fully qualify the ImportantFacts symbol.

ethanc 2019-04-30T14:09:27.034100Z

=> ({:?all-important [#user.C{:z 22} #user.D{:a 51} #user.E{:b 13}]})

2019-04-30T15:03:09.036500Z

@joel380 @ethanc discussed on the side w/Ethan, but the defprotocol pattern for type hierarchies is sort of pedantically “wrong” I’d say. I think the host-type associated w/a defprotocol is meant to be more of an “impl details” (although it isn’t going to change), that is concerned with performance optimizations. So I’d probably go w/ definterface when all you want is the type marker. That said, Clara has supported defprotocol types being used in rules when the symbol is in reference to the the class type, not the protocol metadata var. Ethan is likely going to log a Clara issues concerning the 2nd case and how this can get weird.

👍 1