Changeset 10067 for branches/HeuristicLab.Problems.GPDL/CodeGenerator
- Timestamp:
- 10/18/13 21:33:56 (11 years ago)
- Location:
- branches/HeuristicLab.Problems.GPDL/CodeGenerator
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/HeuristicLab.Problems.GPDL/CodeGenerator/BruteForceCodeGen.cs
r10062 r10067 1 1 using System; 2 2 using System.Collections.Generic; 3 using System.Diagnostics; 3 4 using System.IO; 4 5 using System.Linq; 5 6 using System.Text; 6 7 using System.Threading.Tasks; 8 using HeuristicLab.Grammars; 9 using Attribute = HeuristicLab.Grammars.Attribute; 7 10 8 11 namespace CodeGenerator { … … 17 20 private string solverTemplate = @" 18 21 namespace ?PROBLEMNAME? { 19 privatestatic class Grammar {22 internal static class Grammar { 20 23 ?GRAMMARCLASSCODE? 21 24 } 22 private sealed class PartiallyProcessedSeq { 23 private PartiallyProcessedSeq parent; 24 private int alt; 25 internal sealed class PartiallyProcessedSeq { 25 26 private IEnumerable<string> remaining; 26 p ublic PartiallyProcessedSeq(IEnumerable<string> alternative) {27 this.remaining = alternative;28 } 29 public PartiallyProcessedSeq CreateAlternative(int p, IEnumerable<string> alternative) {30 var child = new PartiallyProcessedSeq(alternative.Concat(remaining));31 child.parent = this;32 } 33 public bool TryProcessToNextSymbolWithAlternatives(out string symbol) { 34 remaining = remaining.SkipWhile(s=>Grammar.NumberOfAlternatives(s)==0);35 if( remaining.Any()) {36 symbol = remaining.First();37 remaining = remaining.Skip(1);38 return true;39 } else { 40 symbol = null;41 return false;42 }43 27 private IEnumerable<int> path; 28 public PartiallyProcessedSeq(IEnumerable<string> remaining) : this (Enumerable.Empty<int>(), remaining) { 29 } 30 public PartiallyProcessedSeq(IEnumerable<int> path, IEnumerable<string> remaining) { 31 this.path = path; 32 this.remaining = remaining; 33 } 34 35 public bool MoveNext() { 36 if(!remaining.Any()) return false; 37 else remaining = remaining.Skip(1); 38 return true; 39 } 40 41 public string Current { 42 get { 43 return remaining.FirstOrDefault(); 44 } 44 45 } 45 46 public IEnumerable<int> Path { 46 47 get { 47 var cur = this; 48 var List<int> path = new List<int>(); 49 while(cur.parent!=null) { 50 path.Append(cur.p); 51 cur = cur.parent; 52 } 53 return path.Reverse(); 54 } 55 } 48 return path; 49 } 50 } 51 public IEnumerable<string> Remaining { 52 get { 53 return remaining; 54 } 55 } 56 public override string ToString() { 57 return path.Aggregate("""", (str, p) => str + "" "" + p) + "" >> "" + 58 remaining.Aggregate("""", (str, r) => str + "" "" + r); 59 } 60 56 61 } 57 62 public sealed class ?IDENT?Solver { … … 71 76 72 77 private bool IsBetter(double a, double b) { 73 ?MAXIMIZATION? ? a > b : a < b; 74 } 75 76 private IEnumerable<IEnumerator<int>> GeneratePaths() { 78 return ?MAXIMIZATION? ? a > b : a < b; 79 } 80 81 #region path generator (BFS in the grammar to generate solutions) 82 ?PATHGENERATORCODE? 83 #endregion 84 85 private IEnumerable<IEnumerable<int>> GeneratePaths() { 77 86 var queue = new Queue<PartiallyProcessedSeq>(); 78 foreach(var alt in Grammar.GetAlternatives(Grammar.RootSymbol)) 79 queue.Enqueue(new PartiallyProcessedSeq(alt)); 80 81 while(queue.Count > 0) { 87 queue.Enqueue(new PartiallyProcessedSeq(new string[] { Grammar.RootSymbol })); 88 89 while (queue.Count > 0) { 82 90 var e = queue.Dequeue(); 83 string ntSöymbol; 84 if(e.TryProcessToNextNtSymbol(out ntSymbol)) { 85 int i=0; 86 foreach(var alt in Grammar.GetAlternatives(symbol)) { 87 queue.Enqueue(new e.CreateAlternative(i++, alt)); 91 var symb = e.Current; // the next symbol to generate paths for 92 // Console.WriteLine(""Out: "" + e); 93 94 var lastSymbol = !e.MoveNext(); 95 96 if (Grammar.IsTerminal(symb)) { 97 // generate all paths for the terminal 98 if (lastSymbol) { 99 var pathsForSymb = GeneratePathsFor(symb); 100 if (pathsForSymb.Any()) { 101 foreach (var path in GeneratePathsFor(symb)) { 102 yield return e.Path.Concat(path); 103 } 104 } else { 105 yield return e.Path; 106 } 107 } else { 108 var paths = GeneratePathsFor(symb); 109 if(!paths.Any() || paths.Count() == 1) { 110 yield return e.Path; 111 } else { 112 foreach (var path in paths) { 113 var eAlt = new PartiallyProcessedSeq(e.Path.Concat(path), e.Remaining); 114 queue.Enqueue(eAlt); 115 // Console.WriteLine(""In: "" + eAlt); 116 } 117 } 88 118 } 89 119 } else { 90 yield return e.Path; 91 } 92 } 93 } 94 95 ?PATHGENERATORCODE? 120 // non-terminal -> generate alternatives if necessary 121 var alts = Grammar.GetAlternatives(symb); 122 if (alts.Count() == 1) { 123 var eAlt = new PartiallyProcessedSeq(e.Path, alts.Single().Concat(e.Remaining)); 124 queue.Enqueue(eAlt); 125 // Console.WriteLine(""In: "" + eAlt); 126 } else { 127 int i = 0; 128 foreach (var alt in alts) { 129 var eAlt = new PartiallyProcessedSeq(e.Path.Concat(new int[] { i++ }), alt.Concat(e.Remaining)); 130 queue.Enqueue(eAlt); 131 // Console.WriteLine(""In: "" + eAlt); 132 } 133 } 134 } 135 } 136 } 96 137 97 138 private void Start() { 98 139 // generate possible paths through the grammar and evaluate each of them 99 140 var bestF = ?MAXIMIZATION? ? double.NegativeInfinity : double.PositiveInfinity; 141 int n = 0; 100 142 foreach(var path in GeneratePaths()) { 143 var length = path.Count(); 101 144 currentPath = path; 102 145 var f = Calculate(); 146 n++; 103 147 if(IsBetter(f, bestF)) bestF = f; 104 Console.WriteLine(""{0}\t{1}"",bestF, f);105 } 106 } 107 108 private IEnumera tor<int> currentPath;148 if (n%1000 == 0) Console.WriteLine(""{0}\t{1}\t{2}\t{3}"",n, length, bestF, f); 149 } 150 } 151 152 private IEnumerable<int> currentPath; 109 153 110 154 public double Calculate() { 111 try { 112 ?FITNESSFUNCTION? 113 } catch(Exception e) { 114 throw; 115 } 155 ?FITNESSFUNCTION? 116 156 } 117 157 … … 137 177 problemSourceCode.Replace("?PROBLEMNAME?", ast.Name); 138 178 139 // write t o a file for debugging179 // write the source file to disk 140 180 using (var stream = new StreamWriter(ast.Name + ".cs")) { 141 181 stream.WriteLine(problemSourceCode.ToString()); … … 144 184 145 185 private void GenerateProblem(GPDefNode ast, StringBuilder problemSourceCode) { 186 var grammar = CreateGrammarFromAst(ast); 146 187 var problemClassCode = 147 188 solverTemplate 148 .Replace("?MAXIMIZATION?", ast.FitnessFunctionNode.Maximization.ToString() )149 .Replace("?GRAMMARCLASSCODE?", GenerateGrammarClassCode( ast))189 .Replace("?MAXIMIZATION?", ast.FitnessFunctionNode.Maximization.ToString().ToLowerInvariant()) 190 .Replace("?GRAMMARCLASSCODE?", GenerateGrammarClassCode(grammar)) 150 191 .Replace("?IDENT?", ast.Name) 151 192 .Replace("?FITNESSFUNCTION?", ast.FitnessFunctionNode.SrcCode) 152 .Replace("?INTERPRETERSOURCE?", GenerateInterpreterSource( ast))193 .Replace("?INTERPRETERSOURCE?", GenerateInterpreterSource(grammar)) 153 194 .Replace("?INITCODE?", ast.InitCodeNode.SrcCode) 154 195 .Replace("?ADDITIONALCODE?", ast.ClassCodeNode.SrcCode) … … 160 201 } 161 202 162 private string GenerateGrammarClassCode(GPDefNode ast) { 203 private AttributedGrammar CreateGrammarFromAst(GPDefNode ast) { 204 string startSymbolName = ast.Rules.First().NtSymbol; 205 var startSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == startSymbolName); 206 // create startSymbol 207 var g = new AttributedGrammar(new Symbol(startSymbolName, ParseSymbolAttributes(startSymbolNode.FormalParameters))); 208 foreach (var rule in ast.Rules) { 209 // create nt-symbol 210 var ntSymbolName = rule.NtSymbol; 211 var ntSymbolNode = ast.NonTerminals.Single(nt => nt.Ident == ntSymbolName); 212 var attributes = ParseSymbolAttributes(ntSymbolNode.FormalParameters); 213 var ntSymbol = new Symbol(ntSymbolName, attributes); 214 foreach (var alt in GetAlternatives(rule.Alternatives)) { 215 g.AddProductionRule(ntSymbol, alt); 216 } 217 // local initialization code 218 if (!string.IsNullOrEmpty(rule.LocalCode)) g.AddLocalDefinitions(ntSymbol, rule.LocalCode); 219 } 220 return g; 221 } 222 223 private IEnumerable<IAttribute> ParseSymbolAttributes(string formalParameters) { 224 return (from fieldDef in Util.ExtractParameters(formalParameters) 225 select new Attribute(fieldDef.Identifier, fieldDef.Type, AttributeType.Parse(fieldDef.RefOrOut))). 226 ToList(); 227 } 228 229 private IEnumerable<Sequence> GetAlternatives(AlternativesNode altNode) { 230 foreach (var alt in altNode.Alternatives) { 231 yield return GetSequence(alt.Sequence); 232 } 233 } 234 235 private Sequence GetSequence(IEnumerable<RuleExprNode> sequence) { 236 Debug.Assert(sequence.All(s => s is CallSymbolNode || s is RuleActionNode)); 237 var l = new List<ISymbol>(); 238 foreach (var node in sequence) { 239 var callSymbolNode = node as CallSymbolNode; 240 var actionNode = node as RuleActionNode; 241 if (callSymbolNode != null) { 242 l.Add(new Symbol(callSymbolNode.Ident, ParseSymbolAttributes(callSymbolNode.ActualParameter))); 243 } else if (actionNode != null) { 244 l.Add(new SemanticSymbol("SEM", actionNode.SrcCode)); 245 } 246 } 247 return new Sequence(l); 248 } 249 250 251 private string GenerateGrammarClassCode(IGrammar grammar) { 163 252 var sb = new StringBuilder(); 164 253 // RootSymbol 165 sb.AppendFormat("public static string RootSymbol {{ get {{ return {0}; }} }}", ast.Rules.First().NtSymbol).AppendLine(); 254 sb.AppendFormat("public static string RootSymbol {{ get {{ return \"{0}\"; }} }}", grammar.StartSymbol.Name).AppendLine(); 255 sb.AppendLine("public static HashSet<string> terminalSymbols = new HashSet<string>() {"); 256 sb.AppendFormat("{0}", grammar.TerminalSymbols.Aggregate("", (str, symb) => str + "\"" + symb.Name + "\", ")); 257 sb.AppendLine("};"); 166 258 // GetAlternatives 167 259 sb.AppendFormat("public static IEnumerable<IEnumerable<string>> GetAlternatives(string symbol) {{"); 168 260 sb.AppendFormat("switch(symbol) {{ ").AppendLine(); 169 foreach (var ntSymbol in ast.NonTerminals) { 170 sb.AppendFormat("case {0}: {{ ").AppendLine(); 171 var rule = ast.Rules.Single(r => r.NtSymbol == ntSymbol.Ident); 172 sb.AppendFormat("return new string[][] {{}}", rule.RuleExpr); 173 sb.AppendLine("break;}}"); 174 } 175 foreach (var tSymbol in ast.NonTerminals) { 176 177 } 178 sb.AppendFormat(" else {{ throw new InvalidOperationException(\"Unkown symbol: \"+symbol); }}"); 179 sb.AppendLine("}}"); 180 sb.AppendFormat("}}").AppendLine(); 181 261 foreach (var ntSymbol in grammar.NonTerminalSymbols) { 262 sb.AppendFormat("case \"{0}\": {{ ", ntSymbol.Name).AppendLine(); 263 sb.Append("return new string[][] { ").AppendLine(); 264 foreach (var alt in grammar.GetAlternatives(ntSymbol)) { 265 sb.Append("new string[] { ") 266 .Append(alt.Skip(1).Aggregate("\"" + alt.First().Name + "\"", (str, symb) => str + ", \"" + symb.Name + "\"")) 267 .AppendLine("},"); 268 } 269 sb.Append("};"); 270 sb.AppendLine("}"); 271 } 272 sb.AppendLine(" default: { throw new InvalidOperationException(\"Unkown symbol: \"+symbol); }"); 273 sb.AppendLine("}"); 274 sb.AppendLine("}"); 275 276 sb.AppendLine("public static bool IsTerminal(string symbol) {"); 277 sb.AppendFormat("return terminalSymbols.Contains(symbol);"); 278 sb.AppendLine("}"); 182 279 // NumberOfAlternatives 183 sb.AppendFormat( 184 "public static int NumberOfAlternatives(string symbol) {{ return GetAlternatives(symbol).Count(); }}").AppendLine(); 185 return sb.ToString(); 186 } 280 sb.AppendLine( 281 "public static int NumberOfAlternatives(string symbol) { return GetAlternatives(symbol).Count(); }"); 282 return sb.ToString(); 283 } 284 187 285 188 286 // produces helper methods for the attributes of all terminal nodes … … 216 314 private string GeneratePathGeneratorCode(GPDefNode ast) { 217 315 var sb = new StringBuilder(); 218 foreach (var s in ast.NonTerminals ) {316 foreach (var s in ast.NonTerminals.OfType<NonTerminalNode>()) { 219 317 sb.Append(GeneratePathGeneratorCode(s)); 220 318 } 221 foreach (var s in ast.Terminals) { 222 sb.Append(GeneratePathGeneratorCode(s)); 223 } 224 return sb.ToString(); 225 } 226 227 // generates code for a breath-first-search generating all possible paths through the grammar 228 private string GeneratePathGeneratorCode(SymbolNode s) { 229 var sb = new StringBuilder(); 230 231 return sb.ToString(); 232 } 233 234 private string GenerateInterpreterSource(GPDefNode definition) { 235 var sb = new StringBuilder(); 236 // create a grammar instance based on the AST 237 var g = new Grammar(definition.NonTerminals, definition.Terminals, definition.Rules); 319 320 sb.Append(GeneratePathGeneratorCode(ast.Terminals.OfType<TerminalNode>())); 321 return sb.ToString(); 322 } 323 324 private string GeneratePathGeneratorCode(NonTerminalNode s) { 325 var sb = new StringBuilder(); 326 327 return sb.ToString(); 328 } 329 330 // generates a method for the terminal that returns all an IEnumerable of int[] representing each possible combination of values for that terminal 331 private string GeneratePathGeneratorCode(IEnumerable<TerminalNode> terminals) { 332 var sb = new StringBuilder(); 333 sb.AppendLine("private IEnumerable<IEnumerable<int>> GeneratePathsFor(string tSymbol) {"); 334 sb.AppendLine("switch(tSymbol) {"); 335 foreach (var t in terminals) { 336 sb.AppendFormat("case \"{0}\": {{", t.Ident).AppendLine(); 337 if (t.FieldDefinitions.Any()) { 338 int i = 0; 339 // open for loop for each field 340 foreach (var f in t.FieldDefinitions) { 341 sb.AppendFormat("for(int i{0}=0; i{0} < GetAllowed{1}_{2}().Length; i{0}++) {{", i++, t.Ident, f.Identifier) 342 . 343 AppendLine(); 344 } 345 sb.AppendFormat("yield return new int[] {{ {0} }};", 346 Enumerable.Range(0, i).Select(ii => "i" + ii + ", ").Aggregate((str, e) => str + e)); 347 // close braces 348 while (i-- > 0) { 349 sb.AppendLine("}"); 350 } 351 sb.AppendLine("break;"); 352 } else { 353 sb.AppendLine("yield return Enumerable.Empty<int>();"); 354 sb.AppendLine("break;"); 355 } 356 sb.AppendLine("}"); 357 } 358 sb.AppendLine("} }"); 359 return sb.ToString(); 360 } 361 362 private string GenerateInterpreterSource(AttributedGrammar grammar) { 363 var sb = new StringBuilder(); 364 365 238 366 // find formal parameters of root node 239 string formalParameter = definition.NonTerminals.Single(nt => nt.Ident == g.RootSymbol).FormalParameters; 367 var attr = grammar.StartSymbol.Attributes; 368 369 var formalParameter = grammar.StartSymbol.GetAttributeString(); 240 370 // actual parameter are the same as formalparameter only without type identifier 241 var actualParameterEnumerable = 242 Util.ExtractFormalParameters(formalParameter).Select(e => e.RefOrOut + " " + e.Identifier); 243 string actualParameter = string.Empty; 244 // generate a string of actual parameters beginning with: ', a0, a1, ...' 245 if (actualParameterEnumerable.Any()) { 246 foreach (var e in actualParameterEnumerable) { 247 actualParameter += ", " + e; 248 } 249 } 371 string actualParameter; 372 if (attr.Any()) 373 actualParameter = attr.Skip(1).Aggregate(attr.First().AttributeType + " " + attr.First().Name, (str, a) => str + ", " + a.AttributeType + " " + a.Name); 374 else 375 actualParameter = string.Empty; 376 250 377 // generate entry method for evaluation. This is called from the min/max function 251 378 // e.g.: ProgramRoot(ref int a0) { ProgramRoot(rootNode , ref a0); } 252 sb.AppendFormat("void {0}({1}) {{ {0}(currentPath {2}); }}", g.RootSymbol, formalParameter, actualParameter).AppendLine(); 379 sb.AppendFormat("void {0}({1}) {{", grammar.StartSymbol.Name, formalParameter).AppendLine(); 380 sb.AppendLine(" var path = currentPath.GetEnumerator();"); 381 sb.AppendFormat("{0}(path, {1});", grammar.StartSymbol.Name, actualParameter).AppendLine(); 382 sb.AppendLine("if(path.MoveNext()) throw new InvalidOperationException(); // assert that the full path has been processed"); 383 sb.AppendLine("}"); 253 384 254 385 // generate methods for all nonterminals and terminals using the grammar instance 255 foreach (var s in definition.NonTerminals) {256 sb.AppendLine(GenerateInterpreterMethod(g , s));257 } 258 foreach (var s in definition.Terminals) {259 sb.AppendLine(GenerateTerminalInterpreterMethod( (TerminalNode)s));260 } 261 return sb.ToString(); 262 } 263 264 private string GenerateTerminalInterpreterMethod( TerminalNodes) {386 foreach (var s in grammar.NonTerminalSymbols) { 387 sb.AppendLine(GenerateInterpreterMethod(grammar, s)); 388 } 389 foreach (var s in grammar.TerminalSymbols) { 390 sb.AppendLine(GenerateTerminalInterpreterMethod(s)); 391 } 392 return sb.ToString(); 393 } 394 395 private string GenerateTerminalInterpreterMethod(ISymbol s) { 265 396 var sb = new StringBuilder(); 266 397 // if the terminal symbol has attributes then we must create values for these attributes 267 if (!s. FormalParameters.Any())268 sb.AppendFormat("private void {0}(IEnumerator<int> path) {{", s. Ident);398 if (!s.Attributes.Any()) 399 sb.AppendFormat("private void {0}(IEnumerator<int> path) {{", s.Name); 269 400 else 270 sb.AppendFormat("private void {0}(IEnumerator<int> path, {1}) {{", s. Ident, s.FormalParameters);401 sb.AppendFormat("private void {0}(IEnumerator<int> path, {1}) {{", s.Name, s.GetAttributeString()); 271 402 272 403 // each field must match a formal parameter, assign a value for each parameter 273 foreach (var element in s. FieldDefinitions) {404 foreach (var element in s.Attributes) { 274 405 // read next symbol 275 406 sb.AppendLine("path.MoveNext();"); 276 sb.AppendFormat("{0} = Get{1}_{0}Element(path.Current)", element. Identifier, s.Ident).AppendLine(";");277 } 278 sb.AppendLine("}"); 279 return sb.ToString(); 280 } 281 282 private string GenerateInterpreterMethod( Grammar g, SymbolNodes) {283 var sb = new StringBuilder(); 284 if (!s. FormalParameters.Any())285 sb.AppendFormat("private void {0}(IEnumerator<int> path) {{", s. Ident);407 sb.AppendFormat("{0} = Get{1}_{0}Element(path.Current)", element.Name, s.Name).AppendLine(";"); 408 } 409 sb.AppendLine("}"); 410 return sb.ToString(); 411 } 412 413 private string GenerateInterpreterMethod(AttributedGrammar g, ISymbol s) { 414 var sb = new StringBuilder(); 415 if (!s.Attributes.Any()) 416 sb.AppendFormat("private void {0}(IEnumerator<int> path) {{", s.Name); 286 417 else 287 sb.AppendFormat("private void {0}(IEnumerator<int> path, {1}) {{", s. Ident, s.FormalParameters);418 sb.AppendFormat("private void {0}(IEnumerator<int> path, {1}) {{", s.Name, s.GetAttributeString()); 288 419 // generate local definitions 289 sb.AppendLine(g.GetLocalDefinitions(s.Ident)); 290 291 // read next symbol 292 sb.AppendLine("path.MoveNext();"); 420 sb.AppendLine(g.GetLocalDefinitions(s)); 421 293 422 294 423 // if there are alternatives for this symbol -> choose alternative based on the path 295 var alts = g.GetAlternatives(s .Ident);424 var alts = g.GetAlternatives(s); 296 425 if (alts.Count() > 1) { 426 // read next symbol 427 sb.AppendLine("path.MoveNext();"); 297 428 int i = 0; 298 429 sb.AppendLine("switch(path.Current) {"); … … 300 431 foreach (var l in alts) { 301 432 sb.AppendFormat("case {0}: {{ ", i).AppendLine(); 302 foreach (var e in g.GetSequenceWithSemanticActions(s.Ident, i++)) {303 sb.AppendLine(GenerateSourceForAction( e));433 foreach (var altS in g.GetAlternativeWithSemanticActions(s, i++)) { 434 sb.AppendLine(GenerateSourceForAction(altS)); 304 435 } 305 436 sb.AppendLine("break;").AppendLine("}"); 306 437 } 307 sb.AppendLine(" } else throw new System.InvalidOperationException()").AppendLine();438 sb.AppendLine("default: throw new System.InvalidOperationException();").AppendLine("}"); 308 439 } else { 309 foreach (var e in g.GetSequenceWithSemanticActions(s.Ident, 0)) {310 sb.AppendLine(GenerateSourceForAction( e));440 foreach (var altS in g.GetAlternativeWithSemanticActions(s, 0)) { 441 sb.AppendLine(GenerateSourceForAction(altS)); 311 442 } 312 443 } … … 316 447 317 448 // helper for generating calls to other symbol methods 318 private string GenerateSourceForAction(RuleExprNode e) { 319 var action = e as RuleActionNode; 320 var call = e as CallSymbolNode; 449 private string GenerateSourceForAction(ISymbol s) { 450 var action = s as SemanticSymbol; 321 451 if (action != null) { 322 return action. SrcCode + ";";323 } else if (call != null){324 if (! call.ActualParameter.Any())325 return string.Format("{0}(path);", call.Ident);452 return action.Code + ";"; 453 } else { 454 if (!s.Attributes.Any()) 455 return string.Format("{0}(path);", s.Name); 326 456 else 327 return string.Format("{0}(path, {1});", call.Ident, call.ActualParameter); 328 } else { 329 throw new ArgumentException(); 457 return string.Format("{0}(path, {1});", s.Name, s.GetAttributeString()); 330 458 } 331 459 } -
branches/HeuristicLab.Problems.GPDL/CodeGenerator/CodeGenerator.csproj
r10062 r10067 32 32 </PropertyGroup> 33 33 <ItemGroup> 34 <Reference Include="System" /> 34 35 <Reference Include="System.Core" /> 35 36 </ItemGroup> … … 39 40 </ItemGroup> 40 41 <ItemGroup> 42 <ProjectReference Include="..\HeuristicLab.Grammars\3.3\HeuristicLab.Grammars-3.3.csproj"> 43 <Project>{A5452B63-B33B-4F9F-9E81-98B75EDB5612}</Project> 44 <Name>HeuristicLab.Grammars-3.3</Name> 45 </ProjectReference> 41 46 <ProjectReference Include="..\HeuristicLab.Problems.GPDL\3.4\HeuristicLab.Problems.GPDL-3.4.csproj"> 42 47 <Project>{E4EE5AFB-D552-447B-8A16-6CBE7938AF32}</Project>
Note: See TracChangeset
for help on using the changeset viewer.