@Test public void testGetNaturalLoopsEmptyGraph() { assertTrue(emptyGraph.getNaturalLoops().isEmpty()); }
public Set<NaturalLoop<V>> getNaturalLoops() { if(naturalLoops == null) { HashMap<V, NaturalLoop<V>> naturalLoopMap = new HashMap<>(); ensureReachableVerticesListIsCalculated(); getDominatorSets(); for(V source : dominatorSets.keySet()) { for(V target : successors.get(source)) { if(dominatorSets.get(source).contains(target)) { if(naturalLoopMap.containsKey(target)) { naturalLoopMap.get(target).tails.add(source); } else { naturalLoopMap.put(target, new NaturalLoop<>(source, target)); } } } } for(NaturalLoop<V> loop : naturalLoopMap.values()) { loop.vertices.add(loop.header); for(V tail : loop.tails) { if(tail != loop.header) { transverseDepthFirstSearch(tail, loop.vertices); } } } naturalLoops = Collections.unmodifiableSet(new HashSet<>(naturalLoopMap.values())); } return naturalLoops; }
FlowGraph { public Set<NaturalLoop<V>> getNaturalLoops() { if(naturalLoops == null) { HashMap<V, NaturalLoop<V>> naturalLoopMap = new HashMap<>(); ensureReachableVerticesListIsCalculated(); getDominatorSets(); for(V source : dominatorSets.keySet()) { for(V target : successors.get(source)) { if(dominatorSets.get(source).contains(target)) { if(naturalLoopMap.containsKey(target)) { naturalLoopMap.get(target).tails.add(source); } else { naturalLoopMap.put(target, new NaturalLoop<>(source, target)); } } } } for(NaturalLoop<V> loop : naturalLoopMap.values()) { loop.vertices.add(loop.header); for(V tail : loop.tails) { if(tail != loop.header) { transverseDepthFirstSearch(tail, loop.vertices); } } } naturalLoops = Collections.unmodifiableSet(new HashSet<>(naturalLoopMap.values())); } return naturalLoops; } }
FlowGraph { public Set<NaturalLoop<V>> getNaturalLoops() { if(naturalLoops == null) { HashMap<V, NaturalLoop<V>> naturalLoopMap = new HashMap<>(); ensureReachableVerticesListIsCalculated(); getDominatorSets(); for(V source : dominatorSets.keySet()) { for(V target : successors.get(source)) { if(dominatorSets.get(source).contains(target)) { if(naturalLoopMap.containsKey(target)) { naturalLoopMap.get(target).tails.add(source); } else { naturalLoopMap.put(target, new NaturalLoop<>(source, target)); } } } } for(NaturalLoop<V> loop : naturalLoopMap.values()) { loop.vertices.add(loop.header); for(V tail : loop.tails) { if(tail != loop.header) { transverseDepthFirstSearch(tail, loop.vertices); } } } naturalLoops = Collections.unmodifiableSet(new HashSet<>(naturalLoopMap.values())); } return naturalLoops; } FlowGraph(Map<V, Set<V>> edges, V entryPoint, V exitPoint); private  FlowGraph(FlowGraph<V> originalGraph); }
FlowGraph { public Set<NaturalLoop<V>> getNaturalLoops() { if(naturalLoops == null) { HashMap<V, NaturalLoop<V>> naturalLoopMap = new HashMap<>(); ensureReachableVerticesListIsCalculated(); getDominatorSets(); for(V source : dominatorSets.keySet()) { for(V target : successors.get(source)) { if(dominatorSets.get(source).contains(target)) { if(naturalLoopMap.containsKey(target)) { naturalLoopMap.get(target).tails.add(source); } else { naturalLoopMap.put(target, new NaturalLoop<>(source, target)); } } } } for(NaturalLoop<V> loop : naturalLoopMap.values()) { loop.vertices.add(loop.header); for(V tail : loop.tails) { if(tail != loop.header) { transverseDepthFirstSearch(tail, loop.vertices); } } } naturalLoops = Collections.unmodifiableSet(new HashSet<>(naturalLoopMap.values())); } return naturalLoops; } FlowGraph(Map<V, Set<V>> edges, V entryPoint, V exitPoint); private  FlowGraph(FlowGraph<V> originalGraph); V getEntryPoint(); V getExitPoint(); Map<V, Set<V>> getSuccessors(); Map<V, Set<V>> getPredecessors(); Set<V> getVertices(); Set<V> getSuccessors(V vertex); Set<V> getPredecessors(V vertex); FlowGraph<V> getTransverseGraph(); Map<V, V> getImmediateDominators(); Map<V, Set<V>> getDominatorTree(); Map<V, Set<V>> getDominatorSets(); Map<V, Set<V>> getDominanceFrontiers(); Map<V, V> getImmediatePostDominators(); Map<V, Set<V>> getPostDominatorSets(); Map<V, Set<V>> getPostDominanceFrontiers(); Set<NaturalLoop<V>> getNaturalLoops(); boolean containsPath(V source, V target); @Override boolean equals(Object o); @Override int hashCode(); void write(Writer writer, String graphName, Comparator<V> vertexComparator,
                      Function<V, String> printer, int fontSize); }
FlowGraph { public Set<NaturalLoop<V>> getNaturalLoops() { if(naturalLoops == null) { HashMap<V, NaturalLoop<V>> naturalLoopMap = new HashMap<>(); ensureReachableVerticesListIsCalculated(); getDominatorSets(); for(V source : dominatorSets.keySet()) { for(V target : successors.get(source)) { if(dominatorSets.get(source).contains(target)) { if(naturalLoopMap.containsKey(target)) { naturalLoopMap.get(target).tails.add(source); } else { naturalLoopMap.put(target, new NaturalLoop<>(source, target)); } } } } for(NaturalLoop<V> loop : naturalLoopMap.values()) { loop.vertices.add(loop.header); for(V tail : loop.tails) { if(tail != loop.header) { transverseDepthFirstSearch(tail, loop.vertices); } } } naturalLoops = Collections.unmodifiableSet(new HashSet<>(naturalLoopMap.values())); } return naturalLoops; } FlowGraph(Map<V, Set<V>> edges, V entryPoint, V exitPoint); private  FlowGraph(FlowGraph<V> originalGraph); V getEntryPoint(); V getExitPoint(); Map<V, Set<V>> getSuccessors(); Map<V, Set<V>> getPredecessors(); Set<V> getVertices(); Set<V> getSuccessors(V vertex); Set<V> getPredecessors(V vertex); FlowGraph<V> getTransverseGraph(); Map<V, V> getImmediateDominators(); Map<V, Set<V>> getDominatorTree(); Map<V, Set<V>> getDominatorSets(); Map<V, Set<V>> getDominanceFrontiers(); Map<V, V> getImmediatePostDominators(); Map<V, Set<V>> getPostDominatorSets(); Map<V, Set<V>> getPostDominanceFrontiers(); Set<NaturalLoop<V>> getNaturalLoops(); boolean containsPath(V source, V target); @Override boolean equals(Object o); @Override int hashCode(); void write(Writer writer, String graphName, Comparator<V> vertexComparator,
                      Function<V, String> printer, int fontSize);  }