private static void InitIds(ContextFreeGrammar cfg)
        {
            int i = 1;

            foreach (var v in cfg.Variables.Concat(cfg.GetNonVariableSymbols()).ToList())
            {
                v.UnqiueId = i++;
            }
        }
        private static ContextFreeGrammar RemoveNonGeneratingSymbols(ContextFreeGrammar cfg, CancellationToken token)
        {
            InitIds(cfg);

            var res = new HashSet <int>(cfg.GetNonVariableSymbols().Select(v => v.UnqiueId));

            var remainingProductions = new Dictionary <int, List <Production> >();

            foreach (var s in cfg.Variables)
            {
                remainingProductions[s.UnqiueId] = new List <Production>();
            }
            foreach (var prod in cfg.GetProductions())
            {
                remainingProductions[prod.Lhs.UnqiueId].Add(prod);
            }

            int oldLength;

            do
            {
                token.ThrowIfCancellationRequested();

                oldLength = res.Count;

                var newSymbols = new HashSet <int>();

                foreach (var e in remainingProductions)
                {
                    token.ThrowIfCancellationRequested();

                    if (e.Value.Any(p => p.Rhs.All(s => res.Contains(s.UnqiueId))))
                    {
                        res.Add(e.Key);
                        newSymbols.Add(e.Key);
                    }
                }

                foreach (var s in newSymbols)
                {
                    token.ThrowIfCancellationRequested();

                    remainingProductions.Remove(s);
                }
            }while (res.Count > oldLength);

            if (!res.Contains(cfg.StartSymbol.UnqiueId))
            {
                return(null);
            }
            else
            {
                var prods = FilterProductions(res, cfg.GetProductions());
                return(new ContextFreeGrammar(cfg.StartSymbol, prods));
            }
        }
        public WordsInGrammarProblem(ContextFreeGrammar grammar, int inNeeded, int outNeeded)
        {
            this.grammar   = grammar;
            this.inNeeded  = inNeeded;
            this.outNeeded = outNeeded;

            numberOfShortWords = GrammarUtilities.generateShortestWords(grammar, shortLength).Count;
            //calculate all possible short words (needed for qual and dif)
            possibleShortWords = 0;
            int termCount = grammar.GetNonVariableSymbols().Count();
            int x         = 1;

            for (int i = 0; i <= shortLength; i++)
            {
                possibleShortWords += x;
                x *= termCount;
            }
        }
        public override double Quality()
        {
            if (word.Length <= 0)
            {
                return(0);
            }

            double res           = 1.0;
            double fillingDegree = getFillingDegree();

            //too full
            if (fillingDegree > 2.7)
            {
                res *= 0.3;
            }
            else if (fillingDegree > 2.3)
            {
                res *= 0.7;
            }
            //too empty
            if (fillingDegree < 0.2)
            {
                res *= 0.3;
            }
            else if (fillingDegree < 0.8)
            {
                res *= 0.7;
            }

            //too short
            if (word.Length <= 1)
            {
                res *= 0.4;
            }

            //nothing on top
            if (cykTable[cykTable.Length - 1][0].Item1.Count == 0)
            {
                res *= 0.6;
            }

            //uses useless terminals
            List <char> allowedTerminals = new List <char>();

            foreach (GrammarSymbol s in grammar.GetNonVariableSymbols())
            {
                if (s.ToString().Length >= 1)
                {
                    allowedTerminals.Add(s.ToString()[0]);
                }
            }
            foreach (char c in word)
            {
                if (!allowedTerminals.Contains(c))
                {
                    res *= 0.6;
                }
            }

            //repetetive
            res *= getRepetetiveness();

            return(res);
        }
Ejemplo n.º 5
0
        public FindDerivationProblem Generate(int targetLevel)
        {
            ContextFreeGrammar grammar = GrammarGenerator.GenerateRandom();
            var productions            = grammar.GetProductions();
            var toAdd = new List <Production>();

            //make sure every varaible has a resolution (production with #NT = 0) and an continuation (production with #NT > 0)
            foreach (Nonterminal nt in grammar.Variables)
            {
                var nt_prods = grammar.GetProductions(nt);
                //resolution check
                var p = nt_prods.ToList().Find(pp => pp.ContainsNoVariables);
                if (p == null)
                {
                    GrammarSymbol t = Choose(grammar.GetNonVariableSymbols());
                    if (t == null)
                    {
                        t = new Exprinal <char>('x', "x");
                    }
                    p = new Production(nt, new GrammarSymbol[] { t });
                    toAdd.Add(p);
                }
                //continuation check
                p = nt_prods.ToList().Find(pp => Derivation.countNT(pp.Rhs) >= 1);
                if (p == null)
                {
                    //resolution check
                    GrammarSymbol t = Choose(grammar.Variables);
                    p = new Production(nt, new GrammarSymbol[] { Choose(grammar.Variables), Choose(grammar.Variables) });
                    toAdd.Add(p);
                }
            }
            //add new productions (for resolution and continuation)
            if (toAdd.Count != 0)
            {
                grammar = new ContextFreeGrammar(grammar.StartSymbol, grammar.GetProductions().Concat(toAdd));
            }
            productions = grammar.GetProductions();

            //type
            bool shouldBeAny = true;

            if (targetLevel == Generation.ANY)
            {
                shouldBeAny = (rnd.Next(0, 9) < 3);                               // 30%
            }
            if (targetLevel == Generation.MEDIUM)
            {
                shouldBeAny = (rnd.Next(0, 9) < 2);                                   // 20%
            }
            if (targetLevel == Generation.HIGH)
            {
                shouldBeAny = (rnd.Next(0, 9) < 9);                                 // 90%
            }
            int type = Derivation.DERIVATION_ALL;

            if (!shouldBeAny)
            {
                type = Derivation.DERIVATION_LEFTMOST;
                if (rnd.Next(0, 9) < 3)
                {
                    type = Derivation.DERIVATION_RIGHTMOST;
                }
            }

            //nr of steps
            int steps = rnd.Next(5, 10);

            if (targetLevel == Generation.LOW)
            {
                steps = rnd.Next(3, 6);
            }
            if (targetLevel == Generation.MEDIUM)
            {
                steps = rnd.Next(7, 9);
            }
            if (targetLevel == Generation.HIGH)
            {
                steps = rnd.Next(10, 12);
            }

            List <GrammarSymbol[]> derivation = new List <GrammarSymbol[]>(steps + 1);
            var cur = new GrammarSymbol[] { grammar.StartSymbol };

            derivation.Add(cur);
            for (int i = 0; i < steps; i++)
            {
                //get possible next steps
                IEnumerable <GrammarSymbol[]> next = Derivation.findAllDerivations(grammar.GetProductions(), cur, type);

                if (Derivation.countNT(cur) <= 1 && i != steps - 1) //don't end yet!
                {
                    next = next.Where(pw => Derivation.countNT(pw) >= 1);
                }

                //try not to repeat
                var next_part = next.Except(derivation);
                if (next_part.Count() > 0)
                {
                    next = next_part;
                }

                cur = Choose(next);
                //cut out repeat
                if (derivation.Contains(cur))
                {
                    int r_i = derivation.IndexOf(cur);
                    derivation = derivation.GetRange(0, r_i);
                }

                //add next step
                derivation.Add(cur);
            }
            //replace all NTs
            while (Derivation.countNT(cur) > 0)
            {
                //get possible next steps
                IEnumerable <GrammarSymbol[]> next = Derivation.findAllDerivations(grammar.GetProductions(), cur, type);

                //filter
                int curNTs = Derivation.countNT(cur);
                next = next.Where(pw => Derivation.countNT(pw) < curNTs);

                cur = Choose(next);
                derivation.Add(cur);
            }

            String word = Derivation.partialWordToString(cur);

            return(new FindDerivationProblem(grammar, word, type, derivation));
        }