/**
  * Constructs automaton that accept strings representing nonnegative integers that are not less
  * that the given value.
  *
  * <p>bug found?? (pocorall)
  *
  * @param n string representation of minimum value
  */
 public static DefaultAutomaton makeMinInteger(String n) {
   int i = 0;
   while (i + 1 < n.length() && n.charAt(i) == '0') i++;
   StringBuilder b = new StringBuilder();
   b.append("0*");
   minInteger(n.substring(i), 0, b);
   b.append("[0-9]*");
   return ((new RegExp(b.toString())).toAutomaton()).minimize();
 }
 private static void minInteger(String n, int i, StringBuilder b) {
   b.append('(');
   if (i < n.length()) {
     char c = n.charAt(i);
     if (c != '9') b.append("[" + (char) (c + 1) + "-9][0-9]{" + (n.length() - i - 1) + "}|");
     b.append(c);
     minInteger(n, i + 1, b);
   }
   b.append(')');
 }
 /**
  * Constructs automaton that accept strings representing nonnegative integers that are not larger
  * than the given value.
  *
  * @param n string representation of maximum value
  */
 public static DefaultAutomaton makeMaxInteger(String n) {
   int i = 0;
   while (i < n.length() && n.charAt(i) == '0') i++;
   StringBuilder b = new StringBuilder();
   b.append("0*(0|");
   if (i < n.length()) b.append("[0-9]{1," + (n.length() - i - 1) + "}|");
   maxInteger(n.substring(i), 0, b);
   b.append(")");
   return ((new RegExp(b.toString())).toAutomaton()).minimize();
 }
 /**
  * Returns a new automaton that accepts strings representing decimal non-negative integers in the
  * given interval.
  *
  * @param min minimal value of interval
  * @param max maximal value of inverval (both end points are included in the interval)
  * @param digits if >0, use fixed number of digits (strings must be prefixed by 0's to obtain the
  *     right length) - otherwise, the number of digits is not fixed
  * @throws IllegalArgumentException if min>max or if numbers in the interval cannot be expressed
  *     with the given fixed number of digits
  */
 public static DefaultAutomaton makeInterval(int min, int max, int digits)
     throws IllegalArgumentException {
   DefaultAutomaton a = new DefaultAutomaton();
   String x = Integer.toString(min);
   String y = Integer.toString(max);
   if (min > max || (digits > 0 && y.length() > digits)) throw new IllegalArgumentException();
   int d;
   if (digits > 0) d = digits;
   else d = y.length();
   StringBuilder bx = new StringBuilder();
   for (int i = x.length(); i < d; i++) bx.append('0');
   bx.append(x);
   x = bx.toString();
   StringBuilder by = new StringBuilder();
   for (int i = y.length(); i < d; i++) by.append('0');
   by.append(y);
   y = by.toString();
   Collection<State> initials = new ArrayList<State>();
   a.initial = between(x, y, 0, initials, digits <= 0);
   if (digits <= 0) {
     ArrayList<StatePair> pairs = new ArrayList<StatePair>();
     for (State p : initials) if (a.initial != p) pairs.add(new StatePair(a.initial, p));
     addEpsilons(a, pairs);
     a.initial.addTransition(new Transition('0', a.initial));
     a.deterministic = false;
   } else a.deterministic = true;
   a.checkMinimizeAlways();
   return a;
 }
 /**
  * Constructs automaton that accept strings representing the given integer. Surrounding whitespace
  * is permitted.
  *
  * @param value string representation of integer
  */
 public static DefaultAutomaton makeIntegerValue(String value) {
   boolean minus = false;
   int i = 0;
   while (i < value.length()) {
     char c = value.charAt(i);
     if (c == '-') minus = true;
     if (c >= '1' && c <= '9') break;
     i++;
   }
   StringBuilder b = new StringBuilder();
   b.append(value.substring(i));
   if (b.length() == 0) b.append("0");
   DefaultAutomaton s;
   if (minus) s = makeChar('-');
   else s = makeChar('+').optional();
   DefaultAutomaton ws = Datatypes.getWhitespaceAutomaton();
   return (ws.concatenate(
               s.concatenate(makeChar('0').repeat()).concatenate(makeString(b.toString())))
           .concatenate(ws))
       .minimize();
 }
 /**
  * Constructs automaton that accept strings representing the given decimal number. Surrounding
  * whitespace is permitted.
  *
  * @param value string representation of decimal number
  */
 public static DefaultAutomaton makeDecimalValue(String value) {
   boolean minus = false;
   int i = 0;
   while (i < value.length()) {
     char c = value.charAt(i);
     if (c == '-') minus = true;
     if ((c >= '1' && c <= '9') || c == '.') break;
     i++;
   }
   StringBuilder b1 = new StringBuilder();
   StringBuilder b2 = new StringBuilder();
   int p = value.indexOf('.', i);
   if (p == -1) b1.append(value.substring(i));
   else {
     b1.append(value.substring(i, p));
     i = value.length() - 1;
     while (i > p) {
       char c = value.charAt(i);
       if (c >= '1' && c <= '9') break;
       i--;
     }
     b2.append(value.substring(p + 1, i + 1));
   }
   if (b1.length() == 0) b1.append("0");
   DefaultAutomaton s;
   if (minus) s = makeChar('-');
   else s = makeChar('+').optional();
   DefaultAutomaton d;
   if (b2.length() == 0) d = makeChar('.').concatenate(repeat(makeChar('0'), 1)).optional();
   else
     d = makeChar('.').concatenate(makeString(b2.toString())).concatenate(makeChar('0').repeat());
   DefaultAutomaton ws = Datatypes.getWhitespaceAutomaton();
   return (ws.concatenate(
               s.concatenate(makeChar('0').repeat())
                   .concatenate(makeString(b1.toString()))
                   .concatenate(d))
           .concatenate(ws))
       .minimize();
 }