Beispiel #1
0
        private static void GetFilteredParametersAndSuffixedMatcherName(
            LGSPRulePattern rulePattern, PatternGraph patternGraph, int index,
            out String[] paramTypesArray, out String[] paramNamesArray, out String suffixedMatcherName)
        {
            List <String> paramTypes   = new List <String>();
            List <String> paramNames   = new List <String>();
            List <String> removedNames = new List <String>();

            for (int i = 0; i < rulePattern.Inputs.Length; ++i)
            {
                String inputName = rulePattern.InputNames[i];
                if (patternGraph.availabilityOfMaybeNullElements[index].ContainsKey(inputName) &&
                    !patternGraph.availabilityOfMaybeNullElements[index][inputName])
                {
                    removedNames.Add(rulePattern.InputNames[i]);
                }
                else
                {
                    paramTypes.Add(TypesHelper.TypeName(rulePattern.Inputs[i]));
                    paramNames.Add(rulePattern.InputNames[i]);
                }
            }
            paramTypesArray = new String[paramTypes.Count];
            paramNamesArray = new String[paramNames.Count];
            for (int i = 0; i < paramTypes.Count; ++i)
            {
                paramTypesArray[i] = paramTypes[i];
                paramNamesArray[i] = paramNames[i];
            }
            suffixedMatcherName = "myMatch";
            foreach (String removedName in removedNames)
            {
                suffixedMatcherName += "_MissingPreset_" + removedName;
            }
        }
        /// <summary>
        /// Maps the multiple component pattern.
        /// </summary>
        /// <param name="pattern">The pattern.</param>
        /// <param name="componentMatches">The component matches.</param>
        /// <returns>The founddesignpatterns model, with the pattern and a list of implementations</returns>
        private FoundDesignPattern MapMultipleComponentPattern(DesignPattern pattern, Dictionary <Component, List <ComponentMatch> > componentMatches)
        {
            var foundPattern = new FoundDesignPattern()
            {
                DesignPattern   = pattern,
                Implementations = new List <Dictionary <Component, List <SymbolInformation> > >()
            };

            var graph = new PatternGraph(pattern);
            var implementationCandidates = this.GetPatternImplementations(graph, componentMatches);

            foreach (var implementationCandidate in implementationCandidates)
            {
                var cleanedImplementation = this.RemoveDuplicateComponentMatches(implementationCandidate);

                if (this.MatchComponentCount(pattern, cleanedImplementation))
                {
                    var checkedImplementation = this.MatchImplementationComponentTypes(graph, cleanedImplementation);

                    if (this.MatchComponentCount(pattern, checkedImplementation) && this.ValidComponentOccurrence(checkedImplementation))
                    {
                        foundPattern.Implementations.Add(this.CastDictionary(checkedImplementation));
                    }
                }
            }

            if (foundPattern.Implementations.Count > 0)
            {
                return(foundPattern);
            }

            return(null);
        }
Beispiel #3
0
 /// <summary>
 /// Inserts schedules of negative and independent pattern graphs into the schedule of the enclosing pattern graph
 /// </summary>
 private static void InsertNegativesAndIndependentsIntoSchedule(PatternGraph patternGraph, bool lazyNegativeIndependentConditionEvaluation)
 {
     for (int i = 0; i < patternGraph.schedules.Length; ++i)
     {
         InsertNegativesAndIndependentsIntoSchedule(patternGraph, i, lazyNegativeIndependentConditionEvaluation);
     }
 }
Beispiel #4
0
		private Rule_testRule()
		{
			PatternNode node_p2 = new PatternNode((int) NodeTypes.@Process, "node_p2", node_p2_AllowedTypes, node_p2_IsAllowedType, PatternElementType.Normal, -1);
			PatternNode node_p1 = new PatternNode((int) NodeTypes.@Process, "node_p1", node_p1_AllowedTypes, node_p1_IsAllowedType, PatternElementType.Normal, -1);
			PatternEdge edge__edge0 = new PatternEdge(node_p1, node_p2, (int) EdgeTypes.@connection, "edge__edge0", edge__edge0_AllowedTypes, edge__edge0_IsAllowedType, PatternElementType.Normal, -1);
			patternGraph = new PatternGraph(
				new PatternNode[] { node_p2, node_p1 }, 
				new PatternEdge[] { edge__edge0 }, 
				new Condition[] { },
				new bool[2, 2] {
					{ true, false, },
					{ false, true, },
				},
				new bool[1, 1] {
					{ true, },
				},
				new bool[] {
					false, false, },
				new bool[] {
					false, }
			);

			negativePatternGraphs = new PatternGraph[] {};
			inputs = new GrGenType[] { };
			outputs = new GrGenType[] { };
		}
Beispiel #5
0
        private Rule_testRule()
        {
            PatternNode node_p2     = new PatternNode((int)NodeTypes.@Process, "node_p2", node_p2_AllowedTypes, node_p2_IsAllowedType, PatternElementType.Normal, -1);
            PatternNode node_p1     = new PatternNode((int)NodeTypes.@Process, "node_p1", node_p1_AllowedTypes, node_p1_IsAllowedType, PatternElementType.Normal, -1);
            PatternEdge edge__edge0 = new PatternEdge(node_p1, node_p2, (int)EdgeTypes.@connection, "edge__edge0", edge__edge0_AllowedTypes, edge__edge0_IsAllowedType, PatternElementType.Normal, -1);

            patternGraph = new PatternGraph(
                new PatternNode[] { node_p2, node_p1 },
                new PatternEdge[] { edge__edge0 },
                new Condition[] { },
                new bool[2, 2] {
                { true, false, },
                { false, true, },
            },
                new bool[1, 1] {
                { true, },
            },
                new bool[] {
                false, false,
            },
                new bool[] {
                false,
            }
                );

            negativePatternGraphs = new PatternGraph[] {};
            inputs  = new GrGenType[] { };
            outputs = new GrGenType[] { };
        }
Beispiel #6
0
        /// <summary>
        /// Non- is-matched-flag-based isomorphy checking for nested alternative cases/iterateds
        /// </summary>
        private static void ParallelizeAlternativeIterated(PatternGraph patternGraph)
        {
            foreach (Alternative alt in patternGraph.alternativesPlusInlined)
            {
                foreach (PatternGraph altCase in alt.alternativeCases)
                {
                    ScheduledSearchPlan ssp = altCase.schedulesIncludingNegativesAndIndependents[0];
                    altCase.parallelizedSchedule = new ScheduledSearchPlan[1];
                    List <SearchOperation> operations = new List <SearchOperation>(ssp.Operations.Length);
                    for (int i = 0; i < ssp.Operations.Length; ++i)
                    {
                        SearchOperation so    = ssp.Operations[i];
                        SearchOperation clone = (SearchOperation)so.Clone();
                        clone.Isomorphy.Parallel = true;
                        operations.Add(clone);
                        if (clone.Element is PatternCondition)
                        {
                            SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                        }
                    }
                    ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan(
                        altCase, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0);
                    altCase.parallelizedSchedule[0] = clonedSsp;

                    ParallelizeNegativeIndependent(clonedSsp);
                    ParallelizeAlternativeIterated(altCase);
                    ParallelizeYielding(altCase);
                }
            }
            foreach (Iterated iter in patternGraph.iteratedsPlusInlined)
            {
                ScheduledSearchPlan ssp = iter.iteratedPattern.schedulesIncludingNegativesAndIndependents[0];
                iter.iteratedPattern.parallelizedSchedule = new ScheduledSearchPlan[1];
                List <SearchOperation> operations = new List <SearchOperation>(ssp.Operations.Length);
                for (int i = 0; i < ssp.Operations.Length; ++i)
                {
                    SearchOperation so    = ssp.Operations[i];
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel = true;
                    operations.Add(clone);
                    if (clone.Element is PatternCondition)
                    {
                        SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                    }
                }
                ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan(
                    iter.iteratedPattern, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0);
                iter.iteratedPattern.parallelizedSchedule[0] = clonedSsp;

                ParallelizeNegativeIndependent(clonedSsp);
                ParallelizeAlternativeIterated(iter.iteratedPattern);
                ParallelizeYielding(iter.iteratedPattern);
            }
        }
Beispiel #7
0
 private static void ParallelizeYielding(PatternGraph patternGraph)
 {
     patternGraph.parallelizedYieldings = new PatternYielding[patternGraph.YieldingsPlusInlined.Length];
     for (int i = 0; i < patternGraph.YieldingsPlusInlined.Length; ++i)
     {
         patternGraph.parallelizedYieldings[i] = (PatternYielding)patternGraph.YieldingsPlusInlined[i].Clone();
         for (int j = 0; j < patternGraph.parallelizedYieldings[i].ElementaryYieldings.Length; ++j)
         {
             SetNeedForParallelizedVersion(patternGraph.parallelizedYieldings[i].ElementaryYieldings[j]);
         }
     }
 }
        /// <summary>
        /// Matches the remaining component.
        /// </summary>
        /// <param name="graph">The graph.</param>
        /// <param name="remainingMatch">The remaining match.</param>
        /// <param name="foundComponents">The found components.</param>
        /// <returns>The component if it has been matched, null otherwise.</returns>
        private GraphComponent MatchRemainingComponent(PatternGraph graph, KeyValuePair <Component, List <ComponentMatch> > remainingMatch, List <GraphComponent> foundComponents)
        {
            var componentMatchFound = false;

            // check if the component inherits any found components
            var remainingMatchGraphComponent = graph.GetGraphComponent(remainingMatch.Key.Name);
            var foundComponentReferences     = remainingMatchGraphComponent.References.Where(r => foundComponents.Contains(r.ReferencedComponent));

            if (foundComponentReferences.Any())
            {
                var componentRef = foundComponentReferences.First();

                this.MatchComponentTypes(remainingMatchGraphComponent, componentRef.ReferencedComponent, componentRef, remainingMatch.Value, true);
                componentMatchFound = true;
            }
            else
            {
                // otherwise check if the component is inherited by any found components
                var referencedByFoundComponents = foundComponents.Where(c => c.References.Any(r => r.ReferencedComponent == remainingMatchGraphComponent));

                if (referencedByFoundComponents.Any())
                {
                    var refByComponent          = referencedByFoundComponents.First();
                    var refByComponentReference = refByComponent.References.Single(r => r.ReferencedComponent == remainingMatchGraphComponent);

                    this.MatchComponentTypes(refByComponent, remainingMatchGraphComponent, refByComponentReference, remainingMatch.Value, false);
                    componentMatchFound = true;
                }
            }

            if (componentMatchFound)
            {
                return(remainingMatchGraphComponent);
            }

            return(null);
        }
Beispiel #9
0
 private static void InsertInlinedElementIdentityCheckIntoSchedule(PatternGraph patternGraph, List <SearchOperation> operations)
 {
     for (int i = 0; i < operations.Count; ++i)
     {
         PatternElement assignmentSource = null;
         if (operations[i].Element is SearchPlanNode)
         {
             assignmentSource = ((SearchPlanNode)operations[i].Element).PatternElement.AssignmentSource;
         }
         if (assignmentSource != null && operations[i].Type != SearchOperationType.Identity)
         {
             for (int j = 0; j < operations.Count; ++j)
             {
                 SearchPlanNode binder = null;
                 if (operations[j].Element is SearchPlanNode)
                 {
                     binder = (SearchPlanNode)operations[j].Element;
                 }
                 if (binder != null &&
                     binder.PatternElement == assignmentSource &&
                     operations[j].Type != SearchOperationType.Identity)
                 {
                     if (operations[i].Type != SearchOperationType.Assign &&
                         operations[j].Type != SearchOperationType.Assign)
                     {
                         int             indexOfSecond = Math.Max(i, j);
                         SearchOperation so            = new SearchOperation(SearchOperationType.Identity,
                                                                             operations[i].Element, binder, operations[indexOfSecond].CostToEnd);
                         operations.Insert(indexOfSecond + 1, so);
                         break;
                     }
                 }
             }
         }
     }
 }
        private static void CreatePlanNodeAndLookupPlanEdge(PatternEdge edge, int elemId, 
            LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isNegativeOrIndependent, bool isSubpatternLike, PlanNode planRoot, float zeroCost,
            IDictionary<PatternNode, PatternNode> originalToInlinedIndependent, IDictionary<PatternElement, SetValueType> presetsFromIndependentInlining,
            out bool isPreset, out PlanNode planNode, out PlanEdge rootToNodePlanEdge)
        {
            float cost;
            SearchOperationType searchOperationType;
            if(edge.DefToBeYieldedTo)
            {
                cost = zeroCost;
                isPreset = true;
                searchOperationType = SearchOperationType.DefToBeYieldedTo;
            }
            else if(edge.PointOfDefinition == null)
            {
                cost = zeroCost;
                isPreset = true;
                searchOperationType = isSubpatternLike ? SearchOperationType.SubPreset : SearchOperationType.ActionPreset;
            }
            else if(edge.PointOfDefinition != patternGraph && edge.OriginalIndependentElement == null)
            {
                cost = zeroCost;
                isPreset = true;
                searchOperationType = isNegativeOrIndependent ? SearchOperationType.NegIdptPreset : SearchOperationType.SubPreset;
            }
            else if(presetsFromIndependentInlining.ContainsKey(edge))
            {
                cost = zeroCost;
                isPreset = true;
                searchOperationType = SearchOperationType.NegIdptPreset;
                edge.PresetBecauseOfIndependentInlining = true;
            }
            else if(edge.Storage != null)
            {
                if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null)
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation
                }
                else
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.PickFromStorage; // pick from storage instead of lookup from graph
                }
            }
            else if(edge.IndexAccess != null)
            {
                if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null)
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation
                }
                else
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.PickFromIndex; // pick from index instead of lookup from graph
                }
            }
            else if(edge.NameLookup != null)
            {
                if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null)
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation
                }
                else
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.PickByName; // pick by name instead of lookup from graph
                }
            }
            else if(edge.UniqueLookup != null)
            {
                if(edge.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() != null)
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.Void; // the element we depend on is needed, so there is no lookup like operation
                }
                else
                {
                    cost = zeroCost;
                    isPreset = false;
                    searchOperationType = SearchOperationType.PickByUnique; // pick by unique instead of lookup from graph
                }
            }
            else if(edge.ElementBeforeCasting != null)
            {
                cost = zeroCost;
                isPreset = false;
                searchOperationType = SearchOperationType.Void; // the element before casting is needed, so there is no lookup like operation
            }
            else
            {
                cost = graphStatistics.edgeCounts[edge.TypeID];
                cost = CostIncreaseForInlinedIndependent(edge, cost);

                isPreset = false;
                searchOperationType = SearchOperationType.Lookup;
            }

            PatternNode source = GetSourcePlusInlined(edge, patternGraph, originalToInlinedIndependent);
            PatternNode target = GetTargetPlusInlined(edge, patternGraph, originalToInlinedIndependent);
            planNode = new PlanNode(edge, elemId, isPreset,
                source != null ? source.TempPlanMapping : null,
                target != null ? target.TempPlanMapping : null);
            rootToNodePlanEdge = null;
            if(searchOperationType != SearchOperationType.Void)
                rootToNodePlanEdge = new PlanEdge(searchOperationType, planRoot, planNode, cost);
        }
 public static IEnumerable<PatternNode> NodesInIndependentMatchedThere(PatternGraph independent)
 {
     foreach(PatternNode node in independent.nodesPlusInlined)
     {
         if(node.PointOfDefinition == independent && !node.defToBeYieldedTo)
             yield return node;
     }
 }
        /// <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);
            }
        }
        public static void SetNeedForProfiling(PatternGraph patternGraph)
        {
            foreach(PatternCondition condition in patternGraph.Conditions)
            {
                SetNeedForProfiling(condition.ConditionExpression);
            }
            foreach(PatternYielding patternYielding in patternGraph.Yieldings)
            {
                foreach(Yielding yielding in patternYielding.ElementaryYieldings)
                {
                    SetNeedForProfiling(yielding);
                }
            }

            foreach(PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined)
            {
                SetNeedForProfiling(idpt);
            }
            foreach(PatternGraph neg in patternGraph.negativePatternGraphsPlusInlined)
            {
                SetNeedForProfiling(neg);
            }

            foreach(Alternative alt in patternGraph.alternativesPlusInlined)
            {
                foreach(PatternGraph altCase in alt.alternativeCases)
                {
                    SetNeedForProfiling(altCase);
                }
            }
            foreach(Iterated iter in patternGraph.iteratedsPlusInlined)
            {
                SetNeedForProfiling(iter.iteratedPattern);
            }
        }
        /// <summary>
        /// Matches the component match types, with the implementations.
        /// </summary>
        /// <param name="graph">The graph.</param>
        /// <param name="possibleImplementation">The possible implementation.</param>
        private Dictionary <Component, List <ComponentMatch> > MatchImplementationComponentTypes(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > possibleImplementation)
        {
            var componentsToRemove = new List <Component>();

            foreach (var componentToCheck in possibleImplementation)
            {
                var componentToCheckMatch = componentToCheck.Value[0];
                var currentComponent      = componentToCheck.Key;
                var currentGraphComponent = graph.GetGraphComponent(currentComponent.Name);

                var otherComponents      = possibleImplementation.Where(i => i.Key != currentComponent);
                var otherGraphComponents = graph.GetGraphComponents(otherComponents.Select(c => c.Key.Name));

                var currentComponentReferences   = currentGraphComponent.References;
                var currentComponentReferencedBy = otherGraphComponents.Where(c => c.References.Any(r => r.ReferencedComponent == currentGraphComponent));

                var typeMatch = true;

                foreach (var currentComponentReference in currentComponentReferences)
                {
                    var knownParentTypes = this.GetSymbolInformation(possibleImplementation, currentComponentReference.ReferencedComponent.Component);
                    typeMatch &= this.MatchUnknownChildWithKnownParent(componentToCheckMatch, knownParentTypes, currentComponentReference);
                }

                foreach (var referencedBy in currentComponentReferencedBy)
                {
                    var knownChildTypes = this.GetSymbolInformation(possibleImplementation, referencedBy.Component);
                    var reference       = referencedBy.References.Single(r => r.ReferencedComponent == currentGraphComponent);
                    typeMatch &= this.MatchKnownChildWithUnknownParent(knownChildTypes, componentToCheckMatch, reference);
                }

                // if there is no match, remove the first hit from the pattern. The pattern is incomplete.
                if (!typeMatch)
                {
                    componentsToRemove.Add(currentGraphComponent.Component);
                }
            }

            foreach (var componentToRemove in componentsToRemove)
            {
                possibleImplementation.Remove(componentToRemove);
            }

            return(possibleImplementation);
        }
        /// <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;
        }
        public readonly float Cost;                   // (needed for scheduling nac-subgraphs into the full graph)

        public ScheduledSearchPlan(PatternGraph patternGraph, SearchOperation[] ops, float cost)
        {
            PatternGraph = patternGraph;
            Operations   = ops;
            Cost         = cost;
        }
 /// <summary>
 /// Instantiates a new PatternElement object as a copy from an original element, used for independent inlining.
 /// </summary>
 /// <param name="original">The original pattern element to be copy constructed.</param>
 /// <param name="nameSuffix">The suffix to be added to the name of the pattern element (to avoid name collisions).</param>
 public PatternElement(PatternElement original, String nameSuffix)
 {
     TypeID = original.TypeID;
     typeName = original.typeName;
     name = original.name + nameSuffix;
     unprefixedName = original.unprefixedName + nameSuffix;
     pointOfDefinition = original.pointOfDefinition;
     defToBeYieldedTo = original.defToBeYieldedTo;
     initialization = original.initialization != null ? original.initialization.Copy(nameSuffix) : null;
     annotations = original.annotations;
     AllowedTypes = original.AllowedTypes;
     IsAllowedType = original.IsAllowedType;
     Cost = original.Cost;
     ParameterIndex = original.ParameterIndex;
     MaybeNull = original.MaybeNull;
     Storage = original.Storage != null ? new StorageAccess(original.Storage) : null;
     StorageIndex = original.StorageIndex != null ? new StorageAccessIndex(original.StorageIndex) : null;
     IndexAccess = original.IndexAccess != null ? original.IndexAccess.Copy(nameSuffix) : null;
     NameLookup = original.NameLookup != null ? original.NameLookup.Copy(nameSuffix) : null;
     UniqueLookup = original.UniqueLookup != null ? original.UniqueLookup.Copy(nameSuffix) : null;
     ElementBeforeCasting = original.ElementBeforeCasting;
     AssignmentSource = original.AssignmentSource;
     OriginalIndependentElement = original;
 }
Beispiel #18
0
        /// <summary>
        /// Builds search program from scheduled search plan in pattern graph of the subpattern rule pattern
        /// </summary>
        public static SearchProgram BuildSearchProgram(
            IGraphModel model,
            LGSPMatchingPattern matchingPattern,
            bool parallelized,
            bool emitProfiling)
        {
            Debug.Assert(!(matchingPattern is LGSPRulePattern));

            PatternGraph patternGraph         = matchingPattern.patternGraph;
            String       rulePatternClassName = NamesOfEntities.RulePatternClassName(matchingPattern.name, matchingPattern.PatternGraph.Package, true);

            SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder(
                SearchProgramType.Subpattern,
                model,
                rulePatternClassName,
                null,
                null,
                null,
                patternGraph,
                emitProfiling,
                parallelized,
                0
                );

            List <String> matchingPatternClassTypeNames = new List <String>();
            List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >();

            ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, patternGraph);

            // build outermost search program operation, create the list anchor starting its program
            SearchProgram searchProgram = new SearchProgramOfSubpattern(
                rulePatternClassName,
                patternGraph.Name,
                matchingPattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                "myMatch",
                builder.wasIndependentInlined(patternGraph, 0),
                matchingPatternClassTypeNames, nestedIndependents,
                parallelized);

            searchProgram.OperationsList = new SearchProgramList(searchProgram);
            SearchProgramOperation insertionPoint = searchProgram.OperationsList;

            insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph);

            // initialize task/result-pushdown handling in subpattern matcher
            InitializeSubpatternMatching initialize =
                new InitializeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal);

            insertionPoint = insertionPoint.Append(initialize);

            // start building with first operation in scheduled search plan
            insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram(
                0,
                insertionPoint);

            // finalize task/result-pushdown handling in subpattern matcher
            FinalizeSubpatternMatching finalize =
                new FinalizeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal);

            insertionPoint = insertionPoint.Append(finalize);

            return(searchProgram);
        }
Beispiel #19
0
        /// <summary>
        /// Negative/Independent schedules are merged as an operation into their enclosing schedules,
        /// at a position determined by their costs but not before all of their needed elements were computed
        /// </summary>
        public static void MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(PatternGraph patternGraph, bool lazyNegativeIndependentConditionEvaluation)
        {
            foreach (PatternGraph neg in patternGraph.negativePatternGraphsPlusInlined)
            {
                MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(neg, lazyNegativeIndependentConditionEvaluation);
            }

            foreach (PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined)
            {
                MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(idpt, lazyNegativeIndependentConditionEvaluation);
            }

            foreach (Alternative alt in patternGraph.alternativesPlusInlined)
            {
                foreach (PatternGraph altCase in alt.alternativeCases)
                {
                    MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(altCase, lazyNegativeIndependentConditionEvaluation);
                }
            }

            foreach (Iterated iter in patternGraph.iteratedsPlusInlined)
            {
                MergeNegativeAndIndependentSchedulesIntoEnclosingSchedules(iter.iteratedPattern, lazyNegativeIndependentConditionEvaluation);
            }

            InsertNegativesAndIndependentsIntoSchedule(patternGraph, lazyNegativeIndependentConditionEvaluation);
        }
Beispiel #20
0
        private static void ExtractNestedIndependents(List <String> matchingPatternClassTypeNames, List <Dictionary <PatternGraph, bool> > nestedIndependents,
                                                      LGSPMatchingPattern matchingPattern, PatternGraph patternGraph)
        {
            matchingPatternClassTypeNames.Add(matchingPattern.GetType().Name);
            nestedIndependents.Add(patternGraph.nestedIndependents);

            foreach (PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined)
            {
                ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, idpt);
            }
        }
Beispiel #21
0
        /// <summary>
        /// Inserts declarations for variables extracted from parameters
        /// </summary>
        private static SearchProgramOperation insertVariableDeclarations(SearchProgramOperation insertionPoint, PatternGraph patternGraph)
        {
            foreach (PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if (!var.defToBeYieldedTo) // def variables are handled with the schedule, must come after the presets
                {
                    // inlined variables are handled later, cause they may depend on elements matched
                    if (var.originalVariable == null || !patternGraph.WasInlinedHere(var.originalSubpatternEmbedding))
                    {
                        insertionPoint = insertionPoint.Append(
                            new ExtractVariable(TypesHelper.TypeName(var.type), var.Name)
                            );
                    }
                }
            }

            return(insertionPoint);
        }
Beispiel #22
0
        /// <summary>
        /// Builds search program for iterated from scheduled search plan of iterated pattern graph
        /// </summary>
        public static SearchProgram BuildSearchProgram(
            IGraphModel model,
            LGSPMatchingPattern matchingPattern,
            PatternGraph iter,
            bool parallelized,
            bool emitProfiling)
        {
            String rulePatternClassName = NamesOfEntities.RulePatternClassName(matchingPattern.name, matchingPattern.PatternGraph.Package, !(matchingPattern is LGSPRulePattern));

            SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder(
                SearchProgramType.Iterated,
                model,
                rulePatternClassName,
                null,
                null,
                null,
                iter,
                emitProfiling,
                parallelized,
                0
                );

            List <String> matchingPatternClassTypeNames = new List <String>();
            List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >();

            ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, iter);

            // build outermost search program operation, create the list anchor starting its program
            SearchProgram searchProgram = new SearchProgramOfIterated(
                rulePatternClassName,
                matchingPattern.patternGraph.Name,
                iter.Name,
                iter.pathPrefix,
                matchingPattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                "myMatch",
                builder.wasIndependentInlined(iter, 0),
                matchingPatternClassTypeNames, nestedIndependents,
                parallelized);

            searchProgram.OperationsList = new SearchProgramList(searchProgram);
            SearchProgramOperation insertionPoint = searchProgram.OperationsList;

            insertionPoint = insertVariableDeclarations(insertionPoint, iter);

            // initialize task/result-pushdown handling in subpattern matcher for iteration
            InitializeSubpatternMatching initialize =
                new InitializeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Iteration);

            insertionPoint = insertionPoint.Append(initialize);

            IteratedMatchingDummyLoop iteratedMatchingDummyLoop = new IteratedMatchingDummyLoop();
            SearchProgramOperation    continuationPointAfterIteratedMatching = insertionPoint.Append(iteratedMatchingDummyLoop);

            iteratedMatchingDummyLoop.NestedOperationsList = new SearchProgramList(iteratedMatchingDummyLoop);
            insertionPoint = iteratedMatchingDummyLoop.NestedOperationsList;

            // start building with first operation in scheduled search plan
            insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram(
                0,
                insertionPoint);

            insertionPoint = continuationPointAfterIteratedMatching;

            // check whether iteration came to an end (pattern not found (again)) and handle it
            insertionPoint = builder.insertEndOfIterationHandling(insertionPoint);

            // finalize task/result-pushdown handling in subpattern matcher for iteration
            FinalizeSubpatternMatching finalize =
                new FinalizeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Iteration);

            insertionPoint = insertionPoint.Append(finalize);

            return(searchProgram);
        }
        public static int NumEdgesInIndependentsMatchedThere(PatternGraph patternGraph)
        {
            int sum = 0;
            
            foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined)
            {
                foreach(PatternEdge edge in independent.edgesPlusInlined)
                {
                    if(edge.PointOfDefinition == independent && !edge.defToBeYieldedTo)
                        ++sum;
                }
            }

            return sum;
        }
Beispiel #24
0
        /// <summary>
        /// Inserts schedules of negative and independent pattern graphs into the schedule of the enclosing pattern graph
        /// for the schedule with the given array index
        /// </summary>
        private static void InsertNegativesAndIndependentsIntoSchedule(PatternGraph patternGraph, int index, bool lazyNegativeIndependentConditionEvaluation)
        {
            // todo: erst implicit node, dann negative/independent, auch wenn negative/independent mit erstem implicit moeglich wird
            patternGraph.schedulesIncludingNegativesAndIndependents[index] = null; // an explain might have filled this

            List <SearchOperation> operations = new List <SearchOperation>();

            for (int i = 0; i < patternGraph.schedules[index].Operations.Length; ++i)
            {
                operations.Add(patternGraph.schedules[index].Operations[i]);
            }

            // nested patterns on the way to an enclosed patternpath modifier
            // must get matched after all local nodes and edges, because they require
            // all outer elements to be known in order to lock them for patternpath processing
            if (patternGraph.patternGraphsOnPathToEnclosedPatternpath
                .Contains(patternGraph.pathPrefix + patternGraph.name))
            {
                operations.Add(new SearchOperation(SearchOperationType.LockLocalElementsForPatternpath, null, null,
                                                   patternGraph.schedules[index].Operations.Length != 0 ? patternGraph.schedules[index].Operations[patternGraph.schedules[index].Operations.Length - 1].CostToEnd : 0));
            }

            // iterate over all negative scheduled search plans (TODO: order?)
            for (int i = 0; i < patternGraph.negativePatternGraphsPlusInlined.Length; ++i)
            {
                ScheduledSearchPlan negSchedule = patternGraph.negativePatternGraphsPlusInlined[i].schedulesIncludingNegativesAndIndependents[0];
                int   bestFitIndex     = operations.Count;
                float bestFitCostToEnd = 0;

                // find best place in scheduled search plan for current negative pattern
                // during search from end of schedule forward until the first element the negative pattern is dependent on is found
                for (int j = operations.Count - 1; j >= 0; --j)
                {
                    SearchOperation op = operations[j];
                    if (op.Type == SearchOperationType.Condition ||
                        op.Type == SearchOperationType.NegativePattern ||
                        op.Type == SearchOperationType.IndependentPattern ||
                        op.Type == SearchOperationType.AssignVar)
                    {
                        continue;
                    }

                    if (lazyNegativeIndependentConditionEvaluation)
                    {
                        break;
                    }

                    if (op.Type == SearchOperationType.LockLocalElementsForPatternpath ||
                        op.Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        break; // LockLocalElementsForPatternpath and DefToBeYieldedTo are barriers for neg/idpt
                    }

                    if (patternGraph.negativePatternGraphsPlusInlined[i].neededNodes.ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name) ||
                        patternGraph.negativePatternGraphsPlusInlined[i].neededEdges.ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name))
                    {
                        break;
                    }

                    if (negSchedule.Cost <= op.CostToEnd)
                    {
                        // best fit as CostToEnd is monotonously growing towards operation[0]
                        bestFitIndex     = j;
                        bestFitCostToEnd = op.CostToEnd;
                    }
                }

                // insert pattern at best position
                operations.Insert(bestFitIndex, new SearchOperation(SearchOperationType.NegativePattern,
                                                                    negSchedule, null, bestFitCostToEnd + negSchedule.Cost));

                // update costs of operations before best position
                for (int j = 0; j < bestFitIndex; ++j)
                {
                    operations[j].CostToEnd += negSchedule.Cost;
                }
            }

            // iterate over all independent scheduled search plans (TODO: order?)
            for (int i = 0; i < patternGraph.independentPatternGraphsPlusInlined.Length; ++i)
            {
                ScheduledSearchPlan idptSchedule = patternGraph.independentPatternGraphsPlusInlined[i].schedulesIncludingNegativesAndIndependents[0];
                int   bestFitIndex     = operations.Count;
                float bestFitCostToEnd = 0;

                IDictionary <PatternElement, SetValueType> presetsFromIndependentInlining = ExtractOwnElements(patternGraph.schedules[index], patternGraph.independentPatternGraphsPlusInlined[i]);

                // find best place in scheduled search plan for current independent pattern
                // during search from end of schedule forward until the first element the independent pattern is dependent on is found
                for (int j = operations.Count - 1; j >= 0; --j)
                {
                    SearchOperation op = operations[j];
                    if (op.Type == SearchOperationType.Condition ||
                        op.Type == SearchOperationType.NegativePattern ||
                        op.Type == SearchOperationType.IndependentPattern ||
                        op.Type == SearchOperationType.AssignVar)
                    {
                        continue;
                    }

                    if (lazyNegativeIndependentConditionEvaluation)
                    {
                        break;
                    }

                    if (op.Type == SearchOperationType.LockLocalElementsForPatternpath ||
                        op.Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        break; // LockLocalElementsForPatternpath and DefToBeYieldedTo are barriers for neg/idpt
                    }

                    PatternElement pe = ((SearchPlanNode)op.Element).PatternElement;
                    if (patternGraph.independentPatternGraphsPlusInlined[i].neededNodes.ContainsKey(pe.Name) ||
                        patternGraph.independentPatternGraphsPlusInlined[i].neededEdges.ContainsKey(pe.Name))
                    {
                        break;
                    }

                    if (pe.OriginalIndependentElement != null &&
                        presetsFromIndependentInlining.ContainsKey(pe.OriginalIndependentElement))
                    {
                        break;
                    }

                    if (idptSchedule.Cost <= op.CostToEnd)
                    {
                        // best fit as CostToEnd is monotonously growing towards operation[0]
                        bestFitIndex     = j;
                        bestFitCostToEnd = op.CostToEnd;
                    }
                }

                // insert pattern at best position
                operations.Insert(bestFitIndex, new SearchOperation(SearchOperationType.IndependentPattern,
                                                                    idptSchedule, null, bestFitCostToEnd + idptSchedule.Cost));

                // update costs of operations before best position
                for (int j = 0; j < bestFitIndex; ++j)
                {
                    operations[j].CostToEnd += idptSchedule.Cost;
                }
            }

            InsertInlinedIndependentCheckForDuplicateMatch(operations);

            float cost = operations.Count > 0 ? operations[0].CostToEnd : 0;

            patternGraph.schedulesIncludingNegativesAndIndependents[index] =
                new ScheduledSearchPlan(patternGraph, operations.ToArray(), cost);
        }
Beispiel #25
0
        /// <summary>
        /// Builds search program for alternative from scheduled search plans of the alternative cases
        /// </summary>
        public static SearchProgram BuildSearchProgram(
            IGraphModel model,
            LGSPMatchingPattern matchingPattern,
            Alternative alternative,
            bool parallelized,
            bool emitProfiling)
        {
            String rulePatternClassName = NamesOfEntities.RulePatternClassName(matchingPattern.name, matchingPattern.PatternGraph.Package, !(matchingPattern is LGSPRulePattern));

            // build combined list of namesOfPatternGraphsOnPathToEnclosedPatternpath
            // from the namesOfPatternGraphsOnPathToEnclosedPatternpath of the alternative cases
            // also build combined lists of matching pattern class type names and nested independents
            List <string> namesOfPatternGraphsOnPathToEnclosedPatternpath = new List <string>();
            List <string> matchingPatternClassTypeNames = new List <string>();
            List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >();

            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);
                    }
                }

                ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, matchingPattern, altCase);
            }

            // build outermost search program operation, create the list anchor starting its program
            SearchProgram searchProgram = new SearchProgramOfAlternative(
                rulePatternClassName,
                namesOfPatternGraphsOnPathToEnclosedPatternpath,
                "myMatch",
                matchingPatternClassTypeNames, nestedIndependents,
                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;
                }

                SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder(
                    SearchProgramType.AlternativeCase,
                    model,
                    rulePatternClassName,
                    null,
                    null,
                    null,
                    altCase,
                    emitProfiling,
                    parallelized,
                    0
                    );

                AlternativeCaseMatching alternativeCaseMatching = new AlternativeCaseMatching(
                    pathPrefixInInlinedPatternClass,
                    unprefixedNameInInlinedPatternClass,
                    inlinedPatternClassName,
                    builder.wasIndependentInlined(altCase, 0));
                alternativeCaseMatching.OperationsList = new SearchProgramList(alternativeCaseMatching);
                SearchProgramOperation continuationPointAfterAltCase = insertionPoint.Append(alternativeCaseMatching);

                // at level of the current alt case
                insertionPoint = alternativeCaseMatching.OperationsList;
                insertionPoint = insertVariableDeclarations(insertionPoint, altCase);

                // start building with first operation in scheduled search plan

                builder.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);
                }
            }

            // finalize task/result-pushdown handling in subpattern matcher
            FinalizeSubpatternMatching finalize =
                new FinalizeSubpatternMatching(InitializeFinalizeSubpatternMatchingType.Normal);

            insertionPoint = insertionPoint.Append(finalize);

            return(searchProgram);
        }
 private ScheduledSearchPlan(PatternGraph patternGraph, float cost)
 {
     PatternGraph = patternGraph;
     Cost         = cost;
 }
 /// <summary>
 /// Instantiates a new PatternEdge object as a copy from an original edge, used for subpattern inlining.
 /// </summary>
 /// <param name="original">The original pattern edge to be copy constructed.</param>
 /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param>
 /// <param name="newHost">The pattern graph the new pattern element will be contained in.</param>
 /// <param name="nameSuffix">The suffix to be added to the name of the pattern edge (to avoid name collisions).</param>
 public PatternEdge(PatternEdge original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix)
     : base(original, inlinedSubpatternEmbedding, newHost, nameSuffix)
 {
     fixedDirection = original.fixedDirection;
 }
        /// <summary>
        /// Gets the pattern implementations.
        /// </summary>
        /// <param name="pattern">The pattern.</param>
        /// <param name="componentMatches">The component matches.</param>
        /// <returns>A list of pattern implementations that need to be checked on completeness</returns>
        private List <Dictionary <Component, List <ComponentMatch> > > GetPatternImplementations(PatternGraph graph, Dictionary <Component, List <ComponentMatch> > componentMatches)
        {
            this.possibleImplementations = new List <Dictionary <Component, List <ComponentMatch> > >();
            var singularComponentNames = graph.GetSingularComponentNames();

            if (singularComponentNames.Count == 0)
            {
                // Todo. Not supported for v1. - Removed exception, just return null.
                return(null);
            }

            var startGraphComponent   = graph.GetGraphComponent(singularComponentNames[0]);
            var startComponentMatches = componentMatches[startGraphComponent.Component];

            foreach (var startComponentMatch in startComponentMatches)
            {
                this.possibleImplementations.Add(new Dictionary <Component, List <ComponentMatch> >()
                {
                    { startGraphComponent.Component, new List <ComponentMatch>()
                      {
                          startComponentMatch
                      } }
                });
            }

            var foundComponents = new List <GraphComponent>()
            {
                startGraphComponent
            };

            return(this.MapImplementations(graph, foundComponents, componentMatches));
        }
        /// <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);
            }
        }
Beispiel #30
0
        public static IDictionary <PatternElement, SetValueType> ExtractOwnElements(ScheduledSearchPlan nestingScheduledSearchPlan, PatternGraph patternGraph)
        {
            Dictionary <PatternElement, SetValueType> ownElements = new Dictionary <PatternElement, SetValueType>();

            // elements contained in the schedule of the nesting pattern, that are declared in the current pattern graph
            // stem from inlining an indepent, extract them to treat them specially in search plan building (preset from nesting pattern)
            if (nestingScheduledSearchPlan != null)
            {
                for (int i = 0; i < nestingScheduledSearchPlan.Operations.Length; ++i)
                {
                    if (nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.Condition ||
                        nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.AssignVar ||
                        nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        continue;
                    }

                    SearchPlanNode spn = (SearchPlanNode)nestingScheduledSearchPlan.Operations[i].Element;
                    if (spn.PatternElement.pointOfDefinition == patternGraph)
                    {
                        ownElements.Add(spn.PatternElement.OriginalIndependentElement, null);
                    }
                }
            }

            return(ownElements);
        }
        /// <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");
        }
 public static PatternNode GetSourcePlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent)
 {
     PatternNode source = patternGraph.GetSourcePlusInlined(edge);
     if(edge.OriginalIndependentElement != null && source == null)
     {
         PatternNode sourceOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetSourcePlusInlined((PatternEdge)edge.OriginalIndependentElement);
         if(originalToInlinedIndependent.ContainsKey(sourceOriginal))
             source = originalToInlinedIndependent[sourceOriginal];
         else
             source = sourceOriginal; // not declared in independent itself, but in some parent
     }
     return source;
 }
        /// <summary>
        /// Generates scheduled search plans needed for matcher code generation for action compilation
        /// out of graph with analyze information, 
        /// The scheduled search plans are added to the main and the nested pattern graphs.
        /// </summary>
        public void GenerateScheduledSearchPlans(PatternGraph patternGraph, LGSPGraph graph,
            bool isSubpatternLike, bool isNegativeOrIndependent, 
            ScheduledSearchPlan nestingScheduledSearchPlan)
        {
            for(int i=0; i<patternGraph.schedules.Length; ++i)
            {
                patternGraph.AdaptToMaybeNull(i);
                if(Profile)
                    SetNeedForProfiling(patternGraph);
                PlanGraph planGraph = GeneratePlanGraph(graph.statistics, patternGraph,
                    isNegativeOrIndependent, isSubpatternLike,
                    ExtractOwnElements(nestingScheduledSearchPlan, patternGraph));
                MarkMinimumSpanningArborescence(planGraph, patternGraph.name);
                SearchPlanGraph searchPlanGraph = GenerateSearchPlanGraph(planGraph);
                ScheduledSearchPlan scheduledSearchPlan = ScheduleSearchPlan(
                    searchPlanGraph, patternGraph, isNegativeOrIndependent);
                AppendHomomorphyInformation(scheduledSearchPlan);
                patternGraph.schedules[i] = scheduledSearchPlan;
                patternGraph.RevertMaybeNullAdaption(i);

                foreach(PatternGraph neg in patternGraph.negativePatternGraphsPlusInlined)
                {
                    GenerateScheduledSearchPlans(neg, graph,
                        isSubpatternLike, true, null);
                }

                foreach(PatternGraph idpt in patternGraph.independentPatternGraphsPlusInlined)
                {
                    GenerateScheduledSearchPlans(idpt, graph,
                        isSubpatternLike, true, patternGraph.schedules[i]);
                }

                foreach(Alternative alt in patternGraph.alternativesPlusInlined)
                {
                    foreach (PatternGraph altCase in alt.alternativeCases)
                    {
                        GenerateScheduledSearchPlans(altCase, graph,
                            true, false, null);
                    }
                }

                foreach(Iterated iter in patternGraph.iteratedsPlusInlined)
                {
                    GenerateScheduledSearchPlans(iter.iteratedPattern, graph,
                        true, false, null);
                }
            }
        }
Beispiel #34
0
 protected LGSPAction(PatternGraph patternGraph, object[] returnArray)
 {
     this.patternGraph = patternGraph;
     this.ReturnArray  = returnArray;
 }
        public static IDictionary<PatternElement, SetValueType> ExtractOwnElements(ScheduledSearchPlan nestingScheduledSearchPlan, PatternGraph patternGraph)
        {
            Dictionary<PatternElement, SetValueType> ownElements = new Dictionary<PatternElement,SetValueType>();

            // elements contained in the schedule of the nesting pattern, that are declared in the current pattern graph
            // stem from inlining an indepent, extract them to treat them specially in search plan building (preset from nesting pattern)
            if(nestingScheduledSearchPlan != null)
            {
                for(int i = 0; i < nestingScheduledSearchPlan.Operations.Length; ++i)
                {
                    if(nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.Condition
                        || nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.AssignVar
                        || nestingScheduledSearchPlan.Operations[i].Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        continue;
                    }

                    SearchPlanNode spn = (SearchPlanNode)nestingScheduledSearchPlan.Operations[i].Element;
                    if(spn.PatternElement.pointOfDefinition == patternGraph)
                    {
                        ownElements.Add(spn.PatternElement.OriginalIndependentElement, null);
                    }
                }
            }

            return ownElements;
        }
        /// <summary>
        /// Builds a pattern graph out of the graph.
        /// The pattern graph retains links to the original graph elements and uses them for attribute comparison.
        /// </summary>
        /// <param name="graph">The graph which is to be transfered into a pattern</param>
        /// <returns></returns>
        private static PatternGraph BuildPatternGraph(IGraph graph)
        {
            int numNodes = graph.NumNodes;
            int numEdges = graph.NumEdges;

            int count = 0;

            PatternNode[] nodes = new PatternNode[numNodes];
            INode[]       correspondingNodes = new INode[numNodes];
            foreach (INode node in graph.Nodes)
            {
                LGSPNode n = (LGSPNode)node;
                nodes[count] = new PatternNode(
                    n.Type.TypeID, n.Type, n.Type.PackagePrefixedName,
                    graph.Name + "_node_" + count, "node_" + count,
                    null, null,
                    1.0f, -1, false,
                    null, null, null, null, null,
                    null, false, null
                    );
                correspondingNodes[count] = node;
                ++count;
            }

            count = 0;
            PatternEdge[] edges = new PatternEdge[numEdges];
            IEdge[]       correspondingEdges = new IEdge[numEdges];
            foreach (IEdge edge in graph.Edges)
            {
                LGSPEdge e = (LGSPEdge)edge;
                edges[count] = new PatternEdge(
                    true,
                    e.Type.TypeID, e.Type, e.Type.PackagePrefixedName,
                    graph.Name + "_edge_" + count, "edge_" + count,
                    null, null,
                    1.0f, -1, false,
                    null, null, null, null, null,
                    null, false, null
                    );
                correspondingEdges[count] = edge;
                ++count;
            }

            bool[,] homNodes = new bool[numNodes, numNodes];
            for (int i = 0; i < numNodes; ++i)
            {
                for (int j = 0; j < numNodes; ++j)
                {
                    homNodes[i, j] = false;
                }
            }

            bool[,] homEdges = new bool[numEdges, numEdges];
            for (int i = 0; i < numEdges; ++i)
            {
                for (int j = 0; j < numEdges; ++j)
                {
                    homEdges[i, j] = false;
                }
            }

            bool[,] homNodesGlobal = new bool[numNodes, numNodes];
            for (int i = 0; i < numNodes; ++i)
            {
                for (int j = 0; j < numNodes; ++j)
                {
                    homNodesGlobal[i, j] = false;
                }
            }

            bool[,] homEdgesGlobal = new bool[numEdges, numEdges];
            for (int i = 0; i < numEdges; ++i)
            {
                for (int j = 0; j < numEdges; ++j)
                {
                    homEdgesGlobal[i, j] = false;
                }
            }

            bool[] totallyHomNodes = new bool[numNodes];
            for (int i = 0; i < numNodes; ++i)
            {
                totallyHomNodes[i] = false;
            }

            bool[] totallyHomEdges = new bool[numEdges];
            for (int i = 0; i < numEdges; ++i)
            {
                totallyHomEdges[i] = false;
            }

            List <PatternCondition> pcs = new List <PatternCondition>();

            for (int i = 0; i < numNodes; ++i)
            {
                if (nodes[i].Type.NumAttributes > 0)
                {
                    pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingNodes[i], nodes[i]),
                                                 new string[] { nodes[i].name }, new string[] { }, new string[] { },
                                                 new PatternNode[] { nodes[i] }, new PatternEdge[] { }, new PatternVariable[] { }));
                }
            }
            for (int i = 0; i < numEdges; ++i)
            {
                if (edges[i].Type.NumAttributes > 0)
                {
                    pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingEdges[i], edges[i]),
                                                 new string[] { }, new string[] { edges[i].name }, new string[] { },
                                                 new PatternNode[] { }, new PatternEdge[] { edges[i] }, new PatternVariable[] { }));
                }
            }
            PatternCondition[] patternConditions = pcs.ToArray();

            PatternGraph patternGraph = new PatternGraph(
                graph.Name,
                nodes, edges,
                patternConditions,
                homNodes, homEdges,
                homNodesGlobal, homEdgesGlobal,
                totallyHomNodes, totallyHomEdges,
                correspondingNodes, correspondingEdges
                );

            foreach (PatternNode node in nodes)
            {
                node.pointOfDefinition = patternGraph;
            }
            foreach (PatternEdge edge in edges)
            {
                edge.pointOfDefinition = patternGraph;
            }

            foreach (IEdge edge in graph.Edges)
            {
                int edgeIndex   = Array.IndexOf <IEdge>(correspondingEdges, edge);
                int sourceIndex = Array.IndexOf <INode>(correspondingNodes, edge.Source);
                int targetIndex = Array.IndexOf <INode>(correspondingNodes, edge.Target);
                patternGraph.edgeToSourceNode.Add(edges[edgeIndex], nodes[sourceIndex]);
                patternGraph.edgeToTargetNode.Add(edges[edgeIndex], nodes[targetIndex]);
            }

            PatternGraphAnalyzer.PrepareInline(patternGraph);

            return(patternGraph);
        }
        private void CreateSourceTargetIncomingOutgoingPlanEdges(PatternEdge edge, PlanNode planNode, 
            List<PlanEdge> planEdges, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent,
            LGSPGraphStatistics graphStatistics, PatternGraph patternGraph, bool isPreset, float zeroCost)
        {
            // only add implicit source operation if edge source is needed and the edge source is 
            // not a preset node and not a storage node and not an index node and not a cast node
            PatternNode source = GetSourcePlusInlined(edge, patternGraph, originalToInlinedIndependent);
            if(source != null
                && !source.TempPlanMapping.IsPreset
                && source.Storage == null
                && source.IndexAccess == null
                && source.NameLookup == null
                && source.UniqueLookup == null
                && source.ElementBeforeCasting == null)
            {
                SearchOperationType operation = edge.fixedDirection ?
                    SearchOperationType.ImplicitSource : SearchOperationType.Implicit;
                PlanEdge implSrcPlanEdge = new PlanEdge(operation, planNode,
                    source.TempPlanMapping, zeroCost);
                planEdges.Add(implSrcPlanEdge);
                source.TempPlanMapping.IncomingEdges.Add(implSrcPlanEdge);
            }
            // only add implicit target operation if edge target is needed and the edge target is
            // not a preset node and not a storage node and not an index node and not a cast node
            PatternNode target = GetTargetPlusInlined(edge, patternGraph, originalToInlinedIndependent);
            if(target != null
                && !target.TempPlanMapping.IsPreset
                && target.Storage == null
                && target.IndexAccess == null
                && target.NameLookup == null
                && target.UniqueLookup == null
                && target.ElementBeforeCasting == null)
            {
                SearchOperationType operation = edge.fixedDirection ?
                    SearchOperationType.ImplicitTarget : SearchOperationType.Implicit;
                PlanEdge implTgtPlanEdge = new PlanEdge(operation, planNode,
                    target.TempPlanMapping, zeroCost);
                planEdges.Add(implTgtPlanEdge);
                target.TempPlanMapping.IncomingEdges.Add(implTgtPlanEdge);
            }

            // edge must only be reachable from other nodes if it's not a preset and not storage determined and not index determined and not a cast
            if(!isPreset
                && edge.Storage == null
                && edge.IndexAccess == null
                && edge.NameLookup == null
                && edge.UniqueLookup == null
                && edge.ElementBeforeCasting == null)
            {
                // no outgoing on source node if no source
                if(source != null)
                {
                    int targetTypeID;
                    if(target != null) targetTypeID = target.TypeID;
                    else targetTypeID = model.NodeModel.RootType.TypeID;
                    // cost of walking along edge
#if MONO_MULTIDIMARRAY_WORKAROUND
                    float normCost = graphStatistics.vstructs[((source.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size
                        + targetTypeID) * 2 + (int)LGSPDirection.Out];
                    if(!edge.fixedDirection)
                    {
                        normCost += graphStatistics.vstructs[((source.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size
                            + targetTypeID) * 2 + (int)LGSPDirection.In];
                    }
#else
                    float normCost = graph.statistics.vstructs[source.TypeID, edge.TypeID, targetTypeID, (int) LGSPDirection.Out];
                    if (!edge.fixedDirection) {
                        normCost += graph.statistics.vstructs[source.TypeID, edge.TypeID, targetTypeID, (int) LGSPDirection.In];
                    }
#endif
                    if(graphStatistics.nodeCounts[source.TypeID] != 0)
                        normCost /= graphStatistics.nodeCounts[source.TypeID];
                    normCost = CostIncreaseForInlinedIndependent(edge, normCost);
                    SearchOperationType operation = edge.fixedDirection ?
                        SearchOperationType.Outgoing : SearchOperationType.Incident;
                    PlanEdge outPlanEdge = new PlanEdge(operation, source.TempPlanMapping,
                        planNode, normCost);
                    planEdges.Add(outPlanEdge);
                    planNode.IncomingEdges.Add(outPlanEdge);
                }

                // no incoming on target node if no target
                if(target != null)
                {
                    int sourceTypeID;
                    if(source != null) sourceTypeID = source.TypeID;
                    else sourceTypeID = model.NodeModel.RootType.TypeID;
                    // cost of walking in opposite direction of edge
#if MONO_MULTIDIMARRAY_WORKAROUND
                    float revCost = graphStatistics.vstructs[((target.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size
                        + sourceTypeID) * 2 + (int)LGSPDirection.In];
                    if(!edge.fixedDirection)
                    {
                        revCost += graphStatistics.vstructs[((target.TypeID * graphStatistics.dim1size + edge.TypeID) * graphStatistics.dim2size
                            + sourceTypeID) * 2 + (int)LGSPDirection.Out];
                    }
#else
                    float revCost = graph.statistics.vstructs[target.TypeID, edge.TypeID, sourceTypeID, (int) LGSPDirection.In];
                    if (!edge.fixedDirection) {
                        revCost += graph.statistics.vstructs[target.TypeID, edge.TypeID, sourceTypeID, (int) LGSPDirection.Out];
                    }
#endif
                    if(graphStatistics.nodeCounts[target.TypeID] != 0)
                        revCost /= graphStatistics.nodeCounts[target.TypeID];
                    revCost = CostIncreaseForInlinedIndependent(edge, revCost); 
                    SearchOperationType operation = edge.fixedDirection ?
                        SearchOperationType.Incoming : SearchOperationType.Incident;
                    PlanEdge inPlanEdge = new PlanEdge(operation, target.TempPlanMapping,
                        planNode, revCost);
                    planEdges.Add(inPlanEdge);
                    planNode.IncomingEdges.Add(inPlanEdge);
                }
            }
        }
        ////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Constructs an Alternative object.
        /// </summary>
        /// <param name="name">Name of the alternative.</param>
        /// <param name="pathPrefix">Prefix for name from nesting path.</param>
        /// <param name="cases">Array with the alternative cases.</param>
        public Alternative(String name, String pathPrefix, PatternGraph[] cases)
        {
            this.name = name;
            this.pathPrefix = pathPrefix;
            this.alternativeCases = cases;
        }
 public static IEnumerable<PatternEdge> EdgesInIndependentMatchedThere(PatternGraph independent)
 {
     foreach(PatternEdge edge in independent.edgesPlusInlined)
     {
         if(edge.PointOfDefinition == independent && !edge.defToBeYieldedTo)
             yield return edge;
     }
 }
        ////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Constructs an Iterated object.
        /// </summary>
        /// <param name="iterated">PatternGraph of the iterated.</param>
        public Iterated(PatternGraph iteratedPattern, int minMatches, int maxMatches)
        {
            this.iteratedPattern = iteratedPattern;
            this.minMatches = minMatches;
            this.maxMatches = maxMatches;
        }
        /// <summary>
        /// Builds a pattern graph out of the graph.
        /// The pattern graph retains links to the original graph elements and uses them for attribute comparison.
        /// </summary>
        /// <param name="graph">The graph which is to be transfered into a pattern</param>
        /// <returns></returns>
        public PatternGraph BuildPatternGraph(LGSPGraph graph)
        {
            int numNodes = graph.NumNodes;
            int numEdges = graph.NumEdges;

            int count = 0;
            PatternNode[] nodes = new PatternNode[numNodes];
            INode[] correspondingNodes = new INode[numNodes];
            foreach(INode node in graph.Nodes)
            {
                LGSPNode n = (LGSPNode)node;
                nodes[count] = new PatternNode(
                    n.Type.TypeID, n.Type, n.Type.PackagePrefixedName,
                    graph.Name+"_node_"+count, "node_"+count,
                    null, null,
                    1.0f, -1, false,
                    null, null, null, null, null,
                    null, false, null
                );
                correspondingNodes[count] = node;
                ++count;
            }

            count = 0;
            PatternEdge[] edges = new PatternEdge[numEdges];
            IEdge[] correspondingEdges = new IEdge[numEdges];
            foreach(IEdge edge in graph.Edges)
            {
                LGSPEdge e = (LGSPEdge)edge;
                edges[count] = new PatternEdge(
                    true,
                    e.Type.TypeID, e.Type, e.Type.PackagePrefixedName,
                    graph.Name+"_edge_"+count, "edge_"+count,
                    null, null,
                    1.0f, -1, false,
                    null, null, null, null, null,
                    null, false, null
                );
                correspondingEdges[count] = edge;
                ++count;
            }

            bool[,] homNodes = new bool[numNodes, numNodes];
            for(int i = 0; i < numNodes; ++i)
                for(int j = 0; j < numNodes; ++j)
                    homNodes[i, j] = false;

            bool[,] homEdges = new bool[numEdges, numEdges];
            for(int i = 0; i < numEdges; ++i)
                for(int j = 0; j < numEdges; ++j)
                    homEdges[i, j] = false;
            
            bool[,] homNodesGlobal = new bool[numNodes, numNodes];
            for(int i = 0; i < numNodes; ++i)
                for(int j = 0; j < numNodes; ++j)
                    homNodesGlobal[i, j] = false;

            bool[,] homEdgesGlobal = new bool[numEdges, numEdges];
            for(int i = 0; i < numEdges; ++i)
                for(int j = 0; j < numEdges; ++j)
                    homEdgesGlobal[i, j] = false;

            bool[] totallyHomNodes = new bool[numNodes];
            for(int i = 0; i < numNodes; ++i)
                totallyHomNodes[i] = false;

            bool[] totallyHomEdges = new bool[numEdges];
            for(int i = 0; i < numEdges; ++i)
                totallyHomEdges[i] = false;

            List<PatternCondition> pcs = new List<PatternCondition>();
            for(int i = 0; i < numNodes; ++i)
            {
                if(nodes[i].Type.NumAttributes > 0)
                    pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingNodes[i], nodes[i]),
                        new string[] { nodes[i].name }, new string[] { }, new string[] { }, new VarType[] { }));
            }
            for(int i = 0; i < numEdges; ++i)
            {
                if(edges[i].Type.NumAttributes > 0)
                    pcs.Add(new PatternCondition(new expression.AreAttributesEqual(correspondingEdges[i], edges[i]),
                        new string[] { }, new string[] { edges[i].name }, new string[] { }, new VarType[] { }));
            }
            PatternCondition[] patternConditions = pcs.ToArray();

            PatternGraph patternGraph = new PatternGraph(
                graph.Name, "",
                null, graph.Name,
                false, false,
                nodes, edges, new PatternVariable[0],
                new PatternGraphEmbedding[0], new Alternative[0], new Iterated[0],
                new PatternGraph[0], new PatternGraph[0],
                patternConditions, new PatternYielding[0],
                homNodes, homEdges,
                homNodesGlobal, homEdgesGlobal,
                totallyHomNodes, totallyHomEdges
            );
            foreach(PatternNode node in nodes)
                node.pointOfDefinition = patternGraph;
            foreach(PatternEdge edge in edges)
                edge.pointOfDefinition = patternGraph;
            patternGraph.correspondingNodes = correspondingNodes;
            patternGraph.correspondingEdges = correspondingEdges;

            foreach(IEdge edge in graph.Edges)
            {
                int edgeIndex = Array.IndexOf<IEdge>(correspondingEdges, edge);
                int sourceIndex = Array.IndexOf<INode>(correspondingNodes, edge.Source);
                int targetIndex = Array.IndexOf<INode>(correspondingNodes, edge.Target);
                patternGraph.edgeToSourceNode.Add(edges[edgeIndex], nodes[sourceIndex]);
                patternGraph.edgeToTargetNode.Add(edges[edgeIndex], nodes[targetIndex]);
            }

            PatternGraphAnalyzer.PrepareInline(patternGraph);

            return patternGraph;
        }
Beispiel #42
0
        /// <summary>
        /// Builds search program from scheduled search plan at given index in pattern graph of the action rule pattern
        /// </summary>
        public static SearchProgram BuildSearchProgram(
            IGraphModel model,
            LGSPRulePattern rulePattern,
            int index,
            string nameOfSearchProgram,
            bool parallelized,
            bool emitProfiling)
        {
            PatternGraph patternGraph         = rulePattern.patternGraph;
            String       rulePatternClassName = NamesOfEntities.RulePatternClassName(rulePattern.name, rulePattern.PatternGraph.Package, false);

            // filter out parameters which are implemented by lookup due to maybe null unfolding
            // and suffix matcher method name by missing parameters which get computed by lookup here
            string[] parameterTypes;
            string[] parameterNames;
            String   name;

            GetFilteredParametersAndSuffixedMatcherName(
                rulePattern, patternGraph, parallelized ? 0 : index,
                out parameterTypes, out parameterNames, out name);

            SearchProgramBodyBuilder builder = new SearchProgramBodyBuilder(
                SearchProgramType.Action,
                model,
                rulePatternClassName,
                rulePattern.patternGraph.Package != null ? rulePattern.patternGraph.Package + "::" + rulePattern.name : rulePattern.name,
                parameterNames,
                parameterTypes,
                patternGraph,
                emitProfiling,
                parallelized,
                index
                );

            // this is the all presets available method (index 0) and there are presets which may be null?
            // -> collect data for missing preset calls
            List <String[]> paramTypesList          = null;
            List <String[]> paramNamesList          = null;
            List <String>   suffixedMatcherNameList = null;

            if (patternGraph.schedules.Length > 1 && index == 0)
            {
                paramTypesList          = new List <String[]>();
                paramNamesList          = new List <String[]>();
                suffixedMatcherNameList = new List <String>();
                for (int i = 0; i < patternGraph.schedules.Length; ++i)
                {
                    String[] paramTypes;
                    String[] paramNames;
                    String   suffixedMatcherName;
                    GetFilteredParametersAndSuffixedMatcherName(
                        rulePattern, patternGraph, i,
                        out paramTypes, out paramNames, out suffixedMatcherName);
                    paramTypesList.Add(paramTypes);
                    paramNamesList.Add(paramNames);
                    suffixedMatcherNameList.Add(suffixedMatcherName);
                }
            }

            // build outermost search program operation, create the list anchor starting its program
            bool containsSubpatterns = patternGraph.embeddedGraphsPlusInlined.Length > 0 ||
                                       patternGraph.iteratedsPlusInlined.Length > 0 ||
                                       patternGraph.alternativesPlusInlined.Length > 0;
            SearchProgram searchProgram;

            if (parallelized)
            {
                if (index == 1)
                {
                    List <String> matchingPatternClassTypeNames = new List <String>();
                    List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >();
                    ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph);

                    searchProgram = new SearchProgramOfActionParallelizationBody(
                        rulePatternClassName,
                        patternGraph.name, name + "_parallelized_body",
                        rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                        containsSubpatterns, builder.wasIndependentInlined(patternGraph, index),
                        matchingPatternClassTypeNames, nestedIndependents,
                        emitProfiling, patternGraph.PackagePrefixedName);
                }
                else // index == 0
                {
                    searchProgram = new SearchProgramOfActionParallelizationHead(
                        rulePatternClassName,
                        patternGraph.name, parameterTypes, parameterNames, name + "_parallelized",
                        emitProfiling, patternGraph.PackagePrefixedName);
                }
            }
            else
            {
                List <String> matchingPatternClassTypeNames = new List <String>();
                List <Dictionary <PatternGraph, bool> > nestedIndependents = new List <Dictionary <PatternGraph, bool> >();
                ExtractNestedIndependents(matchingPatternClassTypeNames, nestedIndependents, rulePattern, patternGraph);

                searchProgram = new SearchProgramOfAction(
                    rulePatternClassName,
                    patternGraph.name, parameterTypes, parameterNames, name,
                    rulePattern.patternGraph.patternGraphsOnPathToEnclosedPatternpath,
                    containsSubpatterns, builder.wasIndependentInlined(patternGraph, 0),
                    matchingPatternClassTypeNames, nestedIndependents,
                    emitProfiling, patternGraph.PackagePrefixedName,
                    patternGraph.maybeNullElementNames, suffixedMatcherNameList, paramNamesList);
            }
            searchProgram.OperationsList = new SearchProgramList(searchProgram);
            SearchProgramOperation insertionPoint = searchProgram.OperationsList;

            if (!parallelized || index == 0)
            {
                insertionPoint = insertVariableDeclarations(insertionPoint, patternGraph);
            }

            // start building with first operation in scheduled search plan
            insertionPoint = builder.BuildScheduledSearchPlanOperationIntoSearchProgram(
                0, insertionPoint);

            return(searchProgram);
        }
 public static PatternNode GetTargetPlusInlined(PatternEdge edge, PatternGraph patternGraph, IDictionary<PatternNode, PatternNode> originalToInlinedIndependent)
 {
     PatternNode target = patternGraph.GetTargetPlusInlined(edge);
     if(edge.OriginalIndependentElement != null && target == null)
     {
         PatternNode targetOriginal = edge.OriginalIndependentElement.pointOfDefinition.GetTargetPlusInlined((PatternEdge)edge.OriginalIndependentElement);
         if(originalToInlinedIndependent.ContainsKey(targetOriginal))
             target = originalToInlinedIndependent[targetOriginal];
         else
             target = targetOriginal; // not declared in independent itself, but in some parent
     }
     return target;
 }
Beispiel #44
0
        /// <summary>
        /// Inserts inlined variable assignments into the schedule given by the operations list at their earliest possible position
        /// </summary>
        private static void InsertInlinedVariableAssignmentsIntoSchedule(PatternGraph patternGraph, List <SearchOperation> operations)
        {
            // compute the number of inlined parameter variables
            int numInlinedParameterVariables = 0;

            foreach (PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if (var.AssignmentSource != null && patternGraph.WasInlinedHere(var.originalSubpatternEmbedding))
                {
                    ++numInlinedParameterVariables;
                }
            }

            if (numInlinedParameterVariables == 0)
            {
                return;
            }

            // get the inlined parameter variables and the elements needed in order to compute their defining expression
            Dictionary <String, PatternElement>[] neededElements = new Dictionary <String, PatternElement> [numInlinedParameterVariables];
            PatternVariable[] inlinedParameterVariables          = new PatternVariable[numInlinedParameterVariables];
            int curInlParamVar = 0;

            foreach (PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if (var.AssignmentSource == null)
                {
                    continue;
                }
                if (!patternGraph.WasInlinedHere(var.originalSubpatternEmbedding))
                {
                    continue;
                }

                neededElements[curInlParamVar] = new Dictionary <string, PatternElement>();
                for (int i = 0; i < var.AssignmentDependencies.neededNodeNames.Length; ++i)
                {
                    String      neededNodeName = var.AssignmentDependencies.neededNodeNames[i];
                    PatternNode neededNode     = var.AssignmentDependencies.neededNodes[i];
                    neededElements[curInlParamVar][neededNodeName] = neededNode;
                }
                for (int i = 0; i < var.AssignmentDependencies.neededEdgeNames.Length; ++i)
                {
                    String      neededEdgeName = var.AssignmentDependencies.neededEdgeNames[i];
                    PatternEdge neededEdge     = var.AssignmentDependencies.neededEdges[i];
                    neededElements[curInlParamVar][neededEdgeName] = neededEdge;
                }
                inlinedParameterVariables[curInlParamVar] = var;

                ++curInlParamVar;
            }

            // iterate over all inlined parameter variables
            for (int i = 0; i < inlinedParameterVariables.Length; ++i)
            {
                int   j;
                float costToEnd = 0;

                // find leftmost place in scheduled search plan for current assignment
                // by search from end of schedule forward until the first element the expression assigned is dependent on is found
                for (j = operations.Count - 1; j >= 0; --j)
                {
                    SearchOperation op = operations[j];
                    if (op.Type == SearchOperationType.Condition ||
                        op.Type == SearchOperationType.Assign ||
                        op.Type == SearchOperationType.AssignVar ||
                        op.Type == SearchOperationType.NegativePattern ||
                        op.Type == SearchOperationType.IndependentPattern ||
                        op.Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        continue;
                    }

                    if (neededElements[i].ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name))
                    {
                        costToEnd = op.CostToEnd;
                        break;
                    }
                }

                SearchOperation so = new SearchOperation(SearchOperationType.AssignVar,
                                                         inlinedParameterVariables[i], null, costToEnd);
                so.Expression = inlinedParameterVariables[i].AssignmentSource;
                operations.Insert(j + 1, so);
            }
        }
Beispiel #45
0
        /// <summary>
        /// Generates a scheduled search plan for a given search plan graph
        /// </summary>
        public static ScheduledSearchPlan ScheduleSearchPlan(SearchPlanGraph spGraph,
                                                             PatternGraph patternGraph, bool isNegativeOrIndependent, bool lazyNegativeIndependentConditionEvaluation)
        {
            // the schedule
            List <SearchOperation> operations = new List <SearchOperation>();

            // a set of search plan edges representing the currently reachable not yet visited elements
            PriorityQueue <SearchPlanEdge> activeEdges = new PriorityQueue <SearchPlanEdge>();

            // first schedule all preset elements
            foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges)
            {
                if (edge.Target.IsPreset && edge.Type != SearchOperationType.DefToBeYieldedTo)
                {
                    foreach (SearchPlanEdge edgeOutgoingFromPresetElement in edge.Target.OutgoingEdges)
                    {
                        activeEdges.Add(edgeOutgoingFromPresetElement);
                    }

                    // note: here a normal preset is converted into a neg/idpt preset operation if in negative/independent pattern
                    SearchOperation newOp = new SearchOperation(
                        isNegativeOrIndependent ? SearchOperationType.NegIdptPreset : edge.Type,
                        edge.Target, spGraph.Root, 0);
                    operations.Add(newOp);
                }
            }

            // then schedule all map with storage / pick from index / pick from storage / pick from name index elements not depending on other elements
            foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges)
            {
                if (edge.Type == SearchOperationType.MapWithStorage)
                {
                    foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges)
                    {
                        activeEdges.Add(edgeOutgoingFromPickedElement);
                    }

                    SearchOperation newOp = new SearchOperation(edge.Type,
                                                                edge.Target, spGraph.Root, 0);
                    newOp.Storage      = edge.Target.PatternElement.Storage;
                    newOp.StorageIndex = edge.Target.PatternElement.StorageIndex;
                    operations.Add(newOp);
                }
            }
            foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges)
            {
                if (edge.Type == SearchOperationType.PickFromStorage)
                {
                    foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges)
                    {
                        activeEdges.Add(edgeOutgoingFromPickedElement);
                    }

                    SearchOperation newOp = new SearchOperation(edge.Type,
                                                                edge.Target, spGraph.Root, 0);
                    newOp.Storage = edge.Target.PatternElement.Storage;
                    operations.Add(newOp);
                }
            }
            foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges)
            {
                if (edge.Type == SearchOperationType.PickFromIndex)
                {
                    foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges)
                    {
                        activeEdges.Add(edgeOutgoingFromPickedElement);
                    }

                    SearchOperation newOp = new SearchOperation(edge.Type,
                                                                edge.Target, spGraph.Root, 0);
                    newOp.IndexAccess = edge.Target.PatternElement.IndexAccess;
                    operations.Add(newOp);
                }
            }
            foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges)
            {
                if (edge.Type == SearchOperationType.PickByName)
                {
                    foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges)
                    {
                        activeEdges.Add(edgeOutgoingFromPickedElement);
                    }

                    SearchOperation newOp = new SearchOperation(edge.Type,
                                                                edge.Target, spGraph.Root, 0);
                    newOp.NameLookup = edge.Target.PatternElement.NameLookup;
                    operations.Add(newOp);
                }
            }
            foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges)
            {
                if (edge.Type == SearchOperationType.PickByUnique)
                {
                    foreach (SearchPlanEdge edgeOutgoingFromPickedElement in edge.Target.OutgoingEdges)
                    {
                        activeEdges.Add(edgeOutgoingFromPickedElement);
                    }

                    SearchOperation newOp = new SearchOperation(edge.Type,
                                                                edge.Target, spGraph.Root, 0);
                    newOp.UniqueLookup = edge.Target.PatternElement.UniqueLookup;
                    operations.Add(newOp);
                }
            }

            // iterate over all reachable elements until the whole graph has been scheduled(/visited),
            // choose next cheapest operation, update the reachable elements and the search plan costs
            SearchPlanNode lastNode = spGraph.Root;

            for (int i = 0; i < spGraph.Nodes.Length - spGraph.NumPresetElements - spGraph.NumIndependentStorageIndexElements; ++i)
            {
                foreach (SearchPlanEdge edge in lastNode.OutgoingEdges)
                {
                    if (edge.Target.IsPreset)
                    {
                        continue;
                    }
                    if (edge.Target.PatternElement.Storage != null &&
                        edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null)
                    {
                        continue;
                    }
                    if (edge.Target.PatternElement.IndexAccess != null &&
                        edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null)
                    {
                        continue;
                    }
                    if (edge.Target.PatternElement.NameLookup != null &&
                        edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null)
                    {
                        continue;
                    }
                    if (edge.Target.PatternElement.UniqueLookup != null &&
                        edge.Target.PatternElement.GetPatternElementThisElementDependsOnOutsideOfGraphConnectedness() == null)
                    {
                        continue;
                    }
                    CostDecreaseForLeavingInlinedIndependent(edge);
                    activeEdges.Add(edge);
                }

                SearchPlanEdge minEdge = activeEdges.DequeueFirst();
                lastNode = minEdge.Target;

                SearchOperation newOp = new SearchOperation(minEdge.Type,
                                                            lastNode, minEdge.Source, minEdge.Cost);
                newOp.Storage      = minEdge.Target.PatternElement.Storage;
                newOp.StorageIndex = minEdge.Target.PatternElement.StorageIndex;
                newOp.IndexAccess  = minEdge.Target.PatternElement.IndexAccess;
                newOp.NameLookup   = minEdge.Target.PatternElement.NameLookup;
                newOp.UniqueLookup = minEdge.Target.PatternElement.UniqueLookup;

                foreach (SearchOperation op in operations)
                {
                    op.CostToEnd += minEdge.Cost;
                }

                operations.Add(newOp);
            }

            // remove the elements stemming from inlined independents
            // they were added in the hope that they might help in matching this pattern,
            // they don't if they are matched after the elements of this pattern (in fact they only increase the costs then)
            RemoveInlinedIndependentElementsAtEnd(operations);

            // insert inlined element identity check into the schedule in case neither of the possible assignments was scheduled
            InsertInlinedElementIdentityCheckIntoSchedule(patternGraph, operations);

            // insert inlined variable assignments into the schedule
            InsertInlinedVariableAssignmentsIntoSchedule(patternGraph, operations);

            // insert conditions into the schedule
            InsertConditionsIntoSchedule(patternGraph.ConditionsPlusInlined, operations, lazyNegativeIndependentConditionEvaluation);

            // schedule the initialization of all def to be yielded to elements and variables at the end,
            // must come after the pattern elements (and preset elements), as they may be used in the def initialization
            foreach (SearchPlanEdge edge in spGraph.Root.OutgoingEdges)
            {
                if (edge.Type == SearchOperationType.DefToBeYieldedTo &&
                    (!isNegativeOrIndependent || (edge.Target.PatternElement.pointOfDefinition == patternGraph && edge.Target.PatternElement.originalElement == null)))
                {
                    SearchOperation newOp = new SearchOperation(
                        SearchOperationType.DefToBeYieldedTo,
                        edge.Target, spGraph.Root, 0);
                    newOp.Expression = edge.Target.PatternElement.Initialization;
                    operations.Add(newOp);
                }
            }
            foreach (PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if (var.defToBeYieldedTo &&
                    (!isNegativeOrIndependent || var.pointOfDefinition == patternGraph && var.originalVariable == null))
                {
                    SearchOperation newOp = new SearchOperation(
                        SearchOperationType.DefToBeYieldedTo,
                        var, spGraph.Root, 0);
                    newOp.Expression = var.initialization;
                    operations.Add(newOp);
                }
            }

            float cost = operations.Count > 0 ? operations[0].CostToEnd : 0;

            return(new ScheduledSearchPlan(patternGraph, operations.ToArray(), cost));
        }
        /// <summary>
        /// Generate plan graph for given pattern graph with costs from the analyzed host graph.
        /// Plan graph contains nodes representing the pattern elements (nodes and edges)
        /// and edges representing the matching operations to get the elements by.
        /// Edges in plan graph are given in the nodes by incoming list, as needed for MSA computation.
        /// </summary>
        public PlanGraph GeneratePlanGraph(LGSPGraphStatistics graphStatistics, PatternGraph patternGraph,
            bool isNegativeOrIndependent, bool isSubpatternLike, 
            IDictionary<PatternElement, SetValueType> presetsFromIndependentInlining)
        {
            // 
            // If you change this method, chances are high you also want to change GenerateStaticPlanGraph in LGSPGrGen
            // look there for version without ifdef junk
            // todo: unify it with GenerateStaticPlanGraph in LGSPGrGen
            // 

            // Create root node
            // Create plan graph nodes for all pattern graph nodes and all pattern graph edges
            // Create "lookup" plan graph edge from root node to each plan graph node
            // Create "implicit source" plan graph edge from each plan graph node originating with a pattern edge 
            //     to the plan graph node created by the source node of the pattern graph edge
            // Create "implicit target" plan graph edge from each plan graph node originating with a pattern edge 
            //     to the plan graph node created by the target node of the pattern graph edge
            // Create "incoming" plan graph edge from each plan graph node originating with a pattern node
            //     to a plan graph node created by one of the incoming edges of the pattern node
            // Create "outgoing" plan graph edge from each plan graph node originating with a pattern node
            //     to a plan graph node created by one of the outgoing edges of the pattern node
            // Ensured: there's no plan graph edge with a preset element as target besides the lookup,
            //     so presets are only search operation sources
            // Create "pick from storage" plan graph edge for plan graph nodes which are to be picked from a storage,
            //     from root node on, instead of lookup, no other plan graph edge having this node as target
            // Create "pick from storage attribute" plan graph edge from storage attribute owner to storage picking result,
            //     no lookup, no other plan graph edge having this node as target
            // Create "map" by storage plan graph edge from accessor to storage mapping result
            //     no lookup, no other plan graph edge having this node as target
            // Create "pick from index" plan graph edge for plan graph nodes which are to be picked from an index,
            //     from root node on, instead of lookup, no other plan graph edge having this node as target
            // Create "pick from index depending" plan graph edge from node the index expressions depend on,
            //     no lookup, no other plan graph edge having this node as target
            // Create "cast" plan graph edge from element before casting to cast result,
            //     no lookup, no other plan graph edge having this node as target

            int numNodes = patternGraph.nodesPlusInlined.Length;
            if(InlineIndependents && !isNegativeOrIndependent)
                numNodes += LGSPMatcherGenerator.NumNodesInIndependentsMatchedThere(patternGraph);
            int numEdges = patternGraph.edgesPlusInlined.Length;
            if(InlineIndependents && !isNegativeOrIndependent)
                numEdges += LGSPMatcherGenerator.NumEdgesInIndependentsMatchedThere(patternGraph);
            PlanNode[] planNodes = new PlanNode[numNodes + numEdges];
            List<PlanEdge> planEdges = new List<PlanEdge>(numNodes + 5 * numEdges); // upper bound for num of edges (lookup nodes + lookup edges + impl. tgt + impl. src + incoming + outgoing)

            Dictionary<PatternNode, PatternNode> originalToInlinedIndependent = new Dictionary<PatternNode, PatternNode>();

            int nodesIndex = 0;
            float zeroCost = 1;

            PlanNode planRoot = new PlanNode("root");

            // create plan nodes and lookup plan edges for all pattern graph nodes
            for(int i = 0; i < patternGraph.nodesPlusInlined.Length; i++)
            {
                PatternNode node = patternGraph.nodesPlusInlined[i];

                PlanNode planNode;
                PlanEdge rootToNodePlanEdge;
                CreatePlanNodeAndLookupPlanEdge(node, i + 1, 
                    graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost,
                    originalToInlinedIndependent, presetsFromIndependentInlining,
                    out planNode, out rootToNodePlanEdge);

                planNodes[nodesIndex] = planNode;
                if(rootToNodePlanEdge != null)
                {
                    planEdges.Add(rootToNodePlanEdge);
                    planNode.IncomingEdges.Add(rootToNodePlanEdge);
                }

                node.TempPlanMapping = planNode;
                ++nodesIndex;
            }
            if(InlineIndependents && !isNegativeOrIndependent) // independent inlining only if not in negative/independent
            {
                foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined)
                {
                    foreach(PatternNode nodeOriginal in LGSPMatcherGenerator.NodesInIndependentMatchedThere(independent))
                    {
                        PatternNode node = new PatternNode(nodeOriginal, "_inlined_" + independent.name);
                        originalToInlinedIndependent.Add(nodeOriginal, node);

                        PlanNode planNode;
                        PlanEdge rootToNodePlanEdge;
                        CreatePlanNodeAndLookupPlanEdge(node, -1,
                            graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost,
                            originalToInlinedIndependent, presetsFromIndependentInlining,
                            out planNode, out rootToNodePlanEdge);

                        planNodes[nodesIndex] = planNode;
                        if(rootToNodePlanEdge != null)
                        {
                            planEdges.Add(rootToNodePlanEdge);
                            planNode.IncomingEdges.Add(rootToNodePlanEdge);
                        }

                        node.TempPlanMapping = planNode;
                        ++nodesIndex;
                    }
                }
            }

            // create plan nodes and lookup plus incidence handling plan edges for all pattern graph edges
            for(int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i)
            {
                PatternEdge edge = patternGraph.edgesPlusInlined[i];

                bool isPreset;
                PlanNode planNode;
                PlanEdge rootToNodePlanEdge;
                CreatePlanNodeAndLookupPlanEdge(edge, i + 1, 
                    graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost,
                    originalToInlinedIndependent, presetsFromIndependentInlining,
                    out isPreset, out planNode, out rootToNodePlanEdge);

                planNodes[nodesIndex] = planNode;
                if(rootToNodePlanEdge != null)
                {
                    planEdges.Add(rootToNodePlanEdge);
                    planNode.IncomingEdges.Add(rootToNodePlanEdge);
                }

                CreateSourceTargetIncomingOutgoingPlanEdges(edge, planNode, planEdges,
                    originalToInlinedIndependent, graphStatistics, patternGraph, isPreset, zeroCost);

                edge.TempPlanMapping = planNode;
                ++nodesIndex;
            }
            if(InlineIndependents && !isNegativeOrIndependent) // independent inlining only if not in negative/independent
            {
                foreach(PatternGraph independent in patternGraph.independentPatternGraphsPlusInlined)
                {
                    foreach(PatternEdge edgeOriginal in LGSPMatcherGenerator.EdgesInIndependentMatchedThere(independent))
                    {
                        PatternEdge edge = new PatternEdge(edgeOriginal, "_inlined_" + independent.name);

                        bool isPreset;
                        PlanNode planNode;
                        PlanEdge rootToNodePlanEdge;
                        CreatePlanNodeAndLookupPlanEdge(edge, -1,
                            graphStatistics, patternGraph, isNegativeOrIndependent, isSubpatternLike, planRoot, zeroCost,
                            originalToInlinedIndependent, presetsFromIndependentInlining,
                            out isPreset, out planNode, out rootToNodePlanEdge);

                        planNodes[nodesIndex] = planNode;
                        if(rootToNodePlanEdge != null)
                        {
                            planEdges.Add(rootToNodePlanEdge);
                            planNode.IncomingEdges.Add(rootToNodePlanEdge);
                        }

                        CreateSourceTargetIncomingOutgoingPlanEdges(edge, planNode, planEdges,
                            originalToInlinedIndependent, graphStatistics, patternGraph, isPreset, zeroCost);

                        edge.TempPlanMapping = planNode;
                        ++nodesIndex;
                    }
                }
            }

            ////////////////////////////////////////////////////////////////////////////
            // second run handling dependent storage and index picking (can't be done in first run due to dependencies between elements)

            // create map/pick/cast/assign plan edges for all pattern graph nodes
            for(int i = 0; i < patternGraph.nodesPlusInlined.Length; ++i)
            {
                PatternNode node = patternGraph.nodesPlusInlined[i];

                if(node.PointOfDefinition == patternGraph && !presetsFromIndependentInlining.ContainsKey(node))
                    CreatePickMapCastAssignPlanEdges(node, planEdges, zeroCost);
            }

            // create map/pick/cast/assign plan edges for all pattern graph edges
            for(int i = 0; i < patternGraph.edgesPlusInlined.Length; ++i)
            {
                PatternEdge edge = patternGraph.edgesPlusInlined[i];

                if(edge.PointOfDefinition == patternGraph && !presetsFromIndependentInlining.ContainsKey(edge))
                    CreatePickMapCastAssignPlanEdges(edge, planEdges, zeroCost);
            }

            return new PlanGraph(planRoot, planNodes, planEdges.ToArray());
        }
        /// <summary>
        /// Instantiates a new pattern graph embedding object as a copy from an original embedding, used for inlining.
        /// </summary>
        /// <param name="original">The original embedding to be copy constructed.</param>
        /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param>
        /// <param name="newHost">The pattern graph the new embedding will be contained in.</param>
        /// <param name="nameSuffix">The suffix to be added to the name of the embedding (to avoid name collisions).</param>
        /// Elements were already copied in the containing pattern(s), their copies have to be reused here.
        public PatternGraphEmbedding(PatternGraphEmbedding original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix)
        {
            PointOfDefinition = newHost;
            name = original.name + nameSuffix;
            originalSubpatternEmbedding = inlinedSubpatternEmbedding;
            matchingPatternOfEmbeddedGraph = original.matchingPatternOfEmbeddedGraph;
            annotations = original.annotations;
            connections = new Expression[original.connections.Length];
            for(int i = 0; i < original.connections.Length; ++i)
            {
                connections[i] = original.connections[i].Copy(nameSuffix);
            }
            yields = new String[original.yields.Length];
            for(int i = 0; i < original.yields.Length; ++i)
            {
                yields[i] = original.yields[i] + nameSuffix;
            }
            neededNodes = new String[original.neededNodes.Length];
            for(int i = 0; i < original.neededNodes.Length; ++i)
            {
                neededNodes[i] = original.neededNodes[i] + nameSuffix;
            }
            neededEdges = new String[original.neededEdges.Length];
            for(int i = 0; i < original.neededEdges.Length; ++i)
            {
                neededEdges[i] = original.neededEdges[i] + nameSuffix;
            }
            neededVariables = new String[original.neededVariables.Length];
            for(int i = 0; i < original.neededVariables.Length; ++i)
            {
                neededVariables[i] = original.neededVariables[i] + nameSuffix;
            }
            neededVariableTypes = (VarType[])original.neededVariableTypes.Clone();

            originalEmbedding = original;
        }
        /// <summary>
        /// Inserts inlined variable assignments into the schedule given by the operations list at their earliest possible position
        /// </summary>
        public void InsertInlinedVariableAssignmentsIntoSchedule(PatternGraph patternGraph, List<SearchOperation> operations)
        {
            // compute the number of inlined parameter variables
            int numInlinedParameterVariables = 0;
            foreach(PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if(var.AssignmentSource != null && patternGraph.WasInlinedHere(var.originalSubpatternEmbedding))
                    ++numInlinedParameterVariables;
            }

            if(numInlinedParameterVariables == 0)
                return;

            // get the inlined parameter variables and the elements needed in order to compute their defining expression
            Dictionary<String, bool>[] neededElements = new Dictionary<String, bool>[numInlinedParameterVariables];
            PatternVariable[] inlinedParameterVariables = new PatternVariable[numInlinedParameterVariables];
            int curInlParamVar = 0;
            foreach(PatternVariable var in patternGraph.variablesPlusInlined)
            {
                if(var.AssignmentSource == null)
                    continue;
                if(!patternGraph.WasInlinedHere(var.originalSubpatternEmbedding))
                    continue;

                neededElements[curInlParamVar] = new Dictionary<string, bool>();
                foreach(String neededNode in var.AssignmentDependencies.neededNodes)
                    neededElements[curInlParamVar][neededNode] = true;
                foreach(String neededEdge in var.AssignmentDependencies.neededEdges)
                    neededElements[curInlParamVar][neededEdge] = true;
                inlinedParameterVariables[curInlParamVar] = var;
                
                ++curInlParamVar;
            }

            // iterate over all inlined parameter variables
            for(int i = 0; i < inlinedParameterVariables.Length; ++i)
            {
                int j;
                float costToEnd = 0;

                // find leftmost place in scheduled search plan for current assignment
                // by search from end of schedule forward until the first element the expression assigned is dependent on is found
                for(j = operations.Count - 1; j >= 0; --j)
                {
                    SearchOperation op = operations[j];
                    if(op.Type == SearchOperationType.Condition
                        || op.Type == SearchOperationType.Assign
                        || op.Type == SearchOperationType.AssignVar
                        || op.Type == SearchOperationType.NegativePattern
                        || op.Type == SearchOperationType.IndependentPattern
                        || op.Type == SearchOperationType.DefToBeYieldedTo)
                    {
                        continue;
                    }

                    if(neededElements[i].ContainsKey(((SearchPlanNode)op.Element).PatternElement.Name))
                    {
                        costToEnd = op.CostToEnd;
                        break;
                    }
                }

                SearchOperation so = new SearchOperation(SearchOperationType.AssignVar,
                    inlinedParameterVariables[i], null, costToEnd);
                so.Expression = inlinedParameterVariables[i].AssignmentSource;
                operations.Insert(j + 1, so);
            }
        }
        /// <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>
        /// Non- is-matched-flag-based isomorphy checking for nested alternative cases/iterateds
        /// </summary>
        public void ParallelizeAlternativeIterated(PatternGraph patternGraph)
        {
            foreach(Alternative alt in patternGraph.alternativesPlusInlined)
            {
                foreach(PatternGraph altCase in alt.alternativeCases)
                {
                    ScheduledSearchPlan ssp = altCase.schedulesIncludingNegativesAndIndependents[0];
                    altCase.parallelizedSchedule = new ScheduledSearchPlan[1];
                    List<SearchOperation> operations = new List<SearchOperation>(ssp.Operations.Length);
                    for(int i = 0; i < ssp.Operations.Length; ++i)
                    {
                        SearchOperation so = ssp.Operations[i];
                        SearchOperation clone = (SearchOperation)so.Clone();
                        clone.Isomorphy.Parallel = true;
                        operations.Add(clone);
                        if(clone.Element is PatternCondition)
                            SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                    }
                    ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan(
                        altCase, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0);
                    altCase.parallelizedSchedule[0] = clonedSsp;

                    ParallelizeNegativeIndependent(clonedSsp);
                    ParallelizeAlternativeIterated(altCase);
                    ParallelizeYielding(altCase);
                }
            }
            foreach(Iterated iter in patternGraph.iteratedsPlusInlined)
            {
                ScheduledSearchPlan ssp = iter.iteratedPattern.schedulesIncludingNegativesAndIndependents[0];
                iter.iteratedPattern.parallelizedSchedule = new ScheduledSearchPlan[1];
                List<SearchOperation> operations = new List<SearchOperation>(ssp.Operations.Length);
                for(int i = 0; i < ssp.Operations.Length; ++i)
                {
                    SearchOperation so = ssp.Operations[i];
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel = true;
                    operations.Add(clone);
                    if(clone.Element is PatternCondition)
                        SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                }
                ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan(
                        iter.iteratedPattern, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0);
                iter.iteratedPattern.parallelizedSchedule[0] = clonedSsp;

                ParallelizeNegativeIndependent(clonedSsp);
                ParallelizeAlternativeIterated(iter.iteratedPattern);
                ParallelizeYielding(iter.iteratedPattern);
            }
        }
        /// <summary>
        /// Instantiates a new iterated object as a copy from an original iterated, used for inlining.
        /// </summary>
        /// <param name="original">The original iterated to be copy constructed.</param>
        /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param>
        /// <param name="newHost">The pattern graph the new iterated will be contained in.</param>
        /// <param name="nameSuffix">The suffix to be added to the name of the iterated 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 Iterated(Iterated original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix,
            Dictionary<PatternNode, PatternNode> nodeToCopy,
            Dictionary<PatternEdge, PatternEdge> edgeToCopy,
            Dictionary<PatternVariable, PatternVariable> variableToCopy)
        {
            iteratedPattern = new PatternGraph(original.iteratedPattern, inlinedSubpatternEmbedding, newHost, nameSuffix, 
                    nodeToCopy, edgeToCopy, variableToCopy);
            minMatches = original.minMatches;
            maxMatches = original.maxMatches;

            originalIterated = original;
            originalSubpatternEmbedding = inlinedSubpatternEmbedding;
        }
 public void ParallelizeYielding(PatternGraph patternGraph)
 {
     patternGraph.parallelizedYieldings = new PatternYielding[patternGraph.YieldingsPlusInlined.Length];
     for(int i = 0; i < patternGraph.YieldingsPlusInlined.Length; ++i)
     {
         patternGraph.parallelizedYieldings[i] = (PatternYielding)patternGraph.YieldingsPlusInlined[i].Clone();
         for(int j = 0; j < patternGraph.parallelizedYieldings[i].ElementaryYieldings.Length; ++j)
         {
             SetNeedForParallelizedVersion(patternGraph.parallelizedYieldings[i].ElementaryYieldings[j]);
         }
     }
 }
 /// <summary>
 /// Instantiates a new PatternNode object as a copy from an original node, used for subpattern inlining.
 /// </summary>
 /// <param name="original">The original pattern node to be copy constructed.</param>
 /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param>
 /// <param name="newHost">The pattern graph the new pattern node will be contained in.</param>
 /// <param name="nameSuffix">The suffix to be added to the name of the pattern node (to avoid name collisions).</param>
 public PatternNode(PatternNode original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix)
     : base(original, inlinedSubpatternEmbedding, newHost, nameSuffix)
 {
 }
        /// <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>
 /// Instantiates a new PatternVariable object as a copy from an original variable, used for inlining.
 /// </summary>
 /// <param name="original">The original pattern variable to be copy constructed.</param>
 /// <param name="inlinedSubpatternEmbedding">The embedding which just gets inlined.</param>
 /// <param name="newHost">The pattern graph the new pattern element will be contained in.</param>
 /// <param name="nameSuffix">The suffix to be added to the name of the pattern variable (to avoid name collisions).</param>
 public PatternVariable(PatternVariable original, PatternGraphEmbedding inlinedSubpatternEmbedding, PatternGraph newHost, String nameSuffix)
 {
     type = original.type;
     name = original.name + nameSuffix;
     unprefixedName = original.unprefixedName + nameSuffix;
     pointOfDefinition = newHost;
     defToBeYieldedTo = original.defToBeYieldedTo;
     initialization = original.initialization;
     annotations = original.annotations;
     ParameterIndex = original.ParameterIndex;
     originalVariable = original;
     originalSubpatternEmbedding = inlinedSubpatternEmbedding;
 }
        /// <summary>
        /// Maps the actual implementations of the designpattern.
        /// </summary>
        /// <param name="graph">The graph.</param>
        /// <param name="foundComponents">The found components.</param>
        /// <param name="componentMatches">The component matches.</param>
        /// <returns>A list of possible matches, these implementations might be incomplete.</returns>
        private List <Dictionary <Component, List <ComponentMatch> > > MapImplementations(PatternGraph graph, List <GraphComponent> foundComponents, Dictionary <Component, List <ComponentMatch> > componentMatches)
        {
            var mappedImplementations = new List <Dictionary <Component, List <ComponentMatch> > >();

            var remainingMatches     = componentMatches.Where(c => foundComponents.Any(fc => fc.Component != c.Key)).ToDictionary(x => x.Key, x => x.Value);
            var noMatchPreviousRound = true;

            while (remainingMatches.Count > 0)
            {
                var matchFound = false;

                foreach (var remainingMatch in remainingMatches)
                {
                    var matchedComponent = this.MatchRemainingComponent(graph, remainingMatch, foundComponents);

                    if (matchedComponent != null)
                    {
                        foundComponents.Add(matchedComponent);
                        matchFound = true;
                    }
                }

                if (matchFound)
                {
                    foreach (var foundComponent in foundComponents)
                    {
                        if (remainingMatches.ContainsKey(foundComponent.Component))
                        {
                            remainingMatches.Remove(foundComponent.Component);
                        }
                    }
                }
                else if (!matchFound && noMatchPreviousRound)
                {
                    // Pattern not updated, no matches to be found. Stop process.
                    remainingMatches.Clear();
                }
                else
                {
                    noMatchPreviousRound = true;
                }
            }

            foreach (var possibleImplementation in this.possibleImplementations)
            {
                if (this.MatchComponentCount(graph.DesignPattern, possibleImplementation))
                {
                    mappedImplementations.Add(possibleImplementation);
                }
            }

            return(mappedImplementations);
        }