Beispiel #1
0
            /// <summary>
            /// Initializes a new instance of the <see cref="EpsilonClosure"/> class.
            /// </summary>
            /// <param name="automaton">The automaton from to which <paramref name="state"/> belongs.</param>
            /// <param name="state">The state, which epsilon closure this instance will represent.</param>
            internal EpsilonClosure(
                Automaton <TSequence, TElement, TElementDistribution, TSequenceManipulator, TThis> automaton,
                State state)
            {
                this.weightedStates = new List <(State, Weight)>(DefaultStateListCapacity);

                // Optimize for a very common case: a single-node closure
                bool   singleNodeClosure = true;
                Weight selfLoopWeight    = Weight.Zero;

                foreach (var transition in state.Transitions)
                {
                    if (transition.IsEpsilon)
                    {
                        if (transition.DestinationStateIndex != state.Index)
                        {
                            singleNodeClosure = false;
                            break;
                        }

                        selfLoopWeight += transition.Weight;
                    }
                }

                if (singleNodeClosure)
                {
                    Weight stateWeight = Weight.ApproximateClosure(selfLoopWeight);
                    this.weightedStates.Add((state, stateWeight));
                    this.EndWeight = stateWeight * state.EndWeight;
                }
                else
                {
                    Condensation condensation = automaton.ComputeCondensation(state, tr => tr.IsEpsilon, true);
                    for (int i = 0; i < condensation.ComponentCount; ++i)
                    {
                        StronglyConnectedComponent component = condensation.GetComponent(i);
                        for (int j = 0; j < component.Size; ++j)
                        {
                            State componentState = component.GetStateByIndex(j);
                            this.weightedStates.Add((componentState, condensation.GetWeightFromRoot(componentState)));
                        }
                    }

                    this.EndWeight = condensation.GetWeightToEnd(state.Index);
                }
            }
Beispiel #2
0
            /// <summary>
            /// Initializes a new instance of the <see cref="EpsilonClosure"/> class.
            /// </summary>
            /// <param name="state">The state, which epsilon closure this instance will represent.</param>
            internal EpsilonClosure(State state)
            {
                Argument.CheckIfValid(!state.IsNull, nameof(state));

                // Optimize for a very common case: a single-node closure
                bool   singleNodeClosure = true;
                Weight selfLoopWeight    = Weight.Zero;

                for (int i = 0; i < state.TransitionCount; ++i)
                {
                    Transition transition = state.GetTransition(i);
                    if (transition.IsEpsilon)
                    {
                        if (transition.DestinationStateIndex != state.Index)
                        {
                            singleNodeClosure = false;
                            break;
                        }

                        selfLoopWeight = Weight.Sum(selfLoopWeight, transition.Weight);
                    }
                }

                if (singleNodeClosure)
                {
                    Weight stateWeight = Weight.ApproximateClosure(selfLoopWeight);
                    this.weightedStates.Add(Pair.Create(state, stateWeight));
                    this.EndWeight = Weight.Product(stateWeight, state.EndWeight);
                }
                else
                {
                    Condensation condensation = state.Owner.ComputeCondensation(state, tr => tr.IsEpsilon, true);
                    for (int i = 0; i < condensation.ComponentCount; ++i)
                    {
                        StronglyConnectedComponent component = condensation.GetComponent(i);
                        for (int j = 0; j < component.Size; ++j)
                        {
                            State componentState = component.GetStateByIndex(j);
                            this.weightedStates.Add(Pair.Create(componentState, condensation.GetWeightFromRoot(componentState)));
                        }
                    }

                    this.EndWeight = condensation.GetWeightToEnd(state);
                }
            }