The framework is released as EGG file to be used on a Desktop platform, therefore it can be easily installed in a Python installation.
The framework needs ANTLR4 library for its operation.
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 solve the shortest-path problem.
The complete code of this example is freely available here.
We will make use of the annotation-guided mapping, in order to create Python object constituting ASP predicates.
To this purpose, the following classes are intended to represent possible predicates that an ASP program can use:
class Edge(Predicate):
predicate_name = "edge"
def __init__(self, source=None, destination=None, weight=None):
Predicate.__init__(self, [("source"),("destination"),("weight")])
self.source = source
self.destination = destination
self.weight = weight
[...]
class Path(Predicate):
predicate_name = "path"
def __init__(self, source=None, destination=None, weight=None):
Predicate.__init__(self, [("source"),("destination"),("weight")])
self.source = source
self.destination = destination
self.weight = weight
[...]
At this point, supposing that we have embedded the DLV2 solver in this project, we can start deploying our application:
def getEdges():
edges = []
edges.append(Edge(0,1,1))
edges.append(Edge(0,2,4))
edges.append(Edge(1,2,2))
edges.append(Edge(1,3,4))
edges.append(Edge(1,4,1))
edges.append(Edge(2,4,4))
edges.append(Edge(3,5,6))
edges.append(Edge(3,6,1))
edges.append(Edge(4,3,1))
edges.append(Edge(6,4,5))
edges.append(Edge(6,5,9))
edges.append(Edge(6,7,1))
edges.append(Edge(7,5,2))
return edges
try:
handler = DesktopHandler(DLV2DesktopService("../../executable/dlv2"))
ASPMapper.get_instance().register_class(Edge)
ASPMapper.get_instance().register_class(Path)
inputProgram = ASPInputProgram()
source = 0 # source node
destination = 7 # destination node
rules = "source(" + str(self.source) + "). destination(" + str(self.destination) + ")."
rules += "path(X,Y,W) | notPath(X,Y,W) :- source(X), edge(X,Y,W)."
rules += "path(X,Y,W) | notPath(X,Y,W) :- path(_,X,_), edge(X,Y,W), not to(X)."
rules += "visited(X) :- path(_,X,_)."
rules += ":- destination(X), not visited(X)."
rules += ":~ path(X,Y,W). [W@1 ,X,Y]"
inputProgram.add_program(rules)
inputProgram.add_objects_input(self.getEdges())
handler.add_program(inputProgram)
answerSets = handler.start_sync()
for answerSet in answerSets.get_optimal_answer_sets():
path = [] # edges in the shortest path (unsorted)
sum_ = 0 # total weight of the path
for obj in answerSet.get_atoms():
if isinstance(obj, Path):
path.append(obj)
sum_ += int(obj.get_weight())
sortedPath = [] # edges in the shortest path (sorted)
join(source, path, sortedPath) # sorts the edges
show(sortedPath, sum_) # shows the path
except Exception as e:
print(str(e))
The class contains an Handler
instance as field, that is initialized with a DesktopHandler
using the parameter DLV2DesktopService
with a string representing the path to the DLV2 local solver.
The ASPMapper
registers the classes created before in order to manage the input and output objects.
A string and a list of Edge
representing facts, rules and constraints of the ASP program are added to an ASPInputProgram
, and the ASPInputProgram
is added to the Handler
.
Finally the solver is invoked, and the output is retrieved.
The output predicates can be managed accordingly to the user's desiderata. In this example the Path
predicates, that represent the shortest path, are collected, sorted, and printed as well as the total weight of the path.
For further information, contact embasp@mat.unical.it or visit our website.