예제 #1
0
            private static TThis BuildSubautomaton(IReadOnlyList <State> states, IReadOnlyList <State> topologicalOrder, int group, HashSet <int> subgraph)
            {
                var weightsFromRoot          = ComputeWeightsFromRoot(states.Count, topologicalOrder, group);
                var weightsToEnd             = ComputeWeightsToEnd(states.Count, topologicalOrder, group);
                var subautomaton             = new TThis();
                var stateMapping             = subgraph.ToDictionary(x => x, _ => subautomaton.AddState());
                var hasNoIncomingTransitions = new HashSet <int>(subgraph);

                // copy the automaton and find states without incoming transitions.
                foreach (var stateIndex in subgraph)
                {
                    var newSourceState = stateMapping[stateIndex];

                    for (int i = 0; i < states[stateIndex].TransitionCount; i++)
                    {
                        var transition = states[stateIndex].GetTransition(i);
                        if (transition.Group != group)
                        {
                            continue;
                        }
                        hasNoIncomingTransitions.Remove(transition.DestinationStateIndex);
                        newSourceState.AddTransition(
                            transition.ElementDistribution,
                            transition.Weight,
                            stateMapping[transition.DestinationStateIndex]);
                    }
                }

                var correctionFactor = Weight.Zero;

                // mark start and end states, modulo paths bypassing the automaton.
                foreach (var stateIndex in subgraph)
                {
                    var newSourceState = stateMapping[stateIndex];

                    // consider start states
                    var weightFromRoot = newSourceState.TransitionCount > 0 ? weightsFromRoot[stateIndex] : Weight.Zero;
                    if (!weightFromRoot.IsZero)
                    {
                        subautomaton.Start.AddEpsilonTransition(weightFromRoot, newSourceState);
                    }

                    // consider end states
                    var weightToEnd = !hasNoIncomingTransitions.Contains(stateIndex) ? weightsToEnd[stateIndex] : Weight.Zero;
                    if (!weightToEnd.IsZero)
                    {
                        newSourceState.SetEndWeight(weightToEnd);
                    }

                    correctionFactor = Weight.Sum(correctionFactor, Weight.Product(weightFromRoot, weightToEnd));
                }

                if (!correctionFactor.IsZero)
                {
                    throw new Exception("Write a unit test for this case. Code should be fine.");
                }
                var epsilonWeight = Weight.AbsoluteDifference(weightsToEnd[topologicalOrder[0].Index], correctionFactor);

                subautomaton.Start.SetEndWeight(epsilonWeight);

                return(subautomaton);
            }
예제 #2
0
 public MyServiceInterface(TThis service, string name, Type[] dependencies)
 {
     m_service      = service;
     this.Name      = name;
     m_dependencies = dependencies;
 }