code: private Graph<String> gengraph(Configuration cf) {
          Graph.Builder<String> builder = new Graph.Builder<>();
          cf.modules().stream()
              .forEach(rm -> {
                  String mn = rm.name();
                  builder.addNode(mn);
                  rm.reads().stream()
                    .map(ResolvedModule::name)
                    .forEach(target -> builder.addEdge(mn, target));
              });
  
          Graph<String> rpg = requiresTransitiveGraph(cf, builder.nodes);
          return builder.build().reduce(rpg);
      }
docs: Returns a Graph of the given Configuration after transitive reduction.
  
  Transitive reduction of requires transitive edge and requires edge have
  to be applied separately to prevent the requires transitive edges
  (e.g. U -> V) from being reduced by a path (U -> X -> Y -> V)
  in which  V would not be re-exported from U.