# Path: planner/operators.py
# class Operator(object):
#   def __init__(self, args):
#     self.args = args
#     for k, v in args.items():
#       setattr(self, k, v)
#     self.conditions = []
#     self.effects = {}
#   def __contains__(self, state):
#     return all(state in precondition for precondition in self.conditions)
#   def apply(self, state):
#     return State(dict(list(state) + [(var, effect(state)) for var, effect in self.effects.items()]))
#   def __call__(self, state):
#     if state not in self: return None
#     return self.apply(state)
#   def __iter__(self):
#     yield self
#   def __len__(self):
#     return 1
#   def fixed_conditions(self):
#     fc = {}
#     for condition in self.conditions:
#       if isinstance(condition, SubstateCondition):
#         for var, value in condition.substate:
#           if var in fc and fc[var] != value:
#             raise RuntimeError('Condition has conflicting conditions')
#           fc[var] = value
#     return fc
#   def fixed_effects(self):
#     return {var: effect.value for var, effect in self.effects.items()
#             if isinstance(effect, ValueEffect)}
#   def fixed_image(self):
#     return merge_dicts(self.fixed_conditions(), self.fixed_effects())
#   #def image(self):
#   #  pass
#   #def fixed_preimage(self):
#   #  pass
#   def __eq__(self, other):
#     if type(self) != type(other): return False
#     return self.args == other.args
#   def __ne__(self, other):
#     return not self == other
#   def __hash__(self):
#     return hash((self.__class__, frozenset(self.args.items())))
#   def __str__(self):
#     return self.__class__.__name__ + str_args(self.args)
#   __repr__ = __str__
# 
# Path: misc/utils.py
# SEPARATOR = '\n'+85*'-'+'\n'
# def arg_info(frame, ignore=['self']):
# def function_name(stack): # NOTE - stack = inspect.stack()
# def get_path(frame):
# def get_directory(abs_path):
# def global_fn(name):
# def refresh(module_name):


from .utils import *
from planner.operators import Operator
from misc.utils import str_object
      if source_vertex is not None:
        source_vertex.update_inactive()

  def update_inactive(self):
    if not self.active or self == self.rg.goal: return # TODO - decide if better condition

    self.active = False # Temporarily set to inactive
    for _, sink_vertex in self.mappings:
      sink_vertex.update_inactive()
      if sink_vertex.active:
        self.active = True
        return
    # Cannot find active parent node
    self.set_inactive()

  def __str__(self):
    return 'E(' + str(self.value) + ')'
  __repr__ = __str__
  def node_str(self):
    node_str = self.value.__class__.__name__
    if isinstance(self.value, Operator):
      for name, arg in self.value.args.items():
        node_str += '\n' + str_object(name) + '=' + str_object(arg)
    return node_str
  def node_attr(self):
    return {
      'shape': 'square',
      'fontcolor': 'white',
      'style': 'filled',
      'colorscheme': 'SVG',

# Path: planner/operators.py
# class Operator(object):
#   def __init__(self, args):
#     self.args = args
#     for k, v in args.items():
#       setattr(self, k, v)
#     self.conditions = []
#     self.effects = {}
#   def __contains__(self, state):
#     return all(state in precondition for precondition in self.conditions)
#   def apply(self, state):
#     return State(dict(list(state) + [(var, effect(state)) for var, effect in self.effects.items()]))
#   def __call__(self, state):
#     if state not in self: return None
#     return self.apply(state)
#   def __iter__(self):
#     yield self
#   def __len__(self):
#     return 1
#   def fixed_conditions(self):
#     fc = {}
#     for condition in self.conditions:
#       if isinstance(condition, SubstateCondition):
#         for var, value in condition.substate:
#           if var in fc and fc[var] != value:
#             raise RuntimeError('Condition has conflicting conditions')
#           fc[var] = value
#     return fc
#   def fixed_effects(self):
#     return {var: effect.value for var, effect in self.effects.items()
#             if isinstance(effect, ValueEffect)}
#   def fixed_image(self):
#     return merge_dicts(self.fixed_conditions(), self.fixed_effects())
#   #def image(self):
#   #  pass
#   #def fixed_preimage(self):
#   #  pass
#   def __eq__(self, other):
#     if type(self) != type(other): return False
#     return self.args == other.args
#   def __ne__(self, other):
#     return not self == other
#   def __hash__(self):
#     return hash((self.__class__, frozenset(self.args.items())))
#   def __str__(self):
#     return self.__class__.__name__ + str_args(self.args)
#   __repr__ = __str__
# 
# Path: misc/utils.py
# SEPARATOR = '\n'+85*'-'+'\n'
# def arg_info(frame, ignore=['self']):
# def function_name(stack): # NOTE - stack = inspect.stack()
# def get_path(frame):
# def get_directory(abs_path):
# def global_fn(name):
# def refresh(module_name):


# Path: retired/planners/reachability_graph/edge.py
from .utils import *
from planner.operators import Operator
from misc.utils import str_object

      if source_vertex is not None:
        source_vertex.update_inactive()

  def update_inactive(self):
    if not self.active or self == self.rg.goal: return # TODO - decide if better condition

    self.active = False # Temporarily set to inactive
    for _, sink_vertex in self.mappings:
      sink_vertex.update_inactive()
      if sink_vertex.active:
        self.active = True
        return
    # Cannot find active parent node
    self.set_inactive()

  def __str__(self):
    return 'E(' + str(self.value) + ')'
  __repr__ = __str__
  def node_str(self):
    node_str = self.value.__class__.__name__
    if isinstance(self.value, Operator):
      for name, arg in self.value.args.items():
        node_str += '\n' + str_object(name) + '=' + str_object(arg)
    return node_str
  def node_attr(self):
    return {
      'shape': 'square',
      'fontcolor': 'white',
      'style': 'filled',
      'colorscheme': 'SVG',

      'color': 'black' if isinstance(self.value, Operator) else 'red',