Fork me on GitHub
#clara
<
2019-04-30
>
Joel00:04:14

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?

mikerod01:04:52

@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.

Joel01:04:51

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

Joel01:04:57

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

mikerod13:04:33

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

mikerod13:04:43

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.

mikerod13:04:44

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.

ethanc14:04:19

@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.

ethanc14:04:27

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

mikerod15:04:09

@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.