Exemple #1
0
        /// <summary>
        /// Handles a nested block. A nested block is explained with an if statement as example.
        /// The given lists/matrices are correctly updated.
        /// <para/>
        /// Consider the following block. Only the first block is shown. The texts in [] describe the role of the important steps for that statement.
        /// <para/>
        /// IF George can fly THEN [block start]
        /// <para/>
        /// Go fly George. [nested block step]
        /// <para/>
        /// And don't come back. [nested block step]
        /// <para/>
        /// ELSE [block end]
        /// <para/>
        /// You're trapped to this world. :(
        /// <para/>
        /// ENDIF [exit target step]
        /// </summary>
        /// <param name="steps">The steps containing the block.</param>
        /// <param name="edgeMatrix">The edge matrix.</param>
        /// <param name="externalEdges">The external edges list.</param>
        /// <param name="possibleInvalidIfEdges">The possible invalid if edge list.</param>
        /// <param name="conditionMatrix">The condition matrix.</param>
        /// <param name="blockStartIndex">The index of the block start. (The step before the nested block begins)</param>
        /// <param name="blockEndIndex">The index of the block end. (The step after the nested block ends)</param>
        /// <param name="exitStepsTargetStep">The step to where create the edges if the nested block has exit steps.</param>
        /// <param name="blockEntryCondition">The condition to be fulfilled to enter the nested block.</param>
        public static void SetEdgesInNestedBlock(
            IReadOnlyList <Node> steps,
            ref Matrix <bool> edgeMatrix,
            ref List <ExternalEdge> externalEdges,
            ref List <InternalEdge> possibleInvalidIfEdges,
            ref Matrix <Condition?> conditionMatrix,
            int blockStartIndex,
            int blockEndIndex,
            int exitStepsTargetStep,
            Condition?blockEntryCondition)
        {
            int blockSize = blockEndIndex - blockStartIndex - 1;

            // Set edge into the nested block
            edgeMatrix[blockStartIndex, blockStartIndex + 1]      = true;
            conditionMatrix[blockStartIndex, blockStartIndex + 1] = blockEntryCondition;

            List <Node> nestedSteps = steps.Skip(blockStartIndex + 1).Take(blockSize).ToList();

            Matrix <bool>                   nestedEdgeMatrix;
            List <ExternalEdge>             nestedExternalEdges;
            List <InternalEdge>             nestedPossibleInvalidIfEdges;
            List <Tuple <int, Condition?> > nestedExitSteps;
            Matrix <Condition?>             nestedConditionMatrix;

            GraphBuilder.SetEdgesInStepBlock(nestedSteps, out nestedEdgeMatrix, out nestedExternalEdges, out nestedPossibleInvalidIfEdges, out nestedExitSteps, out nestedConditionMatrix);

            // Unite matrices
            GraphBuilder.InsertMatrix(ref edgeMatrix, blockStartIndex + 1, blockStartIndex + 1, nestedEdgeMatrix);
            GraphBuilder.InsertMatrix(ref conditionMatrix, blockStartIndex + 1, blockStartIndex + 1, nestedConditionMatrix);

            // Unite externalEdges
            externalEdges.AddRange(nestedExternalEdges.ConvertAll((edge) => edge.NewWithIncreasedSourceStepNumber(blockStartIndex + 1)));

            // Unite possible invalid if edges
            possibleInvalidIfEdges.AddRange(nestedPossibleInvalidIfEdges.ConvertAll((edge) => edge.NewWithIncreasedSourceTargetStep(blockStartIndex + 1)));

            // Wire exit steps to end if step
            foreach (Tuple <int, Condition?> exitStep in nestedExitSteps)
            {
                edgeMatrix[exitStep.Item1 + blockStartIndex + 1, exitStepsTargetStep]      = true;
                conditionMatrix[exitStep.Item1 + blockStartIndex + 1, exitStepsTargetStep] = exitStep.Item2;
            }
        }
Exemple #2
0
        /// <summary>
        /// Wires a flow individually meaning all steps inside. Basically the method <see cref="SetEdgesInStepBlock(IReadOnlyList{Node}, out Matrix{bool}, out List{ExternalEdge}, out List{InternalEdge}, out List{int})"/>
        /// is called for the flow.
        /// </summary>
        /// <param name="flow">The flow to wire.</param>
        /// <param name="flowOffset">The offset of the flows nodes. Later used to identify its edges in the edge matrix.</param>
        /// <returns>A tuple containing the offset as item 1, the flow as item 2 and then all the out parameters of <see cref="SetEdgesInStepBlock(IReadOnlyList{Node}, out Matrix{bool}, out List{ExternalEdge}, out List{InternalEdge}, out List{int})"/>.</returns>
        public static Tuple <int, Flow, Matrix <bool>, List <ExternalEdge>, List <InternalEdge>, List <Tuple <int, Condition?> >, Matrix <Condition?> > WireFlowIndividually(Flow flow, int flowOffset)
        {
            IReadOnlyList <Node>            steps = flow.Nodes;
            Matrix <bool>                   edgeMatrix;
            List <ExternalEdge>             externalEdges;
            List <InternalEdge>             possibleInvalidIfEdges;
            List <Tuple <int, Condition?> > exitSteps;
            Matrix <Condition?>             conditionMatrix;

            GraphBuilder.SetEdgesInStepBlock(steps, out edgeMatrix, out externalEdges, out possibleInvalidIfEdges, out exitSteps, out conditionMatrix);
            return(new Tuple <int, Flow, Matrix <bool>, List <ExternalEdge>, List <InternalEdge>, List <Tuple <int, Condition?> >, Matrix <Condition?> >(
                       flowOffset,
                       flow,
                       edgeMatrix,
                       externalEdges,
                       possibleInvalidIfEdges,
                       exitSteps,
                       conditionMatrix));
        }