-
Notifications
You must be signed in to change notification settings - Fork 2
planning
The sas library provides various methods for dealing with SAS+ planning problems. Most of the code is verbatim from Fast Downward (developed by Malte Helmert), but parts are augmented / documented for use as a stand-alone library.
Note: Some of the functionality listed here (as part of the krtoolkit) may not be found in the original SAS libraries. These have been added to enrich the functionality of the libraries found within the krtoolkit.
There are three parsing methods so far that deal with files output from the PDDL->SAS+ translation process. All of the data structures that are returned are described below.
This file contains information for translating the SAS+ formulation back to a human readable form (ie. the PDDL naming conventions). planning.sas.parseGroups provides a method of parsing such files:
from krrt.planning.sas import parseGroups group_key = parseGroups('test.groups')
A GroupKey object is returned.
This file contains the SAS+ encoding of the problem. More information / explanation about the contents can be found here. planning.sas.parseSAS provides a method of parsing such files:
from krrt.planning.sas import parseSAS sas_task = parseSAS('output.sas', 'test.groups')
A SasTask object is returned.
Note: The test.groups file is required for this method as well.
This file contains additional SAS+ information of interest. More detailed information can be found here. Specifically the following three pieces can be parsed:
- CG: The Causal Graph is a directed graph that captures the dependencies between variables in the SAS+ domain.
- DTG: For each SAS+ variable, a Domain Transition Graph is constructed that indicate how the values of a SAS+ variable can be changed.
- SG: Rarely used, the Successor Generator encodes a data structure that can be used for efficient calculation of applicable operators.
Each part has it's own parsing function, and all three can be parsed with the single parsePRE function:
from krrt.planning.sas import parseCG, parseDTG, parseSG, parsePRE # Parse each individually cg = parseCG('output') dtgs = parseDTG('output') sg = parseSG('output') # Or parse them all at once all_objects = parsePRE('output') cg = all_objects['cg'] dtgs = all_objects['dtg'] sg = all_objects['sg']
The parseCG and parseSG functions return a CG and SG object respectively. The parseDTG function returns a list of DTGs (the index corresponding the the variable number). The parsePRE function returns a dict with keys as 'cs', 'dtg', and 'sg'. The values follow what each individual parsing function would generate.
Sometimes it is useful to have the planning task of the preprocessed form. Since it is structured different, extra care must be taken when parsing. The method to do this is to first convert the preprocessed SAS+ output, and then use the parseSAS function:
from krrt.planning.sas import convert_PRE, parseSAS #--- First convert the output to trick the SAS+ parser convert_PRE('output', 'output.pre') #--- Next parse the sas task task = parseSAS('output.pre', 'test.groups')
This file contains information about all of the mutex relations that the translation phase discovers. Naturally this includes all of the variables in test.groups, but mutex relations are discovered and recorded. planning.sas.AllGroups provides the functionality for parsing this information:
from krrt.planning.sas import AllGroups from krrt.planning.sas import parseSAS, convert_PRE #--- Get a hold of the original and preprocessed tasks convert_PRE('output', 'output.pre') orig_task = parseSAS('output.sas', 'test.groups') pre_task = parseSAS('output.pre', 'test.groups') #--- Create the AllGroups object all_groups = AllGroups('all.groups', orig_task, pre_task)
An AllGroups object is returned.
Note: Both the original translation and preprocessed SAS+ encodings are required due to the indexing convention used in the all.groups file.
The GroupKey object has the following functionality:
group_key.dump() | Display the group key in the same format as test.groups. |
group_key[var] | Return the group associated with variable name var. |
A Group object contains information about a single SAS+ variable. It has the following functionality:
group.dump() | Display information about the group as would be seen in test.groups. |
group.varname | The name of the SAS+ variable. |
group.values | A list of values the SAS+ variable can take on. |
group[i] | The i^th^ value that the SAS+ variable can take on. |
To illustrate this, here is a snippet of code that reads in the test.groups file, and builds a dict with the variable name as a key and it's cardinality as the value.
from krrt.planning.sas import parseGroups # Parse the test.groups group_key = parseGroups('test.groups') # Iterate over each group, and add the information cardinalities = {} for group in group_key: cardinalities[group.varname] = len(group.values) # Print the result print cardinalities
Currently, the AllGroups object is simply a wrapper around a list of MutexGroup objects.
all_groups.groups | List of MutexGroup objects. |
A MutexGroup object currently houses a list of Proposition objects (from the preprocessed SAS+ encoding).
group.props | List of Proposition objects representing a mutex relationship. |
A SasTask object basically houses a number of items related to a SAS Planning Task. We describe each in detail here:
task.dump() | Display information about the SAS planning task. |
task.axioms | Python list of Axiom objects. |
task.variables | List of Variable objects in the planning task. |
task.operators | List of Operator objects in the planning task. |
task.goals | List of Proposition objects that represent the goal. |
task.initial_state | List of Proposition objects that represent the initial state. |
task.name | Name of the SAS planning task. |
task.lookupProp[var_no, val_no] | Returns the Proposition object corresponding to the provided variable and value number (0-indexed). |
task.lookupVarVal[prop] | Returns a tuple (var_no, val_no) that corresponds to the provided Proposition object. |
task.lookupVarID[name] | Returns the variable id given a name. |
Note: The last two items are custom to the krtoolkit version of a SAS task object.
Coming soon...
A Proposition object contains two pieces of information:
prop.name | Name of the proposition (ie. holding(robotA, blockB)) |
prop.var | Variable object associated with the proposition. |
prop.val | Value of the variable (as an integer). |
The Operator object holds information associated with a single SAS operator:
op.dump() | Dump information about the operator (preconditions and effects). |
op.name | Name of the operator (includes the PDDL operator name and arguments). |
op.val | Value of the operator (as an integer). |
op.precond | List of Proposition objects that correspond to the preconditions of the operator. |
op.effects | A Tuple where the first entry is a list of Proposition objects corresponding to the conditional portion of the effect, and the second entry is a Proposition object corresponding to the variable setting effect. |
Note: The prevail conditions (if any) are all compiled away into preconditions during the parsing phase.
A Variable object contains a number of pieces of information:
var.axiom_layer | The axiom layer of this variable. This is -1 if the variable was not introduced to ground away an axiom. |
var.is_axiom | True if the variable is an axiom, False otherwise. |
var.name | Name of the variable in the output.sas file. |
var.val | The id of the SAS+ variable. |
var.propositions | A List of Proposition objects that are associated with this variable. |
var.range | An int indicating the size of the domain. |
The DTG object represents a single Domain Transition graph. It has the following members for quick information:
dtg.name | Name of the variable associated with the DTG. |
dtg.domain_size | Size of the domain (number of nodes in the graph). |
dtg.axiom_layer | Axiom layer of the variable associated with the DTG. |
dtg.graph | (advanced) The digraph associated with the DTG. For more info, see the pygraph project. |
In addition to these bits of information, the DTG object has the following functionality:
dtg.get_transitions(x,y) | Returns a list of DTGTransition objects associated with the edge x->y in the DTG. |
dtg.setGoal(val) | Set the goal of the DTG to val. Note: More than one goal is permitted. |
dtg.setInit(val) | Set the initial value of the DTG to val. Note: More than one initial value is not permitted. |
dtg.dot() | Returns a string representation of the DTG in dot format, including marked up init and goal states. |
Since there may be a number of transitions between two values of a DTG, a special data structure is used to house information about these transitions. The following members are available for use in a DTGTransition object:
dtgt.source_val | The value of a source node in the DTG (usually an integer). |
dtgt.target_val | The value of a target node in the DTG (usually an integer). |
dtgt.op_num | The operator number associated with this transition. |
dtgt.conditions | Conditions associated with this transition as (var, val) pairs. |
Additionally, the following method is available (and used primarily when constructing the DTG objects):
dtgt.addCond(var, val) | Adds the condition (var, val) pair to the list of conditions. |
The CG object represents the Causal Graph of a problem. It has the following members for quick information:
cg.var_names | List of variable names in the problem. |
cg.size | Size of the causal graph. |
cg.graph | (advanced) The digraph associated with the CG. For more info, see the pygraph project. |
In addition to these bits of information, the CG object also has the following functionality:
cg.isAcyclic() | Checks if the causal graph is acyclic. |
cg.dot() | Returns a string representation of the CG in dot format. |
The SG object represents the Successor Generator for a given SAS+ planning problem. It is a compact data structure that allows for quick analysis of which operators are applicable in a given state. Currently it is just a shell capable of parsing the SG output in SAS+ encodings, and exporting to DOT format for inspection. In the future however, further functionality will be added.
sg.gen_output() | Returns the SG encoding as found in the SAS+ encoding. |
sg.dot() | Returns the dot output of the SG data structure. |
Coming soon...
Coming soon...