numeric_axiom_rules.py
Go to the documentation of this file.
00001 import pddl
00002 
00003 def handle_axioms(axioms):
00004     axiom_by_pne = axiom_by_PNE(axioms)
00005     constant_axioms = identify_constants(axioms, axiom_by_pne)
00006     axioms_by_layer, max_layer = compute_axiom_layers(axioms, constant_axioms, axiom_by_pne)
00007     axiom_map = identify_equivalent_axioms(axioms_by_layer, axiom_by_pne)
00008     return axioms_by_layer, max_layer, axiom_map, constant_axioms
00009 
00010 def axiom_by_PNE(axioms):
00011     return dict([(axiom.effect, axiom) for axiom in axioms])
00012 
00013 def identify_constants(axioms, axiom_by_pne):
00014     def is_constant(axiom):
00015         if isinstance(axiom, pddl.PrimitiveNumericExpression):
00016             if axiom in axiom_by_pne:
00017                 axiom = axiom_by_pne[axiom]
00018             else:
00019                 return (False,None)
00020         if (axiom.op == None and 
00021            isinstance(axiom.parts[0],pddl.NumericConstant)):
00022             return (True,axiom.parts[0].value)
00023         else:
00024             all_constants = True
00025             values = []
00026             for part in axiom.parts:
00027                 const, val = is_constant(part)
00028                 if not const:
00029                     all_constants = False
00030                     break
00031                 values.append(val)
00032             if all_constants:
00033                 if len(values) == 1:
00034                     if axiom.op == "-":
00035                         new_value = -values[0]
00036                         axiom.op = None
00037                     else:
00038                         assert axiom.op == None
00039                         new_value = values[0]
00040                     axiom.parts = [pddl.NumericConstant(new_value)]
00041                     return (True, new_value)
00042                 else:
00043                     calculation = axiom.op.join(map(str,values))
00044                     new_val = eval(calculation)
00045                     axiom.parts = [pddl.NumericConstant(new_val)]
00046                     axiom.op = None
00047                     return (True,new_val)
00048             else:
00049                 return (False,None)
00050     
00051     constant_axioms = []
00052     for axiom in axioms:
00053         const, val = is_constant(axiom)
00054         if const:
00055             constant_axioms.append(axiom)
00056     return constant_axioms
00057 
00058     
00059 def compute_axiom_layers(axioms, constant_axioms, axiom_by_pne):
00060 
00061     CONSTANT_OR_NO_AXIOM = -1
00062     UNKNOWN_LAYER = -2
00063 
00064     depends_on = {}
00065     for axiom in axioms:
00066         depends_on.setdefault(axiom,[])
00067         for part in axiom.parts:
00068             depends_on[axiom].append(part)
00069 
00070     layers = dict([(axiom, UNKNOWN_LAYER) for axiom in axioms])
00071     def compute_layer(axiom):
00072         if isinstance(axiom, pddl.PrimitiveNumericExpression):
00073             axiom = axiom_by_pne.get(axiom, None)
00074        
00075         layer = layers.get(axiom, CONSTANT_OR_NO_AXIOM)
00076         
00077         if layer == UNKNOWN_LAYER:
00078             if axiom in constant_axioms:
00079                 layer = CONSTANT_OR_NO_AXIOM
00080             else:
00081                 layer = 0
00082                 for part in depends_on[axiom]:
00083                     layer = max(layer, compute_layer(part)+1)
00084             layers[axiom] = layer
00085         return layer
00086 
00087     max_layer = -2
00088     for axiom in axioms:
00089         max_layer = max(max_layer,compute_layer(axiom))
00090 
00091     layer_to_axioms = {}
00092     for axiom in layers:
00093         layer_to_axioms.setdefault(layers[axiom],[]).append(axiom)
00094     return layer_to_axioms, max_layer
00095 
00096 def identify_equivalent_axioms(axioms_by_layer, axiom_by_pne):
00097     axiom_map = {} 
00098     for layer, axioms in axioms_by_layer.iteritems():
00099         key_to_unique = {}
00100         for ax in axioms:
00101             mapped_args = []
00102             for p in ax.parts:
00103                 if p in axiom_map:
00104                     mapped_args.append(axiom_map[p].effect)
00105                 else:
00106                     mapped_args.append(p)
00107             key = (ax.op, tuple(mapped_args))
00108             if key in key_to_unique: # there has already been an equivalent axiom
00109                 axiom_map[ax.effect] = key_to_unique[key]
00110             else:
00111                 key_to_unique[key] = ax
00112     return axiom_map
00113         
00114 
00115 


tfd_modules
Author(s): Maintained by Christian Dornhege (see AUTHORS file).
autogenerated on Mon Oct 6 2014 07:52:06