This is a follow-up to my previous post on datalog-equivalent queries in core.logic.
Here I present an alternate way to do the unification and join inside core.logic (without having to use clojure.set/join). It uses the the relationships / facts API in core logic, described here. First let's consider this datomic query;
In core.logic we start by defining the relationships between our 2 datasets; This mirrors the layout of the data above. The actual datapoints are defined as facts, and once we have those we can do a core.logic run* using goals with the same name as our defrels; The join is accomplished by using the same lvar (email) is both defrel goals.
Now consider a slightly more complicated query; Applying the same technique (with some more defrels) we get;
Hmm, this looks suspiciously like a victim-of-a-macro(tm), maybe something like this;
The two examples above can now be written like so;
An important point here is that we have separated the definition of the relationships, definition (loading) of the facts, and the actual running of the query.
So how does this perform for larger datasets compared to the unification / clojure.set/join described in the previous post? If we look at the time for running the query it's ~33% faster and about 12x slower than the optimal datomic/datalog query.
Follow this link for some more datalog-y queries in core.logic.