docs: def to_graph_decomposition(H):
      """Returns an UndirectedHypergraph object that has the same nodes (and
      corresponding attributes) as the given H, except that for all
      hyperedges in the given H, each node in the hyperedge is pairwise
      connected to every other node also in that hyperedge in the new H.
      Said another way, each of the original hyperedges are decomposed in the
      new H into cliques (aka the "2-section" or "clique graph").
  
      :param H: the H to decompose into a graph.
      :returns: UndirectedHypergraph -- the decomposed H.
      :raises: TypeError -- Transformation only applicable to
              undirected Hs
  
      """
      if not isinstance(H, UndirectedHypergraph):
          raise TypeError("Transformation only applicable to \
                          undirected Hs")
  
      G = UndirectedHypergraph()
  
      nodes = [(node, H.get_node_attributes(node_attributes))
               for node in G.node_iterator()]
      G.add_nodes(nodes)
  
      edges = [(node_a, node_b)
               for hyperedge_id in H.hyperedge_id_iterator()
               for node_a in H.get_hyperedge_nodes(hyperedge_id)
               for node_b in H.get_hyperedge_nodes(hyperedge_id)
               if node_a != node_b]
  
      G.add_hyperedges(edges)
  
      return G