# Path: stripstream/pddl/logic/connectives.py
# class Not(Connective, Condition, Effect):
#     """
#     Logical negation (not P).
# 
#     .. code:: python
# 
#       CONF = EasyType()
#       AtConf = EasyPredicate(CONF, CONF)
#       Q1 = EasyParameter(CONF)
# 
#       f = Not(AtConf(Q1)))
#     """
#     _pddl_name = 'not'
# 
#     def __init__(self, formula):
#         """
#         :param formula: a :class:`.Formula`
#         """
#         super(Not, self).__init__(formula)
# 
#     @property
#     def formula(self): return self.formulas[0]
# 
#     def de_morgan(self, sign=True): return self.formula.de_morgan(
#         sign=not sign)
# 
#     def simplify(self): return self
# 
#     def get_literals(self):
#         dnf = self.formulas[0].get_literals()
#         for combo in product(*dnf):
#             yield map(utils.invert, combo)
# 
#     def holds(self, atoms, constants):
#         return not self.formula.holds(atoms, constants)
# 
#     def positive_supporters(self, atoms, constants):
#         return set(map(utils.invert, self.formula.negative_supporters(atoms, constants)))
# 
#     def negative_supporters(self, atoms, constants):
#         return set(map(utils.invert, self.formula.positive_supporters(atoms, constants)))
# 
#     def add(self, atoms, constants):
#         return self.formula.delete(atoms, constants)
# 
#     def delete(self, atoms, constants):
#         return self.formula.add(atoms, constants)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.formula == other.formula
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         return hash((self.__class__, self.formulas))
# 
# Path: stripstream/pddl/logic/utils.py
# def is_literal(f):
#     return isinstance(f, atoms.Atom) or (isinstance(f, connectives.Not) and is_literal(f.formulas[0])) or isinstance(f, atoms.Increase) or isinstance(f, atoms.Equal)
# 
# Path: stripstream/pddl/objects.py
# 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`.
#   """
# 
# Path: stripstream/pddl/logic/predicates.py
# class EasyPredicate(Predicate):
#     """
#     Anonymous predicate P which extends :class:`.Predicate`.
# 
#     .. code:: python
# 
#       CONF = EasyType()
#       AtConf = EasyPredicate(CONF)
#     """
#     num = 0
#     template = '_pr%s'
# 
#     def __init__(self, *types):
#         """
#         :param types: a list of :class:`.Type` inputs to the predicate
#         .. automethod:: __call__
#         """
#         name = self.template % EasyPredicate.num
#         EasyPredicate.num += 1
#         super(EasyPredicate, self).__init__(name, types)
# 
# Path: stripstream/pddl/objects.py
# class EasyType(Type):
#     """
#     Anonymous type which extends :class:`.Type` by automatically generating a unique name.
# 
#     .. code:: python
# 
#       CONF = EasyType()
#     """
#     _num = 0
#     _template = '_ty%s'
# 
#     _const_template = '%s_%s'
# 
#     def __init__(self):
#         name = self._template % EasyType._num
#         EasyType._num += 1
#         self.const_to_value = {}
#         self.value_to_const = {}
#         super(EasyType, self).__init__(name)
# 
#     def get_const(self, value):
#         if not isinstance(value, collections.Hashable):
#             raise ValueError('%s is not hashable' % value)
#         if value not in self.value_to_const:
# 
#             name = self._const_template % (self.name, len(self.value_to_const))
#             self.value_to_const[value] = Constant(name, self)
#             self.const_to_value[self.value_to_const[value]] = value
#         return self.value_to_const[value]
# 
#     def get_value(self, const):
#         return self.const_to_value[const]
# 
#     def get_param(self):
#         return EasyParameter(self)
# 
#     def __call__(self, *args):
#         if len(args) == 0:
#             return self.get_param()
#         if len(args) == 1:
#             return self.get_const(args[0])
#         raise ValueError(args)
# 
# class EasyParameter(Parameter):
#     """
#     Anonymous parameter which extends :class:`.Parameter` by automatically generating a unique name.
# 
#     .. code:: python
# 
#       CONF = EasyType()
#       Q = EasyParameter(CONF)
#     """
#     _num = 0
#     _template = 'x%s'
# 
#     def __init__(self, type):
#         """
#         :param type: the :class:`.Type` of the parameter
#         """
#         super(EasyParameter, self).__init__(
#             self._template % EasyParameter._num, type)
#         EasyParameter._num += 1


from stripstream.pddl.logic.connectives import Not
from stripstream.pddl.logic.utils import is_literal
from stripstream.pddl.objects import Parameter, Constant
from stripstream.pddl.logic.predicates import EasyPredicate
from stripstream.pddl.objects import EasyType, EasyParameter


def get_value(x):
    if type(x) != Constant or not isinstance(x.type, EasyType):
        return x
    return x.type.get_value(x)


def convert_plan(plan):
    if plan is None:
        return plan
    return [(action, map(get_value, args)) for action, args in plan]


def get_param_names(literals):
    param_names = {}
    for literal in literals:

# Path: stripstream/pddl/logic/connectives.py
# class Not(Connective, Condition, Effect):
#     """
#     Logical negation (not P).
# 
#     .. code:: python
# 
#       CONF = EasyType()
#       AtConf = EasyPredicate(CONF, CONF)
#       Q1 = EasyParameter(CONF)
# 
#       f = Not(AtConf(Q1)))
#     """
#     _pddl_name = 'not'
# 
#     def __init__(self, formula):
#         """
#         :param formula: a :class:`.Formula`
#         """
#         super(Not, self).__init__(formula)
# 
#     @property
#     def formula(self): return self.formulas[0]
# 
#     def de_morgan(self, sign=True): return self.formula.de_morgan(
#         sign=not sign)
# 
#     def simplify(self): return self
# 
#     def get_literals(self):
#         dnf = self.formulas[0].get_literals()
#         for combo in product(*dnf):
#             yield map(utils.invert, combo)
# 
#     def holds(self, atoms, constants):
#         return not self.formula.holds(atoms, constants)
# 
#     def positive_supporters(self, atoms, constants):
#         return set(map(utils.invert, self.formula.negative_supporters(atoms, constants)))
# 
#     def negative_supporters(self, atoms, constants):
#         return set(map(utils.invert, self.formula.positive_supporters(atoms, constants)))
# 
#     def add(self, atoms, constants):
#         return self.formula.delete(atoms, constants)
# 
#     def delete(self, atoms, constants):
#         return self.formula.add(atoms, constants)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.formula == other.formula
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         return hash((self.__class__, self.formulas))
# 
# Path: stripstream/pddl/logic/utils.py
# def is_literal(f):
#     return isinstance(f, atoms.Atom) or (isinstance(f, connectives.Not) and is_literal(f.formulas[0])) or isinstance(f, atoms.Increase) or isinstance(f, atoms.Equal)
# 
# Path: stripstream/pddl/objects.py
# 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`.
#   """
# 
# Path: stripstream/pddl/logic/predicates.py
# class EasyPredicate(Predicate):
#     """
#     Anonymous predicate P which extends :class:`.Predicate`.
# 
#     .. code:: python
# 
#       CONF = EasyType()
#       AtConf = EasyPredicate(CONF)
#     """
#     num = 0
#     template = '_pr%s'
# 
#     def __init__(self, *types):
#         """
#         :param types: a list of :class:`.Type` inputs to the predicate
#         .. automethod:: __call__
#         """
#         name = self.template % EasyPredicate.num
#         EasyPredicate.num += 1
#         super(EasyPredicate, self).__init__(name, types)
# 
# Path: stripstream/pddl/objects.py
# class EasyType(Type):
#     """
#     Anonymous type which extends :class:`.Type` by automatically generating a unique name.
# 
#     .. code:: python
# 
#       CONF = EasyType()
#     """
#     _num = 0
#     _template = '_ty%s'
# 
#     _const_template = '%s_%s'
# 
#     def __init__(self):
#         name = self._template % EasyType._num
#         EasyType._num += 1
#         self.const_to_value = {}
#         self.value_to_const = {}
#         super(EasyType, self).__init__(name)
# 
#     def get_const(self, value):
#         if not isinstance(value, collections.Hashable):
#             raise ValueError('%s is not hashable' % value)
#         if value not in self.value_to_const:
# 
#             name = self._const_template % (self.name, len(self.value_to_const))
#             self.value_to_const[value] = Constant(name, self)
#             self.const_to_value[self.value_to_const[value]] = value
#         return self.value_to_const[value]
# 
#     def get_value(self, const):
#         return self.const_to_value[const]
# 
#     def get_param(self):
#         return EasyParameter(self)
# 
#     def __call__(self, *args):
#         if len(args) == 0:
#             return self.get_param()
#         if len(args) == 1:
#             return self.get_const(args[0])
#         raise ValueError(args)
# 
# class EasyParameter(Parameter):
#     """
#     Anonymous parameter which extends :class:`.Parameter` by automatically generating a unique name.
# 
#     .. code:: python
# 
#       CONF = EasyType()
#       Q = EasyParameter(CONF)
#     """
#     _num = 0
#     _template = 'x%s'
# 
#     def __init__(self, type):
#         """
#         :param type: the :class:`.Type` of the parameter
#         """
#         super(EasyParameter, self).__init__(
#             self._template % EasyParameter._num, type)
#         EasyParameter._num += 1


# Path: stripstream/pddl/utils.py
from stripstream.pddl.logic.connectives import Not
from stripstream.pddl.logic.utils import is_literal
from stripstream.pddl.objects import Parameter, Constant
from stripstream.pddl.logic.predicates import EasyPredicate
from stripstream.pddl.objects import EasyType, EasyParameter



def get_value(x):
    if type(x) != Constant or not isinstance(x.type, EasyType):
        return x
    return x.type.get_value(x)


def convert_plan(plan):
    if plan is None:
        return plan
    return [(action, map(get_value, args)) for action, args in plan]


def get_param_names(literals):
    param_names = {}
    for literal in literals:

        assert is_literal(literal)