private static void GetFilteredParametersAndSuffixedMatcherName( LGSPRulePattern rulePattern, PatternGraph patternGraph, int index, out String[] paramTypesArray, out String[] paramNamesArray, out String suffixedMatcherName) { List <String> paramTypes = new List <String>(); List <String> paramNames = new List <String>(); List <String> removedNames = new List <String>(); for (int i = 0; i < rulePattern.Inputs.Length; ++i) { String inputName = rulePattern.InputNames[i]; if (patternGraph.availabilityOfMaybeNullElements[index].ContainsKey(inputName) && !patternGraph.availabilityOfMaybeNullElements[index][inputName]) { removedNames.Add(rulePattern.InputNames[i]); } else { paramTypes.Add(TypesHelper.TypeName(rulePattern.Inputs[i])); paramNames.Add(rulePattern.InputNames[i]); } } paramTypesArray = new String[paramTypes.Count]; paramNamesArray = new String[paramNames.Count]; for (int i = 0; i < paramTypes.Count; ++i) { paramTypesArray[i] = paramTypes[i]; paramNamesArray[i] = paramNames[i]; } suffixedMatcherName = "myMatch"; foreach (String removedName in removedNames) { suffixedMatcherName += "_MissingPreset_" + removedName; } }
/// <summary> // generate implementation of the exact action interface, // delegate calls of the inexact action interface IAction to the exact action interface /// </summary> void GenerateActionImplementation(SourceBuilder sb, LGSPRulePattern matchingPattern) { StringBuilder sbInParameters = new StringBuilder(); StringBuilder sbInArguments = new StringBuilder(); StringBuilder sbInArgumentsFromArray = new StringBuilder(); for(int i = 0; i < matchingPattern.Inputs.Length; ++i) { sbInParameters.Append(", "); sbInParameters.Append(TypesHelper.TypeName(matchingPattern.Inputs[i])); sbInParameters.Append(" "); sbInParameters.Append(matchingPattern.InputNames[i]); sbInArguments.Append(", "); sbInArguments.Append(matchingPattern.InputNames[i]); sbInArgumentsFromArray.Append(", ("); sbInArgumentsFromArray.Append(TypesHelper.TypeName(matchingPattern.Inputs[i])); sbInArgumentsFromArray.Append(") parameters["); sbInArgumentsFromArray.Append(i); sbInArgumentsFromArray.Append("]"); } String inParameters = sbInParameters.ToString(); String inArguments = sbInArguments.ToString(); String inArgumentsFromArray = sbInArgumentsFromArray.ToString(); StringBuilder sbOutParameters = new StringBuilder(); StringBuilder sbRefParameters = new StringBuilder(); StringBuilder sbOutLocals = new StringBuilder(); StringBuilder sbRefLocals = new StringBuilder(); StringBuilder sbOutArguments = new StringBuilder(); StringBuilder sbRefArguments = new StringBuilder(); StringBuilder sbOutIntermediateLocalsAll = new StringBuilder(); StringBuilder sbOutParametersAll = new StringBuilder(); StringBuilder sbOutArgumentsAll = new StringBuilder(); StringBuilder sbIntermediateLocalArgumentsAll = new StringBuilder(); StringBuilder sbOutClassArgumentsAll = new StringBuilder(); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sbOutParameters.Append(", out "); sbOutParameters.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sbOutParameters.Append(" output_"); sbOutParameters.Append(i); sbRefParameters.Append(", ref "); sbRefParameters.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sbRefParameters.Append(" output_"); sbRefParameters.Append(i); sbOutLocals.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sbOutLocals.Append(" output_"); sbOutLocals.Append(i); sbOutLocals.Append("; "); sbRefLocals.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sbRefLocals.Append(" output_"); sbRefLocals.Append(i); sbRefLocals.Append(" = "); sbRefLocals.Append(TypesHelper.DefaultValueString(matchingPattern.Outputs[i].PackagePrefixedName, model)); sbRefLocals.Append("; "); sbOutArguments.Append(", out output_"); sbOutArguments.Append(i); sbRefArguments.Append(", ref output_"); sbRefArguments.Append(i); sbOutIntermediateLocalsAll.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sbOutIntermediateLocalsAll.Append(" output_local_"); sbOutIntermediateLocalsAll.Append(i); sbOutIntermediateLocalsAll.Append("; "); sbOutParametersAll.Append(", List<"); sbOutParametersAll.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sbOutParametersAll.Append("> output_"); sbOutParametersAll.Append(i); sbOutArgumentsAll.Append(", output_"); sbOutArgumentsAll.Append(i); sbIntermediateLocalArgumentsAll.Append(", out output_local_"); sbIntermediateLocalArgumentsAll.Append(i); sbOutClassArgumentsAll.Append(", output_list_"); sbOutClassArgumentsAll.Append(i); } String outParameters = sbOutParameters.ToString(); String refParameters = sbRefParameters.ToString(); String outLocals = sbOutLocals.ToString(); String refLocals = sbRefLocals.ToString(); String outArguments = sbOutArguments.ToString(); String refArguments = sbRefArguments.ToString(); String outIntermediateLocalsAll = sbOutIntermediateLocalsAll.ToString(); String outParametersAll = sbOutParametersAll.ToString(); String outArgumentsAll = sbOutArgumentsAll.ToString(); String intermediateLocalArgumentsAll = sbIntermediateLocalArgumentsAll.ToString(); String outClassArgumentsAll = sbOutClassArgumentsAll.ToString(); String matchingPatternClassName = matchingPattern.GetType().Name; String patternName = matchingPattern.name; String matchType = matchingPatternClassName + "." + NamesOfEntities.MatchInterfaceName(patternName); String matchesType = "GRGEN_LIBGR.IMatchesExact<" + matchType + ">"; // implementation of exact action interface sb.AppendFront("/// <summary> Type of the matcher method (with parameters processing environment containing host graph, maximum number of matches to search for (zero=unlimited), and rule parameters; returning found matches). </summary>\n"); sb.AppendFrontFormat("public delegate {0} MatchInvoker(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv, int maxMatches{1});\n", matchesType, inParameters); sb.AppendFront("/// <summary> A delegate pointing to the current matcher program for this rule. </summary>\n"); sb.AppendFront("public MatchInvoker DynamicMatch;\n"); sb.AppendFront("/// <summary> The RulePattern object from which this LGSPAction object has been created. </summary>\n"); sb.AppendFront("public GRGEN_LIBGR.IRulePattern RulePattern { get { return _rulePattern; } }\n"); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFront("List<"); sb.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sb.Append("> output_list_"); sb.Append(i.ToString()); sb.Append(" = new List<"); sb.Append(TypesHelper.TypeName(matchingPattern.Outputs[i])); sb.Append(">();\n"); } sb.AppendFrontFormat("public {0} Match(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int maxMatches{1})\n", matchesType, inParameters); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("return DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, maxMatches{0});\n", inArguments); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFrontFormat("public void Modify(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} match{1})\n", matchType, outParameters); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, match{0});\n", outArguments); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFrontFormat("public void ModifyAll(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} matches{1})\n", matchesType, outParametersAll); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("foreach({0} match in matches)\n", matchType); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0}\n", outIntermediateLocalsAll); sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, match{0});\n", intermediateLocalArgumentsAll); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("output_{0}.Add(output_local_{0});\n", i); } sb.Unindent(); sb.AppendFront("}\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFrontFormat("public bool Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1})\n", inParameters, refParameters); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0} matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{1});\n", matchesType, inArguments); sb.AppendFront("if(matches.Count <= 0) return false;\n"); sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments); sb.AppendFront("return true;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFrontFormat("public int ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1})\n", inParameters, outParametersAll); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0} matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, maxMatches{1});\n", matchesType, inArguments); sb.AppendFront("if(matches.Count <= 0) return 0;\n"); sb.AppendFrontFormat("foreach({0} match in matches)\n", matchType); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0}\n", outIntermediateLocalsAll); sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, match{0});\n", intermediateLocalArgumentsAll); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("output_{0}.Add(output_local_{0});\n", i); } sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return matches.Count;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFrontFormat("public bool ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0})\n", inParameters); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0} matches;\n", matchesType); sb.AppendFrontFormat("{0}\n", outLocals); sb.AppendFront("while(true)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{0});\n", inArguments); sb.AppendFront("if(matches.Count <= 0) return true;\n"); sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments); sb.Unindent(); sb.AppendFront("}\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFrontFormat("public bool ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0})\n", inParameters); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0} matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{1});\n", matchesType, inArguments); sb.AppendFront("if(matches.Count <= 0) return false;\n"); sb.AppendFrontFormat("{0}\n", outLocals); sb.AppendFront("do\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments); sb.AppendFrontFormat("matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{0});\n", inArguments); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("while(matches.Count > 0) ;\n"); sb.AppendFront("return true;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFrontFormat("public bool ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max{0})\n", inParameters); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0} matches;\n", matchesType); sb.AppendFrontFormat("{0}\n", outLocals); sb.AppendFront("for(int i = 0; i < max; i++)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("matches = DynamicMatch((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, 1{0});\n", inArguments); sb.AppendFront("if(matches.Count <= 0) return i >= min;\n"); sb.AppendFrontFormat("_rulePattern.Modify((GRGEN_LGSP.LGSPActionExecutionEnvironment)actionEnv, matches.First{0});\n", outArguments); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return true;\n"); sb.Unindent(); sb.AppendFront("}\n"); // implementation of inexact action interface by delegation to exact action interface sb.AppendFront("// implementation of inexact action interface by delegation to exact action interface\n"); sb.AppendFront("public GRGEN_LIBGR.IMatches Match(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int maxMatches, object[] parameters)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("return Match(actionEnv, maxMatches{0});\n", inArgumentsFromArray); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("public object[] Modify(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, GRGEN_LIBGR.IMatch match)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0}\n", outLocals); sb.AppendFrontFormat("Modify(actionEnv, ({0})match{1});\n", matchType, outArguments); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("ReturnArray[{0}] = output_{0};\n", i); } sb.AppendFront("return ReturnArray;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("public List<object[]> ModifyAll(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, GRGEN_LIBGR.IMatches matches)\n"); sb.AppendFront("{\n"); sb.Indent(); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFront("output_list_"); sb.Append(i.ToString()); sb.Append(".Clear();\n"); } sb.AppendFrontFormat("ModifyAll(actionEnv, ({0})matches{1});\n", matchesType, outClassArgumentsAll); sb.AppendFront("while(AvailableReturnArrays.Count < matches.Count) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n"); sb.AppendFront("ReturnArrayListForAll.Clear();\n"); sb.AppendFront("for(int i=0; i<matches.Count; ++i)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n"); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("ReturnArrayListForAll[i][{0}] = output_list_{0}[i];\n", i); } sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return ReturnArrayListForAll;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("object[] GRGEN_LIBGR.IAction.Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n"); sb.AppendFront("{\n"); sb.Indent(); if(matchingPattern.Inputs.Length == 0) { sb.AppendFrontFormat("{0}\n", refLocals); sb.AppendFrontFormat("if(Apply(actionEnv{0})) ", refArguments); sb.Append("{\n"); sb.Indent(); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("ReturnArray[{0}] = output_{0};\n", i); } sb.AppendFront("return ReturnArray;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("else return null;\n"); } else sb.AppendFront("throw new Exception();\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("object[] GRGEN_LIBGR.IAction.Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("{0}\n", refLocals); sb.AppendFrontFormat("if(Apply(actionEnv{0}{1})) ", inArgumentsFromArray, refArguments); sb.Append("{\n"); sb.Indent(); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("ReturnArray[{0}] = output_{0};\n", i); } sb.AppendFront("return ReturnArray;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("else return null;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("public List<object[]> Reserve(int numReturns)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("while(AvailableReturnArrays.Count < numReturns) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n"); sb.AppendFront("ReturnArrayListForAll.Clear();\n"); sb.AppendFront("for(int i=0; i<numReturns; ++i)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return ReturnArrayListForAll;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("List<object[]> GRGEN_LIBGR.IAction.ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n"); sb.AppendFront("{\n"); sb.Indent(); if(matchingPattern.Inputs.Length == 0) { for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFront("output_list_"); sb.Append(i.ToString()); sb.Append(".Clear();\n"); } sb.AppendFrontFormat("int matchesCount = ApplyAll(maxMatches, actionEnv{0});\n", outClassArgumentsAll); sb.AppendFront("while(AvailableReturnArrays.Count < matchesCount) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n"); sb.AppendFront("ReturnArrayListForAll.Clear();\n"); sb.AppendFront("for(int i=0; i<matchesCount; ++i)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n"); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("ReturnArrayListForAll[i][{0}] = output_list_{0}[i];\n", i); } sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return ReturnArrayListForAll;\n"); } else sb.AppendFront("throw new Exception();\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("List<object[]> GRGEN_LIBGR.IAction.ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n"); sb.AppendFront("{\n"); sb.Indent(); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFront("output_list_"); sb.Append(i.ToString()); sb.Append(".Clear();\n"); } sb.AppendFrontFormat("int matchesCount = ApplyAll(maxMatches, actionEnv{0}{1});\n", inArgumentsFromArray, outClassArgumentsAll); sb.AppendFront("while(AvailableReturnArrays.Count < matchesCount) AvailableReturnArrays.Add(new object[" + matchingPattern.Outputs.Length + "]);\n"); sb.AppendFront("ReturnArrayListForAll.Clear();\n"); sb.AppendFront("for(int i=0; i<matchesCount; ++i)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("ReturnArrayListForAll.Add(AvailableReturnArrays[i]);\n"); for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { sb.AppendFrontFormat("ReturnArrayListForAll[i][{0}] = output_list_{0}[i];\n", i); } sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return ReturnArrayListForAll;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n"); sb.AppendFront("{\n"); sb.Indent(); if(matchingPattern.Inputs.Length == 0) sb.AppendFront("return ApplyStar(actionEnv);\n"); else sb.AppendFront("throw new Exception(); return false;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("return ApplyStar(actionEnv{0});\n", inArgumentsFromArray); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv)\n"); sb.AppendFront("{\n"); sb.Indent(); if(matchingPattern.Inputs.Length == 0) sb.AppendFront("return ApplyPlus(actionEnv);\n"); else sb.AppendFront("throw new Exception(); return false;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, params object[] parameters)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("return ApplyPlus(actionEnv{0});\n", inArgumentsFromArray); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max)\n"); sb.AppendFront("{\n"); sb.Indent(); if(matchingPattern.Inputs.Length == 0) sb.AppendFront("return ApplyMinMax(actionEnv, min, max);\n"); else sb.AppendFront("throw new Exception(); return false;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("bool GRGEN_LIBGR.IAction.ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max, params object[] parameters)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFrontFormat("return ApplyMinMax(actionEnv, min, max{0});\n", inArgumentsFromArray); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("void GRGEN_LIBGR.IAction.Filter(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, GRGEN_LIBGR.IMatches matches, GRGEN_LIBGR.FilterCall filter)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("if(filter.IsAutoSupplied) {\n"); sb.Indent(); sb.AppendFront("switch(filter.Name) {\n"); sb.Indent(); sb.AppendFront("case \"keepFirst\": matches.FilterKeepFirst((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("case \"keepLast\": matches.FilterKeepLast((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("case \"keepFirstFraction\": matches.FilterKeepFirstFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("case \"keepLastFraction\": matches.FilterKeepLastFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("case \"removeFirst\": matches.FilterRemoveFirst((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("case \"removeLast\": matches.FilterRemoveLast((int)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("case \"removeFirstFraction\": matches.FilterRemoveFirstFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("case \"removeLastFraction\": matches.FilterRemoveLastFraction((double)(filter.ArgumentExpressions[0]!=null ? filter.ArgumentExpressions[0].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[0])); break;\n"); sb.AppendFront("default: throw new Exception(\"Unknown auto supplied filter name!\");\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("switch(filter.FullName) {\n"); sb.Indent(); foreach(IFilter filter in matchingPattern.Filters) { if(filter is IFilterAutoGenerated) { if(((IFilterAutoGenerated)filter).Entity != null) { sb.AppendFrontFormat("case \"{1}<{2}>\": GRGEN_ACTIONS.{4}MatchFilters.Filter_{0}_{1}_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches); break;\n", patternName, filter.Name, ((IFilterAutoGenerated)filter).Entity, matchesType, TypesHelper.GetPackagePrefixDot(filter.Package)); if(filter.Package != null) sb.AppendFrontFormat("case \"{5}{1}<{2}>\": GRGEN_ACTIONS.{4}MatchFilters.Filter_{0}_{1}_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches); break;\n", patternName, filter.Name, ((IFilterAutoGenerated)filter).Entity, matchesType, filter.Package + ".", filter.Package + "::"); } else // auto { sb.AppendFrontFormat("case \"{1}\": GRGEN_ACTIONS.{3}MatchFilters.Filter_{0}_{1}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({2})matches); break;\n", patternName, filter.Name, matchesType, TypesHelper.GetPackagePrefixDot(filter.Package)); if(filter.Package != null) sb.AppendFrontFormat("case \"{4}{1}\": GRGEN_ACTIONS.{3}MatchFilters.Filter_{0}_{1}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({2})matches); break;\n", patternName, filter.Name, matchesType, filter.Package + ".", filter.Package + "::"); } } else { IFilterFunction filterFunction = (IFilterFunction)filter; sb.AppendFrontFormat("case \"{0}\": GRGEN_ACTIONS.{1}MatchFilters.Filter_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches", filterFunction.Name, TypesHelper.GetPackagePrefixDot(filterFunction.Package), filterFunction.Name, matchesType); for(int i=0; i<filterFunction.Inputs.Length; ++i) { sb.AppendFormat(", ({0})(filter.ArgumentExpressions[{1}]!=null ? filter.ArgumentExpressions[{1}].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[{1}])", TypesHelper.TypeName(filterFunction.Inputs[i]), i); } sb.Append("); break;\n"); if(filter.Package != null) { sb.AppendFrontFormat("case \"{4}{0}\": GRGEN_ACTIONS.{1}MatchFilters.Filter_{2}((GRGEN_LGSP.LGSPGraphProcessingEnvironment)actionEnv, ({3})matches", filterFunction.Name, TypesHelper.GetPackagePrefixDot(filterFunction.Package), filterFunction.Name, matchesType, filter.Package + "::"); for(int i = 0; i < filterFunction.Inputs.Length; ++i) { sb.AppendFormat(", ({0})(filter.ArgumentExpressions[{1}]!=null ? filter.ArgumentExpressions[{1}].Evaluate((GRGEN_LIBGR.IGraphProcessingEnvironment)actionEnv) : filter.Arguments[{1}])", TypesHelper.TypeName(filterFunction.Inputs[i]), i); } sb.Append("); break;\n"); } } } sb.AppendFront("default: throw new Exception(\"Unknown filter name!\");\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.Unindent(); sb.AppendFront("}\n"); }
/// <summary> // generate the exact action interface /// </summary> void GenerateActionInterface(SourceBuilder sb, LGSPRulePattern matchingPattern) { String actionInterfaceName = "IAction_"+matchingPattern.name; String outParameters = ""; String refParameters = ""; String allParameters = ""; for(int i = 0; i < matchingPattern.Outputs.Length; ++i) { outParameters += ", out " + TypesHelper.TypeName(matchingPattern.Outputs[i]) + " output_"+i; refParameters += ", ref " + TypesHelper.TypeName(matchingPattern.Outputs[i]) + " output_"+i; allParameters += ", List<" + TypesHelper.TypeName(matchingPattern.Outputs[i]) + "> output_"+i; } String inParameters = ""; for(int i=0; i<matchingPattern.Inputs.Length; ++i) { inParameters += ", " + TypesHelper.TypeName(matchingPattern.Inputs[i]) + " " + matchingPattern.InputNames[i]; } String matchingPatternClassName = matchingPattern.GetType().Name; String patternName = matchingPattern.name; String matchType = matchingPatternClassName + "." + NamesOfEntities.MatchInterfaceName(patternName); String matchesType = "GRGEN_LIBGR.IMatchesExact<" + matchType + ">" ; if(matchingPattern.PatternGraph.Package != null) { sb.AppendFrontFormat("namespace {0}\n", matchingPattern.PatternGraph.Package); sb.AppendFront("{\n"); sb.Indent(); } sb.AppendFront("/// <summary>\n"); sb.AppendFront("/// An object representing an executable rule - same as IAction, but with exact types and distinct parameters.\n"); sb.AppendFront("/// </summary>\n"); sb.AppendFrontFormat("public interface {0}\n", actionInterfaceName); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("/// <summary> same as IAction.Match, but with exact types and distinct parameters. </summary>\n"); sb.AppendFrontFormat("{0} Match(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int maxMatches{1});\n", matchesType, inParameters); sb.AppendFront("/// <summary> same as IAction.Modify, but with exact types and distinct parameters. </summary>\n"); sb.AppendFrontFormat("void Modify(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} match{1});\n", matchType, outParameters); sb.AppendFront("/// <summary> same as IAction.ModifyAll, but with exact types and distinct parameters. </summary>\n"); sb.AppendFrontFormat("void ModifyAll(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, {0} matches{1});\n", matchesType, allParameters); sb.AppendFront("/// <summary> same as IAction.Apply, but with exact types and distinct parameters; returns true if applied </summary>\n"); sb.AppendFrontFormat("bool Apply(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1});\n", inParameters, refParameters); sb.AppendFront("/// <summary> same as IAction.ApplyAll, but with exact types and distinct parameters; returns the number of matches found/applied. </summary>\n"); sb.AppendFrontFormat("int ApplyAll(int maxMatches, GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0}{1});\n", inParameters, allParameters); sb.AppendFront("/// <summary> same as IAction.ApplyStar, but with exact types and distinct parameters. </summary>\n"); sb.AppendFrontFormat("bool ApplyStar(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0});\n", inParameters); sb.AppendFront("/// <summary> same as IAction.ApplyPlus, but with exact types and distinct parameters. </summary>\n"); sb.AppendFrontFormat("bool ApplyPlus(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv{0});\n", inParameters); sb.AppendFront("/// <summary> same as IAction.ApplyMinMax, but with exact types and distinct parameters. </summary>\n"); sb.AppendFrontFormat("bool ApplyMinMax(GRGEN_LIBGR.IActionExecutionEnvironment actionEnv, int min, int max{0});\n", inParameters); sb.Unindent(); sb.AppendFront("}\n"); if(matchingPattern.PatternGraph.Package != null) { sb.Unindent(); sb.AppendFront("}\n"); } sb.AppendFront("\n"); }
/// <summary> /// Parallelize the scheduled search plan to the branching factor, /// splitting it at the first loop into a header part and a body part /// </summary> public void ParallelizeHeadBody(LGSPRulePattern rulePattern) { Debug.Assert(rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents.Length == 1); ScheduledSearchPlan ssp = rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents[0]; int indexToSplitAt = 0; for(int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; if(so.Type == SearchOperationType.Lookup || so.Type == SearchOperationType.Incident || so.Type == SearchOperationType.Incoming || so.Type == SearchOperationType.Outgoing || so.Type == SearchOperationType.PickFromStorage || so.Type == SearchOperationType.PickFromStorageDependent || so.Type == SearchOperationType.PickFromIndex || so.Type == SearchOperationType.PickFromIndexDependent) { indexToSplitAt = i; break; } } rulePattern.patternGraph.parallelizedSchedule = new ScheduledSearchPlan[2]; List<SearchOperation> headOperations = new List<SearchOperation>(); List<SearchOperation> bodyOperations = new List<SearchOperation>(); for(int i = 0; i < rulePattern.Inputs.Length; ++i) { if(rulePattern.Inputs[i] is VarType) // those don't appear in the schedule, they are only extracted into the search program { VarType varType = (VarType)rulePattern.Inputs[i]; String varName = rulePattern.InputNames[i]; PatternVariable dummy = new PatternVariable(varType, varName, varName, i, false, null); headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar, dummy, null, 0)); bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar, dummy, null, 0)); } } for(int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; if(i < indexToSplitAt) { SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; clone.Isomorphy.LockForAllThreads = true; headOperations.Add(clone); switch(so.Type) { // the target binding looping operations can't appear in the header, so we don't treat them here // the non-target binding operations are completely handled by just adding them, happended already above // the target binding non-looping operations are handled below, // by parallel preset writing in the header and reading in the body // with exception of def, its declaration and initializion is just re-executed in the body // some presets can't appear in an action header, they are thus not taken care of case SearchOperationType.ActionPreset: case SearchOperationType.MapWithStorage: case SearchOperationType.MapWithStorageDependent: case SearchOperationType.Cast: case SearchOperationType.Assign: case SearchOperationType.Identity: case SearchOperationType.ImplicitSource: case SearchOperationType.ImplicitTarget: case SearchOperationType.Implicit: headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPreset, (SearchPlanNode)so.Element, so.SourceSPNode, 0)); bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPreset, (SearchPlanNode)so.Element, so.SourceSPNode, 0)); break; case SearchOperationType.AssignVar: headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar, (PatternVariable)so.Element, so.SourceSPNode, 0)); bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar, (PatternVariable)so.Element, so.SourceSPNode, 0)); break; case SearchOperationType.DefToBeYieldedTo: bodyOperations.Add((SearchOperation)so.Clone()); break; } } else if(i == indexToSplitAt) { SearchOperation cloneHead = (SearchOperation)so.Clone(); headOperations.Add(cloneHead); SearchOperation cloneBody = (SearchOperation)so.Clone(); cloneBody.Isomorphy.Parallel = true; bodyOperations.Add(cloneBody); switch(so.Type) { case SearchOperationType.Lookup: cloneHead.Type = SearchOperationType.SetupParallelLookup; cloneBody.Type = SearchOperationType.ParallelLookup; break; case SearchOperationType.Incident: cloneHead.Type = SearchOperationType.SetupParallelIncident; cloneBody.Type = SearchOperationType.ParallelIncident; break; case SearchOperationType.Incoming: cloneHead.Type = SearchOperationType.SetupParallelIncoming; cloneBody.Type = SearchOperationType.ParallelIncoming; break; case SearchOperationType.Outgoing: cloneHead.Type = SearchOperationType.SetupParallelOutgoing; cloneBody.Type = SearchOperationType.ParallelOutgoing; break; case SearchOperationType.PickFromStorage: cloneHead.Type = SearchOperationType.SetupParallelPickFromStorage; cloneBody.Type = SearchOperationType.ParallelPickFromStorage; break; case SearchOperationType.PickFromStorageDependent: cloneHead.Type = SearchOperationType.SetupParallelPickFromStorageDependent; cloneBody.Type = SearchOperationType.ParallelPickFromStorageDependent; break; case SearchOperationType.PickFromIndex: cloneHead.Type = SearchOperationType.SetupParallelPickFromIndex; cloneBody.Type = SearchOperationType.ParallelPickFromIndex; break; case SearchOperationType.PickFromIndexDependent: cloneHead.Type = SearchOperationType.SetupParallelPickFromIndexDependent; cloneBody.Type = SearchOperationType.ParallelPickFromIndexDependent; break; } } else { SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; bodyOperations.Add(clone); if(clone.Element is PatternCondition) SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression); } } ScheduledSearchPlan headSsp = new ScheduledSearchPlan( rulePattern.patternGraph, headOperations.ToArray(), headOperations.Count > 0 ? headOperations[0].CostToEnd : 0); rulePattern.patternGraph.parallelizedSchedule[0] = headSsp; ScheduledSearchPlan bodySsp = new ScheduledSearchPlan( rulePattern.patternGraph, bodyOperations.ToArray(), bodyOperations.Count > 0 ? bodyOperations[0].CostToEnd : 0); rulePattern.patternGraph.parallelizedSchedule[1] = bodySsp; ParallelizeNegativeIndependent(bodySsp); ParallelizeAlternativeIterated(rulePattern.patternGraph); ParallelizeYielding(rulePattern.patternGraph); }
/// <summary> /// Parallelize the scheduled search plan to the branching factor, /// splitting it at the first loop into a header part and a body part /// </summary> public static void ParallelizeHeadBody(LGSPRulePattern rulePattern) { Debug.Assert(rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents.Length == 1); ScheduledSearchPlan ssp = rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents[0]; int indexToSplitAt = 0; for (int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; if (so.Type == SearchOperationType.Lookup || so.Type == SearchOperationType.Incident || so.Type == SearchOperationType.Incoming || so.Type == SearchOperationType.Outgoing || so.Type == SearchOperationType.PickFromStorage || so.Type == SearchOperationType.PickFromStorageDependent || so.Type == SearchOperationType.PickFromIndex || so.Type == SearchOperationType.PickFromIndexDependent) { indexToSplitAt = i; break; } } rulePattern.patternGraph.parallelizedSchedule = new ScheduledSearchPlan[2]; List <SearchOperation> headOperations = new List <SearchOperation>(); List <SearchOperation> bodyOperations = new List <SearchOperation>(); for (int i = 0; i < rulePattern.Inputs.Length; ++i) { if (rulePattern.Inputs[i] is VarType) // those don't appear in the schedule, they are only extracted into the search program { VarType varType = (VarType)rulePattern.Inputs[i]; String varName = rulePattern.InputNames[i]; PatternVariable dummy = new PatternVariable(varType, varName, varName, i, false, null); headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar, dummy, null, 0)); bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar, dummy, null, 0)); } } for (int i = 0; i < ssp.Operations.Length; ++i) { SearchOperation so = ssp.Operations[i]; if (i < indexToSplitAt) { SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; clone.Isomorphy.LockForAllThreads = true; headOperations.Add(clone); switch (so.Type) { // the target binding looping operations can't appear in the header, so we don't treat them here // the non-target binding operations are completely handled by just adding them, happended already above // the target binding non-looping operations are handled below, // by parallel preset writing in the header and reading in the body // with exception of def, its declaration and initializion is just re-executed in the body // some presets can't appear in an action header, they are thus not taken care of case SearchOperationType.ActionPreset: case SearchOperationType.MapWithStorage: case SearchOperationType.MapWithStorageDependent: case SearchOperationType.Cast: case SearchOperationType.Assign: case SearchOperationType.Identity: case SearchOperationType.ImplicitSource: case SearchOperationType.ImplicitTarget: case SearchOperationType.Implicit: headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPreset, (SearchPlanNode)so.Element, so.SourceSPNode, 0)); bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPreset, (SearchPlanNode)so.Element, so.SourceSPNode, 0)); break; case SearchOperationType.AssignVar: headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar, (PatternVariable)so.Element, so.SourceSPNode, 0)); bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar, (PatternVariable)so.Element, so.SourceSPNode, 0)); break; case SearchOperationType.DefToBeYieldedTo: bodyOperations.Add((SearchOperation)so.Clone()); break; } } else if (i == indexToSplitAt) { SearchOperation cloneHead; SearchOperation cloneBody; switch (so.Type) { case SearchOperationType.Lookup: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelLookup); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelLookup); break; case SearchOperationType.Incident: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncident); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncident); break; case SearchOperationType.Incoming: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncoming); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncoming); break; case SearchOperationType.Outgoing: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelOutgoing); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelOutgoing); break; case SearchOperationType.PickFromStorage: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorage); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorage); break; case SearchOperationType.PickFromStorageDependent: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorageDependent); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorageDependent); break; case SearchOperationType.PickFromIndex: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndex); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndex); break; case SearchOperationType.PickFromIndexDependent: cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndexDependent); cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndexDependent); break; default: // failure, operation at this index cannot be parallelized/parallelization not supported cloneHead = null; cloneBody = null; break; } headOperations.Add(cloneHead); cloneBody.Isomorphy.Parallel = true; bodyOperations.Add(cloneBody); } else { SearchOperation clone = (SearchOperation)so.Clone(); clone.Isomorphy.Parallel = true; bodyOperations.Add(clone); if (clone.Element is PatternCondition) { SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression); } } } ScheduledSearchPlan headSsp = new ScheduledSearchPlan( rulePattern.patternGraph, headOperations.ToArray(), headOperations.Count > 0 ? headOperations[0].CostToEnd : 0); rulePattern.patternGraph.parallelizedSchedule[0] = headSsp; ScheduledSearchPlan bodySsp = new ScheduledSearchPlan( rulePattern.patternGraph, bodyOperations.ToArray(), bodyOperations.Count > 0 ? bodyOperations[0].CostToEnd : 0); rulePattern.patternGraph.parallelizedSchedule[1] = bodySsp; ParallelizeNegativeIndependent(bodySsp); ParallelizeAlternativeIterated(rulePattern.patternGraph); ParallelizeYielding(rulePattern.patternGraph); }
/// <summary> /// Builds search program from scheduled search plan at given index in pattern graph of the action rule pattern /// </summary> public static SearchProgram BuildSearchProgram( IGraphModel model, LGSPRulePattern rulePattern, int index, string nameOfSearchProgram, bool parallelized, bool emitProfiling) { PatternGraph patternGraph = rulePattern.patternGraph; String rulePatternClassName = NamesOfEntities.RulePatternClassName(rulePattern.name, rulePattern.PatternGraph.Package, false); // filter out parameters which are implemented by lookup due to maybe null unfolding // and suffix matcher method name by missing parameters which get computed by lookup here string[] parameterTypes; string[] parameterNames; String name; GetFilteredParametersAndSuffixedMatcherName( rulePattern, patternGraph, parallelized ? 0 : index, out parameterTypes, out parameterNames, out name); SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder( SearchProgramType.Action, model, rulePatternClassName, rulePattern.patternGraph.Package != null ? rulePattern.patternGraph.Package + "::" + rulePattern.name : rulePattern.name, parameterNames, parameterTypes, patternGraph, emitProfiling, parallelized, index ); // this is the all presets available method (index 0) and there are presets which may be null? // -> collect data for missing preset calls List <String[]> paramTypesList = null; List <String[]> paramNamesList = null; List <String> suffixedMatcherNameList = null; if (patternGraph.schedules.Length > 1 && index == 0) { paramTypesList = new List <String[]>(); paramNamesList = new List <String[]>(); suffixedMatcherNameList = new List <String>(); for (int i = 0; i < patternGraph.schedules.Length; ++i) { String[] paramTypes; String[] paramNames; String suffixedMatcherName; GetFilteredParametersAndSuffixedMatcherName( rulePattern, patternGraph, i, out paramTypes, out paramNames, out suffixedMatcherName); paramTypesList.Add(paramTypes); paramNamesList.Add(paramNames); suffixedMatcherNameList.Add(suffixedMatcherName); } } // build outermost search program operation, create the list anchor starting its program bool containsSubpatterns = patternGraph.embeddedGraphsPlusInlined.Length > 0 || patternGraph.iteratedsPlusInlined.Length > 0 || patternGraph.alternativesPlusInlined.Length > 0; SearchProgram searchProgram; if (parallelized) { if (index == 1) { List <String> matchingPatternClassTypeNames = new List <String>(); List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >(); ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph); searchProgram = new SearchProgramOfActionParallelizationBody( rulePatternClassName, patternGraph.name, name + "_parallelized_body", rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, containsSubpatterns, builder.wasIndependentInlined(patternGraph, index), matchingPatternClassTypeNames, nestedIndependents, emitProfiling, patternGraph.PackagePrefixedName); } else // index == 0 { searchProgram = new SearchProgramOfActionParallelizationHead( rulePatternClassName, patternGraph.name, parameterTypes, parameterNames, name + "_parallelized", emitProfiling, patternGraph.PackagePrefixedName); } } else { List <String> matchingPatternClassTypeNames = new List <String>(); List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >(); ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph); searchProgram = new SearchProgramOfAction( rulePatternClassName, patternGraph.name, parameterTypes, parameterNames, name, rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, containsSubpatterns, builder.wasIndependentInlined(patternGraph, 0), matchingPatternClassTypeNames, nestedIndependents, emitProfiling, patternGraph.PackagePrefixedName, patternGraph.maybeNullElementNames, suffixedMatcherNameList, paramNamesList); } searchProgram.OperationsList = new SearchProgramList(searchProgram); SearchProgramOperation insertionPoint = searchProgram.OperationsList; if (!parallelized || index == 0) { insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph); } // start building with first operation in scheduled search plan insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram( 0, insertionPoint); return(searchProgram); }
void GenerateKeepSameFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable, bool sameAsFirst) { String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name; String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name); String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">"; String filterName = sameAsFirst ? "keepSameAsFirst_" + filterVariable : "keepSameAsLast_" + filterVariable; source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", rulePattern.name, filterName, matchesListType); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName); if(sameAsFirst) { source.AppendFront("int pos = 0 + 1;\n"); source.AppendFrontFormat("while(pos < matchesArray.Count && matchesArray[pos].{0} == matchesArray[0].{0})\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable)); source.AppendFront("{\n"); source.AppendFront("\t++pos;\n"); source.AppendFront("}\n"); source.AppendFront("for(; pos < matchesArray.Count; ++pos)\n"); source.AppendFront("{\n"); source.AppendFront("\tmatchesArray[pos] = null;\n"); source.AppendFront("}\n"); } else { source.AppendFront("int pos = matchesArray.Count-1 - 1;\n"); source.AppendFrontFormat("while(pos >= 0 && matchesArray[pos].{0} == matchesArray[matchesArray.Count-1].{0})\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable)); source.AppendFront("{\n"); source.AppendFront("\t--pos;\n"); source.AppendFront("}\n"); source.AppendFront("for(; pos >= 0; --pos)\n"); source.AppendFront("{\n"); source.AppendFront("\tmatchesArray[pos] = null;\n"); source.AppendFront("}\n"); } source.AppendFront("matches.FromList();\n"); source.Unindent(); source.AppendFront("}\n"); }
/// <summary> /// Builds search program from scheduled search plan at given index in pattern graph of the action rule pattern /// </summary> public SearchProgram BuildSearchProgram( IGraphModel model, LGSPRulePattern rulePattern, int index, string nameOfSearchProgram, bool parallelized, bool emitProfiling) { PatternGraph patternGraph = rulePattern.patternGraph; this.model = model; patternGraphWithNestingPatterns = new Stack<PatternGraph>(); patternGraphWithNestingPatterns.Push(patternGraph); this.parallelized = parallelized; isoSpaceNeverAboveMaxIsoSpace = patternGraphWithNestingPatterns.Peek().maxIsoSpace < (int)LGSPElemFlags.MAX_ISO_SPACE; isNegative = false; isNestedInNegative = false; rulePatternClassName = NamesOfEntities.RulePatternClassName(rulePattern.name, rulePattern.PatternGraph.Package, false); this.emitProfiling = emitProfiling; packagePrefixedActionName = rulePattern.patternGraph.Package != null ? rulePattern.patternGraph.Package + "::" + rulePattern.name : rulePattern.name; firstLoopPassed = false; // filter out parameters which are implemented by lookup due to maybe null unfolding // and suffix matcher method name by missing parameters which get computed by lookup here String name; GetFilteredParametersAndSuffixedMatcherName( rulePattern, patternGraph, parallelized ? 0 : index, out parameterTypes, out parameterNames, out name); // this is the all presets available method (index 0) and there are presets which may be null? // -> collect data for missing preset calls List<String[]> paramTypesList = null; List<String[]> paramNamesList = null; List<String> suffixedMatcherNameList = null; if(patternGraph.schedules.Length>1 && index==0) { paramTypesList = new List<String[]>(); paramNamesList = new List<String[]>(); suffixedMatcherNameList = new List<String>(); for(int i=0; i<patternGraph.schedules.Length; ++i) { String[] paramTypes; String[] paramNames; String suffixedMatcherName; GetFilteredParametersAndSuffixedMatcherName( rulePattern, patternGraph, i, out paramTypes, out paramNames, out suffixedMatcherName); paramTypesList.Add(paramTypes); paramNamesList.Add(paramNames); suffixedMatcherNameList.Add(suffixedMatcherName); } } // build outermost search program operation, create the list anchor starting its program bool containsSubpatterns = patternGraph.embeddedGraphsPlusInlined.Length > 0 || patternGraph.iteratedsPlusInlined.Length > 0 || patternGraph.alternativesPlusInlined.Length > 0; SearchProgram searchProgram; if(parallelized) { if(index == 1) { searchProgram = new SearchProgramOfActionParallelizationBody( rulePatternClassName, patternGraph.name, name + "_parallelized_body", rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, containsSubpatterns, wasIndependentInlined(patternGraph, index), emitProfiling, patternGraph.PackagePrefixedName); } else // index == 0 { searchProgram = new SearchProgramOfActionParallelizationHead( rulePatternClassName, patternGraph.name, parameterTypes, parameterNames, name + "_parallelized", emitProfiling, patternGraph.PackagePrefixedName); } } else { searchProgram = new SearchProgramOfAction( rulePatternClassName, patternGraph.name, parameterTypes, parameterNames, name, rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath, containsSubpatterns, wasIndependentInlined(patternGraph, indexOfSchedule), emitProfiling, patternGraph.PackagePrefixedName, patternGraph.maybeNullElementNames, suffixedMatcherNameList, paramNamesList); } searchProgram.OperationsList = new SearchProgramList(searchProgram); SearchProgramOperation insertionPoint = searchProgram.OperationsList; if(!parallelized || index == 0) insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph); // start building with first operation in scheduled search plan indexOfSchedule = index; insertionPoint = BuildScheduledSearchPlanOperationIntoSearchProgram( 0, insertionPoint); patternGraphWithNestingPatterns.Pop(); return searchProgram; }
private static void GenerateOrderByFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable, bool ascending) { String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name; String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name); String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">"; String filterName = ascending ? "orderAscendingBy_" + filterVariable : "orderDescendingBy_" + filterVariable; source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", rulePattern.name, filterName, matchesListType); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName); source.AppendFrontFormat("matchesArray.Sort(new Comparer_{0}_{1}());\n", rulePattern.name, filterName); source.AppendFront("matches.FromList();\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFrontFormat("class Comparer_{0}_{1} : Comparer<{2}>\n", rulePattern.name, filterName, matchInterfaceName); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("public override int Compare({0} left, {0} right)\n", matchInterfaceName); source.AppendFront("{\n"); source.Indent(); if(ascending) source.AppendFrontFormat("return left.{0}.CompareTo(right.{0});\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable)); else source.AppendFrontFormat("return -left.{0}.CompareTo(right.{0});\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable)); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); }
void GenerateGroupByFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable) { String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name; String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name); String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">"; String filterName = "groupBy_" + filterVariable; if(true) // does the type of the variable to group-by support ordering? then order, is more efficient than equality comparisons { source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", rulePattern.name, filterName, matchesListType); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName); source.AppendFrontFormat("matchesArray.Sort(new Comparer_{0}_{1}());\n", rulePattern.name, filterName); source.AppendFront("matches.FromList();\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFrontFormat("class Comparer_{0}_{1} : Comparer<{2}>\n", rulePattern.name, filterName, matchInterfaceName); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("public override int Compare({0} left, {0} right)\n", matchInterfaceName); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("return left.{0}.CompareTo(right.{0});\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable)); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); } else { // ensure that if two elements are equal, they are neighbours or only separated by equal elements // not needed yet, as of now we only support numerical types and string, that support ordering in addition to equality comparison /*List<T> matchesArray; for(int i = 0; i < matchesArray.Count - 1; ++i) { for(int j = i + 1; j < matchesArray.Count; ++j) { if(matchesArray[i] == matchesArray[j]) { T tmp = matchesArray[i + 1]; matchesArray[i + 1] = matchesArray[j]; matchesArray[j] = tmp; break; } } }*/ } }
private static void GenerateAutomorphyFilter(SourceBuilder source, LGSPRulePattern rulePattern) { String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name; String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name); String matchClassName = rulePatternClassName + "." + NamesOfEntities.MatchClassName(rulePattern.name); String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">"; String filterName = "auto"; source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", rulePattern.name, filterName, matchesListType); source.AppendFront("{\n"); source.Indent(); source.AppendFront("if(matches.Count < 2)\n"); source.AppendFront("\treturn;\n"); source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName); source.AppendFrontFormat("if(matches.Count < 5 || {0}.Instance.patternGraph.nodes.Length + {0}.Instance.patternGraph.edges.Length < 1)\n", rulePatternClassName); source.AppendFront("{\n"); source.Indent(); source.AppendFront("for(int i = 0; i < matchesArray.Count; ++i)\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("if(matchesArray[i] == null)\n"); source.AppendFront("\tcontinue;\n"); source.AppendFront("for(int j = i + 1; j < matchesArray.Count; ++j)\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("if(matchesArray[j] == null)\n"); source.AppendFront("\tcontinue;\n"); source.AppendFront("if(GRGEN_LIBGR.SymmetryChecker.AreSymmetric(matchesArray[i], matchesArray[j], procEnv.graph))\n"); source.AppendFront("\tmatchesArray[j] = null;\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFront("else\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("Dictionary<int, {0}> foundMatchesOfSameMainPatternHash = new Dictionary<int, {0}>();\n", matchClassName); source.AppendFront("for(int i = 0; i < matchesArray.Count; ++i)\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("{0} match = ({0})matchesArray[i];\n", matchClassName); source.AppendFront("int duplicateMatchHash = 0;\n"); source.AppendFront("for(int j = 0; j < match.NumberOfNodes; ++j) duplicateMatchHash ^= match.getNodeAt(j).GetHashCode();\n"); source.AppendFront("for(int j = 0; j < match.NumberOfEdges; ++j) duplicateMatchHash ^= match.getEdgeAt(j).GetHashCode();\n"); source.AppendFront("bool contained = foundMatchesOfSameMainPatternHash.ContainsKey(duplicateMatchHash);\n"); source.AppendFront("if(contained)\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("{0} duplicateMatchCandidate = foundMatchesOfSameMainPatternHash[duplicateMatchHash];\n", matchClassName); source.AppendFront("do\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("if(GRGEN_LIBGR.SymmetryChecker.AreSymmetric(match, duplicateMatchCandidate, procEnv.graph))\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront("matchesArray[i] = null;\n"); source.AppendFrontFormat("goto label_auto_{0};\n", rulePatternClassName.Replace('.', '_')); source.Unindent(); source.AppendFront("}\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFront("while((duplicateMatchCandidate = duplicateMatchCandidate.nextWithSameHash) != null);\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFront("if(!contained)\n"); source.AppendFront("\tfoundMatchesOfSameMainPatternHash[duplicateMatchHash] = match;\n"); source.AppendFront("else\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("{0} duplicateMatchCandidate = foundMatchesOfSameMainPatternHash[duplicateMatchHash];\n", matchClassName); source.AppendFront("while(duplicateMatchCandidate.nextWithSameHash != null) duplicateMatchCandidate = duplicateMatchCandidate.nextWithSameHash;\n"); source.AppendFront("duplicateMatchCandidate.nextWithSameHash = match;\n"); source.Unindent(); source.AppendFront("}\n"); source.AppendFormat("label_auto_{0}: ;\n", rulePatternClassName.Replace('.', '_')); source.Unindent(); source.AppendFront("}\n"); source.AppendFrontFormat("foreach({0} toClean in foundMatchesOfSameMainPatternHash.Values) toClean.CleanNextWithSameHash();\n", matchClassName); source.Unindent(); source.AppendFront("}\n"); source.AppendFront("matches.FromList();\n"); source.Unindent(); source.AppendFront("}\n"); }
public void GenerateFilters(SourceBuilder source, LGSPRulePattern rulePattern) { foreach(IFilter f in rulePattern.Filters) { if(f is IFilterAutoGenerated) { IFilterAutoGenerated filter = (IFilterAutoGenerated)f; if(filter.Package != null) { source.AppendFrontFormat("namespace {0}\n", filter.Package); source.AppendFront("{\n"); source.Indent(); } source.AppendFront("public partial class MatchFilters\n"); source.AppendFront("{\n"); source.Indent(); if(filter.Name == "auto") GenerateAutomorphyFilter(source, rulePattern); else { if(filter.Name == "orderAscendingBy") GenerateOrderByFilter(source, rulePattern, filter.Entity, true); if(filter.Name == "orderDescendingBy") GenerateOrderByFilter(source, rulePattern, filter.Entity, false); if(filter.Name == "groupBy") GenerateGroupByFilter(source, rulePattern, filter.Entity); if(filter.Name == "keepSameAsFirst") GenerateKeepSameFilter(source, rulePattern, filter.Entity, true); if(filter.Name == "keepSameAsLast") GenerateKeepSameFilter(source, rulePattern, filter.Entity, false); if(filter.Name == "keepOneForEach") GenerateKeepOneForEachFilter(source, rulePattern, filter.Entity); } source.Unindent(); source.AppendFront("}\n"); if(filter.Package != null) { source.Unindent(); source.AppendFront("}\n"); } } } }
public void GenerateFilterStubs(SourceBuilder source, LGSPRulePattern rulePattern) { String rulePatternClassName = rulePattern.GetType().Name; String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name); String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">"; foreach(IFilter filter in rulePattern.Filters) { if(filter is IFilterAutoGenerated) continue; IFilterFunction filterFunction = (IFilterFunction)filter; if(!filterFunction.IsExternal) continue; if(filter.Package != null) { source.AppendFrontFormat("namespace {0}\n", filter.Package); source.AppendFront("{\n"); source.Indent(); } source.AppendFront("public partial class MatchFilters\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("//public static void Filter_{0}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {1} matches", filter.Name, matchesListType); for(int i = 0; i < filterFunction.Inputs.Length; ++i) { source.AppendFormat(", {0} {1}", TypesHelper.TypeName(filterFunction.Inputs[i]), filterFunction.InputNames[i]); } source.Append(")\n"); source.Unindent(); source.AppendFront("}\n"); if(filter.Package != null) { source.Unindent(); source.AppendFront("}\n"); } } }
/// <summary> /// Generates matcher class head source code for the pattern of the rulePattern into given source builder /// isInitialStatic tells whether the initial static version or a dynamic version after analyze is to be generated. /// </summary> void GenerateMatcherClassHeadAction(SourceBuilder sb, LGSPRulePattern rulePattern, bool isInitialStatic, SearchProgram searchProgram) { PatternGraph patternGraph = (PatternGraph)rulePattern.PatternGraph; String namePrefix = (isInitialStatic ? "" : "Dyn") + "Action_"; String className = namePrefix + rulePattern.name; String rulePatternClassName = rulePattern.GetType().Name; String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name; String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name; String actionInterfaceName = "IAction_" + rulePattern.name; if(patternGraph.Package != null) { sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package); sb.AppendFront("{\n"); sb.Indent(); } sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPAction, " + "GRGEN_LIBGR.IAction, " + actionInterfaceName + "\n"); sb.AppendFront("{\n"); sb.Indent(); // class level sb.AppendFront("public " + className + "() {\n"); sb.Indent(); // method body level sb.AppendFront("_rulePattern = " + rulePatternClassName + ".Instance;\n"); sb.AppendFront("patternGraph = _rulePattern.patternGraph;\n"); if(rulePattern.patternGraph.branchingFactor < 2) { sb.AppendFront("DynamicMatch = myMatch;\n"); if(!isInitialStatic) sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name); } else { sb.AppendFront("if(Environment.ProcessorCount == 1)\n"); sb.AppendFront("{\n"); sb.AppendFront("\tDynamicMatch = myMatch;\n"); if(!isInitialStatic) sb.AppendFrontFormat("\tGRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name); sb.AppendFront("}\n"); sb.AppendFront("else\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("DynamicMatch = myMatch_parallelized;\n"); if(!isInitialStatic) sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch_parallelized;\n", rulePattern.name); sb.AppendFrontFormat("numWorkerThreads = GRGEN_LGSP.WorkerPool.EnsurePoolSize({0});\n", rulePattern.patternGraph.branchingFactor); sb.AppendFrontFormat("parallelTaskMatches = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>[numWorkerThreads];\n", matchClassName, matchInterfaceName); sb.AppendFront("moveHeadAfterNodes = new List<GRGEN_LGSP.LGSPNode>[numWorkerThreads];\n"); sb.AppendFront("moveHeadAfterEdges = new List<GRGEN_LGSP.LGSPEdge>[numWorkerThreads];\n"); sb.AppendFront("moveOutHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n"); sb.AppendFront("moveInHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n"); sb.AppendFront("for(int i=0; i<numWorkerThreads; ++i)\n"); sb.AppendFront("{\n"); sb.Indent(); sb.AppendFront("moveHeadAfterNodes[i] = new List<GRGEN_LGSP.LGSPNode>();\n"); sb.AppendFront("moveHeadAfterEdges[i] = new List<GRGEN_LGSP.LGSPEdge>();\n"); sb.AppendFront("moveOutHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n"); sb.AppendFront("moveInHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("for(int i=0; i<parallelTaskMatches.Length; ++i)\n"); sb.AppendFrontFormat("\tparallelTaskMatches[i] = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>(this);\n", matchClassName, matchInterfaceName); sb.Unindent(); sb.AppendFront("}\n"); } sb.AppendFrontFormat("ReturnArray = new object[{0}];\n", rulePattern.Outputs.Length); sb.AppendFront("matches = new GRGEN_LGSP.LGSPMatchesList<" + matchClassName +", " + matchInterfaceName + ">(this);\n"); sb.Unindent(); // class level sb.AppendFront("}\n\n"); sb.AppendFront("public " + rulePatternClassName + " _rulePattern;\n"); sb.AppendFront("public override GRGEN_LGSP.LGSPRulePattern rulePattern { get { return _rulePattern; } }\n"); sb.AppendFront("public override string Name { get { return \"" + rulePattern.name + "\"; } }\n"); sb.AppendFront("private GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + "> matches;\n\n"); if (isInitialStatic) { sb.AppendFront("public static " + className + " Instance { get { return instance; } set { instance = value; } }\n"); sb.AppendFront("private static " + className + " instance = new " + className + "();\n"); } GenerateIndependentsMatchObjects(sb, rulePattern, patternGraph); sb.AppendFront("\n"); GenerateParallelizationSetupAsNeeded(sb, rulePattern, searchProgram); }
void GenerateKeepOneForEachFilter(SourceBuilder source, LGSPRulePattern rulePattern, String filterVariable) { String rulePatternClassName = TypesHelper.GetPackagePrefixDot(rulePattern.PatternGraph.Package) + rulePattern.GetType().Name; String matchInterfaceName = rulePatternClassName + "." + NamesOfEntities.MatchInterfaceName(rulePattern.name); String matchesListType = "GRGEN_LIBGR.IMatchesExact<" + matchInterfaceName + ">"; String filterName = "keepOneForEach_" + filterVariable; source.AppendFrontFormat("public static void Filter_{0}_{1}(GRGEN_LGSP.LGSPGraphProcessingEnvironment procEnv, {2} matches)\n", rulePattern.name, filterName, matchesListType); source.AppendFront("{\n"); source.Indent(); source.AppendFrontFormat("List<{0}> matchesArray = matches.ToList();\n", matchInterfaceName); source.AppendFront("int cmpPos = 0;\n"); source.AppendFront("int pos = 0 + 1;\n"); source.AppendFront("for(; pos < matchesArray.Count; ++pos)\n"); source.AppendFront("{\n"); source.AppendFrontFormat("\tif(matchesArray[pos].{0} == matchesArray[cmpPos].{0})\n", NamesOfEntities.MatchName(filterVariable, EntityType.Variable)); source.AppendFront("\t\tmatchesArray[pos] = null;\n"); source.AppendFront("\telse\n"); source.AppendFront("\t\tcmpPos = pos;\n"); source.AppendFront("}\n"); source.AppendFront("matches.FromList();\n"); source.Unindent(); source.AppendFront("}\n"); }
void GenerateParallelizationSetupAsNeeded(SourceBuilder sb, LGSPRulePattern rulePattern, SearchProgram searchProgram) { if(rulePattern.patternGraph.branchingFactor < 2) return; foreach(SearchOperation so in rulePattern.patternGraph.parallelizedSchedule[0].Operations) { switch(so.Type) { case SearchOperationType.WriteParallelPreset: if(so.Element is SearchPlanNodeNode) sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name)); else //SearchPlanEdgeNode sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); break; case SearchOperationType.WriteParallelPresetVar: sb.AppendFrontFormat("{0} {1};\n", TypesHelper.TypeName(((PatternVariable)so.Element).Type), NamesOfEntities.IterationParallelizationParallelPresetCandidate(((PatternVariable)so.Element).Name)); break; case SearchOperationType.SetupParallelLookup: if(so.Element is SearchPlanNodeNode) { sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanNodeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name)); } else { sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); } break; case SearchOperationType.SetupParallelPickFromStorage: if(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("set") || TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("map")) { sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model), TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } else { sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } break; case SearchOperationType.SetupParallelPickFromStorageDependent: if(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("set") || TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("map")) { sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model), TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } else { sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); } break; case SearchOperationType.SetupParallelPickFromIndex: sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ? ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType : ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); break; case SearchOperationType.SetupParallelPickFromIndexDependent: sb.AppendFrontFormat("IEnumerator<{0}> {1};\n", TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ? ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType : ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType), NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name)); break; case SearchOperationType.SetupParallelIncoming: case SearchOperationType.SetupParallelOutgoing: sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); break; case SearchOperationType.SetupParallelIncident: sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); sb.AppendFrontFormat("int {0};\n", NamesOfEntities.IterationParallelizationDirectionRunCounterVariable(((SearchPlanEdgeNode)so.Element).PatternElement.Name)); break; } } sb.AppendFront("\n"); String rulePatternClassName = rulePattern.GetType().Name; String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name; String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name; sb.AppendFront("private static GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + ">[] parallelTaskMatches;\n"); sb.AppendFront("private static int numWorkerThreads;\n"); sb.AppendFront("private static int iterationNumber;\n"); sb.AppendFront("private static int iterationLock;\n"); sb.AppendFront("[ThreadStatic] private static int currentIterationNumber;\n"); sb.AppendFront("[ThreadStatic] private static int threadId;\n"); sb.AppendFront("private static GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnvParallel;\n"); sb.AppendFront("private static int maxMatchesParallel;\n"); sb.AppendFront("private static bool maxMatchesFound = false;\n"); sb.AppendFront("private static List<GRGEN_LGSP.LGSPNode>[] moveHeadAfterNodes;\n"); sb.AppendFront("private static List<GRGEN_LGSP.LGSPEdge>[] moveHeadAfterEdges;\n"); sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveOutHeadAfter;\n"); sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveInHeadAfter;\n"); sb.AppendFront("\n"); }
public void GetFilteredParametersAndSuffixedMatcherName( LGSPRulePattern rulePattern, PatternGraph patternGraph, int index, out String[] paramTypesArray, out String[] paramNamesArray, out String suffixedMatcherName) { List<String> paramTypes = new List<String>(); List<String> paramNames = new List<String>(); List<String> removedNames = new List<String>(); for(int i = 0; i < rulePattern.Inputs.Length; ++i) { String inputName = rulePattern.InputNames[i]; if(patternGraph.availabilityOfMaybeNullElements[index].ContainsKey(inputName) && !patternGraph.availabilityOfMaybeNullElements[index][inputName]) { removedNames.Add(rulePattern.InputNames[i]); } else { paramTypes.Add(TypesHelper.TypeName(rulePattern.Inputs[i])); paramNames.Add(rulePattern.InputNames[i]); } } paramTypesArray = new String[paramTypes.Count]; paramNamesArray = new String[paramNames.Count]; for(int i = 0; i < paramTypes.Count; ++i) { paramTypesArray[i] = paramTypes[i]; paramNamesArray[i] = paramNames[i]; } suffixedMatcherName = "myMatch"; foreach(String removedName in removedNames) { suffixedMatcherName += "_MissingPreset_"+removedName; } }