Fork me on GitHub

Well… i guess its a known issue: However, the “schema” error seems to have been lost some where in the updates to the compiler. The issue as it stands:

#clara.rules.engine.NegationNode{:id 1,
                                 :condition [:exists {:type Stuff, :constraints []}],
                                 :children (#clara.rules.engine.ProductionNode{:id 2,
                                                                               :production {:ns-name 
                                                                                            :lhs [[:not
                                                                                                    {:type Stuff,
                                                                                                     :constraints []}]]],
                                                                                            :rhs (do
                                                                                                  (println "Add stuff")
                                                                                                    (->Stuff "foo")))),
                                                                                            :name "add-stuff"},
                                                                               :rhs #object[eval9894$fn__9895
                                                                                            "[email protected]"]}),
                                 :binding-keys #{}}
This negation node makes no sense… It has no parent, meaning that post session construction it has no interaction with the session. Something equivalent to a rule with no LHS…. just “do” the RHS.


Oh. So it's going to run once no matter what? I guess I could test that.


The compiler is extracting this portion of the graph all wrong. One of the telling bits about this one was, when attaching a listener to the session... the log message from the rule is printed prior to the first interaction with the listener. This is indicative of: the "left-activate" here is provided with a "default-listener"(No-Op) as its pushing basically a "none token". This sort of bootstrapping is catching nodes without a proper parent, the fact that this is triggering the negation means that the :exist and its condition are being ignored all together.

👍 1

Is the workaround to do something like a count accumulator and test against zero?


The quick solution would most likely be to replace that sort of rule with something closer to:

(r/defrule add-stuff
  [:not [Stuff]]
  (println "Add stuff")
  (r/insert! (->MakeStuff (->Stuff "foo"))))


Which should have the desired effect without the accumulator


Ah. That makes more sense anyway. I'll give that a try.


That works. Thank you!


Just for my own edification: why :exists at all? Does it work in the non-negated case?


Yes, the parsing of the graph in a non-negation flow handles it correctly. The :exists sugar has always baffled me, in concept it should make a rule more human readable, ie. if X exists then .... However, personally i rarely/never use it