private static void BuildInterpretationPlan(LGSPGraph graph)
        {
            graph.matchingState.patternGraph = BuildPatternGraph(graph);
            PlanGraph planGraph = PlanGraphGenerator.GeneratePlanGraph(graph.Model, graph.statistics, graph.matchingState.patternGraph,
                                                                       false, false, false, new Dictionary <PatternElement, SetValueType>());

            PlanGraphGenerator.MarkMinimumSpanningArborescence(planGraph, graph.matchingState.patternGraph.name, false);
            SearchPlanGraph     searchPlanGraph     = SearchPlanGraphGeneratorAndScheduler.GenerateSearchPlanGraph(planGraph);
            ScheduledSearchPlan scheduledSearchPlan = SearchPlanGraphGeneratorAndScheduler.ScheduleSearchPlan(
                searchPlanGraph, graph.matchingState.patternGraph, false, false);
            InterpretationPlanBuilder builder = new InterpretationPlanBuilder(scheduledSearchPlan, searchPlanGraph, graph.Model);

            graph.matchingState.interpretationPlan = builder.BuildInterpretationPlan("ComparisonMatcher_" + graph.GraphId);
            ++GraphMatchingState.numInterpretationPlans;
            graph.matchingState.changesCounterAtInterpretationPlanBuilding = graph.changesCounterAtLastAnalyze;
            Debug.Assert(graph.changesCounterAtLastAnalyze == graph.ChangesCounter);

#if LOG_ISOMORPHY_CHECKING
            SourceBuilder sb = new SourceBuilder();
            graph.matchingState.interpretationPlan.Dump(sb);
            writer.WriteLine();
            writer.WriteLine(sb.ToString());
            writer.WriteLine();
            writer.Flush();
#endif
        }
Beispiel #2
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));
        }
Beispiel #3
0
 /// <summary>
 /// Creates an interpretation plan builder for the given scheduled search plan.
 /// Only a limited amount of search operations is supported, the ones needed for isomorphy checking.
 /// </summary>
 /// <param name="ssp">the scheduled search plan to build an interpretation plan for</param>
 /// <param name="spg">the search plan graph for determining the pattern element needed for attribute checking</param>
 /// <param name="model">the model over which the patterns are to be searched</param>
 public InterpretationPlanBuilder(ScheduledSearchPlan ssp, SearchPlanGraph spg, IGraphModel model)
 {
     this.ssp   = ssp;
     this.spg   = spg;
     this.model = model;
 }