use of kodkod.ast.visitor.VoidVisitor in project org.alloytools.alloy by AlloyTools.
the class Nodes method minRoots.
/**
* Returns a minimal subset of {@linkplain #roots(Formula) roots} of the given
* formula such that all nodes in the given collection are reachable from those
* roots. The returned subset is a local minimum in that none of its members can
* be removed without leaving some node in the descendants set unreachable from
* the remaining roots.
*
* @requires descendants in formula.*components
* @return { s: Set<Formula> | s.elements in roots(formula) and descendants in
* s.elements.*components and no s': Set<Formula> | s.containsAll(s')
* and s'.size()<s.size() and descendants in s.elements.*components }
* @throws IllegalArgumentException descendants !in formula.*components
*/
public static Set<Formula> minRoots(Formula formula, Collection<? extends Node> descendants) {
final Set<Node> desc = new IdentityHashSet<Node>(descendants);
final VoidVisitor visitor = new AbstractVoidVisitor() {
final Set<Node> visited = new IdentityHashSet<Node>();
@Override
protected boolean visited(Node n) {
if (visited.add(n)) {
desc.remove(n);
return false;
}
return true;
}
};
final Set<Formula> roots = new LinkedHashSet<Formula>();
for (Formula root : roots(formula)) {
final int size = desc.size();
root.accept(visitor);
if (desc.size() < size) {
roots.add(root);
}
if (desc.isEmpty()) {
break;
}
}
if (!desc.isEmpty())
throw new IllegalArgumentException("descendants !in formula.*components: formula=" + formula + " ; descendants=" + descendants);
return roots;
}
Aggregations