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); }
public MyServiceInterface(TThis service, string name, Type[] dependencies) { m_service = service; this.Name = name; m_dependencies = dependencies; }