Skip to content

Unbound variable in defquery #470

Open
@vganshin

Description

@vganshin

Hello. Could you assist on an exception I got while playing with clara-rules?

I'm trying to make a simple rule that calculates patient's age and a query which retrieve patients older than certain age. When I run (mk-session 'clara.example) I get an exception which says I have Unbound variables: #{?age} in my query. I don't understand, why is it unbound if it's passed as a parameter.

(ns clara.example
  (:require [clara.rules :refer :all]
            [clj-time.core]
            [clojure.string :as str]))

(defn to-int [n]
  (Integer/parseInt n))

(defn age [birth-date]
  (clj-time.core/in-years
   (clj-time.core/interval
    (apply clj-time.core/date-time
           (mapv
            to-int
            (str/split birth-date #"-")))
    (clj-time.core/now))))

(defrule pt-age
  ["Patient" [pt] (= ?pt pt) (some? (get-in pt [:birthDate]))]
  =>
  (insert! {:resourceType "PatientAge"
            :id (:id ?pt)
            :age (age (:birthDate ?pt))}))


(defquery get-pt-older-than
  [?age]
  [?pt <- "PatientAge" [pt-age] (> (:age pt-age) ?age)])

(def sess
  (-> (mk-session 'clara.example :fact-type-fn :resourceType)
      (insert {:id "pt-1"
               :resourceType "Patient"
               :birthDate "1994-09-26"
               :name [{:given ["John"]
                       :family "Smith"}]})
      (insert {:id "pt-2"
               :resourceType "Patient"
               :birthDate "1990-01-01"
               :name [{:given ["Toto"]
                       :family "Ro"}]})
      (fire-rules)))

(query sess get-pt-older-than :?age 30)
   #:clojure.error{:phase :execution, :line 33, :column 7, :source "example.clj"}
             Compiler.java: 3711  clojure.lang.Compiler$InvokeExpr/eval
             Compiler.java: 3705  clojure.lang.Compiler$InvokeExpr/eval
             Compiler.java: 3705  clojure.lang.Compiler$InvokeExpr/eval
             Compiler.java: 3705  clojure.lang.Compiler$InvokeExpr/eval
             Compiler.java:  457  clojure.lang.Compiler$DefExpr/eval
             Compiler.java: 7186  clojure.lang.Compiler/eval
             Compiler.java: 7640  clojure.lang.Compiler/load
                      REPL:    1  user/eval41266
                      REPL:    1  user/eval41266
             Compiler.java: 7181  clojure.lang.Compiler/eval
             Compiler.java: 7136  clojure.lang.Compiler/eval
                  core.clj: 3202  clojure.core/eval
                  core.clj: 3198  clojure.core/eval
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  667  clojure.core/apply
                  core.clj: 1977  clojure.core/with-bindings*
                  core.clj: 1977  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   87  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  437  clojure.main/repl/read-eval-print/fn
                  main.clj:  437  clojure.main/repl/read-eval-print
                  main.clj:  458  clojure.main/repl/fn
                  main.clj:  458  clojure.main/repl
                  main.clj:  368  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   84  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  152  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  202  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  201  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  833  java.lang.Thread/run

1. Caused by clojure.lang.ExceptionInfo
   Using variable that is not previously bound. This can happen when an
   expression uses a previously unbound variable, or if a variable is referenced
   in a nested part of a parent expression, such as (or (= ?my-expression
   my-field) ...). Note that variables used in negations are not bound for
   subsequent rules since the negation can never match. Production: {:lhs
   [{:type "PatientAge", :constraints [(> (:age pt-age) ?age)], :args [pt-age],
   :fact-binding :?pt}], :params #{:?age}, :name
   "clara.example/get-pt-older-than"} Unbound variables: #{?age}
   {:production
    {:lhs
     [{:type "PatientAge",
       :constraints [(> (:age pt-age) ?age)],
       :args [pt-age],
       :fact-binding :?pt}],
     :params #{:?age},
     :name "clara.example/get-pt-older-than"},
    :variables #{?age}}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions