/**
         * Generate a frequency set as the union of two input sets, with the
         * values clipped to a specified maximum value. If an element is
         * contained in both sets, the value for the output, prior to clipping,
         * will be the sum of the two input values.
         *
         * @param a The first set.
         * @param b The second set.
         * @param clip The maximum value to allow for any output.
         * @return The sum of the two sets, with the individual elements clipped
         * to the maximum value given by {@code clip}.
         */
        protected static FrequencySet <string> CombineAndClip(FrequencySet <string> a, FrequencySet <string> b, int clip)
        {
            FrequencySet <string> result = new FrequencySet <string>();

            foreach (KeyValuePair <string, StrongBox <int> > entry in a)
            {
                for (int i = 0; i < entry.Value.Value; i++)
                {
                    result.Add(entry.Key);
                }
            }

            foreach (KeyValuePair <string, StrongBox <int> > entry in b)
            {
                for (int i = 0; i < entry.Value.Value; i++)
                {
                    result.Add(entry.Key);
                }
            }

            foreach (KeyValuePair <string, StrongBox <int> > entry in result)
            {
                entry.Value.Value = Math.Min(entry.Value.Value, clip);
            }

            return(result);
        }
예제 #2
0
        private static FrequencySet[] GetFrequencySets(ITopoArray <IDictionary <Tile, PriorityAndWeight> > weights, TileModelMapping tileModelMapping)
        {
            var frequencies = new FrequencySet[tileModelMapping.PatternTopology.IndexCount];

            foreach (var patternIndex in tileModelMapping.PatternTopology.GetIndices())
            {
                // TODO
                if (tileModelMapping.PatternCoordToTileCoordIndexAndOffset != null)
                {
                    throw new NotImplementedException();
                }

                // TODO: Detect duplicate dictionaries by reference and share the frequency sets?

                var tileIndex     = patternIndex;
                var offset        = 0;
                var weightDict    = weights.Get(tileIndex);
                var newWeights    = new double[tileModelMapping.PatternModel.PatternCount];
                var newPriorities = new int[tileModelMapping.PatternModel.PatternCount];
                foreach (var kv in weightDict)
                {
                    var pattern = tileModelMapping.TilesToPatternsByOffset[offset][kv.Key].Single();
                    newWeights[pattern]    = kv.Value.Weight;
                    newPriorities[pattern] = kv.Value.Priority;
                }
                frequencies[patternIndex] = new FrequencySet(newWeights, newPriorities);
            }
            return(frequencies);
        }
예제 #3
0
        /** for all alts, find which ref X or r needs List
         * Must see across alts.  If any alt needs X or r as list, then
         * define as list.
         */
        public virtual ISet <Decl.Decl> GetDeclsForAllElements(IList <AltAST> altASTs)
        {
            ISet <string>      needsList = new HashSet <string>();
            ISet <string>      optional  = new HashSet <string>();
            ISet <string>      suppress  = new HashSet <string>();
            IList <GrammarAST> allRefs   = new List <GrammarAST>();

            foreach (AltAST ast in altASTs)
            {
                IntervalSet        reftypes = new IntervalSet(ANTLRParser.RULE_REF, ANTLRParser.TOKEN_REF);
                IList <GrammarAST> refs     = ast.GetNodesWithType(reftypes);
                foreach (var @ref in refs)
                {
                    allRefs.Add(@ref);
                }

                System.Tuple <FrequencySet <string>, FrequencySet <string> > minAndAltFreq = GetElementFrequenciesForAlt(ast);
                FrequencySet <string> minFreq = minAndAltFreq.Item1;
                FrequencySet <string> altFreq = minAndAltFreq.Item2;
                foreach (GrammarAST t in refs)
                {
                    string refLabelName = GetLabelName(rule.g, t);
                    if (altFreq.GetCount(refLabelName) == 0)
                    {
                        suppress.Add(refLabelName);
                    }
                    if (minFreq.GetCount(refLabelName) == 0)
                    {
                        optional.Add(refLabelName);
                    }
                    if (altFreq.GetCount(refLabelName) > 1)
                    {
                        needsList.Add(refLabelName);
                    }
                }
            }

            ISet <Decl.Decl> decls = new LinkedHashSet <Decl.Decl>();

            foreach (GrammarAST t in allRefs)
            {
                string refLabelName = GetLabelName(rule.g, t);
                if (suppress.Contains(refLabelName))
                {
                    continue;
                }

                IList <Decl.Decl> d = GetDeclForAltElement(t,
                                                           refLabelName,
                                                           needsList.Contains(refLabelName),
                                                           optional.Contains(refLabelName));
                decls.UnionWith(d);
            }

            return(decls);
        }
        /*
         * Common
         */

        /**
         * Generate a frequency set as the union of two input sets. If an
         * element is contained in both sets, the value for the output will be
         * the maximum of the two input values.
         *
         * @param a The first set.
         * @param b The second set.
         * @return The union of the two sets, with the maximum value chosen
         * whenever both sets contain the same key.
         */
        protected static FrequencySet<string> CombineMax(FrequencySet<string> a, FrequencySet<string> b)
        {
            FrequencySet<string> result = CombineAndClip(a, b, 1);
            foreach (KeyValuePair<string, StrongBox<int>> entry in a)
            {
                result[entry.Key].Value = entry.Value.Value;
            }

            foreach (KeyValuePair<string, StrongBox<int>> entry in b)
            {
                StrongBox<int> slot = result[entry.Key];
                slot.Value = Math.Max(slot.Value, entry.Value.Value);
            }

            return result;
        }
        /**
         * Generate a frequency set as the union of two input sets. If an
         * element is contained in both sets, the value for the output will be
         * the minimum of the two input values.
         *
         * @param a The first set.
         * @param b The second set. If this set is {@link #SENTINEL}, it is treated
         * as though no second set were provided.
         * @return The union of the two sets, with the minimum value chosen
         * whenever both sets contain the same key.
         */
        protected static FrequencySet <string> combineMin(FrequencySet <string> a, FrequencySet <string> b)
        {
            if (b == SENTINEL)
            {
                return(a);
            }

            Debug.Assert(a != SENTINEL);
            FrequencySet <string> result = CombineAndClip(a, b, 1);

            foreach (KeyValuePair <string, StrongBox <int> > entry in result)
            {
                entry.Value.Value = Math.Min(a.GetCount(entry.Key), b.GetCount(entry.Key));
            }

            return(result);
        }
        /*
         * Common
         */

        /**
         * Generate a frequency set as the union of two input sets. If an
         * element is contained in both sets, the value for the output will be
         * the maximum of the two input values.
         *
         * @param a The first set.
         * @param b The second set.
         * @return The union of the two sets, with the maximum value chosen
         * whenever both sets contain the same key.
         */
        protected static FrequencySet <string> CombineMax(FrequencySet <string> a, FrequencySet <string> b)
        {
            FrequencySet <string> result = CombineAndClip(a, b, 1);

            foreach (KeyValuePair <string, StrongBox <int> > entry in a)
            {
                result[entry.Key].Value = entry.Value.Value;
            }

            foreach (KeyValuePair <string, StrongBox <int> > entry in b)
            {
                StrongBox <int> slot = result[entry.Key];
                slot.Value = Math.Max(slot.Value, entry.Value.Value);
            }

            return(result);
        }
        /**
         * Generate a frequency set as the union of two input sets. If an
         * element is contained in both sets, the value for the output will be
         * the minimum of the two input values.
         *
         * @param a The first set.
         * @param b The second set. If this set is {@link #SENTINEL}, it is treated
         * as though no second set were provided.
         * @return The union of the two sets, with the minimum value chosen
         * whenever both sets contain the same key.
         */
        protected static FrequencySet<string> combineMin(FrequencySet<string> a, FrequencySet<string> b)
        {
            if (b == SENTINEL)
            {
                return a;
            }

            Debug.Assert(a != SENTINEL);
            FrequencySet<string> result = CombineAndClip(a, b, 1);
            foreach (KeyValuePair<string, StrongBox<int>> entry in result)
            {
                entry.Value.Value = Math.Min(a.GetCount(entry.Key), b.GetCount(entry.Key));
            }

            return result;
        }
        /**
         * Generate a frequency set as the union of two input sets, with the
         * values clipped to a specified maximum value. If an element is
         * contained in both sets, the value for the output, prior to clipping,
         * will be the sum of the two input values.
         *
         * @param a The first set.
         * @param b The second set.
         * @param clip The maximum value to allow for any output.
         * @return The sum of the two sets, with the individual elements clipped
         * to the maximum value given by {@code clip}.
         */
        protected static FrequencySet<string> CombineAndClip(FrequencySet<string> a, FrequencySet<string> b, int clip)
        {
            FrequencySet<string> result = new FrequencySet<string>();
            foreach (KeyValuePair<string, StrongBox<int>> entry in a)
            {
                for (int i = 0; i < entry.Value.Value; i++)
                {
                    result.Add(entry.Key);
                }
            }

            foreach (KeyValuePair<string, StrongBox<int>> entry in b)
            {
                for (int i = 0; i < entry.Value.Value; i++)
                {
                    result.Add(entry.Key);
                }
            }

            foreach (KeyValuePair<string, StrongBox<int>> entry in result)
            {
                entry.Value.Value = Math.Min(entry.Value.Value, clip);
            }

            return result;
        }