Пример #1
0
        /// <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);
                }
            }
        }
Пример #2
0
        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);
                }
            }
        }
Пример #3
0
 public ArcListDebugDisplay(ArcList item)
 {
     _item = item;
 }
Пример #4
0
        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);
                }
            }
        }
Пример #5
0
        /// <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);
                }
            }
        }