private void appendFill(int nWords, int v) {
   if (vec.isEmpty()) {
     if (v == 0) {
       vec.add(HEADER0 | nWords);
     } else {
       vec.add(HEADER1 | nWords);
     }
   } else if (nWords > 1) {
     int back = getBack();
     if (v == 0) {
       if (isZeroFill(back)) {
         setBack(back + nWords);
       } else {
         vec.add(HEADER0 | nWords);
       }
     } else if (isOneFill(back)) {
       setBack(back + nWords);
     } else {
       vec.add(HEADER1 | nWords);
     }
   } else {
     active.val = v != 0 ? ALLONES : 0;
     appendLiteral();
   }
 }
  /**
   * Checks if the bit is set in the compressed bitset.
   *
   * <p>This operation is considerably slower than the uncompressed version. Use it with care.
   *
   * @param i the index where bit is checked.
   * @return true if the index is set, false otherwise.
   */
  public boolean get(int i) {
    if (i > numBits()) { // no-way
      return false;
    } else { // we have to do hard way

      for (int j = 0; j < vec.size() && i >= 0; j++) {
        int v = vec.getQuick(j);

        // for a fill, we know easily.
        if (isAFill(v)) {
          int size = (v & MAXCNT) * MAXBITS;
          if (i < size) return isOneFill(v);
          i -= size;
        } else {
          // plain value.
          if (i < MAXBITS) { // do we need to check?
            return (1 << (MAXBITS - i - 1) & v) != 0;
          } else { // yet to get there.
            i -= MAXBITS;
          }
        }
      }

      // we need to check the active word.
      if (i >= 0) {
        return (moreThanInUnsigned(active.val << (MAXBITS + 1 - active.nbits + i), ALLONES));
      }
    }

    return false;
  }
Example #3
0
  // Remplit les cycles avec le generateur LFSR.
  // Le nombre de valeurs dans l'ensemble des cycles est de 2^(k1+k2).
  // Cette methode fonctionne pour tous les polynomes, meme ceux dont
  // la periode n'est pas maximale.
  private void fillCyclesLFSR() {
    int n = 1 << (k1 + k2); // Nombre de points dans l'ensemble.
    IntArrayList c; // Array used to store the current cycle.
    int i;
    boolean stateVisited[] = new boolean[n];

    // Indicates which states have been visited so far.
    for (i = 0; i < n; i++) stateVisited[i] = false;
    int startState = 0; // First state of the cycle currently considered.
    numPoints = 0;
    while (startState < n) {
      stateVisited[startState] = true;
      c = new IntArrayList();
      c.add(value);
      nextState();
      while (state != startState) {
        stateVisited[state] = true;
        c.add(value);
        nextState();
      }
      addCycle(c);
      //         System.out.println("Size of Cycle: " + c.size());
      for (i = startState + 1; i < n; i++) if (stateVisited[i] == false) break;
      startState = i;
      validateState(i);
    }
  }
Example #4
0
  /**
   * Fills all values contained in the receiver into the specified list. Fills the list, starting at
   * index 0. After this call returns the specified list has a new size that equals
   * <tt>this.size()</tt>. Iteration order is guaranteed to be <i>identical</i> to the order used by
   * method {@link #forEachKey(DoubleProcedure)}.
   *
   * <p>This method can be used to iterate over the values of the receiver.
   *
   * @param list the list to be filled, can have any size.
   */
  public void values(IntArrayList list) {
    list.setSize(distinct);
    int[] elements = list.elements();

    int[] val = values;
    byte[] stat = state;

    int j = 0;
    for (int i = stat.length; i-- > 0; ) {
      if (stat[i] == FULL) elements[j++] = val[i];
    }
  }
Example #5
0
  /**
   * Fills all pairs satisfying a given condition into the specified lists. Fills into the lists,
   * starting at index 0. After this call returns the specified lists both have a new size, the
   * number of pairs satisfying the condition. Iteration order is guaranteed to be <i>identical</i>
   * to the order used by method {@link #forEachKey(DoubleProcedure)}.
   *
   * <p><b>Example:</b> <br>
   *
   * <pre>
   * DoubleIntProcedure condition = new DoubleIntProcedure() { // match even values only
   * public boolean apply(double key, int value) { return value%2==0; }
   * }
   * keys = (8,7,6), values = (1,2,2) --> keyList = (6,8), valueList = (2,1)</tt>
   * </pre>
   *
   * @param condition the condition to be matched. Takes the current key as first and the current
   *     value as second argument.
   * @param keyList the list to be filled with keys, can have any size.
   * @param valueList the list to be filled with values, can have any size.
   */
  public void pairsMatching(
      final DoubleIntProcedure condition,
      final DoubleArrayList keyList,
      final IntArrayList valueList) {
    keyList.clear();
    valueList.clear();

    for (int i = table.length; i-- > 0; ) {
      if (state[i] == FULL && condition.apply(table[i], values[i])) {
        keyList.add(table[i]);
        valueList.add(values[i]);
      }
    }
  }
  private void appendLiteral() {
    if (vec.size() == 0) {
      vec.add(active.val);
    } else {
      int back = vec.getQuick(vec.size() - 1);

      if (active.val == 0) { // incoming word is zero
        if (back == 0) {
          setBack(HEADER0 + 2);
        } else if (isZeroFill(back)) {
          setBack(++back);
        } else {
          vec.add(active.val);
        }
      } else if (active.val == ALLONES) { // incoming word is allones
        if (back == ALLONES) {
          setBack((HEADER1 | 2));
        } else if (isOneFill(back)) {
          setBack(++back);
        } else {
          vec.add(active.val);
        }
      } else { // incoming word contains a mixture of bits
        vec.add(active.val);
      }
    }
    nbits += MAXBITS;
    active.reset();
    nset = 0;
  }
  private int doCount() {
    nset = 0;
    nbits = 0;

    for (int i = 0; i < vec.size(); i++) {
      int v = vec.getQuick(i);
      if (!isAFill(v)) {
        nbits += MAXBITS;
        nset += Integer.bitCount(v);
      } else {
        int tmp = (v & MAXCNT) * MAXBITS;
        nbits += tmp;
        nset += tmp * (isOneFill(v) ? 1 : 0);
      }
    }

    return nbits;
  }
  /**
   * Returns the number of 1 bits in the bitset.
   *
   * @return the number of 1 bits in the bitset.
   */
  public int cardinality() {
    // check the cardinality, again if it has been reset.
    if (nset == 0 && !vec.isEmpty()) {
      doCount();
    }

    // the sizes in the vector and the active word.
    return nset + Integer.bitCount(active.val);
  }
  private WAHBitSet genericOp(OpType op, WAHBitSet other) {
    WAHBitSet ret = new WAHBitSet();

    // ensure that they have the same bit length.
    if (this.numBits() < other.numBits()) {
      this.setBit(other.numBits() - 1, 0);
    } else if (this.numBits() > other.numBits()) {
      other.setBit(numBits() - 1, 0);
    }

    if (vec.size() > 0) {
      run xrun = new run(vec), yrun = new run(other.vec);
      xrun.decode();
      yrun.decode();
      do {
        if (xrun.nWords == 0) {
          xrun.inc();
          xrun.decode();
        }

        if (yrun.nWords == 0) {
          yrun.inc();
          yrun.decode();
        }

        if (xrun.isFill()) {
          if (yrun.isFill()) {
            int nWords = Math.min(xrun.nWords, yrun.nWords);
            ret.appendFill(nWords, getOpResult(op, xrun.fillWord, yrun.fillWord));
            xrun.nWords -= nWords;
            yrun.nWords -= nWords;
          } else {
            ret.active.val = getOpResult(op, xrun.fillWord, yrun.get());
            ret.appendLiteral();
            --xrun.nWords;
            yrun.nWords = 0;
          }
        } else if (yrun.isFill()) {
          ret.active.val = getOpResult(op, yrun.fillWord, xrun.get());
          ret.appendLiteral();
          yrun.nWords--;
          xrun.nWords = 0;
        } else {
          ret.active.val = getOpResult(op, xrun.get(), yrun.get());
          ret.appendLiteral();
          yrun.nWords = 0;
          xrun.nWords = 0;
        }

      } while (!(xrun.end() && yrun.end()));
    }
    ret.active.val = getOpResult(op, this.active.val, other.active.val);
    ret.active.nbits = this.active.nbits;

    ret.doCount();
    return ret;
  }
 public void decode() {
   int v = vec.get(idx);
   if (WAHBitSet.isAFill(v)) {
     fillWord = (isOneFill(v) ? ALLONES : 0);
     nWords = v & MAXCNT;
     fill = true;
   } else {
     nWords = 1;
     fill = false;
   }
 }
  private void appendCounter(int val, int cnt) {
    int head = 2 + val;
    int w = (head << SECONDBIT) + cnt;

    nbits += cnt * MAXBITS;
    if (vec.isEmpty()) {
      vec.add(w);
    } else {
      int back = getBack();
      if ((back >>> SECONDBIT) == head) {
        back += cnt;
        setBack(back);
      } else if ((back == ALLONES) && head == 3) {
        setBack(w + 1);
      } else if ((back == 0) && head == 2) {
        setBack(w + 1);
      } else {
        vec.add(w);
      }
    }
  }
  /**
   * This is an optimization over the and function. This does not create new bitset. This just
   * counts the number of 1 bits common between the two bitsets.
   *
   * @param other the bitset to and with.
   * @return the number of 1s common between two bitsets.
   */
  public int andSize(WAHBitSet other) {
    int size = 0;

    // ensure that they have the same bit length.
    if (this.numBits() < other.numBits()) {
      this.setBit(other.numBits() - 1, 0);
    } else if (this.numBits() > other.numBits()) {
      other.setBit(numBits() - 1, 0);
    }

    if (vec.size() > 0) {
      run xrun = new run(vec), yrun = new run(other.vec);
      xrun.decode();
      yrun.decode();
      do {
        if (xrun.nWords == 0) {
          xrun.inc();
          xrun.decode();
        }

        if (yrun.nWords == 0) {
          yrun.inc();
          yrun.decode();
        }

        if (xrun.isFill()) {
          if (yrun.isFill()) {
            int nWords = Math.min(xrun.nWords, yrun.nWords);
            if ((xrun.fillWord & yrun.fillWord) == 1) {
              size += nWords * MAXBITS;
            }
            xrun.nWords -= nWords;
            yrun.nWords -= nWords;
          } else {
            size += countInRun(xrun, yrun);
          }
        } else if (yrun.isFill()) {
          size += countInRun(yrun, xrun);
        } else {
          int val = xrun.get() & yrun.get();
          if (val > 0) size += Integer.bitCount(val);
          yrun.nWords = 0;
          xrun.nWords = 0;
        }

      } while (!(xrun.end() && yrun.end()));
    }
    size += Integer.bitCount(this.active.val & other.active.val);

    return size;
  }
    // this function tries to advance the run by nWords
    // sometimes it is not possible, in that case it returns how much it advanced.
    public int inc(int nWords) {
      int orig = nWords;
      nWords--;
      while (nWords > 0) {
        ++idx;
        int v = vec.get(idx);
        if (isAFill(v)) {
          int words = v & MAXCNT;
          if (words > nWords) {
            --idx;
            break;
          }
          nWords -= words;
        } else {
          nWords--;
        }
      }

      return orig - nWords;
    }
 private void appendCompressed(int v) {
   vec.add(v);
   nbits += MAXBITS;
   nset = 0;
 }
 public boolean end() {
   return idx >= vec.size() - 1;
 }
 public int get() {
   return vec.getQuick(idx);
 }
 private void setBack(int val) {
   vec.setQuick(vec.size() - 1, val);
 }
  /**
   * Returns the best cut of a graph w.r.t. the degree of dissimilarity between points of different
   * partitions and the degree of similarity between points of the same partition.
   *
   * @param W the weight matrix of the graph
   * @return an array of two elements, each of these contains the points of a partition
   */
  protected static int[][] bestCut(DoubleMatrix2D W) {
    int n = W.columns();
    // Builds the diagonal matrices D and D^(-1/2) (represented as their diagonals)
    DoubleMatrix1D d = DoubleFactory1D.dense.make(n);
    DoubleMatrix1D d_minus_1_2 = DoubleFactory1D.dense.make(n);
    for (int i = 0; i < n; i++) {
      double d_i = W.viewRow(i).zSum();
      d.set(i, d_i);
      d_minus_1_2.set(i, 1 / Math.sqrt(d_i));
    }
    DoubleMatrix2D D = DoubleFactory2D.sparse.diagonal(d);

    // System.out.println("DoubleMatrix2D :\n"+D.toString());

    DoubleMatrix2D X = D.copy();

    // System.out.println("DoubleMatrix2D copy :\n"+X.toString());

    // X = D^(-1/2) * (D - W) * D^(-1/2)
    X.assign(W, Functions.minus);
    // System.out.println("DoubleMatrix2D X: (D-W) :\n"+X.toString());
    for (int i = 0; i < n; i++)
      for (int j = 0; j < n; j++)
        X.set(i, j, X.get(i, j) * d_minus_1_2.get(i) * d_minus_1_2.get(j));

    // Computes the eigenvalues and the eigenvectors of X
    EigenvalueDecomposition e = new EigenvalueDecomposition(X);
    DoubleMatrix1D lambda = e.getRealEigenvalues();

    // Selects the eigenvector z_2 associated with the second smallest eigenvalue
    // Creates a map that contains the pairs <index, eigenvalue>
    AbstractIntDoubleMap map = new OpenIntDoubleHashMap(n);
    for (int i = 0; i < n; i++) map.put(i, Math.abs(lambda.get(i)));
    IntArrayList list = new IntArrayList();
    // Sorts the map on the value
    map.keysSortedByValue(list);
    // Gets the index of the second smallest element
    int i_2 = list.get(1);

    // y_2 = D^(-1/2) * z_2
    DoubleMatrix1D y_2 = e.getV().viewColumn(i_2).copy();
    y_2.assign(d_minus_1_2, Functions.mult);

    // Creates a map that contains the pairs <i, y_2[i]>
    map.clear();
    for (int i = 0; i < n; i++) map.put(i, y_2.get(i));
    // Sorts the map on the value
    map.keysSortedByValue(list);
    // Search the element in the map previuosly ordered that minimizes the cut
    // of the partition
    double best_cut = Double.POSITIVE_INFINITY;
    int[][] partition = new int[2][];

    // The array v contains all the elements of the graph ordered by their
    // projection on vector y_2
    int[] v = list.elements();
    // For each admissible splitting point i
    for (int i = 1; i < n; i++) {
      // The array a contains all the elements that have a projection on vector
      // y_2 less or equal to the one of i-th element
      // The array b contains the remaining elements
      int[] a = new int[i];
      int[] b = new int[n - i];
      System.arraycopy(v, 0, a, 0, i);
      System.arraycopy(v, i, b, 0, n - i);
      double cut = Ncut(W, a, b, v);
      if (cut < best_cut) {
        best_cut = cut;
        partition[0] = a;
        partition[1] = b;
      }
    }

    // System.out.println("Partition:");
    // UtilsJS.printMatrix(partition);

    return partition;
  }
 private int getBack() {
   return vec.getQuick(vec.size() - 1);
 }
 /**
  * Returns the amount of memory used by the compressed bit set
  *
  * @return the amount of memory used by the compressed bit set
  */
 public long memSize() {
   return vec.size() + 2;
 }
  /**
   * Returns a new WAH compressed bitset after anding the current bitset with the <i>other</i>
   * bitset.
   *
   * @param other the bitset to and with
   * @return The resulting bitset
   */
  public WAHBitSet and(WAHBitSet other) {
    WAHBitSet ret = new WAHBitSet();

    // ensure that they have the same bit length.
    if (this.numBits() < other.numBits()) {
      this.setBit(other.numBits() - 1, 0);
    } else if (this.numBits() > other.numBits()) {
      other.setBit(numBits() - 1, 0);
    }

    // if there is something in the vector.
    if (vec.size() > 0) {
      // create new run objects and decode them.
      run xrun = new run(vec), yrun = new run(other.vec);
      xrun.decode();
      yrun.decode();
      do {
        // if you finished a run, then get the next one.
        if (xrun.nWords == 0) {
          xrun.inc();
          xrun.decode();
        }

        if (yrun.nWords == 0) {
          yrun.inc();
          yrun.decode();
        }

        if (xrun.isFill()) {
          if (yrun.isFill()) {
            // both are fills... this is the best.
            int nWords = Math.min(xrun.nWords, yrun.nWords);
            ret.appendFill(nWords, xrun.fillWord & yrun.fillWord);
            xrun.nWords -= nWords;
            yrun.nWords -= nWords;
          } else {
            // just cut through the other run
            chewUpRun(xrun, ret, yrun);
          }
        } else if (yrun.isFill()) {
          // again do the same, with different order.
          chewUpRun(yrun, ret, xrun);
        } else {
          // both are literals, so get the new literal and
          // append it to the return value.
          ret.active.val = xrun.get() & yrun.get();
          ret.appendLiteral();
          yrun.nWords = 0;
          xrun.nWords = 0;
        }
        // till they are not at the end.
      } while (!(xrun.end() && yrun.end()));
    }

    // set the active word.
    ret.active.val = this.active.val & other.active.val;
    ret.active.nbits = this.active.nbits;

    // ensure that the counts are set properly.
    ret.doCount();

    return ret;
  }
  private void setBit(int ind, int val) {
    assert val == 0 || val == 1;

    if (ind >= numBits()) {
      int diff = ind - numBits() + 1;
      if (active.nbits > 0) {
        if (ind + 1 >= nbits + MAXBITS) {
          diff -= MAXBITS - active.nbits;
          active.val <<= (MAXBITS - active.nbits);
          if (diff == 0) active.val += (val != 0 ? 1 : 0);
          appendLiteral();
        } else {
          active.nbits += diff;
          active.val <<= diff;
          active.val += (val != 0 ? 1 : 0);
          diff = 0;
        }
      }
      if (diff != 0) {
        int w = diff / MAXBITS;
        diff -= w * MAXBITS;
        if (diff != 0) {
          if (w > 1) {
            appendCounter(0, w);
          } else if (w != 0) {
            appendLiteral();
          }
          active.nbits = diff;
          active.val += (val != 0 ? 1 : 0);
        } else if (val != 0) {
          if (w > 2) {
            appendCounter(0, w - 1);
          } else if (w == 2) {
            appendLiteral();
          }
          active.val = 1;
          appendLiteral();
        } else {
          if (w > 1) {
            appendCounter(0, w);
          } else if (w != 0) {
            appendLiteral();
          }
        }
      }

      if (numBits() != ind + 1) logger.warning("Warning");

      if (nset != 0) nset += (val != 0 ? 1 : 0);

      return;
    } else if (ind >= nbits) { // modify an active bit
      int u = active.val;
      if (val != 0) {
        active.val |= (1 << (active.nbits - (ind - nbits) - 1));
      } else {
        active.val &= ~(1 << (active.nbits - (ind - nbits) - 1));
      }
      if (nset != 0 && (u != active.val)) nset += (val != 0 ? 1 : -1);
      return;
    } else if (vec.size() * MAXBITS == nbits) { // uncompressed
      int i = ind / MAXBITS;
      int u = vec.get(i);
      int w = (1 << (SECONDBIT - (ind % MAXBITS)));

      if (val != 0) vec.setQuick(i, u |= w);
      else vec.setQuick(i, u &= ~w);
      if (nset != 0 && (vec.getQuick(i) != u)) nset += (val != 0 ? 1 : -1);
      return;
    }

    // the code after this has not been verified at all...
    // should proceed with caution.
    // compressed bit vector --
    // the bit to be modified is in vec
    if (RUN_UNTESTED_CODE) {
      int idx = 0;
      int compressed = 0, cnt = 0, ind1 = 0, ind0 = ind;
      int current = 0; // current bit value
      while ((ind0 > 0) && (idx < vec.size())) {
        int v = vec.getQuick(idx);

        if (isAFill(v)) { // a fill
          cnt = ((v) & MAXCNT) * MAXBITS;
          if (cnt > ind0) { // found the location
            current = (isOneFill(v) ? 1 : 0);
            compressed = 1;
            ind1 = ind0;
            ind0 = 0;
          } else {
            ind0 -= cnt;
            ind1 = ind0;
            ++idx;
          }
        } else { // a literal word
          cnt = MAXBITS;
          if (MAXBITS > ind0) { // found the location
            current = (1 & ((v) >>> (SECONDBIT - ind0)));
            compressed = 0;
            ind1 = ind0;
            ind0 = 0;
          } else {
            ind0 -= MAXBITS;
            ind1 = ind0;
            ++idx;
          }
        }
      } // while (ind...

      if (ind1 == 0) { // set current and compressed
        int v = vec.getQuick(idx);
        if (isAFill(v)) {
          cnt = (v & MAXCNT) * MAXBITS;
          current = (isOneFill(v) ? 1 : 0);
          compressed = 1;
        } else {
          cnt = MAXBITS;
          current = (v >>> SECONDBIT);
          compressed = 0;
        }
      }

      if (ind0 > 0) // has not found the right location yet.
      {
        if (ind0 < active.nbits) { // in the active word
          ind1 = (1 << (active.nbits - ind0 - 1));
          if (val != 0) {
            active.val |= ind1;
          } else {
            active.val &= ~ind1;
          }
        } else { // extends the current bit vector
          ind1 = ind0 - active.nbits - 1;
          appendWord(HEADER0 | (ind1 / MAXBITS));
          for (ind1 %= MAXBITS; ind1 > 0; --ind1) addOneBit(0);
          addOneBit(val != 0 ? 1 : 0);
        }
        if (nset != 0) nset += val != 0 ? 1 : -1;
        return;
      }

      // locate the bit to be changed, lots of work hidden here
      if (current == val) return; // nothing to do

      int v = vec.getQuick(idx);
      // need to actually modify the bit
      if (compressed == 0) {
        // toggle a single bit of a literal word
        v ^= (1 << (SECONDBIT - ind1));
        vec.setQuick(idx, v);
      } else if (ind1 < MAXBITS) {
        // bit to be modified is in the first word, two pieces
        --v;
        vec.set(idx, v);
        if ((v & MAXCNT) == 1) {
          v = (current != 0) ? ALLONES : 0;
          vec.setQuick(idx, v);
        }
        int w = 1 << (SECONDBIT - ind1);
        if (val == 0) w ^= ALLONES;

        vec.beforeInsert(idx, w);
        idx++;
      } else if (cnt - ind1 <= MAXBITS) {
        // bit to be modified is in the last word, two pieces
        --(v);
        vec.setQuick(idx, v);
        if ((v & MAXCNT) == 1) {
          v = (current != 0) ? ALLONES : 0;
          vec.setQuick(idx, v);
        }
        int w = 1 << (cnt - ind1 - 1);
        if (val == 0) w ^= ALLONES;
        ++idx;
        vec.beforeInsert(idx, w);
      } else { // the counter breaks into three pieces
        int u[] = new int[2], w;
        u[0] = ind1 / MAXBITS;
        w = (v & MAXCNT) - u[0] - 1;
        u[1] = 1 << (SECONDBIT - ind1 + u[0] * MAXBITS);
        if (val == 0) {
          u[0] = (u[0] > 1) ? (HEADER1 | u[0]) : (ALLONES);
          u[1] ^= ALLONES;
          w = (w > 1) ? (HEADER1 | w) : (ALLONES);
        } else {
          u[0] = (u[0] > 1) ? (HEADER0 | u[0]) : 0;
          w = (w > 1) ? (HEADER0 | w) : 0;
        }
        vec.setQuick(idx, w);
        vec.beforeInsertAllOf(idx, Arrays.asList(u));
      }

      if (nset != 0) nset += val != 0 ? 1 : -1;
    } else {
      throw new AssertionError("Untested code detected, would rather die than run this");
    }
  }
Example #23
0
  /**
   * Parses the provided FSMPDA and converts the old transitions to new ones. The {@link #newStates}
   * list and the {@link #oldToNewStates} mapping should already be populated before this method is
   * called.
   *
   * @param fsm
   * @throws ResourceInstantiationException
   */
  protected void createNewTransitions(FSMPDA fsm) throws ResourceInstantiationException {
    LinkedList<StatePDA> oldStatesQueue = new LinkedList<StatePDA>();
    oldStatesQueue.add(fsm.getInitialState());
    IntArrayList visitedOldStates = new IntArrayList();
    while (oldStatesQueue.size() > 0) {
      StatePDA anOldState = oldStatesQueue.removeFirst();
      if (visitedOldStates.contains(anOldState.getIndex())) {
        // state already processed -> nothing to do
      } else {
        if (!oldToNewStates.containsKey(anOldState.getIndex())) {
          throw new ResourceInstantiationException(
              "State mapping org.p4535992.mvc.error: "
                  + "old state not associated with a new state!");
        }
        SPTBase.State newState = newStates.get(oldToNewStates.get(anOldState.getIndex()));
        // now process all transitions
        List<SPTBase.Transition> newTransitions = new LinkedList<SPTBase.Transition>();
        for (gate.fsm.Transition t : anOldState.getTransitions()) {
          TransitionPDA anOldTransition = (TransitionPDA) t;
          if (!visitedOldStates.contains(anOldTransition.getTarget().getIndex())) {
            oldStatesQueue.add((StatePDA) anOldTransition.getTarget());
          }
          if (!oldToNewStates.containsKey(anOldTransition.getTarget().getIndex())) {
            throw new ResourceInstantiationException(
                "State mapping org.p4535992.mvc.error: "
                    + "old target state not associated with a new state!");
          }
          int newStateTarget = oldToNewStates.get(anOldTransition.getTarget().getIndex());
          SPTBase.Transition newTransition = new SPTBase.Transition();
          newTransitions.add(newTransition);
          newTransition.nextState = newStateTarget;
          newTransition.type = anOldTransition.getType();
          if (newTransition.type != TransitionPDA.TYPE_CONSTRAINT) {
            continue;
          }
          Constraint[] oldConstraints = anOldTransition.getConstraints().getConstraints();
          List<int[]> newConstraints = new ArrayList<int[]>();
          for (int i = 0; i < oldConstraints.length; i++) {
            String annType = oldConstraints[i].getAnnotType();
            int annTypeInt = annotationTypes.indexOf(annType);
            if (annTypeInt < 0) {
              annotationTypes.add(annType);
              annTypeInt = annotationTypes.size() - 1;
            }
            int[] newConstraint = new int[oldConstraints[i].getAttributeSeq().size() + 2];
            newConstraints.add(newConstraint);
            newConstraint[0] = annTypeInt;
            newConstraint[1] = oldConstraints[i].isNegated() ? -1 : 0;
            int predId = 2;
            for (ConstraintPredicate oldPredicate : oldConstraints[i].getAttributeSeq()) {
              newConstraint[predId++] = convertPredicate(annType, oldPredicate);
            }
          }
          // now save the new constraints
          newTransition.constraints = new int[newConstraints.size()][];
          newTransition.constraints = newConstraints.toArray(newTransition.constraints);
        }
        // convert the transitions list to an array
        newState.transitions = new SPTBase.Transition[newTransitions.size()];
        newState.transitions = newTransitions.toArray(newState.transitions);

        // finally, mark the old state as visited.
        visitedOldStates.add(anOldState.getIndex());
      }
    }
  }