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}))
i’m using fact-type functions instead of clojure records but i’m having trouble figuring out what are the right patterns
in this case i want to bind the entire object to either ?claim or ?contract
and i also want to bind nested variables in that map
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}))
oh i see — that’s definitely a lot cleaner 🙂 it’s still giving me that error though
hmmm, seems clara is incorrectly moving the joined conditional up in front of the binding itself. Specifially,
[:associated? (= ?claim-provider ?contract-provider)]
however this condition seems odd to me, you are looking to a fact in the session but not asserting anything based on this fact
it almost seems as if that should be a test node:
[:test (= ?claim-provider ?contract-provider)]
or potentially rolled up into the :claim
condition itself
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}))
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…
would the above example give you ones that matched or all combinations of facts?
also how does querying for the fact-type-fn work? i tried the following:
(defquery get-associated-contracts
[]
[?associated-contract <- :associated-contract])
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
oh i see
that’s perfect! thank you so much!!
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}}})
ooh i see — thank you! that makes sense