示例#1
0
        public static void CalculateMinimumExpressionLengths(ISymbolicExpressionGrammarBase grammar,
                                                             Dictionary <string, int> minimumExpressionLengths)
        {
            minimumExpressionLengths.Clear();
            //terminal symbols => minimum expression length = 1
            foreach (var s in grammar.Symbols)
            {
                if (grammar.GetMinimumSubtreeCount(s) == 0)
                {
                    minimumExpressionLengths[s.Name] = 1;
                }
                else
                {
                    minimumExpressionLengths[s.Name] = int.MaxValue;
                }
            }

            foreach (var topSymbol in grammar.GetTopmostSymbols())
            {
                // get all symbols below in reverse breadth order
                // this way we ensure lengths are calculated bottom-up
                var symbols = grammar.IterateBreadthReverse(topSymbol);
                foreach (var symbol in symbols)
                {
                    long minLength = 1;
                    for (int argIndex = 0; argIndex < grammar.GetMinimumSubtreeCount(symbol); ++argIndex)
                    {
                        long length = grammar.GetAllowedActiveSymbols(symbol, argIndex)
                                      .Where(x => minimumExpressionLengths.ContainsKey(x.Name))
                                      .Select(x => minimumExpressionLengths[x.Name]).DefaultIfEmpty(int.MaxValue).Min();
                        minLength += length;
                    }
                    int oldLength;
                    if (minimumExpressionLengths.TryGetValue(symbol.Name, out oldLength))
                    {
                        minLength = Math.Min(minLength, oldLength);
                    }
                    minimumExpressionLengths[symbol.Name] = (int)Math.Min(int.MaxValue, minLength);
                }
                // correction step for cycles
                bool changed = true;
                while (changed)
                {
                    changed = false;
                    foreach (var symbol in symbols)
                    {
                        long minLength = Enumerable.Range(0, grammar.GetMinimumSubtreeCount(symbol))
                                         .Sum(x => grammar.GetAllowedActiveSymbols(symbol, x)
                                              .Select(s => (long)minimumExpressionLengths[s.Name]).DefaultIfEmpty(int.MaxValue).Min()) + 1;
                        if (minLength < minimumExpressionLengths[symbol.Name])
                        {
                            minimumExpressionLengths[symbol.Name] = (int)Math.Min(minLength, int.MaxValue);
                            changed = true;
                        }
                    }
                }
            }
        }
示例#2
0
        private static IEnumerable <ISymbol> GetTopmostSymbols(this ISymbolicExpressionGrammarBase grammar)
        {
            // build parents list so we can find out the topmost symbol(s)
            var parents = new Dictionary <ISymbol, List <ISymbol> >();

            foreach (var symbol in grammar.Symbols.Where(x => grammar.GetMinimumSubtreeCount(x) > 0))
            {
                var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol);
                for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex)
                {
                    foreach (var childSymbol in grammar.GetAllowedActiveSymbols(symbol, argIndex))
                    {
                        if (!parents.ContainsKey(childSymbol))
                        {
                            parents[childSymbol] = new List <ISymbol>();
                        }
                        parents[childSymbol].Add(symbol);
                    }
                }
            }
            // the topmost symbols have no parents
            return(parents.Values.SelectMany(x => x).Distinct().Where(x => !parents.ContainsKey(x)));
        }
示例#3
0
        private static IReadOnlyCollection <ISymbol> IterateBreadthReverse(this ISymbolicExpressionGrammarBase grammar, ISymbol topSymbol)
        {
            // sort symbols in reverse breadth order (starting from the topSymbol)
            // each symbol is visited only once (this avoids infinite recursion)
            var symbols = new List <ISymbol> {
                topSymbol
            };
            var visited = new HashSet <ISymbol> {
                topSymbol
            };
            int i = 0;

            while (i < symbols.Count)
            {
                var symbol          = symbols[i];
                var minSubtreeCount = grammar.GetMinimumSubtreeCount(symbol);

                for (int argIndex = 0; argIndex < minSubtreeCount; ++argIndex)
                {
                    foreach (var childSymbol in grammar.GetAllowedActiveSymbols(symbol, argIndex))
                    {
                        if (grammar.GetMinimumSubtreeCount(childSymbol) == 0)
                        {
                            continue;
                        }

                        if (visited.Add(childSymbol))
                        {
                            symbols.Add(childSymbol);
                        }
                    }
                }
                ++i;
            }
            symbols.Reverse();
            return(symbols);
        }