Example #1
0
        /// <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;
        }