for (int i = 0; i < totalSizes; i++)
tmp.add(new HashSet<Arc>());
int i, j, k;
TIntIterator layerIter;
TIntIterator qijIter;
ArrayList<TIntHashSet> layer = new ArrayList<TIntHashSet>();
TIntHashSet[] tmpQ = new TIntHashSet[totalSizes];
// DLList[vars.length+1];
for (i = 0; i <= size; i++) {
layer.add(new TIntHashSet());// = new DLList(nbNodes);
}
//forward pass, construct all paths described by the automaton for word of length nbVars.
layer.get(0).add(pi.getInitialState());
TIntHashSet succ = new TIntHashSet();
for (i = 0; i < size; i++) {
int ub = vars[i].getUB();
for (j = vars[i].getLB(); j <= ub; j = vars[i].nextValue(j)) {
layerIter = layer.get(i).iterator();
while (layerIter.hasNext()) {
k = layerIter.next();
succ.clear();
pi.delta(k, j, succ);
if (!succ.isEmpty()) {
TIntIterator it = succ.iterator();
for (; it.hasNext(); )
layer.get(i + 1).add(it.next());
int idx = starts[i] + j - offsets[i];
if (tmpQ[idx] == null)
tmpQ[idx] = new TIntHashSet();
tmpQ[idx].add(k);
}
}
}
}
//removing reachable non accepting states
layerIter = layer.get(size).iterator();
while (layerIter.hasNext()) {
k = layerIter.next();
if (!pi.isFinal(k)) {
layerIter.remove();
}
}
//backward pass, removing arcs that does not lead to an accepting state
int nbNodes = pi.getNbStates();
BitSet mark = new BitSet(nbNodes);
Node[] in = new Node[pi.getNbStates() * (size + 1)];
Node tink = new Node(pi.getNbStates() + 1, size + 1, nid++);
graph.addVertex(tink);
for (i = size - 1; i >= 0; i--) {
mark.clear(0, nbNodes);
int ub = vars[i].getUB();
for (j = vars[i].getLB(); j <= ub; j = vars[i].nextValue(j)) {
int idx = starts[i] + j - offsets[i];
TIntHashSet l = tmpQ[idx];
if (l != null) {
qijIter = l.iterator();
while (qijIter.hasNext()) {
k = qijIter.next();
succ.clear();
pi.delta(k, j, succ);
TIntIterator it = succ.iterator();
boolean added = false;
for (; it.hasNext(); ) {
int qn = it.next();
if (layer.get(i + 1).contains(qn)) {
added = true;
Node a = in[i * pi.getNbStates() + k];
if (a == null) {
a = new Node(k, i, nid++);