clara

http://www.clara-rules.org/
dominicm 2018-05-20T08:40:37.000003Z

I seem to have identified a big misunderstanding on my part:

(ns bugB
  (:require
    [clara.rules :refer :all]))

(defrecord DatabaseBox [id])
(defrecord AWSDBInstance [id])

(defrecord DatabaseBoxEngine [e v])
(defrecord AWSDBInstanceEngine [e v])
(defrecord RollCreatedFor [e v])

(defrule DatabaseBox-Engine
  [RollCreatedFor (= e ?dbi) (= v ?dbox)]
  [DatabaseBoxEngine (= e ?dbox) (= ?v v)]
  =>
  (println ?dbi ?dbox ?v))

(comment
  (clear-ns-productions!)
  (let [foo (->DatabaseBox "foo")
        foo-db (->AWSDBInstance "foo")
        foo-db-backup (->AWSDBInstance "foo-backup")]
    (-> (mk-session)
        (insert
          foo
          (->DatabaseBoxEngine foo :postgres)
          foo-db
          (->RollCreatedFor foo-db foo)
          foo-db-backup
          (->RollCreatedFor foo-db-backup foo-db)
          (->RollCreatedFor foo-db-backup foo))
        (fire-rules))))
I cannot understand why this prints #bugB.AWSDBInstance{:id foo-backup} #bugB.AWSDBInstance{:id foo} :postgres (among the 2 other results, I expect of AWSDBInstace with a DatabaseBox). I particularly don't understand how it finds a DatabaseBoxEngine where e is an AWSDBInstance?

dominicm 2018-05-20T08:41:10.000062Z

The total output:

#bugB.AWSDBInstance{:id foo} #bugB.DatabaseBox{:id foo} :postgres
#bugB.AWSDBInstance{:id foo-backup} #bugB.DatabaseBox{:id foo} :postgres
#bugB.AWSDBInstance{:id foo-backup} #bugB.AWSDBInstance{:id foo} :postgres

alex-dixon 2018-05-20T17:32:19.000028Z

Looks like the only a database box engine has an e of foo record and if that’s your only rule there’s no way it should match on two different fact types when the fact type function is type

dominicm 2018-05-20T17:54:08.000093Z

@alex-dixon sorry, I'm struggling to understand. Can you try in different terms.

alex-dixon 2018-05-20T17:54:43.000035Z

What’s happening seems completely wrong

alex-dixon 2018-05-20T17:55:27.000017Z

Your rule expresses a join your input data can satisfy at most once

alex-dixon 2018-05-20T17:57:17.000107Z

And your rule specifies a join on two different fact types. So a match for it that contains only one fact type should be impossible

alex-dixon 2018-05-20T17:58:22.000028Z

Have you tried restarting the repl?

alex-dixon 2018-05-20T17:59:22.000023Z

Something just seems wildly off. Do you think it could be caused by old repl state?

dominicm 2018-05-20T18:04:11.000056Z

I'll try a restart of the repl. I had presumed a fresh namespace was enough.

alex-dixon 2018-05-20T18:08:16.000031Z

I would too. I’m not sure how records refresh or whether they are repl friendly in general (think they need imported?). I see you were using clear ns productions but it’s not clear to me how rules are being loaded using mk session without passing in the productions?

dominicm 2018-05-20T18:10:33.000089Z

I'm still getting this behaviour:

#bugB.AWSDBInstance{:id foo} #bugB.DatabaseBox{:id foo} :postgres
#bugB.AWSDBInstance{:id foo-backup} #bugB.DatabaseBox{:id foo} :postgres
#bugB.AWSDBInstance{:id foo-backup} #bugB.AWSDBInstance{:id foo} :postgres
I experimented with (clear-ns-productions!), but I'm not actually running it anymore.

alex-dixon 2018-05-20T18:11:07.000096Z

I see in the source mk session with no args uses /ns/

dominicm 2018-05-20T18:11:54.000123Z

yes 🙂

dominicm 2018-05-20T18:12:00.000047Z

*ns*

alex-dixon 2018-05-20T18:12:02.000073Z

With earmuffs

alex-dixon 2018-05-20T18:12:07.000012Z

Thx lol

dominicm 2018-05-20T18:12:08.000004Z

` is what you're after

alex-dixon 2018-05-20T18:12:36.000022Z

Yeah...Apple doesn’t have that on their phones

dominicm 2018-05-20T18:13:36.000083Z

oh 😞 silly fruit

alex-dixon 2018-05-20T18:13:41.000094Z

The last result is the most glaring

alex-dixon 2018-05-20T18:15:02.000158Z

Try binding the whole fact and printing that out. I may be confused

dominicm 2018-05-20T18:15:47.000111Z

which fact, first, second or both?

alex-dixon 2018-05-20T18:16:04.000029Z

?fact1 <- condition 1 ?fact2 <- condition 2

dominicm 2018-05-20T18:16:51.000016Z

(defrule DatabaseBox-Engine
  [?a &lt;- RollCreatedFor (= e ?dbi) (= v ?dbox)]
  [?b &lt;- DatabaseBoxEngine (= ?dbox e) (= ?v v)]
  =&gt;
  (prn ?a ?b))

=&gt;

; #bugB.RollCreatedFor{:e #bugB.AWSDBInstance{:id "foo"}, :v #bugB.DatabaseBox{:id "foo"}} #bugB.DatabaseBoxEngine{:e #bugB.DatabaseBox{:id "foo"}, :v :postgres}
; #bugB.RollCreatedFor{:e #bugB.AWSDBInstance{:id "foo-backup"}, :v #bugB.DatabaseBox{:id "foo"}} #bugB.DatabaseBoxEngine{:e #bugB.DatabaseBox{:id "foo"}, :v :postgres}
; #bugB.RollCreatedFor{:e #bugB.AWSDBInstance{:id "foo-backup"}, :v #bugB.AWSDBInstance{:id "foo"}} #bugB.DatabaseBoxEngine{:e #bugB.DatabaseBox{:id "foo"}, :v :postgres}

alex-dixon 2018-05-20T18:21:05.000110Z

Ok so the fact types are right I was mistaken on that

dominicm 2018-05-20T18:52:16.000131Z

I suppose that in [?b &lt;- DatabaseBoxEngine (= ?dbox e) (= ?v v)] The (= ?dbox e) is being ignored.

2018-05-20T22:11:27.000112Z

(= (-&gt;DatabaseBox "foo")
     (-&gt;AWSDBInstance "foo")) ;; =&gt; false
  (.equals (-&gt;DatabaseBox "foo")
           (-&gt;AWSDBInstance "foo")) ;; =&gt; true
So there is probably some confusion in some of the java collections used within clara

2018-05-20T23:06:03.000097Z

@dominicm the problem is here: https://github.com/cerner/clara-rules/blob/master/src/main/clojure/clara/rules/platform.cljc#L11 Replace the group-by-seq with

(seq (group-by f coll))
and it works properly again

🎉 1
2018-05-20T23:07:33.000073Z

(platform/group-by-seq vector
                         [(-&gt;DatabaseBox "foo")
                          (-&gt;AWSDBInstance "foo")])
  ;; =&gt;   [[[#clara_bug.core.DatabaseBox{:id "foo"}] [#clara_bug.core.DatabaseBox{:id "foo"} #clara_bug.core.AWSDBInstance{:id "foo"}]]]

  (defn group-by-seq [f coll]
    (seq (group-by f coll)))
  (group-by-seq vector
                [(-&gt;DatabaseBox "foo")
                 (-&gt;AWSDBInstance "foo")])
  ;; =&gt; ([[#clara_bug.core.DatabaseBox{:id "foo"}] [#clara_bug.core.DatabaseBox{:id "foo"}]] [[#clara_bug.core.AWSDBInstance{:id "foo"}] [#clara_bug.core.AWSDBInstance{:id "foo"}]])