Ejemplo n.º 1
0
        public SubruleDebuggingDecision Decide(SubruleDebuggingEvent sde, object data, IGraphProcessingEnvironment procEnv)
        {
            if (!enabled)
            {
                return(SubruleDebuggingDecision.Undefined);
            }
            if (debuggingEvent != sde)
            {
                return(SubruleDebuggingDecision.Undefined);
            }

            switch (sde)
            {
            case SubruleDebuggingEvent.Add:
            case SubruleDebuggingEvent.Rem:
            case SubruleDebuggingEvent.Emit:
            case SubruleDebuggingEvent.Halt:
            case SubruleDebuggingEvent.Highlight:
            {
                string message = (string)data;
                switch (messageMatchingMode)
                {
                case SubruleMesssageMatchingMode.Equals:
                    if (message == messageToMatch)
                    {
                        return(decisionOnMatch);
                    }
                    break;

                case SubruleMesssageMatchingMode.StartsWith:
                    if (message.StartsWith(messageToMatch))
                    {
                        return(decisionOnMatch);
                    }
                    break;

                case SubruleMesssageMatchingMode.EndsWith:
                    if (message.EndsWith(messageToMatch))
                    {
                        return(decisionOnMatch);
                    }
                    break;

                case SubruleMesssageMatchingMode.Contains:
                    if (message.Contains(messageToMatch))
                    {
                        return(decisionOnMatch);
                    }
                    break;

                default:
                    throw new Exception("INTERNAL FAILURE: unkonwn message matching mode");
                }
            }
                return(SubruleDebuggingDecision.Undefined);

            case SubruleDebuggingEvent.Match:
            {
                IMatches matches = (IMatches)data;
                if (matches.Producer == actionToMatch)
                {
                    if (ifClause != null)
                    {
                        object oldThis = procEnv.GetVariableValue("this");
                        bool   result  = false;
                        foreach (IMatch match in matches)
                        {
                            procEnv.SetVariableValue("this", match);
                            if ((bool)ifClause.Evaluate(procEnv))
                            {
                                result = true;
                                break;
                            }
                        }
                        procEnv.SetVariableValue("this", oldThis);
                        if (result)
                        {
                            return(decisionOnMatch);
                        }
                    }
                    else
                    {
                        return(decisionOnMatch);
                    }
                }
                return(SubruleDebuggingDecision.Undefined);
            }

            case SubruleDebuggingEvent.New:
            case SubruleDebuggingEvent.Delete:
            case SubruleDebuggingEvent.Retype:
            case SubruleDebuggingEvent.SetAttributes:
            {
                IGraphElement elem = (IGraphElement)data;
                if (nameToMatch != null)
                {
                    if (procEnv.NamedGraph.GetElementName(elem) == nameToMatch)
                    {
                        if (If(elem, procEnv))
                        {
                            return(decisionOnMatch);
                        }
                    }
                }
                if (typeToMatch != null)
                {
                    if (elem.Type is NodeType && typeToMatch is NodeType && elem.Type.IsA(typeToMatch) ||
                        elem.Type is EdgeType && typeToMatch is EdgeType && elem.Type.IsA(typeToMatch))
                    {
                        if (onlyThisType)
                        {
                            if (typeToMatch.IsA(elem.Type))
                            {
                                if (If(elem, procEnv))
                                {
                                    return(decisionOnMatch);
                                }
                            }
                        }
                        else
                        {
                            if (If(elem, procEnv))
                            {
                                return(decisionOnMatch);
                            }
                        }
                    }
                }
                return(SubruleDebuggingDecision.Undefined);
            }

            default:
                return(SubruleDebuggingDecision.Undefined);
            }
        }
Ejemplo n.º 2
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

            GrGenType[] 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
                GrGenType type_i   = types[spn_i.PatternElement.TypeID];
                GrGenType type_j   = types[spn_j.PatternElement.TypeID];
                bool      disjoint = true;
                foreach (GrGenType 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;
            }
        }