/** * Returns the node that is selected as the representative of the SCC containing the argument. * @since 1.6 */ public V getRepresentative(V node) { return sccs.find(node); }
/** * Returns a copy of this with the given value removed. The given value does not have to be a set's root node. */ private static <V> UnionFind<V> copyAndRemove(UnionFind<V> unionFind, V element) { UnionFind<V> result = new UnionFind<>(); for (Set<V> partition : unionFind.getPartitions()) { Set<V> filteredPartition = new HashSet<>(partition); filteredPartition.remove(element); result.makeSet(filteredPartition); } return result; }
@Override public void tupleInserted(V source, V target) { alg.notifyTcObservers(alg.sccs.getPartition(source), alg.sccs.getPartition(target), Direction.INSERT); }
@Override public Set<V> getAllReachableSources(V target) { V targetRoot = sccs.find(target); Set<V> containedNodes = sccs.getPartition(targetRoot); Set<V> sources = CollectionsFactory.createSet(); if (containedNodes.size() > 1 || GraphHelper.getEdgeCount(target, gds) == 1) { sources.addAll(containedNodes); } Set<V> rootSet = counting.getAllReachableSources(targetRoot); if (rootSet != null) { for (V _root : rootSet) { sources.addAll(sccs.getPartition(_root)); } } return sources; }
private UnionFind<Variable> calculateEqualVariables(PatternBody body) { UnionFind<Variable> unions = new UnionFind<>(body.getVariables()); TreeIterator<EObject> it = body.eAllContents(); while (it.hasNext()) { EObject obj = it.next(); if (obj instanceof CompareConstraint) { CompareConstraint constraint = (CompareConstraint) obj; if (constraint.getFeature() == CompareFeature.EQUALITY) { ValueReference left = constraint.getLeftOperand(); ValueReference right = constraint.getRightOperand(); if (left instanceof VariableReference && right instanceof VariableReference) { unions.union(((VariableReference) left).getVariable(), ((VariableReference) right).getVariable()); } } it.prune(); } else if (obj instanceof Constraint) { it.prune(); } } return unions; }
@Override public void nodeInserted(V n) { sccs.makeSet(n); reducedGraph.insertNode(n); }
public IncSCCAlg(IGraphDataSource<V> graphDataSource) { if (graphDataSource instanceof IBiDirectionalGraphDataSource<?>) { gds = (IBiDirectionalGraphDataSource<V>) graphDataSource; } else { gds = new IBiDirectionalWrapper<V>(graphDataSource); } observers = CollectionsFactory.createObserverList(); sccs = new UnionFind<V>(); reducedGraph = new Graph<V>(); reducedGraphIndexer = new IBiDirectionalWrapper<V>(reducedGraph); countingListener = new CountingListener<V>(this); initalizeInternalDataStructures(); gds.attachObserver(this); }
private void addPositiveVariablesFromValueReference(List<Variable> unnamedRunningVariables, UnionFind<Variable> justPositiveUnionFindForVariables, Set<Variable> positiveVariables, ValueReference valueReference) { Set<Variable> leftVariables = PatternLanguageHelper.getVariablesFromValueReference(valueReference); leftVariables.removeAll(unnamedRunningVariables); if (justPositiveUnionFindForVariables.isSameUnion(leftVariables)) { positiveVariables.addAll(leftVariables); } }
private static String prettyPrintPartitions(UnionFind<Variable> unionFind) { StringBuilder result = new StringBuilder(); for (Set<Variable> partition : unionFind.getPartitions()) { result.append("["); result.append(partition.stream().map(Variable::getName).collect(Collectors.joining(", "))); result.append("]"); } return result.toString(); }
@Override public void nodeDeleted(V n) { IMemoryView<V> sources = gds.getSourceNodes(n); IMemoryView<V> targets = gds.getTargetNodes(n); for (Entry<V, Integer> entry : sources.entriesWithMultiplicities()) { for (int i = 0; i < entry.getValue(); i++) { V source = entry.getKey(); edgeDeleted(source, n); } } for (Entry<V, Integer> entry : targets.entriesWithMultiplicities()) { for (int i = 0; i < entry.getValue(); i++) { V target = entry.getKey(); edgeDeleted(n, target); } } sccs.deleteSet(n); }
/** * Returns true if the SCC represented by the given root node has outgoing edges in the reduced graph, * false otherwise (if this SCC is a sink in the reduced graph). * * @param root the root node of an SCC * @return true if it has outgoing edges, false otherwise * @since 1.6 */ public boolean hasOutgoingEdges(V root) { for (final V containedNode : this.sccs.getPartition(root)) { final IMemoryView<V> targetNodes = this.gds.getTargetNodes(containedNode); for (final V target : targetNodes.distinctValues()) { final V otherRoot = this.sccs.find(target); if (!Objects.equals(root, otherRoot)) { return true; } } } return false; }
@Override public void tupleDeleted(V source, V target) { alg.notifyTcObservers(alg.sccs.getPartition(source), alg.sccs.getPartition(target), Direction.DELETE); }
/** * Returns true if the SCC represented by the given root node has incoming edges in the reduced graph, * false otherwise (if this SCC is a source in the reduced graph). * * @param root the root node of an SCC * @return true if it has incoming edges, false otherwise * @since 1.6 */ public boolean hasIncomingEdges(final V root) { for (final V containedNode : this.sccs.getPartition(root)) { final IMemoryView<V> sourceNodes = this.gds.getSourceNodes(containedNode); for (final V source : sourceNodes.distinctValues()) { final V otherRoot = this.sccs.find(source); if (!Objects.equals(root, otherRoot)) { return true; } } } return false; }
public boolean checkTcRelation(DRedTcRelation<V> tc) { for (V s : tc.getTupleStarts()) { for (V t : tc.getTupleEnds(s)) { if (!isReachable(s, t)) return false; } } for (V root : counting.getTcRelation().getTupleStarts()) { for (V end : counting.getTcRelation().getTupleEnds(root)) { for (V s : sccs.getPartition(root)) { for (V t : sccs.getPartition(end)) { if (!tc.containsTuple(s, t)) return false; } } } } return true; }
/** * Return the SCCs which are reachable from the SCC represented by the root node. Note that an SCC can be present * multiple times in the returned list (multiple edges between the two SCCs). * * @param root * @return the list of reachable target SCCs */ private List<V> getTargetSCCsOfSCC(V root) { List<V> targetSCCs = new ArrayList<V>(); for (V containedNode : this.sccs.getPartition(root)) { IMemoryView<V> targetNodes = this.gds.getTargetNodes(containedNode); for (V target : targetNodes.distinctValues()) { targetSCCs.add(this.sccs.find(target)); } } return targetSCCs; }
private void checkParameterUsageCounter(ParameterRef var, Map<Variable, VariableReferenceCount> individualCounters, Map<Set<Variable>, VariableReferenceCount> unifiedRefCounters, UnionFind<Variable> variableUnions, PatternBody body) { Variable parameter = var.getReferredParam(); VariableReferenceCount individualCounter = individualCounters.get(var); VariableReferenceCount unifiedCounter = unifiedRefCounters.get(variableUnions.getPartition(var)); if (individualCounter.getReferenceCount() == 0) { error(String.format("Parameter '%s' is never referenced in body '%s'.", parameter.getName(), getPatternBodyName(body)), parameter, PatternLanguagePackage.Literals.VARIABLE__NAME, IssueCodes.SYMBOLIC_VARIABLE_NEVER_REFERENCED); } else if (unifiedCounter.getReferenceCount(ReferenceType.POSITIVE) == 0) { error(String.format("Parameter '%s' has no enumerable reference in body '%s'.", var.getName(), getPatternBodyName(body)), parameter, PatternLanguagePackage.Literals.VARIABLE__NAME, IssueCodes.SYMBOLIC_VARIABLE_NO_POSITIVE_REFERENCE); } }
@Override public Set<V> getAllReachableTargets(V source) { V sourceRoot = sccs.find(source); Set<V> containedNodes = sccs.getPartition(sourceRoot); Set<V> targets = CollectionsFactory.createSet(); if (containedNodes.size() > 1 || GraphHelper.getEdgeCount(source, gds) == 1) { targets.addAll(containedNodes); } Set<V> rootSet = counting.getAllReachableTargets(sourceRoot); if (rootSet != null) { for (V _root : rootSet) { targets.addAll(sccs.getPartition(_root)); } } return targets; }
/** * Return the SCCs from which the SCC represented by the root node is reachable. Note that an SCC can be present * multiple times in the returned list (multiple edges between the two SCCs). * * @param root * @return the list of reachable target SCCs */ private List<V> getSourceSCCsOfSCC(V root) { List<V> sourceSCCs = new ArrayList<V>(); for (V containedNode : this.sccs.getPartition(root)) { IMemoryView<V> sourceNodes = this.gds.getSourceNodes(containedNode); for (V source : sourceNodes.distinctValues()) { sourceSCCs.add(this.sccs.find(source)); } } return sourceSCCs; }
public List<V> getReachabilityPath(V source, V target) { if (!isReachable(source, target)) { return null; } else { Set<V> sccsInSubGraph = CollectionHelper.intersectionMutable(counting.getAllReachableTargets(source), counting.getAllReachableSources(target)); sccsInSubGraph.add(sccs.find(source)); sccsInSubGraph.add(sccs.find(target)); Set<V> nodesInSubGraph = CollectionsFactory.createSet(); for (V sccRoot : sccsInSubGraph) { nodesInSubGraph.addAll(sccs.getPartition(sccRoot)); } return GraphHelper.constructPath(source, target, nodesInSubGraph, gds); } }