/// <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); }
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); } } } } }
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); }
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); }
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)); } }
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); }
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); }
/// <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); }
/// <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)); } }
/// <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); } }
/// <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)); }
/// <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); }
/// <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); }
/// <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)); }
/// <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)); }
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); }
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); }