instantiate.py
Go to the documentation of this file.
00001 #! /usr/bin/env python
00002 # -*- coding: latin-1 -*-
00003 
00004 from collections import defaultdict
00005 
00006 import build_model
00007 import pddl_to_prolog
00008 import normalize #because of "get_function_predicate" 
00009 import pddl
00010 
00011 def get_fluent_facts(task, model):
00012   fluent_predicates = normalize.get_fluent_predicates(task)
00013   return set([fact for fact in model
00014               if fact.predicate in fluent_predicates])
00015 
00016 def get_fluent_functions(model):
00017     fluent_pnes = set()
00018     for atom in model:
00019         if isinstance(atom.predicate,pddl.PrimitiveNumericExpression):
00020             fluent_pnes.add(pddl.PrimitiveNumericExpression(atom.predicate.symbol,atom.args))
00021     return fluent_pnes
00022 
00023 def get_objects_by_type(typed_objects,types):
00024   type_dict = dict((type.name,type) for type in types)
00025   result = {}
00026   for obj in typed_objects:
00027     supertypes = type_dict[obj.type].supertype_names
00028     for type_name in [obj.type] + supertypes:
00029       result.setdefault(type_name, []).append(obj.name)
00030   return result
00031 
00032 def init_function_values(init_facts):
00033   assignments = [func_assign for func_assign in init_facts 
00034                         if isinstance(func_assign, pddl.FunctionAssignment)]
00035   init_values = {}
00036   for assignment in assignments:
00037     init_values[assignment.fluent] = assignment.expression
00038   return init_values
00039 
00040 def instantiate(task, model):
00041   relaxed_reachable = False
00042   fluent_facts = get_fluent_facts(task, model)
00043   fluent_functions = get_fluent_functions(model)
00044 
00045   ## HACK: This is a not very clean way of initializing the previously
00046   ## added functions that store the duration of an action to a haphazardly value
00047   for atom in model:
00048         if isinstance(atom.predicate,str) and atom.predicate.startswith("defined!duration_"):
00049                 pne = pddl.PrimitiveNumericExpression(atom.predicate.replace("defined!","",1),atom.args)
00050                 value = pddl.NumericConstant(1.0)
00051                 init_assign = pddl.Assign(pne, value)
00052                 task.init.append(init_assign)
00053 
00054   init_facts = set(task.init) # TODO adapt
00055   init_function_vals = init_function_values(init_facts)
00056   
00057   # Determine initial facts, that are not fluents => constant facts, that a module might need
00058   init_constant_fluents = set(init_function_vals)
00059   init_constant_fluents.difference_update(fluent_functions)   # all fluents that are in init, but are NOT a fluent -> constant
00060 
00061   # Now get the assigned values from the init_facts for the constant fluents
00062   init_constant_numeric_facts = set()   # This will hold Assigns that assign the fluents
00063   for i in init_constant_fluents:
00064     for j in init_facts:
00065       if isinstance(j, pddl.Assign):
00066         if isinstance(j.fluent, pddl.PrimitiveNumericExpression):
00067           if j.fluent is i:     # Assign in init_fact assign this (i) fluent
00068             init_constant_numeric_facts.add(j) 
00069   
00070   # Now get predicates that are in init, but are not fluent_facts
00071   init_constant_predicate_facts = set()
00072   for i in init_facts:
00073     if isinstance(i, pddl.Atom):  # do NOT consider PNEs, etc.
00074       if i not in fluent_facts:   # only consider non-fluents
00075         if i.predicate is not "=":    # hack to remove the intermediate '=' fluents
00076           init_constant_predicate_facts.add(i)
00077 
00078 #  print "** fluent functions"
00079 #  for function in fluent_functions:
00080 #    function.dump()
00081 #  print "** fluent facts"
00082 #  for fact in fluent_facts:
00083 #    print fact
00084 #  print "** init facts"
00085 #  for fact in init_facts:
00086 #    print fact
00087 
00088   type_to_objects = get_objects_by_type(task.objects,task.types)
00089 
00090   instantiated_actions = []
00091   instantiated_durative_actions = []
00092   instantiated_axioms = []
00093   instantiated_numeric_axioms = set()
00094   new_constant_numeric_axioms = set()
00095   reachable_action_parameters = defaultdict(list)
00096   instantiated_modules = set()
00097   for atom in model:
00098     if isinstance(atom.predicate, pddl.Action):
00099       action = atom.predicate
00100       parameters = action.parameters
00101       if isinstance(action.condition, pddl.ExistentialCondition):
00102         parameters = list(parameters)
00103         parameters += action.condition.parameters
00104       variable_mapping = dict([(pddl.Variable(par.name), arg)
00105                                for par, arg in zip(parameters, atom.args)])
00106       inst_action = action.instantiate(variable_mapping, init_facts,
00107                                        fluent_facts, init_function_vals, fluent_functions,
00108                                        task, new_constant_numeric_axioms, instantiated_modules, type_to_objects)
00109       if inst_action:
00110         instantiated_actions.append(inst_action)
00111     elif isinstance(atom.predicate, pddl.DurativeAction):
00112       action = atom.predicate
00113       parameters = action.parameters
00114       reachable_action_parameters[action.name].append(parameters)
00115       for condition in action.condition:
00116         if isinstance(condition,pddl.ExistentialCondition):
00117           parameters = list(parameters)
00118           parameters += condition.parameters
00119       variable_mapping = dict([(pddl.Variable(par.name), arg)
00120                                for par, arg in zip(parameters, atom.args)])
00121       inst_action = action.instantiate(variable_mapping, init_facts, fluent_facts,
00122                                        init_function_vals, fluent_functions,
00123                                        task, new_constant_numeric_axioms, instantiated_modules, type_to_objects)
00124       if inst_action:
00125         instantiated_durative_actions.append(inst_action)
00126     elif isinstance(atom.predicate, pddl.Axiom):
00127       axiom = atom.predicate
00128       parameters = axiom.parameters
00129       if isinstance(axiom.condition, pddl.ExistentialCondition):
00130         parameters = list(parameters)
00131         parameters += axiom.condition.parameters
00132       variable_mapping = dict([(pddl.Variable(par.name), arg)
00133                                for par, arg in zip(parameters, atom.args)])
00134       inst_axiom = axiom.instantiate(variable_mapping, init_facts, fluent_facts,
00135                                      fluent_functions, init_function_vals, task,
00136                                      new_constant_numeric_axioms, instantiated_modules)
00137       if inst_axiom:
00138         instantiated_axioms.append(inst_axiom)
00139     elif isinstance(atom.predicate, pddl.NumericAxiom):
00140       axiom = atom.predicate
00141       variable_mapping = dict([(pddl.Variable(par.name), arg)
00142                                for par, arg in zip(axiom.parameters, atom.args)])
00143       new_constant_numeric_axioms = set()
00144       inst_axiom = axiom.instantiate(variable_mapping, fluent_functions, init_function_vals, 
00145                                      task, new_constant_numeric_axioms)
00146       instantiated_numeric_axioms.add(inst_axiom)
00147     elif atom.predicate == "@goal-reachable":
00148       relaxed_reachable = True
00149     instantiated_numeric_axioms |= new_constant_numeric_axioms
00150       
00151   return (relaxed_reachable, fluent_facts, fluent_functions, instantiated_actions, 
00152           instantiated_durative_actions, instantiated_axioms, instantiated_numeric_axioms,
00153           instantiated_modules, init_constant_predicate_facts, init_constant_numeric_facts,
00154           reachable_action_parameters)
00155 
00156 def explore(task):
00157   prog = pddl_to_prolog.translate(task)
00158   model = build_model.compute_model(prog)
00159   return instantiate(task, model)
00160 
00161 if __name__ == "__main__":
00162   import pddl
00163 
00164   task = pddl.open()
00165   (relaxed_reachable, atoms, num_fluents, actions,durative_actions, 
00166         axioms, num_axioms, modules, init_constant_predicates, init_constant_numerics) = explore(task)
00167   print "goal relaxed reachable: %s" % relaxed_reachable
00168   print "%d atoms:" % len(atoms)
00169   for atom in atoms:
00170     print " ", atom
00171   print
00172   print "%d numerical fluents:" % len(num_fluents)
00173   for num_f in num_fluents:
00174     print " ", num_f
00175   print
00176   print "%d init constant predicates:" % len(init_constant_predicates)
00177   for p in init_constant_predicates:
00178     print " ", p
00179   print
00180   print "%d init constant numerics:" % len(init_constant_numerics)
00181   for n in init_constant_numerics:
00182     print " ", n
00183   print
00184   print "%d modules:" % len(modules)
00185   for module in modules:
00186     module.dump()
00187   print
00188   print "%d actions:" % len(actions)
00189   for action in actions:
00190     action.dump()
00191     print
00192   print
00193   print "%d durative actions:" % len(durative_actions)
00194   for action in durative_actions:
00195     action.dump()
00196     print
00197   print
00198   print "%d axioms:" % len(axioms)
00199   for axiom in axioms:
00200     axiom.dump()
00201     print
00202   print "%d numeric axioms:" % len(num_axioms)
00203   for axiom in num_axioms:
00204     axiom.dump()
00205     print
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


tfd_modules
Author(s): Maintained by Christian Dornhege (see AUTHORS file).
autogenerated on Tue Jan 22 2013 12:25:03