/// <summary> /// Description: /// Merge identical transitions with identical content, StartState, and EndState. /// /// </summary> private static void MergeIdenticalTransitions(ArcList arcs, List <Arc> identicalWords) { // Need at least two transitions to merge. System.Diagnostics.Debug.Assert(arcs.ContainsMoreThanOneItem); // Need at least two transitions to merge. List <List <Arc> > segmentsToDelete = null; Arc refArc = arcs.First; // Accumulate a set of transition to delete foreach (Arc arc in arcs) { if (Arc.CompareContent(refArc, arc) != 0) { // Identical transition if (identicalWords.Count >= 2) { identicalWords.Sort(Arc.CompareIdenticalTransitions); if (segmentsToDelete == null) { segmentsToDelete = new List <List <Arc> >(); } // Add the list of same words into a list for further processing. // The expectation of having an identical transition is very low so the code // may be a bit slow. segmentsToDelete.Add(new List <Arc>(identicalWords)); } identicalWords.Clear(); } refArc = arc; identicalWords.Add(arc); } // Did the last word was replicated several times? if (identicalWords.Count >= 2) { MergeIdenticalTransitions(identicalWords); } identicalWords.Clear(); // Process the accumulated words if (segmentsToDelete != null) { foreach (List <Arc> segmentToDelete in segmentsToDelete) { MergeIdenticalTransitions(segmentToDelete); } } }
private static void MergeIdenticalTransitions(ArcList arcs, List <Arc> identicalWords) { List <List <Arc> > list = null; Arc arc = arcs.First; foreach (Arc arc2 in arcs) { if (Arc.CompareContent(arc, arc2) != 0) { if (identicalWords.Count >= 2) { identicalWords.Sort(Arc.CompareIdenticalTransitions); if (list == null) { list = new List <List <Arc> >(); } list.Add(new List <Arc>(identicalWords)); } identicalWords.Clear(); } arc = arc2; identicalWords.Add(arc2); } if (identicalWords.Count >= 2) { MergeIdenticalTransitions(identicalWords); } identicalWords.Clear(); if (list != null) { foreach (List <Arc> item in list) { MergeIdenticalTransitions(item); } } }
public ArcListDebugDisplay(ArcList item) { _item = item; }
private void MergeDuplicateOutputTransitions(ArcList arcs, Stack <State> mergeStates) { List <Arc> list = null; Arc arc = null; bool flag = false; foreach (Arc arc5 in arcs) { bool flag2 = arc5.End == null || !arc5.End.InArcs.CountIsOne; if (arc != null && Arc.CompareContent(arc5, arc) == 0) { if (!flag2) { if (list == null) { list = new List <Arc>(); } if (!flag) { list.Add(arc); flag = true; } list.Add(arc5); } } else { arc = (flag2 ? null : arc5); flag = false; } } if (list != null) { list.Sort(Arc.CompareForDuplicateOutputTransitions); arc = null; Arc arc3 = null; State state = null; bool flag3 = false; foreach (Arc item in list) { if (arc == null || Arc.CompareContent(item, arc) != 0) { arc = item; if (flag3) { AddToMergeStateList(mergeStates, state); } arc3 = null; state = null; flag3 = false; } Arc arc4 = item; State end = arc4.End; if (end != end.Rule._firstState && MoveSemanticTagRight(arc4)) { if (arc3 != null) { if (!flag3) { foreach (Arc outArc in state.OutArcs) { outArc.Weight *= arc3.Weight; } flag3 = true; } foreach (Arc outArc2 in end.OutArcs) { outArc2.Weight *= arc4.Weight; } arc4.Weight += arc3.Weight; Arc.CopyTags(arc3, arc4, Direction.Right); DeleteTransition(arc3); MoveOutputTransitionsAndDeleteState(state, end); } arc3 = arc4; state = end; } } if (flag3) { AddToMergeStateList(mergeStates, state); } } }
/// <summary> /// Description: /// Sort and iterate through the output arcs and remove duplicate output transitions. /// /// Algorithm: /// - MergeIdenticalTransitions(Arcs) /// - Sort the output transitions from the state (by content and # input arcs from end state) /// - For each set of transitions with identical content, EndState != null, and EndState.InputArcs.Count() == 1 /// - Move semantic properties to the right, if necessary. /// - Label the first property-less transition as CommonArc /// - For each property-less transition (DuplicateArc) including CommonArc /// - Multiply the weights of output transitions from DuplicateArc.EndState by DuplicateArc.Weight. /// - If DuplicateArc != CommonArc /// - CommonArc.Weight += DuplicateArc.Weight /// - Delete DuplicateArc /// - MoveOutputTransitionsAndDeleteState(DuplicateArc.EndState, CommonArc.EndState) /// - Normalize weights of output transitions from CommonArc.EndState. /// - Add CommonArc.EndtState to ToDoList if not there already. /// /// Moving SemanticTag: /// - Duplicate output transitions can move its semantic tag ownerships/references to the right. /// </summary> /// <param name="arcs">Collection of output transitions to collapse</param> /// <param name="mergeStates">Collection of states with potential transitions to merge</param> private void MergeDuplicateOutputTransitions(ArcList arcs, Stack <State> mergeStates) { List <Arc> arcsToMerge = null; // Reference Arc Arc refArc = null; bool refSet = false; // Build a list of possible arcs to Merge foreach (Arc arc in arcs) { // Skip transitions whose end state has other incoming transitions or if the end state has more than one incoming transition bool skipTransition = arc.End == null || !arc.End.InArcs.CountIsOne; // Find next set of duplicate output transitions (potentially with properties). if (refArc != null && Arc.CompareContent(arc, refArc) == 0) { if (!skipTransition) { // Lazy init as entering this loop is a rare event if (arcsToMerge == null) { arcsToMerge = new List <Arc>(); } // Add the first element if (!refSet) { arcsToMerge.Add(refArc); refSet = true; } arcsToMerge.Add(arc); } } else { // New word, reset everything refArc = skipTransition ? null : arc; refSet = false; } } // Combine the arcs if possible if (arcsToMerge != null) { // Sort the arc per content and output transition arcsToMerge.Sort(Arc.CompareForDuplicateOutputTransitions); refArc = null; Arc commonArc = null; // Common property-less transition to merge into State commonEndState = null; bool fCommonEndStateChanged = false; // Did CommonEndState change and need re-optimization? foreach (Arc arc in arcsToMerge) { if (refArc == null || Arc.CompareContent(arc, refArc) != 0) { // Purge the last operations and reset all the local refArc = arc; // If CommonEndState changed, renormalize weights and add it to MergeStates for reoptimization. if (fCommonEndStateChanged) { AddToMergeStateList(mergeStates, commonEndState); } // Reset the arcs commonArc = null; commonEndState = null; fCommonEndStateChanged = false; } // For each property-less duplicate transition Arc duplicatedArc = arc; State duplicatedEndState = duplicatedArc.End; // Attempt to move properties referencing duplicate arc to the right. // Optimization can only be applied when the duplicate arc is not referenced by any properties // and the duplicate end state is not the RuleInitalState. if ((duplicatedEndState != duplicatedEndState.Rule._firstState) && MoveSemanticTagRight(duplicatedArc)) { // duplicatedArc != commonArc if (commonArc != null) { if (!fCommonEndStateChanged) { // Processing first duplicate arc. // Multiply the weights of transitions from CommonEndState by CommonArc.Weight. foreach (Arc arcOut in commonEndState.OutArcs) { arcOut.Weight *= commonArc.Weight; } fCommonEndStateChanged = true; // Output transitions of CommonEndState changed. } // Multiply the weights of transitions from DuplicateEndState by DuplicateArc.Weight. foreach (Arc arcOut in duplicatedEndState.OutArcs) { arcOut.Weight *= duplicatedArc.Weight; } duplicatedArc.Weight += commonArc.Weight; // Merge duplicate arc weight with common arc Arc.CopyTags(commonArc, duplicatedArc, Direction.Right); DeleteTransition(commonArc); // Delete successive duplicate transitions // Move outputs of duplicate state to common state; Delete duplicate state MoveOutputTransitionsAndDeleteState(commonEndState, duplicatedEndState); } // Label first property-less transition as CommonArc commonArc = duplicatedArc; commonEndState = duplicatedEndState; } } // If CommonEndState changed, renormalize weights and add it to MergeStates for reoptimization. if (fCommonEndStateChanged) { AddToMergeStateList(mergeStates, commonEndState); } } }