=Paper= {{Paper |id=Vol-1433/tc_91 |storemode=property |title=Expressing and Supporting Efficiently Greedy Algorithms as Locally Stratified Logic Programs |pdfUrl=https://ceur-ws.org/Vol-1433/tc_91.pdf |volume=Vol-1433 |dblpUrl=https://dblp.org/rec/conf/iclp/Zaniolo15 }} ==Expressing and Supporting Efficiently Greedy Algorithms as Locally Stratified Logic Programs== https://ceur-ws.org/Vol-1433/tc_91.pdf
Technical Communications of ICLP 2015. Copyright with the Authors.                      1

    Expressing and Supporting Eciently Greedy
   Algorithms as Locally Stratied Logic Programs
                                  CARLO ZANIOLO
                           University of California, Los Angeles
                                E-mail: zaniolo@cs.ucla.edu

                       submitted 29 April 2015; accepted 5 June 2015




                                       Abstract
The problem of expressing and supporting classical greedy algorithms in Datalog has been
the focus of many signicant research eorts that have produced very interesting solutions
for particular algorithms. But we still lack a general treatment that characterizes the
relationship of greedy algorithms to non-monotonic theories and leads to asymptotically
optimal implementations. In this paper, we propose a general solution to this problem.
Our approach begins by identifying a class of locally stratied programs that subsumes
XY-stratied programs and is formally characterized using the Datalog1S representation of
numbers. Then, we propose a simple specialization of the iterated xpoint procedure that
computes eciently the perfect model for these programs, achieving optimal asymptotic
complexities for well-known greedy algorithms.This makes possible their ecient support
in Datalog systems.
KEYWORDS: Horn Clauses, Datalog, Aggregates, Greedy Algorithms.


                                   1 Introduction
Due to the emergence of many important application areas, we are now experi-
encing a major resurgence of interest in Datalog for parallel and distributed pro-
gramming (Hellerstein 2010; Abiteboul et al. 2011) (Gottlob et al. 2011; Abite-
boul et al. 2011). This include exploring parallel execution of recursive queries in
the MapReduce framework (Afrati et al. 2011) and on multicore machines (Yang
et al. 2015), and in Data Stream Management Systems (Zaniolo 2011). The abun-
dance of new applications underscores the need to tackle and solve crucial Datalog
problems that have remained open for a long timstarting with algorithms that
require aggregates in recursive rules that provided the subject of much previous
work (Zaniolo et al. 1997; Greco and Zaniolo 2001a; Mumick et al. 1990; Kolaitis
1991; Mumick and Shmueli 1995; Ross and Sagiv 1997). In this context, a major
step forward was accomplished recently with the introduction of monotonic aggre-
gates (Mazuran et al. 2013; Shkapsky et al. 2013). Monotonic aggregates, however,
cannot address the problem of formulating and supporting eciently greedy al-
gorithms, a dicult challenge that provided the focus of much previous research,
including (Greco et al. 1992; Greco and Zaniolo 1998; Greco and Zaniolo 2001b).
Their work provided a stable-model characterization for specic greedy algorithms
but did not develop a general theory and ecient solutions for such programs. In
this paper, we achieve a general solution by showing that greedy algorithms can be
2                                   Carlo Zaniolo
expressed quite naturally as locally stratied programs that are conducive to a very
ecient implementationi.e., one having the same asymptotic complexity as that
achievable using procedural languages and specialized data structures. This is a
very encouraging result, given that optimal performance is not easily achievable for
algorithms expressed in the concise and elegant formalism of declarative logic, i.e.,
without having to specify detailed operational steps and special data structures in
many pages of procedural code. Furthermore, many intractability results obtained
for locally stratied logic programs (Palopoli 1992) underscore the diculty of us-
ing them to express and support low-complexity algorithms. But in this paper we
show that there is a natural correspondence between greedy algorithm and a special
subclass of locally stratied programs, which we will call strictly stratied temporal
programs, that overcome these diculties.
  In the next section we recall the basic notions of local stratication, and iter-
ated xpoint, and then, in Section 3, we introduce a class of of programs that are
locally stratied by the temporal arguments of their predicates which subsumes
XY-stratied logic programs, and extend it by allowing more powerful logic predi-
cates expressing `>' and `+' primitives needed for greedy algorithms. In Section 4,
therefore we show that these extended programs can be expanded into equivalent
XY-stratied programs via simple rewritings dened by the arithmetic functions
they use. While this rewriting denes the formal semantics of our greedy programs,
the equivalent programs produced by the rewriting would be very inecient if im-
plemented with the standard approach used for XY-stratied programs in systems
such as LDL (Arni et al. 2003) and DeALS (Shkapsky et al. 2013; Yang et al.
             ++

2015). Therefore, we propose a modication of the Iterated Fixpoint computation
that solves this problem and actually achieves asymptotic optimality in the imple-
mentation of many greedy algorithms, which are discussed in details in Section 5.

                2 Local Stratication and Iterated Fixpoint
Let us now recall the denition of local stratication for Datalog programs where
rules have negated goals:
Denition 1. A program P is locally stratied if it is possible to partition its
Herbrand base BP into a countable number of subsets, called strata, B0 , B1 , . . . ,
such that for every r ∈ ground(P ) the stratum of the head of r is strictly higher
that the strata of its negated goals, and higher or equal to the strata of its positive
goals.
  Each locally stratied program has a unique stable model, called its perfect
model, whereby its abstract semantics has many desirable properties (Przymusinski
1988). Moreover, once the aforementioned stratication B , B , . . . is known for a
program P , then the Iterated Fixpoint procedure can be used to compute the perfect
                                                             0   1


model of P . The iterated xpoint can be dened using the immediate-consequence
operator for the rules in ground(P ) whose head is in stratum B : let T denote
the immediate consequence operator for instantiated rules belonging to the K -th
                                                                     K       K
               Greedy Algorithms as Locally Stratied Logic Programs                   3
stratum. and let T denote he inationary version to this operator dened as
T (I) =T (I) ∪ I .
                     K


   Then the iterated computation on our locally stratied program P is performed
 K         K


by starting from M = T (∅) and then continuing with M = T (M ).
                              ↑ω                                              ↑ω

   While the iterated xpoint procedure seems to provide an ecient operational
                     0        0                                     K+1       K        K


semantics for computing of the perfect model for locally stratied program, in
reality this is not the case, because of a number of problems, including the fact that
the existence of local stratication for a given program represents an undecidable
question (Palopoli 1992).
   To address these problems we will introduce the notion of programs that are lo-
cally stratied by the positive numbers that appear in a distinguished argument of
their predicates, that we call temporal argument. Thus, we propose simple syntactic
conditions that assures that (i) a local stratication exists and (ii) the actual strata
are identied quite easily. We then turn to the issue of improving the eciency
of the iterated xpoint procedure, by basically skipping over the computation of
strata that do not produce any useful result. We will thus identify simple syntac-
tic conditions that make this optimization possible, and we will show that greedy
algorithms are naturally expressed under this restricted syntax, producing declar-
ative Datalog programs that preserve the desirable complexity properties of their
procedural counterparts.
                3 Temporally Stratied Datalog1S Programs
Let us consider Datalog programs where the rst argument is a non-negative integer
represented by the successor notation: 0, s(0), s(1), . . . , s (0) described in (Chomicki
                                                            n

and Imielinski 1988). These are known as Datalog programs, and have been stud-
ied extensively in (Chomicki 1990), where the authors called the 1S argument the
                                                     1S


temporal argument, a naming convention that we will also follow in this paper. For
example consider the following program:
Example 1 (A Datalog program dening all even positive integers.)
                         1S


                             int(even, 0).
                             int(even, s(J)) ←   ¬int(even, J).

   Thus the temporal argument in our int predicate is the last one, where a positive
integer n is represented by n applications of the function symbol s to zero. We will
use the short-hand s (X) to denote the application of s to X repeated n times
                         n

s(s(. . . s(X) . . .)).
   Thus the Herbrand universe for the above program is {s (0), s (even)} where n
                                                                    n     n

denotes an arbitrary non-negative integer (under the convention that s (X) = X,    0

and thus s (even) = even).
           0

   Now, let P be a Datalog program, then the temporal layering of P is the one
obtained by assigning each atom in its Herbrand Base B to the layer n whenever
                                1S


the last argument of the atom is s (c), with c an arbitrary constant. For instance
                                                                P
                                       n

the temporal layering of the above program in Example 1 is as follows:
4                                         Carlo Zaniolo
Layer
0:   int(sn (0), 0),    int(sn (even), 0),      int(sn (0), even),    int(sn (even), even)
1: int(sn (0), s(0)), int(sn (even), s(0)), int(sn (0), s(even)), int(sn (even), s(even))
                                                  ...
k: int(sn (0), sk (0)), int(sn (even), sk (0)), int(sn (0), sk (even)), int(sn (even), sk (even))

We will focus on programs that are locally stratied according to their temporal
layering:
Denition 2 A Datalog program P will be said to be temporally stratied if P
                                1S
is locally stratied according to its temporal layering.
   Thus the program in Example 1 is temporally stratied. However, the program
in Example 2, below, it is not locally stratied, although it has the same Herbrand
base, and can be assigned the same temporal layering as Example 1:
Example 2 (A Temporally Layered Program that is not locally stratied )
                             int(even, 0).
                             int(even, J) ←       ¬int(even, s(J)).

The simple programs so far considered only use one predicate, but to express pow-
erful algorithms we need to consider programs featuring several predicates within
each given layer. For these programs, deciding whether they are locally stratied,
and determining the perfect model for those that are stratied, can be quite chal-
lenging in general. A solution is however at hand for the large class of such problems
that satises the notion of XY-stratication discussed next.
                                4 XY-Stratied Programs
Temporally stratied programs have been explored in the past. In particular, (Zan-
iolo et al. 1993) introduced XY-stratied programs that are eciently supported in
LDL   ++
          and DeALS (Shkapsky et al. 2013), (Yang et al. 2015) and were also used in
a number of advanced applications (Guzzo and Saccà 2005), (Borkar et al. 2012). A
generalized version of XY-stratication, called explicitly stratied logic programs
(Lausen et al. 1998), was then used to model active rules and other interesting
applications. Take for instance the transitive closure prgram for a graph:
Example 3 (Transitive Closure expressed in Datalog )
                               cl(X, Z) ← arc(X, Z).
                               cl(X, Z) ← cl(X, Y), arc(Y, Z).

  The dierential xpoint (a.k.a. seminaive xpoint) of this program can be ex-
pressed by the following program, where dcl is the delta version of cl.
Example 4 (Dierential rules used in computing the transitive closure of arc)
        dcl(X, Z, 0) ←       arc(X, Z).
        dcl(X, Z, J1) ←      dcl(X, Y, J), arc(Y, Z), J1 = J+1, ¬previous(X, Z, J).
        previous(X, Z, J1) ←         dcl(X, Z, J), J < J1.
              Greedy Algorithms as Locally Stratied Logic Programs                5
The above program is a Datalog program expressed by a slightly dierent notation
(Chomicki 1990). In fact, instead of representing the successor of integer J by s(J),
                                1S


we represent it here by J+1 where +1 is a postx function symbol. Therefore,
we can easily conclude that the program above is temporally layered by the last
argument (i.e., J and J1) in our predicates. However we cannot conclude that the
resulting program is locally stratied, because the denition of ground(P ) does not
prevent us from instantiating J < J1 to values where J is actually larger than J1.
This problem can be solved by a simple rewriting of the rules to explicitly dene >
using the past values of dcl kept in lower strata, which we will write as hdcl (for
historical dcl).
Example 5 (Dierential rules used in computing the transitive closure of arc)
        dcl(X, Z, 0) ←     arc(X, Z).
        dcl(X, Z, J1) ←    dcl(X, Y, J), arc(Y, Z), J1 = J+1, ¬hdcl(X, Z, J).
        hdcl(X, Z, J) ←    dcl(X, Z, J).
        hdcl(X, Z, J1) ←   hdcl(X, Z, J), J1 = J+1
   The resulting program is temporally stratied, i.e., locally stratied by the tem-
poral layering established by the last argument of its recursive predicates. Observe
that in the program above we only have two kinds of temporal arguments: J and
J+1 = J1, i.e., a variable and its immediate successors. For these programs there
is a simple test that allows us to determine if they are locally stratied. This is the
XY-stratication test that is performed by renaming the predicates in the recursive
rules that have a temporal argument, as follows: in each rule r rename with the
sux `_old' the goals having as temporal argument J when the temporal argument
in the head of r is J1 = J + 1. The program so obtained is called the bi-state version
of the original program. Then, a program P is said to be XY-stratied when its
bi-state version is stratied. XY-stratied programs are locally stratied and their
perfect model can be eciently computed using their bi-state version (Zaniolo et al.
1993). For instance, the bi-state version of the program in Example 5 is as follows:
Example 6 (The Bistate Version of Example 5)
       dcl(X, Z, 0) ←      arc(X, Z).
       dcl(X, Z, J1) ←     dcl(X, Y, J), arc(Y, Z), J1 = J+1, ¬hdcl_old(X, Z, J).
       hdcl(X, Z, J) ←     dcl(X, Z, J).
       hdcl(X, Z, J1) ← hdcl_old(X, Z, J), J1 = J+1.
We have obtained a program that is stratied (e.g., with the following strata:1:{arc},
2:{dcl_old, hdcl_old}, 3:{dcl}, 4:{hdcl}).
   Therefore, XY-stratication provides a simple test to verify that temporally lay-
ered programs are locally stratied and thus temporally stratied. As proven in
(Zaniolo et al. 1993), the perfect model of these programs can be computed as
follows (for clarity we refer to predicates without the sux `_old' as `new'):
  Perfect Model Computation for XY-stratied Programs:
  (i) use the bistate program to derive the values for the new predicates, and
 (ii) re-initializing the values of the `_old' predicates with those of the
      predicates just computed, and then the values of the `new' predicates.
6                                  Carlo Zaniolo
   These steps repeated until (i) stops producing new tuples, construct the perfect
model for our XY-stratied (and therefore temporally stratied) program. This ba-
sic procedure delivers good performance on many simple problems including the
seminaive computation of the least xpoint of Example 2, above, but a more so-
phisticated approach is needed to achieve optimal performance for logic programs
expressing greedy algorithms, since these are considerably more complex.
   To simplify the expression, and also the compilation, of greedy algorithm, we will
introduce the notation not(. . .). Thus, Example 4 can be re-expressed as follows:
Example 7 (Example 4 re-expressed using not( ) )
               dcl(X, Z, 0) ←    arc(X, Z).
               dtrcl(X, Z, J1) ← dcl(X, Y, J), arc(Y, Z), J1 = J+1,
                                 not(dcl(X, Z, K), K < J).
In general, a program with a goal `not(condition)' should be viewed as the short-
hand of the program derived by (i) replacing `not(condition)' with ¬newp(SVlist),
(where SVlist denotes the variables shared between condition and the rest of the
rule), and (ii) adding the rule: newp(SVlist) ← condition.
                             5 Greedy Algorithms
Suppose now that warc(X, Z, W) describes a directed graph where W is the positive
weight of the arc from X to Z. For now, let us assume that all such weights are
integers. Then, a greedy algorithm to nd the shortest path between node pairs is
as follows:
Example 8 (A greedy algorithm to nd shortest paths between node pairs )
             wtc(X, Z, W) ←    warc(X, Z, W).
             wtc(X, Z, Cz) ← wtc(X, Y, Cy), not(wtc(X, _, C), C < Cy),
                               warc(Y, Z, W), Cz = Cy + W.
Thus in the recursive rule, we use the not construct to nd the shortest distance
Cy from a node X to a node Y and, for each arc in warc(Y, Z, W), we add a path from
X to Z of length Cz = Cy + W. Our objective is to re-express this as an equivalent
XY-stratied program. In order to do that, we will re-write the program into the
following one, where we re-express `+' using the successor logic of Datalog .
                                                                            1S

Example 9 (A temporally stratied program to nd shortest paths between node pairs )

         wtc(X, Z, W) ←         warc(X, Z, W).
                                                             _
         succadd(X, Y, W, C1) ← wtc(X, Y, Cy), not(wtc(X, , C), C < Cy),
                                warc(Y, Z, W1), W = W1 + 1, C1 = Cy + 1.
         succadd(X, Y, W, C1) ← succadd(X, Y, W + 1, C), C1 = C + 1.
         wtc(X, Z, Cz) ←        succadd(X, Y, 0, Cz).
Thus recursive succadd rule expresses `+' by raising by 1 the value of Cy while
replacing W + 1 with W until this becomes zero: at this point the addition has been
completed, whereby Cz is the distance of Z from X. We can now expand the not(...)
goal, and nally verify that the resulting program is XY-stratied, by the rst goals
             Greedy Algorithms as Locally Stratied Logic Programs                 7
in the second and third rule as wtc_old and succadd_old, respectively. For the
rules resulting from the expansion of not(...) we proceed as in Example 4. Then
we obtain a bistate program which is stratied: therefore the original program in
Example 9 is XY-stratied and thus temporally stratied.
   A program such as that in Example 9, where the rewriting of its <, +, and not
goals produce a temporally stratied programs will be called an Implicit Temporally
Stratied (ITS) program. Now, many programs expressing greedy algorithms can be
transformed into XY-stratied programs that provide a formal semantics for such
programs, since these are known to be locally stratied. The perfect model for these
programs can also be computed using the standard bistate based computation of
XY-stratied programs, but as discussed next, this computation would fail to deliver
optimal performance for the program in Example 9 and other greedy programs.
   The obvious problem with the standard bistate-based computation of the pro-
gram in Example 9 is that in order to derive Cz = Cy + W, we go through the
computation of the W − 1 temporal strata that take us from Cy to Cz, even though
no new wtc value might be produced in step (i) and in step (ii) of the Perfect
Model Computation for XY-stratied programs discussed on page 5. In order to
bypass this sequence, we might consider jumping directly to stratum with tempo-
ral argument Cz, but that might not be correct, since the same rule that has now
produced Cz might have previously produced a value C z, Cy < C z < Cz, which
                                                         0          0

must be considered before Cz. The solution to this problem is obvious: (1) we store
the value Cz produced by the second rule into a priority queue (PQ) and then (2)
we fetch (and remove) the least value from PQ, and use it as the next value of
the temporal argument. Needless to say, our PQ is exactly the data structure used
in Dijkstra's shortest path algorithm and other greedy algorithms. Thus we can
achieve an optimal computation of our greedy algorithms by simply replacing the
+1 successor operation with a PQ store+fetch operation.
   This PQ optimization however it is is not applicable to all temporally stratied
programs and in particular to Example 1, due to the fact that the only goal in
its rules is a negated goal. To avoid this potential problem we now introduce the
notion of Strict Implicit Temporally Stratied (SITS) that assures the applicability
of the PQ optimization.
Denition 3 An ITS program will be said to be strict when every rule containing
negated goals also contains some positive goal which has a temporal argument that
is ≥ than the temporal argument of every negated goal.
   Thus this condition excludes the program in Example 1, and also disallows the
following rule that satises the standard notion of implicit temporal stratication:
             wtc(X, Z, Cz) ← wtc(X, Y, Cy), arc(Y, Z, W), Cz = Cy + W,
                                          _
                             not(wtc(X, , C), C < Cz).
The problem with this rule is that it oers no assurance that Cy ≥ C. A rule
like the one above is no problem for the iterated xpoint procedure that visits
every successive value of the temporal argument, but it cannot be supported in a
8                                  Carlo Zaniolo
computation that jumps from the current temporal argument to the next temporal
value extracted from PQ. However teh strictness condition solves this problem and
maket it possible to use the following computation:
Algorithm 1 Computation of Perfect Model for SITS Programs
         1: Initialize the priority queue (PQ) to empty.
         2: Let M := T (∅)
                        ↑ω

         3: Add the values of temporal arguments generated in step 2 to PQ.
                        0


         4: Repeat the following three steps until PQ becomes empty:
               5: Remove the least temporal argument K from (PQ) and
               6: Let M := T (M ).
                              ↑ω

               7: Add the values of the newly generated temporal arguments to PQ.
                              K




   Thefore, SITS programs can be computed eciently by a simple optimization of
the iterated xpoint algorithm that consists of skipping over unproductive values
of temporal arguments:
                              5.1 Beyond Integers
In our discussion so far, we have assumed that temporal arguments are positive
integers, but our treatment of greedy algorithms generalizes to the case in which
we have arbitrary positive numbers, not just integers, whereby arbitrary positive
weights can, e.g., be used as arc weights in our graphs. This conclusion follows
from the argument presented in (Mazuran et al. 2013) where it was observed that
non-integers could be represented as rational numbers sharing a common very large
denominator D whereby all computations can be emulated by integer arithmetics on
their numerators. Now the standard mantissa+exponent internal representation of
real and oating-point numbers, that is used in modern hardware/rmware, does
exactly thatmodulo some round-o. For instance, for a decimal oating point.
the smallest value of exponent supported might be −95 (or smaller), whereby every
number can be viewed as the numerator over the denominator D = 10 . (For sim-
                                                                        95

plicity, we have used a decimal base, but the same conclusions hold for other bases.)
Naturally, precision is limited by the fact that the mantissa is of nite length, and
thus, e.g., the operation of addition becomes a rounded-o addition. Rounded-o
addition can also be easily expressed in Datalog whereby the expanded resulting
program is still XY-stratied, and the overall formal semantics remains valid. Of
                                                 1S


course, round-o is also a concern at the operational semantics level, where it can
be addressed by the use of double precision and other techniques used when algo-
rithms are expressed in procedural languages. Once he/she selects single or double
precision, our user is assured an ecient excution for greedy algorithms owing to
the fact that the implementation will not step through each successive oating point
number, but jumps directly the next number in the PQ.
   Using oating-point numbers and real arithmetic, we can now express a cornu-
              Greedy Algorithms as Locally Stratied Logic Programs                9
copia of greedy algorithms, starting with the single-source Dijkstra algorithm shown
below.
Example 10 (Single source Dijistra's Algorithm )
                 wtc(X, W) ←  warc(a, W).
                 wtc(Z, Cz) ← wtc(Y, Cy), not(wtc(Y, C), C < Cy),
                              warc(Y, Z, W), Cz = Cy + W.
Since, ecient Datalog implementations, such as DeALS (Shkapsky et al. 2013),
use Hashing and other indexing techniques to achieve a constant-time computation
of the recursive rule above for each value of Y, an optimal performance can be
expected for the Dijistra's algorithm above, and similar observations can be made
for the other greedy algorithms which which require not special data structure other
than PQ. In particular this is true for the Traveling Salesman's Program (TSP)
discussed next, which closely emulates its procedural counterpart, thus achieving
optimal asymptotic complexity.
                  Traveling Salesman's Greedy Heuristics
Given an undirected graph, g(X, Y, Cxy), the exit rule selects an arbitrary node X,
from which to start the search. Then, the second rule selects candidate new nodes,
using the conditions Y<>a, and not(tspath(_, Y, C1), C1 < C) ensures that we do
not cycle back to the initial node ad previously derived nodes.
   Finally the third rule selects from the candidate new nodes cand(Y, C) the one
that has the shortest distance from a.
Example 11 (Travelling Salesman's starting at node a)
            tspath(a, 0) ← node(a).
            cand(Y, C) ←   tspath(X, Cx), g(X, Y, Cxy), Y<>a,
                           not(tspath(Y, C1), C1 < C), C = Cx + Cxy.
                                                    _
            tspath(Y, C) ← cand(Y, C), not(cand( , C1), C1 ≤ C).
Thus, this algorithm will work correctly under the assumption that there are no ties,
i.e., no two arcs departing from the same node have the same weight. In the situation
where there are ties, we can employ a construct such as choice (Greco et al. 1992),
which models don't care non-deterministic semantics via a special class of stable
models called choice models. Alternatively, we can fall back on the solutions used
by procedural programmers. For instance, since nodes are represented by natural
numbers, or by elements of an ordered domain, we can expand the third rule in
Example 11 as follows:
Example 12 (Extrema as tie-breaker: alternative for 3 rule in Example 11 )
                                                       rd


             tspath(minhYi, C) ← cand(Y, C), not(cand(_, C1), C1 ≤ C).

This program is SITS once we assume that the min aggregate is dened as follows:
            mtspath(Y, C) ← cand(Y, C), not(cand(_, C1), C1 < C).
          tspath(Y, C) ←     mtspath(Y, C), not(mtspath(Y, C1), C1 < C).
10                                   Carlo Zaniolo
Here the intra-layer stratication uses cand al the rst level, and mtspath at the
second level, and tspath at the top level. Thus, while the body of the second rule
eliminates the nodes having a smaller C, the aggregate in the head only retains the
rst (i.e., the smallest) Y out of those candidate nodes that share the same C.
   While the use of min or max aggregates could be all a user wants in most practical
applications, from a conceptual viewpoint we might regret the fact that we have
given up non-determinism, and we can only generate one TSP path rather than a
dierent one at each run. However, non-determinism can be recovered by a builtin
predicate, such a hash function h(_), that reorders its input nondeterministically.
Then our program becomes:
Example 13 (Using randomized hashing for non-determinstic TSP )
        tspath(a, 0) ← node(a).
        cand(Y, C) ←   tspath(X, Cx), g(X, Y, Cxy),
                       Y<>a, not(tspath(Y, C1), C1 < C), C = Cx + Cxy.
        slct(SL, C) ←                            _
                       cand(Y, C), not(cand( , C1), C1 ≤ C),
        tspath(L, C) ← slct(L, C), not(slct(L1, C), h(L) > h(L1)).
  Here the the intra-layer stratication has cand below slct which is below tspath.
  Similar techniques for breaking ties can be used in Prim's and other algorithms.
                                Prim's algorithm
We build a tree with nodes st(X, Cx) where C is a node and Cx is the cost of the tree
when X was produced. We start from a node a with cost 0. Then for the current level
C, we nd all the new nodes reachable from this or previous nodes. This provides
a set of candidates for which, in the third rule, we take the one that delivers the
least cost.
Example 14 (Prim's minimum cost spanning tree.)
               st(a, 0).
               cand(C1, Y) ← st(C, _), st(Cx, X), Cx ≤ C,
                                arc(X, Y, Cxy), Y <> a,
                                not(st(Cy, Y), Cy < C), C1 = C + Cxy.
               st(C1, Y) ←                               _
                                cand(C1, Y), not(cand(C, ), C < C1).
  Our example assumes that no two arcs have the same weight. When this is not
the case, we will use the same tie-breaking solutions used for TSP.
                               Human Encoding
Human coding is a lossless data compression algorithm. The idea is to assign
variable-length codes to input characters, with lengths of the assigned codes based
on the frequencies of corresponding characters. Frequent characters are assigned
shorter codes. The variable-length prex codes are bit sequences assigned to input
characters in such a way that no code of a character is the prex of the code of
another character.
  The input is the list of unique characters along with their frequency of occurrences
              Greedy Algorithms as Locally Stratied Logic Programs            11
and output is the Human tree. The basic algorithm is as follows. We start from a
set of facts, token(Char, Freq) which corresponds to the leaf nodes of the Human
tree. Then the algorithm can be expressed as follows:
Example 15 (Human Encoding Algorithm )
       huf(F, X, 0, 0) ←     token(X, F).
       huf(H, nil, H1, H2) ←
                      ___                        ___
             huf(H1, , , ), not(huf(H11, , , ), H11 < H1),
                      ___                                  ___
             huf(H2, , , ), H1 < H2, not(huf(H22, , , ), H22 < H2),
             H22<>H1, H = H1 + H2.
For instance, say that we have three facts: token(a, 4). token(b, 5). token
(c,10). Then the rst step consists in executing the rules whose body layer is
0: these are the exit rules, since their bodies consists of facts, which are always
viewed as belonging to zero layer. This produces the following leaf nodes in our tree
(identied by the fact that their left and right subtrees are both 0).
                 huf(4, a, 0, 0).      huf(5, b, 0, 0). huf(10, c, 0, 0)
Also as a result of this step, we have that the values 4, 5, and 10 are entered into
the priority PQ. Now, the system takes the least of these values and evaluates the
rules for that layer. The rules produce nothing at layer 4, so we move to next layer,
5 where the second rule produces:
                                    huf(9, nil, 4, 5)
Thus the system has extracted two nodes with the minimum frequency from the
min heap and generated a new node whose weight is the sum of those two.
   At this point we have only 9 in the PQ, and where no node at level below 9 is
still free the evaluation of the second rule produces nothing, but removes 9 from
the PQ. The next value in the PQ is thus 10, and the evaluation of our rule at level
10 produces:
                                 huf(19, nil, 9, 10)
At this point, the evaluation at layer 19 produces no new value, whereby the PQ
becomes empty, and the computation terminates.
                              Kruskal's Algorithm
Kruskal's algorithm also constructs a minimum spanning tree for a connected
weighted unordered graph. Thus an edge of a graph is represented by a fact edge(A, B, W)
where A < B. At each step, the algorithm selects a least-cost edge among those that
do not connect previously connected nodes. Thus, in the example below, the rst
two rules state that each node is connected to itself, starting at level 0. Then, say
that at level C we add the new edge tree(X, Y, C), connecting two nodes which,
until level C were still disconnected.
   Then, the last rule is executed that determines all the nodes X1 and Y1 respec-
tively connected with X and Y. Thus, we dene
                              mM(X, Y, X, Y) ← X < Y.
                              mM(X, Y, Y, X) ← X > Y.
12                                   Carlo Zaniolo
then we see that mM(X1, Y1, S, L) it returns S and L as respectively the smaller and
larger of these two. Then we connect to S all the nodes previously connected to L,
i.e., the Ln nodes in the last rule.
Example 16 (Kruskal's Algorithm )
  connt(X, X, 0) ←    edge(X, Y).
  connt(Y, Y, 0) ←    edge(X, Y).
  tree(X, Y, C) ←           __
                      tree( , , C), edge(X, Y, Cxy), not(connt(X, Y, C1), C1 < C),
                      C = Clast + Cxy.
  connt(S, Ln, C) ←   tree(X, Y, C), connt(X1, X, C), connt(Y, Y1, C),
                      mM(X1, Y1, S, L), connt(L, Ln, C).
   Unlike our previous algorithms, the performance of Kruskal's under our formu-
lation cannot be guaranteed to be optimal, since connectivity is not supported by
the special union-nd data structure.
                                   6 Conclusion
The non-monotonic constructs proposed in this paper introduce a simple declarative
extension for deductive databases that greatly enhances their eectiveness in a range
of applications and thus achieves the same optimal time complexity of procedural
code algorithmsassuming that these do not make use of special data structures
such as Union-Find used by Kruskal's minimum spanning tree algorithm. In fact, we
have shown that the greedy optimizations of procedural algorithms follow directly
from the need to achieve an ecient implementation for the iterated xpoint pro-
cedure of locally stratied programs. From a theoretical viewpoint, this reveals the
computational upside of non-monotonic semantics classes that in the past were pri-
marily analyzed for their intractability downside. From a practical viewpoint, these
results allow us to express and implement eciently in Datalog systems signi-
cant algorithms expressed in declarative logic, while achieving the same asymptotic
complexity as their procedural counterparts. Indeed, support for strict local strati-
cation can be easily achieved through extensions of XY-stratication, which is now
part of DeALS (Shkapsky et al. 2013),(Yang et al. 2015). The integrated support of
monotonic aggregates in recursion, greedy algorithms, and XY-stratication sup-
ported by our system entails a declarative expression and ecient implementation
of complex algorithms, and provides further evidence that this is indeed an age of
renaissance for Datalog and deductive databases.
                               Acknowledgements
The author would like to thank Alex Shkapsky, Mohan Yang, and the referees for
many suggested improvements.
              Greedy Algorithms as Locally Stratied Logic Programs                  13
                                     References
Abiteboul, S., Bienvenu, M., Galland, A., and Antoine, E. 2011.           A rule-based
 language for web data management. In PODS. 293304.
Afrati, F. N., Borkar, V. R., Carey, M. J., Polyzotis, N., and Ullman, J. D.
 2011. Map-reduce extensions and recursive queries. In EDBT. 18.
Arni, F., Ong, K., Tsur, S., Wang, H., and Zaniolo, C. 2003. The deductive database
 system ldl++. TPLP 3, 1, 6194.
Borkar, V. R., Bu, Y., Carey, M. J., Rosen, J., Polyzotis, N., Condie, T.,
 Weimer, M., and Ramakrishnan, R. 2012. Declarative systems for large-scale ma-
 chine learning. IEEE Data Eng. Bull. 35, 2, 2432.
Chomicki, J. 1990. Polynomial time query processing in temporal deductive databases. In
  Proceedings of the Ninth ACM SIGACT-SIGMOD-SIGART Symposium on Principles
  of Database Systems. PODS '90. 379391.
Chomicki, J. and Imielinski, T. 1988.      Temporal deductive databases and innite ob-
  jects. In PODS. 6173.
Gottlob, G., Orsi, G., and Pieris, A. 2011. Ontological queries: Rewriting and opti-
  mization. In ICDE. 213.
Greco, S. and Zaniolo, C. 1998. Greedy algorithms in datalog with choice and nega-
  tion. 294309.
Greco, S. and Zaniolo, C. 2001a. Greedy algorithms in datalog. TPLP 1, 4, 381407.

Greco, S. and Zaniolo, C. 2001b. Greedy algorithms in datalog. TPLP 1, 4, 381407.

Greco, S., Zaniolo, C., and Ganguly, S. 1992. Greedy by choice. In PODS. 105113.

Guzzo, A. and Saccà, D. 2005. Semi-inationary DATALOG: A declarative database
  language with procedural features. AI Commun. 18, 2, 7992.
Hellerstein, J. M. 2010. Datalog redux: experience and conjecture. In PODS. 12.

Kolaitis, P. G. 1991. The expressive power of stratied logic programs. Inf. Comput. 90,
  5066.
Lausen, G., Ludäscher, B., and May, W. 1998. On active deductive databases: The
  statelog approach. In Transactions and Change in Logic Databases. 69106.
Mazuran, M., Serra, E., and Zaniolo, C. 2013. A declarative extension of horn
  clauses, and its signicance for datalog and its applications. TPLP 13, 4-5, 609623.
Mumick, I. S., Pirahesh, H., and Ramakrishnan, R. 1990. The magic of duplicates
  and aggregates. In VLDB. 264277.
Mumick, I. S. and Shmueli, O. 1995. How expressive is stratied aggregation? Annals
  of Mathematics and Articial Intelligence 15, 407435.
Palopoli, L. 1992. Testing logic programs for local stratication. Theor. Comput.
  Sci. 103, 2, 205234.
Przymusinski, T. C. 1988. Perfect model semantics. In ICLP 1988.

Ross, K. A. and Sagiv, Y. 1997. Monotonic aggregation in deductive database. J.
  Comput. Syst. Sci. 54, 1, 7997.
Shkapsky, A., Zeng, K., and Zaniolo, C. 2013. Graph queries in a next-generation
  datalog system. PVLDB 6, 12, 12581261.
Yang, M., Shkapsky, A., and Zaniolo, C. 2015. Parallel bottom-up evaluation of logic
  programs: Deals on shared-memory multicore machines. In ICLP 2015, Cork Ireland.
Zaniolo, C. 2011. The logic of query languages for data streams. In Logic and Databases
  2011. EDBT 2011 Workshops. 12.
Zaniolo, C., Arni, N., and Ong, K. 1993. Negation and aggregates in recursive rules:
  the ldl++ approach. In DOOD. 204221.
14                                Carlo Zaniolo
Zaniolo, C., Ceri, S., Faloutsos, C., Snodgrass, R. T., Subrahmanian, V. S.,
 and Zicari, R. 1997.   Advanced Database Systems. Morgan Kaufmann.