/** * 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 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 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); } }
@Override public void edgeDeleted(V source, V target) { V sourceRoot = sccs.find(source); V targetRoot = sccs.find(target); Graph<V> g = GraphHelper.getSubGraph(sccs.getPartition(sourceRoot), gds); sccs.deleteSet(sourceRoot); reducedGraph.deleteNode(sourceRoot); V newRoot = sccs.makeSet(newSCC); reducedGraph.insertNode(newRoot); newSCCRoots.add(newRoot); reducedGraph.insertEdge(sccs.find(sourceSCC), newSCCRoot); V newSourceRoot = sccs.find(source); V newTargetRoot = sccs.find(target); (sourceSCC.equals(targetSCC) && sccs.getPartition(sourceSCC).size() == 1 && GraphHelper .getEdgeCount(sccs.getPartition(sourceSCC).iterator().next(), gds) == 0) || notifyTcObservers(sccs.getPartition(sourceSCC), sccs.getPartition(targetSCC), Direction.DELETE); if (observers.size() > 0 && sccs.getPartition(sourceRoot).size() == 1 && GraphHelper.getEdgeCount(source, target, gds) == 0) { notifyTcObservers(source, source, Direction.DELETE);
@Override public void edgeInserted(V source, V target) { V sourceRoot = sccs.find(source); V targetRoot = sccs.find(target); (sourceSCC.equals(targetSCC) && sccs.getPartition(sourceSCC).size() == 1 && GraphHelper .getEdgeCount(sccs.getPartition(sourceSCC).iterator().next(), gds) == 0) || notifyTcObservers(sccs.getPartition(sourceSCC), sccs.getPartition(targetSCC), Direction.INSERT); V newRoot = iterator.next(); while (iterator.hasNext()) { newRoot = sccs.union(newRoot, iterator.next()); Set<V> containedNodes = sccs.getPartition(newRoot); if (observers.size() > 0 && sccs.getPartition(sourceRoot).size() == 1 && GraphHelper.getEdgeCount(source, target, gds) == 1) { notifyTcObservers(source, source, Direction.INSERT);
private void initalizeInternalDataStructures() { SCCResult<V> _sccres = SCC.computeSCC(gds); Set<Set<V>> _sccs = _sccres.getSccs(); for (Set<V> _set : _sccs) { sccs.makeSet(_set); } // Initalization of the reduced graph for (V n : sccs.getPartitionHeads()) { reducedGraph.insertNode(n); } for (V source : gds.getAllNodes()) { final IMemoryView<V> targetNodes = gds.getTargetNodes(source); for (Entry<V, Integer> entry : targetNodes.entriesWithMultiplicities()) { for (int i = 0; i < entry.getValue(); i++) { V target = entry.getKey(); V sourceRoot = sccs.find(source); V targetRoot = sccs.find(target); if (!sourceRoot.equals(targetRoot)) { reducedGraph.insertEdge(sourceRoot, targetRoot); } } } } counting = new CountingAlg<V>(reducedGraph); }
@Override public void tupleInserted(V source, V target) { alg.notifyTcObservers(alg.sccs.getPartition(source), alg.sccs.getPartition(target), Direction.INSERT); }
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; }
List<Variable> unnamedRunningVariables = PatternLanguageHelper.getUnnamedRunningVariables(patternBody); variables.removeAll(unnamedRunningVariables); UnionFind<Variable> justPositiveUnionFindForVariables = new UnionFind<>(variables); UnionFind<Variable> generalUnionFindForVariables = new UnionFind<>(variables); boolean isSecondRunNeeded = false; .getReferencedPatternVariablesOfXExpression(checkConstraint.getExpression(), associations)); justPositiveUnionFindForVariables.unite(positiveVariables); generalUnionFindForVariables.unite(generalVariables); positiveVariables, valueReference); justPositiveUnionFindForVariables.unite(positiveVariables); if (generalUnionFindForVariables.getPartitions().size() > 1) { } else if (justPositiveUnionFindForVariables.getPartitions().size() > 1) {
public Set<Tuple<V>> getTcRelation() { Set<Tuple<V>> resultSet = new HashSet<Tuple<V>>(); for (V sourceRoot : sccs.getPartitionHeads()) { Set<V> sources = sccs.getPartition(sourceRoot); if (sources.size() > 1 || GraphHelper.getEdgeCount(sources.iterator().next(), gds) == 1) { for (V source : sources) { for (V target : sources) { resultSet.add(new Tuple<V>(source, target)); } } } Set<V> reachableTargets = counting.getAllReachableTargets(sourceRoot); if (reachableTargets != null) { for (V targetRoot : reachableTargets) { for (V source : sources) { for (V target : sccs.getPartition(targetRoot)) { resultSet.add(new Tuple<V>(source, target)); } } } } } return resultSet; }
individualRefCounters.put(var, new VariableReferenceCount(Collections.singleton(var), isParameter)); for (Set<Variable> partition : variableUnions.getPartitions()) { boolean isParameter = false; for (Variable var : partition) { associations)) { individualRefCounters.get(var).incrementCounter(ReferenceType.READ_ONLY); unifiedRefCounters.get(variableUnions.getPartition(var)).incrementCounter(ReferenceType.READ_ONLY); final ReferenceType referenceClass = classifyReference(ref); individualRefCounters.get(var).incrementCounter(referenceClass); unifiedRefCounters.get(variableUnions.getPartition(var)).incrementCounter(referenceClass);
@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); }
/** * 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); }
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); }
@Override public void tupleDeleted(V source, V target) { alg.notifyTcObservers(alg.sccs.getPartition(source), alg.sccs.getPartition(target), Direction.DELETE); }
/** * 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); } }