This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-06
Channels
- # adventofcode (106)
- # aleph (1)
- # announcements (1)
- # asami (14)
- # babashka (120)
- # beginners (54)
- # calva (106)
- # chlorine-clover (33)
- # clj-kondo (5)
- # cljdoc (3)
- # cljs-dev (3)
- # clojure (92)
- # clojure-android (1)
- # clojure-australia (2)
- # clojure-europe (24)
- # clojure-italy (3)
- # clojure-nl (5)
- # clojure-uk (16)
- # clojuredesign-podcast (1)
- # clojurescript (29)
- # code-reviews (58)
- # conjure (16)
- # core-logic (4)
- # cursive (9)
- # datalevin (2)
- # graphql (20)
- # gratitude (7)
- # jackdaw (11)
- # java (9)
- # jobs (2)
- # lsp (23)
- # minecraft (1)
- # missionary (28)
- # off-topic (5)
- # polylith (5)
- # react (1)
- # reagent (12)
- # releases (1)
- # remote-jobs (4)
- # reveal (7)
- # shadow-cljs (8)
- # slack-help (1)
- # tools-deps (11)
- # vim (6)
Is that possible to get the path between to child? or do I need to structure different way the database?
(def data3
{:db/ident "top-node"
:name "hello"
:children [{:db/ident "A first children"
:name "A first children"
:children {:db/ident "A second children"
:name "A second children"
:children {:db/ident "A third children"
:name "A third children"
:children "no more"}}}
{:db/ident "B first children"
:name "first children"
:children {:db/ident "B second children"
:name "B second children"
:children {:db/ident "B third children"
:name "B third children"
:children "no more"}}}]})
(def db-uri12 "asami:")
(d/create-database db-uri12)
(def conn12 (d/connect db-uri12))
(def p12 @(d/transact conn12 {:tx-data data3}))
(def db12 (d/db conn12))
(q '[:find ?a
:where [?nodeA :name "A third children"]
[?nodeB :name "B third children"]
[?nodeA ?a* ?nodeB]]
db12)
I would like to get path between NodeA and NodeB. [I can get the path between the top-node and third nodes eg ?p a+ nodeA, but how to possible between nodeA and nodeB?] I’m sorry if that is a trivial thing, I’m new at datalog.
I'm not sure that would be possible. Consider that for that to work you would need to have something like `[?node :some-attribute :tg/node-topNode]` which is simply not there. In other words, what you want is not really transitive – you would need to reverse the 'transitive order' once you reach `top-node`. At least, that's my take on it, but I am far from an expert. Combining the two paths `A->top` and `B->top` you know how to obtain is not good enough?
Okay, I've explored this further.
Some general notes. First, note that top-node
:tg/owns
every node below it, so that there is actually more than one path from top-node
to a3
. Second, and this is purely subjective, it might help to have some uniformity: top-node
's children are an array, which is not true for nodes below. Also note that there is no guaranteed order of results, afaik.
Having said all that, you can get all the (unordered) nodes from a3
to b3
like so:
(d/q '[:find ?a
:where
(or [?a ?path-a* :tg/node-A3]
[?a ?path-b* :tg/node-B3])
[?a :children]]
(d/db conn))
Yes, that is works in more difficult trees. I used in my tests in wrong way the “OR Constraint”, thank you very much the example. I have an another question:
(q '[:find ?c ?nm
:where [?nodeA :name "AA third children"]
[?nodeB :name "BA third children"]
[?a ?path-a* ?nodeA]
[?a ?path-b* ?nodeB]
(or [?b ?path-a* ?nodeA]
[?b ?path-b* ?nodeB])
[?b :children]
(not [?a :children])
[?c :children]
[?b :name ?nm]
]
db15)
Mainly my question: if I have ?variableA and ?variableB, how to compare or minus (- A B or “The B set does not contain set A.“), is that possible?
(q '[:find ?b ?nm
:where [?nodeA :name "AA third children"]
[?nodeB :name "BA third children"]
(or [?b ?path-a* ?nodeA]
[?b ?path-b* ?nodeB])
(not [?b ?path-a* ?nodeA]
[?b ?path-b* ?nodeB])
[?b :name ?nm]]
db15)
Hi, @quoll, could you check why this query hangs (does not evaluate):
(def data5
{:db/id :tg/node-0
:name "hello"
:children [{:db/id :tg/node-A1
:name "A first children"
:children {:db/id :tg/node-A2
:name "A second children"
:children {:db/id :tg/node-A3
:name "A third children"
:children "no more"}}}
{:db/id :tg/node-B1
:name "first children"
:children {:db/id :tg/node-B2
:name "B second children"
:children {:db/id :tg/node-B3
:name "B third children"
:children "no more"}}}]})
(d/transact conn data5)
(d/q '[:find ?common
:where
[?common :children+ :tg/node-A3]
[?common :children+ :tg/node-B3]]
(d/db conn))
I would expect it to return the empty set.