00001
00002
00003
00004 from collections import defaultdict
00005
00006 import build_model
00007 import pddl_to_prolog
00008 import normalize
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
00046
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)
00055 init_function_vals = init_function_values(init_facts)
00056
00057
00058 init_constant_fluents = set(init_function_vals)
00059 init_constant_fluents.difference_update(fluent_functions)
00060
00061
00062 init_constant_numeric_facts = set()
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:
00068 init_constant_numeric_facts.add(j)
00069
00070
00071 init_constant_predicate_facts = set()
00072 for i in init_facts:
00073 if isinstance(i, pddl.Atom):
00074 if i not in fluent_facts:
00075 if i.predicate is not "=":
00076 init_constant_predicate_facts.add(i)
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
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