예제 #1
0
            private ControlState Choose()
            {
                ControlState c = ControlState.Fail;
                Permuter p = btp.permuter;
                int count = xtoNodes.Count;
                do
                {
                    for (int i = 0; i < count; i++)
                    {
                        c = ExtendForOnlyFunctionalEdges(xtoNodes.Choose(i), ytoNodes.Choose(p[i]));
                        if (c == ControlState.Fail)
                            break;
                    }

                    if (c == ControlState.Fail && p.Next())
                    {
                        index = btp.index;
                        indexDict = BacktrackPoint.getCopy(btp.indexDict);
                        rangeDict = BacktrackPoint.getCopy(btp.rangeDict);
                    }
                    else
                        break;
                } while (true);
                if (count > 1 && p.Next())
                {
                    btp.permuter = p;
                    backtrackStack.Push(btp);
                }
                btp = null;
                return c;
            }
예제 #2
0
        protected override Result <char, Match2> Parse(ArrayConsList <char> consList, int afterLastMatchIndex)
        {
            BacktrackPoint lastBacktrackPoint = null;

            StackFrame callStack     = new GroupStackFrame(null, Pattern);
            var        partialResult = new Result <char, int>(0, consList);

            while (callStack != null)
            {
                if (callStack is QuantifierStackFrame)
                {
                    QuantifierStackFrame quantStackFrame = (QuantifierStackFrame)callStack;

                    if (quantStackFrame.IsPositionChanged(partialResult.Tree))
                    {
                        lastBacktrackPoint = new BacktrackPoint(lastBacktrackPoint,
                                                                quantStackFrame.SecondAlternative(partialResult.Tree),
                                                                partialResult);

                        callStack = quantStackFrame.FirstAlternative(partialResult.Tree);
                    }
                    else
                    {
                        callStack = quantStackFrame.Parent;
                    }
                }
                else
                {
                    BasePattern currentPattern = callStack.RemainingChildren.Head;

                    if (currentPattern.MinCharLength > partialResult.Rest.Length)
                    {
                        partialResult = null;
                    }
                    else
                    {
                        callStack = ((GroupStackFrame)callStack).MoveToNextChild();

                        switch (currentPattern.Type)
                        {
                        case PatternType.Group:
                            callStack = new GroupStackFrame(callStack, ((GroupPattern)currentPattern).Patterns);
                            break;


                        case PatternType.Quantifier:
                            var quant = (QuantifierPattern)currentPattern;

                            quant.AssertCanonicalForm();

                            if (quant.MinOccurrences == quant.MaxOccurrences)
                            {
                                callStack = new GroupStackFrame(callStack,
                                                                new RepeaterConsList <BasePattern>(quant.ChildPattern,
                                                                                                   quant.MinOccurrences));
                            }

                            else
                            {
                                callStack = new QuantifierStackFrame(callStack, quant);
                            }
                            break;


                        case PatternType.Alternation:
                            var alternatives = ((AlternationPattern)currentPattern).Alternatives;

                            foreach (var alt in alternatives.Skip(1).Reverse())
                            {
                                lastBacktrackPoint = new BacktrackPoint(lastBacktrackPoint,
                                                                        new GroupStackFrame(callStack, alt),
                                                                        partialResult);
                            }

                            callStack = new GroupStackFrame(callStack, alternatives.First());
                            break;


                        case PatternType.Anchor:
                            if (!doesAnchorMatch(((AnchorPattern)currentPattern).AnchorType,
                                                 (ArrayConsList <char>)partialResult.Rest,
                                                 afterLastMatchIndex))
                            {
                                partialResult = null;
                            }
                            break;


                        case PatternType.Char:
                            partialResult = parseChar(partialResult, ((CharPattern)currentPattern).IsMatch);
                            break;


                        default:
                            throw new ApplicationException(
                                      string.Format("BacktrackingMatcher: unrecognized pattern type ({0}).",
                                                    currentPattern.GetType().Name));
                        }
                    }

                    if (partialResult == null)
                    {
                        if (lastBacktrackPoint != null)
                        {
                            callStack     = lastBacktrackPoint.CallStack;
                            partialResult = lastBacktrackPoint.PartialResult;

                            lastBacktrackPoint = lastBacktrackPoint.Previous;
                        }
                        else
                        {
                            return(new Result <char, Match2>(Match2.Empty, consList));
                        }
                    }
                }

                callStack = unwindEmptyFrames(callStack);
            }

            return(new Result <char, Match2>(
                       new Match2(consList.ArrayIndex,
                                  partialResult.Tree,
                                  consList.AsEnumerable().Take(partialResult.Tree).AsString()),
                       partialResult.Rest));
        }
예제 #3
0
            internal Map<Node, Node> ComputeIsomorphism()
            {
                // We start with a functional pass.
                ControlState c = ControlState.InitialFunctionalPass;
                while (true)
                {

                    switch (c)
                    {
                        # region Find all reachable functional matches of current active nodes x and y.
                        case ControlState.InitialFunctionalPass:
                            c = ExtendForOnlyFunctionalEdges(x, y);

                            break;
                        # endregion

                        #region Find all relational matches after one or more functional pass.
                        case ControlState.RelationalPass:
                            if (relationalPassIndex >= index)
                            {
                                if (relationalPassIndex == numberOfNodes)
                                    c = ControlState.Done;
                                else
                                    c = ControlState.Fail;
                                break;

                            }
                            x = bijection[relationalPassIndex, X];
                            y = bijection[relationalPassIndex, Y];
                            xData = g1.vertexRecords[x];
                            yData = g2.vertexRecords[y];
                            if (relationalEdgeEnumerator == default(IEnumerator<CompoundTerm>))
                            {

                                relationalEdgeLabels = Set<CompoundTerm>.EmptySet;
                                foreach (Pair<CompoundTerm, Set<Node>> pair in xData.unorderedOutgoingEdges)
                                {
                                    relationalEdgeLabels = relationalEdgeLabels.Add(pair.First);
                                }
                                relationalEdgeEnumerator = relationalEdgeLabels.GetEnumerator();
                            }
                            if (relationalEdgeEnumerator.MoveNext())
                            {
                                xEdgeLabel = relationalEdgeEnumerator.Current;
                                xtoNodes = xData.unorderedOutgoingEdges[xEdgeLabel];
                                if (yData.unorderedOutgoingEdges.ContainsKey(xEdgeLabel)) // Perhaps this check can be assumed true for all graphs?
                                {
                                    ytoNodes = yData.unorderedOutgoingEdges[xEdgeLabel];
                                    c = ControlState.NextRelationalEdge;
                                }
                                else
                                    c = ControlState.Fail;

                            }
                            else
                            {
                                relationalPassIndex++;
                                relationalEdgeEnumerator = default(IEnumerator<CompoundTerm>);
                                relationalEdgeLabels = default(Set<CompoundTerm>);
                                if (relationalPassIndex == numberOfNodes)
                                    c = ControlState.Done;
                            }
                            break;

                        // It is possible that we have multiple sets of relational edges from a node. The following is done for each set.
                        case ControlState.NextRelationalEdge:

                            // xEdgeLabel has been set
                            // xtoNodes has been set;
                            // ytoNodes has been set;
                            Node x1, y1;
                            // remove all nodes that have already been matched.
                            for (int i = 0; i < xtoNodes.Count; i++)
                            {
                                x1 = xtoNodes.Choose(i);
                                if (indexDict.ContainsKey(x1))
                                {
                                    y1 = bijection[indexDict[x1], Y];
                                    if (ytoNodes.Contains(y1))
                                    {
                                        xtoNodes = xtoNodes.Remove(x1);
                                        ytoNodes = ytoNodes.Remove(y1);
                                    }
                                    else
                                    {
                                        c = ControlState.Fail;
                                        goto EndOfNextRelationalEdge;
                                    }
                                }
                            }
                            if (xtoNodes.Count == 0)
                            {
                                c = ControlState.RelationalPass;
                                break; // out of the switch statement
                            }// we do not need to check as all nodes contained in xtoNodes were already contained.
                            //isoExt = ExtendIsomorphism4(backtrackBuckets, backtrackStack, isoExt, xtoNodes.Choose(), ytoNodes.Choose());

                            btp = new BacktrackPoint(indexDict, rangeDict, xEdgeLabel, index, relationalPassIndex, relationalEdgeLabels.Remove(xEdgeLabel), xtoNodes, ytoNodes);
                            c = ControlState.Choose;

                        //goto case ControlState.Choose;
                        EndOfNextRelationalEdge:
                            break;

                        #endregion

                        #region Choose one combination of matching relational edges
                        case ControlState.Choose:
                            if (btp == null) // check used to stop when backtracking.
                            {
                                c = ControlState.Fail;
                                break;
                            }
                            c = Choose();
                            break;

                        #endregion

                        # region Process a backtrack request.

                        case ControlState.Fail:
                            if (backtrackStack.Count == 0)
                                return null;
                            else
                            {
                                // Reset environment to topmost backtrackpoint and continue
                                // with the relevant Choose from where we left off last time.
                                btp = backtrackStack.Pop();

                                // Restore program state from the BacktrackPoint.
                                index = btp.index;
                                relationalPassIndex = btp.relationalPassIndex;
                                indexDict = BacktrackPoint.getCopy(btp.indexDict);
                                xEdgeLabel = btp.outLabel;
                                rangeDict = BacktrackPoint.getCopy(btp.rangeDict);
                                x = bijection[relationalPassIndex, X];
                                y = bijection[relationalPassIndex, Y];
                                xData = g1.vertexRecords[x];
                                yData = g2.vertexRecords[y];
                                xtoNodes = btp.xtoNodes;
                                ytoNodes = btp.ytoNodes;
                                relationalEdgeLabels = btp.relationalEdgeLabels;
                                relationalEdgeEnumerator = btp.relationalEdgeLabels.GetEnumerator();

                                c = ControlState.Choose;
                            }
                            break;
                        # endregion

                        case ControlState.Done:
                            goto Success;

                        default:
                            break;
                    }
                }
                #region Prepare result map and return.
                Success:

                Map<Node, Node> iso = Map<Node, Node>.EmptyMap;
                for (int i = 0; i < numberOfNodes; i++)
                {
                    iso = iso.Add(bijection[i, X], bijection[i, Y]);
                }
                return iso;
                #endregion
            }