public void addNext(Element element) { for (Element e : this) e.addNext(element); } }
/** * Traverses the {@link Element} graph with DFS * and set {@link #prevPostOrder}. * * Should be first invoked on the source node of the graph. */ /*package*/ Element assignDfsPostOrder(Element prev) { if(prevPostOrder!=null) return prev; // already visited prevPostOrder = this; // set a dummy value to prepare for cycles for (Element next : foreEdges) { prev = next.assignDfsPostOrder(prev); } this.prevPostOrder = prev; // set to the real value return this; }
assert belongsToSCC(); // SCC discomposition must be done first if(isSink()) if(!next.checkCutSet(cc,visited))
/** * Forms a strongly connected component by doing a reverse DFS. */ private void formConnectedComponent(ConnectedComponent group) { if(belongsToSCC()) return; this.cc=group; group.add(this); for (Element prev : backEdges) prev.formConnectedComponent(group); }
/** * Builds a {@link Graph} from an {@link Expression} tree. * * {@link Expression} given to the graph will be modified forever, * and it will not be able to create another {@link Graph}. */ public Graph(Expression body) { // attach source and sink Expression whole = new Sequence(new Sequence(source,body),sink); // build up a graph whole.buildDAG(ElementSet.EMPTY_SET); // decompose into strongly connected components. // the algorithm is standard DFS-based algorithm, // one illustration of this algorithm is available at // http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/strongComponent.htm source.assignDfsPostOrder(sink); source.buildStronglyConnectedComponents(ccs); // cut-set check Set<Element> visited = new HashSet<Element>(); for (ConnectedComponent cc : ccs) { visited.clear(); if(source.checkCutSet(cc,visited)) { cc.isRequired = true; } } }
/** * Returns true iff this {@link ConnectedComponent} * can match a substring whose length is greater than 1. * * <p> * That means this property will become a collection property. */ public final boolean isCollection() { assert !elements.isEmpty(); // a strongly connected component by definition has a cycle, // so if its size is bigger than 1 there must be a cycle. if(elements.size()>1) return true; // if size is 1, it might be still forming a self-cycle Element n = elements.get(0); return n.hasSelfLoop(); }
/** * Builds a {@link Graph} from an {@link Expression} tree. * * {@link Expression} given to the graph will be modified forever, * and it will not be able to create another {@link Graph}. */ public Graph(Expression body) { // attach source and sink Expression whole = new Sequence(new Sequence(source,body),sink); // build up a graph whole.buildDAG(ElementSet.EMPTY_SET); // decompose into strongly connected components. // the algorithm is standard DFS-based algorithm, // one illustration of this algorithm is available at // http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/strongComponent.htm source.assignDfsPostOrder(sink); source.buildStronglyConnectedComponents(ccs); // cut-set check Set<Element> visited = new HashSet<Element>(); for (ConnectedComponent cc : ccs) { visited.clear(); if(source.checkCutSet(cc,visited)) { cc.isRequired = true; } } }
/** * Forms a strongly connected component by doing a reverse DFS. */ private void formConnectedComponent(ConnectedComponent group) { if(belongsToSCC()) return; this.cc=group; group.add(this); for (Element prev : backEdges) prev.formConnectedComponent(group); }
/** * Returns true iff this {@link ConnectedComponent} * can match a substring whose length is greater than 1. * * <p> * That means this property will become a collection property. */ public final boolean isCollection() { assert !elements.isEmpty(); // a strongly connected component by definition has a cycle, // so if its size is bigger than 1 there must be a cycle. if(elements.size()>1) return true; // if size is 1, it might be still forming a self-cycle Element n = elements.get(0); return n.hasSelfLoop(); }
assert belongsToSCC(); // SCC discomposition must be done first if(isSink()) if(!next.checkCutSet(cc,visited))
/** * Builds a {@link Graph} from an {@link Expression} tree. * * {@link Expression} given to the graph will be modified forever, * and it will not be able to create another {@link Graph}. */ public Graph(Expression body) { // attach source and sink Expression whole = new Sequence(new Sequence(source,body),sink); // build up a graph whole.buildDAG(ElementSet.EMPTY_SET); // decompose into strongly connected components. // the algorithm is standard DFS-based algorithm, // one illustration of this algorithm is available at // http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/strongComponent.htm source.assignDfsPostOrder(sink); source.buildStronglyConnectedComponents(ccs); // cut-set check Set<Element> visited = new HashSet<Element>(); for (ConnectedComponent cc : ccs) { visited.clear(); if(source.checkCutSet(cc,visited)) { cc.isRequired = true; } } }
/** * Forms a strongly connected component by doing a reverse DFS. */ private void formConnectedComponent(ConnectedComponent group) { if(belongsToSCC()) return; this.cc=group; group.add(this); for (Element prev : backEdges) prev.formConnectedComponent(group); }
public void addNext(Element element) { for (Element e : this) e.addNext(element); } }
/** * Traverses the {@link Element} graph with DFS * and set {@link #prevPostOrder}. * * Should be first invoked on the source node of the graph. */ /*package*/ Element assignDfsPostOrder(Element prev) { if(prevPostOrder!=null) return prev; // already visited prevPostOrder = this; // set a dummy value to prepare for cycles for (Element next : foreEdges) { prev = next.assignDfsPostOrder(prev); } this.prevPostOrder = prev; // set to the real value return this; }
/** * Returns true iff this {@link ConnectedComponent} * can match a substring whose length is greater than 1. * * <p> * That means this property will become a collection property. */ public final boolean isCollection() { assert !elements.isEmpty(); // a strongly connected component by definition has a cycle, // so if its size is bigger than 1 there must be a cycle. if(elements.size()>1) return true; // if size is 1, it might be still forming a self-cycle Element n = elements.get(0); return n.hasSelfLoop(); }
assert belongsToSCC(); // SCC discomposition must be done first if(isSink()) if(!next.checkCutSet(cc,visited))
/** * Builds a {@link Graph} from an {@link Expression} tree. * * {@link Expression} given to the graph will be modified forever, * and it will not be able to create another {@link Graph}. */ public Graph(Expression body) { // attach source and sink Expression whole = new Sequence(new Sequence(source,body),sink); // build up a graph whole.buildDAG(ElementSet.EMPTY_SET); // decompose into strongly connected components. // the algorithm is standard DFS-based algorithm, // one illustration of this algorithm is available at // http://www.personal.kent.edu/~rmuhamma/Algorithms/MyAlgorithms/GraphAlgor/strongComponent.htm source.assignDfsPostOrder(sink); source.buildStronglyConnectedComponents(ccs); // cut-set check Set<Element> visited = new HashSet<Element>(); for (ConnectedComponent cc : ccs) { visited.clear(); if(source.checkCutSet(cc,visited)) { cc.isRequired = true; } } }