Ejemplo n.º 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);
                }
            }
        }
Ejemplo n.º 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);
                }
            }
        }
Ejemplo n.º 3
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);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        ///  Process the '/item' element.
        /// </summary>
        void IElement.PostParse(IElement parentElement)
        {
            // Special case of no words but only tags. Returns an error as the result is ambiguous
            // <tag>var res= 1;</tag>
            // <item repeat="2-2">
            //    <tag>res= res * 2;</tag>
            // </item>
            // Should the result be 2 or 4
            if (_maxRepeat != _minRepeat && _startArc != null && _startArc == _endArc && _endArc.IsEpsilonTransition && !_endArc.IsPropertylessTransition)
            {
                XmlParser.ThrowSrgsException((SRID.InvalidTagInAnEmptyItem));
            }

            // empty <item> or repeat count == 0
            if (_startArc == null || _maxRepeat == 0)
            {
                // Special Case: _maxRepeat = 0 => Epsilon transition.
                if (_maxRepeat == 0 && _startArc != null && _startArc.End != null)
                {
                    // Delete contents of Item.  Otherwise, we will end up with states disconnected to the rest of the rule.
                    State endState = _startArc.End;
                    _startArc.End = null;
                    _backend.DeleteSubGraph(endState);
                }
                // empty item, just add an epsilon transition.
                _startArc = _endArc = _backend.EpsilonTransition(_repeatProbability);
            }
            else
            {
                // Hard case if repeat count is not one
                if (_minRepeat != 1 || _maxRepeat != 1)
                {
                    // Duplicate the states/transitions graph as many times as repeat count

                    //Add a state before the start to be able to duplicate the graph
                    _startArc = InsertState(_startArc, _repeatProbability, Position.Before);
                    State startState = _startArc.End;

                    // If _maxRepeat = Infinite, add epsilon transition loop back to the start of this
                    if (_maxRepeat == int.MaxValue && _minRepeat == 1)
                    {
                        _endArc = InsertState(_endArc, 1.0f, Position.After);

                        AddEpsilonTransition(_endArc.Start, startState, 1 - _repeatProbability);
                    }
                    else
                    {
                        State currentStartState = startState;

                        // For each additional repeat count, clone a new subgraph and connect with appropriate transitions.
                        for (uint cnt = 1; cnt < _maxRepeat && cnt < 255; cnt++)
                        {
                            // Prepare to clone a new subgraph matching the <item> content.
                            State newStartState = _backend.CreateNewState(_endArc.Start.Rule);

                            // Clone subgraphs and update CurrentEndState.
                            State newEndState = _backend.CloneSubGraph(currentStartState, _endArc.Start, newStartState);

                            // Connect the last state with the first state
                            //_endArc.Start.OutArcs.Add (_endArc);
                            _endArc.End = newStartState;

                            // reset the _endArc
                            System.Diagnostics.Debug.Assert(newEndState.OutArcs.CountIsOne && Arc.CompareContent(_endArc, newEndState.OutArcs.First) == 0);
                            _endArc = newEndState.OutArcs.First;

                            if (_maxRepeat == int.MaxValue)
                            {
                                // If we are beyond _minRepeat, add epsilon transition from startState with (1-_repeatProbability).
                                if (cnt == _minRepeat - 1)
                                {
                                    // Create a new state and attach the last Arc to add
                                    _endArc = InsertState(_endArc, 1.0f, Position.After);

                                    AddEpsilonTransition(_endArc.Start, newStartState, 1 - _repeatProbability);
                                    break;
                                }
                            }
                            else if (cnt <= _maxRepeat - _minRepeat)
                            {
                                // If we are beyond _minRepeat, add epsilon transition from startState with (1-_repeatProbability).
                                AddEpsilonTransition(startState, newStartState, 1 - _repeatProbability);
                            }

                            // reset the current start state
                            currentStartState = newStartState;
                        }
                    }
                    // If _minRepeat == 0, add epsilon transition from currentEndState to FinalState with (1-_repeatProbability).
                    // but do not do it if the only transition is an epsilon
                    if (_minRepeat == 0 && (_startArc != _endArc || !_startArc.IsEpsilonTransition))
                    {
                        if (!_endArc.IsEpsilonTransition || _endArc.SemanticTagCount > 0)
                        {
                            _endArc = InsertState(_endArc, 1.0f, Position.After);
                        }
                        AddEpsilonTransition(startState, _endArc.Start, 1 - _repeatProbability);
                    }

                    // Remove the added startState if possible
                    _startArc = TrimStart(_startArc, _backend);
                }
            }

            // Add this item to the parent list
            base.PostParse((ParseElementCollection)parentElement);
        }
Ejemplo n.º 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);
                }
            }
        }