coala
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.