/*
 * Copyright 2010 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.util.editdistance;

/**
 * A modified version of a string edit distance described by Berghel and
 * Roach that uses only O(d) space and O(n*d) worst-case time, where n is
 * the pattern string length and d is the edit distance computed.
 * We achieve the space reduction by keeping only those sub-computations
 * required to compute edit distance, giving up the ability to
 * reconstruct the edit path.
 */
public class ModifiedBerghelRoachEditDistance implements GeneralEditDistance {
  /*
   * This is a modification of the original Berghel-Roach edit
   * distance (based on prior work by Ukkonen) described in
   *   ACM Transactions on Information Systems, Vol. 14, No. 1,
   *   January 1996, pages 94-106.
   *
   * I observed that only O(d) prior computations are required
   * to compute edit distance.  Rather than keeping all prior
   * f(k,p) results in a matrix, we keep only the two "outer edges"
   * in the triangular computation pattern that will be used in
   * subsequent rounds.  We cannot reconstruct the edit path,
   * but many applications do not require that; for them, this
   * modification uses less space (and empirically, slightly
   * less time).
   *
   * First, some history behind the algorithm necessary to understand
   * Berghel-Roach and our modification...
   *
   * The traditional algorithm for edit distance uses dynamic programming,
   * building a matrix of distances for substrings:
   * D[i,j] holds the distance for string1[0..i]=>string2[0..j].
   * The matrix is initially populated with the trivial values
   * D[0,j]=j and D[i,0]=i; and then expanded with the rule:
   * <pre>
   *    D[i,j] = min( D[i-1,j]+1,       // insertion
   *                  D[i,j-1]+1,       // deletion
   *                  (D[i-1,j-1]
   *                   + (string1[i]==string2[j])
   *                      ? 0           // match
   *                      : 1           // substitution ) )
   * </pre>
   *
   * Ukknonen observed that each diagonal of the matrix must increase
   * by either 0 or 1 from row to row.  If D[i,j] = p, then the
   * then the matching rule requires that D[i+x,j+x] = p for all
   * x where string1[i..i+x) matches string2[j..j+j+x).  Ukkonen
   * defined a function f(k,p) as the highest row number in which p
   * appears on the k-th diagonal (those D[i,j] where k=(i-j), noting
   * that k may be negative).  The final result of the edit
   * distance is the D[n,m] cell, on the (n-m) diagonal; it is
   * the value of p for which f(n-m, p) = m.  The function f can
   * also be computed dynamically, according to a simple recursion:
   * <pre>
   *    f(k,p) {
   *      contains_p = max(f(k-1,p-1), f(k,p-1)+1, f(k+1,p-1)+1)
   *      while (string1[contains_p] == string2[contains_p + k])
   *        contains_p++;
   *      return contains_p;
   *    }
   * </pre>
   * The max() expression finds a row where the k-th diagonal must
   * contain p by virtue of an edit from the prior, same, or following
   * diagonal (corresponding to an insert, substitute, or delete);
   * we need not consider more distant diagonals because row-to-row
   * and column-to-column changes are at most +/- 1.
   *
   * The original Ukkonen algorithm computed f(k,p) roughly as
   * follows:
   * <pre>
   *    for (p = 0; ; p++) {
   *      compute f(k,p) for all valid k
   *      if (f(n-m, p) == m) return p;
   *    }
   * </pre>
   *
   * Berghel and Roach observed that many values of f(k,p) are
   * computed unnecessarily, and reorganized the computation into
   * a just-in-time sequence.  In each iteration, we are primarily
   * interested in the terminating value f(main,p), where main=(n-m)
   * is the main diagonal.  To compute that we need f(x,p-1) for
   * three values of x: main-1, main, and main+1.  Those depend on
   * values for p-2, and so forth.  We will already have computed
   * f(main,p-1) in the prior round, and thus f(main-1,p-2) and
   * f(main+1,p-2), and so forth.  The only new values we need to compute
   * are on the edges: f(main-i,p-i) and f(main+i,p-i).  Noting that
   * f(k,p) is only meaningful when abs(k) is no greater than p,
   * one of the Berghel-Roach reviewers noted that we can compute
   * the bounds for i:
   * <pre>
   *    (main+i &le p-i) implies (i &le; (p-main)/2)
   * </pre>
   * (where main+i is limited on the positive side) and similarly
   * <pre>
   *    (-(main-i) &le p-i) implies (i &le; (p+main)/2).
   * </pre>
   * (where main-i is limited on the negative side).
   *
   * This reduces the computation sequence to
   * <pre>
   *   for (i = (p-main)/2; i > 0; i--) compute f(main+i,p-i);
   *   for (i = (p+main)/2; i > 0; i--) compute f(main-i,p-i);
   *   if (f(main, p) == m) return p;
   * </pre>
   *
   * The original Berghel-Roach algorithm recorded prior values
   * of f(k,p) in a matrix, using O(distance^2) space, enabling
   * reconstruction of the edit path, but if all we want is the
   * edit *distance*, we only need to keep O(distance) prior computations.
   *
   * The requisite prior k-1, k, and k+1 values are conveniently
   * computed in the current round and the two preceding it.
   * For example, on the higher-diagonal side, we compute:
   * <pre>
   *    current[i] = f(main+i, p-i)
   * </pre>
   * We keep the two prior rounds of results, where p was one and two
   * smaller.  So, from the preceidng round
   * <pre>
   *    last[i] = f(main+i, (p-1)-i)
   * </pre>
   *  and from the prior round, but one position back:
   * <pre>
   *    prior[i-1] = f(main+(i-1), (p-2)-(i-1))
   * </pre>
   * In the current round, one iteration earlier:
   * <pre>
   *    current[i+1] = f(main+(i+1), p-(i+1))
   * </pre>
   * Note that the distance in all of these evaluates to p-i-1,
   * and the diagonals are (main+i) and its neighbors... just
   * what we need.  The lower-diagonal side behaves similarly.
   *
   * We need to materialize values that are not computed in prior
   * rounds, for either of two reasons: <ul>
   *    <li> Initially, we have no prior rounds, so we need to fill
   *     all of the "last" and "prior" values for use in the
   *     first round.  The first round uses only on one side
   *     of the main diagonal or the other.
   *    <li> In every other round, we compute one more diagonal than before.
   * </ul>
   * In all of these cases, the missing f(k,p) values are for abs(k) > p,
   * where a real value of f(k,p) is undefined.  [The original Berghel-Roach
   * algorithm prefills its F matrix with these values, but we fill
   * them as we go, as needed.]  We define
   * <pre>
   *    f(-p-1,p) = p, so that we start diagonal -p with row p,
   *    f(p+1,p) = -1, so that we start diagonal p with row 0.
   * </pre>
   * (We also allow f(p+2,p)=f(-p-2,p)=-1, causing those values to
   * have no effect in the starting row computation.]
   *
   * We only expand the set of diagonals visited every other round,
   * when (p-main) or (p+main) is even.  We keep track of even/oddness
   * to save some arithmetic.  The first round is always even, as p=abs(main).
   * Note that we rename the "f" function to "computeRow" to be Googley.
   */

  private static final int [] EMPTY_INT_ARRAY = new int[0];

  /**
   * Creates an instance for computing edit distance from {@code pattern}.
   * @param pattern string from which distances are measured
   * @return an instance for computing distances from the pattern
   */
  public static ModifiedBerghelRoachEditDistance
      getInstance(CharSequence pattern) {
    return getInstance(pattern.toString());
  }

  /**
   * Creates an instance for computing edit distance from {@code pattern}.
   * @param pattern string from which distances are measured
   * @return an instance for computing distances from the pattern
   */
  public static ModifiedBerghelRoachEditDistance
      getInstance(String pattern) {
    return new ModifiedBerghelRoachEditDistance(pattern.toCharArray());
  }

  /*
   * The current and two preceding sets of Ukkonen f(k,p) values for diagonals
   * around the main, computed by the main loop of {@code getDistance}.  These
   * arrays are retained between calls to save allocation costs.  (They are all
   * initialized to a real array so that we can indiscriminately use length
   * when ensuring/resizing.)
   */
  private int[] currentLeft = EMPTY_INT_ARRAY;

  private int[] currentRight = EMPTY_INT_ARRAY;
  
  private int[] lastLeft = EMPTY_INT_ARRAY;

  private int[] lastRight = EMPTY_INT_ARRAY;

  /**
   * The "pattern" string against which others are compared.
   */
  private final char[] pattern;

  private int[] priorLeft = EMPTY_INT_ARRAY;

  private int[] priorRight = EMPTY_INT_ARRAY;

  private ModifiedBerghelRoachEditDistance(char[] pattern) {
    this.pattern = pattern;
  }

  public ModifiedBerghelRoachEditDistance duplicate() {
    return new ModifiedBerghelRoachEditDistance(pattern);
  }

  public int getDistance(CharSequence targetSequence, int limit) {
    final int targetLength = targetSequence.length();

    /*
     * Compute the main diagonal number.
     * The final result lies on this diagonal.
     */
    final int main = pattern.length - targetLength;

    /*
     * Compute our initial distance candidate.
     * The result cannot be less than the difference in
     * string lengths, so we start there.
     */
    int distance = Math.abs(main);
    if (distance > limit) {
      /* More than we wanted.  Give up right away */
      return Integer.MAX_VALUE;
    }

    /* Snag a copy of the second string for efficiency */
    final char[] target = new char[targetLength];
    for (int i = 0; i < targetLength; i++) {
      target[i] = targetSequence.charAt(i);
    }

    /*
     * In the main loop below, the current{Right,Left} arrays record results
     * from the current outer loop pass.  The last{Right,Left} and
     * prior{Right,Left} arrays hold the results from the preceding two passes.
     * At the end of the outer loop, we shift them around (reusing the prior
     * array as the current for the next round, to avoid reallocating).
     * The Right reflects higher-numbered diagonals, Left lower-numbered.
     */

    /*
     * Fill in "prior" values for the first two passes through
     * the distance loop.  Note that we will execute only one side of
     * the main diagonal in these passes, so we only need
     * initialize one side of prior values.
     */

    if (main <= 0) {
      ensureCapacityRight(distance, false);
      for (int j = 0; j <= distance; j++) {
        lastRight[j] = distance - j - 1;  /* Make diagonal -k start in row k */
        priorRight[j] = -1;
      }
    } else {
      ensureCapacityLeft(distance, false);
      for (int j = 0; j <= distance; j++) {
        lastLeft[j] = -1;                 /* Make diagonal +k start in row 0 */
        priorLeft[j] = -1;
      }
    }

    /*
     * Keep track of even rounds.  Only those rounds consider new diagonals,
     * and thus only they require artificial "last" values below.
     */
    boolean even = true;

    /*
     * MAIN LOOP: try each successive possible distance until one succeeds.
     */
    while (true) {
      /*
       * Before calling computeRow(main, distance), we need to fill in
       * missing cache elements.  See the high-level description above.
       */

      /*
       * Higher-numbered diagonals
       */

      int offDiagonal = (distance - main) / 2;
      ensureCapacityRight(offDiagonal, true);

      if (even) {
        /* Higher diagonals start at row 0 */
        lastRight[offDiagonal] = -1;
      }

      int immediateRight = -1;
      for (; offDiagonal > 0; offDiagonal--) {
        currentRight[offDiagonal] = immediateRight = computeRow(
            (main + offDiagonal), 
            (distance - offDiagonal),
            pattern,
            target,
            priorRight[offDiagonal - 1],
            lastRight[offDiagonal],
            immediateRight);
      }

      /*
       * Lower-numbered diagonals
       */

      offDiagonal = (distance + main) / 2;
      ensureCapacityLeft(offDiagonal, true);

      if (even) {
        /* Lower diagonals, fictitious values for f(-x-1,x) = x */
        lastLeft[offDiagonal] = (distance - main) / 2 - 1;
      }

      int immediateLeft = even ? -1 : (distance - main) / 2;

      for (; offDiagonal > 0; offDiagonal--) {
        currentLeft[offDiagonal] = immediateLeft = computeRow(
            (main - offDiagonal),
            (distance - offDiagonal),
            pattern, target,
            immediateLeft,
            lastLeft[offDiagonal],
            priorLeft[offDiagonal - 1]);
      }

      /*
       * We are done if the main diagonal has distance in the last row.
       */
      int mainRow = computeRow(main, distance, pattern, target,
                               immediateLeft, lastLeft[0], immediateRight);

      if ((mainRow == targetLength) || (++distance > limit) || (distance < 0)) {
        break;
      }

      /* The [0] element goes to both sides. */
      currentLeft[0] = currentRight[0] = mainRow;

      /* Rotate rows around for next round: current=>last=>prior (=>current) */
      int[] tmp = priorLeft;
      priorLeft = lastLeft;
      lastLeft = currentLeft;
      currentLeft = priorLeft;

      tmp = priorRight;
      priorRight = lastRight;
      lastRight = currentRight;
      currentRight = tmp;

      /* Update evenness, too */
      even = !even;
    }

    return distance;
  }

  /**
   * Computes the highest row in which the distance {@code p} appears
   * in diagonal {@code k} of the edit distance computation for
   * strings {@code a} and {@code b}.  The diagonal number is
   * represented by the difference in the indices for the two strings;
   * it can range from {@code -b.length()} through {@code a.length()}.
   *
   * More precisely, this computes the highest value x such that
   * <pre>
   *     p = edit-distance(a[0:(x+k)), b[0:x)).
   * </pre>
   *
   * This is the "f" function described by Ukkonen.
   *
   * The caller must assure that abs(k) &le; p, the only values for
   * which this is well-defined.
   *
   * The implementation depends on the cached results of prior
   * computeRow calls for diagonals k-1, k, and k+1 for distance p-1.
   * These must be supplied in {@code knownLeft}, {@code knownAbove},
   * and {@code knownRight}, respectively.
   * @param k diagonal number
   * @param p edit distance
   * @param a one string to be compared
   * @param b other string to be compared
   * @param knownLeft value of {@code computeRow(k-1, p-1, ...)}
   * @param knownAbove value of {@code computeRow(k, p-1, ...)}
   * @param knownRight value of {@code computeRow(k+1, p-1, ...)}
   */
  private int computeRow(int k, int p, char[] a, char[] b,
                         int knownLeft, int knownAbove, int knownRight) {
    assert (Math.abs(k) <= p);
    assert (p >= 0);

    /*
     * Compute our starting point using the recurrance.
     * That is, find the first row where the desired edit distance
     * appears in our diagonal.  This is at least one past
     * the highest row for 
     */
    int t;
    if (p == 0) {
      t = 0;
    } else {
      /*
       * We look at the adjacent diagonals for the next lower edit distance.
       * We can start in the next row after the prior result from
       * our own diagonal (the "substitute" case), or the next diagonal
       * ("delete"), but only the same row as the prior result from
       * the prior diagonal ("insert").
       */
      t = Math.max(Math.max(knownAbove, knownRight) + 1, knownLeft);
    }

    /*
     * Look down our diagonal for matches to find the maximum
     * row with edit-distance p.
     */
    int tmax = Math.min(b.length, (a.length - k));

    while ((t < tmax) && b[t] == a[t + k]) {
      t++;
    }

    return t;
  }

  /*
   * Ensures that the Left arrays can be indexed through {@code index},
   * inclusively, resizing (and copying) as necessary.
   */
  private void ensureCapacityLeft(int index, boolean copy) {
    if (currentLeft.length <= index) {
      index++;
      priorLeft = resize(priorLeft, index, copy);
      lastLeft = resize(lastLeft, index, copy);
      currentLeft = resize(currentLeft, index, false);
    }
  }

  /*
   * Ensures that the Right arrays can be indexed through {@code index},
   * inclusively, resizing (and copying) as necessary.
   */
  private void ensureCapacityRight(int index, boolean copy) {
    if (currentRight.length <= index) {
      index++;
      priorRight = resize(priorRight, index, copy);
      lastRight = resize(lastRight, index, copy);
      currentRight = resize(currentRight, index, false);
    }
  }

  /* Resize an array, copying old contents if requested */
  private int[] resize(int[] array, int size, boolean copy) {
    int[] result = new int[size];
    if (copy) {
      System.arraycopy(array, 0, result, 0, array.length);
    }
    return result;
  }
}
