diff --git a/dg/src/main/jastadd/DependencyGraphReachability.jrag b/dg/src/main/jastadd/DependencyGraphReachability.jrag index 7fa24b4da6f892446be3c0cf69b5d5d8069ccc73..abf2783c94cb6dc048f18b97b8a220ff7e6d2e30 100644 --- a/dg/src/main/jastadd/DependencyGraphReachability.jrag +++ b/dg/src/main/jastadd/DependencyGraphReachability.jrag @@ -1,21 +1,30 @@ +import java.util.Collections; +import java.util.Deque; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; aspect Reachability { - syn Set<Component> Component.successors() circular [new HashSet<>()] { - Set<Component> result = new HashSet<>(); - for (Component c: getFromList()) { - result.add(c); - result.addAll(c.successors()); - } - return result; - } - syn Set<Component> Component.predecessors() circular [new HashSet<>()] { - Set<Component> result = new HashSet<>(); - for (Component c: getToList()) { - result.add(c); - result.addAll(c.predecessors()); - } - return result; - } +// syn Set<Component> Component.successors() circular [new HashSet<>()] { +// Set<Component> result = new HashSet<>(); +// for (Component c: getFromList()) { +// result.add(c); +// result.addAll(c.successors()); +// } +// return result; +// } + +// syn Set<Component> Component.predecessors() circular [new HashSet<>()] { +// Set<Component> result = new HashSet<>(); +// for (Component c: getToList()) { +// result.add(c); +// result.addAll(c.predecessors()); +// } +// return result; +// } // inh DependencyGraph Component.dg(); // eq DependencyGraph.getComponent().dg() = this; @@ -34,50 +43,60 @@ aspect Reachability { // return result; // } + syn lazy Set<Component> Component.predecessors() = new HashSet<>(); + syn lazy Set<Component> Component.successors() = new HashSet<>(); + syn lazy Set<Component> Component.SCC() = new HashSet<>(); +// syn lazy Set<Component> Component.SCC() { +// Set<Component> result = new HashSet<>(successors()); +// result.retainAll(predecessors()); +// return result; +// } - syn lazy Set<Component> Component.SCC() { - Set<Component> result = new HashSet<>(successors()); - result.retainAll(predecessors()); - return result; +// coll HashSet<Set<Component>> DependencyGraph.SCC() with add root DependencyGraph; +// Component contributes SCC() when SCC().size() > 0 to DependencyGraph.SCC(); + + syn Set<Set<Component>> DependencyGraph.SCC() { //Kosaraju's algorithm + System.out.println("Kosaraju's algorithm"); + Map<Component,Integer> visited=new HashMap<>(); + Deque<Component> locked=new LinkedList<>(); + //Visit nodes forward + long startVisit = System.nanoTime(); + for (Component n:getComponentList()) + visit(n,visited,locked); + //Assign nodes to SCCs backward + long startAssign = System.nanoTime(); + int scc=0; + for (Component n:locked) { + assign(n,visited,scc); + scc++; + } + long stop = System.nanoTime(); + //Map visited Map[Node,int]-> result Map[int,Set[Node]] + + System.out.println("visit : "+(startAssign-startVisit)); + System.out.println("assign: "+(stop-startAssign)); + System.out.println("sum: "+(stop-startVisit)); + + Map<Integer,Set<Component>> result=visited.entrySet().stream() + .collect(Collectors.groupingBy(e->e.getValue(), + Collectors.mapping(e->e.getKey(), + Collectors.toSet()))); + return result.values().stream().collect(Collectors.toSet()); } - - coll HashSet<Set<Component>> DependencyGraph.SCC() with add root DependencyGraph; - Component contributes SCC() when SCC().size() > 0 to DependencyGraph.SCC(); -// syn Set<Set<Component>> DependencyGraph.SCC() { //Kosaraju's algorithm -// Map<Component,Integer> visited=new HashMap<>(); -// Deque<Component> locked=new LinkedList<>(); -// //Visit nodes forward -// for (Component n:getComponentList()) -// n.visit(visited,locked); -// //Assign nodes to SCCs backward -// int scc=0; -// for (Node n:locked) { -// n.assign(visited,scc); -// scc++; -// } -// //Map visited Map[Node,int]-> result Map[int,Set[Node]] -// Map<Integer,Set<Component>> result=visited.entrySet().stream() -// .collect(Collectors.groupingBy(e->e.getValue(), -// Collectors.mapping(e->e.getKey(), -// Collectors.toSet()))); -// return result.values().stream().collect(Collectors.toSet()); -// -// } -// -// private void visit(Component n, Map<Component, Integer> visited, Deque<Component> locked){ -// if (visited.containsKey(n)) return; -// visited.put(n,-1); -// for (Component s:n.getFromList()) -// visit(s,visited,locked); -// locked.addFirst(n); -// } -// -// private void assign(Component n, Map<Node, Integer> visited, int root) { -// if (visited.get(n)>-1) return; -// visited.put(n,root); -// for (Component p:n.getToList()) -// assign(p,visited,root); -// } + public void DependencyGraph.visit(Component n, Map<Component, Integer> visited, Deque<Component> locked){ + if (visited.containsKey(n)) return; + visited.put(n,-1); + for (Component s:n.getFromList()) + visit(s,visited,locked); + locked.addFirst(n); + } + + public void DependencyGraph.assign(Component n, Map<Component, Integer> visited, int root) { + if (visited.get(n)>-1) return; + visited.put(n,root); + for (Component p:n.getToList()) + assign(p,visited,root); + } }