//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; }
public bool ChangeHeadOfRule(Grammar grammar) { for (var i = 0; i < NumberOfRetries; i++) { var rule = grammar.GetRandomRule(); if (!rule.IsInitialRule()) continue; //do not change complements of schematic rules. (push/pop) if (rule.Production.Length > 1) { var newRule = new Rule(rule); newRule.HeadPosition = (rule.HeadPosition + 1)%rule.Production.Length; if (grammar.AreHeadRelationsConsistent(newRule)) { grammar.DeleteRule(rule); grammar.AddRule(newRule); return true; } } } return false; }