Transitive Closure Datalog Theoretic

Getting started

The framework is released as WHL file to be used on a Desktop platform, therefore it can be easily installed via pip.

The framework needs ANTLR4 library for its operation.

Using EmbASP

In the following, we describe an actual usage of the framework by means of a running example; as a use case, we will develop a simple Desktop application to compute the transitive closure of a graph.

The complete code of this example is freely available here.

../_images/transitive_closure.png

We will make use of the annotation-guided mapping, in order to create Theoretic object constituting Datalog predicates.

To this purpose, the following classes are intended to represent possible predicates that a Datalog program can use:

class Edge(Predicate):
    predicate_name = "edge"

    def __init__(self, source=None, destination=None):
        Predicate.__init__(self, [("source"),("destination")])
        self.source = source
        self.destination = destination

    [...]
class Path(Predicate):
    predicate_name = "path"

    def __init__(self, source=None, destination=None, weight=None):
        Predicate.__init__(self, [("source"),("destination")])
        self.source = source
        self.destination = destination

    [...]

At this point, supposing that we have embedded the IDLV Datalog engine in this project, we can start deploying our application:

def test_find_reachable_nodes(self):
  try:
      input = DatalogInputProgram()
      handler = DesktopHandler(IDLVDesktopService("executable/idlv"))
      DatalogMapper.get_instance().register_class(Path)
      input.add_program("path(X,Y) :- edge(X,Y).")
      input.add_program("path(X,Y) :- path(X,Z), path(Z,Y). ")
      handler.add_program(input)

      input.add_object_input(Edge(1,2))
      input.add_object_input(Edge(2,3))
      input.add_object_input(Edge(2,4))
      input.add_object_input(Edge(3,5))
      input.add_object_input(Edge(5,6))

      minimalModels = handler.start_sync()

      for o in minimalModels.get_minimal_models().pop().get_atoms_as_objectset():
          if isinstance(o, Path):
              print(o.__str__())

  except Exception as e:
      print(str(e))

The main method contains an Handler instance, that is initialized with a DesktopHandler using the parameter IDLVDesktopService with a string representing the path to the IDLV local grounder.

The DatalogMapper registers the classes created before in order to manage the input and output objects.

A string and a list of Edge objects representing facts, rules and constraints of the Datalog program are added to an DatalogInputProgram, and the DatalogInputProgram is added to the Handler.

Finally the solver is invoked, and the output is retrieved.

In this example the Path predicates, represent all the arcs in the transitive closure of the starting graph. The output predicates can be managed accordingly to the user’s desiderata, as they are simply objects.

For further information, contact embasp@mat.unical.it or visit our website.