public virtual string ToDot()
 {
     StringBuilder b = new StringBuilder("digraph CompiledAutomaton {\n");
     b.Append("  rankdir = LR;\n");
     int initial = RunAutomaton.InitialState;
     for (int i = 0; i < sortedTransitions.Length; i++)
     {
         b.Append("  ").Append(i);
         if (RunAutomaton.IsAccept(i))
         {
             b.Append(" [shape=doublecircle,label=\"\"];\n");
         }
         else
         {
             b.Append(" [shape=circle,label=\"\"];\n");
         }
         if (i == initial)
         {
             b.Append("  initial [shape=plaintext,label=\"\"];\n");
             b.Append("  initial -> ").Append(i).Append("\n");
         }
         for (int j = 0; j < sortedTransitions[i].Length; j++)
         {
             b.Append("  ").Append(i);
             sortedTransitions[i][j].AppendDot(b);
         }
     }
     return b.Append("}\n").ToString();
 }
Example #2
0
        //private static final boolean DEBUG = BlockTreeTermsWriter.DEBUG;

        private BytesRef AddTail(int state, BytesRef term, int idx, int leadLabel)
        {
            // Find biggest transition that's < label
            // TODO: use binary search here
            Transition maxTransition = null;

            foreach (Transition transition in sortedTransitions[state])
            {
                if (transition.min < leadLabel)
                {
                    maxTransition = transition;
                }
            }

            if (Debugging.AssertsEnabled)
            {
                Debugging.Assert(maxTransition != null);
            }

            // Append floorLabel
            int floorLabel;

            if (maxTransition.max > leadLabel - 1)
            {
                floorLabel = leadLabel - 1;
            }
            else
            {
                floorLabel = maxTransition.max;
            }
            if (idx >= term.Bytes.Length)
            {
                term.Grow(1 + idx);
            }
            //if (DEBUG) System.out.println("  add floorLabel=" + (char) floorLabel + " idx=" + idx);
            term.Bytes[idx] = (byte)floorLabel;

            state = maxTransition.to.Number;
            idx++;

            // Push down to last accept state
            while (true)
            {
                Transition[] transitions = sortedTransitions[state];
                if (transitions.Length == 0)
                {
                    if (Debugging.AssertsEnabled)
                    {
                        Debugging.Assert(RunAutomaton.IsAccept(state));
                    }
                    term.Length = idx;
                    //if (DEBUG) System.out.println("  return " + term.utf8ToString());
                    return(term);
                }
                else
                {
                    // We are pushing "top" -- so get last label of
                    // last transition:
                    if (Debugging.AssertsEnabled)
                    {
                        Debugging.Assert(transitions.Length != 0);
                    }
                    Transition lastTransition = transitions[transitions.Length - 1];
                    if (idx >= term.Bytes.Length)
                    {
                        term.Grow(1 + idx);
                    }
                    //if (DEBUG) System.out.println("  push maxLabel=" + (char) lastTransition.max + " idx=" + idx);
                    term.Bytes[idx] = (byte)lastTransition.max;
                    state           = lastTransition.to.Number;
                    idx++;
                }
            }
        }
        /// <summary>
        /// Finds largest term accepted by this Automaton, that's
        /// &lt;= the provided input term.  The result is placed in
        /// output; it's fine for output and input to point to
        /// the same <see cref="BytesRef"/>.  The returned result is either the
        /// provided output, or <c>null</c> if there is no floor term
        /// (ie, the provided input term is before the first term
        /// accepted by this <see cref="Automaton"/>).
        /// </summary>
        public virtual BytesRef Floor(BytesRef input, BytesRef output)
        {
            output.Offset = 0;
            //if (DEBUG) System.out.println("CA.floor input=" + input.utf8ToString());

            int state = RunAutomaton.InitialState;

            // Special case empty string:
            if (input.Length == 0)
            {
                if (RunAutomaton.IsAccept(state))
                {
                    output.Length = 0;
                    return output;
                }
                else
                {
                    return null;
                }
            }

            IList<int> stack = new List<int>();

            int idx = 0;
            while (true)
            {
                int label = ((sbyte)input.Bytes[input.Offset + idx]) & 0xff;
                int nextState = RunAutomaton.Step(state, label);
                //if (DEBUG) System.out.println("  cycle label=" + (char) label + " nextState=" + nextState);

                if (idx == input.Length - 1)
                {
                    if (nextState != -1 && RunAutomaton.IsAccept(nextState))
                    {
                        // Input string is accepted
                        if (idx >= output.Bytes.Length)
                        {
                            output.Grow(1 + idx);
                        }
                        output.Bytes[idx] = (byte)label;
                        output.Length = input.Length;
                        //if (DEBUG) System.out.println("  input is accepted; return term=" + output.utf8ToString());
                        return output;
                    }
                    else
                    {
                        nextState = -1;
                    }
                }

                if (nextState == -1)
                {
                    // Pop back to a state that has a transition
                    // <= our label:
                    while (true)
                    {
                        Transition[] transitions = sortedTransitions[state];
                        if (transitions.Length == 0)
                        {
                            if (Debugging.AssertsEnabled) Debugging.Assert(RunAutomaton.IsAccept(state));
                            output.Length = idx;
                            //if (DEBUG) System.out.println("  return " + output.utf8ToString());
                            return output;
                        }
                        else if (label - 1 < transitions[0].min)
                        {
                            if (RunAutomaton.IsAccept(state))
                            {
                                output.Length = idx;
                                //if (DEBUG) System.out.println("  return " + output.utf8ToString());
                                return output;
                            }
                            // pop
                            if (stack.Count == 0)
                            {
                                //if (DEBUG) System.out.println("  pop ord=" + idx + " return null");
                                return null;
                            }
                            else
                            {
                                state = stack[stack.Count - 1];
                                stack.RemoveAt(stack.Count - 1);
                                idx--;
                                //if (DEBUG) System.out.println("  pop ord=" + (idx+1) + " label=" + (char) label + " first trans.min=" + (char) transitions[0].min);
                                label = input.Bytes[input.Offset + idx] & 0xff;
                            }
                        }
                        else
                        {
                            //if (DEBUG) System.out.println("  stop pop ord=" + idx + " first trans.min=" + (char) transitions[0].min);
                            break;
                        }
                    }

                    //if (DEBUG) System.out.println("  label=" + (char) label + " idx=" + idx);

                    return AddTail(state, output, idx, label);
                }
                else
                {
                    if (idx >= output.Bytes.Length)
                    {
                        output.Grow(1 + idx);
                    }
                    output.Bytes[idx] = (byte)label;
                    stack.Add(state);
                    state = nextState;
                    idx++;
                }
            }
        }