This CLJS code refuses to work: The query ... is invalid or not included in the rule base
DjebbZ opened this issue · 2 comments
Hello,
I'm reporting what I thing is a bug. My colleague wrote this code, and it fails to run the query part.
Dependencies:
CLJS 1.10.339
clara rules 0.18.0
Context:
We want to use Clara rules to create easy to read/write/maintain/evolve rules to determine when to inject some trackers (think Google Analytics) in our website. For now the rules are simple and could be implemented in pure ClojureScript with if
s but the plan is to have much more complex rules, in which case in our opinion Clara rules will shine.
CLJS Code: (the complete code that fails, so you should normally be able to reproduce it)
(ns trackers.tracking-rules
(:require [clara.rules :refer [insert retract fire-rules query insert! retract!]
:refer-macros [defrule defquery defsession]]
[clara.tools.tracing :refer [with-tracing get-trace]]))
(defrecord Navigation [id-user page-type])
(defrecord Adblock [id-user adblock])
(defrecord Tracker [id-user tracker])
(defrecord Entity [id-user entity])
(defn create-navigation
[hash typ]
(let [{:keys [id-user page-type now-page landing referrer adblock entity]} hash
tracker :init]
(cond
(= typ :nav) (->Navigation id-user page-type)
(= typ :adb) (->Adblock id-user adblock)
(= typ :ent) (->Entity id-user entity)
(= typ :track) (->Tracker id-user tracker))))
;;;;;;;;;;;;;
;;; RULES ;;;
;;;;;;;;;;;;;
(defrule position-wt2
"Always true"
[Navigation (= ?id id-user)]
=>
(insert! (->Tracker ?id :wt2)))
(defrule position-ga
"Test if analytics is active"
[Adblock (= ?id id-user) (= adblock "no")]
=>
(insert! (->Tracker ?id :analytics))
)
(defrule position-facebook
"Test if facebook is active"
[Now (= ?id id-user) (= ?now-page now-page)]
[Adblock (= ?id id-user) (= adblock "no")]
[:test (= id-user now-page)];test impossible, pas facebook
=>
(insert! (->Tracker ?id :facebook))
)
(defrule position-admo
"Test if admo is active"
[Entity (= ?id id-user) (= ?entity entity)]
[or [:test (= ?entity "fr")]
[:test (= ?entity "es")]]
=>
(insert! (->Tracker ?id :admo ))
)
(defrule position-tradelab
"Test if quantcast is active"
[Entity (= ?id id-user) (= ?entity entity)]
[Navigation (= ?id id-user) (= ?position page-type)]
[:test (= ?entity "es")]
[:test (not (= ?position "shop-step5"))]
=>
(insert! (->Tracker ?id :tradelab ))
)
(defrule position-tradelab2
"Test if quantcast is active"
[Entity (= ?id id-user) (= ?entity entity)]
[Navigation (= ?id id-user) (= ?position page-type)]
[:test (= ?entity "es")]
[:test (= ?position "shop-step5")]
=>
(insert! (->Tracker ?id :tradelabpanier))
)
(defrule position-iadvize
"Test if iadvize is active"
[Entity (= ?id id-user) (= ?entity entity)]
[:test (= ?entity "fr")]
=>
(insert (->Tracker ?id :iadvize)))
(defrule position-zendesk
"Test if zendesk is active"
[Entity (= ?id id-user) (= ?entity entity)]
[:test (= ?entity "es")]
=>
(insert (->Tracker ?id :zendesk)))
(defrule position-bing2
"Test if bing is active"
[Navigation (= ?id id-user) (= ?position page-type)]
[:test (= ?position "shop-step5")]
=>
(insert! (->Tracker ?id :bingpanier ))
)
(defrule position-bing
"Test if bing is active"
[Navigation (= ?id id-user) (= ?position page-type)]
[:test (not (= ?position "shop-step5"))]
=>
(insert! (->Tracker ?id :bing ))
)
(defrule position-adwords
"Test if adwords is active"
[Navigation (= ?id id-user) (= ?position page-type)]
[:test (not (= ?position "shop-step5"))]
=>
(insert! (->Tracker ?id :adwords))
)
(defrule position-gtm
"Test if gtm is active"
[Adblock (= ?id id-user) (= adblock "no")]
=>
(insert (->Tracker ?id :gtm)))
(defrule position-kenshoo
"Test if kenshoo is active"
[Navigation (= ?id id-user) (= ?position page-type)]
[:test (= ?position "shop-step5")]
=>
(insert! (->Tracker ?id :kenshoo))
)
(defrule position-olark
"Test if olark is active"
[Entity (= ?id id-user) (= ?entity entity)]
[:test (= ?entity "us")]
=>
(insert! (->Tracker ?id :kenshoo))
)
(defquery get-active-tracker
"get the list of active tracker"
[]
[?tracking <- Tracker])
(defn construction-list
[user]
(->> user
(map (fn [x] (list (:tracker x))))
(reduce concat)))
(defn formatage
[{:keys [page-type entity]
{{{:keys [client-id]} :ids} :user } :session-data}]
{:id-user client-id,
:page-type page-type,
:entity entity
:adblock "no"})
(defn validate-trackers
[params session]
(try (let [type-page (create-navigation (formatage params) :nav)
ok-to-track (create-navigation (formatage params) :adb)
tracker-page (create-navigation (formatage params) :track)
entity-user (create-navigation (formatage params) :ent)
session (-> session #_(with-tracing session)
(insert type-page)
(insert ok-to-track)
(insert tracker-page)
(insert entity-user)
(fire-rules)
#_(get-trace))]
;(prn session)
;#{}
(into #{} (construction-list (into [] (map :?tracking (query session get-active-tracker))))))
(catch :default e
(println params)
(throw e))))
(defsession my-session 'tracking-rules)
(defn list-of-active-tracker
[params]
(validate-trackers params my-session))
The call that fails (and shouldn't)
(trackers.tracking-rules/list-of-active-tracker {:page-type "gt"})
I executed this code in several CLJS REPL (the new cljs.main, the new figwheel-main, and with boot-cljs/boot-cljs-repl), and I always got this error:
The query {:lhs [{:type trackers.tracking-rules/Tracker, :constraints [], :fact-binding :?tracking}], :params #{}, :name "trackers.tracking-rules/get-active-tracker", :doc "get the list of active tracker"} is invalid or not included in the rule base.
If you observe the validate-trackers
code (towards the end) I included clara.rules.tracing
to see if the facts were properly added. Here is the output if I uncomment and use the tracing code instead:
[{:type :add-facts, :node nil, :token nil, :facts (#trackers.tracking-rules.Navigation{:id-user nil, :page-type "gt"})}
{:type :add-facts, :node nil, :token nil, :facts (#trackers.tracking-rules.Adblock{:id-user nil, :adblock "no"})}
{:type :add-facts, :node nil, :token nil, :facts (#trackers.tracking-rules.Tracker{:id-user nil, :tracker :init})}
{:type :add-facts, :node nil, :token nil, :facts (#trackers.tracking-rules.Entity{:id-user nil, :entity nil})}]
I'm no clara-rules expert but the output looks pretty correct to us. It seems that the query defined with defquery
isn't working.
Another thing that may be related: in all the REPLs environments cited above, as soon as we edit the code the recompilation fails with this error (this precise output is from Boot-cljs but the message is the same in all REPLs):
java.lang.RuntimeException: Unable to resolve symbol: defrule in this context
clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: defrule in this context, compiling:(trackers/tracking_rules.cljc:31:1)
Thanks in advance for looking at this.
- I think the 'tracking-rules in mk-session here should be 'trackers.tracking-rules, that is the full namespace name. I'd expect this as is to result in a session with no rules or queries, the input here should probably be validated. Can post code links later, on mobile now.
- "insert" is used outside the rules session, insert! is used in the call stack of a rule RHS (right-hand side).
- I don't see a definition of your Now record.
Try that and post if that fixes it.
It worked! I did the changes this afternoon after a long period off of this problem. We can move on to more complex rules now.
Thanks a lot!