/** * Returns whether the provided state is the start of multiple side paths of different length (eg: new york, ny) */ public boolean hasSidePath(int state) { int numT = det.initTransition(state, transition); if (numT <= 1) { return false; } det.getNextTransition(transition); int dest = transition.dest; for (int i = 1; i < numT; i++) { det.getNextTransition(transition); if (dest != transition.dest) { return true; } } return false; }
/** Returns true if, from this state, the automaton accepts any suffix * starting with a label between start and end, inclusive. We just * look for a transition, matching this range, to the sink state. */ private boolean acceptsSuffixRange(int state, int start, int end) { int count = automaton.initTransition(state, scratchTransition); for(int i=0;i<count;i++) { automaton.getNextTransition(scratchTransition); if (start >= scratchTransition.min && end <= scratchTransition.max && scratchTransition.dest == sinkState) { return true; } } return false; }
/** * Returns the list of terms that start at the provided state */ public Term[] getTerms(String field, int state) { int numT = det.initTransition(state, transition); List<Term> terms = new ArrayList<> (); for (int i = 0; i < numT; i++) { det.getNextTransition(transition); for (int id = transition.min; id <= transition.max; id++) { Term term = new Term(field, idToTerm.get(id)); terms.add(term); } } return terms.toArray(new Term[terms.size()]); }
public void setState(int state) { this.state = state; transitionIndex = 0; transitionCount = ite.automaton.getNumTransitions(state); if (transitionCount != 0) { ite.automaton.initTransition(state, transition); ite.automaton.getNextTransition(transition); } else { // Must set min to -1 so the "label < min" check never falsely triggers: transition.min = -1; // Must set max to -1 so we immediately realize we need to step to the next transition and then pop this frame: transition.max = -1; } }
/** Returns bitset marking states reachable from the initial state. */ private static BitSet getLiveStatesFromInitial(Automaton a) { int numStates = a.getNumStates(); BitSet live = new BitSet(numStates); if (numStates == 0) { return live; } ArrayDeque<Integer> workList = new ArrayDeque<>(); live.set(0); workList.add(0); Transition t = new Transition(); while (workList.isEmpty() == false) { int s = workList.removeFirst(); int count = a.initTransition(s, t); for(int i=0;i<count;i++) { a.getNextTransition(t); if (live.get(t.dest) == false) { live.set(t.dest); workList.add(t.dest); } } } return live; }
private static int topoSortStatesRecurse(Automaton a, BitSet visited, int[] states, int upto, int state, int level) { if (level > MAX_RECURSION_LEVEL) { throw new IllegalArgumentException("input automaton is too large: " + level); } Transition t = new Transition(); int count = a.initTransition(state, t); for (int i=0;i<count;i++) { a.getNextTransition(t); if (!visited.get(t.dest)) { visited.set(t.dest); upto = topoSortStatesRecurse(a, visited, states, upto, t.dest, level+1); } } states[upto] = state; upto++; return upto; } }
private static void articulationPointsRecurse(Automaton a, int state, int d, int[] depth, int[] low, int[] parent, BitSet visited, List<Integer> points) { visited.set(state); depth[state] = d; low[state] = d; int childCount = 0; boolean isArticulation = false; Transition t = new Transition(); int numT = a.initTransition(state, t); for (int i = 0; i < numT; i++) { a.getNextTransition(t); if (visited.get(t.dest) == false) { parent[t.dest] = state; articulationPointsRecurse(a, t.dest, d + 1, depth, low, parent, visited, points); childCount++; if (low[t.dest] >= depth[state]) { isArticulation = true; } low[state] = Math.min(low[state], low[t.dest]); } else if (t.dest != parent[state]) { low[state] = Math.min(low[state], depth[t.dest]); } } if ((parent[state] != -1 && isArticulation) || (parent[state] == -1 && childCount > 1)) { points.add(state); } } }
int count = a.initTransition(s, t); for(int i=0;i<count;i++) { a.getNextTransition(t); builder.addTransition(t.dest, s, t.min, t.max); int count = a2.initTransition(s, t); for(int i=0;i<count;i++) { a2.getNextTransition(t); if (live.get(t.dest) == false) { live.set(t.dest);
a.getNextTransition(t); if (seen.get(t.dest) == false) { workList.add(t.dest);
/** * Returns the articulation points (or cut vertices) of the graph: * https://en.wikipedia.org/wiki/Biconnected_component */ public int[] articulationPoints() { if (det.getNumStates() == 0) { return new int[0]; } // Automaton.Builder undirect = new Automaton.Builder(); undirect.copy(det); for (int i = 0; i < det.getNumStates(); i++) { int numT = det.initTransition(i, transition); for (int j = 0; j < numT; j++) { det.getNextTransition(transition); undirect.addTransition(transition.dest, i, transition.min); } } int numStates = det.getNumStates(); BitSet visited = new BitSet(numStates); int[] depth = new int[det.getNumStates()]; int[] low = new int[det.getNumStates()]; int[] parent = new int[det.getNumStates()]; Arrays.fill(parent, -1); List<Integer> points = new ArrayList<>(); articulationPointsRecurse(undirect.finish(), 0, 0, depth, low, parent, visited, points); Collections.reverse(points); return points.stream().mapToInt(p -> p).toArray(); }
/** 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) { Transition t = new Transition(); int count = initTransition(dest, t); for(int i=0;i<count;i++) { getNextTransition(t); addTransition(source, t.dest, t.min, t.max); } if (isAccept(dest)) { setAccept(source, true); } }
/** Returns sink state, if present, else -1. */ private static int findSinkState(Automaton automaton) { int numStates = automaton.getNumStates(); Transition t = new Transition(); int foundState = -1; for (int s=0;s<numStates;s++) { if (automaton.isAccept(s)) { int count = automaton.initTransition(s, t); boolean isSinkState = false; for(int i=0;i<count;i++) { automaton.getNextTransition(t); if (t.dest == s && t.min == 0 && t.max == 0xff) { isSinkState = true; break; } } if (isSinkState) { foundState = s; break; } } } return foundState; }
utf32.initTransition(utf32State, scratch); for(int i=0;i<numTransitions;i++) { utf32.getNextTransition(scratch); int destUTF32 = scratch.dest; int destUTF8 = map[destUTF32];
/** Copies over all states/transitions from other. */ public void copy(Automaton other) { int offset = getNumStates(); int otherNumStates = other.getNumStates(); // Copy all states copyStates(other); // Copy all transitions Transition t = new Transition(); for(int s=0;s<otherNumStates;s++) { int count = other.initTransition(s, t); for(int i=0;i<count;i++) { other.getNextTransition(t); addTransition(offset + s, offset + t.dest, t.min, t.max); } } }
a.getNextTransition(t); if (liveSet.get(t.dest)) { result.addTransition(map[i], map[t.dest], t.min, t.max);
automaton.initTransition(state, transition); for (int i = 0; i < numTransitions; i++) { automaton.getNextTransition(transition); if (transition.min <= (seekBytesRef.byteAt(position) & 0xff) && (seekBytesRef.byteAt(position) & 0xff) <= transition.max) {
int count = a.initTransition(0, t); for(int i=0;i<count;i++) { a.getNextTransition(t); builder.addTransition(0, t.dest+1, t.min, t.max); count = a.initTransition(0, t); for(int i=0;i<count;i++) { a.getNextTransition(t); builder.addTransition(s+1, t.dest+1, t.min, t.max);
a.initTransition(s, t); for(int i=0;i<numTransitions;i++) { a.getNextTransition(t); builder.addTransition(t.dest+1, s+1, t.min, t.max);
int count = a.initTransition(i, t); for(int j=0;j<count;j++) { a.getNextTransition(t); result.addTransition(i, t.dest, t.min, t.max); if (t.min > maxi) {