EmbASP is a framework for the integration (embedding) of Logic Programming
in external systems for generic applications.
It helps developers at designing and implementing
complex reasoning tasks by means of solvers on different platforms.
The framework can be implemented in a object-oriented programming language of choice, easing and guiding the generation of suitable libraries for the use of specific solvers on particular platforms. We currently provide a Java implementation and ready-made libraries for the embedding of the ASP (Answer Set Programming) solvers DLV, clingo and DLV2 and the PDDL (Planning Domain Definition Language) cloud solver Solver.Planning.Domains (SPD) on the Desktop platform and of DLV and SPD on the Mobile (Android™) one.
However, the framework has been designed to be easily extensible and adaptable to different solvers and platforms. It is worth to notice that solvers are invoked in different modes; for instance, SPD is invoked via a remote connection, while for the other, binaries are effectively embedded and natively executed.
The general architecture of EmbASP is depicted in the following figure: it is intended as an abstract framework to be implemented in some object-oriented programming language.
In addition, this architecture can be specialized for different platforms, logic languages and solvers.
The figure also reports general dependencies among the main modules.
The framework architecture has been designed by means of four modules: Core
,
Platforms
, Languages
, and
Systems
. In the following, we denote with "solver" a logic-based
system that is meant to be used by external application with the help of EmbASP.
The Core
module defines the basic components of the Framework.
The Handler
component mediates the communication between the Framework and
the user that can provide it with the input program(s) via the component InputProgram
,
along with any desired solver's option(s) via the component OptionDescriptor
.
A Service
component is meant for managing the chosen solver executions.
Two different execution modes can be made available: synchronous or asynchronous. While in the synchronous mode any call
to the execution of the solver is blocking (i.e., the caller waits until the reasoning task is completed), in asynchronous mode
the call is non-blocking: a Callback
component notifies the caller once
the reasoning task is completed. The result of the execution (i.e., the output of the
logic system) is handled by the Output
component, in both modes.
The Platforms
module is meant for containing what is platform-dependent;
in particular, the Handler
and Service
components from the
Core
module that should be adapted according to the platform
at hand, since they take care of practically launching solvers.
The Languages
module defines specific facilities for each
supported logic language.
The generic Mapper
component is conceived as an utility for managing input
and output via objects, if the programming language at hand permits it.
The sub-module ASP comprises components such as ASPInputProgram
that adapts
InputProgram
to the ASP case, while
AnswerSet
and AnswerSets
represent the Output
for ASP. Moreover the ASPMapper
allow the management of ASP input facts
and answer sets via objects.
Similarly, the sub-module PDDL includes PDDLInputProgram
, Action
,
Plan
and PDDLMapper
.
The Systems
module defines what is system-dependent; in particular,
the InputProgram
, Output
and OptionDescriptor
components from the Core
module should be adapted in order
to effectively interact with the solver at hand.
As mentioned above, we provide a Java implementation of the EmbASP framework.
The following figure provides some details about classes and interfaces of the implementation.
Each component in the Core
module has been implemented by
means of an homonymous class or interface.
In particular, the Handler
class collects InputProgram
and
OptionDescriptor
objects communicated by the user.
For what the asynchronous mode is concerned, the class Service
depends from
the interface Callback
, since once the reasoning service has terminated,
the result of the computation is returned back via a class Callback
.
In order to support a new platform, the Handler
and Service
components must be adapted.
As for the Android platform, we developed an AndroidHandler
that handles
the execution of an AndroidService
, which provides facilities to manage
the execution of an ASP reasoner on the Android platform.
Similarly, for the desktop platform we developed a DesktopHandler
and a
DesktopService
, which generalizes the usage of an ASP reasoner on the desktop
platform, allowing both synchronous and asynchronous execution modes.
This module includes specific classes for the management of input and output to ASP and PDDL solvers.
The Mapper
component of the Languages
module
is implemented via a Mapper
class, that allows to translate input and output
into Java objects. Such translations are guided by Java Annotations,
a form of metadata that mark Java code and provide information that is not part of the
program itself: they have no direct effect on the operation of the code they annotate.
In our setting, we make use of such feature so that it is possible to translate facts into strings and vice-versa via two custom annotations, defined according to the following syntax:
@Id (string_name)
: the target must be a class, and defines the predicate
name (in the ASP case) and the action name (in the PDDL case) the class is mapped
to;
@Param (integer_position)
: the target must be a field of a class annotated
via @Id
, and defines the term (and its position) in the atom (in the
ASP case) and in the action (in the PDDL case) the field is mapped to.
By means of the Java Reflection mechanisms, annotations are examined at runtime, and taken into account to properly define the translation.
If the classes intended for the translation are not annotated or not correctly annotated, an exception is raised.
In addition to the Mapper
, this module features two sub-modules which are
more strictly related to ASP and PDDL.
The classes DLVAnswerSets
, ClingoAnswerSets
, DLV2AnswerSets
and SPDPlan
implement specific extensions of the AnswerSets
or Plan
classes, in charge of manipulating the output of the respective
solvers.
Moreover, this module can contain classes extending OptionDescriptor
to
implement specific options of the solver at hand.
In order to use the framework in your applications you have to import it as module on Android Studio.
In the following, we describe an the actual usage of the framework by means of a running example; as a use case, we will develop a simple Android application for solving Sudoku puzzles.
The complete code of this example is freely available here. Please note that the zip file contains an Android Studio (version 2.3) project and uses the version 3.1.0 of EmbASP.
The framework features a annotation-guided mapping, offered by the ASPMapper component, for two-way translations between strings recognizable by ASP solvers and objects in the programming language at hand, directly employable within applications. By means of this feature, the ASP-based aspects can be separated from the Java coding: the programmer doesn't even necessarily need to be aware of ASP.
Let us think of a user that designed (or has been given) a proper logic program P to solve a sudoku puzzle and has also an initial schema. We assume that the initial schema is well-formed i.e. the complete schema solution exists and is unique. A possible program P is embedded in the complete example, that, coupled with a set of facts F representing the given initial schema, allows to obtain the only admissible solution.
By means of the annotation-guided mapping, the initial schema can be expressed in forms of Java objects. To this extent, we define the class Cell, aimed at representing the single cell of the sudoku schema, as follows:
@Id("cell")
public class Cell {
@Param(0)
private int row;
@Param(1)
private int column;
@Param(2)
private int value;
[...]
}
It is worth noticing how the class has been annotated by two custom annotations, defined according to the following syntax:
Thanks to these annotations the ASPMapper class will be able to map Cell objects into strings properly recognizable from the ASP solver as logic facts of the form cell(Row,Column,Value). At this point, we can create an Android Activity Component, and start deploying our sudoku application:
public class MainActivity extends AppCompatActivity {
[...]
private Handler handler;
@Override
protected void onCreate(Bundle bundle) {
handler = new AndroidHandler(getApplicationContext(), DLVAndroidService.class);
[...]
}
public void onClick(final View view){
startReasoning();
[...]
}
public void startReasoning() {
InputProgram inputProgram = new InputProgram();
for (int i = 0; i < 9; i++){
for (int j = 0; j < 9; j++)
try {
if(sudokuMatrix[i][j]!=0) {
inputProgram.addObjectInput(new Cell(i, j, sudokuMatrix[i][j]));
}
} catch (Exception e) {
// Handle Exception
}
}
handler.addProgram(inputProgram);
String sudokuEncoding = getEncodingFromResources();
handler.addProgram(new InputProgram(sudokuEncoding));
Callback callback = new MyCallback();
handler.startAsync(callback);
}
}
The class contains an Handler instance as field, that is initialized when the Activity is created as an AndroidHandler. Required parameters include the Android Context (an Android utility, needed to start an Android Service Component) and the type of AndroidService to use, in our case a DLVAndroidService.
In addiction, in order to represent an initial sudoku schema, the class features a matrix of integers as another field where position (i,j) contains the value of cell (i,j) in the initial schema; cells initially empty are represented by positions containing zero.
The method startReasoning is in charge of actually managing the reasoning: in our case, it is invoked in response to a click event that is generated when the user asks for the solution. It is firstly created an InputProgram object that is filled with Cell objects representing the initial schema, which is then provided to the handler; then it is provided with the sudoku encoding. It could be loaded, for instance, by means of an utility function that retrieves it from the Android Resources folder, which, within Android applications, is typically meant for containing images, sounds, files and resources in general.
At this point, the reasoning process can start; since for Android we provide only the asynchronous execution mode, a callback object is in charge of fetching the output when the ASP system has done.
Finally, once the computation is over, from within the callback function the output can be retrieved directly in form of Java objects. For instance, in our case an inner class MyCallback implements the interface Callback:
private class MyCallback implements Callback {
@Override
public void callback(Output o) {
if(!(o instanceof AnswerSets))
return;
AnswerSets answerSets=(AnswerSets)o;
if(answerSets.getAnswersets().isEmpty())
return;
AnswerSet as = answerSets.getAnswersets().get(0);
try {
for(Object obj:as.getAtoms()) {
Cell cell = (Cell) obj;
sudokuMatrix[cell.getRow()][cell.getColumn()] = cell.getValue();
}
} catch (Exception e) {
// Handle Exception
}
displaySolution();
}
}
The framework is released as JAR file to be used on a Desktop platform, therefore it can be easily imported and used in any Java project.
The SPD solver is invoked via an HTTP connection using JSON files as data interchange format. In order to manage them, the framework needs the json-simple library (you can download the JAR and include directly in your project or you can use Gradle or Maven)
In the following, we describe an the 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 blocks-world problem.
The complete code of this example is freely available here. Please note that the zip file contains an Eclipse (Neon) project and uses the version 3.1.0 of EmbASP.
We will make use of the annotation-guided mapping, in order to retrieve the actions constituting a PDDL plan via Java objects. To this purpose, the following classes are intended to represent possible actions that a blocks-world solution plan can feature:
@Id("pick-up")
public class PickUp {
@Param(0)
private String block;
[...]
}
@Id("put-down")
public class PutDown {
@Param(0)
private String block;
[...]
}
@Id("stack")
public class Stack {
@Param(0)
private String block1;
@Param(1)
private String block2;
[...]
}
@Id("unstack")
public class Unstack {
@Param(0)
private String block1;
@Param(1)
private String block2;
[...]
}
At this point, supposing that we are given two files defining the blocks-world domain and a problem instance, we can start deploying our application:
public class Blocksworld {
private static String domainFileName = "domain.pddl";
private static String problemFileName = "p01.pddl";;
public static void main(String[] args) {
Handler handler = new DesktopHandler(new SPDDesktopService());
final InputProgram inputProgramDomain = new PDDLInputProgram(PDDLProgramType.DOMAIN);
inputProgramDomain.addFilesPath(domainFileName);
final InputProgram inputProgramProblem = new PDDLInputProgram(PDDLProgramType.PROBLEM);
inputProgramProblem.addFilesPath(problemFileName);
handler.addProgram(inputProgramDomain);
handler.addProgram(inputProgramProblem);
try {
PDDLMapper.getInstance().registerClass(PickUp.class);
PDDLMapper.getInstance().registerClass(PutDown.class);
PDDLMapper.getInstance().registerClass(Stack.class);
PDDLMapper.getInstance().registerClass(Unstack.class);
Plan plan = (Plan)(handler.startSync());
for (final Object obj : plan.getActionsObjects())
//Manage objects as needed
} catch (Exception e) {
// Handle Exception
}
}
}
The class contains an Handler instance as field, that is initialized with a DesktopHandler using the required parameter SPDDesktopService.
Then it's set-up the input to the solver; since PDDL requires separate definitions for domain and problem, two PDDLInputProgram are created and then given to the handler.
The next lines inform the PDDLMapper about what classes are intended to map the output actions.
Finally the solver is invoked, and the output is retrieved. The output actions can be managed accordingly to the user's desiderata.
The framework is released under The MIT License (MIT)
The framework library for DLV on Android embeds the DLV system itself, which is free for academic and non-commercial educational use, as well as for use by non-profit organizations. For further information about DLV, please refer to the DLVSystem Ltd. home page.
DLVfit is a health and fitness app that monitors the user activity during the day and suggests some workout plans that depend on her age, weight, gender and goals. The app periodically stores some information about the user activities (running, walking, etc.) and infers the current amount of calories burned so far. When the user asks for a workout plan, DLVfit proposes a set of exercises that would allow the user to reach her daily goal, taking into account also to her preferences. The suggested workout plans are computed in the background by DLV via EmbASP.
The ASP program used within DLVfit can be found in the repository. Basically, the program guesses for possible fitness exercises to do in order to burn the remaing calories. Each answer set represent a possible workout plan, in which is ensured that the user's requirements about the calories to burn and the time to spend in the workout are respected. Moreover, also user's preferences are taken into account by means of weak constraints.
You can download the latest version of DLVfit here.
The app should work on most devices equipped with Android 4.x/5.x.
The
list of compatible devices include (but it is not limited to):
GuessAndCheckers is a native mobile application that works as an helper for users that play "live" games of the (Italian) checkers (i.e., by means of physical board and pieces). The app, that runs on Android, can help a player at any time: by means of the device camera a picture of the board is taken, and the information about the current status of the game is properly inferred thanks to OpenCV, an open source computer vision and machine learning software; an ASP-based artificial intelligence module then suggests the move.
Thanks to EmbASP and the use of ASP, GuessAndCheckers features a fully-declarative
approach that made easy to develop and improve several different strategies, also experimenting
with many combinations thereof.
The source code of this application along with
the Android Application Package (APK) are available online.
You can download the latest version of GuessAndCheckers here.
DLVEdu is an educational Android App for children, that integrates well-established mobile technologies, such as voice or drawn text recognition, with the modeling capabilities of ASP. In particular, it is able to guide the child throughout the learning tasks, by proposing a series of educational games, and developing a personalized educational path. The games are divided into four macro-areas: Logic, Numeric-Mathematical, Memory, and Verbal Language. The usage of ASP allows the application to adapt to the game experiences fulfilled by the user, her formative gap, and the obtained improvements.
The application continuously profiles the user by recording mistakes and successes, and dynamically builds and updates a customized educational path along the different games. The application features a "Parent Area", that allows parents to monitor child's achievements and to express some preferences, such as explicit filters of some games or educational areas.
Connect4 is an application that allows a user to play the popular Connect Four game (also
known as Four-in-a-Row) against an ASP-based artificial player.
The Connect Four
game is played by two opponents on a vertical 7*6 rectangular board. At each turn, the
players fill the board by dropping 1 disk into one of the column so that it falls from
the top to the lowest unoccupied position in the column. The winner is the first player
who gets four of her disks in a line, connected either horizontally, vertically, or diagonally.
Different AIs have been implemented, ranging from the most powerful one implementing advanced techniques for the perfect play to the simplest one relying on some classical heuristic strategies. By using EmbASP, two different versions of the same app have been built: one for Android, making use of DLV, and one for Java-enabled desktop platforms, making use of clingo.
LoIDE is a web-based IDE
for Logic Programming.
An extensive documentation can be found here.
A live beta version can be found online at https://www.mat.unical.it/calimeri/projects/loide
This online version uses the ASPServerExecutor to run the ASP solvers (using the EmbASP Framework).