Exemplo n.º 1
0
        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
        }
Exemplo n.º 2
0
        /// <summary>
        /// Parallelize the scheduled search plan for usage from a parallelized matcher
        /// (non- is-matched-flag-based isomorphy checking)
        /// </summary>
        public static void Parallelize(LGSPMatchingPattern matchingPattern)
        {
            Debug.Assert(matchingPattern.patternGraph.schedulesIncludingNegativesAndIndependents.Length == 1);
            ScheduledSearchPlan ssp = matchingPattern.patternGraph.schedulesIncludingNegativesAndIndependents[0];

            matchingPattern.patternGraph.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(
                matchingPattern.patternGraph, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0);

            matchingPattern.patternGraph.parallelizedSchedule[0] = clonedSsp;
            ParallelizeNegativeIndependent(clonedSsp);
            ParallelizeAlternativeIterated(matchingPattern.patternGraph);
            ParallelizeYielding(matchingPattern.patternGraph);
        }
Exemplo n.º 3
0
 public static void Explain(ScheduledSearchPlan ssp, SourceBuilder sb, IGraphModel model)
 {
     foreach (SearchOperation searchOp in ssp.Operations)
     {
         Explain(searchOp, sb, model);
     }
 }
Exemplo n.º 4
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);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Appends homomorphy information to each operation of the scheduled search plan
        /// </summary>
        public static void AppendHomomorphyInformation(IGraphModel model, ScheduledSearchPlan ssp)
        {
            // no operation -> nothing which could be homomorph
            if (ssp.Operations.Length == 0)
            {
                return;
            }

            // iterate operations of the search plan to append homomorphy checks
            for (int i = 0; i < ssp.Operations.Length; ++i)
            {
                if (ssp.Operations[i].Type == SearchOperationType.Condition ||
                    ssp.Operations[i].Type == SearchOperationType.AssignVar ||
                    ssp.Operations[i].Type == SearchOperationType.DefToBeYieldedTo ||
                    ssp.Operations[i].Type == SearchOperationType.InlinedIndependentCheckForDuplicateMatch)
                {
                    continue;
                }

                if (ssp.Operations[i].Type == SearchOperationType.NegativePattern)
                {
                    AppendHomomorphyInformation(model, (ScheduledSearchPlan)ssp.Operations[i].Element);
                    continue;
                }

                if (ssp.Operations[i].Type == SearchOperationType.IndependentPattern)
                {
                    AppendHomomorphyInformation(model, (ScheduledSearchPlan)ssp.Operations[i].Element);
                    continue;
                }

                DetermineAndAppendHomomorphyChecks(model, ssp, i);
            }
        }
Exemplo n.º 6
0
        private static void DumpScheduledSearchPlan(ScheduledSearchPlan ssp, IGraphModel model, String dumpname)
        {
            StreamWriter  sw = new StreamWriter(dumpname + "-scheduledsp.txt", false);
            SourceBuilder sb = new SourceBuilder();

            ScheduleExplainer.Explain(ssp, sb, model);
            sb.Append("\n");
            sw.WriteLine(sb.ToString());
            sw.Close();
        }
Exemplo n.º 7
0
        public object Clone()
        {
            ScheduledSearchPlan ssp = new ScheduledSearchPlan(PatternGraph, new SearchOperation[Operations.Length], Cost);

            for (int i = 0; i < Operations.Length; ++i)
            {
                ssp.Operations[i] = (SearchOperation)Operations[i].Clone();
            }
            return(ssp);
        }
Exemplo n.º 8
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);
            }
        }
Exemplo n.º 9
0
        public static void DumpScheduledSearchPlanAsVcg(ScheduledSearchPlan ssp, IGraphModel model, String dumpname)
        {
            StreamWriter sw = new StreamWriter(dumpname + "-scheduledsp.vcg", false);

            sw.WriteLine("graph:{\ninfoname 1: \"Attributes\"\ndisplay_edge_labels: no\nport_sharing: no\nsplines: no\n"
                         + "\nmanhattan_edges: no\nsmanhattan_edges: no\norientation: bottom_to_top\nedges: yes\nnodes: yes\nclassname 1: \"normal\"");
            sw.WriteLine("node:{title:\"root\" label:\"ROOT\"}\n");
            SearchPlanNode root = new SearchPlanNode("root");

            sw.WriteLine("graph:{{title:\"pattern\" label:\"{0}\" status:clustered color:lightgrey", dumpname);

            foreach (SearchOperation op in ssp.Operations)
            {
                switch (op.Type)
                {
                case SearchOperationType.Lookup:
                case SearchOperationType.Incoming:
                case SearchOperationType.Outgoing:
                case SearchOperationType.ImplicitSource:
                case SearchOperationType.ImplicitTarget:
                {
                    SearchPlanNode spnode = (SearchPlanNode)op.Element;
                    DumpNode(sw, spnode);
                    SearchPlanNode src;
                    switch (op.Type)
                    {
                    case SearchOperationType.Lookup:
                    case SearchOperationType.ActionPreset:
                    case SearchOperationType.NegIdptPreset:
                        src = root;
                        break;

                    default:
                        src = op.SourceSPNode;
                        break;
                    }
                    DumpEdge(sw, op.Type, src, spnode, op.CostToEnd, false);
                    break;
                }

                case SearchOperationType.Condition:
                    sw.WriteLine("node:{title:\"Condition\" label:\"CONDITION\"}\n");
                    break;

                case SearchOperationType.NegativePattern:
                    sw.WriteLine("node:{title:\"NAC\" label:\"NAC\"}\n");
                    break;
                }
            }
        }
Exemplo n.º 10
0
        /// <summary>
        /// Non- is-matched-flag-based isomorphy checking for nested negatives/independents,
        /// patch into already cloned parallel ssp
        /// </summary>
        private static void ParallelizeNegativeIndependent(ScheduledSearchPlan ssp)
        {
            foreach (SearchOperation so in ssp.Operations)
            {
                so.Isomorphy.Parallel = true;

                if (so.Type == SearchOperationType.NegativePattern ||
                    so.Type == SearchOperationType.IndependentPattern)
                {
                    ScheduledSearchPlan    nestedSsp  = (ScheduledSearchPlan)so.Element;
                    List <SearchOperation> operations = new List <SearchOperation>(nestedSsp.Operations.Length);
                    for (int i = 0; i < nestedSsp.Operations.Length; ++i)
                    {
                        SearchOperation nestedSo = nestedSsp.Operations[i];
                        SearchOperation clone    = (SearchOperation)nestedSo.Clone();
                        operations.Add(clone);
                        if (clone.Element is PatternCondition)
                        {
                            SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                        }
                    }
                    Debug.Assert(nestedSsp.PatternGraph.parallelizedSchedule == null); // may fire in case explain was used before, ignore it then
                    nestedSsp.PatternGraph.parallelizedSchedule = new ScheduledSearchPlan[1];
                    ScheduledSearchPlan clonedSsp = new ScheduledSearchPlan(
                        nestedSsp.PatternGraph, operations.ToArray(), operations.Count > 0 ? operations[0].CostToEnd : 0);
                    nestedSsp.PatternGraph.parallelizedSchedule[0] = clonedSsp;
                    so.Element = clonedSsp;

                    ParallelizeNegativeIndependent(clonedSsp);
                    ParallelizeAlternativeIterated(nestedSsp.PatternGraph);
                    if (so.Type == SearchOperationType.IndependentPattern)
                    {
                        ParallelizeYielding(nestedSsp.PatternGraph);
                    }
                }
            }
        }
Exemplo n.º 11
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;
 }
Exemplo n.º 12
0
        /// <summary>
        /// Determines which homomorphy check operations are necessary
        /// at the operation of the given position within the scheduled search plan
        /// and appends them.
        /// </summary>
        private static void DetermineAndAppendHomomorphyChecks(IGraphModel model, ScheduledSearchPlan ssp, int j)
        {
            // take care of global homomorphy
            FillInGlobalHomomorphyPatternElements(ssp, j);

            ///////////////////////////////////////////////////////////////////////////
            // first handle special case pure homomorphy

            SearchPlanNode spn_j = (SearchPlanNode)ssp.Operations[j].Element;

            if (spn_j.ElementID == -1)
            {
                // inlined from independent for better matching, independent from the rest
                return;
            }

            bool homToAll = true;

            if (spn_j.NodeType == PlanNodeType.Node)
            {
                for (int i = 0; i < ssp.PatternGraph.nodesPlusInlined.Length; ++i)
                {
                    if (!ssp.PatternGraph.homomorphicNodes[spn_j.ElementID - 1, i])
                    {
                        homToAll = false;
                        break;
                    }
                }
            }
            else //(spn_j.NodeType == PlanNodeType.Edge)
            {
                for (int i = 0; i < ssp.PatternGraph.edgesPlusInlined.Length; ++i)
                {
                    if (!ssp.PatternGraph.homomorphicEdges[spn_j.ElementID - 1, i])
                    {
                        homToAll = false;
                        break;
                    }
                }
            }

            if (homToAll)
            {
                // operation is allowed to be homomorph with everything
                // no checks for isomorphy or restricted homomorphy needed at all
                return;
            }

            ///////////////////////////////////////////////////////////////////////////
            // no pure homomorphy, so we have restricted homomorphy or isomorphy
            // and need to inspect the operations before, together with the homomorphy matrix
            // for determining the necessary homomorphy checks

            GraphElementType[] types;
            bool[,] hom;

            if (spn_j.NodeType == PlanNodeType.Node)
            {
                types = model.NodeModel.Types;
                hom   = ssp.PatternGraph.homomorphicNodes;
            }
            else // (spn_j.NodeType == PlanNodeType.Edge)
            {
                types = model.EdgeModel.Types;
                hom   = ssp.PatternGraph.homomorphicEdges;
            }

            // order operation to check against all elements it's not allowed to be homomorph to

            // iterate through the operations before our position
            bool homomorphyPossibleAndAllowed = false;

            for (int i = 0; i < j; ++i)
            {
                // only check operations computing nodes or edges
                if (ssp.Operations[i].Type == SearchOperationType.Condition ||
                    ssp.Operations[i].Type == SearchOperationType.NegativePattern ||
                    ssp.Operations[i].Type == SearchOperationType.IndependentPattern ||
                    ssp.Operations[i].Type == SearchOperationType.Assign ||
                    ssp.Operations[i].Type == SearchOperationType.AssignVar ||
                    ssp.Operations[i].Type == SearchOperationType.DefToBeYieldedTo ||
                    ssp.Operations[i].Type == SearchOperationType.InlinedIndependentCheckForDuplicateMatch)
                {
                    continue;
                }

                SearchPlanNode spn_i = (SearchPlanNode)ssp.Operations[i].Element;

                if (spn_i.NodeType != spn_j.NodeType)
                {
                    // don't compare nodes with edges
                    continue;
                }

                if (spn_i.ElementID == -1)
                {
                    // inlined from independent for better matching, independent from the rest
                    continue;
                }

                // find out whether element types are disjoint
                GraphElementType type_i   = types[spn_i.PatternElement.TypeID];
                GraphElementType type_j   = types[spn_j.PatternElement.TypeID];
                bool             disjoint = true;
                foreach (GraphElementType subtype_i in type_i.SubOrSameTypes)
                {
                    if (type_j.IsA(subtype_i) || subtype_i.IsA(type_j)) // IsA==IsSuperTypeOrSameType
                    {
                        disjoint = false;
                        break;
                    }
                }

                if (disjoint)
                {
                    // don't check elements if their types are disjoint
                    continue;
                }

                // at this position we found out that spn_i and spn_j
                // might get matched to the same host graph element, i.e. homomorphy is possible

                // if that's ok we don't need to insert checks to prevent this from happening
                if (hom[spn_i.ElementID - 1, spn_j.ElementID - 1])
                {
                    homomorphyPossibleAndAllowed = true;
                    continue;
                }

                // otherwise the generated matcher code has to check
                // that pattern element j doesn't get bound to the same graph element
                // the pattern element i is already bound to
                if (ssp.Operations[j].Isomorphy.PatternElementsToCheckAgainst == null)
                {
                    ssp.Operations[j].Isomorphy.PatternElementsToCheckAgainst = new List <SearchPlanNode>();
                }
                ssp.Operations[j].Isomorphy.PatternElementsToCheckAgainst.Add(spn_i);

                // if spn_j might get matched to the same host graph element as spn_i and this is not allowed
                // make spn_i set the is-matched-bit so that spn_j can detect this situation
                ssp.Operations[i].Isomorphy.SetIsMatchedBit = true;
            }

            // only if elements, the operation must be isomorph to, were matched before
            // (otherwise there were only elements, the operation is allowed to be homomorph to,
            //  matched before, so no check needed here)
            if (ssp.Operations[j].Isomorphy.PatternElementsToCheckAgainst != null &&
                ssp.Operations[j].Isomorphy.PatternElementsToCheckAgainst.Count > 0)
            {
                // order operation to check whether the is-matched-bit is set
                ssp.Operations[j].Isomorphy.CheckIsMatchedBit = true;
            }

            // if no check for isomorphy was skipped due to homomorphy being allowed
            // pure isomorphy is to be guaranteed - simply check the is-matched-bit and be done
            // the pattern elements to check against are only needed
            // if spn_j is allowed to be homomorph to some elements but must be isomorph to some others
            if (ssp.Operations[j].Isomorphy.CheckIsMatchedBit && !homomorphyPossibleAndAllowed)
            {
                ssp.Operations[j].Isomorphy.PatternElementsToCheckAgainst = null;
            }
        }
Exemplo n.º 13
0
        /// <summary>
        /// Parallelize the scheduled search plan to the branching factor,
        /// splitting it at the first loop into a header part and a body part
        /// </summary>
        public static void ParallelizeHeadBody(LGSPRulePattern rulePattern)
        {
            Debug.Assert(rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents.Length == 1);
            ScheduledSearchPlan ssp = rulePattern.patternGraph.schedulesIncludingNegativesAndIndependents[0];

            int indexToSplitAt = 0;

            for (int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if (so.Type == SearchOperationType.Lookup || so.Type == SearchOperationType.Incident ||
                    so.Type == SearchOperationType.Incoming || so.Type == SearchOperationType.Outgoing ||
                    so.Type == SearchOperationType.PickFromStorage || so.Type == SearchOperationType.PickFromStorageDependent ||
                    so.Type == SearchOperationType.PickFromIndex || so.Type == SearchOperationType.PickFromIndexDependent)
                {
                    indexToSplitAt = i;
                    break;
                }
            }

            rulePattern.patternGraph.parallelizedSchedule = new ScheduledSearchPlan[2];
            List <SearchOperation> headOperations = new List <SearchOperation>();
            List <SearchOperation> bodyOperations = new List <SearchOperation>();

            for (int i = 0; i < rulePattern.Inputs.Length; ++i)
            {
                if (rulePattern.Inputs[i] is VarType) // those don't appear in the schedule, they are only extracted into the search program
                {
                    VarType         varType = (VarType)rulePattern.Inputs[i];
                    String          varName = rulePattern.InputNames[i];
                    PatternVariable dummy   = new PatternVariable(varType, varName, varName, i, false, null);
                    headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                                                           dummy, null, 0));
                    bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                                                           dummy, null, 0));
                }
            }
            for (int i = 0; i < ssp.Operations.Length; ++i)
            {
                SearchOperation so = ssp.Operations[i];
                if (i < indexToSplitAt)
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel          = true;
                    clone.Isomorphy.LockForAllThreads = true;
                    headOperations.Add(clone);
                    switch (so.Type)
                    {
                    // the target binding looping operations can't appear in the header, so we don't treat them here
                    // the non-target binding operations are completely handled by just adding them, happended already above
                    // the target binding non-looping operations are handled below,
                    // by parallel preset writing in the header and reading in the body
                    // with exception of def, its declaration and initializion is just re-executed in the body
                    // some presets can't appear in an action header, they are thus not taken care of
                    case SearchOperationType.ActionPreset:
                    case SearchOperationType.MapWithStorage:
                    case SearchOperationType.MapWithStorageDependent:
                    case SearchOperationType.Cast:
                    case SearchOperationType.Assign:
                    case SearchOperationType.Identity:
                    case SearchOperationType.ImplicitSource:
                    case SearchOperationType.ImplicitTarget:
                    case SearchOperationType.Implicit:
                        headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPreset,
                                                               (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                        bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPreset,
                                                               (SearchPlanNode)so.Element, so.SourceSPNode, 0));
                        break;

                    case SearchOperationType.AssignVar:
                        headOperations.Add(new SearchOperation(SearchOperationType.WriteParallelPresetVar,
                                                               (PatternVariable)so.Element, so.SourceSPNode, 0));
                        bodyOperations.Add(new SearchOperation(SearchOperationType.ParallelPresetVar,
                                                               (PatternVariable)so.Element, so.SourceSPNode, 0));
                        break;

                    case SearchOperationType.DefToBeYieldedTo:
                        bodyOperations.Add((SearchOperation)so.Clone());
                        break;
                    }
                }
                else if (i == indexToSplitAt)
                {
                    SearchOperation cloneHead;
                    SearchOperation cloneBody;
                    switch (so.Type)
                    {
                    case SearchOperationType.Lookup:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelLookup);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelLookup);
                        break;

                    case SearchOperationType.Incident:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncident);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncident);
                        break;

                    case SearchOperationType.Incoming:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelIncoming);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelIncoming);
                        break;

                    case SearchOperationType.Outgoing:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelOutgoing);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelOutgoing);
                        break;

                    case SearchOperationType.PickFromStorage:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorage);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorage);
                        break;

                    case SearchOperationType.PickFromStorageDependent:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromStorageDependent);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromStorageDependent);
                        break;

                    case SearchOperationType.PickFromIndex:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndex);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndex);
                        break;

                    case SearchOperationType.PickFromIndexDependent:
                        cloneHead = (SearchOperation)so.Clone(SearchOperationType.SetupParallelPickFromIndexDependent);
                        cloneBody = (SearchOperation)so.Clone(SearchOperationType.ParallelPickFromIndexDependent);
                        break;

                    default: // failure, operation at this index cannot be parallelized/parallelization not supported
                        cloneHead = null;
                        cloneBody = null;
                        break;
                    }
                    headOperations.Add(cloneHead);
                    cloneBody.Isomorphy.Parallel = true;
                    bodyOperations.Add(cloneBody);
                }
                else
                {
                    SearchOperation clone = (SearchOperation)so.Clone();
                    clone.Isomorphy.Parallel = true;
                    bodyOperations.Add(clone);
                    if (clone.Element is PatternCondition)
                    {
                        SetNeedForParallelizedVersion((clone.Element as PatternCondition).ConditionExpression);
                    }
                }
            }
            ScheduledSearchPlan headSsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, headOperations.ToArray(), headOperations.Count > 0 ? headOperations[0].CostToEnd : 0);

            rulePattern.patternGraph.parallelizedSchedule[0] = headSsp;
            ScheduledSearchPlan bodySsp = new ScheduledSearchPlan(
                rulePattern.patternGraph, bodyOperations.ToArray(), bodyOperations.Count > 0 ? bodyOperations[0].CostToEnd : 0);

            rulePattern.patternGraph.parallelizedSchedule[1] = bodySsp;
            ParallelizeNegativeIndependent(bodySsp);
            ParallelizeAlternativeIterated(rulePattern.patternGraph);
            ParallelizeYielding(rulePattern.patternGraph);
        }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
0
        /// <summary>
        /// fill in globally homomorphic elements as exception to global isomorphy check
        /// </summary>
        private static void FillInGlobalHomomorphyPatternElements(ScheduledSearchPlan ssp, int j)
        {
            SearchPlanNode spn_j = (SearchPlanNode)ssp.Operations[j].Element;

            if (spn_j.NodeType == PlanNodeType.Node)
            {
                if (spn_j.ElementID == -1 || // inlined from independent for better matching, independent from the rest
                    ssp.PatternGraph.totallyHomomorphicNodes[spn_j.ElementID - 1])
                {
                    ssp.Operations[j].Isomorphy.TotallyHomomorph = true;
                    return; // iso-exceptions to totally hom are handled with non-global iso checks
                }
            }
            else
            {
                if (spn_j.ElementID == -1 || // inlined from independent for better matching, independent from the rest
                    ssp.PatternGraph.totallyHomomorphicEdges[spn_j.ElementID - 1])
                {
                    ssp.Operations[j].Isomorphy.TotallyHomomorph = true;
                    return; // iso-exceptions to totally hom are handled with non-global iso checks
                }
            }

            bool[,] homGlobal;
            if (spn_j.NodeType == PlanNodeType.Node)
            {
                homGlobal = ssp.PatternGraph.homomorphicNodesGlobal;
            }
            else // (spn_j.NodeType == PlanNodeType.Edge)
            {
                homGlobal = ssp.PatternGraph.homomorphicEdgesGlobal;
            }

            // iterate through the operations before our position
            for (int i = 0; i < j; ++i)
            {
                // only check operations computing nodes or edges
                if (ssp.Operations[i].Type == SearchOperationType.Condition ||
                    ssp.Operations[i].Type == SearchOperationType.NegativePattern ||
                    ssp.Operations[i].Type == SearchOperationType.IndependentPattern ||
                    ssp.Operations[i].Type == SearchOperationType.Assign ||
                    ssp.Operations[i].Type == SearchOperationType.AssignVar ||
                    ssp.Operations[i].Type == SearchOperationType.DefToBeYieldedTo ||
                    ssp.Operations[i].Type == SearchOperationType.InlinedIndependentCheckForDuplicateMatch)
                {
                    continue;
                }

                SearchPlanNode spn_i = (SearchPlanNode)ssp.Operations[i].Element;

                if (spn_i.NodeType != spn_j.NodeType)
                {
                    // don't compare nodes with edges
                    continue;
                }

                if (spn_i.ElementID == -1)
                {
                    // inlined from independent for better matching, independent from the rest
                    continue;
                }

                // in global isomorphy check at current position
                // allow globally homomorphic elements as exception
                // if they were already defined(preset)
                if (homGlobal[spn_j.ElementID - 1, spn_i.ElementID - 1])
                {
                    if (ssp.Operations[j].Isomorphy.GloballyHomomorphPatternElements == null)
                    {
                        ssp.Operations[j].Isomorphy.GloballyHomomorphPatternElements = new List <SearchPlanNode>();
                    }
                    ssp.Operations[j].Isomorphy.GloballyHomomorphPatternElements.Add(spn_i);
                }
            }
        }
Exemplo n.º 16
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);
        }