Changeset 10086
- Timestamp:
- 10/27/13 20:17:17 (11 years ago)
- Location:
- branches/HeuristicLab.Problems.GPDL
- Files:
-
- 1 added
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.GPDL/CodeGenerator/BruteForceCodeGen.cs
r10080 r10086 81 81 nextAlternative = (nextAlternative + 1) % subTrees.Length; 82 82 } while (subTrees[nextAlternative] != null && subTrees[nextAlternative].Done); 83 84 // from the nodes which are not done take the first with minimum count85 //nextAlternative = (from i in Enumerable.Range(0, subTrees.Length)86 // where subTrees[i] == null || !subTrees[i].Done87 // orderby subTrees[i]==null?0:subTrees[i].Count ascending88 // select i).FirstOrDefault(); // possibly there are no children left that can be tried89 83 } else { 90 84 // for sequenceNodes update all sub-trees … … 177 171 178 172 private AttributedGrammar CreateGrammarFromAst(GPDefNode ast) { 173 174 var nonTerminals = ast.NonTerminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray(); 175 var terminals = ast.Terminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray(); 179 176 string startSymbolName = ast.Rules.First().NtSymbol; 180 var startSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == startSymbolName); 177 181 178 // create startSymbol 182 var g = new AttributedGrammar(new Symbol(startSymbolName, ParseSymbolAttributes(startSymbolNode.FormalParameters))); 179 var startSymbol = nonTerminals.Single(s => s.Name == startSymbolName); 180 var g = new AttributedGrammar(startSymbol, nonTerminals, terminals); 181 182 // add all production rules 183 183 foreach (var rule in ast.Rules) { 184 // create nt-symbol 185 var ntSymbolName = rule.NtSymbol; 186 var ntSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == ntSymbolName); 187 var attributes = ParseSymbolAttributes(ntSymbolNode.FormalParameters); 188 var ntSymbol = new Symbol(ntSymbolName, attributes); 189 foreach (var alt in GetAlternatives(rule.Alternatives)) { 184 var ntSymbol = nonTerminals.Single(s => s.Name == rule.NtSymbol); 185 foreach (var alt in GetAlternatives(rule.Alternatives, nonTerminals.Concat(terminals))) { 190 186 g.AddProductionRule(ntSymbol, alt); 191 187 } … … 196 192 } 197 193 198 private IEnumerable<IAttribute> ParseSymbolAttributes(string formalParameters) {194 private IEnumerable<IAttribute> GetSymbolAttributes(string formalParameters) { 199 195 return (from fieldDef in Util.ExtractParameters(formalParameters) 200 196 select new Attribute(fieldDef.Identifier, fieldDef.Type, AttributeType.Parse(fieldDef.RefOrOut))). … … 202 198 } 203 199 204 private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode ) {200 private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode, IEnumerable<ISymbol> allSymbols) { 205 201 foreach (var alt in altNode.Alternatives) { 206 yield return GetSequence(alt.Sequence );207 } 208 } 209 210 private Sequence GetSequence(IEnumerable<RuleExprNode> sequence ) {202 yield return GetSequence(alt.Sequence, allSymbols); 203 } 204 } 205 206 private Sequence GetSequence(IEnumerable<RuleExprNode> sequence, IEnumerable<ISymbol> allSymbols) { 211 207 Debug.Assert(sequence.All(s => s is CallSymbolNode || s is RuleActionNode)); 212 208 var l = new List<ISymbol>(); … … 215 211 var actionNode = node as RuleActionNode; 216 212 if (callSymbolNode != null) { 217 l.Add(new Symbol(callSymbolNode.Ident, ParseSymbolAttributes(callSymbolNode.ActualParameter))); 213 Debug.Assert(allSymbols.Any(s => s.Name == callSymbolNode.Ident)); 214 // create a new symbol with actual parameters 215 l.Add(new Symbol(callSymbolNode.Ident, GetSymbolAttributes(callSymbolNode.ActualParameter))); 218 216 } else if (actionNode != null) { 219 217 l.Add(new SemanticSymbol("SEM", actionNode.SrcCode)); … … 313 311 314 312 // make sure we first descent into terminal alternatives -> we just order by number of non-terminals in the alternative 315 var altsWithSemActions = g.GetAlternativesWithSemanticActions(s).OrderBy(alt => alt.Count(symb => g.IsNonTerminal(symb))).ToArray(); 313 var altsWithSemActions = g.GetAlternativesWithSemanticActions(s) 314 .OrderBy(alt => alt.Count(symb => g.IsNonTerminal(symb))).ToArray(); 316 315 317 316 if (altsWithSemActions.Length > 1) { -
branches/HeuristicLab.Problems.GPDL/CodeGenerator/RandomSearchCodeGen.cs
r10080 r10086 20 20 namespace ?PROBLEMNAME? { 21 21 public sealed class ?IDENT?Solver { 22 public sealed class SolverState { 23 private int currentSeed; 24 public Random random; 25 public int depth; 26 public int steps; 27 public int maxDepth; 28 public SolverState(int seed) { 29 this.currentSeed = seed; 30 } 31 32 public SolverState IncDepth() { 33 depth++; 34 if(depth>maxDepth) maxDepth = depth; 35 return this; 36 } 37 public SolverState Prepare() { 38 this.random = new Random(currentSeed); 39 depth = 0; 40 maxDepth = 0; 41 steps = 0; 42 return this; 43 } 44 } 22 45 23 46 public static void Main(string[] args) { … … 38 61 } 39 62 40 41 private Random seedRandom; 42 private int currentSeed; 63 private double TerminalProbForDepth(int depth) { 64 const double baseProb = 0.05; // 5% of all samples are only a terminal node 65 const double probIncPerLevel = 0.05; // for each level the probability to sample a terminal grows by 5% 66 return baseProb + depth * probIncPerLevel; 67 } 68 69 private SolverState _state; 43 70 private void Start() { 44 seedRandom = new Random();71 var seedRandom = new Random(); 45 72 var bestF = ?MAXIMIZATION? ? double.NegativeInfinity : double.PositiveInfinity; 46 73 int n = 0; … … 51 78 // must make sure that calling the start-symbol multiple times in the fitness function always leads to the same path through the grammar 52 79 // so we use a PRNG for generating seeds for a separate PRNG that is reset each time the start symbol is called 53 currentSeed = seedRandom.Next(); 80 81 _state = new SolverState(seedRandom.Next()); 82 54 83 var f = Calculate(); 55 84 56 85 n++; 57 if (IsBetter(f, bestF)) bestF = f; 58 if (n % 100 == 0) { 86 if (IsBetter(f, bestF)) { 87 bestF = f; 88 Console.WriteLine(""{0}\t{1}\t(depth={2})"", n, bestF, _state.maxDepth); 89 } 90 if (n % 1000 == 0) { 59 91 sw.Stop(); 60 Console.WriteLine(""{0}\t{1}\t{2}\t({3:0.00} sols/ms)"", n, bestF, f, 100 .0 / sw.ElapsedMilliseconds);92 Console.WriteLine(""{0}\t{1}\t{2}\t({3:0.00} sols/ms)"", n, bestF, f, 1000.0 / sw.ElapsedMilliseconds); 61 93 sw.Reset(); 62 94 sw.Start(); … … 112 144 } 113 145 146 #region create grammar instance from AST 114 147 private AttributedGrammar CreateGrammarFromAst(GPDefNode ast) { 148 149 var nonTerminals = ast.NonTerminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray(); 150 var terminals = ast.Terminals.Select(t => new Symbol(t.Ident, GetSymbolAttributes(t.FormalParameters))).ToArray(); 115 151 string startSymbolName = ast.Rules.First().NtSymbol; 116 var startSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == startSymbolName); 152 117 153 // create startSymbol 118 var g = new AttributedGrammar(new Symbol(startSymbolName, ParseSymbolAttributes(startSymbolNode.FormalParameters))); 154 var startSymbol = nonTerminals.Single(s => s.Name == startSymbolName); 155 var g = new AttributedGrammar(startSymbol, nonTerminals, terminals); 156 157 // add all production rules 119 158 foreach (var rule in ast.Rules) { 120 // create nt-symbol 121 var ntSymbolName = rule.NtSymbol; 122 var ntSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == ntSymbolName); 123 var attributes = ParseSymbolAttributes(ntSymbolNode.FormalParameters); 124 var ntSymbol = new Symbol(ntSymbolName, attributes); 125 foreach (var alt in GetAlternatives(rule.Alternatives)) { 159 var ntSymbol = nonTerminals.Single(s => s.Name == rule.NtSymbol); 160 foreach (var alt in GetAlternatives(rule.Alternatives, nonTerminals.Concat(terminals))) { 126 161 g.AddProductionRule(ntSymbol, alt); 127 162 } … … 132 167 } 133 168 134 private IEnumerable<IAttribute> ParseSymbolAttributes(string formalParameters) {169 private IEnumerable<IAttribute> GetSymbolAttributes(string formalParameters) { 135 170 return (from fieldDef in Util.ExtractParameters(formalParameters) 136 171 select new Attribute(fieldDef.Identifier, fieldDef.Type, AttributeType.Parse(fieldDef.RefOrOut))). … … 138 173 } 139 174 140 private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode ) {175 private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode, IEnumerable<ISymbol> allSymbols) { 141 176 foreach (var alt in altNode.Alternatives) { 142 yield return GetSequence(alt.Sequence );143 } 144 } 145 146 private Sequence GetSequence(IEnumerable<RuleExprNode> sequence ) {177 yield return GetSequence(alt.Sequence, allSymbols); 178 } 179 } 180 181 private Sequence GetSequence(IEnumerable<RuleExprNode> sequence, IEnumerable<ISymbol> allSymbols) { 147 182 Debug.Assert(sequence.All(s => s is CallSymbolNode || s is RuleActionNode)); 148 183 var l = new List<ISymbol>(); … … 151 186 var actionNode = node as RuleActionNode; 152 187 if (callSymbolNode != null) { 153 l.Add(new Symbol(callSymbolNode.Ident, ParseSymbolAttributes(callSymbolNode.ActualParameter))); 188 Debug.Assert(allSymbols.Any(s => s.Name == callSymbolNode.Ident)); 189 // create a new symbol with actual parameters 190 l.Add(new Symbol(callSymbolNode.Ident, GetSymbolAttributes(callSymbolNode.ActualParameter))); 154 191 } else if (actionNode != null) { 155 192 l.Add(new SemanticSymbol("SEM", actionNode.SrcCode)); … … 158 195 return new Sequence(l); 159 196 } 160 197 #endregion 198 199 #region helper methods for terminal symbols 161 200 // produces helper methods for the attributes of all terminal nodes 162 201 private string GenerateConstraintMethods(List<SymbolNode> symbols) { … … 177 216 sb.AppendFormat("public {0} GetMax{1}_{2}() {{ return {3}; }}", fieldType, t.Ident, c.Ident, c.RangeMaxExpression).AppendLine(); 178 217 sb.AppendFormat("public {0} GetMin{1}_{2}() {{ return {3}; }}", fieldType, t.Ident, c.Ident, c.RangeMinExpression).AppendLine(); 218 sb.AppendFormat("public {0} GetRandom{1}_{2}(SolverState _state) {{ return _state.random.NextDouble() * (GetMax{1}_{2}() - GetMin{1}_{2}()) + GetMin{1}_{2}(); }}", fieldType, t.Ident, c.Ident).AppendLine(); 179 219 } else if (c.Type == ConstraintNodeType.Set) { 180 sb.AppendFormat("public IEnumerable<{0}> GetAllowed{1}_{2}() {{ return {3} }}", fieldType, t.Ident, c.Ident, c.SetExpression).AppendLine(); 181 } 182 } 183 return sb.ToString(); 184 } 220 sb.AppendFormat("public IEnumerable<{0}> GetAllowed{1}_{2}() {{ return {3}; }}", fieldType, t.Ident, c.Ident, c.SetExpression).AppendLine(); 221 sb.AppendFormat("public {0} GetRandom{1}_{2}(SolverState _state) {{ var tmp = GetAllowed{1}_{2}().ToArray(); return tmp[_state.random.Next(tmp.Length)]; }}", fieldType, t.Ident, c.Ident).AppendLine(); 222 } 223 } 224 return sb.ToString(); 225 } 226 #endregion 185 227 186 228 private string GenerateInterpreterSource(AttributedGrammar grammar) { … … 197 239 } 198 240 199 private string GenerateTerminalInterpreterMethod(ISymbol s) {200 var sb = new StringBuilder();201 // if the terminal symbol has attributes then we must create values for these attributes202 if (!s.Attributes.Any())203 sb.AppendFormat("private void {0}(Random random) {{", s.Name);204 else205 sb.AppendFormat("private void {0}(Random random, {1}) {{", s.Name, s.GetAttributeString());206 207 // each field must match a formal parameter, assign a value for each parameter208 foreach (var element in s.Attributes) {209 // only works for "IN SET"-Constraints210 sb.AppendFormat("{{ var tmp = GetAllowed{1}_{0}().ToArray(); {0} = tmp[random.Next(tmp.Length)]; }} ", element.Name, s.Name);211 }212 sb.AppendLine("}");213 return sb.ToString();214 }215 216 241 private string GenerateInterpreterMethod(AttributedGrammar g, ISymbol s) { 217 242 var sb = new StringBuilder(); 243 218 244 // if this is the start symbol we additionally have to create the method which can be called from the fitness function 219 220 245 if (g.StartSymbol.Equals(s)) { 221 246 if (!s.Attributes.Any()) … … 234 259 actualParameter = string.Empty; 235 260 236 sb.AppendFormat("{0}( new Random(currentSeed), {1});", g.StartSymbol.Name, actualParameter).AppendLine();261 sb.AppendFormat("{0}(_state.Prepare(), {1});", g.StartSymbol.Name, actualParameter).AppendLine(); 237 262 sb.AppendLine("}"); 238 263 } 239 264 240 265 if (!s.Attributes.Any()) 241 sb.AppendFormat("private void {0}( Random random) {{", s.Name);266 sb.AppendFormat("private void {0}(SolverState _state) {{", s.Name); 242 267 else 243 sb.AppendFormat("private void {0}( Random random, {1}) {{", s.Name, s.GetAttributeString());268 sb.AppendFormat("private void {0}(SolverState _state, {1}) {{", s.Name, s.GetAttributeString()); 244 269 245 270 // generate local definitions … … 250 275 var terminalAlts = altsWithSemActions.Where(alt => alt.Count(g.IsNonTerminal) == 0); 251 276 var nonTerminalAlts = altsWithSemActions.Where(alt => alt.Count(g.IsNonTerminal) > 0); 252 bool hasTerminalAlts = terminalAlts. Count() > 0;253 bool hasNonTerminalAlts = nonTerminalAlts. Count() > 0;277 bool hasTerminalAlts = terminalAlts.Any(); 278 bool hasNonTerminalAlts = nonTerminalAlts.Any(); 254 279 255 280 if (altsWithSemActions.Length > 1) { … … 261 286 // the probability of choosing terminals should depend on the depth of the tree (small likelihood to choose terminals for small depths, large likelihood for large depths) 262 287 if (hasTerminalAlts && hasNonTerminalAlts) { 263 sb.AppendLine("if( random.NextDouble() < 0.5) {");288 sb.AppendLine("if(_state.random.NextDouble() < TerminalProbForDepth(_state.depth)) {"); 264 289 // terminals 265 290 sb.AppendLine("// terminals "); … … 287 312 288 313 private void GenerateSwitchStatement(StringBuilder sb, IEnumerable<Sequence> alts) { 289 sb.AppendFormat("switch( random.Next({0})) {{", alts.Count());314 sb.AppendFormat("switch(_state.random.Next({0})) {{", alts.Count()); 290 315 // generate a case for each alternative 291 316 int i = 0; … … 313 338 } else { 314 339 if (!s.Attributes.Any()) 315 return string.Format("{0}( random);", s.Name);340 return string.Format("{0}(_state.IncDepth()); _state.depth--;", s.Name); 316 341 else 317 return string.Format("{0}(random, {1});", s.Name, s.GetAttributeString()); 318 } 342 return string.Format("{0}(_state.IncDepth(), {1}); _state.depth--;", s.Name, s.GetAttributeString()); 343 } 344 } 345 346 private string GenerateTerminalInterpreterMethod(ISymbol s) { 347 var sb = new StringBuilder(); 348 // if the terminal symbol has attributes then we must samples values for these attributes 349 if (!s.Attributes.Any()) 350 sb.AppendFormat("private void {0}(SolverState _state) {{", s.Name); 351 else 352 sb.AppendFormat("private void {0}(SolverState _state, {1}) {{", s.Name, s.GetAttributeString()); 353 354 // each field must match a formal parameter, assign a value for each parameter 355 foreach (var element in s.Attributes) { 356 sb.AppendFormat("{{ {0} = GetRandom{1}_{0}(_state); }} ", element.Name, s.Name); 357 } 358 sb.AppendLine("}"); 359 return sb.ToString(); 319 360 } 320 361 } -
branches/HeuristicLab.Problems.GPDL/Examples/symbreg HEAL.txt
r10061 r10086 5 5 double[] y; 6 6 string[] variableNames; 7 int[] rows; 7 8 Dictionary<string,int> nameToCol; 8 9 … … 19 20 20 21 double RSquared(IEnumerable<double> xs, IEnumerable<double> ys) { 21 HeuristicLab.Problems.DataAnalysis.OnlineCalculatorError error; 22 var r2 = HeuristicLab.Problems.DataAnalysis.OnlinePearsonsRSquaredCalculator.Calculate(xs, ys, out error); 23 if(error == HeuristicLab.Problems.DataAnalysis.OnlineCalculatorError.None) return r2; 24 else return 0.0; 25 } 22 // calculate Pearson's correlation in one pass over xs and ys 23 double sumx = 0.0; 24 double sumy = 0.0; 25 double sumxSq = 0.0; 26 double sumySq = 0.0; 27 double sumxy = 0.0; 28 int n = 0; 29 var xEnum = xs.GetEnumerator(); 30 var yEnum = ys.GetEnumerator(); 31 while(xEnum.MoveNext() & yEnum.MoveNext()) { 32 sumx += xEnum.Current; 33 sumy += yEnum.Current; 34 sumxSq += xEnum.Current * xEnum.Current; 35 sumySq += yEnum.Current * yEnum.Current; 36 sumxy += xEnum.Current * yEnum.Current; 37 n++; 38 } 39 System.Diagnostics.Debug.Assert(!(xEnum.MoveNext() | yEnum.MoveNext())); 40 41 double num; 42 double den; 43 double r = 0.0; 44 num = sumxy - ( ( sumx * sumy ) / n ); 45 den = Math.Sqrt( ( sumxSq - ( sumx*sumx ) / n ) * 46 ( sumySq - ( sumy*sumy ) / n ) ); 47 if(den > 0){ 48 r = num / den; 49 } 50 return r*r; 51 } 26 52 >> 27 53 … … 33 59 x = new double[n, 10]; 34 60 y = new double[n]; 35 for(int row = 0; row < 500; row++) {61 for(int row = 0; row < n; row++) { 36 62 for(int col = 0; col < 10; col++) { 37 63 x[row, col] = rand.NextDouble() * 2.0 - 1.0; … … 43 69 x[row, 2] * x[row, 5] + x[row, 9]; 44 70 } 71 72 rows = System.Linq.Enumerable.Range(0, n).ToArray(); 45 73 >> 46 74 … … 90 118 . 91 119 92 MAXIMIZE /* could also use the keyword MINIMIZE here */120 MAXIMIZE 93 121 << 94 var rows = System.Linq.Enumerable.Range(0, x.GetLength(0));95 122 var predicted = rows.Select(r => { 96 123 double result; -
branches/HeuristicLab.Problems.GPDL/Examples/symbreg Koza.txt
r10061 r10086 3 3 double[,] x; 4 4 double[] y; 5 int[] rows; 5 6 string[] variableNames; 7 double[] randomConsts; 8 6 9 Dictionary<string,int> nameToCol; 7 10 … … 18 21 19 22 double RSquared(IEnumerable<double> xs, IEnumerable<double> ys) { 20 HeuristicLab.Problems.DataAnalysis.OnlineCalculatorError error; 21 var r2 = HeuristicLab.Problems.DataAnalysis.OnlinePearsonsRSquaredCalculator.Calculate(xs, ys, out error); 22 if(error == HeuristicLab.Problems.DataAnalysis.OnlineCalculatorError.None) return r2; 23 else return 0.0; 24 } 23 // calculate Pearson's correlation in one pass over xs and ys 24 double sumx = 0.0; 25 double sumy = 0.0; 26 double sumxSq = 0.0; 27 double sumySq = 0.0; 28 double sumxy = 0.0; 29 int n = 0; 30 var xEnum = xs.GetEnumerator(); 31 var yEnum = ys.GetEnumerator(); 32 while(xEnum.MoveNext() & yEnum.MoveNext()) { 33 sumx += xEnum.Current; 34 sumy += yEnum.Current; 35 sumxSq += xEnum.Current * xEnum.Current; 36 sumySq += yEnum.Current * yEnum.Current; 37 sumxy += xEnum.Current * yEnum.Current; 38 n++; 39 } 40 System.Diagnostics.Debug.Assert(!(xEnum.MoveNext() | yEnum.MoveNext())); 41 42 double num; 43 double den; 44 double r = 0.0; 45 num = sumxy - ( ( sumx * sumy ) / n ); 46 den = Math.Sqrt( ( sumxSq - ( sumx*sumx ) / n ) * 47 ( sumySq - ( sumy*sumy ) / n ) ); 48 if(den > 0){ 49 r = num / den; 50 } 51 return r*r; 52 } 25 53 >> 26 54 … … 32 60 x = new double[n, 10]; 33 61 y = new double[n]; 34 for(int row = 0; row < 500; row++) {62 for(int row = 0; row < n; row++) { 35 63 for(int col = 0; col < 10; col++) { 36 64 x[row, col] = rand.NextDouble() * 2.0 - 1.0; … … 42 70 x[row, 2] * x[row, 5] + x[row, 9]; 43 71 } 72 73 rows = System.Linq.Enumerable.Range(0, n).ToArray(); 74 75 // generate 100 random constants in [-100.0 .. 100.0[ 76 randomConsts = Enumerable.Range(0, 100).Select(i => rand.NextDouble()*200.0 - 100.0).ToArray(); 44 77 >> 45 78 … … 55 88 ERC<<out double val>> 56 89 CONSTRAINTS 57 val IN RANGE <<-100>> .. <<100>>90 val IN SET << randomConsts >> 58 91 . 59 92 60 93 Var<<out string varName>> 61 94 CONSTRAINTS 62 varName IN SET <<variableNames>>95 varName IN SET << variableNames >> 63 96 . 64 97 … … 73 106 | Multiplication<<row, out val>> 74 107 | Var<<out varName>> SEM << val = GetValue(x, varName, row); >> 75 | ERC<<out val>>108 /* | ERC<<out val>> */ 76 109 . 77 110 … … 89 122 . 90 123 91 MAXIMIZE /* could also use the keyword MINIMIZE here */124 MAXIMIZE 92 125 << 93 var rows = System.Linq.Enumerable.Range(0, x.GetLength(0));94 126 var predicted = rows.Select(r => { 95 127 double result; -
branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/AttributedGrammar.cs
r10067 r10086 27 27 namespace HeuristicLab.Grammars { 28 28 public class AttributedGrammar : Grammar { 29 private Dictionary<ISymbol, string> localDefinitions = new Dictionary<ISymbol, string>();30 private Dictionary<ISymbol, IList<Sequence>> alternatives = new Dictionary<ISymbol, IList<Sequence>>();29 private readonly Dictionary<ISymbol, string> localDefinitions; 30 private readonly Dictionary<ISymbol, List<Sequence>> alternatives; 31 31 32 public AttributedGrammar(ISymbol startSymbol) 33 : base(startSymbol) { 34 Debug.Assert(!startSymbol.Equals(EmptySymbol)); 32 public AttributedGrammar(ISymbol startSymbol, IEnumerable<ISymbol> nonTerminals, IEnumerable<ISymbol> terminals) 33 : base(startSymbol, nonTerminals, terminals) { 35 34 this.StartSymbol = startSymbol; 35 localDefinitions = nonTerminals.ToDictionary(nt => nt, nt => string.Empty); 36 alternatives = nonTerminals.ToDictionary(nt => nt, nt => new List<Sequence>()); 36 37 } 37 38 38 39 public IEnumerable<Sequence> GetAlternativesWithSemanticActions(ISymbol ntSymbol) { 39 Debug.Assert(!ntSymbol.Equals(EmptySymbol));40 40 return alternatives[ntSymbol]; 41 41 } 42 42 public Sequence GetAlternativeWithSemanticActions(ISymbol ntSymbol, int index) { 43 Debug.Assert(!ntSymbol.Equals(EmptySymbol));44 43 return alternatives[ntSymbol][index]; 45 44 } … … 48 47 base.AddProductionRule(ntSymbol, new Sequence(production.Where(symb => !(symb is SemanticSymbol)).ToList())); 49 48 50 IList<Sequence> list; 51 if (!alternatives.TryGetValue(ntSymbol, out list)) { 52 list = new List<Sequence>(); 53 alternatives.Add(ntSymbol, list); 54 } 49 IList<Sequence> list = alternatives[ntSymbol]; 50 55 51 // make sure that there is not equivalent production registered already 56 52 Debug.Assert(!list.Any(s => s.SequenceEqual(production))); … … 61 57 public void AddLocalDefinitions(ISymbol ntSymbol, string localDefCode) { 62 58 Debug.Assert(!ntSymbol.Equals(EmptySymbol)); 63 Debug.Assert(!localDefinitions.ContainsKey(ntSymbol));64 59 65 localDefinitions .Add(ntSymbol, localDefCode);60 localDefinitions[ntSymbol] = localDefCode; 66 61 } 67 62 public string GetLocalDefinitions(ISymbol ntSymbol) { 68 string code; 69 if (localDefinitions.TryGetValue(ntSymbol, out code)) return code; 70 else return string.Empty; 63 return localDefinitions[ntSymbol]; 71 64 } 72 73 74 75 //private static Regex ruleExpr = new Regex(@"\s*(?<ntSymbol>\w+)\s*(?<formPar>\<\w+\>)+\s*->\s*(?<alternative>\w+\s*(?<actPar>\<\w+\>)+(?:\s+\w+\s*(?<actPar>\<\w+\>)+)*)(?:\s*\|\s*(?<alternative>\w+\s*(?<formPar>\<\w+\>)+(?:\s+\w+\s*(?<formPar>\<\w+\>)+)*))*");76 //private static Regex empty = new Regex(@"^\s*$");77 //public static Grammar FromString(string gStr) {78 // var lines = gStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);79 // lines = lines.Where(l => !empty.IsMatch(l)).ToArray(); // remove empty lines80 81 // // first line is the rule for the start-symbol82 // var m = ruleExpr.Match(lines.First());83 // var startSymbol = new Symbol(m.Groups["ntSymbol"].Value);84 85 // var g = new Grammar(startSymbol);86 // foreach (var alt in m.Groups["alternative"].Captures) {87 // g.AddProductionRule(startSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n))));88 // }89 // foreach (var line in lines.Skip(1)) {90 // m = ruleExpr.Match(line);91 // var ntSymbol = new Symbol(m.Groups["ntSymbol"].Value);92 // foreach (var alt in m.Groups["alternative"].Captures) {93 // g.AddProductionRule(ntSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n))));94 // }95 // }96 97 // return g;98 //}99 65 } 100 66 } -
branches/HeuristicLab.Problems.GPDL/HeuristicLab.Grammars/3.3/Grammar.cs
r10067 r10086 29 29 public class Grammar : IGrammar { 30 30 public static readonly ISymbol EmptySymbol = new Symbol("EPS"); 31 private Dictionary<ISymbol, List<Sequence>> rules = new Dictionary<ISymbol, List<Sequence>>();32 private HashSet<ISymbol> allSymbols = new HashSet<ISymbol>();31 private readonly Dictionary<ISymbol, List<Sequence>> rules; 32 private readonly HashSet<ISymbol> allSymbols; 33 33 34 34 public ISymbol StartSymbol { get; set; } … … 37 37 public IEnumerable<ISymbol> Symbols { get { return allSymbols; } } 38 38 39 public Grammar(ISymbol startSymbol ) {39 public Grammar(ISymbol startSymbol, IEnumerable<ISymbol> nonTerminals, IEnumerable<ISymbol> terminals) { 40 40 Debug.Assert(startSymbol != EmptySymbol); 41 41 this.StartSymbol = startSymbol; 42 this.allSymbols = new HashSet<ISymbol>(nonTerminals.Concat(terminals)); 43 this.rules = nonTerminals.ToDictionary(nt => nt, nt => new List<Sequence>()); 42 44 } 43 45 … … 56 58 public virtual void AddProductionRule(ISymbol ntSymbol, Sequence production) { 57 59 Debug.Assert(ntSymbol != EmptySymbol); 60 Debug.Assert(rules.ContainsKey(ntSymbol)); 61 Debug.Assert(production.All(s => allSymbols.Contains(s))); 58 62 59 List<Sequence> l; 60 if (!rules.TryGetValue(ntSymbol, out l)) { 61 l = new List<Sequence>(); 62 rules.Add(ntSymbol, l); 63 64 allSymbols.Add(ntSymbol); // register new nt-symbol 65 } 66 // check if the same production exists already 63 var l = rules[ntSymbol]; 67 64 Debug.Assert(!l.Any(s => s.SequenceEqual(production))); 68 65 69 66 l.Add(production); 70 71 foreach (var s in production) allSymbols.Add(s); // register all symbols in the production72 67 } 73 68 74 69 public bool IsTerminal(ISymbol symbol) { 70 // terminals must not have rules but must occur in the set of all symbols 75 71 return !rules.ContainsKey(symbol) && allSymbols.Contains(symbol); 76 72 } 73 77 74 public bool IsNonTerminal(ISymbol symbol) { 78 75 return rules.ContainsKey(symbol); 79 }80 81 // checks if a rule exists for each NT symbol82 public bool IsComplete() {83 return rules.ContainsKey(StartSymbol) &&84 NonTerminalSymbols.All(nt => rules.ContainsKey(nt));85 76 } 86 77 … … 91 82 lines = lines.Where(l => !empty.IsMatch(l)).ToArray(); // remove empty lines 92 83 84 // make two passes: 1) find all symbols 2) add production rules 85 var nonTerminals = new List<ISymbol>(); 86 var allSymbols = new List<ISymbol>(); 87 93 88 // first line is the rule for the start-symbol 94 89 var m = ruleExpr.Match(lines.First()); 95 90 var startSymbol = new Symbol(m.Groups["ntSymbol"].Value); 96 var g = new Grammar(startSymbol); 91 92 nonTerminals.Add(startSymbol); 93 allSymbols.Add(startSymbol); 94 95 // parse first line 97 96 foreach (var alt in m.Groups["alternative"].Captures) { 98 g.AddProductionRule(startSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n)).ToList<ISymbol>())); 97 foreach (var s in alt.ToString() 98 .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 99 .Select(n => new Symbol(n))) allSymbols.Add(s); 99 100 } 101 // parse all remaining lines 100 102 foreach (var line in lines.Skip(1)) { 101 103 m = ruleExpr.Match(line); 102 104 var ntSymbol = new Symbol(m.Groups["ntSymbol"].Value); 105 nonTerminals.Add(ntSymbol); 106 allSymbols.Add(ntSymbol); 107 103 108 foreach (var alt in m.Groups["alternative"].Captures) { 104 g.AddProductionRule(ntSymbol, new Sequence(alt.ToString().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(n => new Symbol(n)).ToList<ISymbol>())); 109 foreach (var s in alt.ToString() 110 .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 111 .Select(n => new Symbol(n))) allSymbols.Add(s); 112 } 113 } 114 115 var g = new Grammar(startSymbol, nonTerminals, allSymbols.Except(nonTerminals)); 116 117 m = ruleExpr.Match(lines.First()); 118 // add production rules 119 foreach (var alt in m.Groups["alternative"].Captures) { 120 g.AddProductionRule(startSymbol, 121 new Sequence(alt.ToString() 122 .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 123 .Select(n => allSymbols.Single(s => s.Name == n)).ToList<ISymbol>())); 124 } 125 // parse all remaining lines 126 foreach (var line in lines.Skip(1)) { 127 m = ruleExpr.Match(line); 128 var ntSymbol = nonTerminals.Single(s => s.Name == m.Groups["ntSymbol"].Value); 129 foreach (var alt in m.Groups["alternative"].Captures) { 130 g.AddProductionRule(ntSymbol, 131 new Sequence(alt.ToString() 132 .Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries) 133 .Select(n => allSymbols.Single(s => s.Name == n)).ToList<ISymbol>())); 105 134 } 106 135 } -
branches/HeuristicLab.Problems.GPDL/HeuristicLab.Problems.GPDL.sln
r10079 r10086 5 5 ProjectSection(SolutionItems) = preProject 6 6 GenerateFromAtg.cmd = GenerateFromAtg.cmd 7 Performance1.psess = Performance1.psess 7 8 PreBuildEvent.cmd = PreBuildEvent.cmd 8 9 EndProjectSection … … 111 112 {E2060931-6700-464B-9E82-50846D7AE4E9} = {3768D612-38EB-47D8-9E79-75D8E5AB00A8} 112 113 EndGlobalSection 114 GlobalSection(Performance) = preSolution 115 HasPerformanceSessions = true 116 EndGlobalSection 113 117 EndGlobal
Note: See TracChangeset
for help on using the changeset viewer.