code: def to_graph_decomposition(H):
      
      if not isinstance(H, DirectedHypergraph):
          raise TypeError("Transformation only applicable to \
                          directed hypergraphs")
  
      G = DirectedHypergraph()
  
      nodes = [(node, H.get_node_attributes(node_attributes))
               for node in G.node_iterator()]
      G.add_nodes(nodes)
  
      edges = [([tail_node], [head_node])
               for hyperedge_id in H.hyperedge_id_iterator()
               for tail_node in H.get_hyperedge_tail(hyperedge_id)
               for head_node in H.get_hyperedge_head(hyperedge_id)]
      G.add_hyperedges(edges)
  
      return G
docs: Returns a DirectedHypergraph object that has the same nodes (and
      corresponding attributes) as the given hypergraph, except that for all
      hyperedges in the given hypergraph, each node in the tail of the hyperedge
      is pairwise connected to each node in the head of the hyperedge in the
      new hypergraph.
      Said another way, each of the original hyperedges are decomposed in the
      new hypergraph into fully-connected bipartite components.
  
      :param H: the hypergraph to decompose into a graph.
      :returns: DirectedHypergraph -- the decomposed hypergraph.
      :raises: TypeError -- Transformation only applicable to
              directed hypergraphs