Fork me on GitHub
#clara
<
2018-10-23
>
dhruv114:10:29

hello. In clara, how can i write recursive queries?

dhruv114:10:44

here is an example of the data I have:

dhruv114:10:51

{:type :foo
 :desc "'Foo' node"
 :parent :D}

{:type :D
 :desc "'D' node"
 :parent :C}

{:type :C
 :desc "'C' node"
 :parent :B}

{:type :B
 :desc "'B' node"
 :parent :A}

{:type :A
 :desc "'A' node"}

dhruv114:10:42

here is what i would like the output of the query to look like:

dhruv114:10:00

'(:?node {:type :foo
          :desc "'Foo' node"
          :parent :D}
         
       :?parents [{:type :D
                      :desc "'D' node"
                     :parent :C}

                    {:type :C
                     :desc "'C' node"
                     :parent :B}

                    {:type :B
                     :desc "'B' node"
                     :parent :A}

                    {:type :A
                     :desc "'A' node"}])

dhruv114:10:51

is this possible with a clara query?

eraserhd15:10:34

Not with just a query, you'll need to introduce some facts.

eraserhd15:10:14

So you'd have one rule that's (heavily abbreviating the code): [:test (no-children? ?node)] => (insert! (->TreeRep ?node ?node))). And one that's [:test (children? ?node)] ?children <- (acc/all) :from [Node (= parent ?node)] => (insert! (->TreeRep ?node (add-children ?node ?children))).

eraserhd15:10:13

Assuming your graph is acyclic. If it isn't, this will be bad.

eraserhd15:10:32

It might be doable with one rule, actually. But the point is, AFAICT, there's no way to recurse without inserting facts.

dhruv116:10:50

Ah understood.

dhruv116:10:04

Will give that a go. Thank you!

eraserhd16:10:58

Oh, you want to (acc/all) :from [TreeRep ...], probably.

eraserhd16:10:34

You could also do this with a custom accumulator, but that would be much harder, I'm guessing.

mikerod16:10:10

@eraserhd I was thinking along those same lines

mikerod16:10:18

about having to introduce some facts to model it

eraserhd16:10:40

By the way, 👋 clara people! We are starting to rely heavily on this for work, and it is a good thing.

mikerod17:10:09

Nice. What sort of things are you using it for (if you can say) and clj or cljs?

eraserhd17:10:50

We are storing data in Datomic, and importing the facts, and deriving a bunch of stuff from them.

eraserhd17:10:13

This includes constraint validation, what we are calling "synthetic attributes", which are computed attributes.

eraserhd17:10:36

This is all business data about the online degree programs we are hosting.

eraserhd17:10:50

And this system drives the stand up of new systems.

mikerod17:10:37

oh that’s cool

mikerod17:10:09

there was a datomic “datom” integration lib with clara

mikerod17:10:14

was that related or something you’ve seen?

eraserhd17:10:02

We built our own, and we have a library we are attempting to Open Source :crossed_fingers:

eraserhd17:10:17

Not specifically about Datoms

mikerod17:10:59

I’m trying to find the github link I had for that before, but was interesting

mikerod17:10:07

but would be really interesting if you open sourced hah

eraserhd17:10:02

@U0LK1552A This actually looks pretty neat. Our library does a different thing, regarding bulk loading facts from datomic and caching intermediate sessions to save work. It seems like we could use them together.

mikerod17:10:37

interesting

mikerod17:10:43

caching intermediate sessions seems interesting too

mikerod17:10:48

seems like some durability stuff I messed with before

mikerod17:10:00

(well I wrote that stuff in clara originally to try some things out)