Beispiel #1
0
    def _convert_problem(self,
                         msg: proto.Problem,
                         env: Optional[Environment] = None) -> Problem:
        problem = Problem(name=msg.problem_name, env=env)

        for t in msg.types:
            problem._add_user_type(self.convert(t, problem))
        for obj in msg.objects:
            problem.add_object(self.convert(obj, problem))
        for f in msg.fluents:
            problem.add_fluent(
                self.convert(f, problem),
                default_initial_value=self.convert(f.default_value, problem)
                if f.HasField("default_value") else None,
            )
        for f in msg.actions:
            problem.add_action(self.convert(f, problem))
        for eff in msg.timed_effects:
            ot = self.convert(eff.occurrence_time, problem)
            effect = self.convert(eff.effect, problem)
            problem.add_timed_effect(
                timing=ot,
                fluent=effect.fluent,
                value=effect.value,
                condition=effect.condition,
            )

        for assign in msg.initial_state:
            problem.set_initial_value(
                fluent=self.convert(assign.fluent, problem),
                value=self.convert(assign.value, problem),
            )

        for g in msg.goals:
            goal = self.convert(g.goal, problem)
            if str(g.timing) == "":
                problem.add_goal(goal)
            else:
                timing = self.convert(g.timing)
                problem.add_timed_goal(interval=timing, goal=goal)

        for metric in msg.metrics:
            problem.add_quality_metric(self.convert(metric, problem))

        return problem
    def get_rewritten_problem(self) -> Problem:
        '''Creates a problem that is a copy of the original problem
        but every ngeative fluent into action preconditions or overall
        goal is replaced by the fluent representing his negative.'''
        if self._new_problem is not None:
            return self._new_problem

        if self._problem.kind.has_simulated_effects():  # type: ignore
            raise up.exceptions.UPUsageError(
                'NegativeConditionsRemover does not work with simulated effects'
            )

        #NOTE that a different environment might be needed when multi-threading
        self._new_problem = Problem(f'{self._name}_{self._problem.name}',
                                    self._env)
        for o in self._problem.all_objects:
            self._new_problem.add_object(o)
        assert self._new_problem is not None

        name_action_map: Dict[str, Union[InstantaneousAction,
                                         DurativeAction]] = {}
        for action in self._problem.actions:
            if isinstance(action, InstantaneousAction):
                new_action = action.clone()
                new_action.name = self.get_fresh_name(action.name)
                new_action.clear_preconditions()
                for p in action.preconditions:
                    np = self._fluent_remover.remove_negative_fluents(p)
                    new_action.add_precondition(np)
                for ce in new_action.conditional_effects:
                    ce.set_condition(
                        self._fluent_remover.remove_negative_fluents(
                            ce.condition))
                name_action_map[action.name] = new_action
            elif isinstance(action, DurativeAction):
                new_durative_action = action.clone()
                new_durative_action.name = self.get_fresh_name(action.name)
                new_durative_action.clear_conditions()
                for i, cl in action.conditions.items():
                    for c in cl:
                        nc = self._fluent_remover.remove_negative_fluents(c)
                        new_durative_action.add_condition(i, nc)
                for t, cel in new_durative_action.conditional_effects.items():
                    for ce in cel:
                        ce.set_condition(
                            self._fluent_remover.remove_negative_fluents(
                                ce.condition))
                name_action_map[action.name] = new_durative_action
            else:
                raise NotImplementedError

        for t, el in self._problem.timed_effects.items():
            for e in el:
                self._new_problem._add_effect_instance(t, e.clone())

        for t, el in self._new_problem.timed_effects.items():
            for e in el:
                if e.is_conditional():
                    e.set_condition(
                        self._fluent_remover.remove_negative_fluents(
                            e.condition))

        for i, gl in self._problem.timed_goals.items():
            for g in gl:
                ng = self._fluent_remover.remove_negative_fluents(g)
                self._new_problem.add_timed_goal(i, ng)

        for g in self._problem.goals:
            ng = self._fluent_remover.remove_negative_fluents(g)
            self._new_problem.add_goal(ng)

        #fluent_mapping is the map between a fluent and it's negation, when the
        # negation is None it means the fluent is never found in a negation into
        # every condititon analized before; therefore it does not need to exist.
        fluent_mapping = self._fluent_remover.fluent_mapping
        for f in self._problem.fluents:
            self._new_problem.add_fluent(f)
            fneg = fluent_mapping.get(f, None)
            if fneg is not None:
                self._new_problem.add_fluent(fneg)

        for fl, v in self._problem.initial_values.items():
            fneg = fluent_mapping.get(fl.fluent(), None)
            self._new_problem.set_initial_value(fl, v)
            if fneg is not None:
                if v.bool_constant_value():
                    self._new_problem.set_initial_value(
                        self._env.expression_manager.FluentExp(
                            fneg, tuple(fl.args)),
                        self._env.expression_manager.FALSE())
                else:
                    self._new_problem.set_initial_value(
                        self._env.expression_manager.FluentExp(
                            fneg, tuple(fl.args)),
                        self._env.expression_manager.TRUE())

        for action in self._problem.actions:
            if isinstance(action, InstantaneousAction):
                new_action = name_action_map[action.name]
                new_effects: List[Effect] = []
                for e in new_action.effects:
                    fl, v = e.fluent, e.value
                    fneg = fluent_mapping.get(fl.fluent(), None)
                    if fneg is not None:
                        simplified_not_v = self._simplifier.simplify(
                            self._env.expression_manager.Not(v))
                        new_effects.append(
                            Effect(
                                self._env.expression_manager.FluentExp(
                                    fneg, tuple(fl.args)), simplified_not_v,
                                e.condition, e.kind))
                for ne in new_effects:
                    new_action._add_effect_instance(ne)
                self._new_problem.add_action(new_action)
                self._old_to_new[action] = [new_action]
                self._new_to_old[new_action] = action
            elif isinstance(action, DurativeAction):
                new_durative_action = name_action_map[action.name]
                new_durative_action.set_duration_constraint(action.duration)

                for t, el in new_durative_action.effects.items():
                    for e in el:
                        fl, v = e.fluent, e.value
                        fneg = fluent_mapping.get(fl.fluent(), None)
                        if fneg is not None:
                            simplified_not_v = self._simplifier.simplify(
                                self._env.expression_manager.Not(v))
                            new_durative_action._add_effect_instance(
                                t,
                                Effect(
                                    self._env.expression_manager.FluentExp(
                                        fneg, tuple(fl.args)),
                                    simplified_not_v, e.condition, e.kind))
                self._new_problem.add_action(new_durative_action)
                self._old_to_new[action] = [new_durative_action]
                self._new_to_old[new_durative_action] = action
            else:
                raise NotImplementedError

        for t, el in self._new_problem.timed_effects.items():
            for e in el:
                fl, v = e.fluent, e.value
                fneg = fluent_mapping.get(fl.fluent(), None)
                if fneg is not None:
                    simplified_not_v = self._simplifier.simplify(
                        self._env.expression_manager.Not(v))
                    self._new_problem._add_effect_instance(
                        t,
                        Effect(
                            self._env.expression_manager.FluentExp(
                                fneg, tuple(fl.args)), simplified_not_v,
                            e.condition, e.kind))

        return self._new_problem