<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Differential Datalog</article-title>
      </title-group>
      <fpage>56</fpage>
      <lpage>67</lpage>
      <abstract>
        <p>Many real-world applications based on deductive databases require incrementally updating output relations (tables) in response to changes to input relations. To make such applications easier to implement we have created Differential Datalog (DDlog), a dialect of Datalog that automates incremental computation. A DDlog programmer writes traditional, non-incremental Datalog programs. However, the execution model of DDlog is fully incremental : at runtime DDlog programs receive streams of changes to the input relations (insertions or deletions) and produce streams of corresponding changes to derived relations. The DDlog compiler translates DDlog programs to Differential Dataflow (DD) [17] programs; DD provides an incremental execution engine supporting all the relational operators, including fixed-point. The DDlog language is targeted for system builders. In consequence, the language emphasizes usability, by providing a rich type system, a powerful expression language, a module system, including string manipulation, arithmetic, and integration with C, Rust, and Java. The code is open-source, available using an MIT permissive license [1].</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>-</title>
      <p>
        Motivation. Many real-world applications must update their output in response
to input changes. Consider, for example, a cluster management system such as
Kubernetes [
        <xref ref-type="bibr" rid="ref11">11</xref>
        ], that configures cluster nodes to execute a user-defined workload.
As the workload changes, e.g., container instances are added or removed from the
system, the configuration must change accordingly. In a large cluster computing
configuration from scratch is prohibitively expensive. Instead, modern cluster
management systems, including Kubernetes, apply changes incrementally, only
updating state effected by the change.
      </p>
      <p>
        As another example, program analysis frameworks like Doop [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ] evaluate a set
of rules defined over the abstract syntax tree of the program. Such an analyzer
can be integrated into an IDE to alert the developer as soon as a potential bug
is introduced in the program. This requires re-evaluating the rules after every
few keystrokes. In order to achieve interactive performance when working with
very large code bases, the re-evaluation must occur incrementally, preserving as
much as possible intermediate results computed at earlier iterations.
      </p>
      <p>Incremental algorithms tend to be significantly more complex than their
nonincremental versions. An incremental algorithm must propagate input changes
to the output via all intermediate computation steps. This, in turn, requires (1)
maintaining intermediate computation results for each step, and (2)
implementing an incremental version of each operation, which, given an update to its input,
computes an update to its output. Incremental computations that operate on
relational state are ubiquitous throughout systems management software stacks.
The complexity of the incremental algorithms greatly impacts the development
cost, feature velocity, maintainability, and performance of the control systems.</p>
      <p>We argue that, instead of dealing with the complexity of incremental
computation on a case-by-case basis, developers should embrace programming tools
that solve the problem once and for all. In this paper we present one such tool
— Differential Datalog (DDlog) — a programming language that automates
incremental computation. A DDlog programmer only has to write a Datalog
specification for the original (non-incremental) problem. From this description
the DDlog compiler generates an efficient incremental implementation.
Overview. DDlog is a bottom-up, incremental, in-memory, typed Datalog engine
for building embedded deductive databases.</p>
      <p>Bottom-up: DDlog starts from a set of ground facts (provided by the user)
and computes all possible derived facts by following Datalog rules, in a
bottomup fashion. (In contrast, top-down engines are optimized to answer individual
user queries without computing all possible facts ahead of time.)</p>
      <p>Incremental: whenever presented with changes to the ground facts, DDlog
only performs the minimum computation necessary to compute all changes in
the derived facts. This has significant performance benefits, and only produces
output of minimum size, also reducing communication requirements. DDlog
evaluation is always incremental ; non-incremental (traditional) evaluation can be
implemented as a special case, starting from empty relations.</p>
      <p>In-memory: DDlog stores and processes data in memory1. At the moment,
DDlog keeps all the data in the memory of a single machine2.</p>
      <p>
        Typed: Pure Datalog does not have concepts like data types, arithmetic,
strings or functions. To facilitate writing of safe, maintainable, and concise code,
DDlog extends Datalog with:
– A powerful type system, including Booleans, unlimited precision integers,
bit-vectors, strings, tuples, and Haskell-style tagged unions.
– Standard integer and bit-vector arithmetic.
– A simple functional language containing functions that allows expressing
many computations over these data-types in DDlog without resorting to
external functions.
– String operations, including string concatenation and interpolation.
– The ability to store and manipulate sets, vectors, and maps as first-class
values in relations, including performing aggregations.
1 In a typical use case, a DDlog program is used in conjunction with a persistent
database; database records are fed to DDlog as inputs and the derived facts computed
by DDlog are written back to the database; DDlog does not include a storage engine.
2 The core engine of DDlog is differential dataflow [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ], which supports distributed
computation over partitioned data; we may add this capability in the future.
      </p>
      <p>C2</p>
      <p>C1</p>
      <p>C3
Input changes</p>
      <p>Datalog
program</p>
      <p>C4</p>
      <p>C5
Output
changes</p>
      <p>Embedded: while DDlog programs can be run interactively via a command
line interface, the primary use case is to run DDlog in the same address space with
an application that requires deductive database functionality. A DDlog program
is compiled into a Rust library that can be linked against a Rust, C/C++ or
Java program (bindings for other languages can be easily added).</p>
      <p>
        DDlog is an open-source project, hosted on github [
        <xref ref-type="bibr" rid="ref1">1</xref>
        ] using an MIT-license.
2
      </p>
    </sec>
    <sec id="sec-2">
      <title>Differential Datalog (DDlog)</title>
      <p>A DDlog program operates on typed relations. The programmer defines a set of
rules to compute a set of output relations based on input relations (Figure 1).
Rules are evaluated incrementally: given a set of changes to the input relations
(insertions or deletions), DDlog produces a set of changes to the output relations
(expressed also as insertions or deletions).</p>
      <p>
        Here we give a brief overview of the language; the DDlog language
reference [
        <xref ref-type="bibr" rid="ref22">22</xref>
        ] and tutorial [
        <xref ref-type="bibr" rid="ref23">23</xref>
        ] provide a detailed presentation of language features.
2.1
      </p>
      <sec id="sec-2-1">
        <title>Type system.</title>
        <p>DDlog is a statically-checked, strongly-typed language; users specify types for
relations, variables, functions, but often DDlog can infer types from the
context. The type system is inspired by Haskell, and supports a rich set of types.
Base types include Booleans, bit-strings (e.g., bit&lt;32&gt;), infinite-precision
integers (bigint), and UTF-8 strings. Derived types are tuples, structures, and
tagged unions (which generalize enumerated types). We currently do not allow
defining recursive types like lists or trees; however DDlog contains three
builtin collection types: maps, sets, and arrays (described in Section 2.4). Figure 2
shows several type declarations.</p>
        <p>Generic types are supported; type variables are syntactically distinguished
by a tick: ’A. The language contains a built-in reference type Ref&lt;’T&gt;. Unlike
other languages, two references are equal if the objects referred are equal; thus
references do not alter the nature of Datalog. References can be used to reduce
memory consumption when complex objects are stored in multiple relations.
// A tagged - union type
typedef IPAddress = IPv4Address { ipv4addr : bit &lt;32 &gt;}
| IPv6Address { ipv6addr : bit &lt;128 &gt;}
// A generic option type
typedef Option &lt;’A &gt; = None</p>
        <p>| Some { value : ’A}
typedef OptionalIPAddress = Option &lt; IPAddress &gt;</p>
        <p>Relations are strongly typed; the value in each column must have a
staticallydetermined type. There are three kinds of relations in DDlog:
Input relations: the content of these relations is provided by the environment,
in an incremental way.</p>
        <p>Output relations: these are computed by the DDlog program, and the DDlog
runtime will inform the environment of changes in these relations.
Intermediate relations: these are also computed by the DDlog program, but
they are hidden from the environment.</p>
        <p>Figure 3 shows three relation declarations. An input relation may declare an
optional primary key — which is a set of columns that can be used to delete
entries efficiently by specifying only the key.</p>
        <p>DDlog rules are composed of standard Datalog operators: joins, antijoins, and
unions, illustrated in Figure 3, as well as aggregation, and flatmap, discussed in
Section 2.4. DDlog allows recursive rules with stratified negation: intuitively, a
DDlog relation cannot recursively depend on its own negation.
2.3</p>
      </sec>
      <sec id="sec-2-2">
        <title>Computations in rules.</title>
        <p>Much of DDlog’s power stems from its ability to perform complex computation
inside rules. For example, the rule in Figure 4 computes an inner join of height
input relation Height ( object_id : int , height : int )
input relation Width ( object_id : int , width : int )
output relation Area ( object_id : int , area : int )
// Compute the area of an object as the product of
// its height and width .</p>
        <p>Area ( oid , area ) :- Height ( oid , h), Width ( oid , w),</p>
        <p>var area = w * h.
// Alternative syntax for defining the same relation .
for o in Height // o is a tuple with fields ( object_id , height )
for o1 in Width if o1 . oid == o. oid</p>
        <p>Area (o. oid , o1 . width * o. height )
and width tables on the object id column, and then computes the area of the
object as the product of its height and width.</p>
        <p>The DDlog expression language supports arithmetic, string manipulation,
control flow constructs and function calls.</p>
        <p>
          Local variables. Local variables are used to store intermediate results of
computations. In DDlog, local variables can be introduced in three different contexts:
(1) variables can be defined directly in the body of a rule, e.g., the area variable
in Figure 4; (2) a variable can be defined in a match pattern, as in Figure 5; and
(3) finally, a variable can be defined inside an expression, e.g., the res variable
in Figure 6. A variable is visible within the syntactic scope where it was defined.
“Imperative” rule syntax. We have also defined an alternative syntax for rules,
inspired by the FLWOR syntax of XQuery expressions [
          <xref ref-type="bibr" rid="ref4">4</xref>
          ]. The “imperative”
fragment offers several statements: skip (does nothing), for, if, match, block
statements (enclosed in braces), and variable definitions var...in. An example
is shown in Figure 4. This language is essentially a language of monoid
comprehensions [
          <xref ref-type="bibr" rid="ref7">7</xref>
          ], so it is easily converted to a traditional Datalog representation
using a syntax-directed translation in the compiler front-end. Recursive relations
cannot be expressed using this syntax.
        </p>
        <p>Integers. The integer types (bigint and bit&lt;N&gt;) provide the standard
arithmetic operations, as well as bit-wise operations, bit selection v[15:8], shifting,
and concatenation.</p>
        <p>Strings All primitive types contain built-in conversions to strings, and users
can implement string conversion functions for user-defined types (like Java’s
toString() method). Expressions enclosed within ${...} in a string literal are
function lastByte (a: OptionalIPAddress ): bit &lt;8 &gt; = {
match (a) {</p>
        <p>None -&gt; 0,
Some { IPv4Address {. ipv4addr = addr }} -&gt; addr [7:0] ,</p>
        <p>Some { IPv6Address {. ipv6addr = addr }} -&gt; addr [7:0]
}
relation Host ( address : OptionalIPAddress )
// Rule that performs matching on address structure
IPv6Addr ( addr ) :- Host (. address = Some { IPv6Address { addr }}).
interpolated : they are evaluated at run-time, converted to strings and
substituted; this is a feature inspired by JavaScript; for example "x+y=${x+y}".
Pattern matching. DDlog borrows the match expression from ML and Haskell;
a match expression simultaneously performs pattern-matching against type
constructors or values, and also can bind values. Figure 5 shows a match
expression that uses a nested pattern to extract a byte from a value a with type
OptionalIPAddress (this type was defined in Figure 2). For example, the last
case binds the addr variable to the value of the ipv6addr field.</p>
        <p>Pattern matching can also be used directly in the body of a rule, as in the last
line from Figure 5, which extracts only IPv6 addresses from the Host relation
and binds their value to the addr variable, which in turn is used in the left-hand
side of the rule defining IPv6Addr relation.</p>
        <p>Functions. DDlog functions encapsulate pure (side-effect-free) computations.
Example functions are lastByte from Figure 5, and concat from Figure 6.
Recursive functions are not supported. Users and libraries can declare prototypes
of extern functions, which must be implemented outside of DDlog (e.g., in Rust),
and linked against the DDlog program at link time. The compiler assumes that
extern functions are pure.
2.4</p>
      </sec>
      <sec id="sec-2-3">
        <title>Collections</title>
        <p>The DDlog standard library contains three built-in generic collection types
(implemented natively in Rust): Vec&lt;’T&gt;, Set&lt;’T&gt; and Map&lt;’K, ’V&gt;. Values of
these types can be stored as first-class values within relations. Equality for values
of these types is defined element-wise. In theory such types are not necessary,
since collections within relations can be represented using separate relations.
We have introduced them into the language because many practical applications
have data models that contain nested collections; by supporting collection-valued
columns natively in DDlog we can more easily interface with such applications,
};
res
// declare external function returning a vector of strings
extern function split (s: string , sep : string ): Vec &lt; string &gt;
// DDlog function to concatenate all elements of a vector
function concat (s: Vec &lt; string &gt;, sep : string ): string = {
var res = "";
for (e in s) {
res = ( if ( res != "") ( res + sep ) else res ) + e</p>
        <p>// last value is function evaluation result
input relation Phrases (p: string )
relation Words (w: string )
// Words contains all words that appear in some phrase
Words (w) :- Phrases (p), var w = FlatMap ( split (p , "␣" )).
// Shortest path between each pair of points x , y
// (x , y) is the key for grouping
// min is the function used to aggregate data in each group
ShortestPath (x , y , min_cost ) :- Path (x , y , cost ),</p>
        <p>var min_cost = Aggregate ((x , y), min ( cost )).
without the need to write glue code to convert collections back and forth into
separate relations using foreign keys.</p>
        <p>Figure 6 shows the declaration in DDlog of an external function which splits a
string into substrings using a separator; this function returns a vector of strings.</p>
        <p>for loops can be used to iterate over elements in collections. Figure 6 shows
an implementation of the function concat, the inverse of split, which uses a
loop.</p>
        <p>The FlatMap operator can be used to flatten a collection into a set of DDlog
records, as illustrated in the definition of relation Words in Figure 6.</p>
        <p>The Aggregate operator can be used to evaluate the equivalent of SQL
groupby-aggregate queries. The aggregate operator has two arguments: a key
function, and an aggregation function. The aggregation function receives a group
of records that share the same key. The ShortestPath relation in Figure 6 is
computed using aggregation.
2.5</p>
      </sec>
      <sec id="sec-2-4">
        <title>Module system</title>
        <p>DDlog offers a simple module system, inspired by Haskell and Python, which
allows importing definitions (types, functions, relations) from multiple files. The
user can add imported definitions directly into the name space of the
importing module or keep them in a separate name space to prevent name
collisions. Similar to Java packages, module names are hierarchical and the module
name hierarchy must match the paths on the the filesystem where modules are
stored. The directive import library.module will load the module from file
library/module.dl.</p>
        <p>The DDlog standard library is a module containing a growing collection of
useful functions and data structures: some generic functions and data-types, such
as min, string manipulation and conversion to strings, functions to manipulate
vectors, sets, maps (insertion, deletion, lookup, etc.).
3
3.1</p>
      </sec>
    </sec>
    <sec id="sec-3">
      <title>DDlog Implementation</title>
      <sec id="sec-3-1">
        <title>Compiling DDlog to Differential Dataflow</title>
        <p>
          Differential Dataflow. The core execution engine of DDlog is Differential Dataflow
(DD). Differential Dataflow [
          <xref ref-type="bibr" rid="ref17">17</xref>
          ] is a streaming big-data processing system which
provides incremental (differential) computation. DD is an incremental
mapreduce-like system, but supporting a wide set of relational operators, including
recursion (fixed-point) and joins. Section 4.3 in [
          <xref ref-type="bibr" rid="ref17">17</xref>
          ] describes the core relational
operators that are used by our compiler to implement DDlog operators. DD is
described in several publications [
          <xref ref-type="bibr" rid="ref17 ref20">20, 17</xref>
          ] and has an open-source implementation
with online documentation [
          <xref ref-type="bibr" rid="ref15 ref16">16, 15</xref>
          ].
        </p>
        <p>
          Compilation. Figure 7 shows how DDlog programs are compiled. The DDlog
compiler is written in Haskell. The compiler generates Rust code (as text files);
the Rust code is compiled and linked with the open-source Rust version of the DD
library [
          <xref ref-type="bibr" rid="ref14">14</xref>
          ]. The DD engine operates on multisets, where elements can have
positive or negative cardinalities; to get a set semantics we need to apply distinct
operators on some multisets, in particular, output collections.
        </p>
        <p>The DDLog compiler performs parsing, type inference, validation, and
several optimization steps. In order to compute incremental results the DD runtime
has to maintain temporal indexes (indexed by logical time), containing
previous versions of relations. Many of our optimizations are geared towards
reducing memory consumption; for example, we attempt to share indexes between
multiple collections and operators. We use reference counting for large values,
but stack-based implementations for small values. The non-linear operators (like
distinct) can be very expensive, so we try to minimize their usage. The
compiler attempts reuse common prefixes of disjoint rules.</p>
        <p>The output of the DDlog compiler is a dataflow graph, which may contain
cycles (introduced by recursion). The nodes of the graph represent relations;
the relations are computed by dataflow relational operators. Edges connect each
operator to its input and output relations. DD natively implements the following
operators: map, filter, distinct, join, antijoin, groupby, union, aggregation, and
flatmap. Each operator has a highly optimized implementation, incorporating
temporal indexes that track updates to each relation over time and allow efficient
incremental evaluation. The DD library is responsible for executing the emitted
dataflow graph across many cores by running a user-defined number of worker
threads.</p>
        <p>DDLog
program</p>
        <p>DDLog
compiler</p>
        <p>Rust
program</p>
        <p>Rust
compiler
Differential
dataflow
library
Transactional API. The interaction with a running DDlog program is done
through a transactional API. At any time only one transaction can be
outstanding. After starting a transaction the user can insert and delete any number of
tuples from input relations. When attempting to commit a transaction all
updates are applied atomically and changes to all output relations are produced.
Users register an upcall to be notified of these changes.</p>
        <p>The DDlog API is implemented in Rust, with bindings available for other
languages, currently C and Java.</p>
        <p>The command-line interface. For every DDlog program the compiler generates
a library that exports the transactional API, which can be invoked from Rust
or other languages. The compiler also generates a command-line interface
program (CLI) that allows users to interact with the DDlog program directly via
a command line or a script. The CLI allows users to start transactions, insert
or delete tuples in input relations, commit transactions, dump the contents of
relations, and get statistics about resource consumption. The CLI is also used
for regression testing and debugging.
4</p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>Applications</title>
      <p>
        Controller for Virtual Networks. The most significant DDlog program we have
written so far is a reimplementation of OVN [
        <xref ref-type="bibr" rid="ref21">21</xref>
        ] – a production-grade virtual
network controller used to implement the network substrate for cloud
management systems.
      </p>
      <p>OVN translates a set of network management policies into OpenFlow rules
that have to be installed on the virtual switches in the network. The logic is very
complicated, comprising tens of input, output and intermediate relations.</p>
      <p>The original program was written in C, and is not fully incremental. The
DDlog implementation has about 6000 lines of code, about the same size as the
original code base, but it is fully incremental. With the exception of a small
number of library functions imported from C, we were able to implement the
entire OVN logic in DDlog. This would not be feasible with a more traditional
dialect of Datalog that does not support types and expressions.</p>
      <p>5000
4000
)sm3000
(
iem2000
t
1000
600
500
)s400
(em300
itm200
100</p>
      <p>DDlog
Java
DDlog
Java
Firewall management. We have re-implemented a proprietary network
management application in DDlog. The application manages a firewall in a network of
switches and virtual machines (VMs). The firewall is driven by a centralized
policy; when the policy changes, the local rules have to be updated in all network
devices. The core of this program is a graph reachability problem in a directed
graph, which is a recursive query written in a few lines of DDlog.</p>
      <p>We compare the performance of the DDlog implementation (blue lines) with a
production-ready hand-written incremental Java program, which has been
heavily optimized (pink lines). The Java program has several thousands lines of code.
The graphs are synthetic network topologies; the average node degree is 2.
Fig. 8. DDlog performance as a function of the graph size. (1) the time taken to execute
the non-incremental reachability computation (inserting all nodes and edges in a single
transaction); (2) the peak memory consumption; (3) the time to insert an additional
12% edges into the graph, and (4) the time to delete 3% of the edges.</p>
    </sec>
    <sec id="sec-5">
      <title>Related work</title>
      <p>
        A survey of Datalog engines can be found in [
        <xref ref-type="bibr" rid="ref13">13</xref>
        ]. Here we focus on incremental
evaluation; a survey of incremental evaluation is [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ]. Notable algorithms include
Delete-Rederive [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ], FOIES [
        <xref ref-type="bibr" rid="ref6">6</xref>
        ]. Saha [
        <xref ref-type="bibr" rid="ref24">24</xref>
        ] provides an algorithm for tabled logic
programs. The Backward-Forward algorithm [
        <xref ref-type="bibr" rid="ref19">19</xref>
        ] improves DRed under some
circumstances. IncA [
        <xref ref-type="bibr" rid="ref25 ref26">25, 26</xref>
        ] is a Datalog dialect for incremental program analysis;
it introduces the DRedL algorithm. Another class of algorithms use provenance
to perform incremental computation [
        <xref ref-type="bibr" rid="ref12">12</xref>
        ]. Several recent paper describe systems
that use incremental evaluation for relational computation models: [
        <xref ref-type="bibr" rid="ref2 ref27">2, 27</xref>
        ].
      </p>
      <p>
        The only other incremental Datalog engine that we are aware of is a LogiQL [
        <xref ref-type="bibr" rid="ref8">8</xref>
        ],
a commercial product of LogicBlox [
        <xref ref-type="bibr" rid="ref3">3</xref>
        ]. Unfortunately there is no published data
about the performance of the LogicBlox incremental engine.
      </p>
      <p>
        DDlog is built on top of Differential Dataflow [
        <xref ref-type="bibr" rid="ref14">14</xref>
        ]; several declarative
incremental query engines generalizing Datalog were built on top of Differential
Dataflo [
        <xref ref-type="bibr" rid="ref17 ref20">20, 17</xref>
        ]. Some of the DDlog features were inspired by .Net LINQ [
        <xref ref-type="bibr" rid="ref18">18</xref>
        ].
6
      </p>
    </sec>
    <sec id="sec-6">
      <title>Conclusion and future work</title>
      <p>DDlog is a young project. The language is evolving quickly, driven by the use
cases. We place paramount importance on language usability; this is why we
have enhanced Datalog with many non-traditional constructs. Our goal is to
reduce as much as possible the need to transition between multiple languages
when writing large projects.</p>
      <p>Our ongoing work on DDlog focuses on continuous improvement of its
performance and memory utilization, as well as use-case-driven evolution of its syntax,
features, and libraries. We welcome any contributions or users!</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          1.
          <string-name>
            <given-names>Differential</given-names>
            <surname>Datalog</surname>
          </string-name>
          . https://github.com/ryzhyk/differential-datalog.
          <source>Retrieved December</source>
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          2.
          <string-name>
            <given-names>Y.</given-names>
            <surname>Ahmad</surname>
          </string-name>
          ,
          <string-name>
            <given-names>O.</given-names>
            <surname>Kennedy</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Koch</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Nikolic</surname>
          </string-name>
          . DBtoaster:
          <article-title>Higher-order delta processing for dynamic, frequently fresh views</article-title>
          .
          <source>Proceedings of the VLDB Endowment</source>
          ,
          <volume>5</volume>
          (
          <issue>10</issue>
          ):
          <fpage>968</fpage>
          -
          <lpage>979</lpage>
          ,
          <year>2012</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          3.
          <string-name>
            <given-names>M.</given-names>
            <surname>Aref</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            ten
            <surname>Cate</surname>
          </string-name>
          , T. J.
          <string-name>
            <surname>Green</surname>
            ,
            <given-names>B.</given-names>
          </string-name>
          <string-name>
            <surname>Kimelfeld</surname>
            ,
            <given-names>D.</given-names>
          </string-name>
          <string-name>
            <surname>Olteanu</surname>
            , E. Pasalic,
            <given-names>T. L.</given-names>
          </string-name>
          <string-name>
            <surname>Veldhuizen</surname>
            , and
            <given-names>G.</given-names>
          </string-name>
          <string-name>
            <surname>Washburn</surname>
          </string-name>
          .
          <article-title>Design and implementation of the LogicBlox system</article-title>
          .
          <source>In International Conf. on Management of Data (SIGMOD)</source>
          , pages
          <fpage>1371</fpage>
          -
          <lpage>1382</lpage>
          ,
          <year>2015</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          4.
          <string-name>
            <given-names>S.</given-names>
            <surname>Boag</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Chamberlin</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. F.</given-names>
            <surname>Fernández</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Florescu</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Robie</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Siméon</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Ştefănescu</surname>
          </string-name>
          .
          <source>XQuery 1</source>
          .0:
          <string-name>
            <surname>An</surname>
            <given-names>XML</given-names>
          </string-name>
          <article-title>query language</article-title>
          . http://www.w3.org/TR/ xquery,
          <year>2002</year>
          . Retrieved March
          <year>2019</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          5.
          <string-name>
            <given-names>M.</given-names>
            <surname>Bravenboer</surname>
          </string-name>
          and
          <string-name>
            <given-names>Y.</given-names>
            <surname>Smaragdakis</surname>
          </string-name>
          .
          <article-title>Strictly declarative specification of sophisticated points-to analyses</article-title>
          .
          <source>In Conference on Object Oriented Programming Systems Languages and Applications (OOPSLA)</source>
          , pages
          <fpage>243</fpage>
          -
          <lpage>262</lpage>
          ,
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          6.
          <string-name>
            <given-names>G.</given-names>
            <surname>Dong</surname>
          </string-name>
          and
          <string-name>
            <given-names>J.</given-names>
            <surname>Su</surname>
          </string-name>
          .
          <article-title>First-order incremental evaluation of Datalog queries</article-title>
          .
          <source>In Database Programming Languages (DBPL)</source>
          , pages
          <fpage>295</fpage>
          -
          <lpage>308</lpage>
          . London, UK,
          <year>1994</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          7.
          <string-name>
            <given-names>L.</given-names>
            <surname>Fegaras</surname>
          </string-name>
          and
          <string-name>
            <given-names>D.</given-names>
            <surname>Maier</surname>
          </string-name>
          .
          <article-title>Towards an effective calculus for object query languages</article-title>
          .
          <source>In ACM SIGMOD Record</source>
          , volume
          <volume>24</volume>
          , pages
          <fpage>47</fpage>
          -
          <lpage>58</lpage>
          . ACM,
          <year>1995</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          8.
          <string-name>
            <given-names>T. J.</given-names>
            <surname>Green</surname>
          </string-name>
          .
          <article-title>LogiQL: A declarative language for enterprise applications</article-title>
          .
          <source>In Symposium on Principles of Database Systems (PODS)</source>
          , pages
          <fpage>59</fpage>
          -
          <lpage>64</lpage>
          ,
          <year>2015</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          9.
          <string-name>
            <given-names>A.</given-names>
            <surname>Gupta</surname>
          </string-name>
          and
          <string-name>
            <given-names>I. S.</given-names>
            <surname>Mumick</surname>
          </string-name>
          .
          <article-title>Maintenance of materialized views: Problems, techniques, and applications</article-title>
          .
          <source>IEEE Data Eng. Bull</source>
          ,
          <volume>18</volume>
          (
          <issue>2</issue>
          ):
          <fpage>3</fpage>
          -
          <lpage>18</lpage>
          ,
          <year>1995</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          10.
          <string-name>
            <given-names>A.</given-names>
            <surname>Gupta</surname>
          </string-name>
          ,
          <string-name>
            <given-names>I. S.</given-names>
            <surname>Mumick</surname>
          </string-name>
          , and
          <string-name>
            <given-names>V. S.</given-names>
            <surname>Subrahmanian</surname>
          </string-name>
          .
          <article-title>Maintaining views incrementally</article-title>
          .
          <source>In International Conf. on Management of Data (SIGMOD)</source>
          , pages
          <fpage>157</fpage>
          -
          <lpage>166</lpage>
          ,
          <year>1993</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref11">
        <mixed-citation>
          11.
          <string-name>
            <surname>Kubernetes</surname>
          </string-name>
          .
          <article-title>Production-grade container orchestration</article-title>
          . https://kubernetes.io/.
        </mixed-citation>
      </ref>
      <ref id="ref12">
        <mixed-citation>
          12.
          <string-name>
            <surname>M. Liu</surname>
            ,
            <given-names>N. E.</given-names>
          </string-name>
          <string-name>
            <surname>Taylor</surname>
            , W. Zhou,
            <given-names>Z. G.</given-names>
          </string-name>
          <string-name>
            <surname>Ives</surname>
            , and
            <given-names>B. T.</given-names>
          </string-name>
          <string-name>
            <surname>Loo</surname>
          </string-name>
          .
          <article-title>Recursive computation of regions and connectivity in networks</article-title>
          .
          <source>In International Conference on Data Engineering (ICDE)</source>
          , pages
          <fpage>1108</fpage>
          -
          <lpage>1119</lpage>
          , Shanghai, China,
          <volume>29</volume>
          <fpage>March</fpage>
          -2
          <source>April</source>
          <year>2009</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref13">
        <mixed-citation>
          13.
          <string-name>
            <given-names>D.</given-names>
            <surname>Maier</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K. T.</given-names>
            <surname>Tekle</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Kifer</surname>
          </string-name>
          , and
          <string-name>
            <given-names>D. S.</given-names>
            <surname>Warren</surname>
          </string-name>
          .
          <article-title>Datalog: Concepts, history, and outlook</article-title>
          . In M. Kifer and
          <string-name>
            <surname>Y. A</surname>
          </string-name>
          . Liu, editors,
          <source>Declarative Logic Programming</source>
          .
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref14">
        <mixed-citation>
          14.
          <string-name>
            <given-names>F.</given-names>
            <surname>McSherry. Differential Dataflow</surname>
          </string-name>
          . https://github.com/TimelyDataflow/ differential-dataflow,
          <source>Retrieved January</source>
          <year>2019</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref15">
        <mixed-citation>
          15.
          <string-name>
            <given-names>F.</given-names>
            <surname>McSherry.</surname>
          </string-name>
          <article-title>Differential Dataflow API reference</article-title>
          . https://docs.rs/ differential-dataflow/0.8.0/differential_dataflow,
          <source>Retrieved March</source>
          <year>2019</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref16">
        <mixed-citation>
          16.
          <string-name>
            <given-names>F.</given-names>
            <surname>McSherry. Differential</surname>
          </string-name>
          <article-title>Dataflow documentation</article-title>
          . https://timelydataflow. github.io/differential-dataflow,
          <source>Retrieved March</source>
          <year>2019</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref17">
        <mixed-citation>
          17.
          <string-name>
            <given-names>F.</given-names>
            <surname>McSherry</surname>
          </string-name>
          ,
          <string-name>
            <given-names>D.</given-names>
            <surname>Murray</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Isaacs</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Isard.</surname>
          </string-name>
          <article-title>Differential Dataflow</article-title>
          .
          <source>In Conference on Innovative Data Systems Research (CIDR)</source>
          ,
          <year>January 2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref18">
        <mixed-citation>
          18. E. Meijer,
          <string-name>
            <given-names>W.</given-names>
            <surname>Schulte</surname>
          </string-name>
          , and
          <string-name>
            <given-names>G.</given-names>
            <surname>Bierman</surname>
          </string-name>
          .
          <article-title>Unifying tables, objects and documents</article-title>
          .
          <source>In International Workshop on Declarative Programming in the Context of ObjectOriented Languages (DPCOOL)</source>
          , Uppsala, Sweden,
          <year>August</year>
          25
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref19">
        <mixed-citation>
          19.
          <string-name>
            <given-names>B.</given-names>
            <surname>Motik</surname>
          </string-name>
          ,
          <string-name>
            <given-names>Y.</given-names>
            <surname>Nenov</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Piro</surname>
          </string-name>
          ,
          <string-name>
            <surname>and I. Horrocks.</surname>
          </string-name>
          <article-title>Incremental update of Datalog materialisation: The backward/forward algorithm</article-title>
          .
          <source>In AAAI Conference on Artifficial Intelligence (AAAI)</source>
          , pages
          <fpage>1560</fpage>
          -
          <lpage>1569</lpage>
          , Austin, TX, January
          <volume>25</volume>
          -30
          <year>2015</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref20">
        <mixed-citation>
          20.
          <string-name>
            <given-names>D. G.</given-names>
            <surname>Murray</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>McSherry</surname>
          </string-name>
          ,
          <string-name>
            <given-names>R.</given-names>
            <surname>Isaacs</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Isard</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Barham</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Abadi</surname>
          </string-name>
          .
          <article-title>Naiad: A timely dataflow system</article-title>
          .
          <source>In ACM Symposium on Operating Systems Principles (SOSP)</source>
          , pages
          <fpage>439</fpage>
          -
          <lpage>455</lpage>
          , Farminton, Pennsylvania,
          <year>2013</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref21">
        <mixed-citation>
          21. OVN.
          <article-title>Open Virtual Network architecture</article-title>
          . http://www.openvswitch.org/ support/dist-docs/ovn-architecture.7.html,
          <source>Retrieved March</source>
          <year>2019</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref22">
        <mixed-citation>
          22.
          <string-name>
            <given-names>L.</given-names>
            <surname>Ryzhyk</surname>
          </string-name>
          and
          <string-name>
            <given-names>M.</given-names>
            <surname>Budiu. Differential</surname>
          </string-name>
          <article-title>Datalog (DDLog) language reference</article-title>
          . https://github.com/ryzhyk/differential-datalog/blob/master/doc/ language_reference/language_reference.md.
          <source>Retrieved December</source>
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref23">
        <mixed-citation>
          23.
          <string-name>
            <given-names>L.</given-names>
            <surname>Ryzhyk</surname>
          </string-name>
          and
          <string-name>
            <given-names>M.</given-names>
            <surname>Budiu</surname>
          </string-name>
          .
          <article-title>A differential Datalog (DDLog) tutorial</article-title>
          . https://github.com/ryzhyk/differential-datalog/blob/master/doc/ tutorial/tutorial.md.
          <source>Retrieved December</source>
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref24">
        <mixed-citation>
          24.
          <string-name>
            <given-names>D.</given-names>
            <surname>Saha</surname>
          </string-name>
          and
          <string-name>
            <given-names>C. R.</given-names>
            <surname>Ramakrishnan</surname>
          </string-name>
          .
          <article-title>Incremental evaluation of tabled logic programs</article-title>
          .
          <source>In International Conference on Logic Programming (ICLP)</source>
          , pages
          <fpage>392</fpage>
          -
          <lpage>406</lpage>
          ,
          <year>2003</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref25">
        <mixed-citation>
          25. T. Szabó, G. Bergmann,
          <string-name>
            <given-names>S.</given-names>
            <surname>Erdweg</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Voelter</surname>
          </string-name>
          .
          <article-title>Incrementalizing latticebased program analyses in Datalog</article-title>
          . In
          <string-name>
            <surname>Object-Oriented</surname>
            <given-names>Programming</given-names>
          </string-name>
          ,
          <source>Systems, Languages and Applications (OOPSLA)</source>
          , Boston, MA, Oct.
          <year>2018</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref26">
        <mixed-citation>
          26.
          <string-name>
            <given-names>T.</given-names>
            <surname>Szabó</surname>
          </string-name>
          ,
          <string-name>
            <given-names>S.</given-names>
            <surname>Erdweg</surname>
          </string-name>
          , and
          <string-name>
            <given-names>M.</given-names>
            <surname>Voelter</surname>
          </string-name>
          .
          <article-title>IncA: A DSL for the definition of incremental program analyses</article-title>
          .
          <source>In International Conference on Automated Software Engineering (ASE)</source>
          , pages
          <fpage>320</fpage>
          -
          <lpage>331</lpage>
          ,
          <year>2016</year>
          .
        </mixed-citation>
      </ref>
      <ref id="ref27">
        <mixed-citation>
          27.
          <string-name>
            <given-names>W.</given-names>
            <surname>Zhao</surname>
          </string-name>
          ,
          <string-name>
            <given-names>F.</given-names>
            <surname>Rusu</surname>
          </string-name>
          ,
          <string-name>
            <given-names>B.</given-names>
            <surname>Dong</surname>
          </string-name>
          ,
          <string-name>
            <given-names>K.</given-names>
            <surname>Wu</surname>
          </string-name>
          , and
          <string-name>
            <given-names>P.</given-names>
            <surname>Nugent</surname>
          </string-name>
          .
          <article-title>Incremental view maintenance over array data</article-title>
          .
          <source>In ACM International Conference on Management of Data (ICMD)</source>
          , pages
          <fpage>139</fpage>
          -
          <lpage>154</lpage>
          . ACM,
          <year>2017</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>