# Path: planner/states.py
# class State(Substate):
#   def __init__(self, values):
#     super(self.__class__, self).__init__({var: value for var, value in values.items() if value is not False})
#   def __getitem__(self, var):
#     if var not in self.__dict__[HASH_DICT]: return False
#     return self.__dict__[HASH_DICT][var]
#   def substate(self, variables):
#     return Substate({var: self[var] for var in variables})
#   def __call__(self, variables):
#     return self.substate(variables)
# 
# 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 .utils import *
from planner.states import State
from misc.objects import str_object
    # TODO - check that the vertex satisfies the connector
    if connector not in self.connectors:
      self.connectors.add(connector)
      connector.vertices.add(self)

      if connector.active and not self.active:
        self.set_active()
      if self.reachable and not connector.reachable:
        connector.set_reachable()

  def set_reachable(self):
    if self.reachable: return
    self.reachable = True

    # list is needed because iterable size changes over iteration
    if PRUNE_INACTIVE and self.rg.greedy:
      self.set_inactive()
    for connector in list(self.connectors):
      if not connector.reachable:
        connector.set_reachable()
    for sink_vertex, edge in list(self.sinks):
      if not sink_vertex.reachable and edge.reachable:
        sink_vertex.set_active()

  def set_active(self):
    if self.active: return
    self.active = True

    for source_vertex, edge in self.sources:
      if source_vertex is not None:

# Path: planner/states.py
# class State(Substate):
#   def __init__(self, values):
#     super(self.__class__, self).__init__({var: value for var, value in values.items() if value is not False})
#   def __getitem__(self, var):
#     if var not in self.__dict__[HASH_DICT]: return False
#     return self.__dict__[HASH_DICT][var]
#   def substate(self, variables):
#     return Substate({var: self[var] for var in variables})
#   def __call__(self, variables):
#     return self.substate(variables)
# 
# 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: retired/planners/reachability_graph/vertex.py
from .utils import *
from planner.states import State
from misc.objects import str_object

    # TODO - check that the vertex satisfies the connector
    if connector not in self.connectors:
      self.connectors.add(connector)
      connector.vertices.add(self)

      if connector.active and not self.active:
        self.set_active()
      if self.reachable and not connector.reachable:
        connector.set_reachable()

  def set_reachable(self):
    if self.reachable: return
    self.reachable = True

    # list is needed because iterable size changes over iteration
    if PRUNE_INACTIVE and self.rg.greedy:
      self.set_inactive()
    for connector in list(self.connectors):
      if not connector.reachable:
        connector.set_reachable()
    for sink_vertex, edge in list(self.sinks):
      if not sink_vertex.reachable and edge.reachable:
        sink_vertex.set_active()

  def set_active(self):
    if self.active: return
    self.active = True

    for source_vertex, edge in self.sources:
      if source_vertex is not None:

        source_vertex.set_active()