Пример #1
0
        /// <summary>
        /// Determines whether the specified element is the last element on a path. That is, if deletion of this
        /// element (and its preceding and following links) would not leave dead-end nodes in the graph, it is considered
        /// to be the last element in the path.
        /// </summary>
        /// <param name="element">The specified element.</param>
        /// <returns>
        ///     <c>true</c> if the specified element is the last element on a path; otherwise, <c>false</c>.
        /// </returns>
        public static bool IsLastElementOnPath(IPfcElement element)
        {
            if (element.ElementType.Equals(PfcElementType.Link))
            {
                IPfcNode pre = ((IPfcLinkElement)element).Predecessor;
                if (pre.SuccessorNodes.Count == 1)
                {
                    return(false);
                }

                IPfcNode post = ((IPfcLinkElement)element).Successor;
                if (post.PredecessorNodes.Count == 1)
                {
                    return(false);
                }
            }
            else
            {
                foreach (IPfcNode pre in ((IPfcNode)element).PredecessorNodes)
                {
                    if (pre.SuccessorNodes.Count == 1)
                    {
                        return(false);
                    }
                }
                foreach (IPfcNode post in ((IPfcNode)element).SuccessorNodes)
                {
                    if (post.PredecessorNodes.Count == 1)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Пример #2
0
        static void DumpElementContents(IPfcElement element, StringBuilder sb, int indent)
        {
            sb.Append("\r\n");

            for (int i = 0; i < indent; i++)
            {
                sb.Append("\t");
            }
            if (element == null)
            {
                sb.Append("<null>");
            }
            else
            {
                sb.Append(element.Name);
                if (element is IPfcStepNode)
                {
                    IPfcStepNode node = (IPfcStepNode)element;
                    sb.Append(" [ " + node.Predecessors.Count + ", " + node.Successors.Count + " ]");
                    foreach (IProcedureFunctionChart childPfc in node.Actions.Values)
                    {
                        foreach (IPfcElement child in childPfc.Elements)
                        {
                            DumpElementContents(child, sb, indent + 1);
                        }
                    }
                }
            }
        }
Пример #3
0
        public static ProcedureFunctionChart CreateLoopTestPfc()
        {
            ProcedureFunctionChart pfc = new ProcedureFunctionChart(new Highpoint.Sage.SimCore.Model("Test model", Guid.NewGuid()), "SFC 1");

            #region Create Nodes

            A = pfc.CreateStep("Step_A", "", Guid.NewGuid());
            B = pfc.CreateStep("Step_B", "", Guid.NewGuid());
            C = pfc.CreateStep("Step_C", "", Guid.NewGuid());

            nA = (IPfcNode)A;
            nB = (IPfcNode)B;
            nC = (IPfcNode)C;

            #endregion Create Nodes

            #region Create Structure

            pfc.Bind(nA, nB);
            pfc.Bind(nB, nC);
            pfc.Bind(nB, nB);

            #endregion Create Structure

            return(pfc);
        }
Пример #4
0
        public static ProcedureFunctionChart CreateTestPfc5()
        {
            // Flip-flop pattern.

            ProcedureFunctionChart pfc = new ProcedureFunctionChart(new Highpoint.Sage.SimCore.Model("Test model", Guid.NewGuid()), "SFC 1");

            #region Create Nodes

            char name = 'A';
            A = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            B = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            C = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            D = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            E = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            F = pfc.CreateStep("Step_" + (name++), "", NextGuid());

            nA = (IPfcNode)A;
            nB = (IPfcNode)B;
            nC = (IPfcNode)C;
            nD = (IPfcNode)D;
            nE = (IPfcNode)E;
            nF = (IPfcNode)F;

            #endregion Create Nodes

            #region Create Structure

            pfc.BindParallelDivergent(nA, new IPfcNode[] { nB, nC });
            pfc.BindSeriesDivergent(nB, new IPfcNode[] { nD, nE });
            pfc.BindSeriesDivergent(nC, new IPfcNode[] { nD, nE });
            pfc.BindParallelConvergent(new IPfcNode[] { nD, nE }, nF);

            PfcLinkElementList links = new PfcLinkElementList(pfc.Links);
            links.Sort(new Comparison <IPfcLinkElement>(delegate(IPfcLinkElement a, IPfcLinkElement b) {
                return(Comparer.Default.Compare(a.Name, b.Name));
            }));


            System.Reflection.BindingFlags bf = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
            foreach (IPfcLinkElement link in links)
            {
                typeof(PfcElement).GetFields(bf);
                typeof(PfcElement).GetField("m_guid", bf).SetValue((PfcElement)link, NextGuid()); // Totally cheating.
            }

            //pfc.Bind(nD, pfc.Nodes["T_005"]);

            #endregion Create Structure

            return(pfc);
        }
Пример #5
0
        private static IPfcNode GetPrevDivergenceNode(IPfcElement element)
        {
            List <IPfcNode> beenThere = new List <IPfcNode>();

            if (element.ElementType.Equals(PfcElementType.Link))
            {
                beenThere.Add(((IPfcLinkElement)element).Successor);
                return(GetPrevDivergenceNode(((IPfcLinkElement)element).Successor, 0, beenThere));
            }
            else
            {
                beenThere.Add((IPfcNode)element);
                return(GetPrevDivergenceNode((IPfcNode)element, 0, beenThere));
            }
        }
Пример #6
0
        public static ProcedureFunctionChart CreateTestPfc4()
        {
            ProcedureFunctionChart pfc = new ProcedureFunctionChart(new Highpoint.Sage.SimCore.Model("Test model", Guid.NewGuid()), "SFC 1");

            #region Create Nodes

            char name = 'A';
            A = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            B = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            C = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            D = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            E = pfc.CreateStep("Step_" + (name++), "", NextGuid());

            nA = (IPfcNode)A;
            nB = (IPfcNode)B;
            nC = (IPfcNode)C;
            nD = (IPfcNode)D;
            nE = (IPfcNode)E;

            #endregion Create Nodes

            #region Create Structure

            pfc.Bind(nA, nB);
            pfc.Bind(nB, nE);
            pfc.Bind(nA.SuccessorNodes[0], nC);
            pfc.Bind(nC, nD);
            pfc.Bind(nD, nE.PredecessorNodes[0]);

            PfcLinkElementList links = new PfcLinkElementList(pfc.Links);
            links.Sort(new Comparison <IPfcLinkElement>(delegate(IPfcLinkElement a, IPfcLinkElement b) {
                return(Comparer.Default.Compare(a.Name, b.Name));
            }));


            System.Reflection.BindingFlags bf = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
            foreach (IPfcLinkElement link in links)
            {
                typeof(PfcElement).GetFields(bf);
                typeof(PfcElement).GetField("m_guid", bf).SetValue((PfcElement)link, NextGuid()); // Totally cheating.
            }

            #endregion Create Structure

            return(pfc);
        }
Пример #7
0
        public static ProcedureFunctionChart CreateOffsetParallelPFC()
        {
            ProcedureFunctionChart pfc    = new ProcedureFunctionChart(null, "OffsetParallelPfc");
            IPfcStepNode           start  = pfc.CreateStep("Start", "", Guid.Empty);
            IPfcStepNode           finish = pfc.CreateStep("Finish", "", Guid.Empty);

            char name = 'A';

            A = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            B = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            C = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            D = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            E = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            F = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            G = pfc.CreateStep("Step_" + (name++), "", NextGuid());

            nA = (IPfcNode)A;
            nB = (IPfcNode)B;
            nC = (IPfcNode)C;
            nD = (IPfcNode)D;
            nE = (IPfcNode)E;
            nF = (IPfcNode)F;
            nG = (IPfcNode)G;

            pfc.Bind(start, nA);
            pfc.Bind(nA, nB);
            pfc.Bind(nB, nE);
            pfc.Bind(nE, nF);
            pfc.Bind(nF, nG);
            pfc.Bind(nG, finish);
            pfc.Bind(((PfcTransition)((PfcStep)nA).SuccessorNodes[0]), nC);
            pfc.Bind(nC, ((PfcTransition)((PfcStep)nE).SuccessorNodes[0]));
            pfc.Bind(((PfcTransition)((PfcStep)nB).SuccessorNodes[0]), nD);
            pfc.Bind(nD, ((PfcTransition)((PfcStep)nF).SuccessorNodes[0]));

            pfc.UpdateStructure();

            return(pfc);
        }
Пример #8
0
        /// <summary>
        /// Gets the join element that brings the path of the specified element and any parallel paths (whether from series
        /// or parallel divergences) together. If the specified node is not a member of a path with simultaneous paths, then
        /// this method returns null.
        /// </summary>
        /// <param name="element">The specified element.</param>
        /// <returns>The join element, if any - otherwise, null.</returns>
        public static IPfcElement GetJoinNodeForParallelPath(IPfcElement element)
        {
            // Algorithm: Find the divergence node. Do a traversal for each outbound path until there
            // are no more nodes (end of path) or we've been there before (loopback). On encountering
            // each node for the first time under each path, increment a counter for that path.
            //
            // The first time we encounter a node whose count is the number of diverging paths from the divergence
            // node, we've found the convergence node.

            IPfcNode node = element as IPfcNode;

            if (node == null)
            {
                node = ((IPfcLinkElement)element).Successor;
            }
            IPfcNode prevDivNode = GetPrevDivergenceNode((IPfcNode)element);

            Dictionary <IPfcNode, int> hitCounts = new Dictionary <IPfcNode, int>();

            IPfcNode convergenceNode = null;

            if (prevDivNode == null)
            {
                return(null);
            }

            int nParallelPaths = prevDivNode.SuccessorNodes.Count;

            foreach (IPfcNode firstNodeInPath in prevDivNode.SuccessorNodes)
            {
                List <IPfcNode> beenThere = new List <IPfcNode>();
                Traverse(nParallelPaths, firstNodeInPath, beenThere, hitCounts, ref convergenceNode);
            }

            return(convergenceNode);
        }
Пример #9
0
 /// <summary>
 /// Determines whether the specified element is a part of a path that has alternate paths. This algorithm
 /// goes up only one level - that is, if it's part of a parallel divergence that, itself, is in a path that
 /// is part of a series divergence, then the result will still be false.
 /// </summary>
 /// <param name="element">The specified element.</param>
 /// <returns>
 ///     <c>true</c> if the specified element is a part of a path that has parallel paths; otherwise, <c>false</c>.
 /// </returns>
 public static bool HasAlternatePaths(IPfcElement element)
 {
     if (element == null)
     {
         return(false);
     }
     if (element.ElementType.Equals(PfcElementType.Link))
     {
         IPfcLinkElement linkElement = (IPfcLinkElement)element;
         if (linkElement.Predecessor != null && linkElement.Predecessor.ElementType.Equals(PfcElementType.Step) && linkElement.Predecessor.Successors.Count > 1)
         {
             return(true);
         }
         else
         {
             return(HasAlternatePaths(((IPfcLinkElement)element).Predecessor));
         }
     }
     else
     {
         IPfcNode prevDivergenceNode = GetPrevDivergenceNode((IPfcNode)element);
         return(prevDivergenceNode != null && prevDivergenceNode.ElementType.Equals(PfcElementType.Step));
     }
 }
Пример #10
0
 /// <summary>
 /// Determines whether the specified element is the sole successor of its immediate precedent node. If immediate predecessor is
 /// null, this method returns false.
 /// </summary>
 /// <param name="element">The specified element.</param>
 /// <returns>
 ///     <c>true</c> if the specified link is the sole successor of its one immediate precedent node; otherwise, (if there
 /// are any number of predecessors other than one, or if the one predecessor node has any number but one successor nodes)<c>false</c>.
 /// </returns>
 public static bool IsSoleSuccessor(IPfcElement element)
 {
     if (element == null)
     {
         return(false);
     }
     if (element.ElementType.Equals(PfcElementType.Link))
     {
         IPfcLinkElement link = (IPfcLinkElement)element;
         if (link.Predecessor == null)
         {
             return(false);
         }
         else
         {
             return(link.Predecessor.Successors.Count == 1);
         }
     }
     else
     {
         IPfcNode node = (IPfcNode)element;
         return(node.PredecessorNodes.Count == 1 && node.PredecessorNodes[0].SuccessorNodes.Count == 1);
     }
 }
Пример #11
0
 /// <summary>
 /// Gets the divergence element where the path of the specified element and any parallel paths (whether from series
 /// or parallel) diverge. If the specified node is not a member of a path with simultaneous paths, then
 /// this method returns null.
 /// </summary>
 /// <param name="element">The specified element.</param>
 /// <returns>The join element, if any - otherwise, null.</returns>
 public static IPfcElement GetDivergenceElementForParallelPath(IPfcElement element)
 {
     return(GetPrevDivergenceNode(element));
 }
Пример #12
0
 /// <summary>
 /// Gets the join transition that brings the path of the specified element and any parallel simultaneous paths together.
 /// If the specified node is not a member of a path with simultaneous paths, then this method returns null.
 /// </summary>
 /// <param name="element">The specified element.</param>
 /// <returns>The join transition, if any - otherwise, null.</returns>
 public static IPfcTransitionNode GetJoinTransitionForSimultaneousPaths(IPfcElement element)
 {
     return(GetJoinNodeForParallelPath(element) as IPfcTransitionNode);
 }
Пример #13
0
 /// <summary>
 /// Gets the join step that brings the path of the specified element and any parallel alternate paths together.
 /// If the specified node is not a member of a path with alternates, then this method returns null.
 /// </summary>
 /// <param name="element">The specified element.</param>
 /// <returns>The join element, if any - otherwise, null.</returns>
 public static IPfcStepNode GetJoinNodeForAlternatePaths(IPfcElement element)
 {
     return(GetJoinNodeForParallelPath(element) as IPfcStepNode);
 }
Пример #14
0
 /// <summary>
 /// Determines whether the specified element is the last element on a path, and that path is a parallel path.
 /// That is, if deletion of this element (and its preceding and following links) would not leave dead-end nodes
 /// in the graph, it is considered to be the last element in the path.
 /// </summary>
 /// <param name="element">The specified element.</param>
 /// <returns>
 ///     <c>true</c> if the specified element is the last element on a parallel path; otherwise, <c>false</c>.
 /// </returns>
 public static bool IsLastElementOnParallelPath(IPfcElement element)
 {
     return(HasParallelPaths(element) && IsLastElementOnPath(element));
 }
Пример #15
0
 /// <summary>
 /// Determines whether the specified element is the last element on a path, and that path is an alternate path.
 /// That is, if deletion of this element (and its preceding and following links) would not leave dead-end nodes
 /// in the graph, it is considered to be the last element in the path.
 /// </summary>
 /// <param name="element">The specified element.</param>
 /// <returns>
 ///     <c>true</c> if the specified element is the last element on an alternate path; otherwise, <c>false</c>.
 /// </returns>
 public static bool IsLastElementOnAlternatePath(IPfcElement element)
 {
     return(HasAlternatePaths(element) && IsLastElementOnPath(element));
 }
Пример #16
0
        public static ProcedureFunctionChart CreateTestPfc()
        {
            ProcedureFunctionChart pfc = new ProcedureFunctionChart(new Highpoint.Sage.SimCore.Model("Test model", Guid.NewGuid()), "SFC 1");

            ((PfcElementFactory)pfc.ElementFactory).SetRepeatable(Guid.Empty); // Ensures Guids are repeatable.

            #region Create Nodes

            char name = 'A';
            A = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            B = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            C = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            D = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            E = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            F = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            G = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            H = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            I = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            J = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            K = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            L = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            M = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            N = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            O = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            P = pfc.CreateStep("Step_" + (name), "", NextGuid());

            nA = (IPfcNode)A;
            nB = (IPfcNode)B;
            nC = (IPfcNode)C;
            nD = (IPfcNode)D;
            nE = (IPfcNode)E;
            nF = (IPfcNode)F;
            nG = (IPfcNode)G;
            nH = (IPfcNode)H;
            nI = (IPfcNode)I;
            nJ = (IPfcNode)J;
            nK = (IPfcNode)K;
            nL = (IPfcNode)L;
            nM = (IPfcNode)M;
            nN = (IPfcNode)N;
            nO = (IPfcNode)O;
            nP = (IPfcNode)P;

            #endregion Create Nodes

            #region Create Structure

            pfc.Bind(nA, nB);
            pfc.BindSeriesDivergent(nB, new IPfcNode[] { nC, nF });
            pfc.Bind(nC, nD);
            pfc.Bind(nD, nE);
            pfc.Bind(nF, nG);
            pfc.BindParallelDivergent(nG, new IPfcNode[] { nH, nI, nP });
            pfc.Bind(nH, nJ);
            pfc.Bind(nI, nK);
            pfc.BindParallelConvergent(new IPfcNode[] { nJ, nK, nP }, nL);
            pfc.Bind(nL, nM);
            pfc.BindSeriesConvergent(new IPfcNode[] { nE, nM }, nN);
            pfc.Bind(nN, nO);
            pfc.Bind(nB, nN);

            #endregion Create Structure

            pfc.UpdateStructure();

            return(pfc);
        }
Пример #17
0
        public static ProcedureFunctionChart CreateTestPfc3()
        {
            ProcedureFunctionChart pfc = new ProcedureFunctionChart(new Highpoint.Sage.SimCore.Model("Test model", Guid.NewGuid()), "SFC 1");

            #region Create Nodes

            char name = 'A';
            A = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            B = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            C = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            D = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            E = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            F = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            G = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            H = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            I = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            J = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            K = pfc.CreateStep("Step_" + (name++), "", NextGuid());
            L = pfc.CreateStep("Step_" + (name++), "", NextGuid());

            nA = (IPfcNode)A;
            nB = (IPfcNode)B;
            nC = (IPfcNode)C;
            nD = (IPfcNode)D;
            nE = (IPfcNode)E;
            nF = (IPfcNode)F;
            nG = (IPfcNode)G;
            nH = (IPfcNode)H;
            nI = (IPfcNode)I;
            nJ = (IPfcNode)J;
            nK = (IPfcNode)K;
            nL = (IPfcNode)L;

            #endregion Create Nodes

            #region Create Structure

            pfc.BindParallelDivergent(nA, new IPfcNode[] { nB, nC, nD, nE });
            pfc.BindParallelDivergent(nB, new IPfcNode[] { nF, nG });
            pfc.BindParallelDivergent(nE, new IPfcNode[] { nJ, nK });

            pfc.BindParallelConvergent(new IPfcNode[] { nF, nG }, nH);
            pfc.BindParallelConvergent(new IPfcNode[] { nC, nD }, nI);
            pfc.BindParallelConvergent(new IPfcNode[] { nH, nI, nJ, nK }, nL);

            PfcLinkElementList links = new PfcLinkElementList(pfc.Links);
            links.Sort(new Comparison <IPfcLinkElement>(delegate(IPfcLinkElement a, IPfcLinkElement b) {
                return(Comparer.Default.Compare(a.Name, b.Name));
            }));


            System.Reflection.BindingFlags bf = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.FlattenHierarchy | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance;
            foreach (IPfcLinkElement link in links)
            {
                typeof(PfcElement).GetFields(bf);
                typeof(PfcElement).GetField("m_guid", bf).SetValue((PfcElement)link, NextGuid()); // Totally cheating.
            }

            #endregion Create Structure

            return(pfc);
        }