# 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
    _pddl_name = 'or'

    def de_morgan(self, sign=True):
        formulas = [f.de_morgan(sign=sign) for f in self.formulas]

        return Or(*formulas) if sign else And(*formulas)

    def get_literals(self):
        return flatten(f.get_literals() for f in self.formulas)

    def holds(self, atoms, constants):
        return any(formula.holds(atoms, constants) for formula in self.formulas)

    def positive_supporters(self, atoms, constants):
        for formula in self.formulas:
            child_literals = formula.positive_supporters(atoms, constants)
            if child_literals is not None:
                return child_literals
        return None

    def negative_supporters(self, atoms, constants):
        literals = set()
        for formula in self.formulas:
            child_literals = formula.negative_supporters(atoms, constants)
            if child_literals is None:
                return None
            literals |= child_literals
        return literals



# 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

    _pddl_name = 'or'

    def de_morgan(self, sign=True):
        formulas = [f.de_morgan(sign=sign) for f in self.formulas]

        return Or(*formulas) if sign else And(*formulas)

    def get_literals(self):
        return flatten(f.get_literals() for f in self.formulas)

    def holds(self, atoms, constants):
        return any(formula.holds(atoms, constants) for formula in self.formulas)

    def positive_supporters(self, atoms, constants):
        for formula in self.formulas:
            child_literals = formula.positive_supporters(atoms, constants)
            if child_literals is not None:
                return child_literals
        return None

    def negative_supporters(self, atoms, constants):
        literals = set()
        for formula in self.formulas:
            child_literals = formula.negative_supporters(atoms, constants)
            if child_literals is None:
                return None
            literals |= child_literals
        return literals



class Not(Connective, Condition, Effect):