Fork me on GitHub
#datalog
<
2020-10-05
>
mauricio.szabo14:10:05

Is there a "datalog parser" that works with ClojureScript?

mauricio.szabo16:10:26

Great! Now, I though a parser would be sufficient, but maybe not... is there something that I can register "resolvers" and then query it with datalog? I'm thinking about adding datalog support for a REPL tooling I'm making, but it seems a lot of work with only a parser 😟

mauricio.szabo17:10:39

Seems like Pathom is better at writing resolvers, but I really think that using datalog would be ideal so it would be less friction on the user...

grounded_sage18:10:51

@U3Y18N0UC we are very interested in making datalog something used to build tooling and it’s one of the areas we have an active interest in with Datahike. There is already some experimental work happening in dev tooling behind the scenes. Would be happy to chat with you to see where we can make things easier for you to do this.

mauricio.szabo18:10:46

Hey, great! Can you point me in the right direction, be it a namespace, a test code, or some usage?

quoll19:10:24

So when asking about Datalog here, I take it that you’re referring to the Datomic-style query syntax, as opposed to standard Datalog?

mauricio.szabo22:10:13

Ok, so to clarify even further, this is something I'm intending to do: to transform REPL interactions into datalog queries, like so: https://gist.github.com/mauricioszabo/8e67c0ee2116f78476f058ad96f31d30 I don't know if this requires "datomic-style query syntax". I don't really need pull syntax, for example, and maybe I could vary a little bit the query format (I believe that crux does queries a little bit different).

quoll01:10:41

Just to explain the basis of my question: it was based on the fact that “Datalog syntax” looks like Prolog. So for a Datomic query that asks, “How old is Alice?” I might have:

[:find ?a
       :where
       [?e :name "Alice"]
       [?e :age ?a]
To get the same thing with traditional Datalog, we would create a rule connecting names to ages and then query for the age:
nameage(N,A) :- name(E,N), age(E,A).
?- nameage("Alice", A).

quoll01:10:55

Since the syntax of Datomic queries is just edn, then it doesn’t need lexing, and the parsing is not difficult. So I thought that perhaps you were looking to parse traditional Datalog.

quoll01:10:29

Thanks for clarifying

lilactown02:10:20

the problem with datalog is that you can embed arbitrary exprs into it - so it’s really bad for the “resolver” style of implementing

lilactown02:10:56

you can’t always statically know what the full query is

lilactown02:10:14

this is where pathom helps a lot, because it’s much stricter in its evaluation

quoll03:10:51

I’m not really a fan of Datalog as a query language. Triple-pattern style where clauses with projection are much better. That said… I don’t understand what you’re saying here. I think I can guess what a “resolver” style of implementation is, but I don’t know what you mean by “statically know that the full query is”

lilactown03:10:55

I’m basing my take on @U3Y18N0UC ‘s message: > is there something that I can register "resolvers" and then query it with datalog? this seems to be borrowing from the way in which pathom and graphql services are built, where for each attribute you have some resolver which will handle looking up the information for that attribute. Thus, in order to construct a result a GraphQL or Pathom implementation simply needs to parse the query, look up and run the resolvers in the correct order

lilactown03:10:46

it is more difficult to do this because you could get a datalog query like: [:find ?x :where [_ :attr attr] [_ attr ?x]]

grounded_sage13:10:24

@U3Y18N0UC I have asked for others to chime in which could answer your questions better.

grounded_sage13:10:48

@U051N6TTC can you provide some resources to such a query language? I am very new to this field and have little context as to what you mean here.

quoll13:10:45

The syntax usually referred to as “Datalog” here is from Datomic. It follows the same data model and semantics as Datalog, but does not adhere to Datalog syntax. SQL is also a language that has Datalog semantics, but has its own syntax. Datalog is a subset of Prolog, and the syntax is a subset of that language. You can start by looking at the Wikipedia page: https://en.wikipedia.org/wiki/Datalog There are also many university courses that introduce Datalog. One nice set of lecture notes is: https://www2.cs.duke.edu/courses/fall16/compsci516/Lectures/Lecture-21-Datalog.pdf I gave a talk on a rules engine called Naga back at the 2016 Conj. This engine talks to either Asami (shown in the talk) or Datomic, and uses a façade that is a Datalog syntax. Towards the end of the talk I demonstrated that the same program ran in both Naga and in Prolog. I didn’t show a query element to the Datalog syntax (though I had to in Prolog) because I find it less useful for querying, as it has no projection facility (that I know of?)

mauricio.szabo01:10:24

Thanks for all the answers! I'll study a little more and try to make a proof of concept of what I am thinking :)

sparkofreason14:10:14

@U051N6TTC Do you have an example of "Triple-pattern style where clauses with projection are much better"? I'm looking at applying the Datomic Datalog dialect to clara, but definitely hitting some limitations, trying to get my head around the space of querying/logic programming in general.

quoll15:10:33

Well, consider the above queries (I will change the datalog version to pure query with no rule): Pure datalog:

?- name(E, "Alice"), age(E, A).
This will return: something like: E,A = internal-42, 21. Whereas languages like Datomic will do the same query (via EAV triple patterns), but can project the result to just the variables of interest:
[:find ?a
       :where
       [?e :name "Alice"]
       [?e :age ?a]
[[21]]

quoll15:10:22

Note, when I say “triple pattern” I mean that pattern that looks like [entity attribute value] where each part of that pattern can either be an atom or a variable. This is a generalization. For datomic, it’s really a quad pattern: [entity attribute value tx] Or if you REALLY want to get into it, a 5 tuple: [entity attribute value tx assert] And then the pattern can be truncated: [entity attribute] which can be interpreted as: [entity attribute _]

quoll15:10:04

“Triple patterns” are a good generalization, because it’s an abstraction that also works on other graph databases, such as OrientDB or SPARQL databases.

sparkofreason13:10:43

Great explanation, thank you!