clara

http://www.clara-rules.org/
2020-11-02T00:13:11.126Z

hi, i get this issue on compiling a rules namespace. could anyone help me understand what’s wrong with my bindings?

Malformed variable binding for #{?contract-provider ?claim-provider}. No associated value.
(defrule associated-contracts
  [:contract (= ?contract this)]
  [:contract (= ?contract-provider (:subject ?contract))]
  [:claim (= ?claim this)]
  [:claim (= ?claim-provider (-> ?claim
                                  :billing-provider
                                  :identifier
                                  :value))]
  [:associated? (= ?claim-provider ?contract-provider)]
  =>
  (insert! {:resource-type :associated-contract
            :claim ?claim
            :contract ?contract}))

2020-11-02T00:14:28.126100Z

i’m using fact-type functions instead of clojure records but i’m having trouble figuring out what are the right patterns

2020-11-02T00:14:43.126300Z

in this case i want to bind the entire object to either ?claim or ?contract

2020-11-02T00:15:04.126500Z

and i also want to bind nested variables in that map

ethanc 2020-11-02T00:20:00.126700Z

I don't have repl open currently, but it looks like this might be because of the multiple conditions with similar fact types. rather than 2 conditions to bind contract and claim, i would assume that you might actually want a single condition for each. Something like:

(defrule associated-contracts
  [:contract 
(= ?contract this)
(= ?contract-provider (:subject this))]
  [:claim 
 (= ?claim this)
(= ?claim-provider (-> this
                                  :billing-provider
                                  :identifier
                                  :value))]
  [:associated? (= ?claim-provider ?contract-provider)]
  =>
  (insert! {:resource-type :associated-contract
            :claim ?claim
            :contract ?contract}))

2020-11-02T00:24:08.127Z

oh i see — that’s definitely a lot cleaner 🙂 it’s still giving me that error though

ethanc 2020-11-02T00:31:01.127200Z

hmmm, seems clara is incorrectly moving the joined conditional up in front of the binding itself. Specifially,

[:associated? (= ?claim-provider ?contract-provider)]

ethanc 2020-11-02T00:31:54.127400Z

however this condition seems odd to me, you are looking to a fact in the session but not asserting anything based on this fact

ethanc 2020-11-02T00:32:55.127600Z

it almost seems as if that should be a test node:

[:test (= ?claim-provider ?contract-provider)]

ethanc 2020-11-02T00:33:35.127800Z

or potentially rolled up into the :claim condition itself

ethanc 2020-11-02T00:34:45.128Z

something like:

(r/defrule associated-contracts
  [:contract
   (= ?contract this)
   (= ?contract-provider (:subject this))]
  [:claim
   (= ?claim this)
   (= (-> this
          :billing-provider
          :identifier
          :value)
      ?contract-provider)]
  =>
  (r/insert! {:resource-type :associated-contract
              :claim ?claim
              :contract ?contract}))

2020-11-02T00:37:04.128300Z

oh that’s totally it — i’m trying to set it up to have the simple predicate comparing facts and i didn’t realize that you had to name it :test in order for that to work…

2020-11-02T00:37:44.128500Z

would the above example give you ones that matched or all combinations of facts?

2020-11-02T00:38:57.128700Z

also how does querying for the fact-type-fn work? i tried the following:

(defquery get-associated-contracts
  []
  [?associated-contract <- :associated-contract])

ethanc 2020-11-02T00:39:11.128900Z

in the example above, the RHS should execute and insert a fact for each combination of a Claim and Contract that share the same provider

2020-11-02T00:43:48.129100Z

oh i see

2020-11-02T00:43:55.129300Z

that’s perfect! thank you so much!!

ethanc 2020-11-02T00:44:01.129500Z

Queries should work the same way while using/not using an overridden fact-type-fn. For example:

(defn test-session
  []
  (-> (r/mk-session :fact-type-fn :resource-type)
      (r/insert {:resource-type :contract :subject :Thomas})
      (r/insert {:resource-type :claim :billing-provider {:identifier {:value :Thomas}}})
      (r/fire-rules)
      (r/query get-associated-contracts)))
should net:
({:?associated-contract {:resource-type :associated-contract,
                         :claim {:resource-type :claim, :billing-provider {:identifier {:value :Thomas}}},
                         :contract {:resource-type :contract, :subject :Thomas}}})

2020-11-02T00:46:27.129700Z

ooh i see — thank you! that makes sense

1👍