Beispiel #1
0
class STRIPStreamProblem(object):
    def __init__(self,
                 initial_atoms,
                 goal_literals,
                 operators,
                 cond_streams,
                 objects=[]):

        self.initial_atoms = list(initial_atoms)
        if isinstance(goal_literals, Iterable):
            self.goal_literals = And(*goal_literals)
        elif isinstance(goal_literals, Formula):
            self.goal_literals = goal_literals

        else:
            raise ValueError(goal_literals)
        self.operators = operators
        self.cond_streams = cond_streams
        self.objects = objects

    def is_strips(self):
        return all(
            isinstance(op, STRIPSAction) or isinstance(op, STRIPSAxiom)
            for op in self.operators)

    def convert_goal(self, axiom=True):
        from stripstream.pddl.logic.predicates import NamedPredicate
        from stripstream.pddl.operators import Action, Axiom
        Goal = NamedPredicate('_goal')
        if axiom:
            operator = Axiom(effect=Goal(), condition=self.goal_literals)
        else:
            operator = Action(name='_achieve_goal',
                              parameters=[],
                              condition=self.goal_literals,
                              effect=Goal(),
                              cost=None)
        operator.is_internal = True
        self.operators.append(operator)
        self.goal_literals = Goal()

    def replace_axioms(self):
        derived = {}
        for op in self.operators:
            if isinstance(op, Axiom):
                derived[op.effect.predicate] = op
        actions = []
        for action in self.operators:
            if isinstance(action, Action):
                substitute_axioms(action.condition, derived)
                actions.append(action)
        self.operators = actions
        substitute_axioms(self.goal_literals, derived)

    def convert_axioms_to_effects(self):
        derived_predicates = self.get_derived_predicates()
        fluent_predicates = self.get_fluent_predicates()
        constants = defaultdict(set)
        for const in self.get_constants():
            constants[const.type].add(const)

        mapping = []
        for op in self.operators:
            if isinstance(op, Axiom):
                [conditions
                 ] = op.condition.dequantify(constants).get_literals()
                assert not filter(lambda a: a.predicate in derived_predicates,
                                  conditions)
                print conditions
                [fluent] = filter(lambda a: a.predicate in fluent_predicates,
                                  conditions)
                others = filter(lambda a: a != fluent, conditions)
                mapping.append((fluent, others, op.effect))

        new_operators = []
        for op in self.operators:
            if isinstance(op, Action):
                new_op = op.clone()
                new_operators.append(new_op)
                [literals] = new_op.effect.get_literals()
                for literal in literals:
                    effect = literal.formula if isinstance(literal,
                                                           Not) else literal
                    for fluent, conditions, derived in mapping:
                        if effect.predicate == fluent.predicate:
                            free_params = set(
                                flatten(
                                    map(lambda a: a.args, [derived] +
                                        conditions))) - set(fluent.args)
                            param_map = dict(zip(fluent.args, effect.args))
                            for i, param in enumerate(free_params):

                                param_map[param] = Parameter(
                                    'l%s' % i, param.type)

                            new_params = list(
                                set(param_map.values()) - set(effect.args))
                            new_derived = derived.instantiate(param_map)
                            new_conditions = [
                                cond.instantiate(param_map)
                                for cond in conditions
                            ]
                            if isinstance(literal, Not):
                                new_op.add_effects(
                                    ForAll(
                                        new_params,
                                        When(And(*new_conditions),
                                             new_derived)))
                            else:
                                new_op.add_effects(
                                    ForAll(
                                        new_params,
                                        When(And(*new_conditions),
                                             Not(new_derived))))

        return new_operators

    def to_strips(self):
        constants = defaultdict(set)
        for const in self.get_constants():
            constants[const.type].add(const)
        new_operators = []
        for operator in self.operators:
            for strips in operator.to_strips(constants):
                new_operators.append(strips)
        self.operators = new_operators

    def new_problem(self, initial_atoms):
        return STRIPStreamProblem(initial_atoms, self.goal_literals,
                                  self.operators, self.cond_streams,
                                  self.objects)

    def get_constants(self):
        objects = set(self.objects)
        for atom in self.initial_atoms:
            objects.update(atom.args)
        if isinstance(self.goal_literals, Formula):
            for atom in self.goal_literals.get_atoms():
                objects.update(atom.args)

        for operator in self.operators:
            for atom in operator.condition.get_atoms(
            ) | operator.effect.get_atoms():
                objects.update(atom.args)
        for cs in self.cond_streams:
            for atom in cs.conditions + cs.effects:
                objects.update(atom.args)
        return filter(lambda o: isinstance(o, Constant), objects)

    def get_fluent_predicates(self):
        from stripstream.pddl.operators import Action
        fluents = set()
        for operator in self.operators:
            if isinstance(operator, Action):
                fluents.update(
                    {atom.predicate
                     for atom in operator.effect.get_atoms()})
        return fluents

    def get_derived_predicates(self):
        from stripstream.pddl.operators import Axiom
        return set(operator.effect.predicate for operator in self.operators
                   if isinstance(operator, Axiom))

    def get_stream_predicates(self):
        return {
            atom.predicate
            for cs in self.cond_streams for atom in cs.conditions + cs.effects
        }

    def get_predicates(self):
        return {
            atom.predicate
            for op in self.operators
            for atom in op.condition.get_atoms() | op.effect.get_atoms()
        } | {
            atom.predicate
            for cs in self.cond_streams for atom in cs.conditions + cs.effects
        } | {atom.predicate
             for atom in self.initial_atoms
             } | {atom.predicate
                  for atom in self.goal_literals.get_atoms()}

    def get_static_predicates(self):
        return self.get_predicates() - self.get_fluent_predicates(
        ) - self.get_derived_predicates() - self.get_stream_predicates()

    def __repr__(self):
        return 'STRIPStream Problem\n' 'Initial: %s\n' 'Goal: %s\n' 'Operators: %s\n' 'Streams: %s\n' 'Constants: %s' % (
            self.initial_atoms, self.goal_literals, self.operators,
            self.cond_streams, self.objects)
class STRIPStreamProblem(object):
    def __init__(self,
                 initial_atoms,
                 goal_literals,
                 operators,
                 cond_streams,
                 objects=[]):
        # TODO - warnings for improperly passed types here
        self.initial_atoms = list(initial_atoms)
        if isinstance(goal_literals, Atom):
            self.goal_literals = And(goal_literals)
        elif isinstance(goal_literals, Iterable):
            self.goal_literals = And(*goal_literals)
        elif isinstance(
                goal_literals,
                Formula):  # or isinstance(goal_literals, AbsCondition):
            self.goal_literals = goal_literals
        else:
            raise ValueError(goal_literals)
        # TODO - assert goals aren't empty
        self.operators = operators
        self.cond_streams = cond_streams
        self.objects = objects

    def get_constants(self):
        objects = set(self.objects)
        for atom in self.initial_atoms:
            objects.update(atom.args)
        if isinstance(self.goal_literals, Formula):
            for atom in self.goal_literals.get_atoms():
                objects.update(atom.args)
        #elif isinstance(self.goal_literals, AbsCondition):
        #  for formula in self.goal_literals.conditions:
        #    for atom in formula.get_atoms():
        #      objects.update(atom.args)
        for operator in self.operators:
            for atom in operator.condition.get_atoms(
            ) | operator.effect.get_atoms():
                objects.update(atom.args)
        for cs in self.cond_streams:
            for atom in cs.conditions + cs.effects:
                objects.update(atom.args)
        return filter(lambda o: isinstance(o, Constant), objects)

    def get_functions(self):
        from stripstream.pddl.operators import get_function_atoms
        functions = set()
        for operator in self.operators:
            if isinstance(operator, Action):
                functions.update(
                    {atom.predicate
                     for atom in get_function_atoms(operator)})
        return functions

    def get_fluent_predicates(
            self
    ):  # TODO - enforce consistency for these and make them a property
        from stripstream.pddl.operators import Action
        fluents = set()
        for operator in self.operators:
            if isinstance(operator, Action):
                fluents.update(
                    {atom.predicate
                     for atom in operator.effect.get_atoms()})
        return fluents

    def get_derived_predicates(self):
        from stripstream.pddl.operators import Axiom
        return set(operator.effect.predicate for operator in self.operators
                   if isinstance(operator, Axiom))

    def get_stream_predicates(self):
        return {
            atom.predicate
            for cs in self.cond_streams for atom in cs.conditions + cs.effects
        }

    def get_predicates(self):
        return {atom.predicate for op in self.operators for atom in op.condition.get_atoms() | op.effect.get_atoms()} | \
          {atom.predicate for cs in self.cond_streams for atom in cs.conditions+cs.effects} | \
          {atom.predicate for atom in self.initial_atoms} | \
          {atom.predicate for atom in self.goal_literals.get_atoms()}

    def get_static_predicates(self):
        return self.get_predicates() - self.get_fluent_predicates() - \
               self.get_derived_predicates() - self.get_stream_predicates()

    def __repr__(self):
        return 'STRIPStream Problem\n' \
               'Initial: %s\n' \
               'Goal: %s\n' \
               'Operators: %s\n' \
               'Streams: %s\n' \
               'Constants: %s'%(self.initial_atoms, self.goal_literals,
                                self.operators, self.cond_streams, self.objects)