ANY HIERARCHIC_GRAPH_NODE NONE
class interface HIERARCHIC_GRAPH_NODE[E->HASHABLE]

creation
   make (i: E)
      ensure
         parents_count = 0;
         children_count = 0;
         item = i

feature(s) from HASHABLE
   hash_code: INTEGER
      -- The hash-code value of Current.
      ensure
         good_hash_value: Result >= 0

feature(s) from HIERARCHIC_GRAPH_NODE
   make (i: E)
      ensure
         parents_count = 0;
         children_count = 0;
         item = i

feature(s) from HIERARCHIC_GRAPH_NODE
   item: E

   max_rank: INTEGER

   min_rank: INTEGER

   parents: FAST_ARRAY[like Current]

   children: FAST_ARRAY[like Current]

   set_item (i: E)

   parents_count: INTEGER

   children_count: INTEGER

   add_parent (node: like Current)
      require
         node /= Void

   add_child (node: like Current)
      require
         node /= Void

   remove_parent (node: like Current)
      require
         has_parent(node)

   has_parent_edge (id: INTEGER): BOOLEAN

   has_child_edge (id: INTEGER): BOOLEAN

   remove_child (node: like Current)
      require
         has_child(node)

   remove_parent_edge (id: INTEGER): like Current
      -- Return connected node.
      require
         has_parent_edge(id)
      ensure
         not has_parent_edge(id)

   restore_parent_edge (id: INTEGER; node: like Current)
      require
         not has_parent_edge(id);
         has_parent_edge(-1);
         has_parent(node);
         not node.has_child_edge(id);
         node.has_child_edge(-1)
      ensure
         has_parent_edge(id)

   remove_child_edge (id: INTEGER): like Current
      -- Return connected node.
      require
         has_child_edge(id)
      ensure
         not has_child_edge(id)

   restore_child_edge (id: INTEGER; node: like Current)
      require
         not has_child_edge(id);
         has_child_edge(-1);
         has_child(node);
         not node.has_parent_edge(id);
         node.has_parent_edge(-1)
      ensure
         has_child_edge(id)

   deep_reset_edges
      -- Set edge identifiers with values starting from 0.

   parent (i: INTEGER): like Current
      require
         i.in_range(1,parents_count)

   child (i: INTEGER): like Current
      require
         i.in_range(1,children_count)

   has_parent (other: like Current): BOOLEAN
      ensure
         Result = other.has_child(Current)

   has_child (other: like Current): BOOLEAN
      ensure
         Result = other.has_parent(Current)

   parent_edge (i: INTEGER): INTEGER
      require
         i.in_range(1,parents_count)

   child_edge (i: INTEGER): INTEGER
      require
         i.in_range(1,children_count)

   has_cycle: BOOLEAN

   has_parent_cycle: BOOLEAN

   has_children_cycle: BOOLEAN

   is_toplevel: BOOLEAN
      ensure
         Result = (parents_count = 0)

   is_leaf: BOOLEAN
      ensure
         Result = (children_count = 0)

   is_connected_to (other: like Current): BOOLEAN
      require
         other /= Void
      ensure
         Result = (distance(other) /= Maximum_integer)

   distance (other: like Current): INTEGER
      require
         other /= Void
      ensure
         is_connected_to(other) = (distance(other) /= Maximum_integer)

   set_rank
      require
         not has_cycle

   add_connected_nodes_in (list: COLLECTION[HIERARCHIC_GRAPH_NODE[E]])
      -- Add in list all nodes belonging to the same graph as Current
      require
         list /= Void

   fill_path_to (path: COLLECTION[INTEGER]; destination: like Current)
      -- Add in path edges identifiers corresponding to a path
      -- from current node to destination node.
      require
         is_connected_to(destination);
         destination /= Current

feature(s) from HIERARCHIC_GRAPH_NODE
   internal_has_parent_cycle: BOOLEAN

   internal_has_children_cycle: BOOLEAN

   internal_is_connected_to (other: like Current): BOOLEAN
      require
         other /= Void

   internal_unmark_parents

   internal_unmark_children

   internal_unmark_connected
      -- unmark parents and children

   internal_deep_reset_edges: INTEGER

   internal_deep_init_edges (use: INTEGER): INTEGER

   internal_distance (other: like Current; pos, max: INTEGER): INTEGER
      -- Returns Maximum_integer if unaccessibility detected
      -- Returns -1 when break needed
      -- Distance from current point otherwise
      -- Warning: max length and pos are from the search start.
      require
         max >= pos;
         max < Maximum_integer
      ensure
         --***	 Result = -1 or Result = Maximum_integer or Result.in_range(0, max-pos)

   clean_mark_score

   internal_set_rank

   internal_add_connected_nodes_in (list: COLLECTION[HIERARCHIC_GRAPH_NODE[E]])

   internal_fill_path_to (path: COLLECTION[INTEGER]; destination: like Current; position: INTEGER): BOOLEAN

feature(s) from HIERARCHIC_GRAPH_NODE
   invariant_checking_mode: MEMO[BOOLEAN]

   valid_parents: BOOLEAN

   valid_children: BOOLEAN

   valid_parents_and_children: BOOLEAN
      ensure
         assertion_only: Result

   set_invariant_checking_mode (new_mode: BOOLEAN)
      require
         new_mode /= invariant_checking_mode.item

   deconnect_current

feature(s) from HIERARCHIC_GRAPH_NODE
   -- *** feature?

   parents_edge: FAST_ARRAY[INTEGER]

   children_edge: FAST_ARRAY[INTEGER]

   mark: BOOLEAN

   unmark

   set_mark

   deep_unmark_connected
      -- deep unmark parents and children (paths stops at unmarked nodes)

feature(s) from HIERARCHIC_GRAPH_NODE
   mark_score: INTEGER


invariant

    valid_parents_and_children;

end of HIERARCHIC_GRAPH_NODE[E->HASHABLE]