FUNCTION_TEMPLATE = '_%s_cost'
def is_concrete(atom):
def constant_from_concrete(atom):
def partition_values(values):
def make_abstract_constant(ty, shared=False):
def has_abstract_inputs(stream):
def replace_abstract_constants(constants, bindings):
def get_target_atoms(universe, plan, static_atoms):
def get_cost_atoms(action):
def get_stream_functions(universe):
def add_stream_cost(universe, atom_nodes, action, stream_cost):
class AbstractConstant(Constant): SEPARATOR = '\n' + 85 * '-' + '\n' class Initialize(Formula):

    def __init__(self, atom, value):
        """
        Formula atom (= F N) which initializes the value of an atom of :class:`.Function`.

        :param atom: an :class:`.Atom` of :class:`.Function`
        :param value: the numeric value of ``value``
        """
        self.atom = atom
        self.value = value

    def get_atoms(self): return set()

    def get_formulas(self): return []

    def get_quantified(self): return set()

    def pddl(self):
        return '(= %s %s)' % (self.atom.pddl(), self.value)
    __repr__ = pddl class Atom(Formula, Condition, Effect):

    def __init__(self, predicate, args):
        """
        Atomic formula (P O1 O2 ... ON).

        :param predicate: the :class:`.Predicate` form of the atom
        :param args: a list of :class:`.Object` arguments to ``predicate``
        :raises ValueError: if ``predicate.types`` does not match the types of ``args``
        .. automethod:: __invert__
        """
        if not all(isinstance(arg, Object) for arg in args):
            raise ValueError(
                'Expected atom arguments %s to extend class Object' % args)
        if len(predicate.types) != len(args):
            raise ValueError('Expected atom arguments %s to have the same length as predicate types %s' % (
                args, predicate.types))
        arg_types = tuple(arg.type for arg in args)
        if not all(ty == arg_ty or ty == OBJECT for ty, arg_ty in zip(predicate.types, arg_types)):
            raise ValueError('Expected atom argument types %s to be the same as predicate types %s' % (
                arg_types, predicate.types))
        self.predicate = predicate
        self.args = tuple(args)
        self._hash = None

    @property
    def name(self): return self.predicate.name

    @property
    def types(self): return self.predicate.types

    @property
    def function(self): return self.predicate

    def get_atoms(self): return {self}

    def get_literals(self): return [[self]]

    def get_formulas(self): return []

    def get_quantified(self): return set()

    def substitute(self, atom, subformula): pass

    def holds(self, atoms, constants): return self in atoms

    def positive_supporters(self, atoms, constants): return {
        self} if self.holds(atoms, constants) else None

    def negative_supporters(self, atoms, constants): return None if self.holds(
        atoms, constants) else {self}

    def add(self, atoms, constants): return [self]

    def delete(self, atoms, constants): return []

    def is_function(self): return isinstance(self.function, Function)

    def get_parameters(self):
        return set(arg for arg in self.args if isinstance(arg, Parameter))

    def propositional(self, constants): return self

    def dequantify(self, constants): return self

    def instantiate(self, parameter_map):
        return Atom(self.predicate, [parameter_map[arg] if arg in parameter_map else arg for arg in self.args])

    def de_morgan(self, sign=True):
        return self if sign else stripstream.pddl.logic.connectives.Not(self)

    def __invert__(self):
        """
        Negates the atom.

        :return: :class:`.Not` of the atom
        """
        return stripstream.pddl.logic.connectives.Not(self)

    def __eq__(self, other):
        return type(self) == type(other) and self.predicate == other.predicate and self.args == other.args

    def __ne__(self, other):
        return not(self == other)

    def __hash__(self):
        if self._hash is None:
            self._hash = hash((self.__class__, self.predicate, self.args))
        return self._hash

    def __repr__(self):
        return self.predicate.name + '(' + ','.join(repr(arg) for arg in self.args) + ')'

    def pddl(self):
        return '(' + ' '.join([self.name] + [arg.pddl() for arg in self.args]) + ')'

    def typed_pddl(self):
        return '(' + self.name + ''.join(' ' + arg.typed_pddl() for arg in self.args) + ')' class Head(object):
class Predicate(Head):
class EasyPredicate(Predicate):
class Function(Head):
class EasyFunction(Function):
    def __init__(self, name, types=tuple()):
    def __call__(self, *args):
    def __eq__(self, other):
    def __ne__(self, other):
    def __hash__(self):
    def pddl(self):
    def __repr__(self):
    def __init__(self, *types):
    def __init__(self, *types):
def convert_args(self, args): class Parameter(Object):

    def __init__(self, name, type):
        """
        PDDL parameter which extends :class:`.Object`.

        :param name: the string name of the parameter
        :param type: the :class:`.Type` of the parameter
        """
        super(Parameter, self).__init__(PARAM_PREFIX + name, type)

    @property
    def original(self):
        return self.name[len(PARAM_PREFIX):] class Constant(Object):
    pass
    """
  PDDL constant which extends :class:`.Object`.
  """ class Action(Operator):
    """
    PDDL action class.

    .. code:: python

      CONF = EasyType()
      AtConf = EasyPredicate(CONF, CONF)
      Q1, Q1 = EasyParameter(CONF), EasyParameter(CONF)

      a = Action(name='move', parameters=[Q1, Q2],
                 condition=AtConf(Q1),
                 effect=And(AtConf(Q2), Not(AtConf(Q1))))
    """

    def __init__(self, name, parameters, condition, effect, cost=None):
        """
        :param name: the name of the action
        :param parameters: a list of :class:`.Parameter`
        :param condition: a :class:`.Condition`
        :param effect: an :class:`.Effect`
        :param cost: a numeric cost
        """
        super(Action, self).__init__(parameters, condition, effect)
        self.name = name.lower()
        self.cost_included = False
        self.cost = cost

    def instantiate(self, args): return ActionInstance(self, args)

    def pddl(self, costs):
        s = '(:action ' + self.name + '\n'
        s += '\t:parameters (' + ' '.join(param.typed_pddl()
                                          for param in self.parameters) + ')\n'
        s += '\t:precondition ' + self.condition.pddl() + '\n'
        augmented_effect = self.effect
        if costs and self.cost is not None and not self.cost_included:
            augmented_effect = And(augmented_effect, Cost(self.cost))
        s += '\t:effect ' + augmented_effect.pddl()
        return s + ')'

    def to_strips(self, constants):
        condition = self.condition.dequantify(constants)
        effect = self.effect.dequantify(constants)
        all_parameters = condition.get_parameters() | effect.get_parameters()
        parameters = list(self.parameters) + \
            [p for p in all_parameters if p not in self.parameters]
        [effs] = effect.get_literals()
        for i, cons in enumerate(condition.get_literals()):
            instance = STRIPSAction('%s_%s' % (
                self.name, i), parameters, cons, effs)
            instance.original = self
            yield instance

    def clone(self):
        return Action(self.name[:], self.parameters[:], self.condition.clone(), self.effect.clone())

    def __repr__(self):
        return self.name
    __str__ = __repr__ class Axiom(Operator):
    """
    PDDL axiom (derived predicate).

    .. code:: python

      BLOCK, POSE = EasyType(), EasyType()
      AtPose = EasyPredicate(BLOCK, POSE)
      CollisionFree = EasyPredicate(POSE, POSE)
      Safe = EasyPredicate(BLOCK, POSE)
      B2 = EasyParameter(BLOCK)
      P1, P2 = EasyParameter(POSE), EasyParameter(POSE)

      x = Axiom(effect=Safe(B2, P1),
                condition=Exists([P2], And(AtPose(B2, P2), CollisionFree(P1, P2))))
    """

    def __init__(self, effect, condition):
        """
        :param effect: the :class:`.Atom` derived predicate
        :param condition: a :class:`.Condition`
        """
        if not isinstance(effect, Atom):
            raw_input('Axiom effect must be an Atom: %s' % effect)

        super(Axiom, self).__init__(effect.args, condition, effect)

    def instantiate(self, args): return AxiomInstance(self, args)

    def to_strips(self, constants):
        condition = self.condition.dequantify(constants)
        for i, cons in enumerate(condition.get_literals()):
            instance = STRIPSAxiom(cons, [self.effect])
            instance.original = self
            yield instance

    def pddl(self):
        return '(:derived %s\n\t%s)' % (self.effect.typed_pddl(), self.condition.pddl())

    def clone(self):
        return Axiom(self.condition.clone(), self.effect.clone())

    def __repr__(self):
        return self.effect.name
    __str__ = __repr__ INF = float('inf') def parameter_product(conditions, condition_values, objects, object_values):
    params = {}
    combos = [[]]
    for ci, cond in enumerate(conditions):
        cond_params = dict(zip(cond.args, range(len(cond.args))))
        intersect = set(params) & set(cond_params)
        new_indices = [i for i, a in enumerate(
            cond.args) if a not in intersect]
        new_combos = []
        for combo in combos:
            for value in condition_values[ci]:
                if all(combo[params[a]] == value.args[cond_params[a]] for a in intersect):
                    new_combos.append(combo + [value.args[i]
                                               for i in new_indices])
        for i in new_indices:
            params[cond.args[i]] = len(params)
        combos = new_combos

    new_indices = [i for i, obj in enumerate(objects) if obj not in params]
    for i in new_indices:
        params[objects[i]] = len(params)
    if not params:
        return
    param_order, _ = zip(*sorted(params.items(), key=lambda (_, i): i))
    values = [object_values[i] for i in new_indices]
    for value in product(*values):
        for combo in combos:
            yield dict(zip(param_order, combo + list(value))) def instantiate_axioms(universe):
    return instantiate_operators(universe.axioms, universe.type_to_objects) def parameter_product2(parameters, parameter_values, conditions, condition_values):
    combo_index = {}
    combos = [[]]
    for cond in conditions:
        cond_index = dict(zip(cond.args, range(len(cond.args))))
        cond_parameters = set(parameters) & set(cond_index)
        intersect_parameters = cond_parameters & set(combo_index)
        free_parameters = cond_parameters - intersect_parameters
        new_indices = [i for i, a in enumerate(
            cond.args) if a in free_parameters]
        for i in new_indices:
            combo_index[cond.args[i]] = len(combo_index)
        new_combos = []
        for combo in combos:
            for value in condition_values:
                if cond.predicate == value.predicate and all(a1 in cond_parameters or a1 == a2 for a1, a2 in zip(cond.args, value.args)) and all(combo[combo_index[a]] == value.args[cond_index[a]] for a in intersect_parameters):
                    new_combos.append(combo + [value.args[i]
                                               for i in new_indices])
        combos = new_combos

    new_indices = [i for i, obj in enumerate(
        parameters) if obj not in combo_index]
    for i in new_indices:
        combo_index[parameters[i]] = len(combo_index)
    if not combo_index:
        return
    param_order, _ = zip(*sorted(combo_index.items(), key=lambda (_, i): i))
    values = [filter(lambda v: parameters[i].type == v.type,
                     parameter_values) for i in new_indices]
    for value in product(*values):
        for combo in combos:
            yield dict(zip(param_order, combo + list(value)))
from collections import defaultdict, namedtuple
from time import time
from operator import attrgetter
from stripstream.algorithms.focused.utils import AbstractConstant, Concrete, partition_values
from stripstream.utils import SEPARATOR
from stripstream.pddl.logic.atoms import Initialize, Atom
from stripstream.pddl.logic.predicates import Predicate, TotalCost, Function
from stripstream.pddl.objects import Parameter, Constant
from stripstream.pddl.operators import Action, Axiom
from stripstream.utils import INF
from stripstream.algorithms.instantiation import parameter_product, instantiate_axioms, parameter_product2
                    lambda c: c.predicate in stream_predicates, act.condition.get_atoms())
                for con in self.act_stream_conditions[act]:
                    self.act_conditions[con.predicate].append((act, con))
                con_params = {a for con in self.act_stream_conditions[
                    act] for a in con.args}
                self.act_free_params[act] = [
                    p for p in act.parameters if p not in con_params]
                for param in self.act_free_params[act]:
                    self.act_params[param.type].append((act, param))

        for cs in problem.cond_streams:
            self.add_cond_stream(cs)
        for atom in problem.initial_atoms:
            if isinstance(atom, Initialize):
                self.add_perm_initialize(atom)
            else:
                self.add_initial_atom(atom)
        self.add_formula(self.goal_formula)
        for obj in problem.objects:
            self.add_object(obj)
        for operator in problem.operators:
            if isinstance(operator, Action):
                self.add_action(operator)
            elif isinstance(operator, Axiom):
                self.add_axiom(operator)

        if self.verbose:
            print 'Fluents:', self.fluent_predicates
            print 'Derived:', set(self.derived_predicates)
            print 'Stream:', self.stream_predicates
            print 'Static:', self.static_predicates

        self.stream_atoms.update(self.initial_stream_atoms())

    @property
    def fixed_predicates(self):
        return set(self.predicates.values()) - self.fluent_predicates - set(self.derived_predicates)

    @property
    def static_predicates(self):
        return self.fixed_predicates - self.stream_predicates

    @property
    def actions(self):
        return self.name_to_action.values()

    def get_object(self, name):
        return self.name_to_object[name]

    def get_action(self, name):
        return self.name_to_action[name]

    def is_internal(self, atom):
        return atom.predicate in [Concrete]

    def is_static(self, atom):
        return atom.predicate in self.static_predicates

    def is_fluent(self, atom):
        return atom.predicate in self.fluent_predicates

    def is_derived(self, atom):
        return atom.predicate in self.derived_predicates

    def is_stream(self, atom):
        return atom.predicate in self.stream_predicates

    def add_stream(self, cond_stream, combo):

        stream = cond_stream(combo)
        self.new_streams.append(stream)

    def add_cond_stream(self, cs):
        for atom in cs.conditions + cs.effects:

            if isinstance(atom.predicate, Predicate):
                self.add_predicate(atom.predicate)
                if self.is_derived(atom):
                    raise ValueError(
                        '%s is a stream and derived predicate' % atom.predicate)
                if self.is_fluent(atom):
                    raise ValueError(
                        '%s is a stream and fluent predicate' % atom.predicate)
                self.stream_predicates.add(atom.predicate)
        if self.make_stream_instances:
            for con in cs.conditions:
                self.cond_conditions[con.predicate].append((cs, con))
            for param in cs.free_params:
                self.cond_params[param.type].append((cs, param))
            if len(cs.inputs) == 0:
                self.add_stream(cs, tuple())

    def add_type(self, ty):
        if ty not in self.type_to_objects:
            self.type_to_objects[ty] = set()

    def add_object(self, obj):
        assert isinstance(obj, Constant)

        self.add_type(obj.type)
        if obj in self.type_to_objects[obj.type]:
            return False

        self.new_problem = True
        self.name_to_object[obj.name] = obj
        self.type_to_objects[obj.type].add(obj)
        if obj in self.object_to_type:
            raise RuntimeError('Cannot share objects across types: %s vs %s' % (
                obj.type, self.object_to_type[obj]))
        assert obj not in self.object_to_type
        self.object_to_type[obj] = obj.type
        if self.use_ground and not isinstance(obj, AbstractConstant):
            self.add_initial_atom(Concrete(obj))

        if self.make_stream_instances and obj.type in self.cond_params:
            for cs, param in self.cond_params[obj.type]:
                con_values = [self.predicate_to_atoms[cond.predicate]
                              for cond in cs.conditions]
                param_values = [self.type_to_objects.get(other.type, []) if param != other else [
                    obj] for other in cs.free_params]

                for param_map in parameter_product(cs.conditions, con_values, cs.free_params, param_values):