/// <summary>
        /// Merges multiple tokens into one, updates activeGlobalIdMonitor accordingly.
        /// </summary>
        /// <param name="tokens">A list of tokens to be merged into one.</param>
        /// <param name="activeGlobalIdMonitor">A monitor of how many tokens of each level are still active.</param>
        /// <returns>A token to be passed further.</returns>
        public static FootprintAnalysisToken MergeTokens(List <FootprintAnalysisToken> tokens, Dictionary <string, int> activeGlobalIdMonitor)
        {
            CheckInputTokens(tokens);
            FootprintAnalysisToken outputToken = new FootprintAnalysisToken(tokens[tokens.Count - 1]);

            for (int i = tokens.Count - 2; i >= 0; i--)
            {
                bool hasMerged = false;
                FootprintAnalysisToken mergedToken = tokens[i];
                for (int j = mergedToken.ActiveLevels.Count - 1; j >= 0 && !hasMerged; j--)
                {
                    string mergedLevel = mergedToken.ActiveLevels[j];
                    for (int k = outputToken.ActiveLevels.Count - 1; k >= 0 && !hasMerged; k--)
                    {
                        string outputLevel = outputToken.ActiveLevels[k];
                        if (StringUtils.GetGlobalId(mergedLevel) == StringUtils.GetGlobalId(outputLevel))
                        {
                            MergeTwoTokens(ref outputToken, mergedToken, mergedLevel, activeGlobalIdMonitor);
                            hasMerged = true;
                        }
                    }
                }
            }
            return(outputToken);
        }
        /// <summary>
        /// Splits given token and passes the new tokens to given output places.
        /// </summary>
        /// <param name="outputPlaces">Output places to be fired into.</param>
        /// <param name="footprint">A token to be split into output places.</param>
        private void FireParallel(List <PlaceTokenTraverseOverlay> outputPlaces, FootprintAnalysisToken footprint)
        {
            List <FootprintAnalysisToken> newFootprints = TokenManipulationUtils.SplitToken(footprint, (uint)outputPlaces.Count, GetNewGlobalId(), ActiveGlobalIdMonitor);

            for (int i = 0; i < newFootprints.Count; i++)
            {
                outputPlaces[i].SetFootprint(newFootprints[i]);
            }
        }
        /// <summary>
        /// Gets current (active) global IDs from given token.
        /// </summary>
        /// <param name="token">A token from which current global IDs should be extracted.</param>
        /// <returns>A list of global IDs of given token.</returns>
        public static List <string> GetActiveGlobalIds(FootprintAnalysisToken token)
        {
            List <string> splitIds = new List <string>();

            foreach (string level in token.ActiveLevels)
            {
                splitIds.Add(StringUtils.GetGlobalId(level));
            }
            return(splitIds);
        }
        /// <summary>
        /// Splits one token into multiple, adds new level to all of the resulting tokens, updates activeGlobalIdMonitor accordingly.
        /// </summary>
        /// <param name="token">A token to be split.</param>
        /// <param name="count">Number of how many new tokens should be created.</param>
        /// <param name="newGlobalId">New global ID of new created level.</param>
        /// <param name="activeGlobalIdMonitor">A monitor of how many tokens of each level are still active.</param>
        /// <returns>List of new tokens.</returns>
        public static List <FootprintAnalysisToken> SplitToken(FootprintAnalysisToken token, uint count, string newGlobalId, Dictionary <string, int> activeGlobalIdMonitor)
        {
            List <FootprintAnalysisToken> outputTokens = new List <FootprintAnalysisToken>();
            string localId = "A";

            for (uint i = 0; i < count; i++)
            {
                FootprintAnalysisToken newToken = new FootprintAnalysisToken(token);
                newToken.ActiveLevels.Add(newGlobalId + localId);
                outputTokens.Add(newToken);
                localId = StringUtils.IncrementId(localId);
            }
            activeGlobalIdMonitor.Add(newGlobalId, (int)count);
            return(outputTokens);
        }
        /// <summary>
        /// Merges two tokens into one on a given level, updates activeGlobalIdMonitor accordingly.
        /// </summary>
        /// <param name="outputToken">Token which will be passed as a result.</param>
        /// <param name="mergedToken">Token which will be merged and dropped.</param>
        /// <param name="mergedLevel">A level on which the merge should occur.</param>
        /// <param name="activeGlobalIdMonitor">A monitor of how many tokens of each level are still active.</param>
        private static void MergeTwoTokens(ref FootprintAnalysisToken outputToken,
                                           FootprintAnalysisToken mergedToken,
                                           string mergedLevel,
                                           Dictionary <string, int> activeGlobalIdMonitor)
        {
            int    i = 0;
            string mergedGlobalId = StringUtils.GetGlobalId(mergedLevel);

            outputToken.MergedLevels.Add(mergedLevel);
            activeGlobalIdMonitor[mergedGlobalId]--;

            foreach (string mergedTokenCurrentLevel in mergedToken.ActiveLevels)
            {
                if (!outputToken.ActiveLevels.Contains(mergedTokenCurrentLevel) && mergedTokenCurrentLevel != mergedLevel)
                {
                    int.TryParse(StringUtils.GetGlobalId(outputToken.ActiveLevels[i]), out int outputCurrentGlobalId);
                    int.TryParse(StringUtils.GetGlobalId(mergedTokenCurrentLevel), out int mergedCurrentGlobalId);
                    while (outputCurrentGlobalId < mergedCurrentGlobalId)
                    {
                        i++;
                        int.TryParse(StringUtils.GetGlobalId(outputToken.ActiveLevels[i]), out outputCurrentGlobalId);
                    }
                    outputToken.ActiveLevels.Insert(i, mergedTokenCurrentLevel);
                }
            }
            foreach (string mergedTokenMergedLevel in mergedToken.MergedLevels)
            {
                if (!outputToken.MergedLevels.Contains(mergedTokenMergedLevel))
                {
                    outputToken.MergedLevels.Add(mergedTokenMergedLevel);
                }
            }
            if (activeGlobalIdMonitor[mergedGlobalId] == 1)
            {
                string level = outputToken.ActiveLevels.Find(a => StringUtils.GetGlobalId(a) == mergedGlobalId);
                if (level != null)
                {
                    outputToken.MergedLevels.Add(level);
                    outputToken.ActiveLevels.Remove(level);
                    activeGlobalIdMonitor.Remove(mergedGlobalId);
                }
            }
        }
Exemple #6
0
 /// <summary>
 /// Sets given FootprintAnalysisToken as footprint and marks the place.
 /// </summary>
 /// <param name="footprint">FootprintAnalysisToken to be set as transition's footprint.</param>
 public void SetFootprint(FootprintAnalysisToken footprint)
 {
     TokenFootprint = footprint;
     IsMarked       = true;
 }
 public FootprintAnalysisToken(FootprintAnalysisToken token)
 {
     ActiveLevels = new List <string>(token.ActiveLevels);
     MergedLevels = new List <string>(token.MergedLevels);
 }