/// <summary> /// Instantiates a new alternative object as a copy from an original alternative, used for inlining. /// </summary> /// <param name="original">The original alternative to be copy constructed.</param> /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param> /// <param name="newHost">The pattern graph the new alternative will be contained in.</param> /// <param name="nameSuffix">The suffix to be added to the name of the alternative and its elements (to avoid name collisions).</param> /// Elements might have been already copied in the containing pattern(s), their copies have to be reused in this case. public Alternative(Alternative original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix, String pathPrefix_, Dictionary<PatternNode, PatternNode> nodeToCopy, Dictionary<PatternEdge, PatternEdge> edgeToCopy, Dictionary<PatternVariable, PatternVariable> variableToCopy) { name = original.name + nameSuffix + "_in_" + inlinedSubpatternEmbedding.PointOfDefinition.pathPrefix + inlinedSubpatternEmbedding.PointOfDefinition.name; originalSubpatternEmbedding = inlinedSubpatternEmbedding; pathPrefix = pathPrefix_; alternativeCases = new PatternGraph[original.alternativeCases.Length]; for(int i = 0; i < original.alternativeCases.Length; ++i) { PatternGraph altCase = original.alternativeCases[i]; alternativeCases[i] = new PatternGraph(altCase, inlinedSubpatternEmbedding, newHost, nameSuffix, nodeToCopy, edgeToCopy, variableToCopy); } originalAlternative = original; }
/// <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"); }
/// <summary> /// Generates the action interface plus action implementation including the matcher source code /// for the given alternative into the given source builder /// </summary> public void GenerateActionAndMatcherOfAlternative(SourceBuilder sb, LGSPMatchingPattern matchingPattern, Alternative alt, bool isInitialStatic) { // generate the search program out of the schedules within the pattern graphs of the alternative cases SearchProgram searchProgram = GenerateSearchProgramAlternative(matchingPattern, alt); // generate the parallelized search program out of the parallelized schedules within the pattern graphs of the alternative cases SearchProgram searchProgramParallelized = GenerateParallelizedSearchProgramAlternativeAsNeeded(matchingPattern, alt); // emit matcher class head, body, tail; body is source code representing search program GenerateMatcherClassHeadAlternative(sb, matchingPattern, alt, isInitialStatic); searchProgram.Emit(sb); if(searchProgramParallelized != null) searchProgramParallelized.Emit(sb); GenerateMatcherClassTail(sb, matchingPattern.PatternGraph.Package != null); // handle alternatives or iterateds nested in the alternative cases foreach (PatternGraph altCase in alt.alternativeCases) { // nested inside the alternatives,iterateds,negatives,independents foreach (Alternative nestedAlt in altCase.alternativesPlusInlined) { GenerateActionAndMatcherOfAlternative(sb, matchingPattern, nestedAlt, isInitialStatic); } foreach (Iterated iter in altCase.iteratedsPlusInlined) { GenerateActionAndMatcherOfIterated(sb, matchingPattern, iter.iteratedPattern, isInitialStatic); } foreach (PatternGraph neg in altCase.negativePatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, neg, isInitialStatic); } foreach (PatternGraph idpt in altCase.independentPatternGraphsPlusInlined) { GenerateActionAndMatcherOfNestedPatterns(sb, matchingPattern, idpt, isInitialStatic); } } }
/// <summary> /// Generates the parallelized search program for the given alternative /// </summary> SearchProgram GenerateParallelizedSearchProgramAlternativeAsNeeded(LGSPMatchingPattern matchingPattern, Alternative alt) { if(matchingPattern.patternGraph.parallelizedSchedule == null) return null; // build pass: build nested program from scheduled search plans of the alternative cases SearchProgramBuilder searchProgramBuilder = new SearchProgramBuilder(); SearchProgram searchProgram = searchProgramBuilder.BuildSearchProgram(model, matchingPattern, alt, 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_" + 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 + "_parallelized_" + alt.name + "_" + searchProgram.Name + "_completed_dump.txt"); writer.Write(builder.ToString()); writer.Close(); #endif return searchProgram; }
/// <summary> /// Builds search program for alternative from scheduled search plans of the alternative cases /// </summary> public SearchProgram BuildSearchProgram( IGraphModel model, LGSPMatchingPattern matchingPattern, Alternative alternative, bool parallelized, bool emitProfiling) { programType = SearchProgramType.AlternativeCase; this.model = model; patternGraphWithNestingPatterns = new Stack<PatternGraph>(); this.parallelized = parallelized; this.alternative = alternative; rulePatternClassName = NamesOfEntities.RulePatternClassName(matchingPattern.name, matchingPattern.PatternGraph.Package, !(matchingPattern is LGSPRulePattern)); this.emitProfiling = emitProfiling; packagePrefixedActionName = null; firstLoopPassed = false; // build combined list of namesOfPatternGraphsOnPathToEnclosedPatternpath // from the namesOfPatternGraphsOnPathToEnclosedPatternpath of the alternative cases List<string> namesOfPatternGraphsOnPathToEnclosedPatternpath = new List<string>(); for (int i = 0; i < alternative.alternativeCases.Length; ++i) { PatternGraph altCase = alternative.alternativeCases[i]; foreach (String name in altCase.patternGraphsOnPathToEnclosedPatternpath) { if(!namesOfPatternGraphsOnPathToEnclosedPatternpath.Contains(name)) namesOfPatternGraphsOnPathToEnclosedPatternpath.Add(name); } } // build outermost search program operation, create the list anchor starting its program SearchProgram searchProgram = new SearchProgramOfAlternative( rulePatternClassName, namesOfPatternGraphsOnPathToEnclosedPatternpath, "myMatch", parallelized); searchProgram.OperationsList = new SearchProgramList(searchProgram); SearchProgramOperation insertionPoint = searchProgram.OperationsList; // initialize task/result-pushdown handling in subpattern matcher InitializeSubpatternMatching initialize = new InitializeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal); insertionPoint = insertionPoint.Append(initialize); // build alternative matching search programs, one per case for (int i=0; i<alternative.alternativeCases.Length; ++i) { PatternGraph altCase = alternative.alternativeCases[i]; ScheduledSearchPlan scheduledSearchPlan = altCase.schedulesIncludingNegativesAndIndependents[0]; string inlinedPatternClassName = rulePatternClassName; string pathPrefixInInlinedPatternClass = scheduledSearchPlan.PatternGraph.pathPrefix; string unprefixedNameInInlinedPatternClass = scheduledSearchPlan.PatternGraph.name; if(alternative.originalAlternative != null) { inlinedPatternClassName = alternative.originalSubpatternEmbedding.matchingPatternOfEmbeddedGraph.GetType().Name; pathPrefixInInlinedPatternClass = alternative.originalAlternative.pathPrefix + alternative.originalAlternative.name + "_"; unprefixedNameInInlinedPatternClass = alternative.originalAlternative.alternativeCases[i].name; } GetPartialMatchOfAlternative matchAlternative = new GetPartialMatchOfAlternative( pathPrefixInInlinedPatternClass, unprefixedNameInInlinedPatternClass, inlinedPatternClassName, wasIndependentInlined(altCase, indexOfSchedule)); matchAlternative.OperationsList = new SearchProgramList(matchAlternative); SearchProgramOperation continuationPointAfterAltCase = insertionPoint.Append(matchAlternative); // at level of the current alt case insertionPoint = matchAlternative.OperationsList; insertionPoint = insertVariableDeclarations(insertionPoint, altCase); patternGraphWithNestingPatterns.Push(altCase); isoSpaceNeverAboveMaxIsoSpace = patternGraphWithNestingPatterns.Peek().maxIsoSpace < (int)LGSPElemFlags.MAX_ISO_SPACE; isNegative = false; isNestedInNegative = false; // start building with first operation in scheduled search plan indexOfSchedule = 0; BuildScheduledSearchPlanOperationIntoSearchProgram( 0, insertionPoint); // back to level of alt cases insertionPoint = continuationPointAfterAltCase; // save matches found by alternative case to get clean start for matching next alternative case if(i<alternative.alternativeCases.Length-1) { NewMatchesListForFollowingMatches newMatchesList = new NewMatchesListForFollowingMatches(true); insertionPoint = insertionPoint.Append(newMatchesList); } patternGraphWithNestingPatterns.Pop(); } // finalize task/result-pushdown handling in subpattern matcher FinalizeSubpatternMatching finalize = new FinalizeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal); insertionPoint = insertionPoint.Append(finalize); return searchProgram; }