# Path: stripstream/pddl/objects.py
# PARAM_PREFIX = '?'
# 
# TYPE_PAIR = '%s - %s'
# 
# class Object(object):
# 
#     def __init__(self, name, type):
#         """
#         PDDL object abstract class.
# 
#         :param name: the string name of the object
#         :param type: the :class:`.Type` of the object
#         """
#         self.name = name.lower()
#         self.type = type
#         self._hash = None
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.name == other.name and self.type == other.type
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         if self._hash is None:
#             self._hash = hash((self.__class__, self.name, self.type))
#         return self._hash
# 
#     def pddl(self):
#         return self.name
# 
#     def typed_pddl(self):
#         return TYPE_PAIR % (self.name, self.type)
#     __repr__ = pddl
# 
# 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)


from stripstream.pddl.objects import PARAM_PREFIX, TYPE_PAIR, Object, EasyType
import atoms
class EasyFunction(Function):
    """
    Anonymous function F which extends :class:`.Function`.

    .. code:: python

      CONF = EasyType()
      Distance = EasyFunction(CONF, CONF)
    """
    num = 0
    template = '_fn%s'

    def __init__(self, *types):
        """
        :param types: a list of :class:`.Type` inputs to the predicate
        .. automethod:: __call__
        """
        name = self.template % EasyFunction.num
        EasyFunction.num += 1
        super(EasyFunction, self).__init__(name, types)




def convert_args(self, args):
    if len(args) != len(self.types):
        raise ValueError('%s must have the same length as %s' %
                         (args, self.types))
    new_args = []
    for ty, arg in zip(self.types, args):

# Path: stripstream/pddl/objects.py
# PARAM_PREFIX = '?'
# 
# TYPE_PAIR = '%s - %s'
# 
# class Object(object):
# 
#     def __init__(self, name, type):
#         """
#         PDDL object abstract class.
# 
#         :param name: the string name of the object
#         :param type: the :class:`.Type` of the object
#         """
#         self.name = name.lower()
#         self.type = type
#         self._hash = None
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.name == other.name and self.type == other.type
# 
#     def __ne__(self, other):
#         return not(self == other)
# 
#     def __hash__(self):
#         if self._hash is None:
#             self._hash = hash((self.__class__, self.name, self.type))
#         return self._hash
# 
#     def pddl(self):
#         return self.name
# 
#     def typed_pddl(self):
#         return TYPE_PAIR % (self.name, self.type)
#     __repr__ = pddl
# 
# 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)


# Path: stripstream/pddl/logic/predicates.py
from stripstream.pddl.objects import PARAM_PREFIX, TYPE_PAIR, Object, EasyType
import atoms

class EasyFunction(Function):
    """
    Anonymous function F which extends :class:`.Function`.

    .. code:: python

      CONF = EasyType()
      Distance = EasyFunction(CONF, CONF)
    """
    num = 0
    template = '_fn%s'

    def __init__(self, *types):
        """
        :param types: a list of :class:`.Type` inputs to the predicate
        .. automethod:: __call__
        """
        name = self.template % EasyFunction.num
        EasyFunction.num += 1
        super(EasyFunction, self).__init__(name, types)




def convert_args(self, args):
    if len(args) != len(self.types):
        raise ValueError('%s must have the same length as %s' %
                         (args, self.types))
    new_args = []
    for ty, arg in zip(self.types, args):

        if isinstance(ty, EasyType) and not isinstance(arg, Object):