How to query in a forall logic?
Hi guys, I’m facing an issue while attempting to write an advanced query following a for-all (for-each / for-any) logic that: given x, for any y, if there is a relationship R between x and y, then y has the property P. This is equivalent to saying that there is no y who shares a relationship R with x but lacks the property P.
An example scenario is:
suppose I only have two pages as follows:
block-exists
- <empty block>
- #query-tag
- <empty block>
block-forall
- #query-tag
- #query-tag
- #query-tag
The goal is to (a) find all pages x such that every block y of the page has the tag #query-tag
,
So a right query should result in a page list that only contains the page block-forall
.
I am new to the datalog query language and don’t know how to directly do the task, but I learn that the equivalent way is to
(b) find all pages x excluding the ones who do have a block y without the tag #query-tag
.
So my current query is
#+BEGIN_QUERY
{
:query [
:find (pull ?p [:block/name])
:where
[?p :block/name]
(not-join [?p]
[?b :block/page ?p]
(not [?b :block/refs [:block/name "query-tag"]])
)
]
}
#+END_QUERY
This query does not work as expected.
The other similar scenario is to find all empty pages. By an empty page
, I mean the page who either does not have any content or contains one property block as the content.
I know how to write a query of finding non-empty pages (as follows), but failed to write a query to do the opposite, too.
#+BEGIN_QUERY
{
:query [
:find (pull ?p [:block/name])
:in $
:where
[?p :block/name] ;; all pages
[?p :block/journal? false] ;; not journal
[?b :block/page ?p] ;; blocks of the page
[(get-else $ ?b :block/pre-block? false) ?first]
[(= ?first false)]
[?b :block/content ?content] ;; block content
[(not= ?content "")]
]
}
#+END_QUERY
I have searched forum and datomic docs but couldn’t identify the problem. Any insights or suggestions? I would greatly appreciate your assistance. Thank you!
Relevant Link: Datalog: does every value for a given entity attribute exactly match a given set? - #5 by dustingetz - General - Datomic Developers
Original post:
[s] Hi guys, I’m facing an issue while attempting to write an advanced query following a forall logic x: ∀y, relation(x,y) <=> x: ¬(∃y, ¬relation(x,y))
. The scenario involves two pages as below:
block-exists
- <empty block>
- #query-tag
- <empty block>
block-forall
- #query-tag
- #query-tag
- #query-tag
My goal is to create a list of pages with blocks each tagged with “#query-tag”.
The result should be the “block-forall” page in the given scenario.
However, my current query did not work as expected (returning a list many other irrelavant pages, including task priority like A, B, C). Here is my current query:
#+BEGIN_QUERY
{
:query [
:find (pull ?p [:block/name])
:where
[?p :block/name]
(not-join [?p]
[?b :block/page ?p]
(not [?b :block/path-refs [:block/name "query-tag"]])
)
]
}
#+END_QUERY
I have searched forum, discord and datomic docs but couldn’t identify the problem. any insights or suggestions? I would greatly appreciate your assistance. Thank you!
Relevant topic: does every value for a given entity attribute exactly match a given set? - #5 by dustingetz - General - Datomic Developers Datalog: does every value for a given entity attribute exactly match a given set? - #5 by dustingetz - General - Datomic Developers [/s]