/** * Constructs sub-automaton corresponding to decimal numbers of value at least * x.substring(n) and length x.substring(n).length(). */ private static int atLeast(Automaton.Builder builder, String x, int n, Collection<Integer> initials, boolean zeros) { int s = builder.createState(); if (x.length() == n) { builder.setAccept(s, true); } else { if (zeros) { initials.add(s); } char c = x.charAt(n); builder.addTransition(s, atLeast(builder, x, n + 1, initials, zeros && c == '0'), c); if (c < '9') { builder.addTransition(s, anyOfRightLength(builder, x, n + 1), (char) (c + 1), '9'); } } return s; }
/** * Internal recursive traversal for conversion. */ private static int convert(Automaton.Builder a, State s, IdentityHashMap<State,Integer> visited) { Integer converted = visited.get(s); if (converted != null) { return converted; } converted = a.createState(); a.setAccept(converted, s.is_final); visited.put(s, converted); int i = 0; int[] labels = s.labels; for (DaciukMihovAutomatonBuilder.State target : s.states) { a.addTransition(converted, convert(a, target, visited), labels[i++]); } return converted; }
/** * Constructs sub-automaton corresponding to decimal numbers of value at most * x.substring(n) and length x.substring(n).length(). */ private static int atMost(Automaton.Builder builder, String x, int n) { int s = builder.createState(); if (x.length() == n) { builder.setAccept(s, true); } else { char c = x.charAt(n); builder.addTransition(s, atMost(builder, x, (char) n + 1), c); if (c > '0') { builder.addTransition(s, anyOfRightLength(builder, x, n + 1), '0', (char) (c - 1)); } } return s; }
/** * Constructs sub-automaton corresponding to decimal numbers of length * x.substring(n).length(). */ private static int anyOfRightLength(Automaton.Builder builder, String x, int n) { int s = builder.createState(); if (x.length() == n) { builder.setAccept(s, true); } else { builder.addTransition(s, anyOfRightLength(builder, x, n + 1), '0', '9'); } return s; }
/** Add a [virtual] epsilon transition between source and dest. * Dest state must already have all transitions added because this * method simply copies those same transitions over to source. */ public void addEpsilon(int source, int dest) { for (int upto = 0; upto < nextTransition; upto += 4) { if (transitions[upto] == dest) { addTransition(source, transitions[upto + 1], transitions[upto + 2], transitions[upto + 3]); } } if (isAccept(dest)) { setAccept(source, true); } }
/** Copies over all states from other. */ public void copyStates(Automaton other) { int otherNumStates = other.getNumStates(); for (int s = 0; s < otherNumStates; s++) { int newState = createState(); setAccept(newState, other.isAccept(s)); } } }
/** Marks the specified state as accept or not. */ public void setAccept(int state, boolean accept) { builder.setAccept(state, accept); }
/** Copies over all states from other. */ public void copyStates(Automaton other) { int otherNumStates = other.getNumStates(); for (int s = 0; s < otherNumStates; s++) { int newState = createState(); setAccept(newState, other.isAccept(s)); } } }
/** Marks the specified state as accept or not. */ public void setAccept(int state, boolean accept) { builder.setAccept(state, accept); }
/** Copies over all states from other. */ public void copyStates(Automaton other) { int otherNumStates = other.getNumStates(); for (int s = 0; s < otherNumStates; s++) { int newState = createState(); setAccept(newState, other.isAccept(s)); } } }
builder.setAccept(state, true);
builder.setAccept(0, true); builder.copy(a);
builder.setAccept(1, true);
/** * Constructs sub-automaton corresponding to decimal numbers of value between * x.substring(n) and y.substring(n) and of length x.substring(n).length() * (which must be equal to y.substring(n).length()). */ private static int between(Automaton.Builder builder, String x, String y, int n, Collection<Integer> initials, boolean zeros) { int s = builder.createState(); if (x.length() == n) { builder.setAccept(s, true); } else { if (zeros) { initials.add(s); } char cx = x.charAt(n); char cy = y.charAt(n); if (cx == cy) { builder.addTransition(s, between(builder, x, y, n + 1, initials, zeros && cx == '0'), cx); } else { // cx<cy builder.addTransition(s, atLeast(builder, x, n + 1, initials, zeros && cx == '0'), cx); builder.addTransition(s, atMost(builder, y, n + 1), cy); if (cx + 1 < cy) { builder.addTransition(s, anyOfRightLength(builder, x, n+1), (char) (cx + 1), (char) (cy - 1)); } } } return s; }
/** Add a [virtual] epsilon transition between source and dest. * Dest state must already have all transitions added because this * method simply copies those same transitions over to source. */ public void addEpsilon(int source, int dest) { for (int upto = 0; upto < nextTransition; upto += 4) { if (transitions[upto] == dest) { addTransition(source, transitions[upto + 1], transitions[upto + 2], transitions[upto + 3]); } } if (isAccept(dest)) { setAccept(source, true); } }
/** Copies over all states from other. */ public void copyStates(Automaton other) { int otherNumStates = other.getNumStates(); for (int s = 0; s < otherNumStates; s++) { int newState = createState(); setAccept(newState, other.isAccept(s)); } } }
/** * Constructs sub-automaton corresponding to decimal numbers of length * x.substring(n).length(). */ private static int anyOfRightLength(Automaton.Builder builder, String x, int n) { int s = builder.createState(); if (x.length() == n) { builder.setAccept(s, true); } else { builder.addTransition(s, anyOfRightLength(builder, x, n + 1), '0', '9'); } return s; }