/// <summary>
 /// Iterate all search programs to complete check operations within each one
 /// </summary>
 public static void CompleteCheckOperationsInAllSearchPrograms(
     SearchProgram searchProgram)
 {
     do
     {
         CompleteCheckOperations(
             searchProgram.GetNestedSearchOperationsList(),
             searchProgram,
             null,
             null,
             searchProgram);
         searchProgram = searchProgram.Next as SearchProgram;
     }while(searchProgram != null);
 }
 /// <summary>
 /// Iterate all search programs to complete check operations within each one
 /// </summary>
 public void CompleteCheckOperationsInAllSearchPrograms(
     SearchProgram searchProgram)
 {
     do
     {
         CompleteCheckOperations(
             searchProgram.GetNestedSearchOperationsList(),
             searchProgram,
             null,
             null,
             searchProgram);
         searchProgram = searchProgram.Next as SearchProgram;
     }
     while (searchProgram != null);
 }
        /// <summary>
        /// move outwards from check succeeded operation until check partial match by independent is found
        /// appending restore isomorphy for isomorphy written on the way
        /// and final jump to operation right after the independent failed operation of the check partial match by independent
        /// </summary>
        private static void MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump(
            CheckContinueMatchingOfIndependentSucceeded checkSucceeded,
            CheckPartialMatchByIndependent enclosingIndependent,
            SearchProgram topLevelSearchProgram)
        {
            // insertion point for candidate failed operations
            SearchProgramOperation insertionPoint =
                checkSucceeded.CheckFailedOperations;

            while (insertionPoint.Next != null) // needed?
            {
                insertionPoint = insertionPoint.Next;
            }

            // move outwards, append remove isomorphy
            string[] neededElements = new string[0];
            SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy(
                checkSucceeded, ref insertionPoint, neededElements, enclosingIndependent, topLevelSearchProgram);

            // move to check failed operation of check independent operation
            while (!(continuationPoint is CheckContinueMatchingOfIndependentFailed))
            {
                continuationPoint = continuationPoint.Next;
            }
            CheckContinueMatchingOfIndependentFailed checkFailed =
                (CheckContinueMatchingOfIndependentFailed)continuationPoint;

            // insert label right thereafter, append jump there at insertion point
            GotoLabel gotoLabel = new GotoLabel();

            checkFailed.Insert(gotoLabel);

            ContinueOperation continueByGoto =
                new ContinueOperation(
                    ContinueOperationType.ByGoto,
                    gotoLabel.LabelName);

            insertionPoint.Append(continueByGoto);
        }
        /// <summary>
        /// move outwards from starting point on until operation to continue at is found
        /// appending restore isomorphy at insertion point for isomorphy written on the way
        /// returns operation to continue at
        /// </summary>
        private static SearchProgramOperation MoveOutwardsAppendingRemoveIsomorphy(
            SearchProgramOperation startingPoint,
            ref SearchProgramOperation insertionPoint,
            string[] neededElementsForCheckOperation,
            SearchProgramOperation outermostOperation,
            SearchProgram topLevelSearchProgram)
        {
            // currently focused operation on our way outwards
            SearchProgramOperation op = startingPoint;
            // move outwards until operation to continue at is found
            bool creationPointOfDominatingElementFound = false;
            bool iterationReached = false;

            do
            {
                op = op.Previous;

                // insert code to clean up isomorphy information written by candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidate)
                {
                    AcceptCandidate writeIsomorphy =
                        op as AcceptCandidate;
                    AbandonCandidate restoreIsomorphy =
                        new AbandonCandidate(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode,
                            writeIsomorphy.NeverAboveMaxIsoSpace,
                            writeIsomorphy.Parallel,
                            writeIsomorphy.LockForAllThreads);
                    insertionPoint = insertionPoint.Append(restoreIsomorphy);
                }
                // insert code to clean up isomorphy information written by global candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidateGlobal)
                {
                    AcceptCandidateGlobal writeIsomorphy =
                        op as AcceptCandidateGlobal;
                    AbandonCandidateGlobal removeIsomorphy =
                        new AbandonCandidateGlobal(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode,
                            writeIsomorphy.NeverAboveMaxIsoSpace,
                            writeIsomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(removeIsomorphy);
                }
                // insert code to clean up isomorphy information written by patternpath candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidatePatternpath)
                {
                    AcceptCandidatePatternpath writeIsomorphy =
                        op as AcceptCandidatePatternpath;
                    AbandonCandidatePatternpath removeIsomorphy =
                        new AbandonCandidatePatternpath(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode);
                    insertionPoint = insertionPoint.Append(removeIsomorphy);
                }
                // insert code to remove iterated pattern acceptance
                if (op is AcceptIterated)
                {
                    AcceptIterated acceptIterated =
                        op as AcceptIterated;
                    AbandonIterated abandonIterated =
                        new AbandonIterated();
                    insertionPoint = insertionPoint.Append(abandonIterated);
                }
                // insert code to undo subpattern matching initialization if we leave the subpattern matching method
                if (op is InitializeSubpatternMatching)
                {
                    InitializeSubpatternMatching initialize =
                        op as InitializeSubpatternMatching;
                    FinalizeSubpatternMatching finalize =
                        new FinalizeSubpatternMatching(initialize.Type);
                    insertionPoint = insertionPoint.Append(finalize);
                }
                // insert code to undo negative/independent matching initialization if we leave the negative/independent matching method
                if (op is InitializeNegativeIndependentMatching)
                {
                    InitializeNegativeIndependentMatching initialize =
                        op as InitializeNegativeIndependentMatching;
                    FinalizeNegativeIndependentMatching finalize =
                        new FinalizeNegativeIndependentMatching(initialize.NeverAboveMaxIsoSpace, initialize.Parallel);
                    insertionPoint = insertionPoint.Append(finalize);
                }

                // determine operation to continue at
                // found by looking at the graph elements
                // the check operation depends on / is dominated by
                // its the first element iteration on our way outwards the search program
                // after or at the point of a get element operation
                // of some dominating element the check depends on
                // (or the outermost operation if no iteration is found until it is reached)
                if (op is GetCandidate || op is BothDirectionsIteration)
                {
                    if (creationPointOfDominatingElementFound == false)
                    {
                        if (neededElementsForCheckOperation != null)
                        {
                            foreach (string dominating in neededElementsForCheckOperation)
                            {
                                GetCandidate            getCandidate   = op as GetCandidate;
                                BothDirectionsIteration bothDirections = op as BothDirectionsIteration;
                                if (getCandidate != null && getCandidate.PatternElementName == dominating ||
                                    bothDirections != null && bothDirections.PatternElementName == dominating)
                                {
                                    creationPointOfDominatingElementFound = true;
                                    iterationReached = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // needed elements == null means everything fits,
                            // take first element iteration on our way outwards the search program
                            // (or the outermost operation if no iteration is found until it is reached)
                            creationPointOfDominatingElementFound = true;
                            iterationReached = false;
                        }
                    }
                    if (op is GetCandidateByIteration || op is GetCandidateByIterationParallel || op is BothDirectionsIteration)
                    {
                        iterationReached = true;
                    }
                }
            }while(!(creationPointOfDominatingElementFound && iterationReached) &&
                   op != outermostOperation);

            return(op);
        }
        ///////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Completes check operations in search program from given currentOperation on
        /// (taking borderlines set by enclosing search program and check negative into account)
        /// Completion:
        /// - determine continuation point
        /// - insert remove isomorphy opertions needed for continuing there
        /// - insert continuing operation itself
        /// </summary>
        private static void CompleteCheckOperations(
            SearchProgramOperation currentOperation,
            SearchProgramOperation enclosingSearchProgram, // might be a negative/independent in case these are nested
            AlternativeCaseMatching enclosingAlternativeCase,
            CheckPartialMatchByNegativeOrIndependent enclosingCheckNegativeOrIndependent,
            SearchProgram topLevelSearchProgram)
        {
            // mainly dispatching and iteration method, traverses search program
            // real completion done in MoveOutwardsAppendingRemoveIsomorphyAndJump
            // outermost operation for that function is computed here, regarding negative patterns
            // program nesting structure: search program - [alternative] - [negative|independent]*

            // complete check operations by inserting failure code
            // find them in depth first search of search program
            while (currentOperation != null)
            {
                //////////////////////////////////////////////////////////
                if (currentOperation is CheckCandidate)
                //////////////////////////////////////////////////////////
                {
                    CheckCandidate checkCandidate =
                        (CheckCandidate)currentOperation;
                    checkCandidate.CheckFailedOperations =
                        new SearchProgramList(checkCandidate);
                    string[] neededElementsForCheckOperation = new string[1];
                    neededElementsForCheckOperation[0] = checkCandidate.PatternElementName;
                    MoveOutwardsAppendingRemoveIsomorphyAndJump(
                        checkCandidate,
                        neededElementsForCheckOperation,
                        enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                        topLevelSearchProgram);
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is CheckPartialMatch)
                //////////////////////////////////////////////////////////
                {
                    if (currentOperation is CheckPartialMatchByCondition)
                    {
                        CheckPartialMatchByCondition checkCondition =
                            (CheckPartialMatchByCondition)currentOperation;
                        checkCondition.CheckFailedOperations =
                            new SearchProgramList(checkCondition);
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkCondition,
                            checkCondition.NeededElements,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckPartialMatchForDuplicate)
                    {
                        CheckPartialMatchForDuplicate checkDuplicateMatch =
                            (CheckPartialMatchForDuplicate)currentOperation;
                        checkDuplicateMatch.CheckFailedOperations =
                            new SearchProgramList(checkDuplicateMatch);
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkDuplicateMatch,
                            checkDuplicateMatch.NeededElements,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckPartialMatchByNegativeOrIndependent)
                    {
                        CheckPartialMatchByNegativeOrIndependent checkNegativeOrIndependent =
                            (CheckPartialMatchByNegativeOrIndependent)currentOperation;

                        // ByNegative/ByIndependent is handled in CheckContinueMatchingFailed
                        // of the negative/independent case - enter negative/independent case
                        CompleteCheckOperations(
                            checkNegativeOrIndependent.NestedOperationsList,
                            enclosingCheckNegativeOrIndependent ?? enclosingSearchProgram,
                            enclosingCheckNegativeOrIndependent != null ? null : enclosingAlternativeCase,
                            checkNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckPartialMatchForSubpatternsFound)
                    {
                        CheckPartialMatchForSubpatternsFound checkSubpatternsFound =
                            (CheckPartialMatchForSubpatternsFound)currentOperation;

                        if (enclosingCheckNegativeOrIndependent == null)
                        {
                            // determine insertion point within check failed operations
                            // to append the nested check maximum matches
                            SearchProgramOperation insertionPoint =
                                checkSubpatternsFound.CheckFailedOperations;
                            while (insertionPoint.Next != null)
                            {
                                insertionPoint = insertionPoint.Next;
                            }

                            // append nested check maximum matches
                            CheckMaximumMatchesType checkMaxMatchesType = CheckMaximumMatchesType.Action;
                            if (enclosingSearchProgram is SearchProgramOfSubpattern ||
                                enclosingSearchProgram is SearchProgramOfAlternative)
                            {
                                checkMaxMatchesType = CheckMaximumMatchesType.Subpattern;
                            }
                            else if (enclosingSearchProgram is SearchProgramOfIterated)
                            {
                                checkMaxMatchesType = CheckMaximumMatchesType.Iterated;
                            }
                            CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                                new CheckContinueMatchingMaximumMatchesReached(checkMaxMatchesType, false,
                                                                               enclosingSearchProgram is SearchProgramOfActionParallelizationBody);
                            insertionPoint.Append(checkMaximumMatches);

                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkSubpatternsFound,
                                null,
                                enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                                topLevelSearchProgram);
                        }

                        // check subpatterns found has a further check maximum matches
                        // or check continue matching of negative failed nested within check failed code
                        // give it its special bit of attention here
                        CompleteCheckOperations(
                            checkSubpatternsFound.CheckFailedOperations,
                            enclosingSearchProgram,
                            enclosingAlternativeCase,
                            enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else
                    {
                        Debug.Assert(false, "unknown check partial match operation");
                    }
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is CheckContinueMatching)
                //////////////////////////////////////////////////////////
                {
                    if (currentOperation is CheckContinueMatchingMaximumMatchesReached)
                    {
                        CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                            (CheckContinueMatchingMaximumMatchesReached)currentOperation;
                        checkMaximumMatches.CheckFailedOperations =
                            new SearchProgramList(checkMaximumMatches);

                        if (checkMaximumMatches.ListHeadAdjustment)
                        {
                            MoveOutwardsAppendingListHeadAdjustment(checkMaximumMatches, checkMaximumMatches.InParallelizedBody);
                        }

                        string[] neededElementsForCheckOperation = new string[0];
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkMaximumMatches,
                            neededElementsForCheckOperation,
                            enclosingSearchProgram,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingOfNegativeFailed)
                    {
                        CheckContinueMatchingOfNegativeFailed checkFailed =
                            (CheckContinueMatchingOfNegativeFailed)currentOperation;
                        checkFailed.CheckFailedOperations =
                            new SearchProgramList(checkFailed);
                        if (checkFailed.IsIterationBreaking)
                        {
                            string[] neededElementsForCheckOperation = new string[0];
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                neededElementsForCheckOperation,
                                enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                        else
                        {
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                enclosingCheckNegativeOrIndependent.NeededElements,
                                enclosingAlternativeCase ?? enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                    }
                    else if (currentOperation is CheckContinueMatchingOfIndependentSucceeded)
                    {
                        CheckContinueMatchingOfIndependentSucceeded checkSucceeded =
                            (CheckContinueMatchingOfIndependentSucceeded)currentOperation;
                        checkSucceeded.CheckFailedOperations = // yep, rotten wording
                                                               new SearchProgramList(checkSucceeded);
                        MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump(
                            checkSucceeded,
                            (CheckPartialMatchByIndependent)enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingOfIndependentFailed)
                    {
                        CheckContinueMatchingOfIndependentFailed checkFailed =
                            (CheckContinueMatchingOfIndependentFailed)currentOperation;
                        checkFailed.CheckFailedOperations =
                            new SearchProgramList(checkFailed);
                        if (checkFailed.IsIterationBreaking)
                        {
                            string[] neededElementsForCheckOperation = new string[0];
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                neededElementsForCheckOperation,
                                enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                        else
                        {
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                checkFailed.CheckIndependent.NeededElements,
                                enclosingAlternativeCase ?? enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                    }
                    else if (currentOperation is CheckContinueMatchingTasksLeft)
                    {
                        CheckContinueMatchingTasksLeft tasksLeft =
                            (CheckContinueMatchingTasksLeft)currentOperation;

                        // determine insertion point within check failed operations
                        // to append the nested check maximum matches
                        SearchProgramOperation insertionPoint =
                            tasksLeft.CheckFailedOperations;
                        while (insertionPoint.Next != null)
                        {
                            insertionPoint = insertionPoint.Next;
                        }

                        // append nested check maximum matches
                        CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                            new CheckContinueMatchingMaximumMatchesReached(
                                enclosingSearchProgram is SearchProgramOfIterated ? CheckMaximumMatchesType.Iterated : CheckMaximumMatchesType.Subpattern,
                                false, topLevelSearchProgram is SearchProgramOfActionParallelizationBody);
                        insertionPoint.Append(checkMaximumMatches);

                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            tasksLeft,
                            null,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternativeCase ?? enclosingSearchProgram),
                            topLevelSearchProgram);

                        // check tasks left has a further check maximum matches nested within check failed code
                        // give it its special bit of attention here
                        CompleteCheckOperations(
                            tasksLeft.CheckFailedOperations,
                            enclosingSearchProgram,
                            enclosingAlternativeCase,
                            enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingIteratedPatternNonNullMatchFound)
                    {
                        // was built completely, nothing to complete
                    }
                    else
                    {
                        Debug.Assert(false, "unknown check abort matching operation");
                    }
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is AlternativeCaseMatching)
                //////////////////////////////////////////////////////////
                {
                    // depth first
                    CompleteCheckOperations(
                        currentOperation.GetNestedSearchOperationsList(),
                        enclosingSearchProgram,
                        (AlternativeCaseMatching)currentOperation,
                        null,
                        topLevelSearchProgram);
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation.IsSearchNestingOperation())
                //////////////////////////////////////////////////////////
                {
                    // depth first
                    CompleteCheckOperations(
                        currentOperation.GetNestedSearchOperationsList(),
                        enclosingSearchProgram,
                        enclosingAlternativeCase,
                        enclosingCheckNegativeOrIndependent,
                        topLevelSearchProgram);
                }

                // breadth
                currentOperation = currentOperation.Next;
            }
        }
        /// <summary>
        /// move outwards from check operation until operation to continue at is found
        /// appending restore isomorphy for isomorphy written on the way
        /// and final jump to operation to continue at
        /// </summary>
        private static void MoveOutwardsAppendingRemoveIsomorphyAndJump(
            CheckOperation checkOperation,
            string[] neededElementsForCheckOperation,
            SearchProgramOperation outermostOperation,
            SearchProgram topLevelSearchProgram)
        {
            // insertion point for candidate failed operations
            SearchProgramOperation insertionPoint =
                checkOperation.CheckFailedOperations;

            while (insertionPoint.Next != null)
            {
                insertionPoint = insertionPoint.Next;
            }

            // set outermost to iterated matching dummy loop if iterated
            if (outermostOperation is SearchProgramOfIterated)
            {
                SearchProgramOperation cur = checkOperation;
                while (!(cur is IteratedMatchingDummyLoop))
                {
                    cur = cur.Previous;
                }
                outermostOperation = cur;
            }

            SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy(
                checkOperation, ref insertionPoint, neededElementsForCheckOperation, outermostOperation, topLevelSearchProgram);

            // decide on type of continuing operation, then insert it

            // continue at top nesting level -> return
            SearchProgramOperation op = continuationPoint;

            while (!(op is SearchProgram))
            {
                op = op.Previous;
            }
            SearchProgram searchProgramRoot = op as SearchProgram;

            if (continuationPoint == searchProgramRoot)
            {
                ContinueOperation continueByReturn =
                    new ContinueOperation(
                        ContinueOperationType.ByReturn,
                        searchProgramRoot is SearchProgramOfAction || searchProgramRoot is SearchProgramOfActionParallelizationHead,
                        searchProgramRoot is SearchProgramOfActionParallelizationBody
                        );
                insertionPoint.Append(continueByReturn);

                return;
            }

            // continue at directly enclosing nesting level -> continue
            op = checkOperation;
            do
            {
                op = op.Previous;
            }while(!op.IsSearchNestingOperation());
            SearchProgramOperation directlyEnclosingOperation = op;

            if (continuationPoint == directlyEnclosingOperation
                // (check negative/independent is enclosing, but not a loop, thus continue wouldn't work)
                && !(directlyEnclosingOperation is CheckPartialMatchByNegative) &&
                !(directlyEnclosingOperation is CheckPartialMatchByIndependent)
                // (check partial match for duplicate contains an internal loop in checking, thus continue wouldn't work)
                && !(checkOperation is CheckPartialMatchForDuplicate))
            {
                ContinueOperation continueByContinue =
                    new ContinueOperation(ContinueOperationType.ByContinue,
                                          directlyEnclosingOperation is GetCandidateByIterationParallel);
                insertionPoint.Append(continueByContinue);

                return;
            }

            // otherwise -> goto label
            string gotoLabelName;

            // if our continuation point is a candidate iteration
            // -> append label at the end of the loop body of the candidate iteration loop
            if (continuationPoint is GetCandidateByIteration)
            {
                GetCandidateByIteration candidateIteration =
                    continuationPoint as GetCandidateByIteration;
                op = candidateIteration.NestedOperationsList;
                while (op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is a candidate iteration parallel
            // -> append label at the end of the loop body of the candidate iteration loop
            else if (continuationPoint is GetCandidateByIterationParallel)
            {
                GetCandidateByIterationParallel candidateIteration =
                    continuationPoint as GetCandidateByIterationParallel;
                op = candidateIteration.NestedOperationsList;
                while (op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is a both directions iteration
            // -> append label at the end of the loop body of the both directions iteration loop
            else if (continuationPoint is BothDirectionsIteration)
            {
                BothDirectionsIteration bothDirections =
                    continuationPoint as BothDirectionsIteration;
                op = bothDirections.NestedOperationsList;
                while (op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is an alternative case
            // -> append label at the end of the alternative case operations
            else if (continuationPoint is AlternativeCaseMatching)
            {
                AlternativeCaseMatching alternativeCase =
                    continuationPoint as AlternativeCaseMatching;
                op = alternativeCase.OperationsList;
                while (op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is the dummy loop of an iterated operation
            // -> we just jump to the label maxMatchesIterReached directly after the loop
            else if (continuationPoint is IteratedMatchingDummyLoop)
            {
                gotoLabelName = "maxMatchesIterReached";
            }
            // otherwise our continuation point is a check negative/independent operation
            // -> insert label directly after the check negative/independent operation
            else
            {
                CheckPartialMatchByNegativeOrIndependent checkNegativeIndependent =
                    continuationPoint as CheckPartialMatchByNegativeOrIndependent;
                GotoLabel gotoLabel = new GotoLabel();
                checkNegativeIndependent.Insert(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }

            ContinueOperation continueByGoto =
                new ContinueOperation(
                    ContinueOperationType.ByGoto,
                    gotoLabelName); // ByGoto due to parameters

            insertionPoint.Append(continueByGoto);
        }
示例#7
0
        void GenerateParallelizationSetupAsNeeded(SourceBuilder sb, LGSPRulePattern rulePattern, SearchProgram searchProgram)
        {
            if(rulePattern.patternGraph.branchingFactor < 2)
                return;

            foreach(SearchOperation so in rulePattern.patternGraph.parallelizedSchedule[0].Operations)
            {
                switch(so.Type)
                {
                    case SearchOperationType.WriteParallelPreset:
                        if(so.Element is SearchPlanNodeNode)
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name));
                        else //SearchPlanEdgeNode
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationParallelPresetCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.WriteParallelPresetVar:
                        sb.AppendFrontFormat("{0} {1};\n",
                            TypesHelper.TypeName(((PatternVariable)so.Element).Type),
                            NamesOfEntities.IterationParallelizationParallelPresetCandidate(((PatternVariable)so.Element).Name));
                        break;
                    case SearchOperationType.SetupParallelLookup:
                        if(so.Element is SearchPlanNodeNode)
                        {
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanNodeNode)so.Element).PatternElement.Name));
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPNode {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanNodeNode)so.Element).PatternElement.Name));
                        }
                        else
                        {
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                            sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        }
                        break;
                    case SearchOperationType.SetupParallelPickFromStorage:
                        if(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("set") || TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.type).StartsWith("map"))
                        {
                            sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n",
                                TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model),
                                TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model),
                                NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        else
                        {
                            sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                                TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.DotNetTypeToXgrsType(so.Storage.Variable.Type)), model),
                                NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        break;
                    case SearchOperationType.SetupParallelPickFromStorageDependent:
                        if(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("set") || TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute).StartsWith("map"))
                        {
                            sb.AppendFrontFormat("IEnumerator<KeyValuePair<{0},{1}>> {2};\n",
                               TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model),
                               TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractDst(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model),
                               NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        else
                        {
                            sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                               TypesHelper.XgrsTypeToCSharpType(TypesHelper.ExtractSrc(TypesHelper.AttributeTypeToXgrsType(so.Storage.Attribute.Attribute)), model),
                               NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        }
                        break;
                    case SearchOperationType.SetupParallelPickFromIndex:
                        sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                           TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ?
                               ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType :
                               ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType),
                           NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.SetupParallelPickFromIndexDependent:
                        sb.AppendFrontFormat("IEnumerator<{0}> {1};\n",
                           TypesHelper.TypeName(so.IndexAccess.Index is AttributeIndexDescription ?
                               ((AttributeIndexDescription)so.IndexAccess.Index).GraphElementType :
                               ((IncidenceCountIndexDescription)so.IndexAccess.Index).StartNodeType),
                           NamesOfEntities.IterationParallelizationIterator(((SearchPlanNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.SetupParallelIncoming:
                    case SearchOperationType.SetupParallelOutgoing:
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        break;
                    case SearchOperationType.SetupParallelIncident:
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationListHead(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        sb.AppendFrontFormat("GRGEN_LGSP.LGSPEdge {0};\n", NamesOfEntities.IterationParallelizationNextCandidate(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        sb.AppendFrontFormat("int {0};\n", NamesOfEntities.IterationParallelizationDirectionRunCounterVariable(((SearchPlanEdgeNode)so.Element).PatternElement.Name));
                        break;
                }
            }
            sb.AppendFront("\n");

            String rulePatternClassName = rulePattern.GetType().Name;
            String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name;
            String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name;
            sb.AppendFront("private static GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + ">[] parallelTaskMatches;\n");
            sb.AppendFront("private static int numWorkerThreads;\n");
            sb.AppendFront("private static int iterationNumber;\n");
            sb.AppendFront("private static int iterationLock;\n");
            sb.AppendFront("[ThreadStatic] private static int currentIterationNumber;\n");
            sb.AppendFront("[ThreadStatic] private static int threadId;\n");
            sb.AppendFront("private static GRGEN_LGSP.LGSPActionExecutionEnvironment actionEnvParallel;\n");
            sb.AppendFront("private static int maxMatchesParallel;\n");
            sb.AppendFront("private static bool maxMatchesFound = false;\n");

            sb.AppendFront("private static List<GRGEN_LGSP.LGSPNode>[] moveHeadAfterNodes;\n");
            sb.AppendFront("private static List<GRGEN_LGSP.LGSPEdge>[] moveHeadAfterEdges;\n");
            sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveOutHeadAfter;\n");
            sb.AppendFront("private static List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[] moveInHeadAfter;\n");
            sb.AppendFront("\n");
        }
示例#8
0
        /// <summary>
        /// Generates matcher class head source code for the pattern of the rulePattern into given source builder
        /// isInitialStatic tells whether the initial static version or a dynamic version after analyze is to be generated.
        /// </summary>
        void GenerateMatcherClassHeadAction(SourceBuilder sb, LGSPRulePattern rulePattern, 
            bool isInitialStatic, SearchProgram searchProgram)
        {
            PatternGraph patternGraph = (PatternGraph)rulePattern.PatternGraph;
                
            String namePrefix = (isInitialStatic ? "" : "Dyn") + "Action_";
            String className = namePrefix + rulePattern.name;
            String rulePatternClassName = rulePattern.GetType().Name;
            String matchClassName = rulePatternClassName + "." + "Match_" + rulePattern.name;
            String matchInterfaceName = rulePatternClassName + "." + "IMatch_" + rulePattern.name;
            String actionInterfaceName = "IAction_" + rulePattern.name;

            if(patternGraph.Package != null)
            {
                sb.AppendFrontFormat("namespace {0}\n", patternGraph.Package);
                sb.AppendFront("{\n");
                sb.Indent();
            }

            sb.AppendFront("public class " + className + " : GRGEN_LGSP.LGSPAction, "
                + "GRGEN_LIBGR.IAction, " + actionInterfaceName + "\n");
            sb.AppendFront("{\n");
            sb.Indent(); // class level

            sb.AppendFront("public " + className + "() {\n");
            sb.Indent(); // method body level
            sb.AppendFront("_rulePattern = " + rulePatternClassName + ".Instance;\n");
            sb.AppendFront("patternGraph = _rulePattern.patternGraph;\n");
            if(rulePattern.patternGraph.branchingFactor < 2)
            {
                sb.AppendFront("DynamicMatch = myMatch;\n");
                if(!isInitialStatic)
                    sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name);
            }
            else
            {
                sb.AppendFront("if(Environment.ProcessorCount == 1)\n");
                sb.AppendFront("{\n");
                sb.AppendFront("\tDynamicMatch = myMatch;\n");
                if(!isInitialStatic)
                    sb.AppendFrontFormat("\tGRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch;\n", rulePattern.name);
                sb.AppendFront("}\n");
                sb.AppendFront("else\n");
                sb.AppendFront("{\n");
                sb.Indent();
                sb.AppendFront("DynamicMatch = myMatch_parallelized;\n");
                if(!isInitialStatic)
                    sb.AppendFrontFormat("GRGEN_ACTIONS.Action_{0}.Instance.DynamicMatch = myMatch_parallelized;\n", rulePattern.name);
                sb.AppendFrontFormat("numWorkerThreads = GRGEN_LGSP.WorkerPool.EnsurePoolSize({0});\n", rulePattern.patternGraph.branchingFactor);
                sb.AppendFrontFormat("parallelTaskMatches = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>[numWorkerThreads];\n", matchClassName, matchInterfaceName);
                sb.AppendFront("moveHeadAfterNodes = new List<GRGEN_LGSP.LGSPNode>[numWorkerThreads];\n");
                sb.AppendFront("moveHeadAfterEdges = new List<GRGEN_LGSP.LGSPEdge>[numWorkerThreads];\n");
                sb.AppendFront("moveOutHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n");
                sb.AppendFront("moveInHeadAfter = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>[numWorkerThreads];\n");
                sb.AppendFront("for(int i=0; i<numWorkerThreads; ++i)\n");
                sb.AppendFront("{\n");
                sb.Indent();
                sb.AppendFront("moveHeadAfterNodes[i] = new List<GRGEN_LGSP.LGSPNode>();\n");
                sb.AppendFront("moveHeadAfterEdges[i] = new List<GRGEN_LGSP.LGSPEdge>();\n");
                sb.AppendFront("moveOutHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n");
                sb.AppendFront("moveInHeadAfter[i] = new List<KeyValuePair<GRGEN_LGSP.LGSPNode, GRGEN_LGSP.LGSPEdge>>();\n");
                sb.Unindent();
                sb.AppendFront("}\n");

                sb.AppendFront("for(int i=0; i<parallelTaskMatches.Length; ++i)\n");
                sb.AppendFrontFormat("\tparallelTaskMatches[i] = new GRGEN_LGSP.LGSPMatchesList<{0}, {1}>(this);\n", matchClassName, matchInterfaceName);
                sb.Unindent();
                sb.AppendFront("}\n");
            }
            sb.AppendFrontFormat("ReturnArray = new object[{0}];\n", rulePattern.Outputs.Length);
            sb.AppendFront("matches = new GRGEN_LGSP.LGSPMatchesList<" + matchClassName +", " + matchInterfaceName + ">(this);\n");
            sb.Unindent(); // class level
            sb.AppendFront("}\n\n");

            sb.AppendFront("public " + rulePatternClassName + " _rulePattern;\n");
            sb.AppendFront("public override GRGEN_LGSP.LGSPRulePattern rulePattern { get { return _rulePattern; } }\n");
            sb.AppendFront("public override string Name { get { return \"" + rulePattern.name + "\"; } }\n");
            sb.AppendFront("private GRGEN_LGSP.LGSPMatchesList<" + matchClassName + ", " + matchInterfaceName + "> matches;\n\n");

            if (isInitialStatic)
            {
                sb.AppendFront("public static " + className + " Instance { get { return instance; } set { instance = value; } }\n");
                sb.AppendFront("private static " + className + " instance = new " + className + "();\n");
            }

            GenerateIndependentsMatchObjects(sb, rulePattern, patternGraph);

            sb.AppendFront("\n");

            GenerateParallelizationSetupAsNeeded(sb, rulePattern, searchProgram);
        }
        /// <summary>
        /// move outwards from starting point on until operation to continue at is found
        /// appending restore isomorphy at insertion point for isomorphy written on the way
        /// returns operation to continue at
        /// </summary>
        private SearchProgramOperation MoveOutwardsAppendingRemoveIsomorphy(
            SearchProgramOperation startingPoint,
            ref SearchProgramOperation insertionPoint,
            string[] neededElementsForCheckOperation,
            SearchProgramOperation outermostOperation,
            SearchProgram topLevelSearchProgram)
        {
            // currently focused operation on our way outwards
            SearchProgramOperation op = startingPoint;
            // move outwards until operation to continue at is found
            bool creationPointOfDominatingElementFound = false;
            bool iterationReached = false;
            do
            {
                op = op.Previous;

                // insert code to clean up isomorphy information written by candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidate)
                {
                    AcceptCandidate writeIsomorphy =
                        op as AcceptCandidate;
                    AbandonCandidate restoreIsomorphy =
                        new AbandonCandidate(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode,
                            writeIsomorphy.NeverAboveMaxIsoSpace,
                            writeIsomorphy.Parallel,
                            writeIsomorphy.LockForAllThreads);
                    insertionPoint = insertionPoint.Append(restoreIsomorphy);
                }
                // insert code to clean up isomorphy information written by global candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidateGlobal)
                {
                    AcceptCandidateGlobal writeIsomorphy =
                        op as AcceptCandidateGlobal;
                    AbandonCandidateGlobal removeIsomorphy =
                        new AbandonCandidateGlobal(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode,
                            writeIsomorphy.NeverAboveMaxIsoSpace,
                            writeIsomorphy.Parallel);
                    insertionPoint = insertionPoint.Append(removeIsomorphy);
                }
                // insert code to clean up isomorphy information written by patternpath candidate acceptance
                // in between the operation to continue and the check operation
                if (op is AcceptCandidatePatternpath)
                {
                    AcceptCandidatePatternpath writeIsomorphy =
                        op as AcceptCandidatePatternpath;
                    AbandonCandidatePatternpath removeIsomorphy =
                        new AbandonCandidatePatternpath(
                            writeIsomorphy.PatternElementName,
                            writeIsomorphy.NegativeIndependentNamePrefix,
                            writeIsomorphy.IsNode);
                    insertionPoint = insertionPoint.Append(removeIsomorphy);
                }
                // insert code to remove iterated pattern acceptance
                if (op is AcceptIterated)
                {
                    AcceptIterated acceptIterated =
                        op as AcceptIterated;
                    AbandonIterated abandonIterated =
                        new AbandonIterated();
                    insertionPoint = insertionPoint.Append(abandonIterated);
                }
                // insert code to undo subpattern matching initialization if we leave the subpattern matching method
                if (op is InitializeSubpatternMatching)
                {
                    InitializeSubpatternMatching initialize =
                        op as InitializeSubpatternMatching;
                    FinalizeSubpatternMatching finalize =
                        new FinalizeSubpatternMatching(initialize.Type);
                    insertionPoint = insertionPoint.Append(finalize);
                }
                // insert code to undo negative/independent matching initialization if we leave the negative/independent matching method
                if (op is InitializeNegativeIndependentMatching)
                {
                    InitializeNegativeIndependentMatching initialize =
                        op as InitializeNegativeIndependentMatching;
                    FinalizeNegativeIndependentMatching finalize =
                        new FinalizeNegativeIndependentMatching(initialize.NeverAboveMaxIsoSpace, initialize.Parallel);
                    insertionPoint = insertionPoint.Append(finalize);
                }

                // determine operation to continue at
                // found by looking at the graph elements
                // the check operation depends on / is dominated by
                // its the first element iteration on our way outwards the search program
                // after or at the point of a get element operation
                // of some dominating element the check depends on
                // (or the outermost operation if no iteration is found until it is reached)
                if (op is GetCandidate || op is BothDirectionsIteration)
                {
                    if (creationPointOfDominatingElementFound == false)
                    {
                        if (neededElementsForCheckOperation != null)
                        {
                            foreach (string dominating in neededElementsForCheckOperation)
                            {
                                GetCandidate getCandidate = op as GetCandidate;
                                BothDirectionsIteration bothDirections = op as BothDirectionsIteration;
                                if (getCandidate!=null && getCandidate.PatternElementName == dominating
                                    || bothDirections!=null && bothDirections.PatternElementName == dominating)
                                {
                                    creationPointOfDominatingElementFound = true;
                                    iterationReached = false;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            // needed elements == null means everything fits,
                            // take first element iteration on our way outwards the search program
                            // (or the outermost operation if no iteration is found until it is reached)
                            creationPointOfDominatingElementFound = true;
                            iterationReached = false;
                        }
                    }
                    if (op is GetCandidateByIteration || op is GetCandidateByIterationParallel || op is BothDirectionsIteration)
                    {
                        iterationReached = true;
                    }
                }
            }
            while (!(creationPointOfDominatingElementFound && iterationReached)
                    && op != outermostOperation);

            return op;
        }
示例#10
0
        /// <summary>
        /// move outwards from check succeeded operation until check partial match by independent is found
        /// appending restore isomorphy for isomorphy written on the way
        /// and final jump to operation right after the independent failed operation of the check partial match by independent
        /// </summary>
        private void MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump(
            CheckContinueMatchingOfIndependentSucceeded checkSucceeded,
            CheckPartialMatchByIndependent enclosingIndependent,
            SearchProgram topLevelSearchProgram)
        {
            // insertion point for candidate failed operations
            SearchProgramOperation insertionPoint =
                checkSucceeded.CheckFailedOperations;
            while (insertionPoint.Next != null) // needed?
            {
                insertionPoint = insertionPoint.Next;
            }

            // move outwards, append remove isomorphy
            string[] neededElements = new string[0];
            SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy(
                checkSucceeded, ref insertionPoint, neededElements, enclosingIndependent, topLevelSearchProgram);

            // move to check failed operation of check independent operation
            while (!(continuationPoint is CheckContinueMatchingOfIndependentFailed))
            {
                continuationPoint = continuationPoint.Next;
            }
            CheckContinueMatchingOfIndependentFailed checkFailed =
                (CheckContinueMatchingOfIndependentFailed)continuationPoint;

            // insert label right thereafter, append jump there at insertion point
            GotoLabel gotoLabel = new GotoLabel();
            checkFailed.Insert(gotoLabel);

            ContinueOperation continueByGoto =
                new ContinueOperation(
                    ContinueOperationType.ByGoto,
                    gotoLabel.LabelName);
            insertionPoint.Append(continueByGoto);
        }
示例#11
0
        ///////////////////////////////////////////////////////////////////////////////////
        ///////////////////////////////////////////////////////////////////////////////////

        /// <summary>
        /// Completes check operations in search program from given currentOperation on
        /// (taking borderlines set by enclosing search program and check negative into account)
        /// Completion:
        /// - determine continuation point
        /// - insert remove isomorphy opertions needed for continuing there
        /// - insert continuing operation itself
        /// </summary>
        private void CompleteCheckOperations(
            SearchProgramOperation currentOperation,
            SearchProgramOperation enclosingSearchProgram, // might be a negative/independent in case these are nested
            GetPartialMatchOfAlternative enclosingAlternative,
            CheckPartialMatchByNegativeOrIndependent enclosingCheckNegativeOrIndependent,
            SearchProgram topLevelSearchProgram)
        {
            // mainly dispatching and iteration method, traverses search program
            // real completion done in MoveOutwardsAppendingRemoveIsomorphyAndJump
            // outermost operation for that function is computed here, regarding negative patterns
            // program nesting structure: search program - [alternative] - [negative|independent]*

            // complete check operations by inserting failure code
            // find them in depth first search of search program
            while (currentOperation != null)
            {
                //////////////////////////////////////////////////////////
                if (currentOperation is CheckCandidate)
                //////////////////////////////////////////////////////////
                {
                    CheckCandidate checkCandidate =
                        (CheckCandidate)currentOperation;
                    checkCandidate.CheckFailedOperations =
                        new SearchProgramList(checkCandidate);
                    string[] neededElementsForCheckOperation = new string[1];
                    neededElementsForCheckOperation[0] = checkCandidate.PatternElementName;
                    MoveOutwardsAppendingRemoveIsomorphyAndJump(
                        checkCandidate,
                        neededElementsForCheckOperation,
                        enclosingCheckNegativeOrIndependent ?? (enclosingAlternative ?? enclosingSearchProgram),
                        topLevelSearchProgram);
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is CheckPartialMatch)
                //////////////////////////////////////////////////////////
                {
                    if (currentOperation is CheckPartialMatchByCondition)
                    {
                        CheckPartialMatchByCondition checkCondition =
                            (CheckPartialMatchByCondition)currentOperation;
                        checkCondition.CheckFailedOperations =
                            new SearchProgramList(checkCondition);
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkCondition,
                            checkCondition.NeededElements,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternative ?? enclosingSearchProgram),
                            topLevelSearchProgram);
                    }
                    else if(currentOperation is CheckPartialMatchForDuplicate)
                    {
                        CheckPartialMatchForDuplicate checkDuplicateMatch =
                            (CheckPartialMatchForDuplicate)currentOperation;
                        checkDuplicateMatch.CheckFailedOperations =
                            new SearchProgramList(checkDuplicateMatch);
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkDuplicateMatch,
                            checkDuplicateMatch.NeededElements,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternative ?? enclosingSearchProgram),
                            topLevelSearchProgram);
                    }
                    else if(currentOperation is CheckPartialMatchByNegativeOrIndependent)
                    {
                        CheckPartialMatchByNegativeOrIndependent checkNegativeOrIndependent =
                            (CheckPartialMatchByNegativeOrIndependent)currentOperation;

                        // ByNegative/ByIndependent is handled in CheckContinueMatchingFailed
                        // of the negative/independent case - enter negative/independent case
                        CompleteCheckOperations(
                            checkNegativeOrIndependent.NestedOperationsList,
                            enclosingCheckNegativeOrIndependent ?? enclosingSearchProgram,
                            enclosingCheckNegativeOrIndependent!=null ? null : enclosingAlternative,
                            checkNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckPartialMatchForSubpatternsFound)
                    {
                        CheckPartialMatchForSubpatternsFound checkSubpatternsFound =
                            (CheckPartialMatchForSubpatternsFound)currentOperation;

                        if (enclosingCheckNegativeOrIndependent == null)
                        {
                            // determine insertion point within check failed operations
                            // to append the nested check maximum matches
                            SearchProgramOperation insertionPoint =
                                checkSubpatternsFound.CheckFailedOperations;
                            while (insertionPoint.Next != null)
                            {
                                insertionPoint = insertionPoint.Next;
                            }

                            // append nested check maximum matches
                            CheckMaximumMatchesType checkMaxMatchesType = CheckMaximumMatchesType.Action;
                            if(enclosingSearchProgram is SearchProgramOfSubpattern
                                || enclosingSearchProgram is SearchProgramOfAlternative) {
                                checkMaxMatchesType = CheckMaximumMatchesType.Subpattern;
                            } else if(enclosingSearchProgram is SearchProgramOfIterated) {
                                checkMaxMatchesType = CheckMaximumMatchesType.Iterated;
                            }
                            CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                                new CheckContinueMatchingMaximumMatchesReached(checkMaxMatchesType, false, 
                                    enclosingSearchProgram is SearchProgramOfActionParallelizationBody);
                            insertionPoint.Append(checkMaximumMatches);

                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkSubpatternsFound,
                                null,
                                enclosingCheckNegativeOrIndependent ?? (enclosingAlternative ?? enclosingSearchProgram),
                                topLevelSearchProgram);
                        }

                        // check subpatterns found has a further check maximum matches
                        // or check continue matching of negative failed nested within check failed code
                        // give it its special bit of attention here
                        CompleteCheckOperations(
                            checkSubpatternsFound.CheckFailedOperations,
                            enclosingSearchProgram,
                            enclosingAlternative,
                            enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else
                    {
                        Debug.Assert(false, "unknown check partial match operation");
                    }

                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is CheckContinueMatching)
                //////////////////////////////////////////////////////////
                {
                    if (currentOperation is CheckContinueMatchingMaximumMatchesReached)
                    {
                        CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                            (CheckContinueMatchingMaximumMatchesReached)currentOperation;
                        checkMaximumMatches.CheckFailedOperations =
                            new SearchProgramList(checkMaximumMatches);

                        if (checkMaximumMatches.ListHeadAdjustment)
                        {
                            MoveOutwardsAppendingListHeadAdjustment(checkMaximumMatches, checkMaximumMatches.InParallelizedBody);
                        }

                        string[] neededElementsForCheckOperation = new string[0];
                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            checkMaximumMatches,
                            neededElementsForCheckOperation,
                            enclosingSearchProgram,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingOfNegativeFailed)
                    {
                        CheckContinueMatchingOfNegativeFailed checkFailed =
                            (CheckContinueMatchingOfNegativeFailed)currentOperation;
                        checkFailed.CheckFailedOperations =
                            new SearchProgramList(checkFailed);
                        if(checkFailed.IsIterationBreaking)
                        {
                            string[] neededElementsForCheckOperation = new string[0];
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                neededElementsForCheckOperation,
                                enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                        else
                        {
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                enclosingCheckNegativeOrIndependent.NeededElements,
                                enclosingAlternative ?? enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                    }
                    else if (currentOperation is CheckContinueMatchingOfIndependentSucceeded)
                    {
                        CheckContinueMatchingOfIndependentSucceeded checkSucceeded =
                            (CheckContinueMatchingOfIndependentSucceeded)currentOperation;
                        checkSucceeded.CheckFailedOperations = // yep, rotten wording
                            new SearchProgramList(checkSucceeded);
                        MoveRightAfterCorrespondingIndependentFailedAppendingRemoveIsomorphyAndJump(
                            checkSucceeded,
                            (CheckPartialMatchByIndependent)enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingOfIndependentFailed)
                    {
                        CheckContinueMatchingOfIndependentFailed checkFailed =
                            (CheckContinueMatchingOfIndependentFailed)currentOperation;
                        checkFailed.CheckFailedOperations =
                            new SearchProgramList(checkFailed);
                        if(checkFailed.IsIterationBreaking)
                        {
                            string[] neededElementsForCheckOperation = new string[0];
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                neededElementsForCheckOperation,
                                enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                        else
                        {
                            MoveOutwardsAppendingRemoveIsomorphyAndJump(
                                checkFailed,
                                checkFailed.CheckIndependent.NeededElements,
                                enclosingAlternative ?? enclosingSearchProgram,
                                topLevelSearchProgram);
                        }
                    }
                    else if (currentOperation is CheckContinueMatchingTasksLeft)
                    {
                        CheckContinueMatchingTasksLeft tasksLeft =
                            (CheckContinueMatchingTasksLeft)currentOperation;

                        // determine insertion point within check failed operations
                        // to append the nested check maximum matches
                        SearchProgramOperation insertionPoint =
                            tasksLeft.CheckFailedOperations;
                        while (insertionPoint.Next != null)
                        {
                            insertionPoint = insertionPoint.Next;
                        }

                        // append nested check maximum matches
                        CheckContinueMatchingMaximumMatchesReached checkMaximumMatches =
                            new CheckContinueMatchingMaximumMatchesReached(
                                enclosingSearchProgram is SearchProgramOfIterated ? CheckMaximumMatchesType.Iterated : CheckMaximumMatchesType.Subpattern,
                                false, topLevelSearchProgram is SearchProgramOfActionParallelizationBody);
                        insertionPoint.Append(checkMaximumMatches);

                        MoveOutwardsAppendingRemoveIsomorphyAndJump(
                            tasksLeft,
                            null,
                            enclosingCheckNegativeOrIndependent ?? (enclosingAlternative ?? enclosingSearchProgram),
                            topLevelSearchProgram);

                        // check tasks left has a further check maximum matches nested within check failed code
                        // give it its special bit of attention here
                        CompleteCheckOperations(
                            tasksLeft.CheckFailedOperations,
                            enclosingSearchProgram,
                            enclosingAlternative,
                            enclosingCheckNegativeOrIndependent,
                            topLevelSearchProgram);
                    }
                    else if (currentOperation is CheckContinueMatchingIteratedPatternNonNullMatchFound)
                    {
                        // was built completely, nothing to complete
                    }
                    else
                    {
                        Debug.Assert(false, "unknown check abort matching operation");
                    }
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation is GetPartialMatchOfAlternative)
                //////////////////////////////////////////////////////////
                {
                    // depth first
                    CompleteCheckOperations(
                        currentOperation.GetNestedSearchOperationsList(),
                        enclosingSearchProgram,
                        (GetPartialMatchOfAlternative)currentOperation,
                        null,
                        topLevelSearchProgram);
                }
                //////////////////////////////////////////////////////////
                else if (currentOperation.IsSearchNestingOperation())
                //////////////////////////////////////////////////////////
                {
                    // depth first
                    CompleteCheckOperations(
                        currentOperation.GetNestedSearchOperationsList(),
                        enclosingSearchProgram,
                        enclosingAlternative,
                        enclosingCheckNegativeOrIndependent,
                        topLevelSearchProgram);
                }

                // breadth
                currentOperation = currentOperation.Next;
            }
        }
示例#12
0
        /// <summary>
        /// move outwards from check operation until operation to continue at is found
        /// appending restore isomorphy for isomorphy written on the way
        /// and final jump to operation to continue at
        /// </summary>
        private void MoveOutwardsAppendingRemoveIsomorphyAndJump(
            CheckOperation checkOperation,
            string[] neededElementsForCheckOperation,
            SearchProgramOperation outermostOperation,
            SearchProgram topLevelSearchProgram)
        {
            // insertion point for candidate failed operations
            SearchProgramOperation insertionPoint =
                checkOperation.CheckFailedOperations;
            while (insertionPoint.Next != null)
            {
                insertionPoint = insertionPoint.Next;
            }

            // set outermost to iterated dummy iteration if iterated
            if (outermostOperation is SearchProgramOfIterated)
            {
                SearchProgramOperation cur = checkOperation;
                while (!(cur is ReturnPreventingDummyIteration))
                {
                    cur = cur.Previous;
                }
                outermostOperation = cur;
            }

            SearchProgramOperation continuationPoint = MoveOutwardsAppendingRemoveIsomorphy(
                checkOperation, ref insertionPoint, neededElementsForCheckOperation, outermostOperation, topLevelSearchProgram);

            // decide on type of continuing operation, then insert it

            // continue at top nesting level -> return
            SearchProgramOperation op = continuationPoint;
            while (!(op is SearchProgram))
            {
                op = op.Previous;
            }
            SearchProgram searchProgramRoot = op as SearchProgram;
            if (continuationPoint == searchProgramRoot)
            {
                ContinueOperation continueByReturn =
                    new ContinueOperation(
                        ContinueOperationType.ByReturn,
                        searchProgramRoot is SearchProgramOfAction || searchProgramRoot is SearchProgramOfActionParallelizationHead,
                        searchProgramRoot is SearchProgramOfActionParallelizationBody
                        );
                insertionPoint.Append(continueByReturn);

                return;
            }

            // continue at directly enclosing nesting level -> continue
            op = checkOperation;
            do
            {
                op = op.Previous;
            }
            while (!op.IsSearchNestingOperation());
            SearchProgramOperation directlyEnclosingOperation = op;
            if (continuationPoint == directlyEnclosingOperation
                // (check negative/independent is enclosing, but not a loop, thus continue wouldn't work) 
                && !(directlyEnclosingOperation is CheckPartialMatchByNegative)
                && !(directlyEnclosingOperation is CheckPartialMatchByIndependent)
                // (check partial match for duplicate contains an internal loop in checking, thus continue wouldn't work)
                && !(checkOperation is CheckPartialMatchForDuplicate))
            {
                ContinueOperation continueByContinue =
                    new ContinueOperation(ContinueOperationType.ByContinue, 
                        directlyEnclosingOperation is GetCandidateByIterationParallel);
                insertionPoint.Append(continueByContinue);

                return;
            }

            // otherwise -> goto label
            string gotoLabelName;

            // if our continuation point is a candidate iteration
            // -> append label at the end of the loop body of the candidate iteration loop
            if (continuationPoint is GetCandidateByIteration)
            {
                GetCandidateByIteration candidateIteration =
                    continuationPoint as GetCandidateByIteration;
                op = candidateIteration.NestedOperationsList;
                while (op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is a candidate iteration parallel
            // -> append label at the end of the loop body of the candidate iteration loop
            else if (continuationPoint is GetCandidateByIterationParallel)
            {
                GetCandidateByIterationParallel candidateIteration =
                    continuationPoint as GetCandidateByIterationParallel;
                op = candidateIteration.NestedOperationsList;
                while(op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is a both directions iteration
            // -> append label at the end of the loop body of the both directions iteration loop
            else if (continuationPoint is BothDirectionsIteration)
            {
                BothDirectionsIteration bothDirections =
                    continuationPoint as BothDirectionsIteration;
                op = bothDirections.NestedOperationsList;
                while (op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is an alternative
            // -> append label at the end of the alternative operations
            else if (continuationPoint is GetPartialMatchOfAlternative)
            {
                GetPartialMatchOfAlternative getAlternative =
                    continuationPoint as GetPartialMatchOfAlternative;
                op = getAlternative.OperationsList;
                while (op.Next != null)
                {
                    op = op.Next;
                }
                GotoLabel gotoLabel = new GotoLabel();
                op.Append(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }
            // if our continuation point is the dummy loop of an iterated operation
            // -> we just jump to the label maxMatchesIterReached directly after the loop
            else if (continuationPoint is ReturnPreventingDummyIteration)
            {
                gotoLabelName = "maxMatchesIterReached";
            }
            // otherwise our continuation point is a check negative/independent operation
            // -> insert label directly after the check negative/independent operation
            else
            {
                CheckPartialMatchByNegativeOrIndependent checkNegativeIndependent =
                    continuationPoint as CheckPartialMatchByNegativeOrIndependent;
                GotoLabel gotoLabel = new GotoLabel();
                checkNegativeIndependent.Insert(gotoLabel);
                gotoLabelName = gotoLabel.LabelName;
            }

            ContinueOperation continueByGoto =
                new ContinueOperation(
                    ContinueOperationType.ByGoto,
                    gotoLabelName); // ByGoto due to parameters
            insertionPoint.Append(continueByGoto);
        }