Coala is a python tool that translates BC into ASP facts. For earlier versions for other action language see Legacy. If you found a bug or would like to leave a comment, please write an email to christian.schulz-hanke( at )cs.uni-potsdam.de

Content

Features

Coala features the following options:

  • Translation BC into ASP facts
  • Using large numeric domains for fluents
  • A Script for cleaning up the clingo output
  • A Script for incremental solving
  • Encodings for the following
    • Printing States of the BC Program
    • Printing possible Transitions of the BC Program
    • Generating Plans given an initial State, goal fluent-assignments and a number of steps
    • Incrementally generating Plans given an initial State, goal fluent-assignments
    • Printing States and Transitions of BC Progams with integers (using clingcon)

Download

Get the most recent Version from Github: https://github.com/potassco/coala

Installation

Download the file, unpack it and install it using

    sudo python setup.py install

Alternatively, it can be run directly from the unpacked folder using python

    python coala/coala

Usage

When installed, coala can be called from anywhere.

  coala [Arguments] Inputfiles

In order to print states and transitions for a BC encoding, the facts given by coala can be run the “encodings/base_translation.lp” using clingo.

    coala file.bc | clingo - encodings/base_translation.lp 0

Or when using the gringo python library

    coala -p -m ps file.bc

Information on parameters can be printed calling coala without parameters

    coala
Usage:
    coala [Arguments] Inputfiles

Arguments:
    --help, -h  Prints the usage and some addition help for people to lazy to search
    --mode <arg>, -m <arg>  States what Coala will do. Default =  translate
        translate, t    Translate all Input into ASP Facts
        solveIterative, s   Translate and try to find a solution
        solveFixed, f   Translate and try to find a solution with a fixed step length
        printStates, ps Translate and display all States
        printTransitions, pt    Translate and display all Transitions
        printStatesAndTransitions, pst  Translate and display all States and Transitions
        conflicts, c    Check an encoding for conflicts given a partial state and actions
    --language <arg>, -l <arg>  Defines the input language. Default =  bc
        bc  Set input language to BC
        bc_legacy   Use an older parser for the input language BC
Output arguments    By default, results are printed to the terminal
    --output_file <arg>, -o <arg>   Output will be written to the file <arg>
    --write_file    Will write into a temporary file
Translator arguments
    --ignore_errors, -i Translation will try to continue even if there are Errors
    --ignore_undefined, -u  Translation ignore Errors due to undefined fluents or actions
    --verbose   Print some additional output
    --silent, -s    Print no output
StateBuilder arguments
    --encoding_s <arg>  Set the encoding for States
    --encoding_t <arg>  Set the encoding for Transitions
    --only_positive, -p Do not output fluents that hold the value false
Solve arguments
    --max_horizon <arg>, -z <arg>   Set the maximal horizon. 0 equals no horizon; Default =  10
    --encoding_i <arg>  Set the encoding for solving iteratively; 
    --encoding_f <arg>  Set the encoding for solving with fixed horizon;

Some addition Information is given using the help parameter

    coala -h

Syntax

The language has the following reserved words:

  • not, true, false, if, causes,
  • ifcons, after, default, inertial,
  • nonexecutable, impossible, action,
  • fluent, where

These words may not be used for and inside fluent and action names. In the following, we will be using “<” and “ to make it easier to distinguish between fluents, actions and reserved words. Note that we accept both with and without “<” and “.

The BC syntax of coala requires the users to define actions and fluents used in the laws.

<action> jump.
<fluent> position(inair).
<fluent> alive.

By default, fluents have a boolean domain. Multivalued fluents can be used by explicitly stating their domain.

<fluent> position=inair.
<fluent> position=onground.
<fluent> position=underwater.
<fluent> position=gone.

If the domain is defined in asp code, a more comact form can be used:

<asp> domain(1..1000). domain(6789).</asp>
<fluent> position=X <where> domain(X).

The static laws of BC are written as

alive <if> -dead.
at(1,2) <ifcons> at(1,2).
position(onground) <if> -position(inair) <ifcons> -flying.

Only fluents can be used in static laws.

The dynamic laws of BC are written as

buttonpressed <after> toggle.
has(cup) <after> pickup(cup), at(cup).
position(inair) <after> jump, position(onground) <ifcons> position(inair).

Actions may only be used in the after part.

Inertial and default laws are written

<inertial>position(onground).
<default> onground.
<default> -position(inair).

The inertial law means that position(onground) will keep it’s value unless changed. The default law means that at each step position(inair) will be set to false if not stated otherwise.

Additionally, nonexecutable and impossible laws are written as

<nonexecutable> jump, position(inair).
<nonexecutable> jump <if> indoors.
<impossible> position(onground), position(inair).
<impossible> at(1,2), has(object).

Impossible laws are state constraints and may only contain fluents while Nonexecutable laws may contain actions and fluents and restrict possible successor states.

We also included variables into our syntax. These need to be bound in a where part.

at(X) <after> goto(X) <where> <action> goto(X).

In where parts, variables can be bound to fluents, actions and arbitrary asp facts.

at(X) <after> goto(X) <where> <action> goto(X).
at(X) <after> goto(X) <where> <fluent> at(X).
at(X,Y) <after> goto(X), at(Y) <where> <fluent> at(Y), <action> goto(X).
at(X) <after> goto(X) <where> arbitrary_position(X).

Plain asp code can be added encapsulated by ASP tags.

<asp>arbitrary_position(1..10).</asp>
<asp>some_crazy_asp(X) :- 1 { something_definately_not_in_BC(Z)} 1, &sum {arg*1024, buarg*56, cargh} = 1.
i_know_what_im_doing :- not not i_know_what_im_doing.</asp>

ASP code will not be checked in coala. (It will be pasted into the output)

It is also allowed to use negation and arithmetic in the where part.

at(X) <after> goto(X) <where> pos(X), not badposition(X).
at(Y) <after> goto(X) <where> pos(X), Y = X + 1.
at(Y) <after> goto(X) <where> pos(X), Y > X * 11.
at(Y) <after> goto(X) <where> pos(X), pos(Y), Y != X.
at(Y) <after> goto(X) <where> pos(X), Y = X ** 1.
at(Y) <after> goto(X) <where> pos(X), Y = X / 2.

Note that each variable still needs to be bound somewhere.

For finding plans, we added initial values and goals. They are not part of BC and will have no effect unless modified encodings are used. Initial values can be set using a simple rule like shown in the file “encodings/base_initial.lp” : “holds(F,0) :- initially(F).” Initial values of fluents can be set using

<initially> -dead.

And goals can be defined using

<goal> winning.

Examples

coala includes a few examples, like:

  • examples/medical.bc
  • examples/sumo.bc
  • examples/walkbot.bc

These examples include one instance each.

  • examples/medical_instance.bc
  • examples/sumo_instance.bc
  • examples/walkbot_instance.bc

These example can be translated by passing them to coala

    coala examples/medical.bc examples/medical_instance.bc

In order to generate states and transitions using clingo for some example, you can use the following call

    coala examples/medical.bc examples/medical_instance.bc | clingo - encodings/base_translation.lp 0

This will generate one answer set for every transition.

[...]  
Answer: 40
action(act(drink(cup(water)))) action(act(medicate)) action(act(look)) fluent(infected) fluent(hydrated) fluent(dead) domain(hydrated,true)
domain(hydrated,false) domain(infected,true) domain(infected,false) domain(dead,true) domain(dead,false) dynamic_law(law(1)) head(law(1),val(hydrated,true))
after(law(1),act(drink(cup(water)))) dynamic_law(law(2)) head(law(2),val(dead,true)) after(law(2),act(medicate)) after(law(2),val(hydrated,false))
after(law(2),val(infected,true)) dynamic_law(law(3)) head(law(3),val(infected,false)) after(law(3),act(medicate)) ifcons(law(3),val(hydrated,true))
nonexecutable(law(4),act(drink(cup(water)))) nonexecutable(law(4),val(dead,true)) nonexecutable(law(5),act(medicate)) nonexecutable(law(5),val(dead,true))
inertial(dead) inertial(hydrated) inertial(infected) initially(val(infected,true)) initially(val(hydrated,false)) initially(val(dead,false))
goal(val(infected,false)) goal(val(dead,false)) step(0) step(1) atom(val(hydrated,true)) atom(val(hydrated,false)) atom(val(infected,true))
atom(val(infected,false)) atom(val(dead,true)) atom(val(dead,false)) head(id(inertial,dead,true),val(dead,true))
head(id(inertial,dead,false),val(dead,false)) head(id(inertial,hydrated,true),val(hydrated,true)) head(id(inertial,hydrated,false),val(hydrated,false))
head(id(inertial,infected,true),val(infected,true)) head(id(inertial,infected,false),val(infected,false)) head(id(nonexecutable,law(4)),_false)
head(id(nonexecutable,law(5)),_false) ifcons(id(inertial,dead,true),val(dead,true)) ifcons(id(inertial,dead,false),val(dead,false))
ifcons(id(inertial,hydrated,true),val(hydrated,true)) ifcons(id(inertial,hydrated,false),val(hydrated,false))
ifcons(id(inertial,infected,true),val(infected,true)) ifcons(id(inertial,infected,false),val(infected,false)) dynamic_law(id(inertial,dead,true))
dynamic_law(id(inertial,dead,false)) dynamic_law(id(inertial,hydrated,true)) dynamic_law(id(inertial,hydrated,false))
dynamic_law(id(inertial,infected,true)) dynamic_law(id(inertial,infected,false)) dynamic_law(id(nonexecutable,law(4))) dynamic_law(id(nonexecutable,law(5)))
after(id(inertial,dead,true),val(dead,true)) after(id(inertial,dead,false),val(dead,false)) after(id(inertial,hydrated,true),val(hydrated,true))
after(id(inertial,hydrated,false),val(hydrated,false)) after(id(inertial,infected,true),val(infected,true))
after(id(inertial,infected,false),val(infected,false)) after(id(nonexecutable,law(4)),act(drink(cup(water)))) after(id(nonexecutable,law(4)),val(dead,true))
after(id(nonexecutable,law(5)),act(medicate)) after(id(nonexecutable,law(5)),val(dead,true)) holds(val(infected,false),0) holds(val(hydrated,true),0)
holds(val(dead,true),0) holds(val(infected,false),1) holds(val(hydrated,true),1) holds(val(dead,true),1) occurs(act(look),0)
SATISFIABLE

Models       : 40    
Calls        : 1
Time         : 0.209s (Solving: 0.11s 1st Model: 0.00s Unsat: 0.01s)
CPU Time     : 0.000s

Since we are normally only interested in “holds” and “occurs” predicates, we provide a script for cleaning the clingo output for BC output, called outputformatclingocoala

    coala examples/medical.bc examples/medical_instance.bc | clingo - encodings/base_translation.lp 0 | outputformatclingocoala

This generates the following output:

[...]  
Answer: 39
holds(val(dead,true),0)
holds(val(dead,true),1)
holds(val(hydrated,true),0)
holds(val(hydrated,true),1)
holds(val(infected,false),0)
holds(val(infected,false),1)

Answer: 40
holds(val(dead,true),0)
holds(val(dead,true),1)
holds(val(hydrated,true),0)
holds(val(hydrated,true),1)
holds(val(infected,false),0)
holds(val(infected,false),1)
occurs(act(look),0)

SATISFIABLE

If you have the gringo library installed and in your python path (old library, the clingo library might get supported later), given a goal and an initial state, you can call

    coala -m solveiterative examples/medical.bc examples/medical_instance.bc

This generates a plan for the given transition system from the/an initial state to a state satisfying the goal.

Plan:

Step  0 : ['infected', '-dead', '-hydrated']
Actions : ['look', 'drink(cup(water))']
Step  1 : ['hydrated', 'infected', '-dead']
Actions : ['look', 'medicate', 'drink(cup(water))']
Step  2 : ['-dead', '-infected', 'hydrated']

( Additionally to these examples, the “testcases” directory contains additional files that may help understanding the syntax. However, some of the testcases need to be run with experimental parameters which are not listed. Files with the ending “.b” are written for the action description language B, therefore the parameter “-l b” must be used. Files beginning with “role_” are written using a modular approach and are translated using the parameter “-l bce” or “-l bca”. )

There is also one example for multivalued fluents, where the instance is included in the file:

    coala -m solveiterative examples/monkey/monkey.bc

Incremental solving by example can be done calling

    coala examples/monkey/monkey.bc | clingo - encodings/solve_incremental.lp 5 -W none -q

Hints

It is possible to use variables representing any action or fluent.

You can write:

<inertial> A <where> <fluent> A.

If you want all fluents to be inertial or

<default> -A <where> <fluent> A.

If you want all fluents to be false by default. Also, you can restrict the actions to maximal one per step by:

<nonexecutable> A,B <where> <action> A, <action> B, A != B.

In BC, you normally get no answer set when something went wrong. One thing to check then is whether each fluent has either an inertial or default law. Additionally, removing impossible and nonexecutable laws might help to track down the problem. You can use the print states mode of coala with the (currently gringo) python library in order to list all possible states:

    coala -p -m ps instance.bc

Printing only positive fluents ( -p ) may prove useful there.

Legacy

Coala earlier than 2.0 is a versatile compiler from action languages to answer set programs. It supports different encodings, variables and LTL style queries.

Download Resources Citation