The Action Plugin and Action Addon Framework


HEX-programs with Action Atoms: The Project
The Team
Download
Publications



HEX-programs with Action Atoms: The Project



Introduction

This dlvhex Plugin provides an implementation of the ActHEX language [1].

The plugin allows the execution of external actions, via the introduction of Action Atoms, that can appear in rules' head.

Actions can execute any arbitrary code, access to web sites, execute scripts in any language, update databases etc.

Intuitively, ActHEX programs extend HEX programs allowing rules like:

#robot[move,D]{b, T}[2 : 1] :- direction(D), time(T).

the above can be seen as a rule for scheduling a movement of a given robot indirection D with execution order T. Action Atoms are executed according to Execution Schedules. The latter in turn depend on answer sets, which in their generalized form, can contain Action Atoms. The order of execution within a schedule can be specified using a Precedence attribute (which in the above rule is set by the variable T); also actions can be associated with Weights and Levels (the values 2 and 1 above). Weights and Levels are used for computing a cost function which helps in selecting preferred actions, as defined here. Action Atoms allow to specify whether they have to be executed bravely (the b switch above), cautiously or preferred cautiously, respectively meaning that an action atom a can get executed if it appears in at least one, all, or all best cost Answer Sets.

Specific action can be programmed the ActionAddon framework. An ActionAddon is a shared library that provides all the facilities for realising custom action executions.

If you designed a nice ActionAddon, tell us.


Installation

You can access the current source of the ActionPlugin here. For putting ActHEX programs at work, you will need dlvhex installed in your system (you can download it from here. Once the ActionPlugin and dlvhex are compiled and installed, you will be able to execute your ActHEX programs simply typing dlvhex --action-enable myprogram from command line. ActionAddons libraries already developed can be found in the Download section.

For any issue, you might want to contact our research group.

In the next section we introduce the principle of ActionAddons and Action Atoms and we give a short hands-on example.


The Action Atom Function

Formally, an Action Atom is executed depending on the following parameters:
  • Input list
  • Action option
  • Action precedence
  • Action weight
  • Action level

For instance, the action atom to control a toy robot can have this form:

#robot[move,left]{b,2}[3:1]

where move stands for a parameter string denoting the type of action, left stands for a string denoting the direction of the action, b represents that brave reasoning will be used to determine whether the action will be executed or not, 2 denotes the action precedence, 3 and 1 are the action weight and level.

Types of Input Parameters

Input parameters can freely represent constants and predicate names: action functions have full access to the answer set that triggered execution, thus enabling access to relational inferred knowledge.


How to write your own Action Addon

An interface (ActionPluginInterface) make possible the creation of Addons for ActionPlugin.

The creation of Addons is extremely simple and fast.

Each Addon has (and can customize in a very simple way) an Environment, it is shared between the Action Atoms and the External Atoms of the same Addon, it also retains its state during various iterations.

In addition, each Addon can include an arbitrary number of Action Atoms, External Atoms, BestModel Selectors, Execution Schedule Builders and through some functions the creator of the Addon can specify which of these use.

To begin with, the following header file from dlvhex needs to be included:

    #include "acthex/ActionPluginInterface.h"

If the ActionPlugin was installed correctly, this header should be available.

We have to extend the class ActionPluginInterface:

    class SmartRobotActionPlugin : public ActionPluginInterface

And we have to override the protected virtual function create:

    virtual ActionPluginInterfacePtr create(ProgramCtx& ctx)

With something like:

    ctx.getPluginEnvironment<SmartRobotActionPlugin>();
   
    return boost::shared_ptr <SmartRobotActionPlugin> (new SmartRobotActionPlugin());

Define an External Atom

To specify an External Atom we have to extend the class PluginActionAtom and we have to use as template our class that extends the ActionPluginInterface:

    class SmartRobotActionAtomGetPosition :
            public PluginActionAtom <SmartRobotActionPlugin> {
    public:

And we have to override the protected virtual function retrieve:

    virtual void retrieve(const Environment& e, const Query& q, Answer& a)

Registering the External Atoms

So far, we described the implementation of a specific External Atom. In order to integrate one or more External Atom in the interface framework, the Addon author needs to override the method createAtoms:

    virtual std::vector<PluginAtomPtr> createAtoms(ProgramCtx& ctx) const

With something like:

    std::vector <PluginAtomPtr> ret;
    ret.push_back(PluginAtomPtr(new SmartRobotActionAtomGetPosition,
                                PluginPtrDeleter<PluginAtom>()));
    return ret;

Define an Action Atom

To specify an Action Atom we have to extend the class PluginAction and we have to use as template our class that extends the ActionPluginInterface:

    class SmartRobotAction :
            public PluginActionAtom <SmartRobotActionPlugin> {
    public:

And we have to override the protected virtual function execute:

    virtual void execute(Environment& e, RegistryPtr r, const Tuple& t,
                          const InterpretationConstPtr i)

Registering the Action Atoms

So far, we described the implementation of a specific Action Atom. In order to integrate one or more Action Atom in the interface framework, the Addon author needs to override the method createActions:

    virtual std::vector<PluginActionBasePtr> createActions(ProgramCtx& ctx) const

With something like:

    std::vector <PluginActionBasePtr> ret;
    ret.push_back(PluginActionBasePtr(new SmartRobotAction,
                                        PluginPtrDeleter<PluginActionBase>()));
    return ret;

Define the Environment

To specify the Environment we have to extend the class PluginEnvironment:

    class Environment : public PluginEnvironment {
    public:

Importing the Action Addon

To make the ActionAddon available, we need to instantiate it. The simplest way to do this is to define a global variable:

    SmartRobotActionPlugin theSmartRobotActionPlugin;

Eventually, we need to import the ActionAddon to action plugin. This is achieved by the dynamic linking mechanism of shared libraries. The author needs to define this function:

    extern "C" void * PLUGINIMPORTFUNCTION() {
        return reinterpret_cast<void*>(& DLVHEX_NAMESPACE theSmartRobotActionPlugin);
    }

Template to build an Action Addon

We provide a template toolkit for building action addons based on the GNU Autotools (http://sourceware.org/autobook/) environment. This means that you will need the respective tools installed on your system - which is usually no problem, since they are provided as packages by all major linux distributions. For instance in Debian, you need the packages libtool, automake1.9, and autoconf.

After downloading and extracting the toolkit skeleton, the user can customize the top-level configure.ac to her own needs regarding dependencies on other packages. This file contains invocations of the Autoconf macros that test the system features your package needs or can use. There are two source-directory in this template. One is src and other is include, where Makefile.am sets the name of the library and its sourcefiles. The user has to take care of referencing them in the top-level Makefile.am. Calling ./bootstrap in the top-level directory creates the configure file. Subsequently calling ./configure and make install installs the shared library. If no further arguments are given to configure, the addon will be installed into the system-wide plugin-directory (specified by the package configuration file lib/pkgconfig/dlvhex.pc of the devel-package). To install the addon into ~/.dlvhex/plugins, run ./configure --enable-userinstall.

Some sample action addons can be found in Download Section.


Examples

An Example of Observe-Think-Act Cycle with ActHEX Programs

New features of version 2.0 [2]

Iterator

Iterators allow to repeat at will the execution of an ActHEX specification.
We call an Iteration the evaluation of a given ActHEX program and the execution of the corresponding action schedule.
The Environment construct (see below) allows to easily carry information from an iteration to another.

The behavior of the iteration process is controlled by means of an Iteration variable.
The default value of Iteration is "NO ITERATION" meaning that we won't do any iteration namely the evaluation/execution of Action Atoms will be performed only one time.
The user can modify this default behavior in 3 different ways:

  • from a command line option
  • by changing some built-in constant values (that override the behavior specified from command line)
  • by entailing the truth of specific built-in action predicates (#acthexContinue, #acthexStop).

For more informations see here.

Environment

The Environment is a class that every Addon can use (each has its own Environment) as a knowledge base. The Environment can be read by External Atoms, and its state can be changed by means of Action atoms. Environments contents are preserved from one iteration to another, when a sequence of calls to an ActHEX specification is programmed by means of Iterators.
Having this space, jointly with the possibilities offered by Iterators is very important for an Addon because it allows to store information, process this information and then change its behavior in subsequent iterations.

BestModel Selector

When an action schedule has to be built, the user can select which Answer Set to use among those that are Best Models by specifying a BestModel Selector.

To specify a BestModel Selector we have to extend the class BestModelSelector:

    class BestModelSelector {
    public:
        BestModelSelector(std::string name) : name(name) { }

And we have to override the public virtual function getBestModel:

    virtual void getBestModel(ActionPluginCtxData::BestModelsContainer::const_iterator&,
                              const ActionPluginCtxData::BestModelsContainer&)

In order to integrate one or more BestModel Selector in the interface framework, the Addon author needs to override the method getAllBestModelSelectors:

    virtual std::vector<BestModelSelectorPtr> getAllBestModelSelectors() const

With something like:

    std::vector<BestModelSelectorPtr> allBestModelSelectors;
   
    return allBestModelSelectors;

The user can select which BestModel Selector to adopt by changing the value of the Built-in Variable #acthexBestModelSelector, and must be set to the name of the BestModel Selector of choice.
For example: #acthexBestModelSelector = bestModelSelector1.

Execution Schedule Builder

The user can select the order of execution of Actions with the same Precedence by specifying a Execution Schedule Builder.

To specify a Execution Schedule Builder we have to extend the class ExecutionScheduleBuilder:

    class ExecutionScheduleBuilder {
    public:
        ExecutionScheduleBuilder(std::string name) : name(name) { }

And we have to override the public virtual function rewrite:

    virtual void rewrite(const std::multimap<int, Tuple> &,
                         std::list< std::set<Tuple> > &, const InterpretationConstPtr)

In order to integrate one or more Execution Schedule Builder in the interface framework, the Addon author needs to override the method getAllExecutionScheduleBuilders:

    virtual std::vector<ExecutionScheduleBuilderPtr> getAllExecutionScheduleBuilders() const

With something like:

    std::vector<ExecutionScheduleBuilderPtr> allExecutionScheduleBuilders;
   
    return allExecutionScheduleBuilders;

The user can select which Execution Schedule Builder to adopt by changing the value of the Built-in Variable #acthexExecutionScheduleBuilder, and must be set to the name of the Execution Schedule Builder of choice. For example: #acthexExecutionScheduleBuilder = executionScheduleBuilder1.



Team


  • Selen Basol
  • Ozan Erdem
  • Michael Fink
  • Giovambattista Ianni
  • Stefano Germano
  • Thomas Krennwallner
  • Christoph Redl
  • Peter Schüller


Download


Action Plugin

Action Addons


Publications


[1] S. Basol, O. Erdem, M. Fink, G. Ianni. "HEX Programs with Action Atoms." In ICLP (Technical Communications), pp. 24-33. 2010. [PDF]
[2] M. Fink, S. Germano, G. Ianni, C. Redl, P. Schüller. "ActHEX: Implementing HEX Programs with Action Atoms." In Logic Programming and Nonmonotonic Reasoning, pp. 317-322. Springer Berlin Heidelberg, 2013. [PDF]


Last edited 2013-09-27

 

General
dlvhex source code @ github.com
Description-Of-A-Project

Popular Plugins
Action Plugin
DecisionDiagrams Plugin
Description Logics Plugin
Description Logics Lite Plugin
MELD: Belief Merging Plugin
Nested HEX Plugin
MCSIE Plugin
String Plugin
dlvhex-semweb Project

Documentation
User Guide
README
doxygen
Writing Plugins in C++
Writing Plugins in Python