# Path: stripstream/pddl/logic/atoms.py
# 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


from collections import defaultdict
from itertools import product
from stripstream.pddl.logic.atoms import Initialize


def instantiate_actions(universe):
    return instantiate_operators(universe.actions, universe.type_to_objects)


def instantiate_axioms(universe):
    return instantiate_operators(universe.axioms, universe.type_to_objects)


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:

# Path: stripstream/pddl/logic/atoms.py
# 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


# Path: stripstream/algorithms/instantiation.py
from collections import defaultdict
from itertools import product
from stripstream.pddl.logic.atoms import Initialize



def instantiate_actions(universe):
    return instantiate_operators(universe.actions, universe.type_to_objects)


def instantiate_axioms(universe):
    return instantiate_operators(universe.axioms, universe.type_to_objects)


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)