コード例 #1
0
        //generate a new rule from random existing productions.
        public bool InsertRule(Grammar grammar)
        {
            for (var i = 0; i < NumberOfRetries; i++)
            {
                var productions = new List<string>();
                var randomDaughter = grammar.StartSymbol;
                while (randomDaughter == grammar.StartSymbol)
                    randomDaughter = grammar.GetRandomNonTerminal(); //the first daughter is never the start symbol.

                productions.Add(randomDaughter);

                if (_rand.NextDouble() < 0.5f)
                    productions.Add(grammar.GetRandomNonTerminal());

                var newRule = new Rule();
                newRule.Occurrences = 1;
                newRule.Production = productions.Select(x => new NonTerminalObject(x)).ToArray();

                newRule.HeadPosition = _rand.Next(newRule.Production.Length);
                newRule.ComplementPosition = _rand.Next(newRule.Production.Length);

                if (newRule.HeadTerm == grammar.StartSymbol)
                    //never let the head be the start symbol. the start symbol can only be the second term(see above).
                    newRule.HeadPosition = 0;


                var ruleName = grammar.StartSymbol;
                if (_rand.NextDouble() < 0.9f)
                    //90% probability of projecting regular head stucture. 10% allow to project to the START symbol.
                {
                    try
                    {
                        ruleName = grammar.NonTerminalsTypeDictionary[newRule.HeadTerm] + "P";
                    }
                    catch
                    {
                        throw new Exception(string.Format("rule head term not found", newRule.HeadTerm));
                    }
                }
                newRule.Name = new NonTerminalObject(ruleName);

                if (grammar.AreHeadRelationsConsistent(newRule))
                {
                    grammar.AddRule(newRule);
                    return true;
                }
            }
            return false;
        }