/** Initialize the provided Transition to iterate through all transitions * leaving the specified state. You must call {@link #getNextTransition} to * get each transition. Returns the number of transitions * leaving this state. */ public int initTransition(int state, Transition t) { assert state < nextState/2: "state=" + state + " nextState=" + nextState; t.source = state; t.transitionUpto = states[2*state]; return getNumTransitions(state); }
public void resetState(Automaton a, int state) { assert a.getNumTransitions(state) != 0; this.state = state; transition = 0; a.getTransition(state, 0, t); label = t.min; to = t.dest; }
/** Use this constructor when the automaton failed to determinize. */ public TooComplexToDeterminizeException(Automaton automaton, int maxDeterminizedStates) { super("Determinizing automaton with " + automaton.getNumStates() + " states and " + automaton.getNumTransitions() + " transitions would result in more than " + maxDeterminizedStates + " states."); this.automaton = automaton; this.regExp = null; this.maxDeterminizedStates = maxDeterminizedStates; }
/** Returns next label of current transition, or * advances to next transition and returns its first * label, if current one is exhausted. If there are * no more transitions, returns -1. */ public int nextLabel(Automaton a) { if (label > t.max) { // We've exhaused the current transition's labels; // move to next transitions: transition++; if (transition >= a.getNumTransitions(state)) { // We're done iterating transitions leaving this state label = -1; return -1; } a.getTransition(state, transition, t); label = t.min; to = t.dest; } return label++; } }
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 the longest string that is a prefix of all accepted strings and * visits each state at most once. The automaton must be deterministic. * * @return common prefix, which can be an empty (length 0) String (never null) */ public static String getCommonPrefix(Automaton a) { if (a.isDeterministic() == false) { throw new IllegalArgumentException("input automaton must be deterministic"); } StringBuilder b = new StringBuilder(); HashSet<Integer> visited = new HashSet<>(); int s = 0; boolean done; Transition t = new Transition(); do { done = true; visited.add(s); if (a.isAccept(s) == false && a.getNumTransitions(s) == 1) { a.getTransition(s, 0, t); if (t.min == t.max && !visited.contains(t.dest)) { b.appendCodePoint(t.min); s = t.dest; done = false; } } } while (!done); return b.toString(); }
/** * Returns true if the given automaton accepts all strings for the specified min/max * range of the alphabet. The automaton must be minimized. */ public static boolean isTotal(Automaton a, int minAlphabet, int maxAlphabet) { if (a.isAccept(0) && a.getNumTransitions(0) == 1) { Transition t = new Transition(); a.getTransition(0, 0, t); return t.dest == 0 && t.min == minAlphabet && t.max == maxAlphabet; } return false; }
/** If this automaton accepts a single input, return it. Else, return null. * The automaton must be deterministic. */ public static IntsRef getSingleton(Automaton a) { if (a.isDeterministic() == false) { throw new IllegalArgumentException("input automaton must be deterministic"); } IntsRefBuilder builder = new IntsRefBuilder(); HashSet<Integer> visited = new HashSet<>(); int s = 0; Transition t = new Transition(); while (true) { visited.add(s); if (a.isAccept(s) == false) { if (a.getNumTransitions(s) == 1) { a.getTransition(s, 0, t); if (t.min == t.max && !visited.contains(t.dest)) { builder.append(t.min); s = t.dest; continue; } } } else if (a.getNumTransitions(s) == 0) { return builder.get(); } // Automaton accepts more than one string: return null; } }
/** Sugar to get all transitions for all states. This is * object-heavy; it's better to iterate state by state instead. */ public Transition[][] getSortedTransitions() { int numStates = getNumStates(); Transition[][] transitions = new Transition[numStates][]; for(int s=0;s<numStates;s++) { int numTransitions = getNumTransitions(s); transitions[s] = new Transition[numTransitions]; for(int t=0;t<numTransitions;t++) { Transition transition = new Transition(); getTransition(s, t, transition); transitions[s][t] = transition; } } return transitions; }
/** * Returns the longest BytesRef that is a prefix of all accepted strings and * visits each state at most once. The automaton must be deterministic. * * @return common prefix, which can be an empty (length 0) BytesRef (never null) */ public static BytesRef getCommonPrefixBytesRef(Automaton a) { BytesRefBuilder builder = new BytesRefBuilder(); HashSet<Integer> visited = new HashSet<>(); int s = 0; boolean done; Transition t = new Transition(); do { done = true; visited.add(s); if (a.isAccept(s) == false && a.getNumTransitions(s) == 1) { a.getTransition(s, 0, t); if (t.min == t.max && !visited.contains(t.dest)) { builder.append((byte) t.min); s = t.dest; done = false; } } } while (!done); return builder.get(); }
if (a.isAccept(0) == false && a.getNumTransitions(0) == 0) {
/** * Constructor. * * @param a Automaton to create finite string from. * @param startState The starting state for each path. * @param endState The state where each path should stop or -1 if only accepted states should be final. */ public FiniteStringsIterator(Automaton a, int startState, int endState) { this.a = a; this.endState = endState; this.nodes = new PathNode[16]; for (int i = 0, end = nodes.length; i < end; i++) { nodes[i] = new PathNode(); } this.string = new IntsRefBuilder(); this.pathStates = new BitSet(a.getNumStates()); this.string.setLength(0); this.emitEmptyString = a.isAccept(0); // Start iteration with node startState. if (a.getNumTransitions(startState) > 0) { pathStates.set(startState); nodes[0].resetState(a, startState); string.append(startState); } }
assert utf8State != -1; int numTransitions = utf32.getNumTransitions(utf32State); utf32.initTransition(utf32State, scratch); for(int i=0;i<numTransitions;i++) {
if (a.getNumTransitions(to) != 0 && to != endState) {
assert state >= 0: "state=" + state; final int numTransitions = automaton.getNumTransitions(state); automaton.initTransition(state, transition); for (int i = 0; i < numTransitions; i++) {
int numTransitions = a.getNumTransitions(s); a.initTransition(s, t); for(int i=0;i<numTransitions;i++) {
int numTransitions = automaton.getNumTransitions(state); if (numTransitions == 0) { assert runAutomaton.isAccept(state);
int numTransitions = a.getNumTransitions(s0); a.initTransition(s0, t); for(int j=0;j<numTransitions;j++) {
numTransitions = automaton.getNumTransitions(state); if (numTransitions == 0) {
visited[state] = curGen; final int numTransitions = automaton.getNumTransitions(state); automaton.initTransition(state, transition);