public void EmitRewritingRuleCountAllCallOrRuleAllCallNonRandom(SourceBuilder source) { // iterate through matches, use Modify on each, fire the next match event after the first if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarationsAllCall + "\n"); } String enumeratorName = "enum_" + ruleCallGen.seqRule.Id; source.AppendFront("IEnumerator<" + matchType + "> " + enumeratorName + " = " + matchesName + ".GetEnumeratorExact();\n"); source.AppendFront("while(" + enumeratorName + ".MoveNext())\n"); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = " + enumeratorName + ".Current;\n"); source.AppendFront("if(" + matchName + "!=" + matchesName + ".FirstExact) procEnv.RewritingNextMatch();\n"); if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarations + "\n"); } source.AppendFront(ruleCallGen.ruleName + ".Modify(procEnv, " + matchName + returnArguments + ");\n"); if (returnAssignments.Length != 0) { source.AppendFront(intermediateReturnAssignmentsAllCall + "\n"); } source.AppendFront("procEnv.PerformanceInfo.RewritesPerformed++;\n"); source.Unindent(); source.AppendFront("}\n"); if (returnAssignments.Length != 0) { source.AppendFront(returnAssignmentsAllCall + "\n"); } }
public void Explain(SourceBuilder sb, IGraphModel model) { foreach (SearchOperation searchOp in Operations) { searchOp.Explain(sb, model); } }
public override void Dump(SourceBuilder builder) { // first dump check builder.AppendFront("CheckCandidate ForType "); if (Type == CheckCandidateForTypeType.ByIsAllowedType) { builder.Append("ByIsAllowedType "); builder.AppendFormat("on {0} in {1} node:{2}\n", PatternElementName, RulePatternTypeName, IsNode); } else if (Type == CheckCandidateForTypeType.ByIsMyType) { builder.Append("ByIsMyType "); builder.AppendFormat("on {0} in {1} node:{2}\n", PatternElementName, TypeName, IsNode); } else // Type == CheckCandidateForTypeType.ByTypeID { builder.Append("ByTypeID "); builder.AppendFormat("on {0} ids:{1} node:{2}\n", PatternElementName, string.Join(",", TypeIDs), IsNode); } // then operations for case check failed if (CheckFailedOperations != null) { builder.Indent(); CheckFailedOperations.Dump(builder); builder.Unindent(); } }
public static void Explain(ScheduledSearchPlan ssp, SourceBuilder sb, IGraphModel model) { foreach (SearchOperation searchOp in ssp.Operations) { Explain(searchOp, sb, model); } }
public override void Emit(SourceBuilder sourceCode) { // emit initialization with element mapped from storage string variableContainingStorage = NamesOfEntities.Variable(StorageName); string variableContainingSourceElement = NamesOfEntities.CandidateVariable(SourcePatternElementName); string tempVariableForMapResult = NamesOfEntities.MapWithStorageTemporary(PatternElementName); sourceCode.AppendFrontFormat("if(!{0}.TryGetValue(({1}){2}, out {3})) ", variableContainingStorage, StorageKeyTypeName, variableContainingSourceElement, tempVariableForMapResult); // emit check failed code sourceCode.Append("{\n"); sourceCode.Indent(); CheckFailedOperations.Emit(sourceCode); sourceCode.Unindent(); sourceCode.AppendFront("}\n"); // assign the value to the candidate variable, cast it to the variable type string typeOfVariableContainingCandidate = "GRGEN_LGSP." + (IsNode ? "LGSPNode" : "LGSPEdge"); string variableContainingCandidate = NamesOfEntities.CandidateVariable(PatternElementName); sourceCode.AppendFrontFormat("{0} = ({1}){2};\n", variableContainingCandidate, typeOfVariableContainingCandidate, tempVariableForMapResult); }
public override void Emit(SourceBuilder sourceCode) { // open decision whether to fail sourceCode.AppendFront("if("); // fail if graph element contained within candidate was already matched // (previously on the pattern derivation path to another pattern element) // as this would cause a inter-pattern-homomorphic match string variableContainingCandidate = NamesOfEntities.CandidateVariable(PatternElementName); string isMatchedBySomeBit = "(uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED_BY_SOME_ENCLOSING_PATTERN"; if (!Always) { sourceCode.Append("searchPatternpath && "); } sourceCode.AppendFormat("({0}.lgspFlags & {1})=={1} && GRGEN_LGSP.PatternpathIsomorphyChecker.IsMatched({0}, {2})", variableContainingCandidate, isMatchedBySomeBit, LastMatchAtPreviousNestingLevel); sourceCode.Append(")\n"); // emit check failed code sourceCode.AppendFront("{\n"); sourceCode.Indent(); CheckFailedOperations.Emit(sourceCode); sourceCode.Unindent(); sourceCode.AppendFront("}\n"); }
public override void Dump(SourceBuilder builder) { // first dump check builder.AppendFront("CheckCandidate ForIsomorphy "); builder.AppendFormat("on {0} negNamePrefix:{1} node:{2} ", PatternElementName, NegativeIndependentNamePrefix, IsNode); if (NamesOfPatternElementsToCheckAgainst != null) { builder.Append("against "); foreach (string name in NamesOfPatternElementsToCheckAgainst) { builder.AppendFormat("{0} ", name); } } builder.AppendFormat("parallel:{0} first for all:{1} ", Parallel, LockForAllThreads); builder.Append("\n"); // then operations for case check failed if (CheckFailedOperations != null) { builder.Indent(); CheckFailedOperations.Dump(builder); builder.Unindent(); } }
public bool GenerateExternalDefinedSequence(SourceBuilder source, ExternalDefinedSequenceInfo sequence) { // exact sequence definition compiled class source.Append("\n"); source.AppendFront("public partial class Sequence_" + sequence.Name + " : GRGEN_LIBGR.SequenceDefinitionCompiled\n"); source.AppendFront("{\n"); source.Indent(); GenerateSequenceDefinedSingleton(source, sequence); source.Append("\n"); GenerateGenericMethodReturnValues(source, sequence); source.Append("\n"); GenerateExactExternalDefinedSequenceApplicationMethod(source, sequence); source.Append("\n"); GenerateGenericExternalDefinedSequenceApplicationMethod(source, sequence); // end of exact sequence definition compiled class source.Unindent(); source.AppendFront("}\n"); return(true); }
private static void BuildInterpretationPlan(LGSPGraph graph) { graph.matchingState.patternGraph = BuildPatternGraph(graph); PlanGraph planGraph = PlanGraphGenerator.GeneratePlanGraph(graph.Model, graph.statistics, graph.matchingState.patternGraph, false, false, false, new Dictionary <PatternElement, SetValueType>()); PlanGraphGenerator.MarkMinimumSpanningArborescence(planGraph, graph.matchingState.patternGraph.name, false); SearchPlanGraph searchPlanGraph = SearchPlanGraphGeneratorAndScheduler.GenerateSearchPlanGraph(planGraph); ScheduledSearchPlan scheduledSearchPlan = SearchPlanGraphGeneratorAndScheduler.ScheduleSearchPlan( searchPlanGraph, graph.matchingState.patternGraph, false, false); InterpretationPlanBuilder builder = new InterpretationPlanBuilder(scheduledSearchPlan, searchPlanGraph, graph.Model); graph.matchingState.interpretationPlan = builder.BuildInterpretationPlan("ComparisonMatcher_" + graph.GraphId); ++GraphMatchingState.numInterpretationPlans; graph.matchingState.changesCounterAtInterpretationPlanBuilding = graph.changesCounterAtLastAnalyze; Debug.Assert(graph.changesCounterAtLastAnalyze == graph.ChangesCounter); #if LOG_ISOMORPHY_CHECKING SourceBuilder sb = new SourceBuilder(); graph.matchingState.interpretationPlan.Dump(sb); writer.WriteLine(); writer.WriteLine(sb.ToString()); writer.WriteLine(); writer.Flush(); #endif }
public void EmitMatchingAndCloning(SourceBuilder source, String maxMatches) { String parameters = seqHelper.BuildParameters(seqRule, ArgumentExpressions, source); EmitMatching(source, parameters, maxMatches); EmitCloning(source); }
public void EmitMatchedReset(SourceBuilder builder, bool parallel) { if(parallel) builder.AppendFrontFormat("flagsPerElement{0}[candidate{0}.uniqueId] &= (ushort)~GRGEN_LGSP.LGSPElemFlagsParallel.IS_MATCHED;\n", this.Id); else builder.AppendFrontFormat("candidate{0}.lgspFlags &= ~((uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED);\n", this.Id); }
public string ExtractEdgeType(SourceBuilder source, SequenceExpression typeExpr) { string incidentEdgeType = "graph.Model.EdgeModel.RootType"; if (typeExpr != null) { if (typeExpr.Type(env) != "") { if (typeExpr.Type(env) == "string") { incidentEdgeType = "graph.Model.EdgeModel.GetType((string)" + exprGen.GetSequenceExpression(typeExpr, source) + ")"; } else { incidentEdgeType = "(GRGEN_LIBGR.EdgeType)" + exprGen.GetSequenceExpression(typeExpr, source); } } else { incidentEdgeType = exprGen.GetSequenceExpression(typeExpr, source) + " is string ? " + "graph.Model.EdgeModel.GetType((string)" + exprGen.GetSequenceExpression(typeExpr, source) + ")" + " : " + "(GRGEN_LIBGR.EdgeType)" + exprGen.GetSequenceExpression(typeExpr, source); } } return("(" + incidentEdgeType + ")"); }
public void EmitFiltering(SourceBuilder source) { for (int i = 0; i < seqRule.Filters.Count; ++i) { seqExprGen.EmitFilterCall(source, seqRule.Filters[i], patternName, matchesName, seqRule.PackagePrefixedName, false); } }
public void EmitCloning(SourceBuilder source, SequenceGenerator seqGen, String matchListName, String originalToCloneName) { source.AppendFront("if(" + matchesName + ".Count != 0) {\n"); source.Indent(); source.AppendFrontFormat("{0} = ({1}){0}.Clone({2});\n", matchesName, matchesType, originalToCloneName); source.Unindent(); source.AppendFront("}\n"); }
public override void Emit(SourceBuilder sourceCode) { sourceCode.Append(IsVar ? NamesOfEntities.Variable(Left) : NamesOfEntities.CandidateVariable(Left)); sourceCode.Append(" = "); sourceCode.Append("(" + TargetType + ")"); Right.Emit(sourceCode); sourceCode.Append(";\n"); }
/// <summary> /// Emit variable declarations needed (only once for every variable) /// </summary> private void EmitVarIfNew(SequenceVariable var, SourceBuilder source) { if (!var.Visited) { var.Visited = true; source.AppendFront(seqHelper.DeclareVar(var)); } }
public void EmitAddRange(SourceBuilder source, String matchListName) { source.AppendFront("if(" + matchesName + ".Count != 0) {\n"); source.Indent(); source.AppendFrontFormat("{0}.AddRange({1});\n", matchListName, matchesName); source.Unindent(); source.AppendFront("}\n"); }
public void EmitCloning(SourceBuilder source) { source.AppendFront("if(" + matchesName + ".Count != 0) {\n"); source.Indent(); source.AppendFront(matchesName + " = (" + matchesType + ")" + matchesName + ".Clone();\n"); source.Unindent(); source.AppendFront("}\n"); }
private void GenerateSequenceDefinedSingleton(SourceBuilder source, DefinedSequenceInfo sequence) { String className = "Sequence_" + sequence.Name; source.AppendFront("private static " + className + " instance = null;\n"); source.AppendFront("public static " + className + " Instance { get { if(instance==null) instance = new " + className + "(); return instance; } }\n"); source.AppendFront("private " + className + "() : base(\"" + sequence.PackagePrefixedName + "\", SequenceInfo_" + sequence.Name + ".Instance) { }\n"); }
public override void Emit(SourceBuilder sourceCode) { sourceCode.AppendFront("{ // " + Name + "\n"); sourceCode.Indent(); NestedOperationsList.Emit(sourceCode); sourceCode.Unindent(); sourceCode.AppendFront("}\n"); }
public override void Emit(SourceBuilder sourceCode) { sourceCode.AppendFrontFormat("if({0}.Count>0) {{\n", NestedMatchObjectName); sourceCode.Indent(); NestedOperationsList.Emit(sourceCode); sourceCode.Unindent(); sourceCode.AppendFront("}\n"); }
public override void Dump(SourceBuilder builder) { // first dump local content builder.AppendFront("FillPartialMatchForDuplicateChecking with "); foreach (string neededElement in NeededElements) { builder.AppendFormat("{0} ", neededElement); } builder.Append("\n"); }
private static void DumpScheduledSearchPlan(ScheduledSearchPlan ssp, IGraphModel model, String dumpname) { StreamWriter sw = new StreamWriter(dumpname + "-scheduledsp.txt", false); SourceBuilder sb = new SourceBuilder(); ScheduleExplainer.Explain(ssp, sb, model); sb.Append("\n"); sw.WriteLine(sb.ToString()); sw.Close(); }
public override void Emit(SourceBuilder sourceCode) { sourceCode.AppendFrontFormat("foreach({0} {1} in {2}) {{\n", IteratedMatchTypeName, HelperMatchName, NestedMatchObjectName); sourceCode.Indent(); NestedOperationsList.Emit(sourceCode); sourceCode.Unindent(); sourceCode.AppendFront("}\n"); }
public void EmitRewriting(SourceBuilder source, SequenceGenerator seqGen, String matchListName, String enumeratorName, bool fireDebugEvents) { source.AppendFrontFormat("case \"{0}\":\n", plainRuleName); source.AppendFront("{\n"); source.Indent(); source.AppendFront(matchType + " " + matchName + " = (" + matchType + ")" + enumeratorName + ".Current;\n"); String returnParameterDeclarations; String returnArguments; String returnAssignments; String returnParameterDeclarationsAllCall; String intermediateReturnAssignmentsAllCall; String returnAssignmentsAllCall; seqHelper.BuildReturnParameters(seqRule, ReturnVars, out returnParameterDeclarations, out returnArguments, out returnAssignments, out returnParameterDeclarationsAllCall, out intermediateReturnAssignmentsAllCall, out returnAssignmentsAllCall); // start a transaction if (fireDebugEvents) { source.AppendFront("procEnv.Matched(" + matchesName + ", " + matchName + ", " + specialStr + ");\n"); } if (fireDebugEvents) { source.AppendFront("procEnv.Finishing(" + matchesName + ", " + specialStr + ");\n"); } if (returnParameterDeclarations.Length != 0) { source.AppendFront(returnParameterDeclarations + "\n"); } source.AppendFront(ruleName + ".Modify(procEnv, " + matchName + returnArguments + ");\n"); if (returnAssignments.Length != 0) { source.AppendFront(returnAssignments + "\n"); } source.AppendFront("++procEnv.PerformanceInfo.RewritesPerformed;\n"); if (fireDebugEvents) { source.AppendFront("procEnv.Finished(" + matchesName + ", " + specialStr + ");\n"); } // rule applied, now execute the sequence seqGen.EmitSequence(seqSeq, source); source.AppendFront(COMP_HELPER.SetResultVar(seqMulti, COMP_HELPER.GetResultVar(seqSeq))); source.AppendFront("break;\n"); source.Unindent(); source.AppendFront("}\n"); }
public override void Emit(SourceBuilder sourceCode) { sourceCode.AppendFrontFormat("// build match of {0} for patternpath checks\n", PatternGraphName); sourceCode.AppendFrontFormat("if({0}==null) {0} = new {1}.{2}();\n", NamesOfEntities.PatternpathMatch(PatternGraphName), RulePatternClassName, NamesOfEntities.MatchClassName(PatternGraphName)); sourceCode.AppendFrontFormat("{0}._matchOfEnclosingPattern = {1};\n", NamesOfEntities.PatternpathMatch(PatternGraphName), MatchOfNestingPattern); }
public void GenerateExternalDefinedSequencePlaceholder(SourceBuilder source, ExternalDefinedSequenceInfo sequence, String externalActionsExtensionFilename) { source.Append("\n"); source.AppendFront("public partial class Sequence_" + sequence.Name + "\n"); source.AppendFront("{\n"); source.Indent(); GenerateInternalDefinedSequenceApplicationMethodStub(source, sequence, externalActionsExtensionFilename); source.Unindent(); source.AppendFront("}\n"); }
public override void Emit(SourceBuilder sourceCode) { SearchProgramOperation currentOperation = Next; // depth first walk over nested search program lists // walk current list here, recursive descent within local Emit-methods while (currentOperation != null) { currentOperation.Emit(sourceCode); currentOperation = currentOperation.Next; } }
public override void Dump(SourceBuilder builder) { SearchProgramOperation currentOperation = Next; // depth first walk over nested search program lists // walk current list here, recursive descent within local dump-methods while (currentOperation != null) { currentOperation.Dump(builder); currentOperation = currentOperation.Next; } }
public override void Dump(SourceBuilder builder) { // first dump check builder.AppendFront("CheckCandidate Failed \n"); // then operations for case check failed if (CheckFailedOperations != null) { builder.Indent(); CheckFailedOperations.Dump(builder); builder.Unindent(); } }
public override void Emit(SourceBuilder sourceCode) { if (sourceCode.CommentSourceCode) { sourceCode.AppendFrontFormat("// Variable {0} assigned from expression {1} \n", VariableName, SourceExpression); } // emit declaration of variable initialized with expression sourceCode.AppendFrontFormat("{0} {1} = ({0}){2};\n", VariableType, NamesOfEntities.Variable(VariableName), SourceExpression); }
public override void Dump(SourceBuilder builder) { // first dump check builder.AppendFront("CheckPartialMatch ForSubpatternsFound\n"); // then operations for case check failed if (CheckFailedOperations != null) { builder.Indent(); CheckFailedOperations.Dump(builder); builder.Unindent(); } }
public void EmitMatchedCheckAndSet(SourceBuilder builder, bool parallel) { if(parallel) { builder.AppendFrontFormat("List<ushort> flagsPerElement{0} = graph.flagsPerThreadPerElement[threadId];\n", this.Id); builder.AppendFrontFormat("if((flagsPerElement{0}[candidate{0}.uniqueId] & (ushort)GRGEN_LGSP.LGSPElemFlagsParallel.IS_MATCHED) != 0)\n", this.Id); builder.AppendFront("\tcontinue;\n"); builder.AppendFrontFormat("flagsPerElement{0}[candidate{0}.uniqueId] |= (ushort)GRGEN_LGSP.LGSPElemFlagsParallel.IS_MATCHED;\n", this.Id); } else { builder.AppendFrontFormat("if((candidate{0}.lgspFlags & (uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED) != 0)\n", this.Id); builder.AppendFront("\tcontinue;\n"); builder.AppendFrontFormat("candidate{0}.lgspFlags |= (uint)GRGEN_LGSP.LGSPElemFlags.IS_MATCHED;\n", this.Id); } }
/// <summary> /// Generates the action interface plus action implementation including the matcher source code /// for the given rule pattern into the given source builder /// </summary> public void GenerateActionAndMatcher(SourceBuilder sb, LGSPMatchingPattern matchingPattern, bool isInitialStatic) { // generate the search program out of the schedule(s) within the pattern graph of the rule SearchProgram searchProgram = GenerateSearchProgram(matchingPattern); // generate the parallelized search program out of the parallelized schedule(s) within the pattern graph of the rule SearchProgram searchProgramParallelized = GenerateParallelizedSearchProgramAsNeeded(matchingPattern); // emit matcher class head, body, tail; body is source code representing search program if(matchingPattern is LGSPRulePattern) { GenerateActionInterface(sb, (LGSPRulePattern)matchingPattern); // generate the exact action interface GenerateMatcherClassHeadAction(sb, (LGSPRulePattern)matchingPattern, isInitialStatic, searchProgram); searchProgram.Emit(sb); if(searchProgramParallelized != null) searchProgramParallelized.Emit(sb); GenerateActionImplementation(sb, (LGSPRulePattern)matchingPattern); GenerateMatcherClassTail(sb, matchingPattern.PatternGraph.Package != null); } else { GenerateMatcherClassHeadSubpattern(sb, matchingPattern, isInitialStatic); searchProgram.Emit(sb); if(searchProgramParallelized != null) searchProgramParallelized.Emit(sb); GenerateMatcherClassTail(sb, matchingPattern.PatternGraph.Package != null); } // finally generate matcher source for all the nested alternatives or iterateds of the pattern graph // nested inside the alternatives,iterateds,negatives,independents foreach(Alternative alt in matchingPattern.patternGraph.alternativesPlusInlined) { GenerateActionAndMatcherOfAlternative(sb, matchingPattern, alt, isInitialStatic); } foreach (Iterated iter in matchingPattern.patternGraph.iteratedsPlusInlined) { GenerateActionAndMatcherOfIterated(sb, matchingPattern, iter.iteratedPattern, isInitialStatic); } foreach (PatternGraph neg in matchingPattern.patternGraph.negativePatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, neg, isInitialStatic); } foreach (PatternGraph idpt in matchingPattern.patternGraph.independentPatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, idpt, isInitialStatic); } }
/// <summary> /// Generates matcher class head source code for the given iterated pattern into given source builder /// isInitialStatic tells whether the initial static version or a dynamic version after analyze is to be generated. /// </summary> public void GenerateMatcherClassHeadIterated(SourceBuilder sb, LGSPMatchingPattern matchingPattern, PatternGraph iter, bool isInitialStatic) { PatternGraph patternGraph = (PatternGraph)matchingPattern.PatternGraph; String namePrefix = (isInitialStatic ? "" : "Dyn") + "IteratedAction_"; String className = namePrefix + iter.pathPrefix + iter.name; String matchingPatternClassName = matchingPattern.GetType().Name; if(patternGraph.Package != null) { sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package); sb.AppendFront("{\n"); sb.Indent(); } sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPSubpatternAction\n"); sb.AppendFront("{\n"); sb.Indent(); // class level sb.AppendFront("private " + className + "(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_) {\n"); sb.Indent(); // method body level sb.AppendFront("actionEnv = actionEnv_; openTasks = openTasks_;\n"); sb.AppendFront("patternGraph = " + matchingPatternClassName + ".Instance.patternGraph;\n"); int index = -1; for (int i=0; i<iter.embeddingGraph.iteratedsPlusInlined.Length; ++i) { if (iter.embeddingGraph.iteratedsPlusInlined[i].iteratedPattern == iter) index = i; } sb.AppendFrontFormat("minMatchesIter = {0};\n", iter.embeddingGraph.iteratedsPlusInlined[index].minMatches); sb.AppendFrontFormat("maxMatchesIter = {0};\n", iter.embeddingGraph.iteratedsPlusInlined[index].maxMatches); sb.AppendFront("numMatchesIter = 0;\n"); if(iter.isIterationBreaking) sb.AppendFront("breakIteration = false;\n"); sb.Unindent(); // class level sb.AppendFront("}\n\n"); sb.AppendFront("int minMatchesIter;\n"); sb.AppendFront("int maxMatchesIter;\n"); sb.AppendFront("int numMatchesIter;\n"); if(iter.isIterationBreaking) sb.AppendFront("bool breakIteration;\n"); sb.Append("\n"); GenerateTasksMemoryPool(sb, className, false, iter.isIterationBreaking, matchingPattern.patternGraph.branchingFactor); Dictionary<string, bool> neededNodes = new Dictionary<string, bool>(); Dictionary<string, bool> neededEdges = new Dictionary<string, bool>(); Dictionary<string, GrGenType> neededVariables = new Dictionary<string, GrGenType>(); foreach (KeyValuePair<string, bool> neededNode in iter.neededNodes) neededNodes[neededNode.Key] = neededNode.Value; foreach (KeyValuePair<string, bool> neededEdge in iter.neededEdges) neededEdges[neededEdge.Key] = neededEdge.Value; foreach (KeyValuePair<string, GrGenType> neededVariable in iter.neededVariables) neededVariables[neededVariable.Key] = neededVariable.Value; foreach (KeyValuePair<string, bool> node in neededNodes) { sb.AppendFront("public GRGEN_LGSP.LGSPNode " + node.Key + ";\n"); } foreach (KeyValuePair<string, bool> edge in neededEdges) { sb.AppendFront("public GRGEN_LGSP.LGSPEdge " + edge.Key + ";\n"); } foreach (KeyValuePair<string, GrGenType> variable in neededVariables) { sb.AppendFront("public " + TypesHelper.TypeName(variable.Value) + " " + variable.Key + ";\n"); } GenerateIndependentsMatchObjects(sb, matchingPattern, iter); sb.AppendFront("\n"); }
/// <summary> /// Does action-backend dependent stuff. /// </summary> /// <param name="args">Any kind of parameters for the stuff to do</param> public override void Custom(params object[] args) { if(args.Length == 0) goto invalidCommand; switch((String) args[0]) { case "gen_searchplan": { if(graph.statistics.edgeCounts == null) throw new ArgumentException("Graph not analyzed yet!\nPlease execute 'custom graph analyze'!"); LGSPAction[] oldActions; if(args.Length == 1) { oldActions = new LGSPAction[actions.Count]; int i = 0; foreach(LGSPAction action in actions.Values) { oldActions[i] = action; ++i; } } else { oldActions = new LGSPAction[args.Length - 1]; for(int i = 0; i < oldActions.Length; i++) { oldActions[i] = (LGSPAction)GetAction((String)args[i + 1]); if(oldActions[i] == null) throw new ArgumentException("'" + (String)args[i + 1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); } } int startticks = Environment.TickCount; matcherGenerator.LazyNegativeIndependentConditionEvaluation = LazyNIC; matcherGenerator.InlineIndependents = InlineIndependents; matcherGenerator.Profile = Profile; LGSPAction[] newActions = matcherGenerator.GenerateActions(graph, modelAssemblyName, actionsAssemblyName, oldActions); int stopticks = Environment.TickCount; Console.Write("Searchplans for actions "); for(int i = 0; i < oldActions.Length; i++) { actions[oldActions[i].Name] = newActions[i]; if(i != 0) Console.Write(", "); Console.Write("'" + oldActions[i].Name + "'"); } Console.WriteLine(" generated in " + (stopticks - startticks) + " ms."); return; } case "dump_sourcecode": if(args.Length != 2) throw new ArgumentException("Usage: dump_sourcecode <bool>\n" + "If <bool> == true, C# files will be dumped for new searchplans."); if(!bool.TryParse((String) args[1], out matcherGenerator.DumpDynSourceCode)) throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\""); return; case "dump_searchplan": if(args.Length != 2) throw new ArgumentException("Usage: dump_searchplan <bool>\n" + "If <bool> == true, VCG and TXT files will be dumped for new searchplans."); if(!bool.TryParse((String) args[1], out matcherGenerator.DumpSearchPlan)) throw new ArgumentException("Illegal bool value specified: \"" + (String) args[1] + "\""); return; case "explain": { if(args.Length != 2) throw new ArgumentException("Usage: explain <name>\n" + "Explains the searchplan of the given action."); LGSPAction action = (LGSPAction)GetAction((String)args[1]); if(action == null) throw new ArgumentException("'" + (String)args[1] + "' is not the name of an action!\n" + "Please use 'show actions' to get a list of the available names."); if(action.patternGraph.schedules[0] == null) { LGSPGraphStatistics graphStatistics = null; if(StatisticsPath != null) { Console.WriteLine("static search plans from " + StatisticsPath); graphStatistics = new LGSPGraphStatistics(graph.Model); graphStatistics.Parse(StatisticsPath); } else Console.WriteLine("static search plans"); LGSPMatcherGenerator matcherGen = new LGSPMatcherGenerator(graph.Model); matcherGen.FillInStaticSearchPlans(graphStatistics, InlineIndependents, action); } SourceBuilder sb = new SourceBuilder(); foreach(KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { usedSubpattern.Key.patternGraph.Explain(sb, graph.Model); } action.patternGraph.Explain(sb, graph.Model); Console.WriteLine(sb.ToString()); return; } } invalidCommand: throw new ArgumentException("Possible commands:\n" + "- gen_searchplan: Generates a new searchplan for a given action\n" + " depending on a previous graph analysis\n" + "- explain: explains the searchplan in use for a given action\n" + "- dump_sourcecode: Sets dumping of C# files for new searchplans\n" + "- dump_searchplan: Sets dumping of VCG and TXT files of new\n" + " searchplans (with some intermediate steps)"); }
public override string ToString() { String fromStr = ""; SourceBuilder sbFrom = new SourceBuilder(); if(From != null) { sbFrom.Append(Index.Name); if(IncludingFrom) sbFrom.Append("<="); else sbFrom.Append("<"); From.Emit(sbFrom); fromStr = sbFrom.ToString(); } String toStr = ""; SourceBuilder sbTo = new SourceBuilder(); if(To != null) { sbTo.Append(Index.Name); if(IncludingTo) sbTo.Append(">="); else sbTo.Append(">"); To.Emit(sbTo); toStr = sbTo.ToString(); } if(From == null && To == null) return "descending(" + Index.Name + ")"; else return "descending(" + fromStr + " " + toStr + ")"; }
/// <summary> /// Generate new actions for the given actions, doing the same work, /// but hopefully faster by taking graph analysis information into account /// </summary> public LGSPAction[] GenerateActions(LGSPGraph graph, String modelAssemblyName, String actionsAssemblyName, params LGSPAction[] actions) { if(actions.Length == 0) throw new ArgumentException("No actions provided!"); SourceBuilder sourceCode = new SourceBuilder(CommentSourceCode); GenerateFileHeaderForActionsFile(sourceCode, model.GetType().Namespace, actions[0].rulePattern.GetType().Namespace); // use domain of dictionary as set with rulepatterns of the subpatterns of the actions, get them from pattern graph Dictionary<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPatterns = new Dictionary<LGSPMatchingPattern, LGSPMatchingPattern>(); foreach (LGSPAction action in actions) { foreach (KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> usedSubpattern in action.rulePattern.patternGraph.usedSubpatterns) { subpatternMatchingPatterns[usedSubpattern.Key] = usedSubpattern.Value; } } // generate code for subpatterns foreach (KeyValuePair<LGSPMatchingPattern, LGSPMatchingPattern> subpatternMatchingPattern in subpatternMatchingPatterns) { LGSPMatchingPattern smp = subpatternMatchingPattern.Key; GenerateScheduledSearchPlans(smp.patternGraph, graph, true, false, null); MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(smp.patternGraph); ParallelizeAsNeeded(smp); GenerateActionAndMatcher(sourceCode, smp, false); } // generate code for actions foreach(LGSPAction action in actions) { GenerateScheduledSearchPlans(action.rulePattern.patternGraph, graph, false, false, null); MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(action.rulePattern.patternGraph); ParallelizeAsNeeded(action.rulePattern); GenerateActionAndMatcher(sourceCode, action.rulePattern, false); } // close namespace sourceCode.Append("}"); if(DumpDynSourceCode) { using(StreamWriter writer = new StreamWriter("dynamic_" + actions[0].Name + ".cs")) writer.Write(sourceCode.ToString()); } // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = GetDynCompilerSetup(modelAssemblyName, actionsAssemblyName); // compile generated code CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if(compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach(CompilerError error in compResults.Errors) errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; throw new ArgumentException("Internal error: Illegal dynamic C# source code produced: " + errorMsg); } // create action instances LGSPAction[] newActions = new LGSPAction[actions.Length]; for(int i = 0; i < actions.Length; i++) { newActions[i] = (LGSPAction) compResults.CompiledAssembly.CreateInstance( "de.unika.ipd.grGen.lgspActions.DynAction_" + actions[i].Name); if(newActions[i] == null) throw new ArgumentException("Internal error: Generated assembly does not contain action '" + actions[i].Name + "'!"); } return newActions; }
public override void Emit(SourceBuilder sourceCode) { String id = fetchId().ToString(); if(Function is Adjacent) { Adjacent adjacent = (Adjacent)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); adjacent.Node.Emit(sourceCode); sourceCode.Append(";\n"); if(!Profiling) { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.GetCompatibleIncident(", id); adjacent.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); } else { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.Incident)\n", id); } sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); sourceCode.AppendFrontFormat("if(!edge_{0}.InstanceOf(", id); adjacent.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); } sourceCode.AppendFrontFormat("if(!edge_{0}.Opposite(node_{0}).InstanceOf(", id); adjacent.AdjacentNodeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2}.Opposite(node_{2});\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is AdjacentIncoming) { AdjacentIncoming adjacent = (AdjacentIncoming)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); adjacent.Node.Emit(sourceCode); sourceCode.Append(";\n"); if(!Profiling) { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.GetCompatibleIncoming(", id); adjacent.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); } else { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.Incoming)\n", id); } sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); sourceCode.AppendFrontFormat("if(!edge_{0}.InstanceOf(", id); adjacent.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); } sourceCode.AppendFrontFormat("if(!edge_{0}.Source.InstanceOf(", id); adjacent.AdjacentNodeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2}.Source;\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is AdjacentOutgoing) { AdjacentOutgoing adjacent = (AdjacentOutgoing)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); adjacent.Node.Emit(sourceCode); sourceCode.Append(";\n"); if(!Profiling) { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.GetCompatibleOutgoing(", id); adjacent.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); } else { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.Outgoing)\n", id); } sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); sourceCode.AppendFrontFormat("if(!edge_{0}.InstanceOf(", id); adjacent.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); } sourceCode.AppendFrontFormat("if(!edge_{0}.Target.InstanceOf(", id); adjacent.AdjacentNodeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2}.Target;\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is Incident) { Incident incident = (Incident)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); incident.Node.Emit(sourceCode); sourceCode.Append(";\n"); if(!Profiling) { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.GetCompatibleIncident(", id); incident.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); } else { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.Incident)\n", id); } sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); sourceCode.AppendFrontFormat("if(!edge_{0}.InstanceOf(", id); incident.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); } sourceCode.AppendFrontFormat("if(!edge_{0}.Opposite(node_{0}).InstanceOf(", id); incident.AdjacentNodeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is Incoming) { Incoming incident = (Incoming)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); incident.Node.Emit(sourceCode); sourceCode.Append(";\n"); if(!Profiling) { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.GetCompatibleIncoming(", id); incident.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); } else { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.Incoming)\n", id); } sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); sourceCode.AppendFrontFormat("if(!edge_{0}.InstanceOf(", id); incident.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); } sourceCode.AppendFrontFormat("if(!edge_{0}.Source.InstanceOf(", id); incident.AdjacentNodeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is Outgoing) { Outgoing incident = (Outgoing)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); incident.Node.Emit(sourceCode); sourceCode.Append(";\n"); if(!Profiling) { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.GetCompatibleOutgoing(", id); incident.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); } else { sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in node_{0}.Outgoing)\n", id); } sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); sourceCode.AppendFrontFormat("if(!edge_{0}.InstanceOf(", id); incident.IncidentEdgeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); } sourceCode.AppendFrontFormat("if(!edge_{0}.Target.InstanceOf(", id); incident.AdjacentNodeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("\tcontinue;\n"); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is Reachable) { Reachable reachable = (Reachable)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.INode iter_{0} in GRGEN_LIBGR.GraphHelper.Reachable(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})iter_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is ReachableIncoming) { ReachableIncoming reachable = (ReachableIncoming)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.INode iter_{0} in GRGEN_LIBGR.GraphHelper.ReachableIncoming(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})iter_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is ReachableOutgoing) { ReachableOutgoing reachable = (ReachableOutgoing)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.INode iter_{0} in GRGEN_LIBGR.GraphHelper.ReachableOutgoing(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})iter_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is ReachableEdges) { ReachableEdges reachable = (ReachableEdges)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in GRGEN_LIBGR.GraphHelper.ReachableEdges(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is ReachableEdgesIncoming) { ReachableEdgesIncoming reachable = (ReachableEdgesIncoming)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in GRGEN_LIBGR.GraphHelper.ReachableEdgesIncoming(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is ReachableEdgesOutgoing) { ReachableEdgesOutgoing reachable = (ReachableEdgesOutgoing)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in GRGEN_LIBGR.GraphHelper.ReachableEdgesOutgoing(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is BoundedReachable) { BoundedReachable reachable = (BoundedReachable)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.INode iter_{0} in GRGEN_LIBGR.GraphHelper.BoundedReachable(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})iter_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is BoundedReachableIncoming) { BoundedReachableIncoming reachable = (BoundedReachableIncoming)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.INode iter_{0} in GRGEN_LIBGR.GraphHelper.BoundedReachableIncoming(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})iter_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is BoundedReachableOutgoing) { BoundedReachableOutgoing reachable = (BoundedReachableOutgoing)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.INode iter_{0} in GRGEN_LIBGR.GraphHelper.BoundedReachableOutgoing(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})iter_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is BoundedReachableEdges) { BoundedReachableEdges reachable = (BoundedReachableEdges)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in GRGEN_LIBGR.GraphHelper.BoundedReachableEdges(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is BoundedReachableEdgesIncoming) { BoundedReachableEdgesIncoming reachable = (BoundedReachableEdgesIncoming)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in GRGEN_LIBGR.GraphHelper.BoundedReachableEdgesIncoming(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is BoundedReachableEdgesOutgoing) { BoundedReachableEdgesOutgoing reachable = (BoundedReachableEdgesOutgoing)Function; sourceCode.AppendFront("GRGEN_LIBGR.INode node_" + id + " = "); reachable.Node.Emit(sourceCode); sourceCode.Append(";\n"); sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in GRGEN_LIBGR.GraphHelper.BoundedReachableEdgesOutgoing(node_{0}, ", id); reachable.IncidentEdgeType.Emit(sourceCode); sourceCode.Append(", "); reachable.AdjacentNodeType.Emit(sourceCode); sourceCode.Append(", "); sourceCode.Append("graph"); if(Profiling) sourceCode.Append(", actionEnv"); if(Parallel) sourceCode.Append(", threadId"); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFrontFormat("{0} {1} = ({0})edge_{2};\n", VariableType, NamesOfEntities.Variable(Variable), id); } else if(Function is Nodes) { Nodes nodes = (Nodes)Function; sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.INode node_{0} in graph.GetCompatibleNodes(", id); nodes.NodeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); } sourceCode.AppendFront(VariableType + " " + NamesOfEntities.Variable(Variable) + " = (" + VariableType + ") node_" + id + ";\n"); } else if(Function is Edges) { Edges edges = (Edges)Function; sourceCode.AppendFrontFormat("foreach(GRGEN_LIBGR.IEdge edge_{0} in graph.GetCompatibleEdges(", id); edges.EdgeType.Emit(sourceCode); sourceCode.Append("))\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); if(Profiling) { if(Parallel) sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchStepsPerThread[threadId];\n"); else sourceCode.AppendFront("++actionEnv.PerformanceInfo.SearchSteps;\n"); } sourceCode.AppendFront(VariableType + " " + NamesOfEntities.Variable(Variable) + " = (" + VariableType + ") edge_" + id + ";\n"); } foreach(Yielding statement in Statements) statement.Emit(sourceCode); sourceCode.Unindent(); sourceCode.AppendFront("}\n"); }
/// <summary> /// Generates the search program for the given alternative /// </summary> SearchProgram GenerateSearchProgramAlternative(LGSPMatchingPattern matchingPattern, Alternative alt) { // build pass: build nested program from scheduled search plans of the alternative cases SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); SearchProgram searchProgram = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, alt, false, Profile); #if DUMP_SEARCHPROGRAMS // dump built search program for debugging SourceBuilder builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + "_" + alt.name + "_" + searchProgram.Name + "_built_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif // complete pass: complete check operations in all search programs SearchProgramCompleter searchProgramCompleter = new SearchProgramCompleter(); searchProgramCompleter.CompleteCheckOperationsInAllSearchPrograms(searchProgram); #if DUMP_SEARCHPROGRAMS // dump completed search program for debugging builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); writer = new StreamWriter(matchingPattern.name + "_" + alt.name + "_" + searchProgram.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgram; }
/// <summary> /// Generates matcher class tail source code /// </summary> public void GenerateMatcherClassTail(SourceBuilder sb, bool containedInPackage) { sb.Unindent(); sb.AppendFront("}\n"); if(containedInPackage) { sb.Unindent(); sb.AppendFront("}\n"); } sb.AppendFront("\n"); }
/// <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> /// Generates the parallelized search program(s) for the pattern graph of the given rule /// </summary> SearchProgram GenerateParallelizedSearchProgramAsNeeded(LGSPMatchingPattern matchingPattern) { PatternGraph patternGraph = matchingPattern.patternGraph; if(patternGraph.parallelizedSchedule == null) return null; SearchProgram searchProgramRoot = null; SearchProgram searchProgramListEnd = null; for(int i = 0; i < patternGraph.parallelizedSchedule.Length; ++i) // 2 for actions, 1 for subpatterns { ScheduledSearchPlan scheduledSearchPlan = patternGraph.parallelizedSchedule[i]; #if DUMP_SCHEDULED_SEARCH_PLAN StreamWriter sspwriter = new StreamWriter(matchingPattern.name + (i==1 ? "_parallelized_body" : "_parallelized") + "_ssp_dump.txt"); float prevCostToEnd = scheduledSearchPlan.Operations.Length > 0 ? scheduledSearchPlan.Operations[0].CostToEnd : 0f; foreach(SearchOperation so in scheduledSearchPlan.Operations) { sspwriter.Write(SearchOpToString(so) + " ; " + so.CostToEnd + " (+" + (prevCostToEnd-so.CostToEnd) + ")" + "\n"); prevCostToEnd = so.CostToEnd; } sspwriter.Close(); #endif // build pass: build nested program from scheduled search plan SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); if(matchingPattern is LGSPRulePattern) { SearchProgram sp = searchProgramBuilder.BuildSearchProgram(model, (LGSPRulePattern)matchingPattern, i, null, true, Profile); if(i == 0) searchProgramRoot = searchProgramListEnd = sp; else searchProgramListEnd = (SearchProgram)searchProgramListEnd.Append(sp); } else { Debug.Assert(searchProgramRoot == null); searchProgramRoot = searchProgramListEnd = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, true, Profile); } } #if DUMP_SEARCHPROGRAMS // dump built search program for debugging SourceBuilder builder = new SourceBuilder(CommentSourceCode); searchProgramRoot.Dump(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + (i==1 ? "_parallelized_body" : "_parallelized") + "_" + searchProgramRoot.Name + "_built_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif // complete pass: complete check operations in all search programs SearchProgramCompleter searchProgramCompleter = new SearchProgramCompleter(); searchProgramCompleter.CompleteCheckOperationsInAllSearchPrograms(searchProgramRoot); #if DUMP_SEARCHPROGRAMS // dump completed search program for debugging builder = new SourceBuilder(CommentSourceCode); searchProgramRoot.Dump(builder); writer = new StreamWriter(matchingPattern.name + (i==1 ? "_parallelized_body" : "_parallelized") + "_" + searchProgramRoot.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgramRoot; }
/// <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> /// Generates the action interface plus action implementation including the matcher source code /// for the alternatives/iterateds nested within the given negative/independent pattern graph into the given source builder /// </summary> public void GenerateActionAndMatcherOfNestedPatterns(SourceBuilder sb, LGSPMatchingPattern matchingPattern, PatternGraph negOrIdpt, bool isInitialStatic) { // nothing to do locally .. // .. just move on to the nested alternatives or iterateds foreach (Alternative alt in negOrIdpt.alternativesPlusInlined) { GenerateActionAndMatcherOfAlternative(sb, matchingPattern, alt, isInitialStatic); } foreach (Iterated iter in negOrIdpt.iteratedsPlusInlined) { GenerateActionAndMatcherOfIterated(sb, matchingPattern, iter.iteratedPattern, isInitialStatic); } foreach (PatternGraph nestedNeg in negOrIdpt.negativePatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, nestedNeg, isInitialStatic); } foreach (PatternGraph nestedIdpt in negOrIdpt.independentPatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, nestedIdpt, isInitialStatic); } }
/// <summary> /// Generates the action interface plus action implementation including the matcher source code /// for the given iterated pattern into the given source builder /// </summary> public void GenerateActionAndMatcherOfIterated(SourceBuilder sb, LGSPMatchingPattern matchingPattern, PatternGraph iter, bool isInitialStatic) { // generate the search program out of the schedule within the pattern graph of the iterated pattern SearchProgram searchProgram = GenerateSearchProgramIterated(matchingPattern, iter); // generate the parallelized search program out of the parallelized schedule within the pattern graph of the iterated pattern SearchProgram searchProgramParallelized = GenerateParallelizedSearchProgramIteratedAsNeeded(matchingPattern, iter); // emit matcher class head, body, tail; body is source code representing search program GenerateMatcherClassHeadIterated(sb, matchingPattern, iter, isInitialStatic); searchProgram.Emit(sb); if(searchProgramParallelized != null) searchProgramParallelized.Emit(sb); GenerateMatcherClassTail(sb, matchingPattern.PatternGraph.Package != null); // finally generate matcher source for all the nested alternatives or iterateds of the iterated pattern graph // nested inside the alternatives,iterateds,negatives,independents foreach (Alternative alt in iter.alternativesPlusInlined) { GenerateActionAndMatcherOfAlternative(sb, matchingPattern, alt, isInitialStatic); } foreach (Iterated nestedIter in iter.iteratedsPlusInlined) { GenerateActionAndMatcherOfIterated(sb, matchingPattern, nestedIter.iteratedPattern, isInitialStatic); } foreach (PatternGraph neg in iter.negativePatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, neg, isInitialStatic); } foreach (PatternGraph idpt in iter.independentPatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, idpt, isInitialStatic); } }
/// <summary> /// Generates match objects of independents (one pre-allocated is part of action class) /// </summary> private void GenerateIndependentsMatchObjects(SourceBuilder sb, LGSPMatchingPattern matchingPatternClass, PatternGraph patternGraph) { if (patternGraph.nestedIndependents != null) { foreach (KeyValuePair<PatternGraph, PatternGraph> nestedIndependent in patternGraph.nestedIndependents) { if(nestedIndependent.Key.originalPatternGraph != null) { sb.AppendFrontFormat("private {0} {1} = new {0}();", nestedIndependent.Key.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name + "." + NamesOfEntities.MatchClassName(nestedIndependent.Key.originalPatternGraph.pathPrefix + nestedIndependent.Key.originalPatternGraph.name), NamesOfEntities.MatchedIndependentVariable(nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name)); } else { sb.AppendFrontFormat("private {0} {1} = new {0}();", matchingPatternClass.GetType().Name + "." + NamesOfEntities.MatchClassName(nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name), NamesOfEntities.MatchedIndependentVariable(nestedIndependent.Key.pathPrefix + nestedIndependent.Key.name)); } } } foreach (PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined) { GenerateIndependentsMatchObjects(sb, matchingPatternClass, idpt); } }
/// <summary> /// Generates the parallelized search program for the given iterated pattern /// </summary> SearchProgram GenerateParallelizedSearchProgramIteratedAsNeeded(LGSPMatchingPattern matchingPattern, PatternGraph iter) { if(matchingPattern.patternGraph.parallelizedSchedule == null) return null; // build pass: build nested program from scheduled search plan of the all pattern SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); SearchProgram searchProgram = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, iter, true, Profile); #if DUMP_SEARCHPROGRAMS // dump built search program for debugging SourceBuilder builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); StreamWriter writer = new StreamWriter(matchingPattern.name + "_parallelized_" + iter.name + "_" + searchProgram.Name + "_built_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif // complete pass: complete check operations in all search programs SearchProgramCompleter searchProgramCompleter = new SearchProgramCompleter(); searchProgramCompleter.CompleteCheckOperationsInAllSearchPrograms(searchProgram); #if DUMP_SEARCHPROGRAMS // dump completed search program for debugging builder = new SourceBuilder(CommentSourceCode); searchProgram.Dump(builder); writer = new StreamWriter(matchingPattern.name + "_parallelized_" + iter.name + "_" + searchProgram.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgram; }
/// <summary> /// Generates memory pooling code for matching tasks of class given by it's name /// </summary> private void GenerateTasksMemoryPool(SourceBuilder sb, String className, bool isAlternative, bool isIterationBreaking, int branchingFactor) { // getNewTask method handing out new task from pool or creating task if pool is empty if(isAlternative) sb.AppendFront("public static " + className + " getNewTask(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, " + "Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_, GRGEN_LGSP.PatternGraph[] patternGraphs_) {\n"); else sb.AppendFront("public static " + className + " getNewTask(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, " + "Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_) {\n"); sb.Indent(); sb.AppendFront(className + " newTask;\n"); sb.AppendFront("if(numFreeTasks>0) {\n"); sb.Indent(); sb.AppendFront("newTask = freeListHead;\n"); sb.AppendFront("newTask.actionEnv = actionEnv_; newTask.openTasks = openTasks_;\n"); if(isAlternative) sb.AppendFront("newTask.patternGraphs = patternGraphs_;\n"); else if(isIterationBreaking) sb.AppendFront("newTask.breakIteration = false;\n"); sb.AppendFront("freeListHead = newTask.next;\n"); sb.AppendFront("newTask.next = null;\n"); sb.AppendFront("--numFreeTasks;\n"); sb.Unindent(); sb.AppendFront("} else {\n"); sb.Indent(); if(isAlternative) sb.AppendFront("newTask = new " + className + "(actionEnv_, openTasks_, patternGraphs_);\n"); else sb.AppendFront("newTask = new " + className + "(actionEnv_, openTasks_);\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return newTask;\n"); sb.Unindent(); sb.AppendFront("}\n\n"); // releaseTask method recycling task into pool if pool is not full sb.AppendFront("public static void releaseTask(" + className + " oldTask) {\n"); sb.Indent(); sb.AppendFront("if(numFreeTasks<MAX_NUM_FREE_TASKS) {\n"); sb.Indent(); sb.AppendFront("oldTask.next = freeListHead;\n"); sb.AppendFront("oldTask.actionEnv = null; oldTask.openTasks = null;\n"); sb.AppendFront("freeListHead = oldTask;\n"); sb.AppendFront("++numFreeTasks;\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.Unindent(); sb.AppendFront("}\n\n"); // tasks pool administration data sb.AppendFront("private static " + className + " freeListHead = null;\n"); sb.AppendFront("private static int numFreeTasks = 0;\n"); sb.AppendFront("private const int MAX_NUM_FREE_TASKS = 100;\n\n"); // todo: compute antiproportional to pattern size sb.AppendFront("private " + className + " next = null;\n\n"); // for parallelized subpatterns/alternatives/iterateds we need a freelist per thread if(branchingFactor > 1) { // getNewTask method handing out new task from pool or creating task if pool is empty if(isAlternative) sb.AppendFront("public static " + className + " getNewTask(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, " + "Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_, GRGEN_LGSP.PatternGraph[] patternGraphs_, int threadId) {\n"); else sb.AppendFront("public static " + className + " getNewTask(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, " + "Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_, int threadId) {\n"); sb.Indent(); sb.AppendFront(className + " newTask;\n"); sb.AppendFront("if(numFreeTasks_perWorker[threadId]>0) {\n"); sb.Indent(); sb.AppendFront("newTask = freeListHead_perWorker[threadId];\n"); sb.AppendFront("newTask.actionEnv = actionEnv_; newTask.openTasks = openTasks_;\n"); if(isAlternative) sb.AppendFront("newTask.patternGraphs = patternGraphs_;\n"); else if(isIterationBreaking) sb.AppendFront("newTask.breakIteration = false;\n"); sb.AppendFront("freeListHead_perWorker[threadId] = newTask.next;\n"); sb.AppendFront("newTask.next = null;\n"); sb.AppendFront("--numFreeTasks_perWorker[threadId];\n"); sb.Unindent(); sb.AppendFront("} else {\n"); sb.Indent(); if(isAlternative) sb.AppendFront("newTask = new " + className + "(actionEnv_, openTasks_, patternGraphs_);\n"); else sb.AppendFront("newTask = new " + className + "(actionEnv_, openTasks_);\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.AppendFront("return newTask;\n"); sb.Unindent(); sb.AppendFront("}\n\n"); // releaseTask method recycling task into pool if pool is not full sb.AppendFront("public static void releaseTask(" + className + " oldTask, int threadId) {\n"); sb.Indent(); sb.AppendFront("if(numFreeTasks_perWorker[threadId]<MAX_NUM_FREE_TASKS/2) {\n"); sb.Indent(); sb.AppendFront("oldTask.next = freeListHead_perWorker[threadId];\n"); sb.AppendFront("oldTask.actionEnv = null; oldTask.openTasks = null;\n"); sb.AppendFront("freeListHead_perWorker[threadId] = oldTask;\n"); sb.AppendFront("++numFreeTasks_perWorker[threadId];\n"); sb.Unindent(); sb.AppendFront("}\n"); sb.Unindent(); sb.AppendFront("}\n\n"); // tasks pool administration data sb.AppendFront("private static " + className + "[] freeListHead_perWorker = new " + className + "[Math.Min(" + branchingFactor + ", Environment.ProcessorCount)];\n"); sb.AppendFront("private static int[] numFreeTasks_perWorker = new int[Math.Min(" + branchingFactor + ", Environment.ProcessorCount)];\n"); } }
/// <summary> /// Generates file header for actions file into given source builer /// </summary> public void GenerateFileHeaderForActionsFile(SourceBuilder sb, String namespaceOfModel, String namespaceOfRulePatterns) { sb.AppendFront("using System;\n" + "using System.Collections.Generic;\n" + "using System.Collections;\n" + "using System.Text;\n" + "using System.Threading;\n" + "using GRGEN_LIBGR = de.unika.ipd.grGen.libGr;\n" + "using GRGEN_EXPR = de.unika.ipd.grGen.expression;\n" + "using GRGEN_LGSP = de.unika.ipd.grGen.lgsp;\n" + "using GRGEN_MODEL = " + namespaceOfModel + ";\n" + "using GRGEN_ACTIONS = " + namespaceOfRulePatterns + ";\n" + "using " + namespaceOfRulePatterns + ";\n\n"); sb.AppendFront("namespace de.unika.ipd.grGen.lgspActions\n"); sb.AppendFront("{\n"); sb.Indent(); // namespace level }
/// <summary> /// Generates an LGSPAction object for the given scheduled search plan. /// </summary> /// <param name="action">Needed for the rule pattern and the name</param> /// <param name="sourceOutputFilename">null if no output file needed</param> public LGSPAction GenerateAction(ScheduledSearchPlan scheduledSearchPlan, LGSPAction action, String modelAssemblyLocation, String actionAssemblyLocation, String sourceOutputFilename) { SourceBuilder sourceCode = new SourceBuilder(CommentSourceCode); GenerateFileHeaderForActionsFile(sourceCode, model.GetType().Namespace, action.rulePattern.GetType().Namespace); // can't generate new subpattern matchers due to missing scheduled search plans for them / missing graph analyze data Debug.Assert(action.rulePattern.patternGraph.embeddedGraphsPlusInlined.Length == 0); GenerateActionAndMatcher(sourceCode, action.rulePattern, false); // close namespace sourceCode.Append("}"); // write generated source to file if requested if(sourceOutputFilename != null) { StreamWriter writer = new StreamWriter(sourceOutputFilename); writer.Write(sourceCode.ToString()); writer.Close(); } // set up compiler CSharpCodeProvider compiler = new CSharpCodeProvider(); CompilerParameters compParams = GetDynCompilerSetup(modelAssemblyLocation, actionAssemblyLocation); // Stopwatch compilerWatch = Stopwatch.StartNew(); // compile generated code CompilerResults compResults = compiler.CompileAssemblyFromSource(compParams, sourceCode.ToString()); if(compResults.Errors.HasErrors) { String errorMsg = compResults.Errors.Count + " Errors:"; foreach(CompilerError error in compResults.Errors) errorMsg += Environment.NewLine + "Line: " + error.Line + " - " + error.ErrorText; throw new ArgumentException("Illegal dynamic C# source code produced for actions \"" + action.Name + "\": " + errorMsg); } // create action instance Object obj = compResults.CompiledAssembly.CreateInstance("de.unika.ipd.grGen.lgspActions.DynAction_" + action.Name); // long compSourceTicks = compilerWatch.ElapsedTicks; // Console.WriteLine("GenMatcher: Compile source: {0} us", compSourceTicks / (Stopwatch.Frequency / 1000000)); return (LGSPAction) obj; }
/// <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); }
public override void Emit(SourceBuilder sourceCode) { sourceCode.Append(NamesOfEntities.Variable(Left)); sourceCode.Append("["); Index.Emit(sourceCode); sourceCode.Append("] = "); Right.Emit(sourceCode); sourceCode.Append(";\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 override void Emit(SourceBuilder sourceCode) { String ascendingVar = "ascending_" + fetchId().ToString(); String entryVar = "entry_" + fetchId().ToString(); String limitVar = "limit_" + fetchId().ToString(); sourceCode.AppendFront("int " + entryVar + " = (int)("); Left.Emit(sourceCode); sourceCode.AppendFront(");\n"); sourceCode.AppendFront("int " + limitVar + " = (int)("); Right.Emit(sourceCode); sourceCode.AppendFront(");\n"); sourceCode.AppendFront("bool " + ascendingVar + " = " + entryVar + " <= " + limitVar + ";\n"); sourceCode.AppendFront("while(" + ascendingVar + " ? " + entryVar + " <= " + limitVar + " : " + entryVar + " >= " + limitVar + ")\n"); sourceCode.AppendFront("{\n"); sourceCode.Indent(); sourceCode.AppendFront(VariableType + " " + NamesOfEntities.Variable(Variable) + " = " + entryVar + ";\n"); foreach(Yielding statement in Statements) statement.Emit(sourceCode); sourceCode.AppendFront("if(" + ascendingVar + ") ++" + entryVar + "; else --" + entryVar + ";\n"); sourceCode.Unindent(); sourceCode.AppendFront("}\n"); }
/// <summary> /// Generates matcher class head source code for the subpattern 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> public void GenerateMatcherClassHeadSubpattern(SourceBuilder sb, LGSPMatchingPattern matchingPattern, bool isInitialStatic) { Debug.Assert(!(matchingPattern is LGSPRulePattern)); PatternGraph patternGraph = (PatternGraph)matchingPattern.PatternGraph; String namePrefix = (isInitialStatic ? "" : "Dyn") + "PatternAction_"; String className = namePrefix + matchingPattern.name; String matchingPatternClassName = matchingPattern.GetType().Name; if(patternGraph.Package != null) { sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package); sb.AppendFront("{\n"); sb.Indent(); } sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPSubpatternAction\n"); sb.AppendFront("{\n"); sb.Indent(); // class level sb.AppendFront("private " + className + "(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_) {\n"); sb.Indent(); // method body level sb.AppendFront("actionEnv = actionEnv_; openTasks = openTasks_;\n"); sb.AppendFront("patternGraph = " + matchingPatternClassName + ".Instance.patternGraph;\n"); sb.Unindent(); // class level sb.AppendFront("}\n\n"); GenerateTasksMemoryPool(sb, className, false, false, matchingPattern.patternGraph.branchingFactor); for (int i = 0; i < patternGraph.nodesPlusInlined.Length; ++i) { PatternNode node = patternGraph.nodesPlusInlined[i]; if (node.PointOfDefinition == null) { sb.AppendFront("public GRGEN_LGSP.LGSPNode " + node.name + ";\n"); } } for (int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i) { PatternEdge edge = patternGraph.edgesPlusInlined[i]; if (edge.PointOfDefinition == null) { sb.AppendFront("public GRGEN_LGSP.LGSPEdge " + edge.name + ";\n"); } } for (int i = 0; i < patternGraph.variablesPlusInlined.Length; ++i) { PatternVariable variable = patternGraph.variablesPlusInlined[i]; sb.AppendFront("public " +TypesHelper.TypeName(variable.type) + " " + variable.name + ";\n"); } GenerateIndependentsMatchObjects(sb, matchingPattern, patternGraph); sb.AppendFront("\n"); }
public override string ToString() { SourceBuilder sb = new SourceBuilder(); Expr.Emit(sb); return Index.Name + "==" + sb.ToString(); }
/// <summary> /// Generates matcher class head source code for the given alternative into given source builder /// isInitialStatic tells whether the initial static version or a dynamic version after analyze is to be generated. /// </summary> public void GenerateMatcherClassHeadAlternative(SourceBuilder sb, LGSPMatchingPattern matchingPattern, Alternative alternative, bool isInitialStatic) { PatternGraph patternGraph = (PatternGraph)matchingPattern.PatternGraph; String namePrefix = (isInitialStatic ? "" : "Dyn") + "AlternativeAction_"; String className = namePrefix + alternative.pathPrefix+alternative.name; if(patternGraph.Package != null) { sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package); sb.AppendFront("{\n"); sb.Indent(); } sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPSubpatternAction\n"); sb.AppendFront("{\n"); sb.Indent(); // class level sb.AppendFront("private " + className + "(GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnv_, " + "Stack<GRGEN_LGSP.LGSPSubpatternAction> openTasks_, GRGEN_LGSP.PatternGraph[] patternGraphs_) {\n"); sb.Indent(); // method body level sb.AppendFront("actionEnv = actionEnv_; openTasks = openTasks_;\n"); // pfadausdruck gebraucht, da das alternative-objekt im pattern graph steckt sb.AppendFront("patternGraphs = patternGraphs_;\n"); sb.Unindent(); // class level sb.AppendFront("}\n\n"); GenerateTasksMemoryPool(sb, className, true, false, matchingPattern.patternGraph.branchingFactor); Dictionary<string, bool> neededNodes = new Dictionary<string,bool>(); Dictionary<string, bool> neededEdges = new Dictionary<string,bool>(); Dictionary<string, GrGenType> neededVariables = new Dictionary<string, GrGenType>(); foreach (PatternGraph altCase in alternative.alternativeCases) { foreach (KeyValuePair<string, bool> neededNode in altCase.neededNodes) neededNodes[neededNode.Key] = neededNode.Value; foreach (KeyValuePair<string, bool> neededEdge in altCase.neededEdges) neededEdges[neededEdge.Key] = neededEdge.Value; foreach (KeyValuePair<string, GrGenType> neededVariable in altCase.neededVariables) neededVariables[neededVariable.Key] = neededVariable.Value; } foreach (KeyValuePair<string, bool> node in neededNodes) { sb.AppendFront("public GRGEN_LGSP.LGSPNode " + node.Key + ";\n"); } foreach (KeyValuePair<string, bool> edge in neededEdges) { sb.AppendFront("public GRGEN_LGSP.LGSPEdge " + edge.Key + ";\n"); } foreach (KeyValuePair<string, GrGenType> variable in neededVariables) { sb.AppendFront("public " + TypesHelper.TypeName(variable.Value) + " " + variable.Key + ";\n"); } foreach (PatternGraph altCase in alternative.alternativeCases) { GenerateIndependentsMatchObjects(sb, matchingPattern, altCase); } sb.AppendFront("\n"); }
public override string ToString() { SourceBuilder sb = new SourceBuilder(); Expr.Emit(sb); return "unique[" + sb.ToString() + "]"; }
private void DumpScheduledSearchPlan(ScheduledSearchPlan ssp, String dumpname) { StreamWriter sw = new StreamWriter(dumpname + "-scheduledsp.txt", false); SourceBuilder sb = new SourceBuilder(); ssp.Explain(sb, model); sb.Append("\n"); sw.WriteLine(sb.ToString()); sw.Close(); /* StreamWriter sw = new StreamWriter(dumpname + "-scheduledsp.vcg", false); sw.WriteLine("graph:{\ninfoname 1: \"Attributes\"\ndisplay_edge_labels: no\nport_sharing: no\nsplines: no\n" + "\nmanhattan_edges: no\nsmanhattan_edges: no\norientation: bottom_to_top\nedges: yes\nnodes: yes\nclassname 1: \"normal\""); sw.WriteLine("node:{title:\"root\" label:\"ROOT\"}\n"); SearchPlanNode root = new SearchPlanNode("root"); sw.WriteLine("graph:{{title:\"pattern\" label:\"{0}\" status:clustered color:lightgrey", dumpname); foreach(SearchOperation op in ssp.Operations) { switch(op.Type) { case SearchOperationType.Lookup: case SearchOperationType.Incoming: case SearchOperationType.Outgoing: case SearchOperationType.ImplicitSource: case SearchOperationType.ImplicitTarget: { SearchPlanNode spnode = (SearchPlanNode) op.Element; DumpNode(sw, spnode); SearchPlanNode src; switch(op.Type) { case SearchOperationType.Lookup: case SearchOperationType.ActionPreset: case SearchOperationType.NegPreset: src = root; break; default: src = op.SourceSPNode; break; } DumpEdge(sw, op.Type, src, spnode, op.CostToEnd, false); break; } case SearchOperationType.Condition: sw.WriteLine("node:{title:\"Condition\" label:\"CONDITION\"}\n"); break; case SearchOperationType.NegativePattern: sw.WriteLine("node:{title:\"NAC\" label:\"NAC\"}\n"); break; } }*/ }