def parse(alist): iterator = iter(alist) assert iterator.next() == ":action" name = iterator.next() parameters_tag_opt = iterator.next() if parameters_tag_opt == ":parameters": parameters = pddl_types.parse_typed_list(iterator.next(), only_variables=True) precondition_tag_opt = iterator.next() else: parameters = [] precondition_tag_opt = parameters_tag_opt if precondition_tag_opt == ":precondition": p = iterator.next() if len(p) > 0: precondition = conditions.parse_condition(p) else: precondition = conditions.Conjunction([]) effect_tag = iterator.next() else: precondition = conditions.Conjunction([]) effect_tag = precondition_tag_opt assert effect_tag == ":effect" effect_list = iterator.next() eff = [] effects.parse_effects(effect_list, eff) for rest in iterator: assert False, rest return Action(name, parameters, precondition, eff)
def parse(alist): iterator = iter(alist) action_tag = next(iterator) assert action_tag == ':action' name = next(iterator) parameters_tag_opt = next(iterator) if parameters_tag_opt == ':parameters': parameters = pddl_types.parse_typed_list(next(iterator), only_variables=True) precondition_tag_opt = next(iterator) else: parameters = [] precondition_tag_opt = parameters_tag_opt if precondition_tag_opt == ':precondition': precondition_list = next(iterator) if not precondition_list: # Note that :precondition () is allowed in PDDL. precondition = conditions.Conjunction([]) else: precondition = \ conditions.parse_condition(precondition_list) precondition = precondition.simplified() effect_tag = next(iterator) else: precondition = conditions.Conjunction([]) effect_tag = precondition_tag_opt assert effect_tag == ':effect' effect_list = next(iterator) try: cost_eff_pairs = effects.parse_effects(effect_list) if 1 == len(cost_eff_pairs): cost_eff_pairs = [(cost_eff_pairs[0][0], cost_eff_pairs[0][1], '')] else: # Convert floats to fractions to output # TODO : Benchmark this fraction conversion all_fractions = [] for cep in cost_eff_pairs: all_fractions.append( fractions.Fraction(cep[2]).limit_denominator()) lcm = reduce(lambda a, b: a * b / fractions.gcd(a, b), [f.denominator for f in all_fractions], 1) # Use the fractions and lcm to build the weights #for i in range(len(cost_eff_pairs)): # for j in range(len(cost_eff_pairs[i])): # print(cost_eff_pairs[i][j]) cost_eff_pairs = [(cost_eff_pairs[i][0], cost_eff_pairs[i][1], '_DETDUP_%d_WEIGHT_%d_%d' % (i, all_fractions[i].numerator, all_fractions[i].denominator)) for i in range(len(cost_eff_pairs))] except ValueError, e: raise SystemExit('Error in Action %s\nReason: %s.' % (name, e))
def parse(alist): iterator = iter(alist) assert iterator.next() == ":action" name = iterator.next() parameters_tag_opt = iterator.next() if parameters_tag_opt == ":parameters": parameters = pddl_types.parse_typed_list(iterator.next(), only_variables=True) precondition_tag_opt = iterator.next() else: parameters = [] precondition_tag_opt = parameters_tag_opt if precondition_tag_opt == ":precondition": precondition = conditions.parse_condition(iterator.next()) effect_tag = iterator.next() else: precondition = conditions.Conjunction([]) effect_tag = precondition_tag_opt assert effect_tag == ":effect" effect_list = iterator.next() eff = [] try: cost = effects.parse_effects(effect_list, eff) except ValueError, e: raise SystemExit("Error in Action %s\nReason: %s." % (name, e))
def __init__(self, condition, effect): if isinstance(effect, ConditionalEffect): self.condition = conditions.Conjunction([condition, effect.condition]) self.effect = effect.effect else: self.condition = condition self.effect = effect
def __init__(self, condition, effect, time=None): if isinstance(effect, ConditionalEffect): assert len(condition) == len(effect.condition) if len(condition) == 1: self.condition = conditions.Conjunction([condition, effect.condition]) else: new_condition = [] for index, cond in enumerate(condition): new_condition.append(conditions.Conjunction([cond, effect.condition[index]])) self.condition = new_condition self.effects = effect.effects else: self.condition = condition self.effects = [effect] self.time = time assert len(self.effects) == 1
def untyped(self): # We do not actually remove the types from the parameter lists, # just additionally incorporate them into the conditions. # Maybe not very nice. result = copy.copy(self) parameter_atoms = [par.to_untyped_strips() for par in self.parameters] new_precondition = self.precondition.untyped() result.precondition = conditions.Conjunction(parameter_atoms + [new_precondition]) result.effects = [eff.untyped() for eff in self.effects] return result
def normalize(self): effects = [] for eff in self.effects: if isinstance(eff, ObjectFunctionAssignment): results = [] eff.normalize(self.time, results) effects += results else: assert (isinstance(eff, f_expression.FunctionAssignment) or isinstance(eff, conditions.Literal) or isinstance(eff, conditions.ModuleCall) # HACK CHECK ) used_variables = [eff.free_variables()] typed_vars = [] conjunction_parts = [] new_args = [] if isinstance(eff, f_expression.FunctionAssignment): args = [eff.fluent, eff.expression] else: args = eff.args for arg in args: typed, parts, new_arg = arg.compile_objectfunctions_aux( used_variables) typed_vars += typed conjunction_parts += parts new_args.append(new_arg) if len(typed_vars) == 0: effects.append(ConjunctiveEffect([eff], self.time)) else: if isinstance(eff, f_expression.FunctionAssignment): new_eff = eff.__class__(*new_args) else: new_eff = eff.__class__(eff.predicate, new_args) conjunction = conditions.Conjunction(conjunction_parts) if self.time == "start": condition = [ conjunction, conditions.Truth(), conditions.Truth() ] elif self.time == "end": condition = [ conditions.Truth(), conditions.Truth(), conjunction ] else: condition = conjunction cond_eff = ConditionalEffect(condition, new_eff) effects.append( UniversalEffect(typed_vars, cond_eff, self.time)) return TmpEffect(effects)
def parse(alist): iterator = iter(alist) action_tag = next(iterator) assert action_tag == ":action" name = next(iterator) parameters_tag_opt = next(iterator) if parameters_tag_opt == ":parameters": parameters = pddl_types.parse_typed_list(next(iterator), only_variables=True) precondition_tag_opt = next(iterator) else: parameters = [] precondition_tag_opt = parameters_tag_opt if precondition_tag_opt == ":precondition": precondition_list = next(iterator) if not precondition_list: # Note that :precondition () is allowed in PDDL. precondition = conditions.Conjunction([]) else: precondition = conditions.parse_condition(precondition_list) precondition = precondition.simplified() effect_tag = next(iterator) else: precondition = conditions.Conjunction([]) effect_tag = precondition_tag_opt assert effect_tag == ":effect" effect_list = next(iterator) try: cost_eff_pairs = effects.parse_effects(effect_list) if 1 == len(cost_eff_pairs): cost_eff_pairs = [(cost_eff_pairs[0][0], cost_eff_pairs[0][1], '')] else: cost_eff_pairs = [(cost_eff_pairs[i][0], cost_eff_pairs[i][1], "_DETDUP_%d" % i) for i in range(len(cost_eff_pairs))] except ValueError as e: raise SystemExit("Error in Action %s\nReason: %s." % (name, e)) for rest in iterator: assert False, rest return [Action(name + suffix, parameters, len(parameters), precondition, eff, cost) for (cost, eff, suffix) in cost_eff_pairs]
def unary_actions(self): # TODO: An neue Effect-Repräsentation anpassen. result = [] for i, effect in enumerate(self.effects): unary_action = copy.copy(self) unary_action.name += "@%d" % i if isinstance(effect, effects.UniversalEffect): # Careful: Create a new parameter list, the old one might be shared. unary_action.parameters = unary_action.parameters + effect.parameters effect = effect.effect if isinstance(effect, effects.ConditionalEffect): unary_action.precondition = conditions.Conjunction( [unary_action.precondition, effect.condition]).simplified() effect = effect.effect unary_action.effects = [effect] result.append(unary_action) return result
def normalize(self, time, results): used_variables = list(self.head.free_variables() | self.value.free_variables()) typed1, conjunction_parts1, term1 = self.head.compile_objectfunctions_aux( used_variables) typed2, conjunction_parts2, term2 = self.value.compile_objectfunctions_aux( used_variables) assert isinstance(term1, conditions.Variable) add_params = set( [typed for typed in typed1 if not typed.name == term1.name] + typed2) del_params = set(typed1 + typed2) add_conjunction_parts = conjunction_parts1[1:] + conjunction_parts2 del_conjunction_parts = conjunction_parts1 + conjunction_parts2 del_conjunction_parts = conjunction_parts1[1:] + conjunction_parts2 # conjunctive_parts1[0] is left out because we do not need the condition # that the atom in the del effect hast been true before # These conjunction parts are sufficient under the add-after-delete semantics. # Under the consistent effect semantics we need a further condition # that prevents deleting the added predicate. del_param = conjunction_parts1[0].args[-1] del_conjunction_parts.append( conditions.NegatedAtom("=", [del_param, term2])) del_effect = ConjunctiveEffect([ conjunction_parts1[0].negate(), ]) atom_name = conjunction_parts1[0].predicate atom_parts = list(conjunction_parts1[0].args) atom_parts[-1] = term2 add_effect = ConjunctiveEffect([ conditions.Atom(atom_name, atom_parts), ], time) add_conjunction = conditions.Conjunction(add_conjunction_parts) del_conjunction = conditions.Conjunction(del_conjunction_parts) if time == "start": del_condition = [ del_conjunction, conditions.Truth(), conditions.Truth() ] add_condition = [ add_conjunction, conditions.Truth(), conditions.Truth() ] elif time == "end": add_condition = [ conditions.Truth(), conditions.Truth(), add_conjunction ] del_condition = [ conditions.Truth(), conditions.Truth(), del_conjunction ] else: add_condition = add_conjunction del_condition = del_conjunction if len(add_conjunction_parts) > 0: add_effect = ConditionalEffect(add_condition, add_effect, time) del_effect = ConditionalEffect(del_condition, del_effect) if len(add_params) > 0: add_effect = UniversalEffect(add_params, add_effect, time) del_effect = UniversalEffect(del_params, del_effect, time) results.append(add_effect) results.append(del_effect) # value "undefined" must be treated specially because it has not the type # required in del_params if term2.name != "undefined": del_undef_params = set([ typed for typed in del_params if not typed.name == del_param.name ]) atom_parts = list(conjunction_parts1[0].args) atom_parts[-1] = conditions.ObjectTerm("undefined") del_undef_effect = ConjunctiveEffect([ conditions.NegatedAtom(atom_name, atom_parts), ], time) del_undef_conjunction_parts = del_conjunction_parts[:-1] del_undef_conjunction = conditions.Conjunction( del_undef_conjunction_parts) if time == "start": del_undef_condition = [ del_undef_conjunction, conditions.Truth(), conditions.Truth() ] elif time == "end": del_undef_condition = [ conditions.Truth(), conditions.Truth(), del_undef_conjunction ] else: del_undef_condition = del_undef_conjunction if len(del_undef_conjunction_parts) > 0: del_undef_effect = ConditionalEffect(del_undef_condition, del_undef_effect, time) if len(del_undef_params) > 0: del_undef_effect = UniversalEffect(del_undef_params, del_undef_effect, time) results.append(del_undef_effect)