Output of the LAMA Translator
======================================

The translator generates three output files:

  1. output.sas: The SAS encoding of the planning task.
     We call this the "translation".

  2. test.groups: A human-readable description of the relationship
     between propositions in the original STRIPS representation and
     variable/value pairs in the SAS encoding.
     We call this the "translation key".

  3. all.groups: All mutex groups (see description below) found during 
     the translation. This file is later used to derive landmarks in 
     the search component of LAMA.

The translation contains all information required for solving the
task. The translation key is only generated for the benefit of the
human using the translator.

Roughly speaking, the translation process works by determining sets of
mutually exclusive propositions in the STRIPS task, then replacing
each such set {p_0, p_1, ..., p_{k-1}} by a single SAS variable with
domain {0, 1, ..., k}, where a value of i < k means that proposition
p_i is true and all others are false, while a value of k means that
all propositions in the set are false.

Any set of propositions can be covered by such mutex groups because it
is always possible to put a STRIPS proposition into a singleton set,
which will be translated to a binary SAS variable, amounting to a
trivial translation. Of course, the translator tries to avoid such
trivial translations, preferring encodings which use few SAS
variables. The actual mutex group cover computed by the translator is
written to the translation key file "test.groups". The translator
usually finds more mutex groups than are needed to encode the
task. All mutex groups found are written to "all.groups".


Translation Key Example
=======================

Let us explain the translation key file with a small example from the
Gripper domain, namely prob01.pddl from IPC-1. The relevant
(non-constant) STRIPS propositions in this task are the following:

  * (at-robby rooma), (at-robby roomb)
    These denote whether or not the robot is currently inside a given
    room.
  * (at ball1 rooma), (at ball2 rooma), (at ball3 rooma),
    (at ball4 rooma), (at ball2 rooma), (at ball2 rooma),
    (at ball3 rooma), (at ball4 rooma) 
    These denote whether or not a given ball is currently lying in a
    given room.
  * (free left), (free right)
    These denote whether or not a given gripper is currently carring
    some ball.
  * (carry ball1 left), (carry ball2 left), (carry ball3 left),
    (carry ball4 left), (carry ball1 right), (carry ball2 right), 
    (carry ball3 right), (carry ball4 right)
    These denote whether or not a given ball is currently being held
    in a given gripper.

The test.groups file generated by the translator looks as follows
(slight differences in translation are possible because the translator
is not completely deterministic; however, in this example, these will
not amount to a qualitative difference):

----- Sample test.groups file (Gripper domain) -----------------------
  var0:
    0: Atom carry(ball3, left)
    1: Atom free(left)
    2: Atom carry(ball2, left)
    3: Atom carry(ball1, left)
    4: Atom carry(ball4, left)
    5: <none of those>
  var1:
    0: Atom carry(ball1, right)
    1: Atom carry(ball2, right)
    2: Atom carry(ball3, right)
    3: Atom free(right)
    4: Atom carry(ball4, right)
    5: <none of those>
  var2:
    0: Atom at(ball1, rooma)
    1: Atom at(ball1, roomb)
    2: <none of those>
  var3:
    0: Atom at(ball2, rooma)
    1: Atom at(ball2, roomb)
    2: <none of those>
  var4:
    0: Atom at(ball3, rooma)
    1: Atom at(ball3, roomb)
    2: <none of those>
  var5:
    0: Atom at(ball4, rooma)
    1: Atom at(ball4, roomb)
    2: <none of those>
  var6:
    0: Atom at-robby(roomb)
    1: Atom at-robby(rooma)
    2: <none of those>
----------------------------------------------------------------------

This means that the translator generates a SAS encoding using seven
state variables. Variable var0 with domain {0, 1, 2, 3, 4, 5} encodes
which ball the left gripper is carrying if it is currently carrying a
ball (values 0, 2, 3, 4 corresponding to ball3, ball2, ball1, ball4),
whether the left gripper is currently free (value 4), or whether the
gripper is neither carrying a ball nor free (value 5).

Note that value 5 is actually unreachable, since a given gripper that
is not carrying a ball must be free. In general, the translator does
not try to detect such unreachable values because the LAMA
planner is not sensitive to them. If you want to use the translator
within another planning system, you might want to prune away
impossible values such as this one after the translation phase.
Most unreachable values are trivially unreachable because there is no
operator that could establish them. For example, in this Gripper task,
there is no operator that sets the value of the first state variable
to 5, and the initial value is also different from 5.

The second SAS variable (var1) similarly encodes the status of the
right gripper. Variables var2 through var5 encode the status of a
given ball. For example, variable var4 assumes the value 0 if ball3 is
in rooma, the value 1 if ball3 is in roomb, and the value 2 if neither
is the case (which implies that ball3 is currently being carried).

Finally, the seventh SAS variable (var6) encodes the location of the
robot, with 0 and 1 corresponding to rooma and roomb. Like for the
first two state variables, the last value (neither in rooma nor in
roomb) is actually unreachable.


----- Partial corresponding all.groups file -----------------------
  begin_groups
  7
  group
  5
  0 0 carry 2 ball3 left
  0 1 free 1 left
  0 2 carry 2 ball2 left
  0 3 carry 2 ball1 left
  0 4 carry 2 ball4 left
  group
  ...
  end_groups

The content of the all.groups file is somewhat less easy to read for
humans as it is mainly intended to be read by the search component of
LAMA. The first and last lines are "begin_groups" and "end_groups",
respectively. The second line contains a single number denoting the
number of mutex groups. Each group starts with a line containing
"group", followed by a line containing the number of facts in this
group. Each fact is represented by a line containing its SAS variable
and value, followed by the PDDL proposition in plain text, the number
of its arguments, and the arguments in plain text.


Translation Key Notes
=====================

In some planning tasks, the translator introduces new predicates for
compiling away axioms, quantified effects or non-STRIPS goal
conditions. These always have names containing an '@' sign to
distinguish them from regular predicates.

For example, the test.groups file obtained for the first task in the
PSR-Middle domain (ADL + derived predicates formulation) of IPC4
contains the following fragment:

----- test.groups fragment (PSR-Middle domain) -----------------------
  var359:
    0: Atom new-axiom@0()
    1: <none of those>
----------------------------------------------------------------------

The predicate new-axiom@0 is introduced here to compile away the
non-STRIPS goal condition (forall (?b - DEVICE) (not (affected ?b))).


Translation File Format
=======================

The translation file consists of six sections:

  1. Metric section
  2. Variable section
  3. Initial state section
  4. Goal section
  5. Operator section
  6. Axiom section

We explain these six sections in sequence.

Translation File Format: Metric Section
=========================================

The metric section begins with the line "begin_metric", followed by a
line containing 0 or 1. If this line is 0, the planner will aim to
optimise plan length; if the line is 1, this means a "minimise action
costs" requirement was given in the PDDL input, and the planner will
aim to minimse the plan cost. The section ends with the line
"end_metric".

Translation File Format: Variable Section
=========================================

The variable section begins with the line "begin_variables", followed
by a line containing the number of SAS state variables. This is
followed by one line for each state variable, which contains three
parts separated by spaces:

  * the name of the variables (always "var<i>", where <i> is the index
    of the variable in the list, starting from 0),
  * the size of the domain of the variable, and
  * the axiom layer of the variable.

For state variables that do not correspond to axioms, i.e. which are
not computed from the values of other state variables, the axiom layer
is always -1. For state variables that do correspond to axioms, the
axiom layer determines the order of evaluation of axiom rules,
described further below in the section "Evaluating Axioms".

The variable section ends with the line "end_variables".

Here is an example from the same Gripper task we used before:

----- Sample variable section (Gripper domain) -----------------------
  begin_variables
  7
  var0 6 -1
  var1 6 -1
  var2 3 -1
  var3 3 -1
  var4 3 -1
  var5 3 -1
  var6 3 -1
  end_variables
----------------------------------------------------------------------

The example shows that there are 7 SAS variables in this task, the
first two of which can assume 6 different values (in the set {0, 1, 2,
3, 4, 5}), and the other of which can assume 3 different values (in
the set {0, 1, 2}). This is consistent with our earlier explanation of
the translation key. None of those variables corresponds to a derived
predicate, so all axiom layers are -1.


Translation File Format: Initial State Section
==============================================

The initial state section begins with the line "begin_state", followed
by one line for each SAS state variable. Each of those lines contains
a single number, denoting the value of the given state variable in the
initial state (for state variables which do not correspond to derived
predicates) or the "default value" of the state variable (for state
variables corresponding to derived predicates; see section "Evaluating
Axioms" below). The section ends with the line "end_state".

Here is the initial state section for the Gripper example:

----- Sample initial state section (Gripper domain) ------------------
  begin_state
  1
  3
  0
  0
  0
  0
  1
  end_state
----------------------------------------------------------------------

So the initial value of var0 in the example is 1, the initial value of
var1 is 3, the initial values of var2 through var5 are 0, and the
initial value of var6 is 1. Recalling the translation key shown
earlier, this means that exactly the following STRIPS propositions are
true in the initial state:

  (free left), (free right), (at ball1 rooma), (at ball2 rooma),
  (at ball3 rooma), (at ball4 rooma), (at-robby rooma).


Translation File Format: Goal Section
=====================================

The goal section begins with the line "begin_goal", followed by a line
which contains the number of goal pairings. This is followed by one
line for each goal pairing, where a goal pairing is given by two
numbers separated by spaces, where the pair "i j" means that "var<i>"
must have the value j in the goal. The goal section ends with the line
"end_goal".

Here is the goal section for the Gripper example:

----- Sample goal section (Gripper domain) ---------------------------
  begin_goal
  4
  2 1
  3 1
  4 1
  5 1
  end_goal
----------------------------------------------------------------------

We see that there are four goal conditions: Each of the variables var2
through var5 shall assume the value 1. In other words, the goal is
reached if all four balls are in roomb.

Note that the goal condition of the translated task is always a simple
conjunction of atomic goals. If the original PDDL goal is more
complicated, it is transformed by the translator to fit this
requirement. In some cases, this leads to the introduction of new
derived predicates and axiom rules.


Translation File Format: Operator Section
=========================================

Unlike the previous sections, the operator section does not begin with
a specific line. Instead, it begins with a line containing a single
number, the number of operators in the task. Following that line, each
operator is defined in sequence.

An operator definition is structured as follows:

  * The first line is "begin_operator".
  * The second line contains the name of the operator.
  * The third line contains a single number, denoting the number of
    prevail conditions.
  * The following lines describe the prevail conditions, one line for
    each condition. A prevail condition is given by two numbers
    separated by spaces, denoting a variable/value pairing in the same
    notation for goals described above.
  * The first line after the prevail conditions contains a single
    number, denoting the number of effects.
  * The following lines describe the effects, one line for each
    effect (read on).
  * The next line contains a single number denoting the cost of the
    operator (0 if no action costs are specified in the PDDL input).
  * The final line is "end_operator".

Of these parts, the lines that describe an effect are most complicated
because effects can have associated effect conditions (often called
"secondary preconditions" in the literature) and a condition on the
old value of the affected state variable (called a "precondition" as
opposed to a "prevail condition" in the SAS+ literature). An effect is
always given in a single line, with the individual parts separated by
spaces. It is structured as follows:

 * First comes the number of effect conditions. In STRIPS domains,
   this will usually be 0 (additional effect conditions can be
   introduced by the translator in rare cases, though)
 * This is followed by one variable/value pair for each effect
   condition. This is given as two numbers like for goal conditions
   and prevail conditions.
 * This is followed by a number denoting the variable affected by the
   effect in the third-last position.
 * This is followed by the value that this variable must have for the
   operator to be applicable (precondition), or -1 if there is no
   particular value that the variable must have. (Note that is truly
   part of the operator precondition and not an effect condition, and
   having it separated from the operator precondition is somewhat
   clumsy. Let's call it a historical accident caused by SAS+'s
   distinction of prevail and preconditions.)
 * Finally, the last number denotes the new value for the affected
   variable.

Even for fairly small examples, the operator section becomes quite
big, so we omit most operator definitions of the Gripper example:

----- Sample operator section (Gripper domain) -----------------------
  34
  begin_operator
  move rooma roomb
  0
  1
  0 6 1 0
  0
  end_operator
  begin_operator
  pick ball4 rooma left
  1
  6 1
  2
  0 0 1 4
  0 5 0 2
  0
  end_operator
  [... 31 operators omitted]
  begin_operator
  pick ball1 roomb right
  1
  6 0
  2
  0 1 3 0
  0 2 1 2
  0
  end_operator
----------------------------------------------------------------------

The example shows that there are 34 operators in this domain, and
three of them are shown in detail.

The first operator is called "move rooma roomb" and has no prevail
conditions (0) and one effect (1).
The effect has no associated effect conditions (0) and affects var6
(6). It requires that the old value of the variable is 1, so it is
only applicable if the robot is in rooma. It establishes the value 0,
so that the robot will be in roomb afterwards.

The two pick-up operators are similar, so we only explain the first
one. Its name is "pick ball4 rooma left". It has one prevail
condition, namely that var6 has the value 1 (i.e. the robot is in
rooma). It has two effects. The first effect has no associated
conditions, requires that var0 currently has value 1 (that is, the
left gripper is free) and changes var0 to value 4 (the left gripper
carries ball4). The second effect has no associated conditions either,
requires that var5 currently has value 0 (ball4 is in rooma) and sets
it to value 2 (ball4 is in neither room afterwards).

As an example of an operator involving effect conditions and the don't
care value -1 for an effect precondition, consider the following
operator from a task in the Schedule domain:

----- Sample operator with effect conditions (Schedule domain) -------
  begin_operator
  do-polish a0
  1
  7 0
  4
  0 24 1 0
  0 3 -1 0
  1 29 1 29 -1 0
  0 22 1 0
  0
  end_operator
----------------------------------------------------------------------

The operator is named "do-polish a0".
The prevail condition "7 0" requires that the temperature of object a0
is cold. The four effects of the operators are:

  * 0 24 1 0:
    Unconditionally (0), the polisher (var24), which must be non-busy
    (1), becomes busy (0).
  * 0 3 -1 0:
    Unconditionally (0), the surface condition of a0 (var3), whose
    current status can be anything (-1), will become polished (0).
  * 1 29 1 29 -1 0:
    Under the one (1) effect condition that we have not currently
    scheduled any object (var29 equals 1), we will have scheduled an
    object afterwards (var29 is set to 0). The variable var29 may have
    any value currently (-1).
  * 0 22 1 0:
    Unconditionally (0), the scheduled-status of a0 (var22), which
    must be not-scheduled (1), becomes scheduled (0).

Note that the only effect with an effect condition (1 29 1 29 -1 0)
could be rewritten as (0 29 -1 0) in this situation, because var29 can
only take on the possible values 0 and 1 anyway. However, the
translator does not try to detect and simplify this effect pattern,
which occurs quite commonly in some of the planning benchmarks.


Translation File Format: Axiom Section
======================================

The axiom section is similar in structure to the operator section, as
axiom rules can be considered to be operators that are automatically
executed whenever applicable. However, the section is somewhat simpler
in structure because axiom rules only ever affect a single state
variable.

Similar to the operator section, the axiom section begins with a line
containing the number of axiom rules. Following that line, each axiom
rule is defined in sequence.

An axiom rule is structured as follows:

  * The first line is "begin_rule"
  * The second line contains a single number, denoting the number of
    conditions in the "body" of the rule.
  * The following lines describe these conditions, one line for each
    condition. A condition is given by two numbers separated by
    spaces, denoting a variable/value pairing. In other words, the
    same notation as for operator prevail conditions is used.
  * The following line contains three numbers, denoting the variable
    affected by the axiom rule, the value that this variable must
    have for this rule to be applicable, and the new value assigned to
    this variable. The variable and this latter value together form
    the "head" of the rule.
  * The final line is "end_rule".

Variables appearing in the head of axiom rules (axiom variables) are
disjoint from variables affected by operators. In the current version
of the translator, axiom variables always have a binary domain, so the
"old value" for the affected variable is always the complement of the
new value and can be safely ignored.

In the Gripper example, the axiom section looks as follows:

----- Sample axiom section (Gripper domain) --------------------------
  0
----------------------------------------------------------------------

This shows that there are no axiom rules in this domain, which is
the case for all pure-STRIPS benchmarks. Axiom rules will of course be
generated for domains that contain derived predicates, but they can
also be generated for PDDL tasks without derived predicates if they
use non-STRIPS features such as universally quantified conditions, as
some of these are compiled away with the help of axioms. As an
example, here is an axiom rules from a Miconic-FullADL task:

----- Sample axiom section (Miconic-FullADL domain) ------------------
  1
  begin_rule
  2
  1 0
  3 0
  5 0 1
  end_rule
----------------------------------------------------------------------

The axiom section contains a single axiom rule. It has two conditions
in the body, namely that var1 and var3 are both set to 0, i.e. that
passengers p1 and p0 have both been served. The head of the axiom
states that if the condition is satisfied, then var5 will assume the
value 1 if it currently has the value0. Variable var5 corresponds to a
proposition over a newly introduced predicate "new-axiom@9" which has
been generated to simplify the original PDDL goal 
(forall (?p - passenger) (served ?p)). (Of course, in this case the
goal could also have been transformed to a simple conjunction in a
different way that does not require axioms.)


Evaluating Axioms
=================

State variables that correspond to derived predicates are not directly
affected by operator applications. Instead, their values in a given
world state are computed from the values of the other state variables
using the following algorithm:

  * First, all axiom state variables are set to their default value
    (the one specified in the initial state section).
  * Second, all axiom rules which affect variables at axiom layer 0
    are evaluated. An axiom rule is evaluated by determining whether
    all variable/value pairings in its body match the current state.
    If so, the variable in the head is changed to the value in the
    head. This process is repeated until no further changes occur.
  * Third, all axioms rules which affect variables at axiom layer 1
    are evaluated.
  * Fourth, all axioms rules which affect variables at axiom layer 2
    are evaluated.
  * ...

The semantics of the translation guarantees that the algorithm always
terminates and that the result is independent of the order in which
axiom rules at the same layer are considered.
