# Path: stripstream/pddl/logic/formulas.py
# class Formula(object):
# 
#     def is_valid_condition(self):
#         return isinstance(self, Condition) and all(f.is_valid_condition() for f in self.get_formulas())
# 
#     def is_valid_effect(self):
#         return isinstance(self, Effect) and all(f.is_valid_effect() for f in self.get_formulas())
# 
#     def get_atoms(self): raise NotImplementedError()
# 
#     def get_literals(self): raise NotImplementedError()
# 
#     def get_formulas(self): raise NotImplementedError()
# 
#     def de_morgan(self, sign=True): raise NotImplementedError()
# 
#     def simplify(self): return self
# 
#     def get_objects(self):
#         return set(flatten(atom.args for atom in self.get_atoms()))
# 
#     def get_parameters(self):
#         return set(flatten(atom.get_parameters() for atom in self.get_atoms()))
# 
#     def get_quantified(self): raise NotImplementedError()
# 
#     def propositional(self, constants): raise NotImplementedError()
# 
#     def dequantify(self, constants): raise NotImplementedError()
# 
#     def instantiate(self, parameter_map): raise NotImplementedError()
# 
#     def clone(self): return self.instantiate({})
# 
#     def substitute(self, atom, subformula): raise NotImplementedError()
# 
#     def pddl(self): raise NotImplementedError()
#     __repr__ = pddl
#     """
#   Logical formula abstract class.
#   """
# 
# class Condition():
# 
#     def holds(self, atoms, constants): raise NotImplementedError()
# 
#     def positive_supporters(
#         self, atoms, constants): raise NotImplementedError()
# 
#     def negative_supporters(
#         self, atoms, constants): raise NotImplementedError()
#     """
#   Legal condition component interface.
#   """
# 
# class Effect():
# 
#     def add(self, atoms, constants): raise NotImplementedError()
# 
#     def delete(self, atoms, constants): raise NotImplementedError()
#     """
#   Legal effect component interface.
#   """
# 
# Path: stripstream/utils.py
# def flatten(iterable_of_iterables):
#     return (item for iterables in iterable_of_iterables for item in iterables)
# 
# Path: stripstream/pddl/logic/utils.py
# def invert(literal):
# def is_literal(f):
# def is_conjunction(f):
# def get_literals(f):
# def get_increases(f):


from stripstream.pddl.logic.formulas import Formula, Condition, Effect
from stripstream.utils import flatten
from itertools import product
from stripstream.pddl.logic import utils
import stripstream.pddl.logic.atoms
import operator
        formulas = [f.simplify()
                    for f in combine_connectives(self, self.__class__)]
        if len(formulas) == 1:
            return formulas[0]
        return self.__class__(*formulas)

    def substitute(self, atom, subformula):
        new_formulas = list(self.formulas)
        for i, formula in enumerate(self.formulas):
            if isinstance(formula, stripstream.pddl.logic.atoms.Atom) and formula.predicate == atom.predicate:
                new_formulas[i] = subformula.instantiate(
                    dict(zip(atom.args, self.formulas[i].args)))
            else:
                formula.substitute(atom, subformula)
        self.formulas = tuple(new_formulas)

    def propositional(self, constants):
        return self.__class__(*[formula.propositional(constants) for formula in self.formulas])

    def dequantify(self, constants):
        return self.__class__(*[formula.dequantify(constants) for formula in self.formulas])

    def instantiate(self, parameter_map):
        return self.__class__(*[formula.instantiate(parameter_map) for formula in self.formulas])

    def pddl(self):
        return '(%s %s)' % (self._pddl_name, ' '.join(formula.pddl() for formula in self.formulas))
    __repr__ = pddl



# Path: stripstream/pddl/logic/formulas.py
# class Formula(object):
# 
#     def is_valid_condition(self):
#         return isinstance(self, Condition) and all(f.is_valid_condition() for f in self.get_formulas())
# 
#     def is_valid_effect(self):
#         return isinstance(self, Effect) and all(f.is_valid_effect() for f in self.get_formulas())
# 
#     def get_atoms(self): raise NotImplementedError()
# 
#     def get_literals(self): raise NotImplementedError()
# 
#     def get_formulas(self): raise NotImplementedError()
# 
#     def de_morgan(self, sign=True): raise NotImplementedError()
# 
#     def simplify(self): return self
# 
#     def get_objects(self):
#         return set(flatten(atom.args for atom in self.get_atoms()))
# 
#     def get_parameters(self):
#         return set(flatten(atom.get_parameters() for atom in self.get_atoms()))
# 
#     def get_quantified(self): raise NotImplementedError()
# 
#     def propositional(self, constants): raise NotImplementedError()
# 
#     def dequantify(self, constants): raise NotImplementedError()
# 
#     def instantiate(self, parameter_map): raise NotImplementedError()
# 
#     def clone(self): return self.instantiate({})
# 
#     def substitute(self, atom, subformula): raise NotImplementedError()
# 
#     def pddl(self): raise NotImplementedError()
#     __repr__ = pddl
#     """
#   Logical formula abstract class.
#   """
# 
# class Condition():
# 
#     def holds(self, atoms, constants): raise NotImplementedError()
# 
#     def positive_supporters(
#         self, atoms, constants): raise NotImplementedError()
# 
#     def negative_supporters(
#         self, atoms, constants): raise NotImplementedError()
#     """
#   Legal condition component interface.
#   """
# 
# class Effect():
# 
#     def add(self, atoms, constants): raise NotImplementedError()
# 
#     def delete(self, atoms, constants): raise NotImplementedError()
#     """
#   Legal effect component interface.
#   """
# 
# Path: stripstream/utils.py
# def flatten(iterable_of_iterables):
#     return (item for iterables in iterable_of_iterables for item in iterables)
# 
# Path: stripstream/pddl/logic/utils.py
# def invert(literal):
# def is_literal(f):
# def is_conjunction(f):
# def get_literals(f):
# def get_increases(f):


# Path: stripstream/pddl/logic/connectives.py
from stripstream.pddl.logic.formulas import Formula, Condition, Effect
from stripstream.utils import flatten
from itertools import product
from stripstream.pddl.logic import utils
import stripstream.pddl.logic.atoms
import operator

        formulas = [f.simplify()
                    for f in combine_connectives(self, self.__class__)]
        if len(formulas) == 1:
            return formulas[0]
        return self.__class__(*formulas)

    def substitute(self, atom, subformula):
        new_formulas = list(self.formulas)
        for i, formula in enumerate(self.formulas):
            if isinstance(formula, stripstream.pddl.logic.atoms.Atom) and formula.predicate == atom.predicate:
                new_formulas[i] = subformula.instantiate(
                    dict(zip(atom.args, self.formulas[i].args)))
            else:
                formula.substitute(atom, subformula)
        self.formulas = tuple(new_formulas)

    def propositional(self, constants):
        return self.__class__(*[formula.propositional(constants) for formula in self.formulas])

    def dequantify(self, constants):
        return self.__class__(*[formula.dequantify(constants) for formula in self.formulas])

    def instantiate(self, parameter_map):
        return self.__class__(*[formula.instantiate(parameter_map) for formula in self.formulas])

    def pddl(self):
        return '(%s %s)' % (self._pddl_name, ' '.join(formula.pddl() for formula in self.formulas))
    __repr__ = pddl



class And(Connective, Condition, Effect):