for (int i = 0; i < totalSizes; i++)
tmp.add(new HashSet<Arc>());
int i, j, k;
TIntIterator layerIter;
TIntIterator qijIter;
//forward pass, construct all paths described by the automaton for word of length nbVars.
TIntHashSet[] layer = new TIntHashSet[n+1];
TIntHashSet[] tmpQ = new TIntHashSet[totalSizes];
for (i = 0; i <= n; i++) {
layer[i] = new TIntHashSet();
}
layer[0].add(auto.getInitialState());
TIntHashSet nexts = new TIntHashSet();
for (i = 0; i < n; i++) {
int ub = vars[i].getUB();
for (j = vars[i].getLB(); j <= ub; j = vars[i].nextValue(j)) {
layerIter = layer[i].iterator();
while (layerIter.hasNext()) {
k = layerIter.next();
nexts.clear();
auto.delta(k, j, nexts);
for (TIntIterator it = nexts.iterator(); it.hasNext(); ) {
int succ = it.next();
layer[i+1].add(succ);
}
if (!nexts.isEmpty()) {
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[n].iterator();
while (layerIter.hasNext()) {
k = layerIter.next();
if (!auto.isFinal(k)) {
layerIter.remove();
}
}
//backward pass, removing arcs that does not lead to an accepting state
int nbNodes = auto.getNbStates();
BitSet mark = new BitSet(nbNodes);
Node[] in = new Node[auto.getNbStates() * (n + 1)];
for (i = n - 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();
nexts.clear();
auto.delta(k, j, nexts);
boolean added = false;
for (TIntIterator it = nexts.iterator(); it.hasNext(); ) {
int qn = it.next();
if (layer[i+1].contains(qn)) {
added = true;
Node a = in[i * auto.getNbStates() + k];
if (a == null) {
a = new Node(k, i, nid++);
in[i * auto.getNbStates() + k] = a;
graph.addVertex(a);
}
Node b = in[(i + 1) * auto.getNbStates() + qn];
if (b == null) {
b = new Node(qn, i + 1, nid++);
in[(i + 1) * auto.getNbStates() + qn] = b;
graph.addVertex(b);
}
// BEWARE<CPRU>: cost is not required, 0.0 is a default value
Arc arc = new Arc(a, b, j, aid++);
graph.addEdge(a, b, arc);
tmp.get(idx).add(arc);
mark.set(k);
}
}
if (!added)
qijIter.remove();
}
}
}
layerIter = layer[i].iterator();
// If no more arcs go out of a given state in the layer, then we remove the state from that layer