<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Datalog on Werner&#39;s home on the Web</title>
    <link>https://wstoop.co.za/tags/datalog/</link>
    <description>Recent content in Datalog on Werner&#39;s home on the Web</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Tue, 03 Jan 2017 00:00:00 +0000</lastBuildDate><atom:link href="https://wstoop.co.za/tags/datalog/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Why Jatalog</title>
      <link>https://wstoop.co.za/posts/why-jatalog/</link>
      <pubDate>Tue, 03 Jan 2017 00:00:00 +0000</pubDate>
      
      <guid>https://wstoop.co.za/posts/why-jatalog/</guid>
      <description>&lt;p&gt;I recently posted an entry on my &lt;a href=&#34;https://wstoop.co.za/posts/jatalog/&#34;&gt;Jatalog project&lt;/a&gt;, which is a Java implementation of the Datalog deductive database system. I thought I could elaborate on why I created it.&lt;/p&gt;
&lt;p&gt;At some point in my career I was working at a department of a cell phone company that developed all sorts of software to keep the network operational. We were always wondering about ways to do Root Cause Analysis: If a network link broke down somewhere, then everything that relies on that link also fails. Being able to identify the failed link would&amp;rsquo;ve sped up the troubleshooting process immensely.&lt;/p&gt;
&lt;p&gt;Unfortunately the network was old and a lot of equipment in it was added and removed and replaced over the years so there was no complete database of exactly what equipment was in the network and how they depended on each other.&lt;/p&gt;
&lt;p&gt;It is by some coincidence that I learned of Datalog, but the concepts behind it made me think back to the root cause analysis problem, and so I was inspired to create my own Datalog implementation.&lt;/p&gt;
&lt;p&gt;Datalog on its own wouldn&amp;rsquo;t have been able to solve root cause analysis, but I imagined that it could be used track the pieces of equipment and to model the relationships between them. The Datalog queries could then be used to derive new relationships that can be processed later.&lt;/p&gt;
&lt;p&gt;Another motivation for trying to create a Datalog implementation was a series of articles by &lt;a href=&#34;https://twitter.com/Jonathan_Blow&#34;&gt;Jonathan Blow&lt;/a&gt; on &lt;a href=&#34;http://number-none.com/product/Predicate%20Logic/index.html&#34;&gt;Predicate Logic&lt;/a&gt; and the implementation of his programming language Lerp (
&lt;a href=&#34;http://number-none.com/product/Lerp,%20Part%201/index.html&#34;&gt;part 1&lt;/a&gt;,
&lt;a href=&#34;http://number-none.com/product/Lerp,%20Part%202/index.html&#34;&gt;part 2&lt;/a&gt; and
&lt;a href=&#34;http://number-none.com/product/Lerp,%20Part%203/index.html&#34;&gt;part 3&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Blow describes a computer game scripting language where predicate logic is used as a first class construct. The facts can be used to describe states in the game, like &amp;ldquo;the ogre is at the tavern&amp;rdquo;, &amp;ldquo;the ogre is carrying the sword&amp;rdquo; and then to use predicate logic to infer new facts, like &amp;ldquo;the sword is at the tavern&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I liked his ideas: I imagined a system where NPCs could have their own goals and motivations, so that the story could be more emergent on the player&amp;rsquo;s actions. As an example, the Ogre carries the sword. The ogre wants revenge on the troll. If the player fights the troll, the ogre might be willing to give his sword to the player, otherwise the ogre might go and fight the troll himself, and if the ogre loses, the troll might end up with the sword.&lt;/p&gt;
&lt;p&gt;However, I didn&amp;rsquo;t think it was necessary to implement predicate logic as a first order construct in a new programming language. It would suffice to create a Datalog implementation as a library that is exposed to an existing language.&lt;/p&gt;
&lt;p&gt;I decided to implement the Jatalog engine in Java as a proof-of-concept first. The source code is now available on &lt;a href=&#34;https://github.com/wernsey/jatalog&#34;&gt;GitHub&lt;/a&gt; under the Apache license.&lt;/p&gt;
&lt;p&gt;It took me a while to finish my implementation. Looking back on it now, the engine doesn&amp;rsquo;t feel &lt;em&gt;that&lt;/em&gt; complex, but reading the literature and understanding how to implement algorithms took up so much time.&lt;/p&gt;
&lt;p&gt;There are several open-source implementations available online, but I couldn&amp;rsquo;t find any modern implementations that has all the features of Jatalog. Stratified negation is a particularly rare feature, for example, but Jatalog wouldn&amp;rsquo;t have been complete without it.&lt;/p&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/wernsey/Jatalog/blob/master/README.md&#34;&gt;README.md&lt;/a&gt; as well as &lt;a href=&#34;https://wstoop.co.za/posts/jatalog/&#34;&gt;my previous blog entry&lt;/a&gt; contains a lot of notes about the implementation.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Jatalog: A Datalog deductive database in Java</title>
      <link>https://wstoop.co.za/posts/jatalog/</link>
      <pubDate>Mon, 02 Jan 2017 00:00:00 +0000</pubDate>
      
      <guid>https://wstoop.co.za/posts/jatalog/</guid>
      <description>&lt;p&gt;The source code for Jatalog is &lt;a href=&#34;https://github.com/wernsey/jatalog&#34;&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I originally published the article below on
&lt;a href=&#34;https://www.codeproject.com/articles/1114911/jatalog-a-datalog-deductive-database-in-java&#34;&gt;CodeProject in July 2016&lt;/a&gt;.
I&amp;rsquo;ve been meaning to republish it on my personal blog for completeness, but haven&amp;rsquo;t come around to doing it until now.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://wstoop.co.za/images/Jatalog_screenshot.png&#34; alt=&#34;Jatalog console&#34;&gt;&lt;/p&gt;
&lt;h1 id=&#34;introduction&#34;&gt;Introduction &lt;a href=&#34;#introduction&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Datalog&#34;&gt;Datalog&lt;/a&gt; is a subset of the Prolog programming language that is used as a query language in deductive databases.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/wernsey/jatalog&#34;&gt;Jatalog&lt;/a&gt; is a Datalog implementation in Java. It provides a parser for the language and an evaluation engine to execute queries that can be embedded into larger applications.&lt;/p&gt;
&lt;p&gt;In a nutshell:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The engine implements semi-naive, bottom-up evaluation.&lt;/li&gt;
&lt;li&gt;It implements stratified negation;
&lt;ul&gt;
&lt;li&gt;Technically, it implements the &lt;strong&gt;Stratified Datalog¬&lt;/strong&gt; language [ceri].&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;It can parse and evaluate Datalog programs from files and &lt;code&gt;Strings&lt;/code&gt;       (actually anything that implements &lt;code&gt;java.io.Reader&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;It has a fluent API through which it can be embedded in Java applications to run queries.&lt;/li&gt;
&lt;li&gt;It implements &lt;code&gt;&amp;quot;=&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;&amp;lt;&amp;gt;&amp;quot;&lt;/code&gt; (alternatively &lt;code&gt;&amp;quot;!=&amp;quot;&lt;/code&gt;), &lt;code&gt;&amp;quot;&amp;lt;&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;&amp;lt;=&amp;quot;&lt;/code&gt;, &lt;code&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/code&gt; and &lt;code&gt;&amp;quot;&amp;gt;=&amp;quot;&lt;/code&gt; as built-in predicates.&lt;/li&gt;
&lt;li&gt;It avoids third party dependencies.&lt;/li&gt;
&lt;li&gt;Values with &lt;code&gt;&amp;quot;quoted strings&amp;quot;&lt;/code&gt; are supported.&lt;/li&gt;
&lt;li&gt;Retract facts with the &lt;code&gt;~&lt;/code&gt; operator, for example &lt;code&gt;p(q,r)~&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The class &lt;code&gt;Shell&lt;/code&gt; implements a REPL command-line interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id=&#34;background&#34;&gt;Background &lt;a href=&#34;#background&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;A Datalog program consists of &lt;em&gt;facts&lt;/em&gt; and &lt;em&gt;rules&lt;/em&gt;. Facts describe knowledge about the world. Rules describe the relationships between facts from which new facts can be derived.&lt;/p&gt;
&lt;p&gt;The following Datalog program describes that Alice is a parent of Bob and Bob is a parent of Carol, and then provides rules for deriving an ancestor relationship from the facts: (&lt;a href=&#34;https://en.wikipedia.org/wiki/Datalog&#34;&gt;wiki&lt;/a&gt;)&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;% Facts:
parent(alice, bob).
parent(bob, carol).

% Rules:
ancestor(X, Y) :- parent(X, Y).
ancestor(X, Y) :- ancestor(X, Z), parent(Z, Y).
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Variables in Datalog are capitalized. In the example, &lt;code&gt;X&lt;/code&gt;, &lt;code&gt;Y&lt;/code&gt; and &lt;code&gt;Z&lt;/code&gt; are variables, whereas alice and bob are constants. Facts cannot contain variables; they are said to be &lt;em&gt;ground&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The collection of facts is called the &lt;em&gt;Extensional Database&lt;/em&gt; (EDB).&lt;/p&gt;
&lt;p&gt;In the fact &lt;code&gt;parent(alice, bob)&lt;/code&gt; the &lt;code&gt;parent&lt;/code&gt; is called the &lt;em&gt;predicate&lt;/em&gt;, while &lt;code&gt;alice&lt;/code&gt; and &lt;code&gt;bob&lt;/code&gt; are the &lt;em&gt;terms&lt;/em&gt;. The number of terms is called the &lt;em&gt;arity&lt;/em&gt;. The arity of &lt;code&gt;parent&lt;/code&gt; is 2 and some literature will write it as &lt;code&gt;parent/2&lt;/code&gt;. It is expected that all facts with the same predicate will have the same arity.&lt;/p&gt;
&lt;p&gt;In the example, the two facts&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;parent(alice, bob) reads &lt;em&gt;&amp;ldquo;alice is a parent of bob&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;parent(bob, carol) reads &lt;em&gt;&amp;ldquo;bob is a parent of carol&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The collection of rules is called the &lt;em&gt;Intensional Database&lt;/em&gt; (IDB).&lt;/p&gt;
&lt;p&gt;Rules consist of a &lt;em&gt;head&lt;/em&gt; and a &lt;em&gt;body&lt;/em&gt;, separated by a &lt;code&gt;:-&lt;/code&gt; symbol. The head of the rule describes a new fact that can be derived whereas the body describes how that fact should be derived.&lt;/p&gt;
&lt;p&gt;In the rule &lt;code&gt;ancestor(X, Y) :- parent(X, Y)&lt;/code&gt; the &lt;code&gt;ancestor(X, Y)&lt;/code&gt; is the head, and &lt;code&gt;parent(X, Y)&lt;/code&gt; is the body. It specifies that the fact &lt;em&gt;&amp;ldquo;X is an ancestor of Y&amp;rdquo;&lt;/em&gt; can be derived if the fact &lt;em&gt;&amp;ldquo;X is a parent of Y&amp;rdquo;&lt;/em&gt; holds true.&lt;/p&gt;
&lt;p&gt;It is also said that the body of the rule implies the head, so &lt;code&gt;parent(X, Y)&lt;/code&gt; implies &lt;code&gt;ancestor(X, Y)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The Datalog engine will use this rule to determine that &lt;em&gt;&amp;ldquo;alice is an ancestor of bob&amp;rdquo;&lt;/em&gt; and &lt;em&gt;&amp;ldquo;bob is an ancestor of carol&amp;rdquo;&lt;/em&gt; when queries are executed.&lt;/p&gt;
&lt;p&gt;The second rule &lt;code&gt;ancestor(X, Y) :- ancestor(X, Z), parent(Z, Y)&lt;/code&gt; says that the fact &lt;em&gt;&amp;ldquo;X is an ancestor of Y&amp;rdquo;&lt;/em&gt; can also be derived if there exists a &lt;code&gt;Z&lt;/code&gt; such that &lt;em&gt;&amp;ldquo;X is an ancestor of Z&amp;rdquo;&lt;/em&gt; and &lt;em&gt;&amp;ldquo;Z is a parent of Y&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Using this rule, the Datalog engine will determine that &lt;em&gt;&amp;ldquo;alice is an ancestor of carol&amp;rdquo;&lt;/em&gt; from all the other facts that have already been derived during query evaluation.&lt;/p&gt;
&lt;p&gt;Queries can be run against the database once the facts and the rules have been entered into the system:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ancestor(X, carol)?&lt;/code&gt; queries &lt;em&gt;&amp;ldquo;who are carol&amp;rsquo;s ancestors?&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ancestor(alice, Y)?&lt;/code&gt; queries &lt;em&gt;&amp;ldquo;of who is alice the ancestor?&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ancestor(alice, carol)?&lt;/code&gt; asks &lt;em&gt;&amp;ldquo;Is alice an ancestor of carol?&amp;rdquo;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Answers come in the form of a collection of the mapping of variable names to values that satisfy the query. For example, the query &lt;code&gt;ancestor(X, carol)?&lt;/code&gt;&amp;rsquo;s results will be &lt;code&gt;{X: alice}&lt;/code&gt; and &lt;code&gt;{X: bob}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Jatalog implements some built-in predicates which can be used in rules and queries: equals &lt;code&gt;&amp;quot;=&amp;quot;&lt;/code&gt;, not equals &lt;code&gt;&amp;quot;&amp;lt;&amp;gt;&amp;quot;&lt;/code&gt;, greater than &lt;code&gt;&amp;quot;&amp;gt;&amp;quot;&lt;/code&gt;, greater or equals &lt;code&gt;&amp;quot;&amp;gt;=&amp;quot;&lt;/code&gt;, less than &lt;code&gt;&amp;quot;&amp;lt;&amp;quot;&lt;/code&gt; and less or equals &lt;code&gt;&amp;quot;&amp;lt;=&amp;quot;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can have multiple clauses in a query, separated by commas. For example &lt;code&gt;sibling(A, B), A &amp;lt;&amp;gt; alice?&lt;/code&gt; asks &amp;ldquo;who are siblings of A where A is not alice?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Additionally, Jatalog&amp;rsquo;s syntax uses the &lt;code&gt;~&lt;/code&gt; symbol for retracting facts form the database. For example, the statement &lt;code&gt;planet(pluto)~&lt;/code&gt; will retract the fact that pluto is a planet. The syntax is adapted from [rack]&amp;rsquo;s, but it is unclear whether other Datalog implementations use it.&lt;/p&gt;
&lt;p&gt;The retract query can contain variables and multiple clauses: The statement &lt;code&gt;thing(N, X), X &amp;gt; 5~&lt;/code&gt; will delete all things from the database where &lt;code&gt;X&lt;/code&gt; is greater than 5.&lt;/p&gt;
&lt;h1 id=&#34;using-the-code&#34;&gt;Using the code &lt;a href=&#34;#using-the-code&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;If you want to use the Java API, you just need to add the compiled JAR to your classpath.&lt;/p&gt;
&lt;p&gt;The Main-Class in the JAR&amp;rsquo;s manifest points to &lt;code&gt;za.co.wstoop.jatalog.Shell&lt;/code&gt;, which implements the REPL interface. To start the interpreter, simply run the JAR file with the Java &lt;code&gt;-jar&lt;/code&gt; command-line option, like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;java -jar target/jatalog-0.0.1-SNAPSHOT.jar [filename]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In addition to an interpreter for the Datalog language, Jatalog also provides an API through which the database can be accessed and queried directly in Java programs.&lt;/p&gt;
&lt;p&gt;The following is an example of how the facts and the rules from above example can be written using the Fluent API:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Jatalog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jatalog&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;alice&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;bob&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;fact&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;bob&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;carol&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;rule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ancestor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;X&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;X&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Z&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ancestor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Z&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;rule&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ancestor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;X&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;parent&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;X&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Y&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The queries can then then be executed as follows:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Collection&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;answers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;answers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;query&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;expr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ancestor&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;X&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;carol&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;answers&lt;/code&gt; collection will contain a list of all the variable mappings that satisfy the query:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;{X: alice}
{X: bob}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The query from the previous example can also be written as&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;answers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;executeAll&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ancestor(X, carol)?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Jatalog also provides a &lt;code&gt;Jatalog.prepareStatement()&lt;/code&gt; method that will parse strings into Statement objects that can be executed later. The &lt;code&gt;Statement.execute()&lt;/code&gt; method takes a &lt;code&gt;Map&amp;lt;String, String&amp;gt;&lt;/code&gt; of variable bindings as a parameter, so that it can be used to do batch inserts or queries. For example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-java&#34; data-lang=&#34;java&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;Statement&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;statement&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;prepareStatement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;sibling(Me, You)?&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bindings&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;makeBindings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Me&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;bob&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Collection&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Map&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;String&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;answers&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;answers&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;statement&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;na&#34;&gt;execute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;jatalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bindings&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the above example, the variable &lt;code&gt;Me&lt;/code&gt; is bound to the value bob, so the &lt;code&gt;statement.execute(...)&lt;/code&gt; line is equivalent to executing the query &lt;code&gt;sibling(bob, You)?&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The Javadoc documentation contains more information and the unit tests in the &lt;code&gt;src/test&lt;/code&gt; directory contain some more examples.&lt;/p&gt;
&lt;h2 id=&#34;compiling-with-maven&#34;&gt;Compiling with Maven &lt;a href=&#34;#compiling-with-maven&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;The preferred method of building Jatalog is through Maven.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Compile like so:
mvn package

# Generate Javadocs
mvn javadoc:javadoc

# Run like so:
java -jar target/jatalog-0.0.1-SNAPSHOT.jar file.dl
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Where file.dl is the name of a file containing Datalog commands to be executed. It is omitted, the interpreter will enter an interactive mode where commands will be read from System.in&lt;/p&gt;
&lt;h2 id=&#34;compiling-with-ant&#34;&gt;Compiling with Ant &lt;a href=&#34;#compiling-with-ant&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;An Ant &lt;code&gt;build.xml&lt;/code&gt; file is also provided:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;# Compile like so:
ant

# Generate Javadocs
ant docs

# Run like so:
java -jar dist/jatalog-0.0.1.jar
&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&#34;points-of-interest&#34;&gt;Points of Interest &lt;a href=&#34;#points-of-interest&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;p&gt;Jatalog&amp;rsquo;s evaluation engine is &lt;em&gt;bottom-up, semi-naive with stratified negation&lt;/em&gt;. See [ceri] for more details.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Bottom-up&lt;/em&gt; means that the evaluator will start with all the known facts in the EDB and use the rules to derive new facts. It will repeat this process until no more new facts can be derived. It will then match all of the facts to the goal of the query to determine the answer (The alternative is &lt;em&gt;top-down&lt;/em&gt;, where the evaluator starts with a series of goals and use the rules and facts in the database to prove those goals).&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Semi-naive&lt;/em&gt; is an optimization of the Datalog engine wherein the evaluator will only consider a subset of the rules that may be affected by facts derived during the previous iteration, rather than all of the rules in the IDB.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Stratified negation&lt;/em&gt; means that the order in which rules are evaluated are arranged in such a way that negated goals cause sensible facts to be derived.&lt;/p&gt;
&lt;p&gt;Consider, for example, the rule &lt;code&gt;p(X) :- q(X), not r(X)&lt;/code&gt;. with the fact &lt;code&gt;q(a)&lt;/code&gt; present in the EDB, but not &lt;code&gt;r(a)&lt;/code&gt;, and suppose that there are other rules in the database that imply &lt;code&gt;p(X)&lt;/code&gt; and &lt;code&gt;r(X)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If the engine were to evaluate these rules naively then it will derive the fact &lt;code&gt;p(a)&lt;/code&gt; in the initial iteration. It is then possible that the fact &lt;code&gt;r(a)&lt;/code&gt; may be derived in a subsequent iteration, which results in the facts &lt;code&gt;p(a)&lt;/code&gt; and &lt;code&gt;r(a)&lt;/code&gt; contradicting each other.&lt;/p&gt;
&lt;p&gt;The stratified negation evaluates the rules in an order such that all the &lt;code&gt;r(X)&lt;/code&gt; facts are derived before any of the &lt;code&gt;p(X)&lt;/code&gt; facts can be derived which eliminates such contradictions.&lt;/p&gt;
&lt;p&gt;Stratified negation puts additional constraints on the usage of negated expressions in Jatalog, which the engine checks for.&lt;/p&gt;
&lt;p&gt;The above are well known optimization and evaluation techniques described in the literature. See [ceri] for a good overview. Jatalog also implements some other minor optimizations where it makes sense:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The class &lt;code&gt;StackMap&lt;/code&gt; provides a Map implementation that has a handle to a parent Map. A large part of Jatalog&amp;rsquo;s internal implementation revolves around looking up variable bindings in recursive calls in the Engine.&lt;code&gt;matchGoals()&lt;/code&gt; method. Having the StackMap eliminates the need to copy existing variable bindings into a new Map with each recursive call to &lt;code&gt;matchGoals()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The class &lt;code&gt;IndexedSet&lt;/code&gt; is a &lt;code&gt;Set&lt;/code&gt; implementation where the elements stored in it can be indexed according to some key for quick lookup. The Jatalog implementation uses it to group the facts by predicate, and find those facts quickly. It prevents iterating through the entire EDB when it already knows the predicate it is looking for.&lt;/li&gt;
&lt;li&gt;Jatalog also filters out irrelevant facts before it starts the bottom-up expansion of the database. For example, if the query is about the &lt;code&gt;ancestor&lt;/code&gt; predicate, then the bottom-up expansion does not need to expand rules relating to &lt;code&gt;employed&lt;/code&gt;. This is done through a mechanism similar to the semi-naive evaluation in the &lt;code&gt;getRelevantPredicates()&lt;/code&gt; method of the &lt;code&gt;Engine&lt;/code&gt; class.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are opportunities to run some of the methods in parallel using the Java 8 Streams API (I&amp;rsquo;m thinking of the calls to &lt;code&gt;expandStrata()&lt;/code&gt; in &lt;code&gt;expandDatabase()&lt;/code&gt; and the calls to &lt;code&gt;matchRule()&lt;/code&gt; in &lt;code&gt;expandStrata()&lt;/code&gt; in particular). This is a bit more complicated than I thought it would be, and so I&amp;rsquo;m not too concerned about implementing it at the moment.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve decided against implementing arithmetic built-in predicates, such as &lt;code&gt;plus(X,Y,Z) =&amp;gt; X + Y = Z&lt;/code&gt;, for now because they aren&amp;rsquo;t that simple. They should be evaluated as soon as the input variables (X and Y in this case) becomes available, so that &lt;code&gt;Z&lt;/code&gt; can be computed and bound for the remaining goals. It would require a more complex parser and for the &lt;code&gt;Expr&lt;/code&gt; objects to represent an abstract syntax tree.&lt;/p&gt;
&lt;p&gt;It is conceptually possible to make the &lt;code&gt;List&amp;lt;String&amp;gt;&lt;/code&gt; terms of Expr a &lt;code&gt;List&amp;lt;Object&amp;gt;&lt;/code&gt; instead, so that you can store complex Java objects in the database (as POJOs). It won&amp;rsquo;t be that useful a feature if you just use the interpreter, but it could be a nice-to-have if you use the fluent API. I don&amp;rsquo;t intend to implement it at the moment, though.&lt;/p&gt;
&lt;h1 id=&#34;references&#34;&gt;References &lt;a href=&#34;#references&#34; class=&#34;anchor&#34;&gt;🔗&lt;/a&gt;&lt;/h1&gt;&lt;ul&gt;
&lt;li&gt;Wikipedia topic, &lt;a href=&#34;http://en.wikipedia.org/wiki/Datalog&#34;&gt;http://en.wikipedia.org/wiki/Datalog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[elma] Fundamentals of Database Systems (3rd Edition); Ramez Elmasri, Shamkant Navathe&lt;/li&gt;
&lt;li&gt;[ceri] What You Always Wanted to Know About Datalog (And Never Dared to Ask); Stefano Ceri, Georg Gottlob, and Letizia Tanca&lt;/li&gt;
&lt;li&gt;[bra1] Deductive Databases and Logic Programming; Stefan Brass, Univ. Halle, 2009 &lt;a href=&#34;http://dbs.informatik.uni-halle.de/Lehre/LP09/c6_botup.pdf&#34;&gt;http://dbs.informatik.uni-halle.de/Lehre/LP09/c6_botup.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[banc] An Amateur’s Introduction to Recursive Query Processing Strategies; Francois Bancilhon, Raghu Ramakrishnan&lt;/li&gt;
&lt;li&gt;[mixu] mixu/datalog.js; Mikito Takada, &lt;a href=&#34;https://github.com/mixu/datalog.js&#34;&gt;https://github.com/mixu/datalog.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[kett] bottom-up-datalog-js; Frederic Kettelhoit &lt;a href=&#34;http://fkettelhoit.github.io/bottom-up-datalog-js/docs/dl.html&#34;&gt;http://fkettelhoit.github.io/bottom-up-datalog-js/docs/dl.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[davi] Inference in Datalog; Ernest Davis, &lt;a href=&#34;http://cs.nyu.edu/faculty/davise/ai/datalog.html&#34;&gt;http://cs.nyu.edu/faculty/davise/ai/datalog.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[gree] Datalog and Recursive Query Processing; Todd J. Green, Shan Shan Huang, Boon Thau Loo and Wenchao Zhou Foundations and Trends in Databases Vol. 5, No. 2 (2012) 105-195, 2013 &lt;a href=&#34;http://blogs.evergreen.edu/sosw/files/2014/04/Green-Vol5-DBS-017.pdf&#34;&gt;http://blogs.evergreen.edu/sosw/files/2014/04/Green-Vol5-DBS-017.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[bra2] Bottom-Up Query Evaluation in Extended Deductive Databases, Stefan Brass, 1996 &lt;a href=&#34;https://www.deutsche-digitale-bibliothek.de/binary/4ENXEC32EMXHKP7IRB6OKPBWSGJV5JMJ/full/1.pdf&#34;&gt;https://www.deutsche-digitale-bibliothek.de/binary/4ENXEC32EMXHKP7IRB6OKPBWSGJV5JMJ/full/1.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[sund] Datalog Evaluation Algorithms, Dr. Raj Sunderraman, 1998 &lt;a href=&#34;http://tinman.cs.gsu.edu/~raj/8710/f98/alg.html&#34;&gt;http://tinman.cs.gsu.edu/~raj/8710/f98/alg.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[ull1] Lecture notes: Datalog Rules Programs Negation; Jeffrey D. Ullman; &lt;a href=&#34;http://infolab.stanford.edu/~ullman/cs345notes/cs345-1.ppt&#34;&gt;http://infolab.stanford.edu/~ullman/cs345notes/cs345-1.ppt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[ull2] Lecture notes: Datalog Logical Rules Recursion; Jeffrey D. Ullman; &lt;a href=&#34;http://infolab.stanford.edu/~ullman/dscb/pslides/dlog.ppt&#34;&gt;http://infolab.stanford.edu/~ullman/dscb/pslides/dlog.ppt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[meye] Prolog in Python, Chris Meyers, &lt;a href=&#34;http://www.openbookproject.net/py4fun/prolog/intro.html&#34;&gt;http://www.openbookproject.net/py4fun/prolog/intro.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[alec] G53RDB Theory of Relational Databases Lecture 14; Natasha Alechina; &lt;a href=&#34;http://www.cs.nott.ac.uk/~psznza/G53RDB07/rdb14.pdf&#34;&gt;http://www.cs.nott.ac.uk/~psznza/G53RDB07/rdb14.pdf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[rack] Datalog: Deductive Database Programming, Jay McCarthy, &lt;a href=&#34;https://docs.racket-lang.org/datalog/&#34;&gt;https://docs.racket-lang.org/datalog/&lt;/a&gt; (Datalog library for the Racket language)&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
  </channel>
</rss>
