# Path: misc/objects.py
# def str_object(obj):
#   if type(obj) in (list, np.ndarray):
#     return '[%s]' % ', '.join(str_object(item) for item in obj)
#   if type(obj) == tuple:
#     return '(%s)' % ', '.join(str_object(item) for item in obj)
#   if type(obj) == dict:
#     return '{%s}' % ', '.join(str_object(item) + ': ' +  str_object(obj[item])
#                               for item in sorted(obj.keys(), key=lambda k: str_object(k)))
#   if type(obj) in (set, frozenset):
#     return '{%s}' % ', '.join(sorted(str_object(item) for item in obj))
#   if type(obj) in (float, np.float64):
#     obj = round(obj, 3)
#     if obj == 0:
#       obj = 0 # NOTE - catches -0.0 bug
#     return '%.3f'%obj
#   if isinstance(obj, types.FunctionType):
#     return obj.__name__
#   return str(obj)


from collections import namedtuple
from misc.objects import str_object
        self.sign = True
    @property
    def negated(self):
        return not self.sign
    def copy(self):
        new = self.__class__(*self.args)
        new.sign = self.sign
        return new
    def positive(self):
        new = self.copy()
        new.sign = True
        return new
    __abs__ = positive # abs(literal)
    def negate(self):
        new = self.copy()
        new.sign = not self.sign
        return new
    __neg__ = negate # -literal
    __invert__ = negate # ~literal
    def __iter__(self):
        return iter(self.args)
    def __eq__(self, other):
        return (type(self) == type(other)) and (self.sign == other.sign) and (self.args == other.args)
    def __ne__(self, other):
        return not (self == other)
    def __hash__(self):
        return hash((self.__class__, self.args, self.sign))
    def __lt__(self, other):
        return id(self) < id(other)
    def __str__(self):

# Path: misc/objects.py
# def str_object(obj):
#   if type(obj) in (list, np.ndarray):
#     return '[%s]' % ', '.join(str_object(item) for item in obj)
#   if type(obj) == tuple:
#     return '(%s)' % ', '.join(str_object(item) for item in obj)
#   if type(obj) == dict:
#     return '{%s}' % ', '.join(str_object(item) + ': ' +  str_object(obj[item])
#                               for item in sorted(obj.keys(), key=lambda k: str_object(k)))
#   if type(obj) in (set, frozenset):
#     return '{%s}' % ', '.join(sorted(str_object(item) for item in obj))
#   if type(obj) in (float, np.float64):
#     obj = round(obj, 3)
#     if obj == 0:
#       obj = 0 # NOTE - catches -0.0 bug
#     return '%.3f'%obj
#   if isinstance(obj, types.FunctionType):
#     return obj.__name__
#   return str(obj)


# Path: strips/states.py
from collections import namedtuple
from misc.objects import str_object

        self.sign = True
    @property
    def negated(self):
        return not self.sign
    def copy(self):
        new = self.__class__(*self.args)
        new.sign = self.sign
        return new
    def positive(self):
        new = self.copy()
        new.sign = True
        return new
    __abs__ = positive # abs(literal)
    def negate(self):
        new = self.copy()
        new.sign = not self.sign
        return new
    __neg__ = negate # -literal
    __invert__ = negate # ~literal
    def __iter__(self):
        return iter(self.args)
    def __eq__(self, other):
        return (type(self) == type(other)) and (self.sign == other.sign) and (self.args == other.args)
    def __ne__(self, other):
        return not (self == other)
    def __hash__(self):
        return hash((self.__class__, self.args, self.sign))
    def __lt__(self, other):
        return id(self) < id(other)
    def __str__(self):

        s = self.__class__.__name__ + str_object(self.args)