예제 #1
0
 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)
예제 #2
0
    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))
예제 #3
0
 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))
예제 #4
0
 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
예제 #5
0
 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
예제 #6
0
 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
예제 #7
0
 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)
예제 #8
0
 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]
예제 #9
0
 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
예제 #10
0
    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)